diff options
-rw-r--r-- | include/modules.h | 22 | ||||
-rw-r--r-- | src/InspIRCd.layout | 40 | ||||
-rw-r--r-- | src/inspircd.cpp | 186 | ||||
-rw-r--r-- | src/modules.cpp | 4 | ||||
-rw-r--r-- | src/modules/m_testcommand.cpp | 24 |
5 files changed, 252 insertions, 24 deletions
diff --git a/include/modules.h b/include/modules.h index b26554d56..82f6e6466 100644 --- a/include/modules.h +++ b/include/modules.h @@ -36,6 +36,7 @@ typedef file_cache string_list; #define FOREACH_MOD for (int i = 0; i <= MODCOUNT; i++) modules[i]-> extern void createcommand(char* cmd, handlerfunc f, char flags, int minparams); +extern void server_mode(char **parameters, int pcnt, userrec *user); // class Version holds the version information of a Module, returned // by Module::GetVersion (thanks RD) @@ -151,7 +152,8 @@ class Module : public classbase * If the mode is not a channel mode, chanrec* chan is null, and should not be read from or written to. */ virtual bool OnExtendedMode(userrec* user, chanrec* chan, char modechar, int type, bool mode_on, string_list ¶ms); - + + }; @@ -291,6 +293,24 @@ class Server : public classbase */ virtual void AddCommand(char* cmd, handlerfunc f, char flags, int minparams); + /** Sends a servermode. + * you must format the parameters array with the target, modes and parameters for those modes. + * + * For example: + * + * char modes[3][MAXBUF]; + * modes[0] = ChannelName; + * modes[1] = "+o"; + * modes[2] = user->nick; + * Srv->SendMode(modes,3,user); + * + * The modes will originate from the server where the command was issued, however responses (e.g. numerics) + * will be sent to the user you provide as the third parameter. + * You must be sure to get the number of parameters correct in the pcnt parameter otherwise you could leave + * your server in an unstable state! + */ + + virtual void SendMode(char **parameters, int pcnt, userrec *user); }; /** Allows reading of values from configuration files diff --git a/src/InspIRCd.layout b/src/InspIRCd.layout index ced5aa688..fd2b099c3 100644 --- a/src/InspIRCd.layout +++ b/src/InspIRCd.layout @@ -1,5 +1,5 @@ [Editors] -Focused=-1 +Focused=1 Order=1,7,3,2,0,6,5,4,25,24,-1 [Editor_0] @@ -12,10 +12,10 @@ LeftChar=1 [Editor_1] Open=1 -Top=0 -CursorCol=1 -CursorRow=4004 -TopLine=3977 +Top=1 +CursorCol=34 +CursorRow=456 +TopLine=404 LeftChar=1 [Editor_2] @@ -37,8 +37,8 @@ LeftChar=1 [Editor_4] Open=1 Top=0 -CursorCol=5 -CursorRow=47 +CursorCol=14 +CursorRow=128 TopLine=77 LeftChar=1 @@ -75,7 +75,7 @@ TopLine=38 LeftChar=1 [Editor_9] -Open=0 +Open=1 Top=0 CursorCol=1 CursorRow=1 @@ -83,7 +83,7 @@ TopLine=1 LeftChar=1 [Editor_10] -Open=0 +Open=1 Top=0 CursorCol=1 CursorRow=1 @@ -123,7 +123,7 @@ TopLine=1 LeftChar=1 [Editor_15] -Open=0 +Open=1 Top=0 CursorCol=1 CursorRow=1 @@ -131,7 +131,7 @@ TopLine=1 LeftChar=1 [Editor_16] -Open=0 +Open=1 Top=0 CursorCol=21 CursorRow=22 @@ -139,7 +139,7 @@ TopLine=1 LeftChar=1 [Editor_17] -Open=0 +Open=1 Top=0 CursorCol=1 CursorRow=1 @@ -147,7 +147,7 @@ TopLine=1 LeftChar=1 [Editor_18] -Open=0 +Open=1 Top=0 CursorCol=1 CursorRow=1 @@ -155,7 +155,7 @@ TopLine=1 LeftChar=1 [Editor_19] -Open=0 +Open=1 Top=0 CursorCol=1 CursorRow=1 @@ -165,9 +165,9 @@ LeftChar=1 [Editor_20] Open=1 Top=0 -CursorCol=8 -CursorRow=38 -TopLine=30 +CursorCol=1 +CursorRow=314 +TopLine=285 LeftChar=1 [Editor_21] @@ -210,8 +210,8 @@ TopLine=1 LeftChar=1 [Editor_26] Open=1 -Top=1 -CursorCol=47 -CursorRow=18 +Top=0 +CursorCol=2 +CursorRow=30 TopLine=1 LeftChar=1 diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 082576797..29ee0d686 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -497,6 +497,23 @@ void WriteChannel(chanrec* Ptr, userrec* user, char* text, ...) } } +void WriteChannelWithServ(char* ServerName, chanrec* Ptr, userrec* user, char* text, ...) +{ + char textbuffer[MAXBUF]; + va_list argsPtr; + va_start (argsPtr, text); + vsnprintf(textbuffer, MAXBUF, text, argsPtr); + va_end(argsPtr); + for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++) + { + if (has_channel(i->second,Ptr)) + { + WriteServ(i->second->fd,"%s",textbuffer); + } + } +} + + /* write formatted text from a source user to all users on a channel except * for the sender (for privmsg etc) */ @@ -1680,7 +1697,7 @@ int take_ban(userrec *user,char *dest,chanrec *chan,int status) return 0; } -void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int pcnt) +void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int pcnt, bool servermode) { char modelist[MAXBUF]; char outlist[MAXBUF]; @@ -2007,7 +2024,14 @@ void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int strcat(outstr," "); strcat(outstr,outpars[ptr]); } - WriteChannel(chan,user,"MODE %s %s",chan->name,outstr); + if (servermode) + { + WriteChannelWithServ(ServerName,chan,user,"MODE %s %s",chan->name,outstr); + } + else + { + WriteChannel(chan,user,"MODE %s %s",chan->name,outstr); + } } } @@ -2205,7 +2229,162 @@ void handle_mode(char **parameters, int pcnt, userrec *user) return; } - process_modes(parameters,user,Ptr,cstatus(user,Ptr),pcnt); + process_modes(parameters,user,Ptr,cstatus(user,Ptr),pcnt,false); + } + else + { + WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, parameters[0]); + } +} + + + + +void server_mode(char **parameters, int pcnt, userrec *user) +{ + chanrec* Ptr; + userrec* dest; + int can_change,i; + int direction = 1; + char outpars[MAXBUF]; + + dest = Find(parameters[0]); + + if ((dest) && (pcnt > 1)) + { + strcpy(outpars,"+"); + direction = 1; + + if ((parameters[1][0] != '+') && (parameters[1][0] != '-')) + return; + + for (i = 0; i < strlen(parameters[1]); i++) + { + if (parameters[1][i] == '+') + { + if (direction != 1) + { + if ((outpars[strlen(outpars)-1] == '+') || (outpars[strlen(outpars)-1] == '-')) + { + outpars[strlen(outpars)-1] = '+'; + } + else + { + strcat(outpars,"+"); + } + } + direction = 1; + } + else + if (parameters[1][i] == '-') + { + if (direction != 0) + { + if ((outpars[strlen(outpars)-1] == '+') || (outpars[strlen(outpars)-1] == '-')) + { + outpars[strlen(outpars)-1] = '-'; + } + else + { + strcat(outpars,"-"); + } + } + direction = 0; + } + else + { + can_change = 0; + if (strchr(user->modes,'o')) + { + can_change = 1; + } + else + { + if ((parameters[1][i] == 'i') || (parameters[1][i] == 'w') || (parameters[1][i] == 's')) + { + can_change = 1; + } + } + if (can_change) + { + if (direction == 1) + { + if (!strchr(dest->modes,parameters[1][i])) + { + dest->modes[strlen(dest->modes)+1]='\0'; + dest->modes[strlen(dest->modes)] = parameters[1][i]; + outpars[strlen(outpars)+1]='\0'; + outpars[strlen(outpars)] = parameters[1][i]; + } + } + else + { + int q = 0; + char temp[MAXBUF]; + char moo[MAXBUF]; + + outpars[strlen(outpars)+1]='\0'; + outpars[strlen(outpars)] = parameters[1][i]; + + strcpy(temp,""); + for (q = 0; q < strlen(user->modes); q++) + { + if (user->modes[q] != parameters[1][i]) + { + moo[0] = user->modes[q]; + moo[1] = '\0'; + strcat(temp,moo); + } + } + strcpy(user->modes,temp); + } + } + } + } + if (strlen(outpars)) + { + char b[MAXBUF]; + strcpy(b,""); + int z = 0; + int i = 0; + while (i < strlen (outpars)) + { + b[z++] = outpars[i++]; + b[z] = '\0'; + if (i<strlen(outpars)-1) + { + if (((outpars[i] == '-') || (outpars[i] == '+')) && ((outpars[i+1] == '-') || (outpars[i+1] == '+'))) + { + // someones playing silly buggers and trying + // to put a +- or -+ into the line... + i++; + } + } + if (i == strlen(outpars)-1) + { + if ((outpars[i] == '-') || (outpars[i] == '+')) + { + i++; + } + } + } + + z = strlen(b)-1; + if ((b[z] == '-') || (b[z] == '+')) + b[z] == '\0'; + + if ((!strcmp(b,"+")) || (!strcmp(b,"-"))) + return; + + WriteTo(user, dest, "MODE %s :%s", dest->nick, b); + } + return; + } + + Ptr = FindChan(parameters[0]); + if (Ptr) + { + process_modes(parameters,user,Ptr,STATUS_OP,pcnt,true); } else { @@ -2213,6 +2392,7 @@ void handle_mode(char **parameters, int pcnt, userrec *user) } } + /* This function pokes and hacks at a parameter list like the following: * * PART #winbot, #darkgalaxy :m00! diff --git a/src/modules.cpp b/src/modules.cpp index 820488c99..f65f8b1bd 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -125,6 +125,10 @@ void Server::AddCommand(char* cmd, handlerfunc f, char flags, int minparams) createcommand(cmd,f,flags,minparams); } +void Server::SendMode(char **parameters, int pcnt, userrec *user) +{ + server_mode(parameters,pcnt,user); +} void Server::Send(int Socket, std::string s) { diff --git a/src/modules/m_testcommand.cpp b/src/modules/m_testcommand.cpp index 72ca9e16a..f3dcaec2d 100644 --- a/src/modules/m_testcommand.cpp +++ b/src/modules/m_testcommand.cpp @@ -16,7 +16,25 @@ void handle_woot(char **parameters, int pcnt, userrec *user) // and sends <text> to all opers with +s mode. // NB: The ':' is *REQUIRED* otherwise the parser will // split the line into multiple parameters[]! + // + // If you want to process all the line with no leading colon, you must + // implement a parser here that assembles parameters[] to match the + // syntax of your command - the way it is done in the core is to meet + // rfc-compatibility. Srv->SendOpers(parameters[0]); + + + // Here is a sample of how to send servermodes. Note that unless remote + // servers in your net are u:lined, they may reverse this, but its a + // quick and effective modehack. + char* modes[3]; + modes[0] = "#chatspike"; + modes[1] = "+o"; + modes[2] = user->nick; + + // run the mode change, send numerics (such as "no such channel") back + // to "user". + Srv->SendMode(modes,3,user); } class ModuleTestCommand : public Module @@ -25,6 +43,12 @@ class ModuleTestCommand : public Module ModuleTestCommand() { Srv = new Server; + // Create a new command: + // command will be called /WOOT, and will + // call handle_woot when triggered, the + // 0 in the modes parameter signifies that + // anyone can issue the command, and the + // command takes only one parameter. Srv->AddCommand("WOOT",handle_woot,0,1); } |