- break;
-
- default:
- string_list p;
- p.clear();
- bool x = chan->modes[*modechar-65];
- if ((!x && !mdir) || (x && mdir))
- {
- if (!ModeIsListMode(*modechar,MT_CHANNEL))
- {
- log(DEBUG,"Mode %c isnt set on %s but trying to remove!",*modechar,chan->name);
- break;
- }
- }
- if (ModeDefined(*modechar,MT_CHANNEL))
- {
- /* A module has claimed this mode */
- if (param<pcnt)
- {
- if ((ModeDefinedOn(*modechar,MT_CHANNEL)>0) && (mdir))
- {
- p.push_back(parameters[param]);
- }
- if ((ModeDefinedOff(*modechar,MT_CHANNEL)>0) && (!mdir))
- {
- p.push_back(parameters[param]);
- }
- }
- bool handled = false;
- if (param>=pcnt)
- {
- // we're supposed to have a parameter, but none was given... so dont handle the mode.
- if (((ModeDefinedOn(*modechar,MT_CHANNEL)>0) && (mdir)) || ((ModeDefinedOff(*modechar,MT_CHANNEL)>0) && (!mdir)))
- {
- log(DEBUG,"Not enough parameters for module-mode %c",*modechar);
- handled = true;
- param++;
- }
- }
- // BIG ASS IDIOTIC CODER WARNING!
- // Using OnRawMode on another modules mode's behavour
- // will confuse the crap out of admins! just because you CAN
- // do it, doesnt mean you SHOULD!
- MOD_RESULT = 0;
- std::string para = "";
- if (p.size())
- para = p[0];
-
- FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, *modechar, para, mdir, pcnt));
- if(!MOD_RESULT)
- {
- for (int i = 0; i <= MODCOUNT; i++)
- {
- if (!handled)
- {
- int t = modules[i]->OnExtendedMode(user,chan,*modechar,MT_CHANNEL,mdir,p);
- if (t != 0)
- {
- log(DEBUG,"OnExtendedMode returned nonzero for a module");
- if (ModeIsListMode(*modechar,MT_CHANNEL))
- {
- if (t == -1)
- {
- //pc++;
- param++;
- }
- else
- {
- if (param < pcnt)
- {
- *outl++ = *modechar;
- }
- outpars[pc++] = parameters[param++];
- }
- }
- else
- {
- *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(*modechar,parameters[param],mdir);
- outpars[pc++] = parameters[param++];
- }
- }
- }
- // break, because only one module can handle the mode.
- handled = true;
- }
- }
- }
- }
- }
- else
- {
- WriteServ(user->fd,"472 %s %c :is unknown mode char to me",user->nick,*modechar);
- }
- break;
- }
- }
-
- /* Null terminate it now we're done */
- *outl = 0;
-
-
- /************ Fast, but confusing string tidying ************/
- outl = outlist;
- while (*outl && (*outl < 'A'))
- outl++;
- /* outl now points to the first mode character after +'s and -'s */
- outl--;
- /* Now points at first mode-modifier + or - symbol */
- char* trim = outl;
- /* Now we tidy off any trailing -'s etc */
- while (*trim++);
- trim--;
- while ((*--trim == '+') || (*trim == '-'))
- *trim = 0;
- /************ Done wih the string tidy functions ************/
-
-
- /* The mode change must be at least two characters long (+ or - and at least one mode) */
- if (((*outl == '+') || (*outl == '-')) && *(outl+1))
- {
- for (ptr = 0; ptr < pc; ptr++)
- {
- charlcat(outl,' ',MAXBUF);
- strlcat(outl,outpars[ptr],MAXBUF-1);
- }
- if (local)
- {
- log(DEBUG,"Local mode change");
- WriteChannelLocal(chan, user, "MODE %s %s",chan->name,outl);
- FOREACH_MOD(I_OnMode,OnMode(user, chan, TYPE_CHANNEL, outl));
- }
- else
- {
- if (servermode)
- {
- if (!silent)
- {
- WriteChannelWithServ(Config->ServerName,chan,"MODE %s %s",chan->name,outl);
- }
-