diff --git a/CMakeLists.txt b/CMakeLists.txt index 2793cc623..6f0a0fbde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2522,6 +2522,8 @@ if(SERVER) server.h server_logger.cpp server_logger.h + snap_id_pool.cpp + snap_id_pool.h sql_string_helpers.cpp sql_string_helpers.h upnp.cpp diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index a5aa62fe7..129f7ccf0 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -47,96 +47,6 @@ extern bool IsInterrupted(); -CSnapIDPool::CSnapIDPool() -{ - Reset(); -} - -void CSnapIDPool::Reset() -{ - for(int i = 0; i < MAX_IDS; i++) - { - m_aIDs[i].m_Next = i + 1; - m_aIDs[i].m_State = ID_FREE; - } - - m_aIDs[MAX_IDS - 1].m_Next = -1; - m_FirstFree = 0; - m_FirstTimed = -1; - m_LastTimed = -1; - m_Usage = 0; - m_InUsage = 0; -} - -void CSnapIDPool::RemoveFirstTimeout() -{ - int NextTimed = m_aIDs[m_FirstTimed].m_Next; - - // add it to the free list - m_aIDs[m_FirstTimed].m_Next = m_FirstFree; - m_aIDs[m_FirstTimed].m_State = ID_FREE; - m_FirstFree = m_FirstTimed; - - // remove it from the timed list - m_FirstTimed = NextTimed; - if(m_FirstTimed == -1) - m_LastTimed = -1; - - m_Usage--; -} - -int CSnapIDPool::NewID() -{ - int64_t Now = time_get(); - - // process timed ids - while(m_FirstTimed != -1 && m_aIDs[m_FirstTimed].m_Timeout < Now) - RemoveFirstTimeout(); - - int ID = m_FirstFree; - if(ID == -1) - { - dbg_msg("server", "invalid id"); - return ID; - } - m_FirstFree = m_aIDs[m_FirstFree].m_Next; - m_aIDs[ID].m_State = ID_ALLOCATED; - m_Usage++; - m_InUsage++; - return ID; -} - -void CSnapIDPool::TimeoutIDs() -{ - // process timed ids - while(m_FirstTimed != -1) - RemoveFirstTimeout(); -} - -void CSnapIDPool::FreeID(int ID) -{ - if(ID < 0) - return; - dbg_assert((size_t)ID < std::size(m_aIDs), "id is out of range"); - dbg_assert(m_aIDs[ID].m_State == ID_ALLOCATED, "id is not allocated"); - - m_InUsage--; - m_aIDs[ID].m_State = ID_TIMED; - m_aIDs[ID].m_Timeout = time_get() + time_freq() * 5; - m_aIDs[ID].m_Next = -1; - - if(m_LastTimed != -1) - { - m_aIDs[m_LastTimed].m_Next = ID; - m_LastTimed = ID; - } - else - { - m_FirstTimed = ID; - m_LastTimed = ID; - } -} - void CServerBan::InitServerBan(IConsole *pConsole, IStorage *pStorage, CServer *pServer) { CNetBan::Init(pConsole, pStorage); diff --git a/src/engine/server/server.h b/src/engine/server/server.h index cb6890915..68977c4e1 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -26,6 +26,7 @@ #include "antibot.h" #include "authmanager.h" #include "name_ban.h" +#include "snap_id_pool.h" #if defined(CONF_UPNP) #include "upnp.h" @@ -39,47 +40,6 @@ class CPacker; class IEngineMap; class ILogger; -class CSnapIDPool -{ - enum - { - MAX_IDS = 32 * 1024, - }; - - // State of a Snap ID - enum - { - ID_FREE = 0, - ID_ALLOCATED = 1, - ID_TIMED = 2, - }; - - class CID - { - public: - short m_Next; - short m_State; // 0 = free, 1 = allocated, 2 = timed - int m_Timeout; - }; - - CID m_aIDs[MAX_IDS]; - - int m_FirstFree; - int m_FirstTimed; - int m_LastTimed; - int m_Usage; - int m_InUsage; - -public: - CSnapIDPool(); - - void Reset(); - void RemoveFirstTimeout(); - int NewID(); - void TimeoutIDs(); - void FreeID(int ID); -}; - class CServerBan : public CNetBan { class CServer *m_pServer; diff --git a/src/engine/server/snap_id_pool.cpp b/src/engine/server/snap_id_pool.cpp new file mode 100644 index 000000000..0f317cab9 --- /dev/null +++ b/src/engine/server/snap_id_pool.cpp @@ -0,0 +1,96 @@ +/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ +/* If you are missing that file, acquire a complete release at teeworlds.com. */ + +#include "snap_id_pool.h" + +#include + +CSnapIDPool::CSnapIDPool() +{ + Reset(); +} + +void CSnapIDPool::Reset() +{ + for(int i = 0; i < MAX_IDS; i++) + { + m_aIDs[i].m_Next = i + 1; + m_aIDs[i].m_State = ID_FREE; + } + + m_aIDs[MAX_IDS - 1].m_Next = -1; + m_FirstFree = 0; + m_FirstTimed = -1; + m_LastTimed = -1; + m_Usage = 0; + m_InUsage = 0; +} + +void CSnapIDPool::RemoveFirstTimeout() +{ + int NextTimed = m_aIDs[m_FirstTimed].m_Next; + + // add it to the free list + m_aIDs[m_FirstTimed].m_Next = m_FirstFree; + m_aIDs[m_FirstTimed].m_State = ID_FREE; + m_FirstFree = m_FirstTimed; + + // remove it from the timed list + m_FirstTimed = NextTimed; + if(m_FirstTimed == -1) + m_LastTimed = -1; + + m_Usage--; +} + +int CSnapIDPool::NewID() +{ + int64_t Now = time_get(); + + // process timed ids + while(m_FirstTimed != -1 && m_aIDs[m_FirstTimed].m_Timeout < Now) + RemoveFirstTimeout(); + + int ID = m_FirstFree; + if(ID == -1) + { + dbg_msg("server", "invalid id"); + return ID; + } + m_FirstFree = m_aIDs[m_FirstFree].m_Next; + m_aIDs[ID].m_State = ID_ALLOCATED; + m_Usage++; + m_InUsage++; + return ID; +} + +void CSnapIDPool::TimeoutIDs() +{ + // process timed ids + while(m_FirstTimed != -1) + RemoveFirstTimeout(); +} + +void CSnapIDPool::FreeID(int ID) +{ + if(ID < 0) + return; + dbg_assert((size_t)ID < std::size(m_aIDs), "id is out of range"); + dbg_assert(m_aIDs[ID].m_State == ID_ALLOCATED, "id is not allocated"); + + m_InUsage--; + m_aIDs[ID].m_State = ID_TIMED; + m_aIDs[ID].m_Timeout = time_get() + time_freq() * 5; + m_aIDs[ID].m_Next = -1; + + if(m_LastTimed != -1) + { + m_aIDs[m_LastTimed].m_Next = ID; + m_LastTimed = ID; + } + else + { + m_FirstTimed = ID; + m_LastTimed = ID; + } +} diff --git a/src/engine/server/snap_id_pool.h b/src/engine/server/snap_id_pool.h new file mode 100644 index 000000000..f56eed95b --- /dev/null +++ b/src/engine/server/snap_id_pool.h @@ -0,0 +1,48 @@ +/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ +/* If you are missing that file, acquire a complete release at teeworlds.com. */ + +#ifndef ENGINE_SERVER_SNAP_ID_POOL_H +#define ENGINE_SERVER_SNAP_ID_POOL_H + +class CSnapIDPool +{ + enum + { + MAX_IDS = 32 * 1024, + }; + + // State of a Snap ID + enum + { + ID_FREE = 0, + ID_ALLOCATED = 1, + ID_TIMED = 2, + }; + + class CID + { + public: + short m_Next; + short m_State; // 0 = free, 1 = allocated, 2 = timed + int m_Timeout; + }; + + CID m_aIDs[MAX_IDS]; + + int m_FirstFree; + int m_FirstTimed; + int m_LastTimed; + int m_Usage; + int m_InUsage; + +public: + CSnapIDPool(); + + void Reset(); + void RemoveFirstTimeout(); + int NewID(); + void TimeoutIDs(); + void FreeID(int ID); +}; + +#endif