summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/modules.h22
-rw-r--r--src/InspIRCd.layout40
-rw-r--r--src/inspircd.cpp186
-rw-r--r--src/modules.cpp4
-rw-r--r--src/modules/m_testcommand.cpp24
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 &params);
-
+
+
};
@@ -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);
}