modes.reset();
}
-void Channel::SetMode(char mode,bool mode_on)
-{
- modes[mode-65] = mode_on;
-}
-
void Channel::SetMode(ModeHandler* mh, bool on)
{
modes[mh->GetModeChar() - 65] = on;
void Channel::SetModeParam(char mode, const std::string& parameter)
{
- CustomModeList::iterator n = custom_mode_params.find(mode);
- // always erase, even if changing, so that the map gets the new value
- if (n != custom_mode_params.end())
- custom_mode_params.erase(n);
if (parameter.empty())
{
+ custom_mode_params.erase(mode);
modes[mode-65] = false;
}
else
return "";
}
-int Channel::SetTopic(User *u, std::string &ntopic, bool forceset)
+void Channel::SetTopic(User* u, const std::string& ntopic)
{
- if (IS_LOCAL(u) && !forceset)
- {
- ModResult res;
- FIRST_MOD_RESULT(OnPreTopicChange, res, (u,this,ntopic));
-
- if (res == MOD_RES_DENY)
- return CMD_FAILURE;
- if (res != MOD_RES_ALLOW)
- {
- 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 (IsModeSet('t') && !ServerInstance->OnCheckExemption(u,this,"topiclock").check(GetPrefixValue(u) >= HALFOP_VALUE))
- {
- u->WriteNumeric(482, "%s %s :You do not have access 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->WriteChannel(u, "TOPIC %s :%s", this->name.c_str(), this->topic.c_str());
this->topicset = ServerInstance->Time();
FOREACH_MOD(I_OnPostTopicChange,OnPostTopicChange(u, this, this->topic));
-
- return CMD_SUCCESS;
}
Membership* Channel::AddUser(User* user)
void Channel::ForceJoin(User* user, const std::string* privs, bool bursting, bool created_by_local)
{
- Membership* memb = this->AddUser(user);
- if (!memb)
- return; // Already on the channel
-
if (IS_SERVER(user))
{
ServerInstance->Logs->Log("CHANNELS", LOG_DEBUG, "Attempted to join server user " + user->uuid + " to channel " + this->name);
return;
}
+ Membership* memb = this->AddUser(user);
+ if (!memb)
+ return; // Already on the channel
+
user->chans.insert(this);
if (privs)
this->WriteAllExcept(user, serversource, status, except_list, std::string(text));
}
-/*
- * return a count of the users on a specific channel accounting for
- * invisible users who won't increase the count. e.g. for /LIST
- */
-int Channel::CountInvisible()
-{
- int count = 0;
- for (UserMembIter i = userlist.begin(); i != userlist.end(); i++)
- {
- if (!i->first->quitting && !i->first->IsModeSet('i'))
- count++;
- }
-
- return count;
-}
-
const char* Channel::ChanModes(bool showkey)
{
static std::string scratch;
*/
void Channel::UserList(User *user)
{
- char list[MAXBUF];
- size_t dlen, curlen;
-
- if (!IS_LOCAL(user))
- return;
-
if (this->IsModeSet('s') && !this->HasUser(user) && !user->HasPrivPermission("channels/auspex"))
{
user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(), this->name.c_str());
return;
}
- dlen = curlen = snprintf(list,MAXBUF,"%s %c %s :", user->nick.c_str(), this->IsModeSet('s') ? '@' : this->IsModeSet('p') ? '*' : '=', this->name.c_str());
+ std::string list = user->nick;
+ list.push_back(' ');
+ list.push_back(this->IsModeSet('s') ? '@' : this->IsModeSet('p') ? '*' : '=');
+ list.push_back(' ');
+ list.append(this->name).append(" :");
+ std::string::size_type pos = list.size();
- int numusers = 0;
- char* ptr = list + dlen;
+ bool has_one = false;
/* Improvement by Brain - this doesnt change in value, so why was it inside
* the loop?
*/
bool has_user = this->HasUser(user);
- for (UserMembIter i = userlist.begin(); i != userlist.end(); i++)
+ std::string prefixlist;
+ std::string nick;
+ for (UserMembIter i = userlist.begin(); i != userlist.end(); ++i)
{
if (i->first->quitting)
continue;
continue;
}
- std::string prefixlist = this->GetPrefixChar(i->first);
- std::string nick = i->first->nick;
+ prefixlist = this->GetPrefixChar(i->first);
+ nick = i->first->nick;
FOREACH_MOD(I_OnNamesListItem, OnNamesListItem(user, i->second, prefixlist, nick));
if (nick.empty())
continue;
- size_t ptrlen = 0;
-
- if (curlen + prefixlist.length() + nick.length() + 1 > 480)
+ if (list.size() + prefixlist.length() + nick.length() + 1 > 480)
{
/* list overflowed into multiple numerics */
- user->WriteNumeric(RPL_NAMREPLY, std::string(list));
+ user->WriteNumeric(RPL_NAMREPLY, list);
- /* reset our lengths */
- dlen = curlen = snprintf(list,MAXBUF,"%s %c %s :", user->nick.c_str(), this->IsModeSet('s') ? '@' : this->IsModeSet('p') ? '*' : '=', this->name.c_str());
- ptr = list + dlen;
-
- numusers = 0;
+ // Erase all nicks, keep the constant part
+ list.erase(pos);
+ has_one = false;
}
- ptrlen = snprintf(ptr, MAXBUF, "%s%s ", prefixlist.c_str(), nick.c_str());
-
- curlen += ptrlen;
- ptr += ptrlen;
+ list.append(prefixlist).append(nick).push_back(' ');
- numusers++;
+ has_one = true;
}
/* if whats left in the list isnt empty, send it */
- if (numusers)
+ if (has_one)
{
- user->WriteNumeric(RPL_NAMREPLY, std::string(list));
+ user->WriteNumeric(RPL_NAMREPLY, list);
}
user->WriteNumeric(RPL_ENDOFNAMES, "%s %s :End of /NAMES list.", user->nick.c_str(), this->name.c_str());
return adding;
}
-void Channel::RemoveAllPrefixes(User* user)
-{
- UserMembIter m = userlist.find(user);
- if (m != userlist.end())
- {
- m->second->modes.clear();
- }
-}
-
void Invitation::Create(Channel* c, LocalUser* u, time_t timeout)
{
if ((timeout != 0) && (ServerInstance->Time() >= timeout))