]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_kicknorejoin.cpp
Merge insp20
[user/henk/code/inspircd.git] / src / modules / m_kicknorejoin.cpp
index 5d9b7f8b95c140f2435b0c23954ef48a4d81b0c9..b8a7766675e8e191ea0cb45331ba495058f695d9 100644 (file)
 
 #include "inspircd.h"
 
-typedef std::map<std::string, time_t> delaylist;
-
 class KickRejoinData
 {
-       mutable delaylist kicked;
+       struct KickedUser
+       {
+               std::string uuid;
+               time_t expire;
+
+               KickedUser(User* user, unsigned int Delay)
+                       : uuid(user->uuid)
+                       , expire(ServerInstance->Time() + Delay)
+               {
+               }
+       };
+
+       typedef std::vector<KickedUser> KickedList;
+
+       mutable KickedList kicked;
 
  public:
        const unsigned int delay;
@@ -38,18 +50,21 @@ class KickRejoinData
 
        bool canjoin(LocalUser* user) const
        {
-               for (delaylist::iterator i = kicked.begin(); i != kicked.end(); )
+               for (KickedList::iterator i = kicked.begin(); i != kicked.end(); )
                {
-                       if (i->second > ServerInstance->Time())
+                       KickedUser& rec = *i;
+                       if (rec.expire > ServerInstance->Time())
                        {
-                               if (i->first == user->uuid)
+                               if (rec.uuid == user->uuid)
                                        return false;
                                ++i;
                        }
                        else
                        {
                                // Expired record, remove.
-                               kicked.erase(i++);
+                               stdalgo::vector::swaperase(kicked, i);
+                               if (kicked.empty())
+                                       break;
                        }
                }
                return true;
@@ -57,7 +72,10 @@ class KickRejoinData
 
        void add(User* user)
        {
-               kicked[user->uuid] = ServerInstance->Time() + delay;
+               // One user can be in the list multiple times if the user gets kicked, force joins
+               // (skipping OnUserPreJoin) and gets kicked again, but that's okay because canjoin()
+               // works correctly in this case as well
+               kicked.push_back(KickedUser(user, delay));
        }
 };
 
@@ -65,10 +83,11 @@ class KickRejoinData
  */
 class KickRejoin : public ParamMode<KickRejoin, SimpleExtItem<KickRejoinData> >
 {
-       static const unsigned int max = 60;
+       const unsigned int max;
  public:
        KickRejoin(Module* Creator)
                : ParamMode<KickRejoin, SimpleExtItem<KickRejoinData> >(Creator, "kicknorejoin", 'J')
+               , max(60)
        {
        }
 
@@ -89,6 +108,11 @@ class KickRejoin : public ParamMode<KickRejoin, SimpleExtItem<KickRejoinData> >
        {
                out.append(ConvToStr(krd->delay));
        }
+
+       std::string GetModuleSettings() const
+       {
+               return ConvToStr(max);
+       }
 };
 
 class ModuleKickNoRejoin : public Module
@@ -129,7 +153,7 @@ public:
 
        Version GetVersion() CXX11_OVERRIDE
        {
-               return Version("Channel mode to delay rejoin after kick", VF_VENDOR);
+               return Version("Channel mode to delay rejoin after kick", VF_VENDOR | VF_COMMON, kr.GetModuleSettings());
        }
 };