modes[mh->GetId()] = on;
}
-void Channel::SetTopic(User* u, const std::string& ntopic)
+void Channel::SetTopic(User* u, const std::string& ntopic, time_t topicts, const std::string* setter)
{
- this->topic.assign(ntopic, 0, ServerInstance->Config->Limits.MaxTopic);
- this->setby.assign(ServerInstance->Config->FullHostInTopic ? u->GetFullHost() : u->nick, 0, 128);
- this->WriteChannel(u, "TOPIC %s :%s", this->name.c_str(), this->topic.c_str());
- this->topicset = ServerInstance->Time();
+ // Send a TOPIC message to the channel only if the new topic text differs
+ if (this->topic != ntopic)
+ {
+ this->topic = ntopic;
+ this->WriteChannel(u, "TOPIC %s :%s", this->name.c_str(), this->topic.c_str());
+ }
+
+ // Always update setter and set time
+ if (!setter)
+ setter = ServerInstance->Config->FullHostInTopic ? &u->GetFullHost() : &u->nick;
+ this->setby.assign(*setter, 0, 128);
+ this->topicset = topicts;
FOREACH_MOD(OnPostTopicChange, (u, this, this->topic));
}
}
if (user->chans.size() >= maxchans)
{
- user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s :You are on too many channels", cname.c_str());
+ user->WriteNumeric(ERR_TOOMANYCHANNELS, cname, "You are on too many channels");
return NULL;
}
}
if (!MOD_RESULT.check(InspIRCd::TimingSafeCompare(ckey, key)))
{
// If no key provided, or key is not the right one, and can't bypass +k (not invited or option not enabled)
- user->WriteNumeric(ERR_BADCHANNELKEY, "%s :Cannot join channel (Incorrect channel key)", chan->name.c_str());
+ user->WriteNumeric(ERR_BADCHANNELKEY, chan->name, "Cannot join channel (Incorrect channel key)");
return NULL;
}
}
FIRST_MOD_RESULT(OnCheckInvite, MOD_RESULT, (user, chan));
if (MOD_RESULT != MOD_RES_ALLOW)
{
- user->WriteNumeric(ERR_INVITEONLYCHAN, "%s :Cannot join channel (Invite only)", chan->name.c_str());
+ user->WriteNumeric(ERR_INVITEONLYCHAN, chan->name, "Cannot join channel (Invite only)");
return NULL;
}
}
FIRST_MOD_RESULT(OnCheckLimit, MOD_RESULT, (user, chan));
if (!MOD_RESULT.check((chan->GetUserCounter() < atol(limit.c_str()))))
{
- user->WriteNumeric(ERR_CHANNELISFULL, "%s :Cannot join channel (Channel is full)", chan->name.c_str());
+ user->WriteNumeric(ERR_CHANNELISFULL, chan->name, "Cannot join channel (Channel is full)");
return NULL;
}
}
if (chan->IsBanned(user))
{
- user->WriteNumeric(ERR_BANNEDFROMCHAN, "%s :Cannot join channel (You're banned)", chan->name.c_str());
+ user->WriteNumeric(ERR_BANNEDFROMCHAN, chan->name, "Cannot join channel (You're banned)");
return NULL;
}
}
* Remove a channel from a users record, remove the reference to the Membership object
* from the channel and destroy it.
*/
-void Channel::PartUser(User *user, std::string &reason)
+bool Channel::PartUser(User* user, std::string& reason)
{
MemberMap::iterator membiter = userlist.find(user);
- if (membiter != userlist.end())
- {
- Membership* memb = membiter->second;
- CUList except_list;
- FOREACH_MOD(OnUserPart, (memb, reason, except_list));
+ if (membiter == userlist.end())
+ return false;
- WriteAllExcept(user, false, 0, except_list, "PART %s%s%s", this->name.c_str(), reason.empty() ? "" : " :", reason.c_str());
+ Membership* memb = membiter->second;
+ CUList except_list;
+ FOREACH_MOD(OnUserPart, (memb, reason, except_list));
- // Remove this channel from the user's chanlist
- user->chans.erase(memb);
- // Remove the Membership from this channel's userlist and destroy it
- this->DelUser(membiter);
- }
+ WriteAllExcept(user, false, 0, except_list, "PART %s%s%s", this->name.c_str(), reason.empty() ? "" : " :", reason.c_str());
+
+ // Remove this channel from the user's chanlist
+ user->chans.erase(memb);
+ // Remove the Membership from this channel's userlist and destroy it
+ this->DelUser(membiter);
+
+ return true;
}
void Channel::KickUser(User* src, const MemberMap::iterator& victimiter, const std::string& reason)
return scratch.c_str();
}
+void Channel::WriteNotice(const std::string& text)
+{
+ std::string rawmsg = "NOTICE ";
+ rawmsg.append(this->name).append(" :").append(text);
+ WriteChannelWithServ(ServerInstance->Config->ServerName, rawmsg);
+}
+
/* returns the status character for a given user on a channel, e.g. @ for op,
* % for halfop etc. If the user has several modes set, the highest mode
* the user has must be returned.