diff options
-rw-r--r-- | include/channels.h | 11 | ||||
-rw-r--r-- | include/modules.h | 7 | ||||
-rw-r--r-- | src/channels.cpp | 50 | ||||
-rw-r--r-- | src/cmd_part.cpp | 10 | ||||
-rw-r--r-- | src/modules.cpp | 5 | ||||
-rw-r--r-- | src/modules/m_park.cpp | 6 | ||||
-rw-r--r-- | src/modules/m_remove.cpp | 6 | ||||
-rw-r--r-- | src/modules/m_sapart.cpp | 16 |
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; } } }; |