- Srv = new Server;
-
- // doesn't require oper, client umode with no params
- // (actually, you cant have params for a umode!)
- if (!Srv->AddExtendedMode('x',MT_CLIENT,false,0,0))
+ }
+
+ ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding)
+ {
+ LocalUser* user = IS_LOCAL(dest);
+
+ /* For remote clients, we don't take any action, we just allow it.
+ * The local server where they are will set their cloak instead.
+ * This is fine, as we will receive it later.
+ */
+ if (!user)
+ {
+ dest->SetMode(this, adding);
+ return MODEACTION_ALLOW;
+ }
+
+ if (user->uuid == debounce_uid && debounce_ts == ServerInstance->Time())
+ {
+ // prevent spamming using /mode user +x-x+x-x+x-x
+ if (++debounce_count > 2)
+ return MODEACTION_DENY;
+ }
+ else
+ {
+ debounce_uid = user->uuid;
+ debounce_count = 1;
+ debounce_ts = ServerInstance->Time();
+ }
+
+ if (adding == user->IsModeSet(this))
+ return MODEACTION_DENY;
+
+ /* don't allow this user to spam modechanges */
+ if (source == dest)
+ user->CommandFloodPenalty += 5000;
+
+ if (adding)
+ {
+ std::string* cloak = ext.get(user);
+
+ if (!cloak)
+ {
+ /* Force creation of missing cloak */
+ creator->OnUserConnect(user);
+ cloak = ext.get(user);
+ }
+ if (cloak)
+ {
+ user->ChangeDisplayedHost(*cloak);
+ user->SetMode(this, true);
+ return MODEACTION_ALLOW;
+ }
+ else
+ return MODEACTION_DENY;
+ }
+ else