summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/channels.h11
-rw-r--r--include/modules.h7
-rw-r--r--src/channels.cpp50
-rw-r--r--src/cmd_part.cpp10
-rw-r--r--src/modules.cpp5
-rw-r--r--src/modules/m_park.cpp6
-rw-r--r--src/modules/m_remove.cpp6
-rw-r--r--src/modules/m_sapart.cpp16
8 files changed, 47 insertions, 64 deletions
diff --git a/include/channels.h b/include/channels.h
index 444adf64f..906297104 100644
--- a/include/channels.h
+++ b/include/channels.h
@@ -263,6 +263,15 @@ class chanrec : public Extensible
*/
long ServerKickUser(userrec* user, const char* reason, bool triggerevents);
+ /* Part a user from this channel with the given reason.
+ * If the reason field is NULL, no reason will be sent.
+ * @param user The user who is parting (must be on this channel)
+ * @param reason The (optional) part reason
+ * @return The number of users left on the channel. If this is zero
+ * when the method returns, you MUST delete the chanrec immediately!
+ */
+ long PartUser(userrec *user, const char* reason = NULL);
+
/** Destructor for chanrec
*/
virtual ~chanrec() { /* stub */ }
@@ -304,7 +313,7 @@ class ucrec : public classbase
};
chanrec* add_channel(userrec *user, const char* cn, const char* key, bool override);
-chanrec* del_channel(userrec *user, const char* cname, const char* reason, bool local);
+//chanrec* del_channel(userrec *user, const char* cname, const char* reason, bool local);
//void kick_channel(userrec *src,userrec *user, chanrec *Ptr, char* reason);
//void server_kick_channel(userrec* user, chanrec* Ptr, char* reason, bool triggerevents);
diff --git a/include/modules.h b/include/modules.h
index 25fb52077..39265fcee 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -1520,13 +1520,6 @@ class Server : public Extensible
*/
virtual chanrec* JoinUserToChannel(userrec* user, const std::string &cname, const std::string &key);
- /** Forces a user to part a channel.
- * This is similar to svspart and can be used to implement redirection, etc.
- * Although the return value of this function is a pointer to a channel record, the returned data is
- * undefined and should not be read or written to. This behaviour may be changed in a future version.
- */
- virtual chanrec* PartUserFromChannel(userrec* user, const std::string &cname, const std::string &reason);
-
/** Forces a user nickchange.
* This command works similarly to SVSNICK, and can be used to implement Q-lines etc.
* If you specify an invalid nickname, the nick change will be dropped and the target user will receive
diff --git a/src/channels.cpp b/src/channels.cpp
index 3f1d2ecb6..6d8cb756f 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -479,68 +479,50 @@ chanrec* ForceChan(chanrec* Ptr,ucrec *a,userrec* user, int created)
return Ptr;
}
-/*
- *remove a channel from a users record, and remove the record from memory
+/* chanrec::PartUser
+ * remove a channel from a users record, and remove the record from the hash
* if the channel has become empty
*/
-
-chanrec* del_channel(userrec *user, const char* cname, const char* reason, bool local)
+long chanrec::PartUser(userrec *user, const char* reason)
{
- if ((!user) || (!cname))
- {
- log(DEFAULT,"*** BUG *** del_channel was given an invalid parameter");
- return NULL;
- }
-
- chanrec* Ptr = FindChan(cname);
-
- if (!Ptr)
- return NULL;
-
- log(DEBUG,"del_channel: removing: %s %s",user->nick,Ptr->name);
+ if (!user)
+ return this->GetUserCounter();
for (unsigned int i =0; i < user->chans.size(); i++)
{
/* zap it from the channel list of the user */
- if (user->chans[i]->channel == Ptr)
+ if (user->chans[i]->channel == this)
{
if (reason)
{
- FOREACH_MOD(I_OnUserPart,OnUserPart(user,Ptr,reason));
- WriteChannel(Ptr,user,"PART %s :%s",Ptr->name, reason);
+ FOREACH_MOD(I_OnUserPart,OnUserPart(user, this, reason));
+ WriteChannel(this, user, "PART %s :%s", this->name, reason);
}
else
{
- FOREACH_MOD(I_OnUserPart,OnUserPart(user,Ptr,""));
- WriteChannel(Ptr,user,"PART :%s",Ptr->name);
+ FOREACH_MOD(I_OnUserPart,OnUserPart(user, this, ""));
+ WriteChannel(this, user, "PART :%s", this->name);
}
user->chans[i]->uc_modes = 0;
user->chans[i]->channel = NULL;
- log(DEBUG,"del_channel: unlinked: %s %s",user->nick,Ptr->name);
break;
}
}
- Ptr->DelUser(user);
-
- /* if there are no users left on the channel */
- if (!usercount(Ptr))
+ if (!this->DelUser(user)) /* if there are no users left on the channel... */
{
- chan_hash::iterator iter = chanlist.find(Ptr->name);
-
- log(DEBUG,"del_channel: destroying channel: %s",Ptr->name);
-
+ chan_hash::iterator iter = chanlist.find(this->name);
/* kill the record */
if (iter != chanlist.end())
{
- log(DEBUG,"del_channel: destroyed: %s",Ptr->name);
- FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(Ptr));
- DELETE(Ptr);
+ log(DEBUG,"del_channel: destroyed: %s", this->name);
+ FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(this));
chanlist.erase(iter);
}
+ return 0;
}
- return NULL;
+ return this->GetUserCounter();
}
long chanrec::ServerKickUser(userrec* user, const char* reason, bool triggerevents)
diff --git a/src/cmd_part.cpp b/src/cmd_part.cpp
index 39a962140..1b9680d5d 100644
--- a/src/cmd_part.cpp
+++ b/src/cmd_part.cpp
@@ -26,13 +26,17 @@ void cmd_part::Handle (const char** parameters, int pcnt, userrec *user)
{
if (ServerInstance->Parser->LoopCall(user, this, parameters, pcnt, 0))
return;
+
+ chanrec* c = FindChan(parameters[0]);
- if (pcnt > 1)
+ if (c)
{
- del_channel(user,parameters[0],parameters[1],false);
+ if (!c->PartUser(user, pcnt > 1 ? parameters[0] : NULL))
+ /* Arse, who stole our channel! :/ */
+ delete c;
}
else
{
- del_channel(user,parameters[0],NULL,false);
+ WriteServ(user->fd, "401 %s %s :No such channel", user->nick, parameters[0]);
}
}
diff --git a/src/modules.cpp b/src/modules.cpp
index f09c85d08..a171e427f 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -405,11 +405,6 @@ chanrec* Server::JoinUserToChannel(userrec* user, const std::string &cname, cons
return add_channel(user,cname.c_str(),key.c_str(),false);
}
-chanrec* Server::PartUserFromChannel(userrec* user, const std::string &cname, const std::string &reason)
-{
- return del_channel(user,cname.c_str(),reason.c_str(),false);
-}
-
chanuserlist Server::GetUsers(chanrec* chan)
{
chanuserlist userl;
diff --git a/src/modules/m_park.cpp b/src/modules/m_park.cpp
index 9fbae3529..31da8f033 100644
--- a/src/modules/m_park.cpp
+++ b/src/modules/m_park.cpp
@@ -163,9 +163,11 @@ class cmd_unpark : public command_t
// first part the user from all chans theyre on, so things dont get messy
for (std::vector<ucrec*>::iterator i = user->chans.begin(); i != user->chans.end(); i++)
{
- if (((ucrec*)(*i))->channel != NULL)
+ chanrec* chan = (*i)->channel;
+ if (chan != NULL)
{
- Srv->PartUserFromChannel(user,((ucrec*)(*i))->channel->name,"Unparking");
+ if (!chan->PartUser(user, "Unparking"))
+ delete chan;
}
}
// remove all their old modes
diff --git a/src/modules/m_remove.cpp b/src/modules/m_remove.cpp
index ab0f2dbaa..bab5ea11b 100644
--- a/src/modules/m_remove.cpp
+++ b/src/modules/m_remove.cpp
@@ -181,10 +181,12 @@ class RemoveBase
/* Build up the part reason string. */
reason << "Removed by " << user->nick << reasonparam;
-
- Srv->PartUserFromChannel(target, channel->name, reason.str());
+
WriteChannelWithServ(Srv->GetServerName().c_str(), channel, "NOTICE %s :%s removed %s from the channel", channel->name, user->nick, target->nick);
WriteServ(target->fd, "NOTICE %s :*** %s removed you from %s with the message: %s", target->nick, user->nick, channel->name, reasonparam.c_str());
+
+ if (!channel->PartUser(target, reason.str().c_str()))
+ delete channel;
}
else
{
diff --git a/src/modules/m_sapart.cpp b/src/modules/m_sapart.cpp
index f7620ec00..df44e4671 100644
--- a/src/modules/m_sapart.cpp
+++ b/src/modules/m_sapart.cpp
@@ -38,22 +38,18 @@ class cmd_sapart : public command_t
void Handle (const char** parameters, int pcnt, userrec *user)
{
- userrec* dest = Srv->FindNick(std::string(parameters[0]));
- if (dest)
+ userrec* dest = Srv->FindNick(parameters[0]);
+ chanrec* channel = Srv->FindChannel(parameters[1]);
+ if (dest && channel)
{
if (Srv->IsUlined(dest->server))
{
WriteServ(user->fd,"990 %s :Cannot use an SA command on a u-lined client",user->nick);
return;
}
- if (!IsValidChannelName(parameters[1]))
- {
- Srv->SendTo(NULL,user,"NOTICE "+std::string(user->nick)+" :*** Invalid characters in channel name");
- return;
- }
-
- Srv->SendOpers(std::string(user->nick)+" used SAPART to make "+std::string(dest->nick)+" part "+parameters[1]);
- Srv->PartUserFromChannel(dest,std::string(parameters[1]),std::string(dest->nick));
+ Srv->SendOpers(std::string(user->nick)+" used SAPART to make "+dest->nick+" part "+parameters[1]);
+ if (!channel->PartUser(dest, dest->nick))
+ delete channel;
}
}
};