switch (MASK)
{
case UCMODE_OP:
- d->chans[i].channel->AddOppedUser((char*)d);
+ d->chans[i].channel->AddOppedUser(d);
break;
case UCMODE_HOP:
- d->chans[i].channel->AddHalfoppedUser((char*)d);
+ d->chans[i].channel->AddHalfoppedUser(d);
break;
case UCMODE_VOICE:
- d->chans[i].channel->AddVoicedUser((char*)d);
+ d->chans[i].channel->AddVoicedUser(d);
break;
}
log(DEBUG,"grant: %s %s",d->chans[i].channel->name,d->nick);
switch (MASK)
{
case UCMODE_OP:
- d->chans[i].channel->DelOppedUser((char*)d);
+ d->chans[i].channel->DelOppedUser(d);
break;
case UCMODE_HOP:
- d->chans[i].channel->DelHalfoppedUser((char*)d);
+ d->chans[i].channel->DelHalfoppedUser(d);
break;
case UCMODE_VOICE:
- d->chans[i].channel->DelVoicedUser((char*)d);
+ d->chans[i].channel->DelVoicedUser(d);
break;
}
log(DEBUG,"revoke: %s %s",d->chans[i].channel->name,d->nick);
return NULL;
}
-// tidies up redundant modes, e.g. +nt-nt+i becomes +-+i,
-// a section further down the chain tidies up the +-+- crap.
+
+/** ModeParser::CompressModes()
+ * Tidies up redundant modes,
+ * e.g. +nt-nt+i becomes +-+i
+ * A section further down the chain tidies up the +-+- crap.
+ */
std::string ModeParser::CompressModes(std::string modes,bool channelmodes)
{
- int counts[127];
+ /*
+ * OK, iterate over the mode string and count how many times a certain mode appears in it.
+ * Then, erase all instances of any character that appears more than once.
+ * This only operates on modes with no parameters, you can still +v-v+v-v+v-v to your heart's content.
+ */
+
+ /* Do we really need an int here? Can you fit enough modes in a line to overflow a short? */
+ short counts[127];
bool active[127];
- memset(counts,0,sizeof(counts));
- memset(active,0,sizeof(active));
- for (unsigned int i = 0; i < modes.length(); i++)
+ memset(counts, 0, sizeof(counts));
+ memset(active, 0, sizeof(active));
+
+ for(unsigned char* i = (unsigned char*)modes.c_str(); *i; i++)
{
- if ((modes[i] == '+') || (modes[i] == '-'))
+ if((*i == '+') || (*i == '-'))
continue;
- if (channelmodes)
- {
- if ((strchr("itnmsp",modes[i])) || ((ModeDefined(modes[i],MT_CHANNEL)) && (ModeDefinedOn(modes[i],MT_CHANNEL)==0) && (ModeDefinedOff(modes[i],MT_CHANNEL)==0)))
- {
- log(DEBUG,"Tidy mode %c",modes[i]);
- counts[(unsigned int)modes[i]]++;
- active[(unsigned int)modes[i]] = true;
- }
- }
- else
+
+ if(!channelmodes || (channelmodes && (strchr("itnmsp", *i) || (ModeDefined(*i, MT_CHANNEL) && !ModeDefinedOn(*i,MT_CHANNEL) && !ModeDefinedOff(*i,MT_CHANNEL)))))
{
- log(DEBUG,"Tidy mode %c",modes[i]);
- counts[(unsigned int)modes[i]]++;
- active[(unsigned int)modes[i]] = true;
+ log(DEBUG,"Tidy mode %c", *i);
+ counts[*i]++;
+ active[*i] = true;
}
}
- for (int j = 65; j < 127; j++)
+
+ for(unsigned char j = 65; j < 127; j++)
{
if ((counts[j] > 1) && (active[j] == true))
{
- static char v[2];
- v[0] = (unsigned char)j;
- v[1] = '\0';
- std::string mode_str = v;
- std::string::size_type pos = modes.find(mode_str);
- if (pos != std::string::npos)
+ std::string::size_type pos;
+
+ while((pos = modes.find(j)) != std::string::npos)
{
- log(DEBUG,"all occurances of mode %c to be deleted...",(unsigned char)j);
- while (modes.find(mode_str) != std::string::npos)
- modes.erase(modes.find(mode_str),1);
- log(DEBUG,"New mode line: %s",modes.c_str());
+ log(DEBUG, "Deleting occurence of mode %c...", j);
+ modes.erase(pos, 1);
+ log(DEBUG,"New mode line: %s", modes.c_str());
}
}
}
+
return modes;
}
}
char outlist[MAXBUF];
+ char mlist[MAXBUF];
char *outpars[32];
int param = 2;
int pc = 0;
return;
}
- char* modelist = parameters[1]; /* mode list, e.g. +oo-o *
- * parameters[2] onwards are parameters for
- * modes that require them :) */
+ std::string tidied = this->CompressModes(parameters[1],true);
+ strlcpy(mlist,tidied.c_str(),MAXBUF);
+ char* modelist = mlist;
+
*outlist = *modelist;
char* outl = outlist+1;
log(DEBUG,"process_modes: modelist: %s",modelist);
- std::string tidied = this->CompressModes(modelist,true);
- strlcpy(modelist,tidied.c_str(),MAXBUF);
-
int len = tidied.length();
while (modelist[len-1] == ' ')
modelist[--len] = '\0';
default:
string_list p;
p.clear();
- bool x = strchr(chan->custom_modes,*modechar);
+ bool x = chan->custom_modes[*modechar-65];
if ((!x && !mdir) || (x && mdir))
{
if (!ModeIsListMode(*modechar,MT_CHANNEL))
}
else
{
- if (param < pcnt)
+ *outl++ = *modechar;
+ chan->SetCustomMode(*modechar,mdir);
+ // include parameters in output if mode has them
+ if ((ModeDefinedOn(*modechar,MT_CHANNEL)>0) && (mdir))
{
- *outl++ = *modechar;
- chan->SetCustomMode(*modechar,mdir);
- // include parameters in output if mode has them
- if ((ModeDefinedOn(*modechar,MT_CHANNEL)>0) && (mdir))
+ if (param < pcnt)
{
- chan->SetCustomModeParam(modelist[ptr],parameters[param],mdir);
+ chan->SetCustomModeParam(*modechar,parameters[param],mdir);
outpars[pc++] = parameters[param++];
}
}
if (pcnt == 1)
{
/* just /modes #channel */
- WriteServ(user->fd,"324 %s %s +%s",user->nick, Ptr->name, chanmodes(Ptr,has_channel(user,Ptr)));
+ WriteServ(user->fd,"324 %s %s +%s",user->nick, Ptr->name, chanmodes(Ptr,Ptr->HasUser(user)));
WriteServ(user->fd,"329 %s %s %d", user->nick, Ptr->name, Ptr->created);
return;
}
}
}
- if (((Ptr) && (!has_channel(user,Ptr))) && (!is_uline(user->server)) && (IS_LOCAL(user)))
+ if ((IS_LOCAL(user)) && (!is_uline(user->server)) && (!Ptr->HasUser(user)))
{
WriteServ(user->fd,"442 %s %s :You're not on that channel!",user->nick, Ptr->name);
return;
return;
if (MOD_RESULT == ACR_DEFAULT)
{
- if ((cstatus(user,Ptr) < STATUS_HOP) && (IS_LOCAL(user)))
+ if ((IS_LOCAL(user)) && (cstatus(user,Ptr) < STATUS_HOP))
{
WriteServ(user->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",user->nick, Ptr->name);
return;