}
Channel::Channel(const std::string &cname, time_t ts)
+ : name(cname), age(ts), topicset(0)
{
if (!ServerInstance->chanlist->insert(std::make_pair(cname, this)).second)
throw CoreException("Cannot create duplicate channel " + cname);
-
- this->name = cname;
- this->age = ts ? ts : ServerInstance->Time();
-
- topicset = 0;
- modes.reset();
}
void Channel::SetMode(ModeHandler* mh, bool on)
ModeHandler* mode = ServerInstance->Modes->FindMode(*n, MODETYPE_CHANNEL);
if (mode)
{
+ if (mode->IsPrefixMode())
+ continue;
+
if (mode->GetNumParams(true))
list.GetToken(parameter);
else
{
if (user->chans.size() >= ServerInstance->Config->OperMaxChans)
{
- user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s %s :You are on too many channels",user->nick.c_str(), cname.c_str());
+ user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s :You are on too many channels", cname.c_str());
return NULL;
}
}
maxchans = ServerInstance->Config->MaxChans;
if (user->chans.size() >= maxchans)
{
- user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s %s :You are on too many channels",user->nick.c_str(), cname.c_str());
+ user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s :You are on too many channels", cname.c_str());
return NULL;
}
}
if (!chan)
{
- privs = "o";
+ privs = ServerInstance->Config->DefaultModes.substr(0, ServerInstance->Config->DefaultModes.find(' '));
if (override == false)
{
if (!MOD_RESULT.check((ckey == key) || can_bypass))
{
// 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 %s :Cannot join channel (Incorrect channel key)",user->nick.c_str(), chan->name.c_str());
+ user->WriteNumeric(ERR_BADCHANNELKEY, "%s :Cannot join channel (Incorrect channel key)", chan->name.c_str());
return NULL;
}
}
FIRST_MOD_RESULT(OnCheckInvite, MOD_RESULT, (user, chan));
if (!MOD_RESULT.check(invited))
{
- user->WriteNumeric(ERR_INVITEONLYCHAN, "%s %s :Cannot join channel (Invite only)",user->nick.c_str(), chan->name.c_str());
+ user->WriteNumeric(ERR_INVITEONLYCHAN, "%s :Cannot join channel (Invite only)", chan->name.c_str());
return NULL;
}
}
FIRST_MOD_RESULT(OnCheckLimit, MOD_RESULT, (user, chan));
if (!MOD_RESULT.check((chan->GetUserCounter() < atol(limit.c_str()) || can_bypass)))
{
- user->WriteNumeric(ERR_CHANNELISFULL, "%s %s :Cannot join channel (Channel is full)",user->nick.c_str(), chan->name.c_str());
+ user->WriteNumeric(ERR_CHANNELISFULL, "%s :Cannot join channel (Channel is full)", chan->name.c_str());
return NULL;
}
}
if (chan->IsBanned(user) && !can_bypass)
{
- user->WriteNumeric(ERR_BANNEDFROMCHAN, "%s %s :Cannot join channel (You're banned)",user->nick.c_str(), chan->name.c_str());
+ user->WriteNumeric(ERR_BANNEDFROMCHAN, "%s :Cannot join channel (You're banned)", chan->name.c_str());
return NULL;
}
if (!memb)
return; // Already on the channel
- user->chans.insert(this);
+ user->chans.push_front(memb);
if (privs)
{
// If the user was granted prefix modes (in the OnUserPreJoin hook, or he's a
// remote user and his own server set the modes), then set them internally now
- memb->modes = *privs;
for (std::string::const_iterator i = privs->begin(); i != privs->end(); ++i)
{
- ModeHandler* mh = ServerInstance->Modes->FindMode(*i, MODETYPE_CHANNEL);
+ PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(*i);
if (mh)
{
std::string nick = user->nick;
- /* Set, and make sure that the mode handler knows this mode was now set */
- this->SetPrefix(user, mh->GetModeChar(), true);
- mh->OnModeChange(ServerInstance->FakeClient, ServerInstance->FakeClient, this, nick, true);
+ // Set the mode on the user
+ mh->OnModeChange(ServerInstance->FakeClient, NULL, this, nick, true);
}
}
}
{
if (this->topicset)
{
- user->WriteNumeric(RPL_TOPIC, "%s %s :%s", user->nick.c_str(), this->name.c_str(), this->topic.c_str());
- user->WriteNumeric(RPL_TOPICTIME, "%s %s %s %lu", user->nick.c_str(), this->name.c_str(), this->setby.c_str(), (unsigned long)this->topicset);
+ user->WriteNumeric(RPL_TOPIC, "%s :%s", this->name.c_str(), this->topic.c_str());
+ user->WriteNumeric(RPL_TOPICTIME, "%s %s %lu", this->name.c_str(), this->setby.c_str(), (unsigned long)this->topicset);
}
this->UserList(user);
}
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(this);
+ user->chans.erase(memb);
// Remove the Membership from this channel's userlist and destroy it
this->DelUser(membiter);
}
if (!memb)
{
- src->WriteNumeric(ERR_USERNOTINCHANNEL, "%s %s %s :They are not on that channel",src->nick.c_str(), victim->nick.c_str(), this->name.c_str());
+ src->WriteNumeric(ERR_USERNOTINCHANNEL, "%s %s :They are not on that channel", victim->nick.c_str(), this->name.c_str());
return;
}
if (them < req)
{
- src->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must be a channel %soperator",
- src->nick.c_str(), this->name.c_str(), req > HALFOP_VALUE ? "" : "half-");
+ src->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s :You must be a channel %soperator",
+ this->name.c_str(), req > HALFOP_VALUE ? "" : "half-");
return;
}
}
WriteAllExcept(src, false, 0, except_list, "KICK %s %s :%s", name.c_str(), victim->nick.c_str(), reason.c_str());
- victim->chans.erase(this);
+ victim->chans.erase(memb);
this->DelUser(victimiter);
}
unsigned int minrank = 0;
if (status)
{
- ModeHandler* mh = ServerInstance->Modes->FindPrefix(status);
+ PrefixMode* mh = ServerInstance->Modes->FindPrefix(status);
if (mh)
minrank = mh->GetPrefixRank();
}
*/
void Channel::UserList(User *user)
{
- if (this->IsModeSet(secretmode) && !this->HasUser(user) && !user->HasPrivPermission("channels/auspex"))
+ bool has_privs = user->HasPrivPermission("channels/auspex");
+ if (this->IsModeSet(secretmode) && !this->HasUser(user) && !has_privs)
{
- user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(), this->name.c_str());
+ user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", this->name.c_str());
return;
}
- std::string list = user->nick;
- list.push_back(' ');
+ std::string list;
list.push_back(this->IsModeSet(secretmode) ? '@' : this->IsModeSet(privatemode) ? '*' : '=');
list.push_back(' ');
list.append(this->name).append(" :");
std::string nick;
for (UserMembIter i = userlist.begin(); i != userlist.end(); ++i)
{
- if (i->first->quitting)
- continue;
- if ((!has_user) && (i->first->IsModeSet(invisiblemode)))
+ if ((!has_user) && (i->first->IsModeSet(invisiblemode)) && (!has_privs))
{
/*
* user is +i, and source not on the channel, does not show
user->WriteNumeric(RPL_NAMREPLY, list);
}
- user->WriteNumeric(RPL_ENDOFNAMES, "%s %s :End of /NAMES list.", user->nick.c_str(), this->name.c_str());
+ user->WriteNumeric(RPL_ENDOFNAMES, "%s :End of /NAMES list.", this->name.c_str());
}
/* returns the status character for a given user on a channel, e.g. @ for op,
{
for(unsigned int i=0; i < m->second->modes.length(); i++)
{
- char mchar = m->second->modes[i];
- ModeHandler* mh = ServerInstance->Modes->FindMode(mchar, MODETYPE_CHANNEL);
+ PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(m->second->modes[i]);
if (mh && mh->GetPrefixRank() > bestrank && mh->GetPrefix())
{
bestrank = mh->GetPrefixRank();
unsigned int rv = 0;
if (mchar)
{
- ModeHandler* mh = ServerInstance->Modes->FindMode(mchar, MODETYPE_CHANNEL);
+ PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(mchar);
if (mh)
rv = mh->GetPrefixRank();
}
{
for(unsigned int i=0; i < m->second->modes.length(); i++)
{
- char mchar = m->second->modes[i];
- ModeHandler* mh = ServerInstance->Modes->FindMode(mchar, MODETYPE_CHANNEL);
+ PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(m->second->modes[i]);
if (mh && mh->GetPrefix())
prefix[ctr++] = mh->GetPrefix();
}
return m->second->getRank();
}
-bool Channel::SetPrefix(User* user, char prefix, bool adding)
+bool Membership::SetPrefix(PrefixMode* delta_mh, bool adding)
{
- ModeHandler* delta_mh = ServerInstance->Modes->FindMode(prefix, MODETYPE_CHANNEL);
- if (!delta_mh)
- return false;
- UserMembIter m = userlist.find(user);
- if (m == userlist.end())
- return false;
- for(unsigned int i=0; i < m->second->modes.length(); i++)
+ char prefix = delta_mh->GetModeChar();
+ for (unsigned int i = 0; i < modes.length(); i++)
{
- char mchar = m->second->modes[i];
- ModeHandler* mh = ServerInstance->Modes->FindMode(mchar, MODETYPE_CHANNEL);
+ char mchar = modes[i];
+ PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(mchar);
if (mh && mh->GetPrefixRank() <= delta_mh->GetPrefixRank())
{
- m->second->modes =
- m->second->modes.substr(0,i) +
+ modes = modes.substr(0,i) +
(adding ? std::string(1, prefix) : "") +
- m->second->modes.substr(mchar == prefix ? i+1 : i);
+ modes.substr(mchar == prefix ? i+1 : i);
return adding != (mchar == prefix);
}
}
if (adding)
- m->second->modes += std::string(1, prefix);
+ modes.push_back(prefix);
return adding;
}
else
{
inv = new Invitation(c, u, timeout);
- c->invites.push_back(inv);
- u->invites.push_back(inv);
+ c->invites.push_front(inv);
+ u->invites.push_front(inv);
ServerInstance->Logs->Log("INVITATION", LOG_DEBUG, "Invitation::Create created new invitation %p", (void*) inv);
}
}
if (!u || u->invites.empty())
return NULL;
- InviteList locallist;
- locallist.swap(u->invites);
-
Invitation* result = NULL;
- for (InviteList::iterator i = locallist.begin(); i != locallist.end(); )
+ for (InviteList::iterator i = u->invites.begin(); i != u->invites.end(); )
{
Invitation* inv = *i;
+ ++i;
+
if ((check_expired) && (inv->expiry != 0) && (inv->expiry <= ServerInstance->Time()))
{
/* Expired invite, remove it. */
- std::string expiration = ServerInstance->TimeString(inv->expiry);
+ std::string expiration = InspIRCd::TimeString(inv->expiry);
ServerInstance->Logs->Log("INVITATION", LOG_DEBUG, "Invitation::Find ecountered expired entry: %p expired %s", (void*) inv, expiration.c_str());
- i = locallist.erase(i);
- inv->cull();
delete inv;
}
else
result = inv;
break;
}
- ++i;
}
}
- locallist.swap(u->invites);
ServerInstance->Logs->Log("INVITATION", LOG_DEBUG, "Invitation::Find result=%p", (void*) result);
return result;
}
Invitation::~Invitation()
{
// Remove this entry from both lists
- InviteList::iterator it = std::find(chan->invites.begin(), chan->invites.end(), this);
- if (it != chan->invites.end())
- chan->invites.erase(it);
- it = std::find(user->invites.begin(), user->invites.end(), this);
- if (it != user->invites.end())
- user->invites.erase(it);
-}
-
-void InviteBase::ClearInvites()
-{
- ServerInstance->Logs->Log("INVITEBASE", LOG_DEBUG, "InviteBase::ClearInvites %p", (void*) this);
- InviteList locallist;
- locallist.swap(invites);
- for (InviteList::const_iterator i = locallist.begin(); i != locallist.end(); ++i)
- {
- (*i)->cull();
- delete *i;
- }
+ chan->invites.erase(this);
+ user->invites.erase(this);
+ ServerInstance->Logs->Log("INVITEBASE", LOG_DEBUG, "Invitation::~ %p", (void*) this);
}