summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2006-04-10 11:50:48 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2006-04-10 11:50:48 +0000
commitb01e94da8f5b58da0343d04c9d387da0c663083a (patch)
tree005c383a489aecdb3e8a9f8416ec5a7e0526d933
parent87f5ef38db9c47f04e76578d781e067c97e7096c (diff)
Start of new mode parser
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@3857 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--include/mode.h15
-rw-r--r--src/mode.cpp82
2 files changed, 93 insertions, 4 deletions
diff --git a/include/mode.h b/include/mode.h
index e692c5345..70c02a503 100644
--- a/include/mode.h
+++ b/include/mode.h
@@ -80,13 +80,23 @@ class ModeWatcher
char GetModeChar();
ModeType GetModeType();
- virtual bool BeforeMode(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding); /* Can change the mode parameter */
- virtual void AfterMode(userrec* source, userrec* dest, chanrec* channel, const std::string &parameter, bool adding);
+ virtual bool BeforeMode(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding, ModeType type); /* Can change the mode parameter */
+ virtual void AfterMode(userrec* source, userrec* dest, chanrec* channel, const std::string &parameter, bool adding, ModeType type);
};
class ModeParser
{
private:
+ /**
+ * Mode handlers for each mode, to access a handler subtract
+ * 65 from the ascii value of the mode letter.
+ */
+ ModeHandler* modehandlers[64];
+ /**
+ * Mode watcher classes
+ */
+ std::vector<ModeWatcher*> modewatchers[65];
+
char* GiveOps(userrec *user,char *dest,chanrec *chan,int status);
char* GiveHops(userrec *user,char *dest,chanrec *chan,int status);
char* GiveVoice(userrec *user,char *dest,chanrec *chan,int status);
@@ -99,6 +109,7 @@ class ModeParser
char* Grant(userrec *d,chanrec *chan,int MASK);
char* Revoke(userrec *d,chanrec *chan,int MASK);
public:
+ void Process(char **parameters, int pcnt, userrec *user);
std::string CompressModes(std::string modes,bool channelmodes);
void ProcessModes(char **parameters,userrec* user,chanrec *chan,int status, int pcnt, bool servermode, bool silent, bool local);
bool AllowedUmode(char umode, char* sourcemodes,bool adding,bool serveroverride);
diff --git a/src/mode.cpp b/src/mode.cpp
index 7433f4756..7d6423d02 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -119,12 +119,12 @@ ModeType ModeWatcher::GetModeType()
return m_type;
}
-bool ModeWatcher::BeforeMode(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding)
+bool ModeWatcher::BeforeMode(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding, ModeType type)
{
return true;
}
-void ModeWatcher::AfterMode(userrec* source, userrec* dest, chanrec* channel, const std::string &parameter, bool adding)
+void ModeWatcher::AfterMode(userrec* source, userrec* dest, chanrec* channel, const std::string &parameter, bool adding, ModeType type)
{
}
@@ -475,6 +475,84 @@ char* ModeParser::TakeBan(userrec *user,char *dest,chanrec *chan,int status)
return NULL;
}
+void ModeParser::Process(char **parameters, int pcnt, userrec *user)
+{
+ std::string target = parameters[0];
+ ModeType type = MODETYPE_USER;
+ chanrec* targetchannel = FindChan(parameters[0]);
+ userrec* targetuser = Find(parameters[0]);
+
+ if (pcnt > 1)
+ {
+ if (targetchannel)
+ {
+ type = MODETYPE_CHANNEL;
+ }
+ else if (targetuser)
+ {
+ type = MODETYPE_USER;
+ }
+ else
+ {
+ /* No such nick/channel */
+ return;
+ }
+ std::string mode_sequence = parameters[1];
+ std::string parameter = "";
+ std::ostringstream parameter_list;
+ std::string output_sequence = "";
+ bool adding = true, state_change = false;
+ int handler_id = 0;
+
+ for (std::string::const_iterator modeletter = mode_sequence.begin(); modeletter != mode_sequence.end(); modeletter++)
+ {
+ switch (*modeletter)
+ {
+ case '+':
+ adding = true;
+ state_change = true;
+ continue;
+ break;
+ case '-':
+ adding = false;
+ state_change = true;
+ continue;
+ break;
+ default:
+ if (state_change)
+ output_sequence.append(adding ? "+" : "-");
+
+ handler_id = *modeletter-65;
+ state_change = false;
+
+ if (modehandlers[handler_id])
+ {
+ bool abort = false;
+ for (std::vector<ModeWatcher*>::iterator watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++)
+ {
+ if ((*watchers)->BeforeMode(user, targetuser, targetchannel, parameter, adding, type) == MODEACTION_DENY)
+ abort = true;
+ }
+ if ((modehandlers[handler_id]->GetModeType() == type) && (!abort))
+ {
+ ModeAction ma = modehandlers[handler_id]->OnModeChange(user, targetuser, targetchannel, parameter, adding);
+ if (ma == MODEACTION_ALLOW)
+ {
+ output_sequence = output_sequence + *modeletter;
+
+ for (std::vector<ModeWatcher*>::iterator watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++)
+ {
+ (*watchers)->AfterMode(user, targetuser, targetchannel, parameter, adding, type);
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+
/** ModeParser::CompressModes()
* Tidies up redundant modes,