diff options
author | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2006-04-10 11:50:48 +0000 |
---|---|---|
committer | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2006-04-10 11:50:48 +0000 |
commit | b01e94da8f5b58da0343d04c9d387da0c663083a (patch) | |
tree | 005c383a489aecdb3e8a9f8416ec5a7e0526d933 | |
parent | 87f5ef38db9c47f04e76578d781e067c97e7096c (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.h | 15 | ||||
-rw-r--r-- | src/mode.cpp | 82 |
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 ¶meter, bool adding); /* Can change the mode parameter */ - virtual void AfterMode(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter, bool adding); + virtual bool BeforeMode(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding, ModeType type); /* Can change the mode parameter */ + virtual void AfterMode(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter, 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 ¶meter, bool adding) +bool ModeWatcher::BeforeMode(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding, ModeType type) { return true; } -void ModeWatcher::AfterMode(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter, bool adding) +void ModeWatcher::AfterMode(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter, 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, |