X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fchannels.cpp;h=4d32f671905bfd570e1c965f34b8f5354b545b00;hb=9ebc0997ccd8c6eea8742d0f9c59b9e3f78c85fc;hp=8628148cf7d3d89ebf0ded664c1194b13e519f3a;hpb=ca781714c1651a9e7042eb930c6b117449f8e1fc;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/channels.cpp b/src/channels.cpp index 8628148cf..4d32f6719 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -11,7 +11,7 @@ * --------------------------------------------------- */ -/* $Core: libIRCDchannels */ +/* $Core */ #include "inspircd.h" #include @@ -29,8 +29,7 @@ Channel::Channel(InspIRCd* Instance, const std::string &cname, time_t ts) : Serv this->created = ts ? ts : ServerInstance->Time(); this->age = this->created; - - maxbans = topicset = limit = 0; + maxbans = topicset = 0; modes.reset(); } @@ -68,19 +67,52 @@ bool Channel::IsModeSet(char mode) std::string Channel::GetModeParameter(char mode) { - switch (mode) + CustomModeList::iterator n = custom_mode_params.find(mode); + if (n != custom_mode_params.end()) + return n->second; + return ""; +} + +int Channel::SetTopic(User *u, std::string &ntopic, bool forceset) +{ + if (IS_LOCAL(u)) { - case 'k': - return this->key; - case 'l': - return ConvToStr(this->limit); - default: - CustomModeList::iterator n = custom_mode_params.find(mode); - if (n != custom_mode_params.end()) - return n->second; - return ""; - break; + if(!forceset) + { + int MOD_RESULT = 0; + /* 0: check status, 1: don't, -1: disallow change silently */ + + FOREACH_RESULT(I_OnLocalTopicChange,OnLocalTopicChange(u,this,ntopic)); + + if (MOD_RESULT == 1) + return CMD_FAILURE; + else if (MOD_RESULT == 0) + { + if (!this->HasUser(u)) + { + u->WriteNumeric(442, "%s %s :You're not on that channel!",u->nick.c_str(), this->name.c_str()); + return CMD_FAILURE; + } + if ((this->IsModeSet('t')) && (this->GetStatus(u) < STATUS_HOP)) + { + u->WriteNumeric(482, "%s %s :You must be at least a half-operator to change the topic on this channel", u->nick.c_str(), this->name.c_str()); + return CMD_FAILURE; + } + } + } + } + + this->topic.assign(ntopic, 0, ServerInstance->Config->Limits.MaxTopic); + this->setby.assign(ServerInstance->Config->FullHostInTopic ? u->GetFullHost() : u->nick, 0, 128); + this->topicset = ServerInstance->Time(); + this->WriteChannel(u, "TOPIC %s :%s", this->name.c_str(), this->topic.c_str()); + + if (IS_LOCAL(u)) + { + FOREACH_MOD(I_OnPostLocalTopicChange,OnPostLocalTopicChange(u, this, this->topic)); } + + return CMD_SUCCESS; } long Channel::GetUserCounter() @@ -225,9 +257,10 @@ Channel* Channel::JoinUser(InspIRCd* Instance, User *user, const char* cn, bool */ if (IS_LOCAL(user) && !override) { - if (user->GetMaxChans()) + // Checking MyClass exists because we *may* get here with NULL, not 100% sure. + if (user->MyClass && user->MyClass->GetMaxChans()) { - if (user->chans.size() >= user->GetMaxChans()) + if (user->chans.size() >= user->MyClass->GetMaxChans()) { user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s %s :You are on too many channels",user->nick.c_str(), cn); return NULL; @@ -302,13 +335,14 @@ Channel* Channel::JoinUser(InspIRCd* Instance, User *user, const char* cn, bool } else if (MOD_RESULT == 0) { - if (!Ptr->key.empty()) + std::string ckey = Ptr->GetModeParameter('k'); + if (!ckey.empty()) { MOD_RESULT = 0; - FOREACH_RESULT_I(Instance,I_OnCheckKey,OnCheckKey(user, Ptr, key ? key : "")); + FOREACH_RESULT_I(Instance, I_OnCheckKey, OnCheckKey(user, Ptr, key ? key : "")); if (!MOD_RESULT) { - if ((!key) || Ptr->key == key) + if ((!key) || ckey != key) { user->WriteNumeric(ERR_BADCHANNELKEY, "%s %s :Cannot join channel (Incorrect channel key)",user->nick.c_str(), Ptr->name.c_str()); return NULL; @@ -329,19 +363,23 @@ Channel* Channel::JoinUser(InspIRCd* Instance, User *user, const char* cn, bool } user->RemoveInvite(Ptr->name.c_str()); } - if (Ptr->limit) + + std::string limit = Ptr->GetModeParameter('l'); + if (!limit.empty()) { MOD_RESULT = 0; - FOREACH_RESULT_I(Instance,I_OnCheckLimit,OnCheckLimit(user, Ptr)); + FOREACH_RESULT_I(Instance, I_OnCheckLimit, OnCheckLimit(user, Ptr)); if (!MOD_RESULT) { - if (Ptr->GetUserCounter() >= Ptr->limit) + long llimit = atol(limit.c_str()); + if (Ptr->GetUserCounter() >= llimit) { user->WriteNumeric(ERR_CHANNELISFULL, "%s %s :Cannot join channel (Channel is full)",user->nick.c_str(), Ptr->name.c_str()); return NULL; } } } + if (Ptr->bans.size()) { if (Ptr->IsBanned(user)) @@ -362,7 +400,7 @@ Channel* Channel::JoinUser(InspIRCd* Instance, User *user, const char* cn, bool } Channel* Channel::ForceChan(InspIRCd* Instance, Channel* Ptr, User* user, const std::string &privs, bool bursting) -{ +{ std::string nick = user->nick; bool silent = false; @@ -845,11 +883,16 @@ char* Channel::ChanModes(bool showkey) switch (n) { case CM_KEY: - extparam = (showkey ? this->key : ""); - break; - case CM_LIMIT: - extparam = ConvToStr(this->limit); - break; + // Unfortunately this must be special-cased, as we definitely don't want to always display key. + if (showkey) + { + extparam = this->GetModeParameter('k'); + } + else + { + extparam = ""; + } + break; case CM_NOEXTERNAL: case CM_TOPICLOCK: case CM_INVITEONLY: