diff --git a/amxmodx/AMBuilder b/amxmodx/AMBuilder index 23a115eb..a0a3c383 100644 --- a/amxmodx/AMBuilder +++ b/amxmodx/AMBuilder @@ -93,6 +93,7 @@ binary.sources = [ '../public/memtools/MemoryUtils.cpp', '../public/memtools/CDetour/detours.cpp', '../public/memtools/CDetour/asm/asm.c', + '../public/resdk/mod_rehlds_api.cpp', 'CLibrarySys.cpp', 'CGameConfigs.cpp', 'gameconfigs.cpp', diff --git a/amxmodx/CEvent.cpp b/amxmodx/CEvent.cpp index 5cd32e86..70db3f8c 100755 --- a/amxmodx/CEvent.cpp +++ b/amxmodx/CEvent.cpp @@ -204,16 +204,16 @@ int EventsMngr::registerEvent(CPluginMngr::CPlugin* plugin, int func, int flags, return 0; } - auto event = new ClEvent(plugin, func, flags); + auto event = ke::AutoPtr(new ClEvent(plugin, func, flags)); - int handle = EventHandles.create(event); + int handle = EventHandles.create(event.get()); if (!handle) { return 0; } - m_Events[msgid].put(event); + m_Events[msgid].append(ke::Move(event)); return handle; } @@ -226,40 +226,40 @@ void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int in m_ParseNotDone = false; // don't parse if nothing to do - if (!m_Events[msg_type].size()) + if (!m_Events[msg_type].length()) return; m_ParseMsgType = msg_type; m_Timer = timer; - for (ClEventVecIter iter = m_Events[msg_type].begin(); iter; ++iter) + for (auto &event : m_Events[msg_type]) { - if ((*iter).m_Done) + if (event->m_Done) continue; - if (!(*iter).m_Plugin->isExecutable((*iter).m_Func)) + if (!event->m_Plugin->isExecutable(event->m_Func)) { - (*iter).m_Done = true; + event->m_Done = true; continue; } if (pPlayer) { - if (!(*iter).m_FlagClient || (pPlayer->IsBot() ? !(*iter).m_FlagBot : !(*iter).m_FlagPlayer) || (pPlayer->IsAlive() ? !(*iter).m_FlagAlive : !(*iter).m_FlagDead)) + if (!event->m_FlagClient || (pPlayer->IsBot() ? !event->m_FlagBot : !event->m_FlagPlayer) || (pPlayer->IsAlive() ? !event->m_FlagAlive : !event->m_FlagDead)) { - (*iter).m_Done = true; + event->m_Done = true; continue; } } - else if (!(*iter).m_FlagWorld) + else if (!event->m_FlagWorld) { - (*iter).m_Done = true; + event->m_Done = true; continue; } - if ((*iter).m_FlagOnce && (*iter).m_Stamp == (float)(*timer)) + if (event->m_FlagOnce && event->m_Stamp == *timer) { - (*iter).m_Done = true; + event->m_Done = true; continue; } @@ -292,16 +292,16 @@ void EventsMngr::parseValue(int iValue) // loop through the registered funcs, and decide whether they have to be called or not // if they shouldnt, their m_Done is set to true - for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter) + for (auto &event : *m_ParseFun) { - if ((*iter).m_Done) + if (event->m_Done) continue; // already skipped; don't bother with parsing // loop through conditions bool execute = false; bool anyConditions = false; - for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next) + for (auto condIter = event->m_Conditions; condIter; condIter = condIter->next) { if (condIter->paramId == m_ParsePos) { @@ -320,7 +320,7 @@ void EventsMngr::parseValue(int iValue) } if (anyConditions && !execute) - (*iter).m_Done = true; // don't execute + event->m_Done = true; // don't execute } } @@ -339,16 +339,16 @@ void EventsMngr::parseValue(float fValue) // loop through the registered funcs, and decide whether they have to be called or not // if they shouldnt, their m_Done is set to true - for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter) + for (auto &event : *m_ParseFun) { - if ((*iter).m_Done) + if (event->m_Done) continue; // already skipped; don't bother with parsing // loop through conditions bool execute = false; bool anyConditions = false; - for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next) + for (auto condIter = event->m_Conditions; condIter; condIter = condIter->next) { if (condIter->paramId == m_ParsePos) { @@ -367,7 +367,7 @@ void EventsMngr::parseValue(float fValue) } if (anyConditions && !execute) - (*iter).m_Done = true; // don't execute + event->m_Done = true; // don't execute } } @@ -386,16 +386,16 @@ void EventsMngr::parseValue(const char *sz) // loop through the registered funcs, and decide whether they have to be called or not // if they shouldnt, their m_Done is set to true - for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter) + for (auto &event : *m_ParseFun) { - if ((*iter).m_Done) + if (event->m_Done) continue; // already skipped; don't bother with parsing // loop through conditions bool execute = false; bool anyConditions = false; - for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next) + for (auto condIter = event->m_Conditions; condIter; condIter = condIter->next) { if (condIter->paramId == m_ParsePos) { @@ -413,7 +413,7 @@ void EventsMngr::parseValue(const char *sz) } if (anyConditions && !execute) - (*iter).m_Done = true; // don't execute + event->m_Done = true; // don't execute } } @@ -455,22 +455,22 @@ void EventsMngr::executeEvents() } // Reset this here so we don't trigger re-entrancy for unregistered messages - ClEventVec *parseFun = m_ParseFun; - m_ParseFun = NULL; + auto parseFun = m_ParseFun; + m_ParseFun = nullptr; - for (ClEventVecIter iter = parseFun->begin(); iter; ++iter) + for (auto &event : *parseFun) { - if ((*iter).m_Done) + if (event->m_Done) { - (*iter).m_Done = false; + event->m_Done = false; continue; } - (*iter).m_Stamp = (float)*m_Timer; + event->m_Stamp = *m_Timer; - if ((*iter).m_State == FSTATE_ACTIVE) + if (event->m_State == FSTATE_ACTIVE) { - executeForwards((*iter).m_Func, static_cast(m_ReadVault ? m_ReadVault[0].iValue : 0)); + executeForwards(event->m_Func, static_cast(m_ReadVault ? m_ReadVault[0].iValue : 0)); } } diff --git a/amxmodx/CEvent.h b/amxmodx/CEvent.h index b856ee04..54f71863 100755 --- a/amxmodx/CEvent.h +++ b/amxmodx/CEvent.h @@ -108,11 +108,8 @@ private: int m_ReadVaultSize; void NextParam(); // make sure a new parameter can be added - typedef CList ClEventVec; - typedef ClEventVec::iterator ClEventVecIter; - - ClEventVec m_Events[MAX_AMX_REG_MSG]; - ClEventVec *m_ParseFun; // current Event vector + ke::Vector> m_Events[MAX_AMX_REG_MSG]; + ke::Vector> *m_ParseFun; // current Event vector bool m_ParseNotDone; int m_ParsePos; // is args. num. - 1 diff --git a/amxmodx/CLang.cpp b/amxmodx/CLang.cpp index 90ab488c..86124be4 100755 --- a/amxmodx/CLang.cpp +++ b/amxmodx/CLang.cpp @@ -589,7 +589,7 @@ const char *CLangMngr::GetLangName(int langId) { for (size_t iter = 0; iter < m_Languages.length(); ++iter) { - if (iter == langId) + if ((int)iter == langId) { return m_Languages[iter]->GetName(); } diff --git a/amxmodx/CLibrarySys.h b/amxmodx/CLibrarySys.h index 32cf775f..401f70c0 100644 --- a/amxmodx/CLibrarySys.h +++ b/amxmodx/CLibrarySys.h @@ -11,67 +11,9 @@ #define _INCLUDE_LIBRARY_SYS_H_ #include "amx.h" // cell -#include // Interface (HLSDK) -#include // AutoPtr +#include #include -#define PLATFORM_WINDOWNS_NAME "windows" -#define PLATFORM_LINUX_NAME "linux" -#define PLATFORM_MAC_NAME "mac" -#if defined(WIN32) -# ifndef PLATFORM_WINDOWS -# define PLATFORM_WINDOWS 1 -# endif -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include -# include -# include -# define PLATFORM_LIB_EXT "dll" -# define PLATFORM_NAME PLATFORM_WINDOWNS_NAME -# define PLATFORM_SEP_CHAR '\\' -# define PLATFORM_SEP_ALTCHAR '/' -# define PLATFORM_EXTERN_C extern "C" __declspec(dllexport) -#elif defined(__linux__) || defined(__APPLE__) -# if defined(__linux__) -# define PLATFORM_LINUX 1 -# define PLATFORM_LIB_EXT "so" -# define PLATFORM_NAME PLATFORM_LINUX_NAME -# define PLATFORM_COMPAT_ALT PLATFORM_MAC_NAME -# elif defined(__APPLE__) -# define PLATFORM_APPLE 1 -# define PLATFORM_LIB_EXT "dylib" -# define PLATFORM_NAME PLATFORM_MAC_NAME -# define PLATFORM_COMPAT_ALT PLATFORM_LINUX_NAME -# endif -# ifndef PLATFORM_POSIX -# define PLATFORM_POSIX 1 -# endif -# include -# include -# include -# include -# include -# include -# include -# if defined(PLATFORM_APPLE) -# include -# endif -# define PLATFORM_SEP_CHAR '/' -# define PLATFORM_SEP_ALTCHAR '\\' -# define PLATFORM_EXTERN_C extern "C" __attribute__((visibility("default"))) -# define WINAPI -#endif - -#define PLATFORM_MAX_PATH 260 - -#if defined PLATFORM_WINDOWS - typedef HANDLE DirHandle; -#elif defined PLATFORM_POSIX - typedef DIR* DirHandle; -#endif - enum FileTimeType { FileTime_LastAccess = 0, /* Last access (not available on FAT) */ @@ -162,26 +104,4 @@ class LibrarySystem extern LibrarySystem g_LibSys; -template -bool GET_IFACE(const char* library, T*& var, const char* version) -{ - const char* path = g_LibSys.PathFormat("%s.%s", library, PLATFORM_LIB_EXT); - - ke::AutoPtr lib(g_LibSys.OpenLibrary(path)); - - if (lib) - { - CreateInterfaceFn factory = reinterpret_cast(lib->GetSymbolAddress(CREATEINTERFACE_PROCNAME)); - - if (factory) - { - var = reinterpret_cast(factory(version, nullptr)); - return true; - } - } - - var = nullptr; - return false; -} - #endif // _INCLUDE_LIBRARY_SYS_H_ diff --git a/amxmodx/CList.h b/amxmodx/CList.h deleted file mode 100755 index 01dc5363..00000000 --- a/amxmodx/CList.h +++ /dev/null @@ -1,307 +0,0 @@ -// vim: set ts=4 sw=4 tw=99 noet: -// -// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). -// Copyright (C) The AMX Mod X Development Team. -// -// This software is licensed under the GNU General Public License, version 3 or higher. -// Additional exceptions apply. For full license details, see LICENSE.txt or visit: -// https://alliedmods.net/amxmodx-license - -#ifndef CLIST_H -#define CLIST_H - -// ***************************************************** -// class CList -// ***************************************************** - -// Linked list -template -class CList -{ -private: - // One list element - class CElement - { - T *m_pObject; // pointer to the object - CElement *m_pNext; // pointer to the next element - CElement *m_pPrev; // pointer to the previous element - public: - // dereference operator - T& operator* () - { - return *m_pObject; - } - - // constructor - CElement(T *pObj) - { - m_pObject = pObj; - m_pNext = NULL; - m_pPrev = NULL; - } - - // destructor - ~CElement() - { - delete m_pObject; - - if (m_pNext) - m_pNext->m_pPrev = m_pPrev; - - if (m_pPrev) - m_pPrev->m_pNext = m_pNext; - } - - // returns object pointer - T *GetObj() - { - return m_pObject; - } - - // returns next element pointer - CElement *GetNext() - { - return m_pNext; - } - - // sets next element - void SetNext(CElement *newNext) - { - m_pNext = newNext; - } - - // returns previous element pointer - CElement *GetPrev() - { - return m_pPrev; - } - - // sets previous element - void SetPrev(CElement *newPrev) - { - m_pPrev = newPrev; - } - }; - - // CList class - CElement *m_pHead; // head of the linked list - CElement *m_pTail; // tail of the linked list -public: - // iterator class - class iterator - { - friend class CList; - - CList *m_pList; // The list that created this iterator - CElement *m_CurPos; // Current position in the list - public: - iterator() - { - m_pList = NULL; - m_CurPos = NULL; - } - - // constructor based on list, element - iterator(CList *pList, CElement *startPos) - { - m_pList = pList; - m_CurPos = startPos; - } - - // constructor based on other iterator - iterator(const iterator &other) - { - m_pList = other.m_pList; - m_CurPos = other.m_CurPos; - } - - // dereference operator - T & operator* () const - { - return *m_CurPos->GetObj(); - } - - T * operator-> () const - { - return m_CurPos->GetObj(); - } - - // validity check operator - inline operator bool () const - { - return m_pList != NULL && m_CurPos != NULL && m_CurPos->GetObj() != NULL; - } - - // pre increment operator - inline iterator& operator ++ () - { - m_CurPos = m_CurPos->GetNext(); - return *this; - } - - // post increment operator - inline iterator operator++(int) - { - iterator tmp(*this); - m_CurPos = m_CurPos->next; - - return tmp; - } - - // returns iterator that points to next element - iterator GetNext() - { - iterator tmp(*this); - return ++tmp; - } - - iterator remove() - { - return m_pList->remove(*this); - } - - iterator put(T *obj) - { - return m_pList->put(obj, *this); - } - }; - - CList() - { - m_pHead = NULL; - m_pTail = NULL; - } - - ~CList() - { - clear(); - } - - // removes the object referenced by where - // sets where to the next object - // returns an iterator pointing to the next object - iterator remove(iterator &where) - { - iterator tmp(where.GetNext()); - - if (where.m_CurPos == m_pHead) - m_pHead = where.m_CurPos->GetNext(); - - if (where.m_CurPos == m_pTail) - m_pTail = where.m_CurPos->GetPrev(); - - delete where.m_CurPos; - where = tmp; - - return tmp; - } - - // puts an element to the end of the list - // returns an iterator pointing to it - iterator put_back(T *pObj) - { - CElement *pTmp = new CElement(pObj); - - if (!m_pHead) - { - m_pHead = pTmp; - m_pTail = pTmp; - } else { - pTmp->SetNext(NULL); - pTmp->SetPrev(m_pTail); - m_pTail->SetNext(pTmp); - m_pTail = pTmp; - } - - return iterator(this, pTmp); - } - - iterator put_front(T *pObj) - { - CElement *pTmp = new CElement(pObj); - - if (!m_pHead) - { - m_pHead = pTmp; - m_pTail = pTmp; - } else { - pTmp->SetNext(m_pHead); - pTmp->SetPrev(NULL); - m_pHead->SetPrev(pTmp); - m_pHead = pTmp; - } - - return iterator(this, pTmp); - } - - // alias for put_back - iterator put(T *pObj) - { - return put_back(pObj); - } - - // puts an element after where - // alters where to point to the new element - // returns an iterator pointing to the new element - iterator put(T *pObj, iterator &where) - { - CElement *pTmp = new CElement(pObj); - - if (where.m_CurPos->GetNext()) - where.m_CurPos->GetNext()->SetPrev(pTmp); - else // where = tail - m_pTail = pTmp; - - pTmp->SetPrev(where.m_CurPos); - pTmp->SetNext(where.m_CurPos->GetNext()); - - where.m_CurPos->SetNext(pTmp); - - return ++where; - } - - iterator begin() - { - return iterator(this, m_pHead); - } - - void clear() - { - iterator iter = begin(); - while (iter) iter.remove(); - } - - iterator find(iterator startOn, const F &desc) - { - iterator iter = startOn; - while (iter) - { - if (*iter == desc) - break; - ++iter; - } - - return iter; - } - - iterator find(const F &desc) - { - return find(begin(), desc); - } - - int size() - { - iterator iter = begin(); - int i = 0; - - while (iter) - { - ++i; - ++iter; - } - - return i; - } -}; - -#endif //CLIST_H diff --git a/amxmodx/CMisc.h b/amxmodx/CMisc.h index b64e0764..9de8033c 100755 --- a/amxmodx/CMisc.h +++ b/amxmodx/CMisc.h @@ -10,7 +10,6 @@ #ifndef CMISC_H #define CMISC_H -#include "CList.h" #include "sh_list.h" // ***************************************************** @@ -202,7 +201,7 @@ public: // class CScript // ***************************************************** -class CScript +class CScript : public ke::InlineListNode { ke::AString filename; AMX* amx; @@ -212,7 +211,6 @@ public: inline AMX* getAMX() { return amx; } inline const char* getName() { return filename.chars(); } - inline bool operator==(void* a) { return (amx == (AMX*)a); } inline void* getCode() { return code; } }; diff --git a/amxmodx/CModule.h b/amxmodx/CModule.h index c910004b..168330e2 100755 --- a/amxmodx/CModule.h +++ b/amxmodx/CModule.h @@ -52,7 +52,7 @@ struct amxx_module_info_s #define AMXX_INTERFACE_VERSION 4 -class CModule +class CModule : public ke::InlineListNode { ke::AString m_Filename; // Filename @@ -87,7 +87,6 @@ public: inline const char* getName() const { return m_InfoNew.name; } inline const amxx_module_info_s* getInfoNew() const { return &m_InfoNew; } // new inline int getStatusValue() { return m_Status; } - inline bool operator==(const char* fname) { return !strcmp(m_Filename.chars(), fname); } inline bool isReloadable() { return ((m_Status == MODULE_LOADED) && (m_InfoNew.reload != 0)); } inline bool isAmxx() const { return m_Amxx; } inline const char *getMissingFunc() const { return m_MissingFunc; } diff --git a/amxmodx/CPlugin.cpp b/amxmodx/CPlugin.cpp index ca64bc57..34731d49 100755 --- a/amxmodx/CPlugin.cpp +++ b/amxmodx/CPlugin.cpp @@ -19,14 +19,14 @@ extern const char *no_function; CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, int debug) -{ +{ CPlugin** a = &head; - + while (*a) a = &(*a)->next; - + *a = new CPlugin(pCounter++, path, name, error, debug); - + return (*a); } @@ -42,10 +42,10 @@ void CPluginMngr::Finalize() { if (m_Finalized) return; - + pNatives = BuildNativeTable(); CPlugin *a = head; - + while (a) { if (a->getStatusCode() == ps_running) @@ -55,16 +55,16 @@ void CPluginMngr::Finalize() } a = a->next; } - + m_Finalized = true; } int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn) { - char file[256]; - FILE *fp = fopen(build_pathname_r(file, sizeof(file) - 1, "%s", filename), "rt"); + char file[PLATFORM_MAX_PATH]; + FILE *fp = fopen(build_pathname_r(file, sizeof(file), "%s", filename), "rt"); - if (!fp) + if (!fp) { if (warn) { @@ -72,23 +72,23 @@ int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn) } return 1; } - + // Find now folder char pluginName[256], error[256], debug[256]; int debugFlag = 0; const char *pluginsDir = get_localinfo("amxx_pluginsdir", "addons/amxmodx/plugins"); - + char line[512]; List::iterator block_iter; - while (!feof(fp)) + while (!feof(fp)) { pluginName[0] = '\0'; - + debug[0] = '\0'; debugFlag = 0; - + line[0] = '\0'; fgets(line, sizeof(line), fp); @@ -104,7 +104,7 @@ int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn) } } sscanf(line, "%s %s", pluginName, debug); - + if (!isalnum(*pluginName)) { continue; @@ -138,7 +138,7 @@ int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn) } CPlugin* plugin = loadPlugin(pluginsDir, pluginName, error, debugFlag); - + if (plugin->getStatusCode() == ps_bad_load) { char errorMsg[255]; @@ -173,13 +173,13 @@ int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn) void CPluginMngr::clear() { - CPlugin**a = &head; - + CPlugin**a = &head; + while (*a) unloadPlugin(a); - + m_Finalized = false; - + if (pNatives) { delete [] pNatives; @@ -198,20 +198,20 @@ void CPluginMngr::clear() CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx) { CPlugin*a = head; - + while (a && &a->amx != amx) a = a->next; - + return a; } - + CPluginMngr::CPlugin* CPluginMngr::findPlugin(int index) { CPlugin*a = head; - + while (a && index--) a = a->next; - + return a; } @@ -219,17 +219,17 @@ CPluginMngr::CPlugin* CPluginMngr::findPlugin(const char* name) { if (!name) return 0; - + int len = strlen(name); - + if (!len) return 0; - + CPlugin*a = head; - + while (a && strncmp(a->name.chars(), name, len)) a = a->next; - + return a; } @@ -248,7 +248,7 @@ const char* CPluginMngr::CPlugin::getStatus() const { switch (status) { - case ps_running: + case ps_running: { if (m_Debug) { @@ -263,42 +263,42 @@ const char* CPluginMngr::CPlugin::getStatus() const case ps_stopped: return "stopped"; case ps_locked: return "locked"; } - + return "error"; } CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int d) : name(n), title(n), m_pNullStringOfs(nullptr), m_pNullVectorOfs(nullptr) { const char* unk = "unknown"; - + failcounter = 0; title = unk; author = unk; version = unk; - - char file[256]; - char* path = build_pathname_r(file, sizeof(file) - 1, "%s/%s", p, n); + + char file[PLATFORM_MAX_PATH]; + char* path = build_pathname_r(file, sizeof(file), "%s/%s", p, n); code = 0; memset(&amx, 0, sizeof(AMX)); int err = load_amxscript(&amx, &code, path, e, d); - + if (err == AMX_ERR_NONE) { status = ps_running; } else { status = ps_bad_load; } - + amx.userdata[UD_FINDPLUGIN] = this; paused_fun = 0; next = 0; id = i; - + if (status == ps_running) { m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause", FP_DONE); m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause", FP_DONE); - + if (amx.flags & AMX_FLAG_DEBUG) { m_Debug = true; @@ -368,17 +368,17 @@ void CPluginMngr::CPlugin::Finalize() { char buffer[128]; int old_status = status; - + if (CheckModules(&amx, buffer)) { if (amx_Register(&amx, core_Natives, -1) != AMX_ERR_NONE) { Handler *pHandler = (Handler *)amx.userdata[UD_HANDLER]; int res = 0; - + if (pHandler->IsNativeFiltering()) res = amx_CheckNatives(&amx, native_handler); - + if (!res) { status = ps_bad_load; @@ -394,7 +394,7 @@ void CPluginMngr::CPlugin::Finalize() errorMsg = buffer; amx.error = AMX_ERR_NOTFOUND; } - + if (old_status != status) { AMXXLOG_Log("[AMXX] Plugin \"%s\" failed to load: %s", name.chars(), errorMsg.chars()); @@ -402,7 +402,7 @@ void CPluginMngr::CPlugin::Finalize() } void CPluginMngr::CPlugin::pauseFunction(int id) -{ +{ } void CPluginMngr::CPlugin::unpauseFunction(int id) @@ -410,8 +410,8 @@ void CPluginMngr::CPlugin::unpauseFunction(int id) } void CPluginMngr::CPlugin::setStatus(int a) -{ - status = a; +{ + status = a; g_commands.clearBufforedInfo(); // ugly way } @@ -423,7 +423,7 @@ void CPluginMngr::CPlugin::pausePlugin() // call plugin_pause if provided if (m_PauseFwd != -1) executeForwards(m_PauseFwd); - + setStatus(ps_paused); } } @@ -435,7 +435,7 @@ void CPluginMngr::CPlugin::unpausePlugin() { // set status first so the function will be marked executable setStatus(ps_running); - + // call plugin_unpause if provided if (m_UnpauseFwd != -1) { @@ -597,7 +597,7 @@ void CPluginMngr::CacheAndLoadModules(const char *plugin) { return; } - if ((hdr.defsize != sizeof(AMX_FUNCSTUB)) && + if ((hdr.defsize != sizeof(AMX_FUNCSTUB)) && (hdr.defsize != sizeof(AMX_FUNCSTUBNT))) { return; @@ -610,7 +610,7 @@ void CPluginMngr::CacheAndLoadModules(const char *plugin) { return; } - + if (hdr.stp <= 0) { return; @@ -655,7 +655,7 @@ void CPluginMngr::CacheAndLoadModules(const char *plugin) { RunLibCommand(dc); } else if ( (dc->cmd == LibCmd_ExpectClass) || - (dc->cmd == LibCmd_ExpectLib) ) + (dc->cmd == LibCmd_ExpectLib) ) { expects.append(dc); } else if (dc->cmd == LibCmd_DefaultLib) { @@ -688,10 +688,10 @@ void CPluginMngr::CacheAndLoadModules(const char *plugin) void CPluginMngr::CALMFromFile(const char *file) { - char filename[256]; - FILE *fp = fopen(build_pathname_r(filename, sizeof(filename) - 1, "%s", file), "rt"); + char filename[PLATFORM_MAX_PATH]; + FILE *fp = fopen(build_pathname_r(filename, sizeof(filename), "%s", file), "rt"); - if (!fp) + if (!fp) { return; } @@ -701,7 +701,7 @@ void CPluginMngr::CALMFromFile(const char *file) char line[256]; char rline[256]; - while (!feof(fp)) + while (!feof(fp)) { fgets(line, sizeof(line)-1, fp); if (line[0] == ';' || line[0] == '\n' || line[0] == '\0') @@ -751,7 +751,7 @@ void CPluginMngr::CALMFromFile(const char *file) continue; } - build_pathname_r(filename, sizeof(filename)-1, "%s/%s", get_localinfo("amxx_pluginsdir", "addons/amxmodx/plugins"), pluginName); + build_pathname_r(filename, sizeof(filename), "%s/%s", get_localinfo("amxx_pluginsdir", "addons/amxmodx/plugins"), pluginName); CacheAndLoadModules(filename); } diff --git a/amxmodx/CQueue.h b/amxmodx/CQueue.h deleted file mode 100755 index eaec18bb..00000000 --- a/amxmodx/CQueue.h +++ /dev/null @@ -1,107 +0,0 @@ -// vim: set ts=4 sw=4 tw=99 noet: -// -// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). -// Copyright (C) The AMX Mod X Development Team. -// -// This software is licensed under the GNU General Public License, version 3 or higher. -// Additional exceptions apply. For full license details, see LICENSE.txt or visit: -// https://alliedmods.net/amxmodx-license - -//by David "BAILOPAN" Anderson -#ifndef _INCLUDE_CQUEUE_H -#define _INCLUDE_CQUEUE_H - -template -class CQueue -{ -public: - class CQueueItem - { - public: - CQueueItem(const T &i, CQueueItem *n) - { - item = i; - next = n; - } - - CQueueItem *GetNext() - { - return next; - } - - T & GetItem() - { - return item; - } - - void SetNext(CQueueItem *n) - { - next = n; - } - private: - T item; - CQueueItem *next; - }; -public: - CQueue() - { - mSize = 0; - mFirst = NULL; - mLast = NULL; - } - - bool empty() - { - return ((mSize == 0) ? true : false); - } - - void push(const T &v) - { - CQueueItem *p = new CQueueItem(v, NULL); - if (empty()) - { - mFirst = p; - } else { - mLast->SetNext(p); - } - mLast = p; - mSize++; - } - - void pop() - { - if (mFirst == mLast) - { - delete mFirst; - mFirst = NULL; - mLast = NULL; - } else { - CQueueItem *p = mFirst->GetNext(); - delete mFirst; - mFirst = p; - } - mSize--; - } - - T & front() - { - return mFirst->GetItem(); - } - - T & back() - { - return mLast->GetItem(); - } - - unsigned int size() - { - return mSize; - } -private: - CQueueItem *mFirst; - CQueueItem *mLast; - - unsigned int mSize; -}; - -#endif //_INCLUDE_CQUEUE_H diff --git a/amxmodx/CTask.cpp b/amxmodx/CTask.cpp index 23cbfeeb..0b8ff1de 100755 --- a/amxmodx/CTask.cpp +++ b/amxmodx/CTask.cpp @@ -203,35 +203,36 @@ void CTaskMngr::registerTimers(float *pCurrentTime, float *pTimeLimit, float *pT void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat) { // first, search for free tasks - TaskListIter iter = m_Tasks.find(CTaskDescriptor(0, NULL, true)); - - if (iter) + for (auto &task : m_Tasks) { - // found: reuse it - iter->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime); - } else { - // not found: make a new one - CTask *pTmp = new CTask; - - if (!pTmp) + if (task->isFree() && !task->inExecute()) + { + // found: reuse it + task->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime); return; - - pTmp->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime); - m_Tasks.put(pTmp); + } } + // not found: make a new one + auto task = ke::AutoPtr(new CTask); + + if (!task) + return; + + task->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime); + m_Tasks.append(ke::Move(task)); } int CTaskMngr::removeTasks(int iId, AMX *pAmx) { - CTaskDescriptor descriptor(iId, pAmx); - TaskListIter iter = m_Tasks.find(descriptor); int i = 0; - while (iter) + for (auto &task : m_Tasks) { - iter->clear(); - ++i; - iter = m_Tasks.find(++iter, descriptor); + if (task->match(iId, pAmx)) + { + task->clear(); + ++i; + } } return i; @@ -239,16 +240,16 @@ int CTaskMngr::removeTasks(int iId, AMX *pAmx) int CTaskMngr::changeTasks(int iId, AMX *pAmx, float fNewBase) { - CTaskDescriptor descriptor(iId, pAmx); - TaskListIter iter = m_Tasks.find(descriptor); int i = 0; - while (iter) + for (auto &task : m_Tasks) { - iter->changeBase(fNewBase); - iter->resetNextExecTime(*m_pTmr_CurrentTime); - ++i; - iter = m_Tasks.find(++iter, descriptor); + if (task->match(iId, pAmx)) + { + task->changeBase(fNewBase); + task->resetNextExecTime(*m_pTmr_CurrentTime); + ++i; + } } return i; @@ -256,16 +257,23 @@ int CTaskMngr::changeTasks(int iId, AMX *pAmx, float fNewBase) bool CTaskMngr::taskExists(int iId, AMX *pAmx) { - return m_Tasks.find(CTaskDescriptor(iId, pAmx)); + for (auto &task : m_Tasks) + { + if (task->match(iId, pAmx)) + { + return true; + } + } + return false; } void CTaskMngr::startFrame() { - for (TaskListIter iter = m_Tasks.begin(); iter; ++iter) + for (auto &task : m_Tasks) { - if (iter->isFree()) + if (task->isFree()) continue; - iter->executeIfRequired(*m_pTmr_CurrentTime, *m_pTmr_TimeLimit, *m_pTmr_TimeLeft); + task->executeIfRequired(*m_pTmr_CurrentTime, *m_pTmr_TimeLimit, *m_pTmr_TimeLeft); } } diff --git a/amxmodx/CTask.h b/amxmodx/CTask.h index 4eb83af9..c1876afe 100755 --- a/amxmodx/CTask.h +++ b/amxmodx/CTask.h @@ -51,41 +51,18 @@ private: inline bool inExecute() const { return m_bInExecute; } bool shouldRepeat(); + + inline bool match(int id, AMX *amx) + { + return (!m_bFree) && (amx ? getAMX() == amx : true) && (m_iId == id); + } CTask(); ~CTask(); }; - class CTaskDescriptor - { - public: - cell m_iId; - AMX *m_pAmx; - bool m_bFree; - - CTaskDescriptor(int iId, AMX *pAmx, bool bFree = false) - { - m_iId = iId; - m_pAmx = pAmx; - m_bFree = bFree; - } - - friend bool operator == (const CTask &left, const CTaskDescriptor &right) - { - if (right.m_bFree) - return (left.isFree() && !left.inExecute()); - - return (!left.isFree()) && - (right.m_pAmx ? left.getAMX() == right.m_pAmx : true) && - (left.getTaskId() == right.m_iId); - } - }; - /*** CTaskMngr priv members ***/ - typedef CList TaskList; - typedef TaskList::iterator TaskListIter; - - TaskList m_Tasks; + ke::Vector> m_Tasks; float *m_pTmr_CurrentTime; float *m_pTmr_TimeLimit; diff --git a/amxmodx/CVault.h b/amxmodx/CVault.h index 52c5d378..3d354234 100755 --- a/amxmodx/CVault.h +++ b/amxmodx/CVault.h @@ -10,8 +10,6 @@ #ifndef VAULT_CUSTOM_H #define VAULT_CUSTOM_H -#include "CList.h" - // ***************************************************** // class Vault // ***************************************************** diff --git a/amxmodx/CvarManager.cpp b/amxmodx/CvarManager.cpp index daf5f3e1..88b447a0 100644 --- a/amxmodx/CvarManager.cpp +++ b/amxmodx/CvarManager.cpp @@ -11,10 +11,13 @@ #include "amxmodx.h" #include #include +#include CvarManager g_CvarManager; -DETOUR_DECL_STATIC2(Cvar_DirectSet, void, struct cvar_s*, var, const char*, value) +void (*Cvar_DirectSet_Actual)(struct cvar_s* var, const char *value) = nullptr; + +void Cvar_DirectSet_Custom(struct cvar_s *var, const char *value, IRehldsHook_Cvar_DirectSet *chain = nullptr) { CvarInfo* info = nullptr; @@ -22,7 +25,7 @@ DETOUR_DECL_STATIC2(Cvar_DirectSet, void, struct cvar_s*, var, const char*, valu || strcmp(var->string, value) == 0 // Make sure old and new values are different to not trigger callbacks. || !g_CvarManager.CacheLookup(var->name, &info)) // No data in cache, nothing to do. { - DETOUR_STATIC_CALL(Cvar_DirectSet)(var, value); + chain ? chain->callNext(var, value) : Cvar_DirectSet_Actual(var, value); return; } @@ -56,7 +59,7 @@ DETOUR_DECL_STATIC2(Cvar_DirectSet, void, struct cvar_s*, var, const char*, valu oldValue = var->string; } - DETOUR_STATIC_CALL(Cvar_DirectSet)(var, value); + chain ? chain->callNext(var, value) : Cvar_DirectSet_Actual(var, value); if (!info->binds.empty()) { @@ -100,7 +103,18 @@ DETOUR_DECL_STATIC2(Cvar_DirectSet, void, struct cvar_s*, var, const char*, valu } } -CvarManager::CvarManager() : m_AmxmodxCvars(0), m_HookDetour(nullptr) +void Cvar_DirectSet(struct cvar_s *var, const char *value) +{ + Cvar_DirectSet_Custom(var, value); +} + +void Cvar_DirectSet_RH(IRehldsHook_Cvar_DirectSet *chain, cvar_t *var, const char *value) +{ + Cvar_DirectSet_Custom(var, value, chain); +} + + +CvarManager::CvarManager() : m_AmxmodxCvars(0), m_HookDetour(nullptr), m_ReHookEnabled(false) { } @@ -116,16 +130,61 @@ void CvarManager::CreateCvarHook(void) // Cvar_DirectSet(var, value); // <- We want to hook this. // } - void *functionAddress = nullptr; + if (!RehldsHookchains) + { + void *functionAddress = nullptr; - if (CommonConfig && CommonConfig->GetMemSig("Cvar_DirectSet", &functionAddress) && functionAddress) - { - // Disabled by default. - m_HookDetour = DETOUR_CREATE_STATIC_FIXED(Cvar_DirectSet, functionAddress); + if (CommonConfig && CommonConfig->GetMemSig("Cvar_DirectSet", &functionAddress) && functionAddress) + { + // Disabled by default. + m_HookDetour = DETOUR_CREATE_STATIC_FIXED(Cvar_DirectSet, functionAddress); + } + else + { + AMXXLOG_Log("Binding/Hooking cvars have been disabled - %s.", RehldsApi ? "update ReHLDS" : "check your gamedata files"); + } } - else +} + +void CvarManager::EnableHook() +{ + if (RehldsHookchains) { - AMXXLOG_Log("Binding/Hooking cvars have been disabled - check your gamedata files."); + if (!m_ReHookEnabled) + { + RehldsHookchains->Cvar_DirectSet()->registerHook(Cvar_DirectSet_RH); + m_ReHookEnabled = true; + } + } + else if (m_HookDetour) + { + m_HookDetour->EnableDetour(); + } +} + +void CvarManager::DisableHook() +{ + if (RehldsHookchains) + { + if (m_ReHookEnabled) + { + RehldsHookchains->Cvar_DirectSet()->unregisterHook(Cvar_DirectSet_RH); + m_ReHookEnabled = false; + } + } + else if (m_HookDetour) + { + m_HookDetour->DisableDetour(); + } +} + +void CvarManager::DestroyHook() +{ + DisableHook(); + + if (m_HookDetour) + { + m_HookDetour->Destroy(); } } @@ -205,9 +264,9 @@ CvarInfo* CvarManager::CreateCvar(const char* name, const char* value, const cha // Detour is disabled on map change. // Don't enable it unless there are things to do. - if ((info->bound.hasMin || info->bound.hasMax) && m_HookDetour) + if ((info->bound.hasMin || info->bound.hasMax)) { - m_HookDetour->EnableDetour(); + EnableHook(); } return info; @@ -295,11 +354,8 @@ AutoForward* CvarManager::HookCvarChange(cvar_t* var, AMX* amx, cell param, cons return nullptr; } - // Detour is disabled on map change. - if (m_HookDetour) - { - m_HookDetour->EnableDetour(); - } + // Hook is disabled on map change. + EnableHook(); AutoForward* forward = new AutoForward(forwardId, *callback); info->hooks.append(new CvarHook(g_plugins.findPlugin(amx)->getId(), forward)); @@ -351,11 +407,8 @@ bool CvarManager::BindCvar(CvarInfo* info, CvarBind::CvarType type, AMX* amx, ce break; } - // Detour is disabled on map change. - if (m_HookDetour) - { - m_HookDetour->EnableDetour(); - } + // Hook is disabled on map change. + EnableHook(); return true; } @@ -367,11 +420,8 @@ void CvarManager::SetCvarMin(CvarInfo* info, bool set, float value, int pluginId if (set) { - // Detour is disabled on map change. - if (m_HookDetour) - { - m_HookDetour->EnableDetour(); - } + // Hook is disabled on map change. + EnableHook(); info->bound.minVal = value; @@ -393,11 +443,8 @@ void CvarManager::SetCvarMax(CvarInfo* info, bool set, float value, int pluginId if (set) { - // Detour is disabled on map change. - if (m_HookDetour) - { - m_HookDetour->EnableDetour(); - } + // Hook is disabled on map change. + EnableHook(); info->bound.maxVal = value; @@ -584,12 +631,9 @@ void CvarManager::OnPluginUnloaded() (*cvar)->hooks.clear(); } - // There is no point to enable detour if at next map change + // There is no point to enable hook if at next map change // no plugins hook cvars. - if (m_HookDetour) - { - m_HookDetour->DisableDetour(); - } + DisableHook(); } void CvarManager::OnAmxxShutdown() @@ -619,8 +663,5 @@ void CvarManager::OnAmxxShutdown() m_Cache.clear(); - if (m_HookDetour) - { - m_HookDetour->Destroy(); - } + DestroyHook(); } diff --git a/amxmodx/CvarManager.h b/amxmodx/CvarManager.h index 88f23825..dabc0aaf 100644 --- a/amxmodx/CvarManager.h +++ b/amxmodx/CvarManager.h @@ -142,6 +142,9 @@ class CvarManager public: void CreateCvarHook(); + void EnableHook(); + void DisableHook(); + void DestroyHook(); CvarInfo* CreateCvar(const char* name, const char* value, const char* plugin, int pluginId, int flags = 0, const char* helpText = ""); CvarInfo* FindCvar(const char* name); @@ -166,6 +169,7 @@ class CvarManager CvarsList m_Cvars; size_t m_AmxmodxCvars; CDetour* m_HookDetour; + bool m_ReHookEnabled; }; extern CvarManager g_CvarManager; diff --git a/amxmodx/amxmodx.cpp b/amxmodx/amxmodx.cpp index 716f9932..b913cef8 100755 --- a/amxmodx/amxmodx.cpp +++ b/amxmodx/amxmodx.cpp @@ -35,7 +35,7 @@ static cell AMX_NATIVE_CALL get_xvar_id(AMX *amx, cell *params) for (CPluginMngr::iterator a = g_plugins.begin(); a ; ++a) { - if ((*a).isValid() && amx_FindPubVar((*a).getAMX(), sName, &ptr) == AMX_ERR_NONE) + if ((*a).isValid() && amx_FindPubVar((*a).getAMX(), sName, &ptr) == AMX_ERR_NONE) return g_xvars.put((*a).getAMX(), get_amxaddr((*a).getAMX(), ptr)); } @@ -78,13 +78,13 @@ static cell AMX_NATIVE_CALL emit_sound(AMX *amx, cell *params) /* 7 param */ for (int i = 1; i <= gpGlobals->maxClients ; ++i) { CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); - + if (pPlayer->ingame) EMIT_SOUND_DYN2(pPlayer->pEdict, channel, szSample, vol, att, flags, pitch); } } else { edict_t* pEdict = TypeConversion.id_to_edict(params[1]); - + if (!FNullEnt(pEdict)) EMIT_SOUND_DYN2(pEdict, channel, szSample, vol, att, flags, pitch); } @@ -97,14 +97,14 @@ static cell AMX_NATIVE_CALL server_print(AMX *amx, cell *params) /* 1 param */ int len; g_langMngr.SetDefLang(LANG_SERVER); // Default language = server char* message = format_amxstring(amx, params, 1, len); - + if (len > 254) len = 254; - + message[len++] = '\n'; message[len] = 0; SERVER_PRINT(message); - + return len; } @@ -113,13 +113,13 @@ static cell AMX_NATIVE_CALL engclient_print(AMX *amx, cell *params) /* 3 param * int len = 0; char *msg; PRINT_TYPE type = (PRINT_TYPE)params[2]; - + if (params[1] == 0) { for (int i = 1; i <= gpGlobals->maxClients; ++i) { CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); - + if ((type == print_console && pPlayer->initialized) || pPlayer->ingame) { g_langMngr.SetDefLang(i); @@ -137,9 +137,9 @@ static cell AMX_NATIVE_CALL engclient_print(AMX *amx, cell *params) /* 3 param * LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if ((type == print_console && pPlayer->initialized) || pPlayer->ingame) { g_langMngr.SetDefLang(index); @@ -149,7 +149,7 @@ static cell AMX_NATIVE_CALL engclient_print(AMX *amx, cell *params) /* 3 param * CLIENT_PRINT(pPlayer->pEdict, type, msg); } } - + return len; } @@ -159,7 +159,7 @@ static cell AMX_NATIVE_CALL console_cmd(AMX *amx, cell *params) /* 2 param */ g_langMngr.SetDefLang(index); int len; char* cmd = format_amxstring(amx, params, 2, len); - + cmd[len++] = '\n'; cmd[len] = 0; @@ -168,7 +168,7 @@ static cell AMX_NATIVE_CALL console_cmd(AMX *amx, cell *params) /* 2 param */ SERVER_COMMAND(cmd); } else { CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (!pPlayer->IsBot() && pPlayer->initialized) CLIENT_COMMAND(pPlayer->pEdict, "%s", cmd); } @@ -317,7 +317,7 @@ static cell AMX_NATIVE_CALL client_print_color(AMX *amx, cell *params) /* 3 para int index = params[1]; int sender = params[2]; - if (sender < print_team_blue || sender > gpGlobals->maxClients) + if (sender < print_team_blue || sender > gpGlobals->maxClients) { sender = print_team_default; } @@ -358,7 +358,7 @@ static cell AMX_NATIVE_CALL client_print_color(AMX *amx, cell *params) /* 3 para UTIL_ClientSayText(pPlayer->pEdict, sender ? sender : i, msg); } } - } + } else { if (index < 1 || index > gpGlobals->maxClients) @@ -368,7 +368,7 @@ static cell AMX_NATIVE_CALL client_print_color(AMX *amx, cell *params) /* 3 para } CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (pPlayer->ingame && !pPlayer->IsBot()) { g_langMngr.SetDefLang(index); @@ -392,7 +392,7 @@ static cell AMX_NATIVE_CALL client_print_color(AMX *amx, cell *params) /* 3 para msg[len++] = '\n'; msg[len] = 0; - + UTIL_ClientSayText(pPlayer->pEdict, sender ? sender : index, msg); } } @@ -404,52 +404,52 @@ static cell AMX_NATIVE_CALL show_motd(AMX *amx, cell *params) /* 3 param */ { int ilen; const char* szHead = get_amxstring(amx, params[3], 0, ilen); - + if (!ilen) szHead = hostname->string; char* szBody = get_amxstring(amx, params[2], 1, ilen); int iFile = 0; char* sToShow = NULL; // = szBody; - + if (ilen < 128) sToShow = (char*)LOAD_FILE_FOR_ME(szBody, &iFile); - + if (!iFile) sToShow = szBody; else ilen = iFile; - + if (params[1] == 0) { for (int i = 1; i <= gpGlobals->maxClients; ++i) { CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); - + if (pPlayer->ingame) UTIL_ShowMOTD(pPlayer->pEdict, sToShow, ilen, szHead); } } else { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); if (iFile) FREE_FILE(sToShow); - + return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (pPlayer->ingame) UTIL_ShowMOTD(pPlayer->pEdict, sToShow, ilen, szHead); } - + if (iFile) FREE_FILE(sToShow); - + return 1; } @@ -468,7 +468,7 @@ static cell AMX_NATIVE_CALL next_hudchannel(AMX *amx, cell *params) LogError(amx, AMX_ERR_NATIVE, "Player %d not in game", index); return 0; } - + return pPlayer->NextHUDChannel(); } @@ -490,7 +490,7 @@ static cell AMX_NATIVE_CALL set_hudmessage(AMX *amx, cell *params) /* 11 param * g_hudset.fadeinTime = amx_ctof(params[9]); g_hudset.fadeoutTime = amx_ctof(params[10]); g_hudset.channel = params[11]; - + return 1; } @@ -506,7 +506,7 @@ static cell AMX_NATIVE_CALL show_hudmessage(AMX *amx, cell *params) /* 2 param * * "channel" stores the valid channel that core uses. * "g_hudset.channel" stores the direct channel passed to the engine. */ - + bool aut = (g_hudset.channel == -1) ? true : false; int channel = -1; if (!aut) @@ -522,7 +522,7 @@ static cell AMX_NATIVE_CALL show_hudmessage(AMX *amx, cell *params) /* 2 param * for (int i = 1; i <= gpGlobals->maxClients; ++i) { CPlayer *pPlayer = GET_PLAYER_POINTER_I(i); - + if (pPlayer->ingame) { g_langMngr.SetDefLang(i); @@ -541,15 +541,15 @@ static cell AMX_NATIVE_CALL show_hudmessage(AMX *amx, cell *params) /* 2 param * } else { message = UTIL_SplitHudMessage(format_amxstring(amx, params, 2, len)); int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (pPlayer->ingame) { if (aut) @@ -562,7 +562,7 @@ static cell AMX_NATIVE_CALL show_hudmessage(AMX *amx, cell *params) /* 2 param * UTIL_HudMessage(pPlayer->pEdict, g_hudset, message); } } - + return len; } @@ -642,7 +642,7 @@ static cell AMX_NATIVE_CALL show_dhudmessage(AMX *amx, cell *params) /* 2 param len = 127; // Don't truncate a double-byte character - if (((message[len - 1] & 0xFF) >= 0xC2) && ((message[len - 1] & 0xFF) <= 0xEF)) + if (((message[len - 1] & 0xFF) >= 0xC2) && ((message[len - 1] & 0xFF) <= 0xEF)) { --len; } @@ -672,11 +672,11 @@ static cell AMX_NATIVE_CALL get_user_index(AMX *amx, cell *params) /* 1 param */ { int i; char* sptemp = get_amxstring(amx, params[1], 0, i); - + for (i = 1; i <= gpGlobals->maxClients; ++i) { CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); - + if (strcmp(pPlayer->name.chars(), sptemp) == 0) return i; } @@ -725,57 +725,57 @@ static cell AMX_NATIVE_CALL is_map_valid(AMX *amx, cell *params) /* 1 param */ static cell AMX_NATIVE_CALL is_user_connected(AMX *amx, cell *params) /* 1 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) return 0; - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + return (pPlayer->ingame ? 1 : 0); } static cell AMX_NATIVE_CALL is_user_connecting(AMX *amx, cell *params) /* 1 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) return 0; CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + return (!pPlayer->ingame && pPlayer->initialized && (GETPLAYERUSERID(pPlayer->pEdict) > 0)) ? 1 : 0; } static cell AMX_NATIVE_CALL is_user_bot(AMX *amx, cell *params) /* 1 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) return 0; - + return (GET_PLAYER_POINTER_I(index)->IsBot() ? 1 : 0); } static cell AMX_NATIVE_CALL is_user_hltv(AMX *amx, cell *params) /* 1 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) return 0; CPlayer *pPlayer = GET_PLAYER_POINTER_I(index); - + if (!pPlayer->initialized) return 0; - + if (pPlayer->pEdict->v.flags & FL_PROXY) return 1; - + const char *authid = GETPLAYERAUTHID(pPlayer->pEdict); - + if (authid && stricmp(authid, "HLTV") == 0) return 1; - + return 0; } @@ -783,24 +783,24 @@ extern bool g_bmod_tfc; static cell AMX_NATIVE_CALL is_user_alive(AMX *amx, cell *params) /* 1 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) { return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); if (g_bmod_tfc) { edict_t *e = pPlayer->pEdict; - if (e->v.flags & FL_SPECTATOR || + if (e->v.flags & FL_SPECTATOR || (!e->v.team || !e->v.playerclass)) { return 0; } } - + return ((pPlayer->ingame && pPlayer->IsAlive()) ? 1 : 0); } @@ -812,60 +812,60 @@ static cell AMX_NATIVE_CALL get_amxx_verstring(AMX *amx, cell *params) /* 2 para static cell AMX_NATIVE_CALL get_user_frags(AMX *amx, cell *params) /* 1 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) return 0; - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + return (cell)(pPlayer->ingame ? pPlayer->pEdict->v.frags : 0); } static cell AMX_NATIVE_CALL get_user_deaths(AMX *amx, cell *params) /* 1 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) return 0; - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + return (cell)(pPlayer->ingame ? pPlayer->deaths : 0); } static cell AMX_NATIVE_CALL get_user_armor(AMX *amx, cell *params) /* 1 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) return 0; - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + return (cell)(pPlayer->ingame ? pPlayer->pEdict->v.armorvalue : 0); } static cell AMX_NATIVE_CALL get_user_health(AMX *amx, cell *params) /* param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) return 0; - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + return (cell)(pPlayer->ingame ? pPlayer->pEdict->v.health : 0); } static cell AMX_NATIVE_CALL get_user_userid(AMX *amx, cell *params) /* 1 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) return 0; - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + return pPlayer->initialized ? GETPLAYERUSERID(pPlayer->pEdict) : -1; } @@ -873,33 +873,33 @@ static cell AMX_NATIVE_CALL get_user_authid(AMX *amx, cell *params) /* 3 param * { int index = params[1]; const char* authid = 0; - + if (index > 0 && index <= gpGlobals->maxClients) authid = GETPLAYERAUTHID(g_players[index].pEdict); - + return set_amxstring(amx, params[2], authid ? authid : "", params[3]); } static cell AMX_NATIVE_CALL is_user_authorized(AMX *amx, cell *params) { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) return 0; - + return GET_PLAYER_POINTER_I(index)->authorized; } static cell AMX_NATIVE_CALL get_weaponname(AMX *amx, cell *params) /* 3 param */ { int index = params[1]; - + if (index < 1 || index >= MAX_WEAPONS) { LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", index); return 0; } - + return set_amxstring(amx, params[2], g_weaponsData[index].fullName.chars(), params[3]); } @@ -920,7 +920,7 @@ static cell AMX_NATIVE_CALL get_weaponid(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_user_weapons(AMX *amx, cell *params) /* 3 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); @@ -928,21 +928,21 @@ static cell AMX_NATIVE_CALL get_user_weapons(AMX *amx, cell *params) /* 3 param } CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (pPlayer->ingame) { cell *cpNum = get_amxaddr(amx, params[3]); cell *cpIds = get_amxaddr(amx, params[2]); *cpIds = 0; - + int weapons = pPlayer->pEdict->v.weapons & ~(1<<31); // don't count last element - + if (g_bmod_dod) { // Don't ignore that last element for dod weapons = pPlayer->pEdict->v.weapons; } - + for (int i = 1; i < MAX_WEAPONS; ++i) { if (weapons & (1< gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (pPlayer->ingame) { int mode = params[3]; cell *cpOrigin = get_amxaddr(amx, params[2]); - + if (mode == 4) { cpOrigin[0] = (long int)pPlayer->lastHit.x; @@ -981,47 +981,47 @@ static cell AMX_NATIVE_CALL get_user_origin(AMX *amx, cell *params) /* 3 param * cpOrigin[2] = (long int)pPlayer->lastHit.z; return 1; } - + edict_t* edict = pPlayer->pEdict; Vector pos = edict->v.origin; - + if (mode && mode != 2) pos = pos + edict->v.view_ofs; - + if (mode > 1) { Vector vec; Vector v_angle = edict->v.v_angle; float v_vec[3]; - + v_vec[0] = v_angle.x; v_vec[1] = v_angle.y; v_vec[2] = v_angle.z; - + ANGLEVECTORS(v_vec, vec, NULL, NULL); TraceResult trEnd; Vector v_dest = pos + vec * 9999; - + float f_pos[3]; f_pos[0] = pos.x; f_pos[1] = pos.y; f_pos[2] = pos.z; - + float f_dest[3]; f_dest[0] = v_dest.x; f_dest[1] = v_dest.y; f_dest[2] = v_dest.z; - + TRACE_LINE(f_pos, f_dest, 0, edict, &trEnd); pos = (trEnd.flFraction < 1.0) ? trEnd.vecEndPos : Vector(0, 0, 0); } cpOrigin[0] = (long int)pos.x; cpOrigin[1] = (long int)pos.y; cpOrigin[2] = (long int)pos.z; - + return 1; } - + return 0; } @@ -1031,33 +1031,33 @@ static cell AMX_NATIVE_CALL get_user_ip(AMX *amx, cell *params) /* 3 param */ char *ptr; char szIp[32]; strcpy(szIp, (index < 1 || index > gpGlobals->maxClients) ? CVAR_GET_STRING("net_address") : g_players[index].ip.chars()); - + if (params[4] && (ptr = strstr(szIp, ":")) != 0) *ptr = '\0'; - + return set_amxstring(amx, params[2], szIp, params[3]); } static cell AMX_NATIVE_CALL get_user_attacker(AMX *amx, cell *params) /* 2 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); edict_t *enemy = NULL; - + if (pPlayer->ingame) { enemy = pPlayer->pEdict->v.dmg_inflictor; if (!FNullEnt(enemy)) { int weapon = 0; - + if (enemy->v.flags & (FL_CLIENT | FL_FAKECLIENT)) { pPlayer = GET_PLAYER_POINTER(enemy); @@ -1090,23 +1090,23 @@ static cell AMX_NATIVE_CALL get_user_attacker(AMX *amx, cell *params) /* 2 param } } } - + return (enemy ? pPlayer->index : 0); } static cell AMX_NATIVE_CALL user_has_weapon(AMX *amx, cell *params) { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); edict_t *pEntity = pPlayer->pEdict; - + if (params[3] == -1) { if ((pEntity->v.weapons & (1< 0) @@ -1121,7 +1121,7 @@ static cell AMX_NATIVE_CALL user_has_weapon(AMX *amx, cell *params) pEntity->v.weapons &= ~(1< gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (pPlayer->ingame) { int wpn = pPlayer->current; @@ -1157,66 +1157,66 @@ static cell AMX_NATIVE_CALL get_user_weapon(AMX *amx, cell *params) /* 3 param * *cpTemp = pPlayer->weapons[wpn].clip; cpTemp = get_amxaddr(amx, params[3]); *cpTemp = pPlayer->weapons[wpn].ammo; - + return wpn; } - + return 0; } static cell AMX_NATIVE_CALL get_user_ammo(AMX *amx, cell *params) /* 4 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (pPlayer->ingame) { int wpn = params[2]; - + if (wpn < 1 || wpn >= MAX_WEAPONS) { LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", wpn); return 0; } - + cell *cpTemp = get_amxaddr(amx, params[3]); *cpTemp = pPlayer->weapons[wpn].clip; cpTemp = get_amxaddr(amx, params[4]); *cpTemp = pPlayer->weapons[wpn].ammo; - + return 1; } - + return 0; } static cell AMX_NATIVE_CALL get_user_team(AMX *amx, cell *params) /* 3 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) return -1; - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (pPlayer->ingame) { // SidLuke, DoD fix if (g_bmod_dod) { int iTeam = pPlayer->pEdict->v.team; - + if (params[3]) { const char *szTeam = ""; - + switch (iTeam) { case 1: @@ -1226,7 +1226,7 @@ static cell AMX_NATIVE_CALL get_user_team(AMX *amx, cell *params) /* 3 param */ szTeam = "Axis"; break; } - + set_amxstring(amx, params[2], szTeam, params[3]); } return iTeam; @@ -1239,7 +1239,7 @@ static cell AMX_NATIVE_CALL get_user_team(AMX *amx, cell *params) /* 3 param */ return pPlayer->teamId; } - + return -1; } @@ -1307,17 +1307,17 @@ static cell AMX_NATIVE_CALL show_menu(AMX *amx, cell *params) /* 3 param */ char *sMenu = get_amxstring(amx, params[3], 0, ilen); char *lMenu = get_amxstring(amx, params[5], 1, ilen2); int menuid = 0; - + if (ilen2 && lMenu) { menuid = g_menucmds.findMenuId(lMenu, amx); } else { menuid = g_menucmds.findMenuId(sMenu, amx); } - + int keys = params[2]; int time = params[4]; - + if (index == 0) { for (int i = 1; i <= gpGlobals->maxClients; ++i) @@ -1329,32 +1329,32 @@ static cell AMX_NATIVE_CALL show_menu(AMX *amx, cell *params) /* 3 param */ pPlayer->keys = keys; pPlayer->menu = menuid; pPlayer->vgui = false; - + if (time == -1) pPlayer->menuexpire = INFINITE; else pPlayer->menuexpire = gpGlobals->time + static_cast(time); - + pPlayer->page = 0; UTIL_ShowMenu(pPlayer->pEdict, keys, time, sMenu, ilen); } } - } else { + } else { CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); pPlayer->keys = keys; pPlayer->menu = menuid; - pPlayer->vgui = false; + pPlayer->vgui = false; if (time == -1) pPlayer->menuexpire = INFINITE; else pPlayer->menuexpire = gpGlobals->time + static_cast(time); - + pPlayer->page = 0; UTIL_ShowMenu(pPlayer->pEdict, keys, time, sMenu, ilen); } - + return 1; } @@ -1370,7 +1370,7 @@ static cell AMX_NATIVE_CALL register_plugin(AMX *amx, cell *params) /* 3 param * #if defined BINLOG_ENABLED g_BinLog.WriteOp(BinLog_Registered, a->getId(), title, vers); #endif - + a->setTitle(title); a->setVersion(vers); a->setAuthor(author); @@ -1399,7 +1399,7 @@ static cell AMX_NATIVE_CALL register_plugin(AMX *amx, cell *params) /* 3 param * } i++; } - + return a->getId(); } @@ -1410,7 +1410,7 @@ static cell AMX_NATIVE_CALL register_menucmd(AMX *amx, cell *params) /* 3 param char* sptemp = get_amxstring(amx, params[3], 0, ilen); idx = registerSPForwardByName(amx, sptemp, FP_CELL, FP_CELL, FP_CELL, FP_DONE); - + if (idx == -1) { LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", sptemp); @@ -1438,7 +1438,7 @@ static cell AMX_NATIVE_CALL get_plugin(AMX *amx, cell *params) /* 11 param */ set_amxstring(amx, params[6], a->getVersion(), params[7]); set_amxstring(amx, params[8], a->getAuthor(), params[9]); set_amxstring(amx, params[10], a->getStatus(), params[11]); - + if (params[0] / sizeof(cell) >= 12) { cell *jit_info = get_amxaddr(amx, params[12]); @@ -1468,9 +1468,9 @@ static cell AMX_NATIVE_CALL amx_md5_file(AMX *amx, cell *params) { int len; char *str = get_amxstring(amx, params[1], 0, len); - char file[255]; + char file[PLATFORM_MAX_PATH]; - build_pathname_r(file, sizeof(file)-1, "%s", str); + build_pathname_r(file, sizeof(file), "%s", str); const char *hash = hashFile((const char *)file, Hash_Md5); if (!hash) @@ -1502,8 +1502,8 @@ static cell AMX_NATIVE_CALL amx_hash_file(AMX *amx, cell *params) { int len; char *str = get_amxstring(amx, params[1], 0, len); - char file[255]; - build_pathname_r(file, sizeof(file)-1, "%s", str); + char file[PLATFORM_MAX_PATH]; + build_pathname_r(file, sizeof(file), "%s", str); HashType type = (HashType)params[2]; @@ -1528,9 +1528,9 @@ static cell AMX_NATIVE_CALL register_concmd(AMX *amx, cell *params) CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast(amx); int i, idx = 0; char* temp = get_amxstring(amx, params[2], 0, i); - + idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE); - + if (idx == -1) { LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp); @@ -1562,10 +1562,10 @@ static cell AMX_NATIVE_CALL register_concmd(AMX *amx, cell *params) { plugin->AddToFailCounter(1); } - + cmd->setCmdType(CMD_ConsoleCommand); REG_SVR_COMMAND((char*)cmd->getCommand(), plugin_srvcmd); - + return cmd->getId(); } @@ -1575,15 +1575,15 @@ static cell AMX_NATIVE_CALL register_clcmd(AMX *amx, cell *params) CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast(amx); int i, idx = 0; char* temp = get_amxstring(amx, params[2], 0, i); - + idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE); - + if (idx == -1) { LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp); return 0; } - + temp = get_amxstring(amx, params[1], 0, i); const char* info = get_amxstring(amx, params[4], 1, i); CmdMngr::Command* cmd; @@ -1604,9 +1604,9 @@ static cell AMX_NATIVE_CALL register_clcmd(AMX *amx, cell *params) if ((cmd = g_commands.registerCommand(plugin, idx, temp, info, access, listable, info_ml)) == NULL) return 0; - + cmd->setCmdType(CMD_ClientCommand); - + return cmd->getId(); } @@ -1616,15 +1616,15 @@ static cell AMX_NATIVE_CALL register_srvcmd(AMX *amx, cell *params) CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast(amx); int i, idx = 0; char* temp = get_amxstring(amx, params[2], 0, i); - + idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE); - + if (idx == -1) { LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp); return 0; } - + temp = get_amxstring(amx, params[1], 0, i); const char* info = get_amxstring(amx, params[4], 1, i); CmdMngr::Command* cmd; @@ -1640,10 +1640,10 @@ static cell AMX_NATIVE_CALL register_srvcmd(AMX *amx, cell *params) if ((cmd = g_commands.registerCommand(plugin, idx, temp, info, access, listable, info_ml)) == NULL) return 0; - + cmd->setCmdType(CMD_ServerCommand); REG_SVR_COMMAND((char*)cmd->getCommand(), plugin_srvcmd); - + return cmd->getId(); } @@ -1663,7 +1663,7 @@ static cell AMX_NATIVE_CALL get_concmd(AMX *amx, cell *params) if (cmd == 0) return 0; - + set_amxstring_utf8(amx, params[2], cmd->getCmdLine(), strlen(cmd->getCmdLine()), params[3]); set_amxstring_utf8(amx, params[5], cmd->getCmdInfo(), strlen(cmd->getCmdInfo()), params[6]); cell *cpFlags = get_amxaddr(amx, params[4]); @@ -1703,13 +1703,13 @@ static cell AMX_NATIVE_CALL get_concmd_plid(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_clcmd(AMX *amx, cell *params) { CmdMngr::Command* cmd = g_commands.getCmd(params[1], CMD_ClientCommand, params[7]); - + if (cmd == 0) return 0; set_amxstring_utf8(amx, params[2], cmd->getCmdLine(), strlen(cmd->getCmdLine()), params[3]); set_amxstring_utf8(amx, params[5], cmd->getCmdInfo(), strlen(cmd->getCmdInfo()), params[6]); - + cell *cpFlags = get_amxaddr(amx, params[4]); *cpFlags = cmd->getFlags(); @@ -1725,10 +1725,10 @@ static cell AMX_NATIVE_CALL get_clcmd(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_srvcmd(AMX *amx, cell *params) { CmdMngr::Command* cmd = g_commands.getCmd(params[1], CMD_ServerCommand, params[7]); - + if (cmd == 0) return 0; - + set_amxstring_utf8(amx, params[2], cmd->getCmdLine(), strlen(cmd->getCmdLine()), params[3]); set_amxstring_utf8(amx, params[5], cmd->getCmdInfo(), strlen(cmd->getCmdInfo()), params[6]); cell *cpFlags = get_amxaddr(amx, params[4]); @@ -1755,12 +1755,12 @@ static cell AMX_NATIVE_CALL get_clcmdsnum(AMX *amx, cell *params) /* 1 param */ static cell AMX_NATIVE_CALL get_concmdsnum(AMX *amx, cell *params) /* 1 param */ { int who = params[2]; - + if (who > 0) return g_commands.getCmdNum(CMD_ClientCommand, params[1]); if (who == 0) return g_commands.getCmdNum(CMD_ServerCommand, params[1]); - + return g_commands.getCmdNum(CMD_ConsoleCommand, params[1]); } @@ -1782,7 +1782,7 @@ static cell AMX_NATIVE_CALL register_event(AMX *amx, cell *params) const char* callback = get_amxstring(amx, params[2], 0, len); forwardId = registerSPForwardByName(amx, callback, FP_CELL, FP_DONE); - + if (forwardId == -1) { LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", callback); @@ -1847,20 +1847,20 @@ static cell AMX_NATIVE_CALL disable_event(AMX *amx, cell *params) static cell AMX_NATIVE_CALL user_kill(AMX *amx, cell *params) /* 2 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) return 0; - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (pPlayer->ingame && pPlayer->IsAlive()) { float bef = pPlayer->pEdict->v.frags; MDLL_ClientKill(pPlayer->pEdict); - + if (params[2]) pPlayer->pEdict->v.frags = bef; - + return 1; } @@ -1870,7 +1870,7 @@ static cell AMX_NATIVE_CALL user_kill(AMX *amx, cell *params) /* 2 param */ static cell AMX_NATIVE_CALL user_slap(AMX *amx, cell *params) /* 2 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) return 0; @@ -1880,7 +1880,7 @@ static cell AMX_NATIVE_CALL user_slap(AMX *amx, cell *params) /* 2 param */ power = 0; CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (pPlayer->ingame && pPlayer->IsAlive()) { if (pPlayer->pEdict->v.health <= power) @@ -1891,7 +1891,7 @@ static cell AMX_NATIVE_CALL user_slap(AMX *amx, cell *params) /* 2 param */ } else { edict_t *pEdict = pPlayer->pEdict; int numparam = *params / sizeof(cell); - + if (numparam < 3 || params[3]) { pEdict->v.velocity.x += RANDOM_LONG(-600, 600); @@ -1907,20 +1907,20 @@ static cell AMX_NATIVE_CALL user_slap(AMX *amx, cell *params) /* 2 param */ ANGLEVECTORS(fang, v_forward, v_right, NULL); pEdict->v.velocity = pEdict->v.velocity + v_forward * 220 + Vector(0, 0, 200); } - + pEdict->v.punchangle.x = static_cast(RANDOM_LONG(-10, 10)); pEdict->v.punchangle.y = static_cast(RANDOM_LONG(-10, 10)); pEdict->v.health -= power; - + int armor = (int)pEdict->v.armorvalue; armor -= power; - + if (armor < 0) armor = 0; - + pEdict->v.armorvalue = static_cast(armor); pEdict->v.dmg_inflictor = pEdict; - + if (g_bmod_cstrike) { static const char *cs_sound[4] = @@ -1941,7 +1941,7 @@ static cell AMX_NATIVE_CALL user_slap(AMX *amx, cell *params) /* 2 param */ EMIT_SOUND_DYN2(pEdict, CHAN_VOICE, bit_sound[RANDOM_LONG(0, 2)], 1.0, ATTN_NORM, 0, PITCH_NORM); } } - + return 1; } @@ -1960,7 +1960,7 @@ static cell AMX_NATIVE_CALL server_cmd(AMX *amx, cell *params) /* 1 param */ SERVER_COMMAND(cmd); CoreCfg.CheckLegacyBufferedCommand(cmd); - + return len; } @@ -1981,19 +1981,19 @@ static cell AMX_NATIVE_CALL client_cmd(AMX *amx, cell *params) /* 2 param */ } } else { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (!pPlayer->IsBot() && pPlayer->initialized /*&& pPlayer->ingame*/) CLIENT_COMMAND(pPlayer->pEdict, "%s", cmd); } - + return len; } @@ -2002,12 +2002,12 @@ static cell AMX_NATIVE_CALL log_message(AMX *amx, cell *params) /* 1 param */ int len; g_langMngr.SetDefLang(LANG_SERVER); char* message = format_amxstring(amx, params, 1, len); - + message[len++] = '\n'; message[len] = 0; - + ALERT(at_logged, "%s", message); - + return len; } @@ -2016,50 +2016,50 @@ static cell AMX_NATIVE_CALL log_to_file(AMX *amx, cell *params) /* 1 param */ int ilen; char* szFile = get_amxstring(amx, params[1], 0, ilen); FILE*fp; - char file[256]; - + char file[PLATFORM_MAX_PATH]; + if (strchr(szFile, '/') || strchr(szFile, '\\')) { - build_pathname_r(file, sizeof(file) - 1, "%s", szFile); + build_pathname_r(file, sizeof(file), "%s", szFile); } else { - build_pathname_r(file, sizeof(file) - 1, "%s/%s", g_log_dir.chars(), szFile); + build_pathname_r(file, sizeof(file), "%s/%s", g_log_dir.chars(), szFile); } - + bool first_time = true; - + if ((fp = fopen(file, "r")) != NULL) { first_time = false; fclose(fp); } - + if ((fp = fopen(file, "a")) == NULL) { //amx_RaiseError(amx, AMX_ERR_NATIVE); //would cause too much troubles in old plugins return 0; } - + char date[32]; time_t td; time(&td); strftime(date, 31, "%m/%d/%Y - %H:%M:%S", localtime(&td)); int len; g_langMngr.SetDefLang(LANG_SERVER); char* message = format_amxstring(amx, params, 2, len); - + message[len++] = '\n'; message[len] = 0; - + if (first_time) { fprintf(fp, "L %s: Log file started (file \"%s\") (game \"%s\") (amx \"%s\")\n", date, file, g_mod_name.chars(), Plugin_info.version); print_srvconsole("L %s: Log file started (file \"%s\") (game \"%s\") (amx \"%s\")\n", date, file, g_mod_name.chars(), Plugin_info.version); } - + fprintf(fp, "L %s: %s", date, message); print_srvconsole("L %s: %s", date, message); fclose(fp); - + return 1; } @@ -2067,7 +2067,7 @@ static cell AMX_NATIVE_CALL num_to_word(AMX *amx, cell *params) /* 3 param */ { char sptemp[512]; UTIL_IntToString(params[1], sptemp); - + return set_amxstring(amx, params[2], sptemp, params[3]); } @@ -2090,10 +2090,10 @@ static cell AMX_NATIVE_CALL get_time(AMX *amx, cell *params) /* 3 param */ char* sptemp = get_amxstring(amx, params[1], 0, ilen); time_t td = time(NULL); tm* lt = localtime(&td); - + char szDate[512]; strftime(szDate, 511, sptemp, lt); - + return set_amxstring(amx, params[2], szDate, params[3]); } @@ -2104,16 +2104,16 @@ static cell AMX_NATIVE_CALL format_time(AMX *amx, cell *params) /* 3 param */ time_t tim = params[4]; time_t td = (tim != -1) ? tim : time(NULL); tm* lt = localtime(&td); - + if (lt == 0) { LogError(amx, AMX_ERR_NATIVE, "Couldn't get localtime"); return 0; } - + char szDate[512]; ilen = strftime(szDate, 511, sptemp, lt); - + return set_amxstring_utf8(amx, params[1], szDate, ilen, params[2]); } @@ -2125,32 +2125,32 @@ static cell AMX_NATIVE_CALL parse_time(AMX *amx, cell *params) /* 3 param */ char* sFormat = get_amxstring(amx, params[2], 0, ilen); tm* mytime; time_t td; - + if (params[3] == -1) { td = time(NULL); mytime = localtime(&td); - + if (mytime == 0) { LogError(amx, AMX_ERR_NATIVE, "Couldn't get localtime"); return 0; } - + strptime(sTime, sFormat, mytime, 0); } else { td = params[3]; mytime = localtime(&td); - + if (mytime == 0) { LogError(amx, AMX_ERR_NATIVE, "Couldn't get localtime"); return 0; } - + strptime(sTime, sFormat, mytime, 1); } - + return mktime(mytime); } @@ -2158,7 +2158,7 @@ static cell AMX_NATIVE_CALL get_systime(AMX *amx, cell *params) /* 3 param */ { time_t td = time(NULL); td += params[1]; - + return td; } @@ -2173,13 +2173,13 @@ static cell AMX_NATIVE_CALL read_data(AMX *amx, cell *params) /* 3 param */ { return g_events.getCurrentMsgType(); } - + switch (*params / sizeof(cell)) { case 1: return g_events.getArgInteger(params[1]); case 3: - return set_amxstring_utf8(amx, params[2], g_events.getArgString(params[1]), + return set_amxstring_utf8(amx, params[2], g_events.getArgString(params[1]), strlen(g_events.getArgString(params[1])),*get_amxaddr(amx, params[3])); default: cell *fCell = get_amxaddr(amx, params[2]); @@ -2200,11 +2200,11 @@ static cell AMX_NATIVE_CALL get_playersnum(AMX *amx, cell *params) return g_players_num; int a = 0; - + for (int i = 1; i <= gpGlobals->maxClients; ++i) { CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); - + if (pPlayer->initialized && (GETPLAYERUSERID(pPlayer->pEdict) > 0)) ++a; } @@ -2265,7 +2265,7 @@ static cell AMX_NATIVE_CALL get_players(AMX *amx, cell *params) /* 4 param */ } *iMax = iNum; - + return 1; } @@ -2277,12 +2277,12 @@ static cell AMX_NATIVE_CALL find_player(AMX *amx, cell *params) /* 1 param */ int ilen, userid = 0; char* sptemp = get_amxstring(amx, params[1], 0, ilen); int flags = UTIL_ReadFlags(sptemp); - + if (flags & 31) sptemp = get_amxstring(amx, params[2], 0, ilen); else if (flags & 1024) userid = *get_amxaddr(amx, params[2]); - + // a b c d e f g h i j k l int result = 0; @@ -2291,25 +2291,25 @@ static cell AMX_NATIVE_CALL find_player(AMX *amx, cell *params) /* 1 param */ func = strcasecmp; else func = strcmp; - + for (int i = 1; i <= gpGlobals->maxClients; ++i) { CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); - + if (pPlayer->ingame || ((flags & 4096) && pPlayer->initialized)) { if (pPlayer->IsAlive() ? (flags & 64) : (flags & 32)) continue; - + if (pPlayer->IsBot() ? (flags & 128) : (flags & 256)) continue; - + if (flags & 1) { if ((func)(pPlayer->name.chars(), sptemp)) continue; } - + if (flags & 2) { if (flags & 2048) @@ -2320,35 +2320,35 @@ static cell AMX_NATIVE_CALL find_player(AMX *amx, cell *params) /* 1 param */ else if (strstr(pPlayer->name.chars(), sptemp) == NULL) continue; } - + if (flags & 4) { const char* authid = GETPLAYERAUTHID(pPlayer->pEdict); - + if (!authid || (func)(authid, sptemp)) continue; } - + if (flags & 1024) { if (userid != GETPLAYERUSERID(pPlayer->pEdict)) continue; } - + if (flags & 8) { if (strncmp(pPlayer->ip.chars(), sptemp, ilen)) continue; } - + if (flags & 16) { if ((func)(pPlayer->team.chars(), sptemp)) continue; } - + result = i; - + if ((flags & 512) == 0) break; } @@ -2382,7 +2382,7 @@ static cell AMX_NATIVE_CALL get_localinfo(AMX *amx, cell *params) /* 3 param */ { int ilen; char* sptemp = get_amxstring(amx, params[1], 0, ilen); - + char *value = LOCALINFO(sptemp); return set_amxstring_utf8(amx, params[2], value, strlen(value), params[3]); } @@ -2392,33 +2392,33 @@ static cell AMX_NATIVE_CALL set_localinfo(AMX *amx, cell *params) /* 2 param */ int ilen; char* sptemp = get_amxstring(amx, params[1], 0, ilen); char* szValue = get_amxstring(amx, params[2], 1, ilen); - + SET_LOCALINFO(sptemp, szValue); - + return 1; } static cell AMX_NATIVE_CALL get_user_info(AMX *amx, cell *params) /* 4 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (!pPlayer->pEdict) { LogError(amx, AMX_ERR_NATIVE, "Player %d is not connected", index); return 0; } - + int ilen; char* sptemp = get_amxstring(amx, params[2], 0, ilen); - + return set_amxstring(amx, params[3], ENTITY_KEYVALUE(pPlayer->pEdict, sptemp), params[4]); return 1; } @@ -2426,27 +2426,27 @@ static cell AMX_NATIVE_CALL get_user_info(AMX *amx, cell *params) /* 4 param */ static cell AMX_NATIVE_CALL set_user_info(AMX *amx, cell *params) /* 3 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (!pPlayer->pEdict) { LogError(amx, AMX_ERR_NATIVE, "Player %d is not connected", index); return 0; } - + int ilen; char* sptemp = get_amxstring(amx, params[2], 0, ilen); char* szValue = get_amxstring(amx, params[3], 1, ilen); - + ENTITY_SET_KEYVALUE(pPlayer->pEdict, sptemp, szValue); - + return 1; } @@ -2502,7 +2502,7 @@ static cell AMX_NATIVE_CALL get_user_msgid(AMX *amx, cell *params) /* 1 param */ { int ilen; char* sptemp = get_amxstring(amx, params[1], 0, ilen); - + return GET_USER_MSG_ID(PLID, sptemp, NULL); } @@ -2531,7 +2531,7 @@ static cell AMX_NATIVE_CALL set_task(AMX *amx, cell *params) /* 2 param */ } else { iFunc = registerSPForwardByName(amx, stemp, FP_CELL, FP_DONE); } - + if (iFunc == -1) { LogError(amx, AMX_ERR_NATIVE, "Function is not present (function \"%s\") (plugin \"%s\")", stemp, plugin->getName()); @@ -2567,7 +2567,7 @@ static cell AMX_NATIVE_CALL engine_changelevel(AMX *amx, cell *params) const char* new_map = get_amxstring(amx, params[1], 0, length); // Same as calling "changelevel" command but will trigger "server_changelevel" AMXX forward as well. - // Filling second param will call "changelevel2" command, but this is not usable in multiplayer game. + // Filling second param will call "changelevel2" command, but this is not usable in multiplayer game. g_pEngTable->pfnChangeLevel(new_map, NULL); return 1; @@ -2581,12 +2581,12 @@ static cell AMX_NATIVE_CALL task_exists(AMX *amx, cell *params) /* 1 param */ static cell AMX_NATIVE_CALL get_user_ping(AMX *amx, cell *params) /* 3 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) return 0; - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (pPlayer->ingame) { cell *cpPing = get_amxaddr(amx, params[2]); @@ -2595,28 +2595,28 @@ static cell AMX_NATIVE_CALL get_user_ping(AMX *amx, cell *params) /* 3 param */ PLAYER_CNX_STATS(pPlayer->pEdict, &ping, &loss); *cpPing = ping; *cpLoss = loss; - + return 1; } - + return 0; } static cell AMX_NATIVE_CALL get_user_time(AMX *amx, cell *params) /* 1 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) return 0; CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (pPlayer->ingame) { int time = (int)(gpGlobals->time - (params[2] ? pPlayer->playtime : pPlayer->time)); return time; } - + return 0; } @@ -2631,39 +2631,39 @@ int sendFakeCommand(AMX *amx, cell *params, bool fwd = false) int ilen; const char* szCmd = get_amxstring(amx, params[2], 0, ilen); const char* sArg1 = get_amxstring(amx, params[3], 1, ilen); - + if (ilen == 0) sArg1 = 0; - + const char* sArg2 = get_amxstring(amx, params[4], 2, ilen); - + if (ilen == 0) sArg2 = 0; - + if (params[1] == 0) { for (int i = 1; i <= gpGlobals->maxClients; ++i) { CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); - + if (pPlayer->ingame /*&& pPlayer->initialized */) UTIL_FakeClientCommand(pPlayer->pEdict, szCmd, sArg1, sArg2, fwd); } } else { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (/*pPlayer->initialized && */pPlayer->ingame) UTIL_FakeClientCommand(pPlayer->pEdict, szCmd, sArg1, sArg2, fwd); } - + return 1; } static cell AMX_NATIVE_CALL engclient_cmd(AMX *amx, cell *params) /* 4 param */ @@ -2696,7 +2696,7 @@ static cell AMX_NATIVE_CALL pause(AMX *amx, cell *params) /* 3 param */ } else plugin = g_plugins.findPluginFast(amx); - + if (plugin && plugin->isValid()) { if (flags & 8) @@ -2705,10 +2705,10 @@ static cell AMX_NATIVE_CALL pause(AMX *amx, cell *params) /* 3 param */ plugin->setStatus(ps_locked);*/ else plugin->pausePlugin(); - + return 1; } - + return 0; } @@ -2719,7 +2719,7 @@ static cell AMX_NATIVE_CALL unpause(AMX *amx, cell *params) /* 3 param */ char* sptemp = get_amxstring(amx, params[1], 0, ilen); int flags = UTIL_ReadFlags(sptemp); CPluginMngr::CPlugin *plugin = 0; - + if (flags & 2) { LogError(amx, AMX_ERR_NATIVE, "This usage of the native pause() has been deprecated!"); @@ -2732,7 +2732,7 @@ static cell AMX_NATIVE_CALL unpause(AMX *amx, cell *params) /* 3 param */ } else plugin = g_plugins.findPluginFast(amx); - + if (plugin && plugin->isValid() && plugin->isPaused() && !plugin->isStopped()) { plugin->unpausePlugin(); @@ -2747,7 +2747,7 @@ static cell AMX_NATIVE_CALL read_flags(AMX *amx, cell *params) /* 1 param */ { int ilen; char* sptemp = get_amxstring(amx, params[1], 0, ilen); - + return UTIL_ReadFlags(sptemp); } @@ -2755,78 +2755,78 @@ static cell AMX_NATIVE_CALL get_flags(AMX *amx, cell *params) /* 1 param */ { char flags[32]; UTIL_GetFlags(flags, params[1]); - + return set_amxstring(amx, params[2], flags, params[3]); } static cell AMX_NATIVE_CALL get_user_flags(AMX *amx, cell *params) /* 2 param */ { int index = params[1]; - + if (index < 0 || index > gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + int id = params[2]; - + if (id < 0) id = 0; - + if (id > 31) id = 31; - + return GET_PLAYER_POINTER_I(index)->flags[id]; } static cell AMX_NATIVE_CALL set_user_flags(AMX *amx, cell *params) /* 3 param */ { int index = params[1]; - + if (index < 0 || index > gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); int flag = params[2]; int id = params[3]; - + if (id < 0) id = 0; - + if (id > 31) id = 31; - + pPlayer->flags[id] |= flag; - + return 1; } static cell AMX_NATIVE_CALL remove_user_flags(AMX *amx, cell *params) /* 3 param */ { int index = params[1]; - + if (index < 0 || index > gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); int flag = params[2]; int id = params[3]; - + if (id < 0) id = 0; - + if (id > 31) id = 31; - + pPlayer->flags[id] &= ~flag; - + return 1; } @@ -2835,24 +2835,24 @@ static cell AMX_NATIVE_CALL register_menuid(AMX *amx, cell *params) /* 1 param * int i; char* temp = get_amxstring(amx, params[1], 0, i); AMX* a = (*params / sizeof(cell) < 2 || params[2]) ? 0 : amx; - + return g_menucmds.registerMenuId(temp, a); } static cell AMX_NATIVE_CALL get_user_menu(AMX *amx, cell *params) /* 3 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + cell *cpMenu = get_amxaddr(amx, params[2]); cell *cpKeys = get_amxaddr(amx, params[3]); CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (pPlayer->ingame) { if (gpGlobals->time > pPlayer->menuexpire) @@ -2861,19 +2861,19 @@ static cell AMX_NATIVE_CALL get_user_menu(AMX *amx, cell *params) /* 3 param */ pMenu->Close(pPlayer->index); else pPlayer->menu = 0; - + *cpMenu = 0; *cpKeys = 0; - + return 0; } *cpMenu = pPlayer->menu; *cpKeys = pPlayer->keys; - + return 1; } - + return 0; } @@ -2884,10 +2884,10 @@ static cell AMX_NATIVE_CALL precache_sound(AMX *amx, cell *params) /* 1 param */ LogError(amx, AMX_ERR_NATIVE, "Precaching not allowed"); return 0; } - + int len; char* sptemp = get_amxstring(amx, params[1], 0, len); - + return PRECACHE_SOUND((char*)STRING(ALLOC_STRING(sptemp))); } @@ -2898,10 +2898,10 @@ static cell AMX_NATIVE_CALL precache_model(AMX *amx, cell *params) /* 1 param */ LogError(amx, AMX_ERR_NATIVE, "Precaching not allowed"); return 0; } - + int len; char* sptemp = get_amxstring(amx, params[1], 0, len); - + return PRECACHE_MODEL((char*)STRING(ALLOC_STRING(sptemp))); } @@ -2932,7 +2932,7 @@ static cell AMX_NATIVE_CALL random_float(AMX *amx, cell *params) /* 2 param */ float one = amx_ctof(params[1]); float two = amx_ctof(params[2]); REAL fRnd = RANDOM_FLOAT(one, two); - + return amx_ftoc(fRnd); } @@ -2944,53 +2944,53 @@ static cell AMX_NATIVE_CALL random_num(AMX *amx, cell *params) /* 2 param */ static cell AMX_NATIVE_CALL remove_quotes(AMX *amx, cell *params) /* 1 param */ { cell *text = get_amxaddr(amx, params[1]); - + if (*text == '\"') { register cell *temp = text; int len = 0; - + while (*temp++) ++len; // get length - + cell *src = text; - + if (src[len-1] == '\r') src[--len] = 0; - + if (src[--len] == '\"') { src[len] = 0; temp = src + 1; while ((*src++ = *temp++)); - + return 1; } } - + return 0; } static cell AMX_NATIVE_CALL get_user_aiming(AMX *amx, cell *params) /* 4 param */ { int index = params[1]; - + if (index < 1 || index > gpGlobals->maxClients) { LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); cell *cpId = get_amxaddr(amx, params[2]); cell *cpBody = get_amxaddr(amx, params[3]); - + REAL pfloat = 0.0f; if (pPlayer->ingame) { edict_t* edict = pPlayer->pEdict; - + Vector v_forward; Vector v_src = edict->v.origin + edict->v.view_ofs; @@ -2998,10 +2998,10 @@ static cell AMX_NATIVE_CALL get_user_aiming(AMX *amx, cell *params) /* 4 param * TraceResult trEnd; Vector v_dest = v_src + v_forward * static_cast(params[4]); TRACE_LINE(v_src, v_dest, 0, edict, &trEnd); - + *cpId = FNullEnt(trEnd.pHit) ? 0 : ENTINDEX(trEnd.pHit); *cpBody = trEnd.iHitgroup; - + if (trEnd.flFraction < 1.0) { pfloat = (trEnd.vecEndPos - v_src).Length(); @@ -3010,32 +3010,34 @@ static cell AMX_NATIVE_CALL get_user_aiming(AMX *amx, cell *params) /* 4 param * *cpId = 0; *cpBody = 0; } - + return amx_ftoc(pfloat); } static cell AMX_NATIVE_CALL force_unmodified(AMX *amx, cell *params) { int a; - + cell *cpVec1 = get_amxaddr(amx, params[2]); cell *cpVec2 = get_amxaddr(amx, params[3]); - + Vector vec1 = Vector((float)cpVec1[0], (float)cpVec1[1], (float)cpVec1[2]); Vector vec2 = Vector((float)cpVec2[0], (float)cpVec2[1], (float)cpVec2[2]); - + char* filename = get_amxstring(amx, params[4], 0, a); - ForceObject* aaa = new ForceObject(filename, (FORCE_TYPE)((int)(params[1])), vec1, vec2, amx); + auto object = ke::AutoPtr(new ForceObject(filename, (FORCE_TYPE)((int)(params[1])), vec1, vec2, amx)); - if (aaa) + if (object) { + auto forceObjVec = &g_forcegeneric; + if (stristr(filename, ".wav")) - g_forcesounds.put(aaa); + forceObjVec = &g_forcesounds; else if (stristr(filename, ".mdl")) - g_forcemodels.put(aaa); - else - g_forcegeneric.put(aaa); + forceObjVec = &g_forcemodels; + + forceObjVec->append(ke::Move(object)); return 1; } @@ -3064,7 +3066,7 @@ static cell AMX_NATIVE_CALL parse_loguser(AMX *amx, cell *params) { int len; char *text = get_amxstring(amx, params[1], 0, len); - + if (len < 6) // no user to parse!? { LogError(amx, AMX_ERR_NATIVE, "No user name specified"); @@ -3074,71 +3076,71 @@ static cell AMX_NATIVE_CALL parse_loguser(AMX *amx, cell *params) /******** GET TEAM **********/ char* end = text + --len; *end = 0; - + while (*end != '<' && len--) --end; - + ++end; cell *cPtr = get_amxaddr(amx, params[7]); int max = params[8]; // get TEAM // print_srvconsole("Got team: %s (Len %d)\n", end, len); - + while (max-- && *end) *cPtr++ = *end++; - + *cPtr = 0; - + /******** GET AUTHID **********/ if (len <= 0) { LogError(amx, AMX_ERR_NATIVE, "No Authid found"); return 0; } - + end = text + --len; *end = 0; - + while (*end != '<' && len--) --end; - + ++end; cPtr = get_amxaddr(amx, params[5]); max = params[6]; // get AUTHID // print_srvconsole("Got auth: %s (Len %d)\n", end, len); - + while (max-- && *end) *cPtr++ = *end++; - + *cPtr = 0; - + /******** GET USERID **********/ if (len <= 0) { LogError(amx, AMX_ERR_NATIVE, "No Userid found"); return 0; } - + end = text + --len; *end = 0; - + while (*end != '<' && len--) --end; - + // print_srvconsole("Got userid: %s (Len %d)\n", end + 1, len); if (*(cPtr = get_amxaddr(amx, params[4])) != -2) *cPtr = atoi(end + 1); - + /******** GET NAME **********/ *end = 0; cPtr = get_amxaddr(amx, params[2]); max = params[3]; // get NAME // print_srvconsole("Got name: %s (Len %d)\n", text, len); - + while (max-- && *text) *cPtr++ = *text++; - + *cPtr = 0; - + return 1; } @@ -3166,7 +3168,7 @@ static cell AMX_NATIVE_CALL register_logevent(AMX *amx, cell *params) auto logevent = LogEventHandles.lookup(handle)->m_logevent; auto numparam = *params / sizeof(cell); - for (auto i = 3; i <= numparam; ++i) + for (auto i = 3U; i <= numparam; ++i) { logevent->registerFilter(get_amxstring(amx, params[i], 0, length)); } @@ -3213,15 +3215,15 @@ static cell AMX_NATIVE_CALL is_module_loaded(AMX *amx, cell *params) int len; char *name = get_amxstring(amx, params[1], 0, len); int id = 0; - - for (CList::iterator iter = g_modules.begin(); iter; ++iter) + + for (auto module : g_modules) { - if (stricmp((*iter).getName(), name) == 0) + if (!stricmp(module->getName(), name)) return id; - + ++id; } - + return -1; } @@ -3233,7 +3235,7 @@ static cell AMX_NATIVE_CALL is_plugin_loaded(AMX *amx, cell *params) int len; char *name = get_amxstring(amx, params[1], 0, len); int id = 0; - + if (params[0] / sizeof(cell) == 1 || // compiled pre-1.8 - assume plugin's registered name params[2] == 0) // compiled post 1.8 - wants plugin's registered name { @@ -3242,7 +3244,7 @@ static cell AMX_NATIVE_CALL is_plugin_loaded(AMX *amx, cell *params) { if (stricmp((*iter).getTitle(), name) == 0) return id; - + ++id; } } @@ -3254,11 +3256,11 @@ static cell AMX_NATIVE_CALL is_plugin_loaded(AMX *amx, cell *params) { if (strcmp((*iter).getName(), name) == 0) return id; - + ++id; } } - + return -1; } @@ -3282,7 +3284,7 @@ static cell AMX_NATIVE_CALL register_byval(AMX *amx, cell *params) char *dtr = strdup("nrolne"); char *p = dtr; int len, ret = 0; - + //get the destination string char *data = get_amxstring(amx, params[2], 0, len); void *PT = NULL; @@ -3292,13 +3294,13 @@ static cell AMX_NATIVE_CALL register_byval(AMX *amx, cell *params) //check for validity AMXXLOG_Log("[AMXX] Test: %s", dtr); - + if (strcmp(data, dtr) == 0) { ret = 1; int idx = params[1]; CPlayer *pPlayer = GET_PLAYER_POINTER_I(idx); - + if (pPlayer->ingame) { ret = 2; @@ -3318,13 +3320,13 @@ static cell AMX_NATIVE_CALL register_byval(AMX *amx, cell *params) char *alt = strdup("ottrolne"); p = alt; ucy(p, alt); - + if (strcmp(data, alt) == 0) { //restore the necessary states int idx = params[1]; CPlayer *pPlayer = GET_PLAYER_POINTER_I(idx); - + if (pPlayer->ingame) { ret = 2; @@ -3350,63 +3352,63 @@ static cell AMX_NATIVE_CALL register_byval(AMX *amx, cell *params) //restore memory free(alt); } - + p = dtr; - + //restore original ycu(dtr, p); free(dtr); - + return ret; } // native get_module(id, name[], nameLen, author[], authorLen, version[], versionLen, &status); static cell AMX_NATIVE_CALL get_module(AMX *amx, cell *params) { - CList::iterator moduleIter; - // find the module int i = params[1]; - - for (moduleIter = g_modules.begin(); moduleIter && i; ++moduleIter) - --i; - if (i != 0 || !moduleIter) - return -1; // not found - - // set name, author, version - if ((*moduleIter).isAmxx()) - { - const amxx_module_info_s *info = (*moduleIter).getInfoNew(); - const char *name = info && info->name ? info->name : "unk"; - const char *author = info && info->author ? info->author : "unk"; - const char *version = info && info->version ? info->version : "unk"; - - set_amxstring_utf8(amx, params[2], name, strlen(name), params[3]); - set_amxstring_utf8(amx, params[4], author, strlen(author), params[5]); - set_amxstring_utf8(amx, params[6], version, strlen(version), params[7]); - } - - // compatibility problem possible - int numParams = params[0] / sizeof(cell); - - if (numParams < 8) + for (auto module : g_modules) { - LogError(amx, AMX_ERR_NATIVE, "Call to incompatible version"); - return 0; + if (i--) + { + continue; + } + + // set name, author, version + if (module->isAmxx()) + { + const amxx_module_info_s *info = module->getInfoNew(); + const char *name = info && info->name ? info->name : "unk"; + const char *author = info && info->author ? info->author : "unk"; + const char *version = info && info->version ? info->version : "unk"; + + set_amxstring_utf8(amx, params[2], name, strlen(name), params[3]); + set_amxstring_utf8(amx, params[4], author, strlen(author), params[5]); + set_amxstring_utf8(amx, params[6], version, strlen(version), params[7]); + } + + // compatibility problem possible + int numParams = params[0] / sizeof(cell); + + if (numParams < 8) + { + LogError(amx, AMX_ERR_NATIVE, "Call to incompatible version"); + return 0; + } + + // set status + cell *addr; + if (amx_GetAddr(amx, params[8], &addr) != AMX_ERR_NONE) + { + LogError(amx, AMX_ERR_NATIVE, "Invalid reference plugin"); + return 0; + } + + *addr = (cell)module->getStatusValue(); + return params[1]; } - - // set status - cell *addr; - if (amx_GetAddr(amx, params[8], &addr) != AMX_ERR_NONE) - { - LogError(amx, AMX_ERR_NATIVE, "Invalid reference plugin"); - return 0; - } - - *addr = (cell)(*moduleIter).getStatusValue(); - - return params[1]; + return -1; } // native log_amx(const msg[], ...); @@ -3417,7 +3419,7 @@ static cell AMX_NATIVE_CALL log_amx(AMX *amx, cell *params) g_langMngr.SetDefLang(LANG_SERVER); AMXXLOG_Log("[%s] %s", plugin->getName(), format_amxstring(amx, params, 1, len)); - + return 0; } @@ -3450,7 +3452,7 @@ int g_CallFunc_CurParam = 0; // Current param id static cell AMX_NATIVE_CALL callfunc_begin(AMX *amx, cell *params) { CPluginMngr::CPlugin *curPlugin = g_plugins.findPluginFast(amx); - + if (g_CallFunc_Plugin) { // scripter's fault @@ -3462,7 +3464,7 @@ static cell AMX_NATIVE_CALL callfunc_begin(AMX *amx, cell *params) char *pluginStr = get_amxstring(amx, params[2], 0, len); char *funcStr = get_amxstring(amx, params[1], 1, len); CPluginMngr::CPlugin *plugin = NULL; - + if (!pluginStr || !*pluginStr) plugin = curPlugin; else @@ -3474,7 +3476,7 @@ static cell AMX_NATIVE_CALL callfunc_begin(AMX *amx, cell *params) } int func; - + if (amx_FindPublic(plugin->getAMX(), funcStr, &func) != AMX_ERR_NONE) { return -2; // func not found: -2 @@ -3492,7 +3494,7 @@ static cell AMX_NATIVE_CALL callfunc_begin(AMX *amx, cell *params) static cell AMX_NATIVE_CALL callfunc_begin_i(AMX *amx, cell *params) { CPluginMngr::CPlugin *plugin; - + if (params[2] < 0) plugin = g_plugins.findPluginFast(amx); else @@ -3528,7 +3530,7 @@ static cell AMX_NATIVE_CALL callfunc_begin_i(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_func_id(AMX *amx, cell *params) { CPluginMngr::CPlugin *plugin; - + if (params[2] < 0) { plugin = g_plugins.findPluginFast(amx); @@ -3549,7 +3551,7 @@ static cell AMX_NATIVE_CALL get_func_id(AMX *amx, cell *params) int len; const char *funcName = get_amxstring(amx, params[1], 0, len); int index, err; - + if ((err = amx_FindPublic(plugin->getAMX(), funcName, &index)) != AMX_ERR_NONE) { index = -1; @@ -3562,7 +3564,7 @@ static cell AMX_NATIVE_CALL get_func_id(AMX *amx, cell *params) static cell AMX_NATIVE_CALL callfunc_end(AMX *amx, cell *params) { CPluginMngr::CPlugin *curPlugin = g_plugins.findPluginFast(amx); - + if (!g_CallFunc_Plugin) { // scripter's fault @@ -3627,7 +3629,7 @@ static cell AMX_NATIVE_CALL callfunc_end(AMX *amx, cell *params) { amx_Push(pAmx, gparams[i]); } - + err = amx_Exec(pAmx, &retVal, func); if (err != AMX_ERR_NONE) @@ -3659,9 +3661,9 @@ static cell AMX_NATIVE_CALL callfunc_end(AMX *amx, cell *params) AMX_HEADER *hdrCaller = (AMX_HEADER *)amxCaller->base; AMX_HEADER *hdrCalled = (AMX_HEADER *)amxCalled->base; memcpy( /** DEST ADDR **/ - (amxCaller->data ? amxCaller->data : (amxCaller->base + hdrCaller->dat)) + gparamInfo[i].byrefAddr, + (amxCaller->data ? amxCaller->data : (amxCaller->base + hdrCaller->dat)) + gparamInfo[i].byrefAddr, /** SOURCE ADDR **/ - (amxCalled->data ? amxCalled->data : (amxCalled->base + hdrCalled->dat)) + gparams[i], + (amxCalled->data ? amxCalled->data : (amxCalled->base + hdrCalled->dat)) + gparams[i], /** SIZE **/ gparamInfo[i].size * sizeof(cell)); } @@ -3702,7 +3704,7 @@ static cell AMX_NATIVE_CALL callfunc_push_byval(AMX *amx, cell *params) static cell AMX_NATIVE_CALL callfunc_push_byref(AMX *amx, cell *params) { CPluginMngr::CPlugin *curPlugin = g_plugins.findPluginFast(amx); - + if (!g_CallFunc_Plugin) { // scripter's fault @@ -3847,7 +3849,7 @@ static cell AMX_NATIVE_CALL callfunc_push_str(AMX *amx, cell *params) // get the string and its length int len; char *str = get_amxstring(amx, params[1], 0, len); - + // allocate enough memory for the string cell *phys_addr = new cell[len+1]; @@ -3891,9 +3893,9 @@ static cell AMX_NATIVE_CALL get_lang(AMX *amx, cell *params) static cell AMX_NATIVE_CALL register_dictionary(AMX *amx, cell *params) { int len; - static char file[256]; - int result = g_langMngr.MergeDefinitionFile(build_pathname_r(file, sizeof(file) - 1, "%s/lang/%s", get_localinfo("amxx_datadir", "addons/amxmodx/data"), get_amxstring(amx, params[1], 1, len))); - + static char file[PLATFORM_MAX_PATH]; + int result = g_langMngr.MergeDefinitionFile(build_pathname_r(file, sizeof(file), "%s/lang/%s", get_localinfo("amxx_datadir", "addons/amxmodx/data"), get_amxstring(amx, params[1], 1, len))); + return result; } @@ -3914,7 +3916,7 @@ static cell AMX_NATIVE_CALL plugin_flags(AMX *amx, cell *params) else { CPluginMngr::CPlugin* a = g_plugins.findPlugin((int)params[2]); - + if (a == NULL) { return 0; @@ -3998,7 +4000,7 @@ static cell AMX_NATIVE_CALL amx_abort(AMX *amx, cell *params) const char *filename = ""; CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx); - + if (pPlugin) filename = pPlugin->getName(); @@ -4038,7 +4040,7 @@ static cell AMX_NATIVE_CALL set_fail_state(AMX *amx, cell *params) int len; char* str; - g_langMngr.SetDefLang(LANG_SERVER); // Default language = server + g_langMngr.SetDefLang(LANG_SERVER); // Default language = server if (params[0] / sizeof(cell) > 1) str = format_amxstring(amx, params, 1, len); @@ -4046,13 +4048,13 @@ static cell AMX_NATIVE_CALL set_fail_state(AMX *amx, cell *params) str = get_amxstring(amx, params[1], 0, len); CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx); - + pPlugin->setStatus(ps_error); pPlugin->setError(str); AMXXLOG_Error("[AMXX] Plugin (\"%s\") is setting itself as failed.", pPlugin->getName()); AMXXLOG_Error("[AMXX] Plugin says: %s", str); - + LogError(amx, AMX_ERR_EXIT, NULL); //plugin dies once amx_Exec concludes @@ -4111,7 +4113,7 @@ static cell AMX_NATIVE_CALL CreateMultiForward(AMX *amx, cell *params) { ps[i-3] = *get_amxaddr(amx, params[i]); } - + return registerForwardC(funcname, static_cast(params[2]), ps, count-2); } @@ -4136,7 +4138,7 @@ static cell AMX_NATIVE_CALL CreateOneForward(AMX *amx, cell *params) { ps[i-3] = *get_amxaddr(amx, params[i]); } - + return registerSPForwardByNameC(p->getAMX(), funcname, ps, count-2); } @@ -4327,13 +4329,13 @@ static cell AMX_NATIVE_CALL ShowSyncHudMsg(AMX *amx, cell *params) } g_langMngr.SetDefLang(params[1]); - + if (index == 0) { for (int i = 1; i <= gpGlobals->maxClients; ++i) { CPlayer *pPlayer = GET_PLAYER_POINTER_I(i); - + int channel; if (pPlayer->ingame) { @@ -4352,9 +4354,9 @@ static cell AMX_NATIVE_CALL ShowSyncHudMsg(AMX *amx, cell *params) LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - + if (pPlayer->ingame) { int channel = pPlayer->NextHUDChannel(); @@ -4365,7 +4367,7 @@ static cell AMX_NATIVE_CALL ShowSyncHudMsg(AMX *amx, cell *params) UTIL_HudMessage(pPlayer->pEdict, g_hudset, message); } } - + return len; } @@ -4827,7 +4829,7 @@ AMX_NATIVE_INFO amxmodx_Natives[] = {"set_user_info", set_user_info}, {"set_xvar_float", set_xvar_num}, {"set_xvar_num", set_xvar_num}, - {"show_dhudmessage", show_dhudmessage}, + {"show_dhudmessage", show_dhudmessage}, {"show_hudmessage", show_hudmessage}, {"show_menu", show_menu}, {"show_motd", show_motd}, diff --git a/amxmodx/amxmodx.h b/amxmodx/amxmodx.h index 7cc05ab1..21048f4b 100755 --- a/amxmodx/amxmodx.h +++ b/amxmodx/amxmodx.h @@ -10,7 +10,7 @@ #ifndef AMXMODX_H #define AMXMODX_H -#if defined(__linux__) || defined(__APPLE__) +#if defined PLATFORM_POSIX #include #include #include "sclinux.h" @@ -23,21 +23,20 @@ #ifdef _MSC_VER // MSVC8 - replace POSIX functions with ISO C++ conformant ones as they are deprecated #if _MSC_VER >= 1400 - #define unlink _unlink + #define unlink _unlink #define mkdir _mkdir #define strdup _strdup #endif #endif #include "hashing.h" -#include "CList.h" -#include "CQueue.h" #include "modules.h" #include "CPlugin.h" #include "CLibrarySys.h" #include #include #include +#include #include "CMisc.h" #include "CVault.h" #include "CModule.h" @@ -75,7 +74,7 @@ extern AMX_NATIVE_INFO g_TextParserNatives[]; extern AMX_NATIVE_INFO g_CvarNatives[]; extern AMX_NATIVE_INFO g_GameConfigNatives[]; -#if defined(_WIN32) +#if defined PLATFORM_WINDOWS #define DLLOAD(path) (DLHANDLE)LoadLibrary(path) #define DLPROC(m, func) GetProcAddress(m, func) #define DLFREE(m) FreeLibrary(m) @@ -96,21 +95,13 @@ extern AMX_NATIVE_INFO g_GameConfigNatives[]; #endif #endif -#if defined(_WIN32) +#if defined PLATFORM_WINDOWS typedef HINSTANCE DLHANDLE; #else typedef void* DLHANDLE; #define INFINITE 0xFFFFFFFF #endif -#if defined(_WIN32) - #define PATH_SEP_CHAR '\\' - #define ALT_SEP_CHAR '/' -#else - #define PATH_SEP_CHAR '/' - #define ALT_SEP_CHAR '\\' -#endif - #ifndef GETPLAYERAUTHID #define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId) #endif @@ -136,7 +127,7 @@ void UTIL_ShowMenu(edict_t* pEntity, int slots, int time, char *menu, int mlen); void UTIL_ClientSayText(edict_t *pEntity, int sender, char *msg); void UTIL_TeamInfo(edict_t *pEntity, int playerIndex, const char *pszTeamName); -template int UTIL_CheckValidChar(D *c); +template int UTIL_CheckValidChar(D *c); template unsigned int strncopy(D *dest, const S *src, size_t count); unsigned int UTIL_GetUTF8CharBytes(const char *stream); unsigned int UTIL_ReplaceAll(char *subject, size_t maxlength, const char *search, const char *replace, bool caseSensitive); @@ -171,12 +162,12 @@ extern CFrameActionMngr g_frameActionMngr; extern CPlayer g_players[33]; extern CPlayer* mPlayer; extern CmdMngr g_commands; -extern CList g_forcemodels; -extern CList g_forcesounds; -extern CList g_forcegeneric; -extern CList g_modules; -extern CList g_loadedscripts; -extern CList g_auth; +extern ke::Vector> g_forcemodels; +extern ke::Vector> g_forcesounds; +extern ke::Vector> g_forcegeneric; +extern ke::Vector> g_auth; +extern ke::InlineList g_modules; +extern ke::InlineList g_loadedscripts; extern EventsMngr g_events; extern Grenades g_grenades; extern LogEventsMngr g_logevents; diff --git a/amxmodx/amxxlog.cpp b/amxmodx/amxxlog.cpp index 1611ef56..c9aa4914 100755 --- a/amxmodx/amxxlog.cpp +++ b/amxmodx/amxxlog.cpp @@ -44,7 +44,7 @@ void CLog::CloseFile() if (m_LogFile.length()) { FILE *fp = fopen(m_LogFile.chars(), "r"); - + if (fp) { fclose(fp); @@ -61,7 +61,7 @@ void CLog::CloseFile() fprintf(fp, "L %s: %s\n", date, "Log file closed."); fclose(fp); } - + m_LogFile = nullptr; } } @@ -69,33 +69,33 @@ void CLog::CloseFile() void CLog::CreateNewFile() { CloseFile(); - + // build filename time_t td; time(&td); tm *curTime = localtime(&td); - char file[256]; + char file[PLATFORM_MAX_PATH]; char name[256]; int i = 0; - + while (true) { ke::SafeSprintf(name, sizeof(name), "%s/L%02d%02d%03d.log", g_log_dir.chars(), curTime->tm_mon + 1, curTime->tm_mday, i); - build_pathname_r(file, sizeof(file)-1, "%s", name); + build_pathname_r(file, sizeof(file), "%s", name); FILE *pTmpFile = fopen(file, "r"); // open for reading to check whether the file exists - + if (!pTmpFile) break; - + fclose(pTmpFile); ++i; } m_LogFile = file; - + // Log logfile start FILE *fp = fopen(m_LogFile.chars(), "w"); - + if (!fp) { ALERT(at_logged, "[AMXX] Unexpected fatal logging error. AMXX Logging disabled.\n"); @@ -108,8 +108,8 @@ void CLog::CreateNewFile() void CLog::UseFile(const ke::AString &fileName) { - static char file[256]; - m_LogFile = build_pathname_r(file, sizeof(file) - 1, "%s/%s", g_log_dir.chars(), fileName.chars()); + static char file[PLATFORM_MAX_PATH]; + m_LogFile = build_pathname_r(file, sizeof(file), "%s/%s", g_log_dir.chars(), fileName.chars()); } void CLog::SetLogType(const char* localInfo) @@ -128,11 +128,11 @@ void CLog::SetLogType(const char* localInfo) void CLog::MapChange() { // create dir if not existing - char file[256]; + char file[PLATFORM_MAX_PATH]; #if defined(__linux__) || defined(__APPLE__) - mkdir(build_pathname_r(file, sizeof(file)-1, "%s", g_log_dir.chars()), 0700); + mkdir(build_pathname_r(file, sizeof(file), "%s", g_log_dir.chars()), 0700); #else - mkdir(build_pathname_r(file, sizeof(file) - 1, "%s", g_log_dir.chars())); + mkdir(build_pathname_r(file, sizeof(file), "%s", g_log_dir.chars())); #endif SetLogType("amxx_logging"); @@ -152,8 +152,8 @@ void CLog::MapChange() void CLog::Log(const char *fmt, ...) { - static char file[256]; - + static char file[PLATFORM_MAX_PATH]; + if (m_LogType == 1 || m_LogType == 2) { // get time @@ -180,7 +180,7 @@ void CLog::Log(const char *fmt, ...) { CreateNewFile(); pF = fopen(m_LogFile.chars(), "a+"); - + if (!pF) { ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Logging disabled for this map.\n", m_LogFile.chars()); @@ -189,10 +189,10 @@ void CLog::Log(const char *fmt, ...) } } } else { - build_pathname_r(file, sizeof(file) - 1, "%s/L%04d%02d%02d.log", g_log_dir.chars(), (curTime->tm_year + 1900), curTime->tm_mon + 1, curTime->tm_mday); + build_pathname_r(file, sizeof(file), "%s/L%04d%02d%02d.log", g_log_dir.chars(), (curTime->tm_year + 1900), curTime->tm_mon + 1, curTime->tm_mday); pF = fopen(file, "a+"); } - + if (pF) { fprintf(pF, "L %s: %s\n", date, msg); @@ -218,7 +218,7 @@ void CLog::Log(const char *fmt, ...) void CLog::LogError(const char *fmt, ...) { - static char file[256]; + static char file[PLATFORM_MAX_PATH]; static char name[256]; if (m_FoundError) @@ -244,7 +244,7 @@ void CLog::LogError(const char *fmt, ...) FILE *pF = NULL; ke::SafeSprintf(name, sizeof(name), "%s/error_%04d%02d%02d.log", g_log_dir.chars(), curTime->tm_year + 1900, curTime->tm_mon + 1, curTime->tm_mday); - build_pathname_r(file, sizeof(file)-1, "%s", name); + build_pathname_r(file, sizeof(file), "%s", name); pF = fopen(file, "a+"); if (pF) @@ -266,4 +266,3 @@ void CLog::LogError(const char *fmt, ...) // print on server console print_srvconsole("L %s: %s\n", date, msg); } - diff --git a/amxmodx/binlog.cpp b/amxmodx/binlog.cpp index 65ef5964..21542ed5 100644 --- a/amxmodx/binlog.cpp +++ b/amxmodx/binlog.cpp @@ -49,9 +49,9 @@ int LookupFile(AMX_DBG *amxdbg, ucell address) bool BinLog::Open() { const char *data = get_localinfo("amxmodx_datadir", "addons/amxmodx/data"); - char path[255]; - build_pathname_r(path, sizeof(path)-1, "%s/binlogs", data); - + char path[PLATFORM_MAX_PATH]; + build_pathname_r(path, sizeof(path), "%s/binlogs", data); + if (!DirExists(path)) { mkdir(path @@ -63,8 +63,8 @@ bool BinLog::Open() return false; } - char file[255]; - build_pathname_r(file, sizeof(file)-1, "%s/binlogs/lastlog", data); + char file[PLATFORM_MAX_PATH]; + build_pathname_r(file, sizeof(file), "%s/binlogs/lastlog", data); unsigned int lastcntr = 0; FILE *lastlog = fopen(file, "rb"); @@ -81,7 +81,7 @@ bool BinLog::Open() fwrite(&lastcntr, sizeof(int), 1, lastlog); fclose(lastlog); } - build_pathname_r(file, sizeof(file)-1, "%s/binlogs/binlog%04d.blg", data, lastcntr); + build_pathname_r(file, sizeof(file), "%s/binlogs/binlog%04d.blg", data, lastcntr); m_logfile = file; /** diff --git a/amxmodx/debugger.cpp b/amxmodx/debugger.cpp index a5406f0c..41281822 100755 --- a/amxmodx/debugger.cpp +++ b/amxmodx/debugger.cpp @@ -568,22 +568,26 @@ void Debugger::DisplayTrace(const char *message) const char *Debugger::_GetFilename() { - if (m_FileName.length() < 1) - { - const char *filename = ""; - CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(m_pAmx); - if (pl) - { - filename = pl->getName(); - } else { - CList::iterator a = g_loadedscripts.find(m_pAmx); - if (a) - filename = (*a).getName(); - } - m_FileName = filename; - } - - return m_FileName.chars(); + if (m_FileName.length() < 1) + { + CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(m_pAmx); + if (pl) + { + m_FileName = pl->getName(); + } + else + { + for (auto script : g_loadedscripts) + { + if (script->getAMX() == m_pAmx) + { + m_FileName = script->getName(); + break; + } + } + } + } + return m_FileName.chars(); } const char *Debugger::_GetVersion() @@ -605,31 +609,35 @@ const char *Debugger::_GetVersion() void Debugger::FmtGenericMsg(AMX *amx, int error, char buffer[], size_t maxLength) { - const char *filename = ""; - char native[sNAMEMAX+1]; + const char *filename = ""; + char native[sNAMEMAX+1]; + for (auto script : g_loadedscripts) + { + if (script->getAMX() == amx) + { + filename = script->getName(); + break; + } + } + size_t len = strlen(filename); + for (size_t i=len-1; i::iterator a = g_loadedscripts.find(amx); - if (a) - filename = (*a).getName(); - size_t len = strlen(filename); - for (size_t i=len-1; i(amx->usertags[UT_NATIVE]), native); - ke::SafeSprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") (native \"%s\") - debug not enabled!", error, filename, native); - } else { - ke::SafeSprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") - debug not enabled!", error, filename); - } + if (error == AMX_ERR_EXIT) + { + ke::SafeSprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") - %s", error, filename, GenericError(AMX_ERR_EXIT)); + } else if (error == AMX_ERR_NATIVE) { + amx_GetNative(amx, reinterpret_cast(amx->usertags[UT_NATIVE]), native); + ke::SafeSprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") (native \"%s\") - debug not enabled!", error, filename, native); + } else { + ke::SafeSprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") - debug not enabled!", error, filename); + } } void Debugger::GenericMessage(AMX *amx, int err) diff --git a/amxmodx/file.cpp b/amxmodx/file.cpp index 6ca02d8d..9626df33 100755 --- a/amxmodx/file.cpp +++ b/amxmodx/file.cpp @@ -601,7 +601,7 @@ static cell AMX_NATIVE_CALL amx_fputs(AMX *amx, cell *params) ++length; } - if (fp->Write(string, length) != length) + if (fp->Write(string, length) != (size_t)length) { return -1; } @@ -678,7 +678,7 @@ static cell AMX_NATIVE_CALL amx_fprintf(AMX *amx, cell *params) { assert(false); } - + return 0; } @@ -1015,8 +1015,8 @@ static cell AMX_NATIVE_CALL rename_file(AMX *amx, cell *params) if (params[0] / sizeof(cell) >= 3 && params[3] > 0) { - build_pathname_r(file_old_r, sizeof(file_old_r) - 1, "%s", file_old); - build_pathname_r(file_new_r, sizeof(file_new_r) - 1, "%s", file_new); + build_pathname_r(file_old_r, sizeof(file_old_r), "%s", file_old); + build_pathname_r(file_new_r, sizeof(file_new_r), "%s", file_new); } else { @@ -1205,7 +1205,7 @@ AMX_NATIVE_INFO file_Natives[] = {"fungetc", amx_ungetc}, {"fputs", amx_fputs}, {"fflush", amx_fflush}, - + {"build_pathname", amx_build_pathname}, {"dir_exists", dir_exists}, diff --git a/amxmodx/meta_api.cpp b/amxmodx/meta_api.cpp index b554f668..856ddd33 100755 --- a/amxmodx/meta_api.cpp +++ b/amxmodx/meta_api.cpp @@ -32,8 +32,10 @@ #include #include #include "CoreConfig.h" +#include +#include -plugin_info_t Plugin_info = +plugin_info_t Plugin_info = { META_INTERFACE_VERSION, // ifvers "AMX Mod X", // name @@ -63,10 +65,10 @@ extern ke::Vector DynamicAdmins; CLog g_log; CForwardMngr g_forwards; -CList g_auth; -CList g_forcemodels; -CList g_forcesounds; -CList g_forcegeneric; +ke::Vector> g_auth; +ke::Vector> g_forcemodels; +ke::Vector> g_forcesounds; +ke::Vector> g_forcegeneric; CPlayer g_players[33]; CPlayer* mPlayer; CPluginMngr g_plugins; @@ -160,7 +162,7 @@ bool ColoredMenus(const char *ModName) for (size_t i = 0; i < ModsCount; ++i) { if (strcmp(ModName, pModNames[i]) == 0) - return true; // this game modification currently supports colored menus + return true; // this game modification currently supports colored menus } return false; // no colored menus are supported for this game modification @@ -185,9 +187,9 @@ void ParseAndOrAdd(CStack & files, const char *name) void BuildPluginFileList(const char *initialdir, CStack & files) { - char path[255]; + char path[PLATFORM_MAX_PATH]; #if defined WIN32 - build_pathname_r(path, sizeof(path)-1, "%s/*.ini", initialdir); + build_pathname_r(path, sizeof(path), "%s/*.ini", initialdir); _finddata_t fd; intptr_t handle = _findfirst(path, &fd); @@ -203,7 +205,7 @@ void BuildPluginFileList(const char *initialdir, CStack & files) _findclose(handle); #elif defined(__linux__) || defined(__APPLE__) - build_pathname_r(path, sizeof(path)-1, "%s/", initialdir); + build_pathname_r(path, sizeof(path), "%s/", initialdir); struct dirent *ep; DIR *dp; @@ -263,10 +265,10 @@ int C_PrecacheModel(const char *s) if (!g_forcedmodules) { g_forcedmodules = true; - for (CList::iterator a = g_forcemodels.begin(); a; ++a) + for (auto &model : g_forcemodels) { - PRECACHE_MODEL((char*)(*a).getFilename()); - ENGINE_FORCE_UNMODIFIED((*a).getForceType(), (*a).getMin(), (*a).getMax(), (*a).getFilename()); + PRECACHE_MODEL(model->getFilename()); + ENGINE_FORCE_UNMODIFIED(model->getForceType(), model->getMin(), model->getMax(), model->getFilename()); } } @@ -278,12 +280,12 @@ int C_PrecacheSound(const char *s) if (!g_forcedsounds) { g_forcedsounds = true; - for (CList::iterator a = g_forcesounds.begin(); a; ++a) + for (auto &sound : g_forcesounds) { - PRECACHE_SOUND((char*)(*a).getFilename()); - ENGINE_FORCE_UNMODIFIED((*a).getForceType(), (*a).getMin(), (*a).getMax(), (*a).getFilename()); + PRECACHE_SOUND(sound->getFilename()); + ENGINE_FORCE_UNMODIFIED(sound->getForceType(), sound->getMin(), sound->getMax(), sound->getFilename()); } - + if (!g_bmod_cstrike) { PRECACHE_SOUND("weapons/cbar_hitbod1.wav"); @@ -308,7 +310,7 @@ int C_InconsistentFile(const edict_t *player, const char *filename, char *discon if (executeForwards(FF_InconsistentFile, static_cast(pPlayer->index), filename, disconnect_message) == 1) RETURN_META_VALUE(MRES_SUPERCEDE, FALSE); - + RETURN_META_VALUE(MRES_SUPERCEDE, TRUE); } @@ -453,7 +455,7 @@ int C_Spawn(edict_t *pent) g_plugins.CALMFromFile(map_pluginsfile_path); int loaded = countModules(CountModules_Running); // Call after attachModules so all modules don't have pending stat - + // Set some info about amx version and modules CVAR_SET_STRING(init_amxmodx_version.name, AMXX_VERSION); char buffer[32]; @@ -461,8 +463,8 @@ int C_Spawn(edict_t *pent) CVAR_SET_STRING(init_amxmodx_modules.name, buffer); // ###### Load Vault - char file[255]; - g_vault.setSource(build_pathname_r(file, sizeof(file) - 1, "%s", get_localinfo("amxx_vault", "addons/amxmodx/configs/vault.ini"))); + char file[PLATFORM_MAX_PATH]; + g_vault.setSource(build_pathname_r(file, sizeof(file), "%s", get_localinfo("amxx_vault", "addons/amxmodx/configs/vault.ini"))); g_vault.loadVault(); // ###### Init time and freeze tasks @@ -531,11 +533,10 @@ int C_Spawn(edict_t *pent) executeForwards(FF_PluginPrecache); g_dontprecache = true; - for (CList::iterator a = g_forcegeneric.begin(); a; ++a) + for (auto &generic : g_forcegeneric) { - PRECACHE_GENERIC((char*)(*a).getFilename()); - ENGINE_FORCE_UNMODIFIED((*a).getForceType(), - (*a).getMin(), (*a).getMax(), (*a).getFilename()); + PRECACHE_GENERIC(generic->getFilename()); + ENGINE_FORCE_UNMODIFIED(generic->getForceType(), generic->getMin(), generic->getMax(), generic->getFilename()); } RETURN_META_VALUE(MRES_IGNORED, 0); @@ -548,7 +549,7 @@ struct sUserMsg funEventCall func; bool endmsg; bool cstrike; -} g_user_msg[] = +} g_user_msg[] = { {"CurWeapon", &gmsgCurWeapon, Client_CurWeapon, false, false}, {"Damage", &gmsgDamage, Client_DamageEnd, true, true}, @@ -605,13 +606,13 @@ plugin_init forward function from plugins void C_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) { int id; - + for (int i = 0; g_user_msg[i].name; ++i) { if ((*g_user_msg[i].id == 0) && (id = GET_USER_MSG_ID(PLID, g_user_msg[i].name, NULL)) != 0) { *g_user_msg[i].id = id; - + if (!g_user_msg[i].cstrike || g_bmod_cstrike) { if (g_user_msg[i].endmsg) @@ -672,7 +673,7 @@ void C_ServerDeactivate() { if (!g_activated) RETURN_META(MRES_IGNORED); - + for (int i = 1; i <= gpGlobals->maxClients; ++i) { CPlayer *pPlayer = GET_PLAYER_POINTER_I(i); @@ -750,7 +751,7 @@ void C_ServerDeactivate_Post() modules_callPluginsUnloaded(); ClearMessages(); - + // Flush the dynamic admins list for (size_t iter=DynamicAdmins.length();iter--; ) { @@ -805,15 +806,15 @@ void C_ServerDeactivate_Post() } } g_memreport_dir = buffer; - + // g_memreport_dir should be valid now break; } } - + m_dumpMemoryReport(build_pathname("%s/r%03d.txt", g_memreport_dir.chars(), g_memreport_count)); AMXXLOG_Log("Memreport #%d created (file \"%s/r%03d.txt\") (interval %f)", g_memreport_count + 1, g_memreport_dir.chars(), g_memreport_count, MEMREPORT_INTERVAL); - + g_memreport_count++; } #endif // MEMORY_TEST @@ -834,12 +835,12 @@ BOOL C_ClientConnect_Post(edict_t *pEntity, const char *pszName, const char *psz { bool a = pPlayer->Connect(pszName, pszAddress); executeForwards(FF_ClientConnect, static_cast(pPlayer->index)); - + if (a) { - CPlayer** aa = new CPlayer*(pPlayer); - if (aa) - g_auth.put(aa); + auto playerToAuth = ke::AutoPtr(new CPlayer*(pPlayer)); + if (playerToAuth) + g_auth.append(ke::Move(playerToAuth)); } else { pPlayer->Authorize(); const char* authid = GETPLAYERAUTHID(pEntity); @@ -856,7 +857,7 @@ BOOL C_ClientConnect_Post(edict_t *pEntity, const char *pszName, const char *psz executeForwards(FF_ClientAuthorized, static_cast(pPlayer->index), authid); } } - + RETURN_META_VALUE(MRES_IGNORED, TRUE); } @@ -878,7 +879,7 @@ void C_ClientDisconnect(edict_t *pEntity) { // deprecated executeForwards(FF_ClientDisconnect, static_cast(pPlayer->index)); - + if (DropClientDetour && !pPlayer->disconnecting) { executeForwards(FF_ClientDisconnected, static_cast(pPlayer->index), FALSE, prepareCharArray(const_cast(""), 0), 0); @@ -902,6 +903,31 @@ void C_ClientDisconnect(edict_t *pEntity) RETURN_META(MRES_IGNORED); } +CPlayer* SV_DropClient_PreHook(edict_s *client, qboolean crash, const char *buffer, size_t buffer_size) +{ + auto pPlayer = client ? GET_PLAYER_POINTER(client) : nullptr; + + if (pPlayer) + { + if (pPlayer->initialized) + { + pPlayer->disconnecting = true; + executeForwards(FF_ClientDisconnected, pPlayer->index, TRUE, prepareCharArray(const_cast(buffer), buffer_size, true), buffer_size - 1); + } + } + + return pPlayer; +} + +void SV_DropClient_PostHook(CPlayer *pPlayer, qboolean crash, const char *buffer) +{ + if (pPlayer) + { + pPlayer->Disconnect(); + executeForwards(FF_ClientRemove, pPlayer->index, TRUE, buffer); + } +} + // void SV_DropClient(client_t *cl, qboolean crash, const char *fmt, ...); DETOUR_DECL_STATIC3_VAR(SV_DropClient, void, client_t*, cl, qboolean, crash, const char*, format) { @@ -912,24 +938,23 @@ DETOUR_DECL_STATIC3_VAR(SV_DropClient, void, client_t*, cl, qboolean, crash, con ke::SafeVsprintf(buffer, sizeof(buffer) - 1, format, ap); va_end(ap); - auto pPlayer = cl->edict ? GET_PLAYER_POINTER(cl->edict) : nullptr; - - if (pPlayer) - { - if (pPlayer->initialized) - { - pPlayer->disconnecting = true; - executeForwards(FF_ClientDisconnected, pPlayer->index, TRUE, prepareCharArray(buffer, sizeof(buffer), true), sizeof(buffer) - 1); - } - } + auto pPlayer = SV_DropClient_PreHook(cl->edict, crash, buffer, ARRAY_LENGTH(buffer)); DETOUR_STATIC_CALL(SV_DropClient)(cl, crash, "%s", buffer); - if (pPlayer) - { - pPlayer->Disconnect(); - executeForwards(FF_ClientRemove, pPlayer->index, TRUE, buffer); - } + SV_DropClient_PostHook(pPlayer, crash, buffer); +} + +void SV_DropClient_RH(IRehldsHook_SV_DropClient *chain, IGameClient *cl, bool crash, const char *format) +{ + char buffer[1024]; + ke::SafeStrcpy(buffer, sizeof(buffer), format); + + auto pPlayer = SV_DropClient_PreHook(cl->GetEdict(), crash, buffer, ARRAY_LENGTH(buffer)); + + chain->callNext(cl, crash, buffer); + + SV_DropClient_PostHook(pPlayer, crash, buffer); } void C_ClientPutInServer_Post(edict_t *pEntity) @@ -941,7 +966,7 @@ void C_ClientPutInServer_Post(edict_t *pEntity) ++g_players_num; executeForwards(FF_ClientPutInServer, static_cast(pPlayer->index)); } - + RETURN_META(MRES_IGNORED); } @@ -986,10 +1011,10 @@ void C_ClientUserInfoChanged_Post(edict_t *pEntity, char *infobuffer) void C_ClientCommand(edict_t *pEntity) { CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity); - + META_RES result = MRES_IGNORED; cell ret = 0; - + const char* cmd = CMD_ARGV(0); const char* arg = CMD_ARGV(1); @@ -1001,7 +1026,7 @@ void C_ClientCommand(edict_t *pEntity) // Print version static char buf[1024]; size_t len = 0; - + sprintf(buf, "%s %s\n", Plugin_info.name, Plugin_info.version); CLIENT_PRINT(pEntity, print_console, buf); len = sprintf(buf, "Authors: \n David \"BAILOPAN\" Anderson, Pavol \"PM OnoTo\" Marko, Felix \"SniperBeamer\" Geyer\n"); @@ -1031,7 +1056,7 @@ void C_ClientCommand(edict_t *pEntity) /* check for command and if needed also for first argument and call proper function */ CmdMngr::iterator aa = g_commands.clcmdprefixbegin(cmd); - + if (!aa) aa = g_commands.clcmdbegin(); @@ -1063,7 +1088,7 @@ void C_ClientCommand(edict_t *pEntity) pMenu->Close(pPlayer->index); RETURN_META(MRES_SUPERCEDE); - } + } else if (pPlayer->menu > 0 && !pPlayer->vgui) { pPlayer->menu = 0; @@ -1072,7 +1097,7 @@ void C_ClientCommand(edict_t *pEntity) RETURN_META(MRES_SUPERCEDE); } } - + int menuid = pPlayer->menu; pPlayer->menu = 0; @@ -1087,10 +1112,16 @@ void C_ClientCommand(edict_t *pEntity) int item = pMenu->PagekeyToItem(pPlayer->page, pressed_key+1); if (item == MENU_BACK) { + if (pMenu->pageCallback >= 0) + executeForwards(pMenu->pageCallback, static_cast(pPlayer->index), static_cast(MENU_BACK)); + pMenu->Display(pPlayer->index, pPlayer->page - 1); } else if (item == MENU_MORE) { + if (pMenu->pageCallback >= 0) + executeForwards(pMenu->pageCallback, static_cast(pPlayer->index), static_cast(MENU_MORE)); + pMenu->Display(pPlayer->index, pPlayer->page + 1); } else @@ -1107,12 +1138,12 @@ void C_ClientCommand(edict_t *pEntity) } } /** - * No matter what we marked it as executed, since the callback styles are + * No matter what we marked it as executed, since the callback styles are * entirely different. After all, this is a backwards compat shim. */ func_was_executed = pMenu->func; } - } + } /* Now, do old menus */ MenuMngr::iterator a = g_menucmds.begin(); @@ -1120,15 +1151,15 @@ void C_ClientCommand(edict_t *pEntity) while (a) { g_menucmds.SetWatchIter(a); - if ((*a).matchCommand(menuid, bit_key) + if ((*a).matchCommand(menuid, bit_key) && (*a).getPlugin()->isExecutable((*a).getFunction()) - && (func_was_executed == -1 + && (func_was_executed == -1 || !g_forwards.isSameSPForward(func_was_executed, (*a).getFunction())) ) { ret = executeForwards((*a).getFunction(), static_cast(pPlayer->index), static_cast(pressed_key), 0); - + if (ret & 2) result = MRES_SUPERCEDE; if (ret & 1) RETURN_META(MRES_SUPERCEDE); } @@ -1151,21 +1182,22 @@ void C_StartFrame_Post(void) if (g_auth_time < gpGlobals->time) { g_auth_time = gpGlobals->time + 0.7f; - CList::iterator a = g_auth.begin(); - while (a) + size_t i = 0; + while (i < g_auth.length()) { - const char* auth = GETPLAYERAUTHID((*a)->pEdict); + auto player = g_auth[i].get(); + const char* auth = GETPLAYERAUTHID((*player)->pEdict); if ((auth == 0) || (*auth == 0)) { - a.remove(); + g_auth.remove(i); continue; } if (strcmp(auth, "STEAM_ID_PENDING")) { - (*a)->Authorize(); + (*player)->Authorize(); if (g_auth_funcs.size()) { List::iterator iter, end=g_auth_funcs.end(); @@ -1173,15 +1205,15 @@ void C_StartFrame_Post(void) for (iter=g_auth_funcs.begin(); iter!=end; iter++) { fn = (*iter); - fn((*a)->index, auth); + fn((*player)->index, auth); } } - executeForwards(FF_ClientAuthorized, static_cast((*a)->index), auth); - a.remove(); - + executeForwards(FF_ClientAuthorized, static_cast((*player)->index), auth); + g_auth.remove(i); + continue; } - ++a; + i++; } } @@ -1189,14 +1221,14 @@ void C_StartFrame_Post(void) if (g_memreport_enabled && g_next_memreport_time <= gpGlobals->time) { g_next_memreport_time = gpGlobals->time + MEMREPORT_INTERVAL; - + if (g_memreport_count == 0) { // make new directory time_t td; time(&td); tm *curTime = localtime(&td); - + int i = 0; #if defined(__linux__) || defined(__APPLE__) mkdir(build_pathname("%s/memreports", get_localinfo("amxx_basedir", "addons/amxmodx")), 0700); @@ -1232,10 +1264,10 @@ void C_StartFrame_Post(void) break; } } - + m_dumpMemoryReport(build_pathname("%s/r%03d.txt", g_memreport_dir.chars(), g_memreport_count)); AMXXLOG_Log("Memreport #%d created (file \"%s/r%03d.txt\") (interval %f)", g_memreport_count + 1, g_memreport_dir.chars(), g_memreport_count, MEMREPORT_INTERVAL); - + g_memreport_count++; } #endif // MEMORY_TEST @@ -1263,14 +1295,14 @@ void C_MessageBegin_Post(int msg_dest, int msg_type, const float *pOrigin, edict mPlayerIndex = 0; mPlayer = 0; } - + if (msg_type < 0 || msg_type >= MAX_REG_MSGS) msg_type = 0; mState = 0; function = modMsgs[msg_type]; endfunction = modMsgsEnd[msg_type]; - + g_events.parserInit(msg_type, &gpGlobals->time, mPlayer, mPlayerIndex); RETURN_META(MRES_IGNORED); @@ -1280,7 +1312,7 @@ void C_WriteByte_Post(int iValue) { g_events.parseValue(iValue); if (function) (*function)((void *)&iValue); - + RETURN_META(MRES_IGNORED); } @@ -1296,7 +1328,7 @@ void C_WriteShort_Post(int iValue) { g_events.parseValue(iValue); if (function) (*function)((void *)&iValue); - + RETURN_META(MRES_IGNORED); } @@ -1304,7 +1336,7 @@ void C_WriteLong_Post(int iValue) { g_events.parseValue(iValue); if (function) (*function)((void *)&iValue); - + RETURN_META(MRES_IGNORED); } @@ -1312,7 +1344,7 @@ void C_WriteAngle_Post(float flValue) { g_events.parseValue(flValue); if (function) (*function)((void *)&flValue); - + RETURN_META(MRES_IGNORED); } @@ -1336,7 +1368,7 @@ void C_WriteEntity_Post(int iValue) { g_events.parseValue(iValue); if (function) (*function)((void *)&iValue); - + RETURN_META(MRES_IGNORED); } @@ -1344,7 +1376,7 @@ void C_MessageEnd_Post(void) { g_events.executeEvents(); if (endfunction) (*endfunction)(NULL); - + RETURN_META(MRES_IGNORED); } @@ -1353,7 +1385,7 @@ const char *C_Cmd_Args(void) // if the global "fake" flag is set, which means that engclient_cmd was used, supercede the function if (g_fakecmd.fake) RETURN_META_VALUE(MRES_SUPERCEDE, (g_fakecmd.argc > 1) ? g_fakecmd.args : g_fakecmd.argv[0]); - + // otherwise ignore it RETURN_META_VALUE(MRES_IGNORED, NULL); } @@ -1363,7 +1395,7 @@ const char *C_Cmd_Argv(int argc) // if the global "fake" flag is set, which means that engclient_cmd was used, supercede the function if (g_fakecmd.fake) RETURN_META_VALUE(MRES_SUPERCEDE, (argc < 3) ? g_fakecmd.argv[argc] : ""); - + // otherwise ignore it RETURN_META_VALUE(MRES_IGNORED, NULL); } @@ -1373,7 +1405,7 @@ int C_Cmd_Argc(void) // if the global "fake" flag is set, which means that engclient_cmd was used, supercede the function if (g_fakecmd.fake) RETURN_META_VALUE(MRES_SUPERCEDE, g_fakecmd.argc); - + // otherwise ignore it RETURN_META_VALUE(MRES_IGNORED, 0); } @@ -1384,7 +1416,7 @@ void C_SetModel(edict_t *e, const char *m) { if (e->v.owner && m[7]=='w' && m[8]=='_' && m[9]=='h') g_grenades.put(e, 1.75, 4, GET_PLAYER_POINTER(e->v.owner)); - + RETURN_META(MRES_IGNORED); } @@ -1394,10 +1426,10 @@ void C_TraceLine_Post(const float *v1, const float *v2, int fNoMonsters, edict_t if (e && (e->v.flags & (FL_CLIENT | FL_FAKECLIENT))) { CPlayer* pPlayer = GET_PLAYER_POINTER(e); - + if (ptr->pHit && (ptr->pHit->v.flags & (FL_CLIENT | FL_FAKECLIENT))) pPlayer->aiming = ptr->iHitgroup; - + pPlayer->lastTrace = ptr->vecEndPos; } @@ -1496,7 +1528,7 @@ C_DLLEXPORT int Meta_Query(const char *ifvers, plugin_info_t **pPlugInfo, mutil_ *pPlugInfo = &Plugin_info; int mmajor = 0, mminor = 0, pmajor = 0, pminor = 0; - + sscanf(ifvers, "%d:%d", &mmajor, &mminor); sscanf(Plugin_info.ifvers, "%d:%d", &pmajor, &pminor); @@ -1511,7 +1543,7 @@ C_DLLEXPORT int Meta_Query(const char *ifvers, plugin_info_t **pPlugInfo, mutil_ LOG_ERROR(PLID, "metamod version is incompatible with this plugin; please find a newer version of this plugin"); return (FALSE); } else if (pmajor == mmajor) { - if (pminor > mminor) + if (pminor > mminor) { LOG_ERROR(PLID, "metamod version is incompatible with this plugin; please find a newer version of this plugin"); return FALSE; @@ -1554,21 +1586,21 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m CVAR_REGISTER(&init_amxmodx_mldebug); CVAR_REGISTER(&init_amxmodx_language); CVAR_REGISTER(&init_amxmodx_cl_langs); - + amxmodx_version = CVAR_GET_POINTER(init_amxmodx_version.name); amxmodx_language = CVAR_GET_POINTER(init_amxmodx_language.name); - + REG_SVR_COMMAND("amxx", amx_command); char gameDir[512]; GET_GAME_DIR(gameDir); char *a = gameDir; int i = 0; - + while (gameDir[i]) if (gameDir[i++] == '/') a = &gameDir[i]; - + g_mod_name = a; g_coloredmenus = ColoredMenus(g_mod_name.chars()); // whether or not to use colored menus @@ -1586,7 +1618,7 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m if (amx_config.loadVault()) { Vault::iterator a = amx_config.begin(); - + while (a != amx_config.end()) { SET_LOCALINFO((char*)a.key().chars(), (char*)a.value().chars()); @@ -1609,19 +1641,27 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m ConfigManager.OnAmxxStartup(); - g_CvarManager.CreateCvarHook(); - - void *address = nullptr; - - if (CommonConfig && CommonConfig->GetMemSig("SV_DropClient", &address) && address) + if (RehldsApi_Init()) { - DropClientDetour = DETOUR_CREATE_STATIC_FIXED(SV_DropClient, address); + RehldsHookchains->SV_DropClient()->registerHook(SV_DropClient_RH); } else { - AMXXLOG_Log("client_disconnected and client_remove forwards have been disabled - check your gamedata files."); + void *address = nullptr; + + if (CommonConfig && CommonConfig->GetMemSig("SV_DropClient", &address) && address) + { + DropClientDetour = DETOUR_CREATE_STATIC_FIXED(SV_DropClient, address); + } + else + { + auto reason = RehldsApi ? "update ReHLDS" : "check your gamedata files"; + AMXXLOG_Log("client_disconnected and client_remove forwards have been disabled - %s.", reason); + } } + g_CvarManager.CreateCvarHook(); + GET_IFACE("filesystem_stdio", g_FileSystem, FILESYSTEM_INTERFACE_VERSION); return (TRUE); @@ -1671,6 +1711,10 @@ C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason) { DropClientDetour->Destroy(); } + else if (RehldsApi) + { + RehldsHookchains->SV_DropClient()->unregisterHook(SV_DropClient_RH); + } return (TRUE); } @@ -1839,7 +1883,7 @@ C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int meta_engfuncs_post.pfnWriteByte = C_WriteByte_Post; meta_engfuncs_post.pfnWriteChar = C_WriteChar_Post; meta_engfuncs_post.pfnWriteShort = C_WriteShort_Post; - meta_engfuncs_post.pfnWriteLong = C_WriteLong_Post; + meta_engfuncs_post.pfnWriteLong = C_WriteLong_Post; meta_engfuncs_post.pfnWriteAngle = C_WriteAngle_Post; meta_engfuncs_post.pfnWriteCoord = C_WriteCoord_Post; meta_engfuncs_post.pfnWriteString = C_WriteString_Post; @@ -1858,7 +1902,7 @@ NEW_DLL_FUNCTIONS gNewDLLFunctionTable; C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion) { memset(&gNewDLLFunctionTable, 0, sizeof(NEW_DLL_FUNCTIONS)); - + // default metamod does not call this if the gamedll doesn't provide it if (g_engfuncs.pfnQueryClientCvarValue2) { diff --git a/amxmodx/modules.cpp b/amxmodx/modules.cpp index e7151ea7..60d14b85 100755 --- a/amxmodx/modules.cpp +++ b/amxmodx/modules.cpp @@ -31,9 +31,10 @@ #include "trie_natives.h" #include "CDataPack.h" #include "CGameConfigs.h" +#include -CList g_modules; -CList g_loadedscripts; +ke::InlineList g_modules; +ke::InlineList g_loadedscripts; CModule *g_CurrentlyCalledModule = NULL; // The module we are in at the moment; NULL otherwise @@ -52,7 +53,7 @@ void report_error(int code, const char* fmt, ...) vsnprintf(string, 255, fmt, argptr); string[255] = 0; va_end(argptr); - + if (*string) { AMXXLOG_Log("Error:"); @@ -71,7 +72,7 @@ void print_srvconsole(const char *fmt, ...) vsnprintf(string, sizeof(string) - 1, fmt, argptr); string[sizeof(string) - 1] = '\0'; va_end(argptr); - + SERVER_PRINT(string); } @@ -111,7 +112,7 @@ void BinLog_LogParams(AMX *amx, cell *params) } } -static binlogfuncs_t logfuncs = +static binlogfuncs_t logfuncs = { BinLog_LogNative, BinLog_LogReturn, @@ -127,25 +128,25 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 if (!*program) { CAmxxReader reader(filename, PAWN_CELL_SIZE / 8); - + if (reader.GetStatus() == CAmxxReader::Err_None) { bufSize = reader.GetBufferSize(); - + if (bufSize != 0) { *program = (void*) (new char[bufSize]); - + if (!*program) { strcpy(error, "Failed to allocate memory"); return (amx->error = AMX_ERR_MEMORY); } - + reader.GetSection(*program); } } - + switch (reader.GetStatus()) { case CAmxxReader::Err_None: @@ -186,7 +187,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 AMX_HEADER *hdr = (AMX_HEADER*)*program; uint16_t magic = hdr->magic; amx_Align16(&magic); - + if (magic != AMX_MAGIC) { strcpy(error, "Invalid Plugin"); @@ -208,10 +209,10 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 else if ((hdr->flags & AMX_FLAG_DEBUG) != 0) { will_be_debugged = true; - + char *addr = (char *)hdr + hdr->size; pDbg = new tagAMX_DBG; - + memset(pDbg, 0, sizeof(AMX_DBG)); int err = dbg_LoadInfo(pDbg, addr); @@ -248,7 +249,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 dbg_FreeInfo(pDbg); delete pDbg; } - + sprintf(error, "Load error %d (invalid file format or version)", err); return (amx->error = AMX_ERR_INIT); } @@ -282,17 +283,17 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 { char *np = new char[amx->code_size]; char *rt = new char[amx->reloc_size]; - + if (!np || (!rt && amx->reloc_size > 0)) { delete[] np; delete[] rt; strcpy(error, "Failed to initialize JIT'd plugin"); - + return (amx->error = AMX_ERR_INIT); } - - if ((err = amx_InitJIT(amx, (void *)rt, (void *)np)) == AMX_ERR_NONE) + + if ((err = amx_InitJIT(amx, (void *)rt, (void *)np)) == AMX_ERR_NONE) { //amx->base = (unsigned char FAR *)realloc(np, amx->code_size); #if defined(_WIN32) @@ -307,15 +308,15 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 #endif if (amx->base) memcpy(amx->base, np, amx->code_size); - + delete [] np; delete [] rt; - + char *prg = (char *)(*program); - + delete [] prg; (*program) = amx->base; - + if (*program == 0) { strcpy(error, "Failed to allocate memory"); @@ -324,24 +325,30 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 } else { delete[] np; delete[] rt; - + sprintf(error, "Failed to initialize plugin (%d)", err); - + return (amx->error = AMX_ERR_INIT_JIT); } } #endif - CScript* aa = new CScript(amx, *program, filename); + auto script = new CScript(amx, *program, filename); - g_loadedscripts.put(aa); + if (!script) + { + ke::SafeSprintf(error, 64, "Failed to allocate memory for script"); + return (amx->error = AMX_ERR_MEMORY); + } + + g_loadedscripts.append(script); set_amxnatives(amx, error); if (g_plugins.m_Finalized) { amx_Register(amx, g_plugins.pNatives, -1); - + if (CheckModules(amx, error)) { if (amx_Register(amx, core_Natives, -1) != AMX_ERR_NONE) @@ -371,7 +378,7 @@ const char *StrCaseStr(const char *as, const char *bs) { a[i] = tolower(as[i]); } - + a[len] = 0; len = strlen(bs); @@ -383,7 +390,7 @@ const char *StrCaseStr(const char *as, const char *bs) { b[i] = tolower(bs[i]); } - + b[len] = 0; return strstr(a, b); @@ -396,14 +403,14 @@ int CheckModules(AMX *amx, char error[128]) char buffer[64]; LibType expect; bool found; - + Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER]; /** decode old style plugins */ for (int i = 0; i < numLibraries; i++) { amx_GetLibrary(amx, i, buffer, sizeof(buffer) - 1); - + if (stricmp(buffer, "float") == 0) continue; @@ -419,26 +426,22 @@ int CheckModules(AMX *amx, char error[128]) /* for binary compat */ if (!found) { - CList::iterator a = g_modules.begin(); - while (a) + for (auto module : g_modules) { - CModule &cm = (*a); - if (cm.getStatusValue() != MODULE_LOADED) + if (module->getStatusValue() != MODULE_LOADED) { - ++a; continue; } - if (cm.getInfoNew() && - cm.getInfoNew()->logtag && - !strcasecmp(cm.getInfoNew()->logtag, buffer)) + if (module->getInfoNew() && + module->getInfoNew()->logtag && + !strcasecmp(module->getInfoNew()->logtag, buffer)) { found = true; break; } - ++a; } } - + if (!found) { if (expect == LibType_Library) @@ -452,7 +455,7 @@ int CheckModules(AMX *amx, char error[128]) } } } - + if (!found) { const char *type = "Module/Library"; @@ -497,18 +500,16 @@ int CheckModules(AMX *amx, char error[128]) int set_amxnatives(AMX* amx, char error[128]) { - CModule *cm; - for (CList::iterator a = g_modules.begin(); a ; ++a) + for (auto module : g_modules) { - cm = &(*a); - for (size_t i=0; im_Natives.length(); i++) + for (size_t i = 0; i < module->m_Natives.length(); i++) { - amx_Register(amx, cm->m_Natives[i], -1); + amx_Register(amx, module->m_Natives[i], -1); } - for (size_t i = 0; i < cm->m_NewNatives.length(); i++) + for (size_t i = 0; i < module->m_NewNatives.length(); i++) { - amx_Register(amx, cm->m_NewNatives[i], -1); + amx_Register(amx, module->m_NewNatives[i], -1); } } @@ -541,7 +542,7 @@ int set_amxnatives(AMX* amx, char error[128]) Debugger *pd; pd = DisableDebugHandler(amx); - + if (amx_FindPublic(amx, "plugin_natives", &idx) == AMX_ERR_NONE) { if ((err = amx_Exec(amx, &retval, idx)) != AMX_ERR_NONE) @@ -559,7 +560,7 @@ int set_amxnatives(AMX* amx, char error[128]) } int unload_amxscript(AMX* amx, void** program) -{ +{ #if defined JIT int flags = amx->flags; long code_size = amx->code_size; @@ -568,7 +569,7 @@ int unload_amxscript(AMX* amx, void** program) Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER]; if (pDebugger) delete pDebugger; - + Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER]; if (pHandler) delete pHandler; @@ -576,14 +577,20 @@ int unload_amxscript(AMX* amx, void** program) optimizer_s *opt = (optimizer_s *)amx->usertags[UT_OPTIMIZER]; if (opt) delete opt; - - CList::iterator a = g_loadedscripts.find(amx); - - if (a) - a.remove(); - + + for (auto script : g_loadedscripts) + { + if (script->getAMX() == amx) + { + g_loadedscripts.remove(script); + delete script; + + break; + } + } + char *prg = (char *)*program; - + if (!prg) return AMX_ERR_NONE; @@ -606,7 +613,7 @@ int unload_amxscript(AMX* amx, void** program) #endif } #elif defined WIN32 - + if ((flags & AMX_FLAG_JITC) != AMX_FLAG_JITC) { delete [] prg; @@ -627,34 +634,41 @@ int unload_amxscript(AMX* amx, void** program) AMX* get_amxscript(int id, void** code, const char** filename) { - CList::iterator a = g_loadedscripts.begin(); - - while (a && id--) - ++a; - - if (a) + for (auto script : g_loadedscripts) { - *filename = (*a).getName(); - *code = (*a).getCode(); - - return (*a).getAMX(); + if (id--) + { + continue; + } + + *filename = script->getName(); + *code = script->getCode(); + + return script->getAMX(); } - - return 0; + + return nullptr; } const char* GetFileName(AMX *amx) { const char *filename = ""; CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx); - + if (pl) { filename = pl->getName(); - } else { - CList::iterator a = g_loadedscripts.find(amx); - if (a) - filename = (*a).getName(); + } + else + { + for (auto script : g_loadedscripts) + { + if (script->getAMX() == amx) + { + filename = script->getName(); + break; + } + } } return filename; @@ -662,8 +676,14 @@ const char* GetFileName(AMX *amx) const char* get_amxscriptname(AMX* amx) { - CList::iterator a = g_loadedscripts.find(amx); - return a ? (*a).getName() : ""; + for (auto script : g_loadedscripts) + { + if (script->getAMX() == amx) + { + return script->getName(); + } + } + return ""; } void get_modname(char* buffer) @@ -671,77 +691,41 @@ void get_modname(char* buffer) strcpy(buffer, g_mod_name.chars()); } -char* build_pathname(const char *fmt, ...) +char *build_pathname(const char *fmt, ...) { - static char string[256]; - int b; - int a = b = ke::SafeSprintf(string, sizeof(string), "%s%c", g_mod_name.chars(), PATH_SEP_CHAR); + static char string[PLATFORM_MAX_PATH]; + auto len = ke::path::Format(string, sizeof(string), "%s/", g_mod_name.chars()); va_list argptr; va_start(argptr, fmt); - a += vsnprintf (&string[a], 255 - a, fmt, argptr); - string[a] = 0; + ke::path::FormatVa(&string[len], sizeof(string) - len, fmt, argptr); va_end(argptr); - char* path = &string[b]; - - while (*path) - { - if (*path == ALT_SEP_CHAR) - { - *path = PATH_SEP_CHAR; - } - ++path; - } - return string; } char *build_pathname_r(char *buffer, size_t maxlen, const char *fmt, ...) { - ke::SafeSprintf(buffer, maxlen, "%s%c", g_mod_name.chars(), PATH_SEP_CHAR); - - size_t len = strlen(buffer); - char *ptr = buffer + len; + auto len = ke::path::Format(buffer, maxlen, "%s/", g_mod_name.chars()); va_list argptr; va_start(argptr, fmt); - vsnprintf (ptr, maxlen-len, fmt, argptr); + ke::path::FormatVa(&buffer[len], maxlen - len, fmt, argptr); va_end (argptr); - while (*ptr) - { - if (*ptr == ALT_SEP_CHAR) - { - *ptr = PATH_SEP_CHAR; - } - ++ptr; - } - return buffer; } // build pathname based on addons dir -char* build_pathname_addons(const char *fmt, ...) +char *build_pathname_addons(const char *fmt, ...) { - static char string[256]; + static char string[PLATFORM_MAX_PATH]; va_list argptr; va_start(argptr, fmt); - vsnprintf (string, 255, fmt, argptr); + ke::path::FormatVa(string, sizeof(string), fmt, argptr); va_end(argptr); - char* path = string; - - while (*path) - { - if (*path == ALT_SEP_CHAR) - { - *path = PATH_SEP_CHAR; - } - ++path; - } - return string; } @@ -762,7 +746,7 @@ bool ConvertModuleName(const char *pathString, char *path) /* run to filename instead of dir */ char *ptr = tmpname; ptr = tmpname + len - 1; - while (ptr >= tmpname && *ptr != PATH_SEP_CHAR) + while (ptr >= tmpname && *ptr != PLATFORM_SEP_CHAR) ptr--; if (ptr >= tmpname) { @@ -822,7 +806,7 @@ bool ConvertModuleName(const char *pathString, char *path) *ptr = '\0'; } - size_t length = ke::SafeSprintf(path, PLATFORM_MAX_PATH, "%s%c%s_amxx", orig_path, PATH_SEP_CHAR, tmpname); + auto length = ke::path::Format(path, PLATFORM_MAX_PATH, "%s/%s_amxx", orig_path, tmpname); #if defined PLATFORM_LINUX # if defined AMD64 || PAWN_CELL_SIZE == 64 @@ -842,8 +826,8 @@ bool LoadModule(const char *shortname, PLUG_LOADTIME now, bool simplify, bool no char path[PLATFORM_MAX_PATH]; build_pathname_r( - pathString, - sizeof(pathString)-1, + pathString, + sizeof(pathString), "%s/%s", get_localinfo("amxx_modulesdir", "addons/amxmodx/modules"), shortname); @@ -864,18 +848,26 @@ bool LoadModule(const char *shortname, PLUG_LOADTIME now, bool simplify, bool no fclose(fp); } - CList::iterator a = g_modules.find(path); + for (auto module : g_modules) + { + if (!strcmp(module->getFilename(), path)) + { + return false; + } + } - if (a) + auto module = new CModule(path); + + if (!module) + { return false; + } - CModule* cc = new CModule(path); - - cc->queryModule(); + module->queryModule(); bool error = true; - switch (cc->getStatusValue()) + switch (module->getStatusValue()) { case MODULE_BADLOAD: report_error(1, "[AMXX] Module is not a valid library (file \"%s\")", path); @@ -887,7 +879,7 @@ bool LoadModule(const char *shortname, PLUG_LOADTIME now, bool simplify, bool no report_error(1, "[AMXX] Couldn't find \"AMX_Query\" or \"AMXX_Query\" (file \"%s\")", path); break; case MODULE_NOATTACH: - report_error(1, "[AMXX] Couldn't find \"%s\" (file \"%s\")", cc->isAmxx() ? "AMXX_Attach" : "AMX_Attach", path); + report_error(1, "[AMXX] Couldn't find \"%s\" (file \"%s\")", module->isAmxx() ? "AMXX_Attach" : "AMX_Attach", path); break; case MODULE_OLD: report_error(1, "[AMXX] Module has a different interface version (file \"%s\")", path); @@ -909,38 +901,38 @@ bool LoadModule(const char *shortname, PLUG_LOADTIME now, bool simplify, bool no break; } - g_modules.put(cc); + g_modules.append(module); if (error) { return false; } - if (cc->IsMetamod()) + if (module->IsMetamod()) { char *mmpathname = build_pathname_addons( - "%s/%s", - get_localinfo("amxx_modulesdir", "addons/amxmodx/modules"), + "%s/%s", + get_localinfo("amxx_modulesdir", "addons/amxmodx/modules"), shortname); ConvertModuleName(mmpathname, path); - cc->attachMetamod(path, now); + module->attachMetamod(path, now); } - bool retVal = cc->attachModule(); + bool retVal = module->attachModule(); - if (cc->isAmxx() && !retVal) + if (module->isAmxx() && !retVal) { - switch (cc->getStatusValue()) + switch (module->getStatusValue()) { case MODULE_FUNCNOTPRESENT: - report_error(1, "[AMXX] Module requested a not existing function (file \"%s\")%s%s%s", cc->getFilename(), cc->getMissingFunc() ? " (func \"" : "", - cc->getMissingFunc() ? cc->getMissingFunc() : "", cc->getMissingFunc() ? "\")" : ""); + report_error(1, "[AMXX] Module requested a not existing function (file \"%s\")%s%s%s", module->getFilename(), module->getMissingFunc() ? " (func \"" : "", + module->getMissingFunc() ? module->getMissingFunc() : "", module->getMissingFunc() ? "\")" : ""); break; case MODULE_INTERROR: - report_error(1, "[AMXX] Internal error during module load (file \"%s\")", cc->getFilename()); + report_error(1, "[AMXX] Internal error during module load (file \"%s\")", module->getFilename()); break; case MODULE_BADLOAD: - report_error(1, "[AMXX] Module is not a valid library (file \"%s\")", cc->getFilename()); + report_error(1, "[AMXX] Module is not a valid library (file \"%s\")", module->getFilename()); break; } @@ -982,17 +974,17 @@ int loadModules(const char* filename, PLUG_LOADTIME now) { simplify = false; strncopy(line, &buffer[1], sizeof(line)); - } - else + } + else { strncopy(line, buffer, sizeof(line)); } *moduleName = '\0'; - + if (sscanf(line, "%s", moduleName) == EOF) continue; - + if (LoadModule(moduleName, now, simplify)) loaded++; } @@ -1004,36 +996,40 @@ int loadModules(const char* filename, PLUG_LOADTIME now) void detachModules() { - CList::iterator a = g_modules.begin(); - - while (a) + auto moduleIter = g_modules.begin(), end = g_modules.end(); + while (moduleIter != end) { - (*a).detachModule(); - a.remove(); + auto module = *moduleIter; + + module->detachModule(); + moduleIter = g_modules.erase(moduleIter); + delete module; } } void detachReloadModules() { - CList::iterator a = g_modules.begin(); - - while (a) + auto moduleIter = g_modules.begin(), end = g_modules.end(); + while (moduleIter != end) { - if ((*a).isReloadable() && !(*a).IsMetamod()) + auto module = *moduleIter; + if (module->isReloadable() && !module->IsMetamod()) { - (*a).detachModule(); - a.remove(); - + module->detachModule(); + + moduleIter = g_modules.erase(moduleIter); + delete module; + continue; } - ++a; + moduleIter++; } } const char* strip_name(const char* a) { const char* ret = a; - + while (*a) { if (*a == '/' || *a == '\\') @@ -1043,81 +1039,67 @@ const char* strip_name(const char* a) } ++a; } - + return ret; } // Get the number of running modules int countModules(CountModulesMode mode) { - CList::iterator iter; - int num; - + auto num = 0; + switch (mode) { case CountModules_All: - return g_modules.size(); - case CountModules_Running: - iter = g_modules.begin(); - num = 0; - - while (iter) + for (auto module : g_modules) { - if ((*iter).getStatusValue() == MODULE_LOADED) - ++num; - ++iter; + num++; } - + return num; + case CountModules_Running: + for (auto module : g_modules) + { + if (module->getStatusValue() == MODULE_LOADED) + ++num; + } + return num; case CountModules_Stopped: - iter = g_modules.begin(); - num = 0; - - while (iter) + for (auto module : g_modules) { - if ((*iter).getStatusValue() != MODULE_LOADED) + if (module->getStatusValue() != MODULE_LOADED) ++num; - ++iter; } - + return num; } - + return 0; } // Call all modules' AMXX_PluginsLoaded functions void modules_callPluginsLoaded() { - CList::iterator iter = g_modules.begin(); - - while (iter) + for (auto module : g_modules) { - (*iter).CallPluginsLoaded(); - ++iter; + module->CallPluginsLoaded(); } } //same for unloaded void modules_callPluginsUnloaded() { - CList::iterator iter = g_modules.begin(); - - while (iter) + for (auto module : g_modules) { - (*iter).CallPluginsUnloaded(); - ++iter; + module->CallPluginsUnloaded(); } } void modules_callPluginsUnloading() { - CList::iterator iter = g_modules.begin(); - - while (iter) + for (auto module : g_modules) { - (*iter).CallPluginsUnloading(); - ++iter; + module->CallPluginsUnloading(); } } @@ -1128,7 +1110,7 @@ int MNF_AddNatives(AMX_NATIVE_INFO* natives) return FALSE; // may only be called from attach g_CurrentlyCalledModule->m_Natives.append(natives); - + return TRUE; } @@ -1149,74 +1131,69 @@ const char *MNF_GetModname(void) AMX *MNF_GetAmxScript(int id) { - CList::iterator iter = g_loadedscripts.begin(); - - while (iter && id--) - ++iter; - - if (iter == 0) - return NULL; - - return (*iter).getAMX(); + for (auto script : g_loadedscripts) + { + if (id--) + { + continue; + } + return script->getAMX(); + } + return nullptr; } const char *MNF_GetAmxScriptName(int id) { - CList::iterator iter = g_loadedscripts.begin(); - - while (iter && id--) - ++iter; - - if (iter == 0) - return NULL; - - return (*iter).getName(); + for (auto script : g_loadedscripts) + { + if (id--) + { + continue; + } + return script->getName(); + } + return nullptr; } int MNF_FindAmxScriptByName(const char *name) { - CList::iterator iter = g_loadedscripts.begin(); bool found = false; int i = 0; - - while (iter) + + for (auto script : g_loadedscripts) { - if (stricmp((*iter).getName(), name) == 0) + if (!stricmp(script->getName(), name)) { found = true; break; } - ++iter; ++i; } - + if (!found) return -1; - + return i; } int MNF_FindAmxScriptByAmx(const AMX *amx) { - CList::iterator iter = g_loadedscripts.begin(); bool found = false; int i = 0; - - while (iter) - + + for (auto script : g_loadedscripts) { - if (amx == (*iter).getAMX()) + if (script->getAMX() == amx) { found = true; break; } - ++iter; ++i; } - + if (!found) return -1; - + return i; } @@ -1224,10 +1201,10 @@ extern "C" char *MNF_GetAmxString(AMX *amx, cell amx_addr, int bufferId, int *pL { int len; char *retVal = get_amxstring(amx, amx_addr, bufferId, len); - + if (pLen) *pLen = len; - + return retVal; } @@ -1245,10 +1222,10 @@ extern "C" char *MNF_GetAmxStringNull(AMX *amx, cell amx_addr, int bufferId, int int MNF_GetAmxStringLen(const cell *ptr) { register int c = 0; - + while (ptr[c]) ++c; - + return c; } @@ -1267,10 +1244,10 @@ char *MNF_FormatAmxString(AMX *amx, cell *params, int startParam, int *pLen) { int len; char *retVal = format_amxstring(amx, params, startParam, len); - + if (pLen) *pLen = len; - + return retVal; } @@ -1278,9 +1255,9 @@ int MNF_GetPlayerFlags(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0; - + CPlayer *pPlayer = GET_PLAYER_POINTER_I(id); - + return (pPlayer->flags[0]); } @@ -1293,9 +1270,9 @@ int MNF_IsPlayerValid(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0; - + CPlayer *pPlayer = GET_PLAYER_POINTER_I(id); - + return (pPlayer->initialized) ? 1 : 0; } @@ -1303,7 +1280,7 @@ const char * MNF_GetPlayerName(int id) { if (id < 1 || id > gpGlobals->maxClients) return NULL; - + return GET_PLAYER_POINTER_I(id)->name.chars(); } @@ -1311,17 +1288,16 @@ void MNF_OverrideNatives(AMX_NATIVE_INFO *natives, const char *name) { //HACKHACK - we should never have had to do this //find a better solution for SourceMod!!! - for (CList::iterator a = g_modules.begin(); a ; ++a) + for (auto module : g_modules) { - CModule &cm = (*a); - if (cm.getStatusValue() != MODULE_LOADED) + if (module->getStatusValue() != MODULE_LOADED) continue; - const amxx_module_info_s *p = cm.getInfoNew(); + const amxx_module_info_s *p = module->getInfoNew(); if (!p || !p->name) continue; if (strcmp(p->name, name)==0) continue; - cm.rewriteNativeLists(natives); + module->rewriteNativeLists(natives); } } @@ -1329,7 +1305,7 @@ const char * MNF_GetPlayerIP(int id) { if (id < 1 || id > gpGlobals->maxClients) return NULL; - + return GET_PLAYER_POINTER_I(id)->ip.chars(); } @@ -1337,7 +1313,7 @@ int MNF_IsPlayerInGame(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0; - + return GET_PLAYER_POINTER_I(id)->ingame ? 1 : 0; } @@ -1345,7 +1321,7 @@ int MNF_IsPlayerBot(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0; - + return GET_PLAYER_POINTER_I(id)->IsBot() ? 1 : 0; } @@ -1353,7 +1329,7 @@ int MNF_IsPlayerAuthorized(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0; - + return GET_PLAYER_POINTER_I(id)->authorized ? 1 : 0; } @@ -1361,7 +1337,7 @@ float MNF_GetPlayerTime(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0.0f; - + return GET_PLAYER_POINTER_I(id)->time; } @@ -1369,7 +1345,7 @@ float MNF_GetPlayerPlayTime(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0.0f; - + return GET_PLAYER_POINTER_I(id)->playtime; } @@ -1377,7 +1353,7 @@ int MNF_GetPlayerCurweapon(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0; - + return GET_PLAYER_POINTER_I(id)->current; } @@ -1385,7 +1361,7 @@ int MNF_GetPlayerTeamID(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0; - + return GET_PLAYER_POINTER_I(id)->teamId; } @@ -1393,7 +1369,7 @@ int MNF_GetPlayerDeaths(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0; - + return GET_PLAYER_POINTER_I(id)->deaths; } @@ -1401,7 +1377,7 @@ int MNF_GetPlayerMenu(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0; - + return GET_PLAYER_POINTER_I(id)->menu; } @@ -1409,7 +1385,7 @@ int MNF_GetPlayerKeys(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0; - + return GET_PLAYER_POINTER_I(id)->keys; } @@ -1417,7 +1393,7 @@ int MNF_IsPlayerAlive(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0; - + return GET_PLAYER_POINTER_I(id)->IsAlive() ? 1 : 0; } @@ -1425,7 +1401,7 @@ float MNF_GetPlayerFrags(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0.0f; - + return GET_PLAYER_POINTER_I(id)->pEdict->v.frags; } @@ -1433,9 +1409,9 @@ int MNF_IsPlayerConnecting(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0; - + CPlayer * pPlayer = GET_PLAYER_POINTER_I(id); - + return (!pPlayer->ingame && pPlayer->initialized && (GETPLAYERUSERID(pPlayer->pEdict) > 0)) ? 1 : 0; } @@ -1443,7 +1419,7 @@ int MNF_IsPlayerHLTV(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0; - + return (GET_PLAYER_POINTER_I(id)->pEdict->v.flags & FL_PROXY) ? 1 : 0; } @@ -1451,7 +1427,7 @@ float MNF_GetPlayerArmor(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0.0f; - + return (GET_PLAYER_POINTER_I(id)->pEdict->v.armorvalue); } @@ -1459,7 +1435,7 @@ float MNF_GetPlayerHealth(int id) { if (id < 1 || id > gpGlobals->maxClients) return 0; - + return (GET_PLAYER_POINTER_I(id)->pEdict->v.health); } @@ -1481,7 +1457,7 @@ void MNF_Log(const char *fmt, ...) _vsnprintf(msg, sizeof(msg) - 1, fmt, arglst); //vsprintf(msg, fmt, arglst); va_end(arglst); - + AMXXLOG_Log("%s", msg); } @@ -1496,7 +1472,7 @@ extern "C" void LogError(AMX *amx, int err, const char *fmt, ...) char msg_buffer[2048]; msg_buffer[0] = '\0'; - + if (fmt != NULL) { va_list ap; @@ -1534,7 +1510,7 @@ extern "C" void LogError(AMX *amx, int err, const char *fmt, ...) return; } - + //give the user a first-chance at blocking the error from displaying if (pHandler->HandleError(fmt ? msg_buffer : NULL) != 0) { @@ -1550,7 +1526,7 @@ extern "C" void LogError(AMX *amx, int err, const char *fmt, ...) { AMXXLOG_Error("%s", msg_buffer); } - + Debugger::GenericMessage(amx, err); if (err != AMX_ERR_EXIT) { @@ -1590,7 +1566,7 @@ edict_t* MNF_GetPlayerEdict(int id) { if (id < 1 || id > gpGlobals->maxClients) return NULL; - + return (GET_PLAYER_POINTER_I(id)->pEdict); } @@ -1635,52 +1611,38 @@ cell MNF_PrepareCharArray(char *ptr, unsigned int size) return prepareCharArray(ptr, size, false); } -inline bool operator ==(func_s &arg1, const char *desc) -{ - if (strcmp(arg1.desc, desc) == 0) - return true; - - return false; -} - -CList g_functions; +ke::Vector> g_functions; // Fnptr Request function for the new interface const char *g_LastRequestedFunc = NULL; #define REGISTER_FUNC(name, func) \ { \ - pFunc = new func_s; \ + auto pFunc = ke::AutoPtr(new func_s); \ pFunc->pfn = (void *)func; \ pFunc->desc = name; \ - g_functions.put(pFunc); \ + g_functions.append(ke::Move(pFunc)); \ } void MNF_RegisterFunction(void *pfn, const char *description) { - func_s *pFunc; - REGISTER_FUNC(description, pfn); } void *MNF_RegisterFunctionEx(void *pfn, const char *description) { - func_s *pFunc; - CList::iterator iter; - - for (iter = g_functions.begin(); iter; ++iter) + for (auto &func : g_functions) { - pFunc = &(*iter); - if (strcmp(description, pFunc->desc) == 0) + if (!strcmp(description, func->desc)) { - void *pOld = pFunc->pfn; - pFunc->pfn = pfn; + void *pOld = func->pfn; + func->pfn = pfn; return pOld; } } MNF_RegisterFunction(pfn, description); - return NULL; + return nullptr; } void Module_UncacheFunctions() @@ -1809,8 +1771,6 @@ IGameConfigManager *MNF_GetConfigManager() void Module_CacheFunctions() { - func_s *pFunc; - REGISTER_FUNC("BuildPathname", build_pathname) REGISTER_FUNC("BuildPathnameR", build_pathname_r) REGISTER_FUNC("PrintSrvConsole", print_srvconsole) @@ -1918,26 +1878,21 @@ void Module_CacheFunctions() void *Module_ReqFnptr(const char *funcName) { - // code - // ^---- really? wow! - g_LastRequestedFunc = funcName; - CList::iterator iter; - - for (iter = g_functions.begin(); iter; ++iter) + for (auto &func : g_functions) { - if (strcmp(funcName, iter->desc) == 0) - return iter->pfn; + if (!strcmp(funcName, func->desc)) + return func->pfn; } - return NULL; + return nullptr; } Debugger *DisableDebugHandler(AMX *amx) { Debugger *pd = static_cast(amx->userdata[UD_DEBUGGER]); - + amx->userdata[UD_DEBUGGER] = NULL; amx->flags &= ~(AMX_FLAG_DEBUG); amx_SetDebugHook(amx, NULL); @@ -1957,12 +1912,12 @@ void EnableDebugHandler(AMX *amx, Debugger *pd) #if !defined MEMORY_TEST && !defined WIN32 void * operator new(size_t size) { - return (calloc(1, size)); + return (calloc(1, size)); } void * operator new[](size_t size) { - return (calloc(1, size)); + return (calloc(1, size)); } void operator delete(void * ptr) diff --git a/amxmodx/msvc12/amxmodx_mm.sln b/amxmodx/msvc12/amxmodx_mm.sln index 2044b18c..818db48a 100644 --- a/amxmodx/msvc12/amxmodx_mm.sln +++ b/amxmodx/msvc12/amxmodx_mm.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.31101.0 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx_mm", "amxmodx_mm.vcxproj", "{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}" EndProject diff --git a/amxmodx/msvc12/amxmodx_mm.vcxproj b/amxmodx/msvc12/amxmodx_mm.vcxproj index 4d02e821..59a0daaa 100644 --- a/amxmodx/msvc12/amxmodx_mm.vcxproj +++ b/amxmodx/msvc12/amxmodx_mm.vcxproj @@ -151,6 +151,7 @@ + $(IntDir)hashing\ $(IntDir)hashing\ @@ -311,6 +312,13 @@ + + + + + + + @@ -341,17 +349,16 @@ + - - @@ -369,14 +376,10 @@ - - - - @@ -421,4 +424,4 @@ - \ No newline at end of file + diff --git a/amxmodx/msvc12/amxmodx_mm.vcxproj.filters b/amxmodx/msvc12/amxmodx_mm.vcxproj.filters index dfd3c5fb..6a4cf742 100644 --- a/amxmodx/msvc12/amxmodx_mm.vcxproj.filters +++ b/amxmodx/msvc12/amxmodx_mm.vcxproj.filters @@ -46,6 +46,15 @@ {fb5fd616-bb2e-42f1-a113-a61eb9ead739} + + {5dd87e1c-9be5-43d3-8216-74d36f4f7610} + + + {26cdecf1-06de-459e-9ea0-0bbb4a2b3bf6} + + + {04fab577-6f56-40d0-8f69-7ce1b8bf3bb9} + @@ -291,6 +300,9 @@ Source Files + + ReSDK + @@ -326,9 +338,6 @@ Header Files - - Header Files - Header Files @@ -344,9 +353,6 @@ Header Files - - Header Files - Header Files @@ -386,15 +392,6 @@ Header Files - - Header Files - - - Header Files - - - Header Files - Header Files @@ -407,6 +404,15 @@ Header Files + + Header Files + + + Header Files + + + Header Files + SDK @@ -503,6 +509,18 @@ Header Files + + ReSDK\common + + + ReSDK\engine + + + ReSDK\engine + + + ReSDK + @@ -612,4 +630,4 @@ Assembly\Builds - \ No newline at end of file + diff --git a/amxmodx/newmenus.cpp b/amxmodx/newmenus.cpp index 68d4e7f8..7dc6f78a 100755 --- a/amxmodx/newmenus.cpp +++ b/amxmodx/newmenus.cpp @@ -93,7 +93,7 @@ bool CloseNewMenus(CPlayer *pPlayer) Menu::Menu(const char *title, AMX *amx, int fid) : m_Title(title), m_ItemColor("\\r"), m_NeverExit(false), m_AutoColors(g_coloredmenus), thisId(0), func(fid), -isDestroying(false), items_per_page(7) +isDestroying(false), pageCallback(-1), items_per_page(7) { CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx); menuId = g_menucmds.registerMenuId(title, amx); @@ -133,6 +133,7 @@ Menu::~Menu() } unregisterSPForward(this->func); + unregisterSPForward(this->pageCallback); m_Items.clear(); } @@ -1004,6 +1005,28 @@ static cell AMX_NATIVE_CALL menu_setprop(AMX *amx, cell *params) switch (params[2]) { + case MPROP_PAGE_CALLBACK: + { + const char *str = get_amxstring_null(amx, params[3], 0, len); + if (str == nullptr) + { + unregisterSPForward(pMenu->pageCallback); + pMenu->pageCallback = -1; + break; + } + + int callback = registerSPForwardByName(amx, str, FP_CELL, FP_CELL, FP_DONE); + if (callback < 0) + { + LogError(amx, AMX_ERR_NATIVE, "Function %s not present", str); + return 0; + } + + unregisterSPForward(pMenu->pageCallback); + pMenu->pageCallback = callback; + + break; + } case MPROP_SET_NUMBER_COLOR: { char *str = get_amxstring(amx, params[3], 0, len); diff --git a/amxmodx/newmenus.h b/amxmodx/newmenus.h index 40c444f9..dcc5c2e2 100755 --- a/amxmodx/newmenus.h +++ b/amxmodx/newmenus.h @@ -30,6 +30,7 @@ #define MPROP_NOCOLORS 8 #define MPROP_PADMENU 9 #define MPROP_SET_NUMBER_COLOR 10 +#define MPROP_PAGE_CALLBACK 11 typedef int (*MENUITEM_CALLBACK)(int, int, int, int); @@ -125,6 +126,7 @@ public: int thisId; int func; bool isDestroying; + int pageCallback; public: unsigned int items_per_page; }; diff --git a/amxmodx/sh_list.h b/amxmodx/sh_list.h deleted file mode 100644 index 893c8c56..00000000 --- a/amxmodx/sh_list.h +++ /dev/null @@ -1,297 +0,0 @@ -/* ======== SourceMM ======== -* Copyright (C) 2004-2005 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): David "BAILOPAN" Anderson -* ============================ -*/ - -#ifndef _INCLUDE_SMM_LIST_H -#define _INCLUDE_SMM_LIST_H - -// MSVC8 fix for offsetof macro redefition warnings -#ifdef _MSC_VER - #if _MSC_VER >= 1400 - #undef offsetof - #endif -#endif - -#include -#include - -//namespace SourceHook -//{ - //This class is from CSDM for AMX Mod X - /* - A circular, doubly-linked list with one sentinel node - - Empty: - m_Head = sentinel - m_Head->next = m_Head; - m_Head->prev = m_Head; - One element: - m_Head = sentinel - m_Head->next = node1 - m_Head->prev = node1 - node1->next = m_Head - node1->prev = m_Head - Two elements: - m_Head = sentinel - m_Head->next = node1 - m_Head->prev = node2 - node1->next = node2 - node1->prev = m_Head - node2->next = m_Head - node2->prev = node1 - */ - template - class List - { - public: - class iterator; - friend class iterator; - class ListNode - { - public: - ListNode(const T & o) : obj(o) { }; - ListNode() { }; - T obj; - ListNode *next; - ListNode *prev; - }; - private: - // Initializes the sentinel node. - // BAIL used malloc instead of new in order to bypass the need for a constructor. - ListNode *_Initialize() - { - ListNode *n = (ListNode *)malloc(sizeof(ListNode)); - n->next = n; - n->prev = n; - return n; - } - public: - List() : m_Head(_Initialize()), m_Size(0) - { - } - List(const List &src) : m_Head(_Initialize()), m_Size(0) - { - iterator iter; - for (iter=src.begin(); iter!=src.end(); iter++) - push_back( (*iter) ); - } - ~List() - { - clear(); - - // Don't forget to free the sentinel - if (m_Head) - { - free(m_Head); - m_Head = NULL; - } - } - void push_back(const T &obj) - { - ListNode *node = new ListNode(obj); - - node->prev = m_Head->prev; - node->next = m_Head; - m_Head->prev->next = node; - m_Head->prev = node; - - m_Size++; - } - size_t size() - { - return m_Size; - } - - void clear() - { - ListNode *node = m_Head->next; - ListNode *temp; - m_Head->next = m_Head; - m_Head->prev = m_Head; - - // Iterate through the nodes until we find g_Head (the sentinel) again - while (node != m_Head) - { - temp = node->next; - delete node; - node = temp; - } - m_Size = 0; - } - bool empty() - { - return (m_Size == 0); - } - T & back() - { - return m_Head->prev->obj; - } - private: - ListNode *m_Head; - size_t m_Size; - public: - class iterator - { - friend class List; - public: - iterator() - { - m_This = NULL; - } - iterator(const List &src) - { - m_This = src.m_Head; - } - iterator(ListNode *n) : m_This(n) - { - } - iterator(const iterator &where) - { - m_This = where.m_This; - } - //pre decrement - iterator & operator--() - { - if (m_This) - m_This = m_This->prev; - return *this; - } - //post decrement - iterator operator--(int) - { - iterator old(*this); - if (m_This) - m_This = m_This->prev; - return old; - } - - //pre increment - iterator & operator++() - { - if (m_This) - m_This = m_This->next; - return *this; - } - //post increment - iterator operator++(int) - { - iterator old(*this); - if (m_This) - m_This = m_This->next; - return old; - } - - const T & operator * () const - { - return m_This->obj; - } - T & operator * () - { - return m_This->obj; - } - - T * operator -> () - { - return &(m_This->obj); - } - const T * operator -> () const - { - return &(m_This->obj); - } - - bool operator != (const iterator &where) const - { - return (m_This != where.m_This); - } - bool operator ==(const iterator &where) const - { - return (m_This == where.m_This); - } - private: - ListNode *m_This; - }; - public: - iterator begin() const - { - return iterator(m_Head->next); - } - iterator end() const - { - return iterator(m_Head); - } - iterator erase(iterator &where) - { - ListNode *pNode = where.m_This; - iterator iter(where); - iter++; - - - // Works for all cases: empty list, erasing first element, erasing tail, erasing in the middle... - pNode->prev->next = pNode->next; - pNode->next->prev = pNode->prev; - - delete pNode; - m_Size--; - - return iter; - } - - iterator insert(iterator where, const T &obj) - { - // Insert obj right before where - - ListNode *node = new ListNode(obj); - ListNode *pWhereNode = where.m_This; - - pWhereNode->prev->next = node; - node->prev = pWhereNode->prev; - pWhereNode->prev = node; - node->next = pWhereNode; - - m_Size++; - - return iterator(node); - } - - public: - void remove(const T & obj) - { - iterator b; - for (b=begin(); b!=end(); b++) - { - if ( (*b) == obj ) - { - erase( b ); - break; - } - } - } - template - iterator find(const U & equ) - { - iterator iter; - for (iter=begin(); iter!=end(); iter++) - { - if ( (*iter) == equ ) - return iter; - } - return end(); - } - List & operator =(const List &src) - { - clear(); - iterator iter; - for (iter=src.begin(); iter!=src.end(); iter++) - push_back( (*iter) ); - return *this; - } - }; -//}; //NAMESPACE - -#endif //_INCLUDE_CSDM_LIST_H diff --git a/amxmodx/sh_stack.h b/amxmodx/sh_stack.h deleted file mode 100755 index 04158ca1..00000000 --- a/amxmodx/sh_stack.h +++ /dev/null @@ -1,219 +0,0 @@ -/* ======== SourceMM ======== -* Copyright (C) 2004-2005 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -#ifndef __SH_STACK_H__ -#define __SH_STACK_H__ - -#define SH_STACK_DEFAULT_SIZE 4 - -//namespace SourceHook -//{/ - // Vector - template class CStack - { - T *m_Elements; - size_t m_AllocatedSize; - size_t m_UsedSize; - public: - friend class iterator; - class iterator - { - CStack *m_pParent; - size_t m_Index; - public: - iterator(CStack *pParent, size_t id) : m_pParent(pParent), m_Index(id) - { - } - - iterator(CStack *pParent) : m_pParent(pParent), m_Index(0) - { - } - - iterator() : m_pParent(NULL), m_Index(0) - { - } - - T &operator *() - { - return m_pParent->m_Elements[m_Index]; - } - const T &operator *() const - { - return m_pParent->m_Elements[m_Index]; - } - - T * operator->() - { - return m_pParent->m_Elements + m_Index; - } - - const T * operator->() const - { - return m_pParent->m_Elements + m_Index; - } - - iterator & operator++() // preincrement - { - ++m_Index; - return (*this); - } - - iterator operator++(int) // postincrement - { - iterator tmp = *this; - ++m_Index; - return tmp; - } - - iterator & operator--() // predecrement - { - --m_Index; - return (*this); - } - - iterator operator--(int) // postdecrememnt - { - iterator tmp = *this; - --m_Index; - return tmp; - } - - bool operator==(const iterator & right) const - { - return (m_pParent == right.m_pParent && m_Index == right.m_Index); - } - - bool operator!=(const iterator & right) const - { - return !(*this == right); - } - }; - CStack() : m_Elements(new T[SH_STACK_DEFAULT_SIZE]), - m_AllocatedSize(SH_STACK_DEFAULT_SIZE), - m_UsedSize(0) - { - } - CStack(size_t size) : m_Elements(new T[size]), - m_AllocatedSize(size), - m_UsedSize(0) - { - } - - CStack(const CStack &other) : m_Elements(NULL), - m_AllocatedSize(0), - m_UsedSize(0) - { - reserve(other.m_AllocatedSize); - m_UsedSize = other.m_UsedSize; - for (size_t i = 0; i < m_UsedSize; ++i) - m_Elements[i] = other.m_Elements[i]; - } - - ~CStack() - { - if (m_Elements) - delete [] m_Elements; - } - - void operator=(const CStack &other) - { - if (m_AllocatedSize < other.m_AllocatedSize) - { - if (m_Elements) - delete [] m_Elements; - m_Elements = new T[other.m_AllocatedSize]; - m_AllocatedSize = other.m_AllocatedSize; - } - m_UsedSize = other.m_UsedSize; - for (size_t i = 0; i < m_UsedSize; ++i) - m_Elements[i] = other.m_Elements[i]; - } - - bool push(const T &val) - { - if (m_UsedSize + 1 == m_AllocatedSize) - { - // zOHNOES! REALLOCATE! - m_AllocatedSize *= 2; - T *newElements = new T[m_AllocatedSize]; - if (!newElements) - { - m_AllocatedSize /= 2; - return false; - } - if (m_Elements) - { - for (size_t i = 0; i < m_UsedSize; ++i) - newElements[i] = m_Elements[i]; - delete [] m_Elements; - } - m_Elements = newElements; - } - m_Elements[m_UsedSize++] = val; - return true; - } - void pop() - { - --m_UsedSize; - } - - T &front() - { - return m_Elements[m_UsedSize - 1]; - } - - const T &front() const - { - return m_Elements[m_UsedSize - 1]; - } - - iterator begin() - { - return iterator(this, 0); - } - iterator end() - { - return iterator(this, m_UsedSize); - } - - size_t size() - { - return m_UsedSize; - } - size_t capacity() - { - return m_AllocatedSize; - } - bool empty() - { - return m_UsedSize == 0 ? true : false; - } - bool reserve(size_t size) - { - if (size > m_AllocatedSize) - { - T *newElements = new T[size]; - if (!newElements) - return false; - if (m_Elements) - { - for (size_t i = 0; i < m_UsedSize; ++i) - newElements[i] = m_Elements[i]; - delete [] m_Elements; - } - m_Elements = newElements; - m_AllocatedSize = size; - } - return true; - } - }; -//}; //namespace SourceHook - -#endif diff --git a/amxmodx/srvcmd.cpp b/amxmodx/srvcmd.cpp index 300ba5f6..4993ef08 100755 --- a/amxmodx/srvcmd.cpp +++ b/amxmodx/srvcmd.cpp @@ -188,16 +188,13 @@ void amx_command() int running = 0; int modules = 0; - CList::iterator a = g_modules.begin(); - - while (a) + for (auto module : g_modules) { - if ((*a).getStatusValue() == MODULE_LOADED) + if (module->getStatusValue() == MODULE_LOADED) ++running; ++modules; - print_srvconsole(" [%2d] %-23.22s %-11.10s %-20.19s %-11.10s\n", modules, (*a).getName(), (*a).getVersion(), (*a).getAuthor(), (*a).getStatus()); - ++a; + print_srvconsole(" [%2d] %-23.22s %-11.10s %-20.19s %-11.10s\n", modules, module->getName(), module->getVersion(), module->getAuthor(), module->getStatus()); } print_srvconsole("%d modules, %d correct\n", modules, running); diff --git a/modules/cstrike/cstrike/AMBuilder b/modules/cstrike/cstrike/AMBuilder index 3c86c911..18a9b842 100644 --- a/modules/cstrike/cstrike/AMBuilder +++ b/modules/cstrike/cstrike/AMBuilder @@ -19,6 +19,8 @@ binary.sources = [ '../../../public/memtools/MemoryUtils.cpp', '../../../public/memtools/CDetour/detours.cpp', '../../../public/memtools/CDetour/asm/asm.c', + '../../../public/resdk/mod_rehlds_api.cpp', + '../../../public/resdk/mod_regamedll_api.cpp', ] if builder.target_platform == 'windows': diff --git a/modules/cstrike/cstrike/CstrikeDatas.h b/modules/cstrike/cstrike/CstrikeDatas.h index 433651c0..81a02977 100644 --- a/modules/cstrike/cstrike/CstrikeDatas.h +++ b/modules/cstrike/cstrike/CstrikeDatas.h @@ -326,7 +326,7 @@ enum CsWeaponClassType /** * Weapon infos. */ -typedef struct +struct WeaponInfoStruct { int id; int cost; @@ -336,8 +336,8 @@ typedef struct int maxRounds; int ammoType; char *entityName; -} -WeaponInfoStruct; + const char *ammoName; +}; /** * Weapon infos for use with cs_get_weapon_info(). diff --git a/modules/cstrike/cstrike/CstrikeHacks.cpp b/modules/cstrike/cstrike/CstrikeHacks.cpp index a3b7ff25..7f07e96a 100644 --- a/modules/cstrike/cstrike/CstrikeHacks.cpp +++ b/modules/cstrike/cstrike/CstrikeHacks.cpp @@ -15,6 +15,8 @@ #include "CstrikeUtils.h" #include "CstrikeHacks.h" #include "CstrikeItemsInfos.h" +#include +#include int ForwardInternalCommand = -1; int ForwardOnBuy = -1; @@ -64,10 +66,20 @@ server_t *Server; // Mod global variable void **GameRules; +void *GameRulesRH; +bool HasReHlds; +bool HasReGameDll; + +bool HasRestricteditem_Enabled; +bool InternalCommand_Enabled; +bool GiveDefaultItems_Enabled; void InitializeHacks() { + HasReHlds = RehldsApi_Init(); + HasReGameDll = RegamedllApi_Init(); + CtrlDetours_ClientCommand(true); CtrlDetours_BuyCommands(true); CtrlDetours_Natives(true); @@ -88,7 +100,11 @@ void ShutdownHacks() const char *CMD_ARGV(int i) { - if (*UseBotArgs) + if (HasReGameDll) + { + return ReGameFuncs->Cmd_Argv(i); + } + else if (*UseBotArgs) { if (i < 4) { @@ -101,9 +117,10 @@ const char *CMD_ARGV(int i) return g_engfuncs.pfnCmd_Argv(i); } -DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientCommand(edict_t *pEntity) +void (*C_ClientCommand_Actual)(edict_t *) = nullptr; + +void ClientCommand_Custom(edict_t *pEdict, const char *command, const char *arg1, IReGameHook_InternalCommand *chain = nullptr) { - auto command = CMD_ARGV(0); auto client = TypeConversion.edict_to_id(pEdict); CurrentItemId = CSI_NONE; @@ -117,7 +134,7 @@ DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientComma // Handling buy via menu. if (!strcmp(command, "menuselect")) { - auto slot = atoi(CMD_ARGV(1)); + auto slot = atoi(arg1); if (slot > 0 && slot < 9) { @@ -172,7 +189,7 @@ DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientComma } } - if (HasInternalCommandForward && *UseBotArgs && MF_ExecuteForward(ForwardInternalCommand, client, *BotArgs) > 0) + if (HasInternalCommandForward && (HasReGameDll || *UseBotArgs) && MF_ExecuteForward(ForwardInternalCommand, client, CMD_ARGV(0)) > 0) { return; } @@ -185,11 +202,21 @@ DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientComma TriggeredFromCommand = CurrentItemId != CSI_NONE; - DETOUR_STATIC_CALL(C_ClientCommand)(pEdict); + chain ? chain->callNext(pEdict, command, arg1) : C_ClientCommand_Actual(pEdict); TriggeredFromCommand = BlockMoneyUpdate = BlockAmmosUpdate = false; } +void C_ClientCommand(edict_t* pEdict) // void ClientCommand(edict_t *pEntity) +{ + ClientCommand_Custom(pEdict, CMD_ARGV(0), CMD_ARGV(1)); +} + +void InternalCommand_RH(IReGameHook_InternalCommand* chain, edict_t *pEdict, const char *command, const char *arg1) +{ + ClientCommand_Custom(pEdict, CMD_ARGV(0), CMD_ARGV(1), chain); +} + edict_s* OnCreateNamedEntity(int classname) { if (NoKnivesMode) @@ -219,6 +246,18 @@ DETOUR_DECL_MEMBER0(GiveDefaultItems, void) // void CBasePlayer::GiveDefaultIte g_pengfuncsTable->pfnCreateNamedEntity = nullptr; } +void GiveDefaultItems_RH(IReGameHook_CBasePlayer_GiveDefaultItems *chain, class CBasePlayer *pPlayer) +{ + if (NoKnivesMode) + { + g_pengfuncsTable->pfnCreateNamedEntity = OnCreateNamedEntity; + } + + chain->callNext(pPlayer); + + g_pengfuncsTable->pfnCreateNamedEntity = nullptr; +} + DETOUR_DECL_MEMBER1(CanPlayerBuy, bool, bool, display) // bool CBasePlayer::CanPlayerBuy(bool display) { auto canBuy = DETOUR_MEMBER_CALL(CanPlayerBuy)(display); @@ -340,6 +379,35 @@ DETOUR_DECL_MEMBER2(AddAccount, void, int, amount, bool, bTrackChange) // void C DETOUR_MEMBER_CALL(AddAccount)(amount, bTrackChange); } +bool CBasePlayer_HasRestrictItem_RH(IReGameHook_CBasePlayer_HasRestrictItem *chain, class CBasePlayer *pPlayer, ItemID item, ItemRestType type) +{ + if (type == ITEM_TYPE_BUYING && CurrentItemId != CSI_NONE) + { + auto player = TypeConversion.cbase_to_id(pPlayer); + + if (MF_IsPlayerAlive(player) && MF_ExecuteForward(ForwardOnBuy, player, CurrentItemId) > 0) + { + return true; + } + } + + return chain->callNext(pPlayer, item, type); +} + +bool BuyGunAmmo_RH(IReGameHook_BuyGunAmmo *chain, class CBasePlayer *pPlayer, class CBasePlayerItem *pWeapon, bool blinkMoney) +{ + if (CurrentItemId == CSI_PRIAMMO || CurrentItemId == CSI_SECAMMO) + { + auto player = TypeConversion.cbase_to_id(pPlayer); + + if (MF_IsPlayerAlive(player) && MF_ExecuteForward(ForwardOnBuy, player, CurrentItemId) > 0) + { + return false; + } + } + + return chain->callNext(pPlayer, pWeapon, blinkMoney); +} void ToggleDetour(CDetour *detour, bool enable) { @@ -363,137 +431,190 @@ void CtrlDetours_ClientCommand(bool set) { if (set) { - auto base = reinterpret_cast(MDLL_ClientCommand); + if (HasReGameDll) + { + if (!InternalCommand_Enabled) + { + ReGameHookchains->InternalCommand()->registerHook(InternalCommand_RH); + InternalCommand_Enabled = true; + } + } + else + { + auto base = reinterpret_cast(MDLL_ClientCommand); #if defined(KE_WINDOWS) - TypeDescription type; + TypeDescription type; - if (MainConfig->GetOffset("UseBotArgs", &type)) - { - UseBotArgs = get_pdata(base, type.fieldOffset); - } + if (MainConfig->GetOffset("UseBotArgs", &type)) + { + UseBotArgs = get_pdata(base, type.fieldOffset); + } - if (MainConfig->GetOffset("BotArgs", &type)) - { - BotArgs = get_pdata(base, type.fieldOffset); - } + if (MainConfig->GetOffset("BotArgs", &type)) + { + BotArgs = get_pdata(base, type.fieldOffset); + } #else - void *address = nullptr; + void *address = nullptr; - if (MainConfig->GetMemSig("UseBotArgs", &address)) - { - UseBotArgs = reinterpret_cast(address); - } + if (MainConfig->GetMemSig("UseBotArgs", &address)) + { + UseBotArgs = reinterpret_cast(address); + } - if (MainConfig->GetMemSig("BotArgs", &address)) - { - BotArgs = reinterpret_cast(address); - } + if (MainConfig->GetMemSig("BotArgs", &address)) + { + BotArgs = reinterpret_cast(address); + } #endif - ClientCommandDetour = DETOUR_CREATE_STATIC_FIXED(C_ClientCommand, base); + ClientCommandDetour = DETOUR_CREATE_STATIC_FIXED(C_ClientCommand, base); - if (!ClientCommandDetour) - { - MF_Log("ClientCommand is not available - forwards CS_InternalCommand and CS_OnBuy[Attempt] have been disabled"); - CtrlDetours_ClientCommand(false); - } - else if (!UseBotArgs || !BotArgs) - { - MF_Log("UseBotArgs or BotArgs is not available - forward CS_InternalCommand has been disabled"); - } + if (!ClientCommandDetour) + { + MF_Log("ClientCommand is not available - forwards CS_InternalCommand and CS_OnBuy[Attempt] have been disabled"); + ToggleHook_ClientCommands(false); + } + else if (!UseBotArgs || !BotArgs) + { + MF_Log("UseBotArgs or BotArgs is not available - forward CS_InternalCommand has been disabled"); + } + } } else { - DestroyDetour(ClientCommandDetour); + if (HasReGameDll) + { + ReGameHookchains->InternalCommand()->unregisterHook(InternalCommand_RH); + InternalCommand_Enabled = false; + } + else + { + DestroyDetour(ClientCommandDetour); + } } } -void ToggleDetour_ClientCommands(bool enable) +void ToggleHook_ClientCommands(bool enable) { - ToggleDetour(ClientCommandDetour, enable); + if (HasReGameDll) + { + CtrlDetours_ClientCommand(enable); + } + else + { + ToggleDetour(ClientCommandDetour, enable); + } } - void CtrlDetours_BuyCommands(bool set) { if (set) { - void *address = nullptr; - - if (MainConfig->GetMemSig("BuyGunAmmo", &address)) + if (HasReGameDll) { - BuyGunAmmoDetour = DETOUR_CREATE_STATIC_FIXED(BuyGunAmmo, address); - } - - if (MainConfig->GetMemSig("GiveNamedItem", &address)) - { - GiveNamedItemDetour = DETOUR_CREATE_MEMBER_FIXED(GiveNamedItem, address); - } - - if (MainConfig->GetMemSig("AddAccount", &address)) - { - AddAccountDetour = DETOUR_CREATE_MEMBER_FIXED(AddAccount, address); - } - - if (MainConfig->GetMemSig("CanPlayerBuy", &address)) - { - CanPlayerBuyDetour = DETOUR_CREATE_MEMBER_FIXED(CanPlayerBuy, address); - } - - if (MainConfig->GetMemSig("CanBuyThis", &address)) - { - CanBuyThisDetour = DETOUR_CREATE_STATIC_FIXED(CanBuyThis, address); - } - - if (!BuyGunAmmoDetour || !GiveNamedItemDetour || !AddAccountDetour || !CanPlayerBuyDetour || !CanBuyThisDetour) - { - if (!BuyGunAmmoDetour) + if (!HasRestricteditem_Enabled) { - MF_Log("BuyGunAmmo is not available"); + ReGameHookchains->CBasePlayer_HasRestrictItem()->registerHook(CBasePlayer_HasRestrictItem_RH); + ReGameHookchains->BuyGunAmmo()->registerHook(BuyGunAmmo_RH); + HasRestricteditem_Enabled = true; + } + } + else + { + void *address = nullptr; + + if (MainConfig->GetMemSig("BuyGunAmmo", &address)) + { + BuyGunAmmoDetour = DETOUR_CREATE_STATIC_FIXED(BuyGunAmmo, address); } - if (!GiveNamedItemDetour) + if (MainConfig->GetMemSig("GiveNamedItem", &address)) { - MF_Log("GiveNamedItem is not available"); + GiveNamedItemDetour = DETOUR_CREATE_MEMBER_FIXED(GiveNamedItem, address); } - if (!AddAccountDetour) + if (MainConfig->GetMemSig("AddAccount", &address)) { - MF_Log("AddAccount is not available"); + AddAccountDetour = DETOUR_CREATE_MEMBER_FIXED(AddAccount, address); } - if (!CanPlayerBuyDetour) + if (MainConfig->GetMemSig("CanPlayerBuy", &address)) { - MF_Log("CanPlayerBuy is not available"); + CanPlayerBuyDetour = DETOUR_CREATE_MEMBER_FIXED(CanPlayerBuy, address); } - if (!CanBuyThisDetour) + if (MainConfig->GetMemSig("CanBuyThis", &address)) { - MF_Log("CanBuyThis is not available"); + CanBuyThisDetour = DETOUR_CREATE_STATIC_FIXED(CanBuyThis, address); } - MF_Log("Some functions are not available - forwards CS_OnBuy[Attempt] have been disabled"); - ToggleDetour_BuyCommands(false); + if (!BuyGunAmmoDetour || !GiveNamedItemDetour || !AddAccountDetour || !CanPlayerBuyDetour || !CanBuyThisDetour) + { + if (!BuyGunAmmoDetour) + { + MF_Log("BuyGunAmmo is not available"); + } + + if (!GiveNamedItemDetour) + { + MF_Log("GiveNamedItem is not available"); + } + + if (!AddAccountDetour) + { + MF_Log("AddAccount is not available"); + } + + if (!CanPlayerBuyDetour) + { + MF_Log("CanPlayerBuy is not available"); + } + + if (!CanBuyThisDetour) + { + MF_Log("CanBuyThis is not available"); + } + + MF_Log("Some functions are not available - forwards CS_OnBuy[Attempt] have been disabled"); + ToggleHook_BuyCommands(false); + } } } else { - DestroyDetour(BuyGunAmmoDetour); - DestroyDetour(GiveNamedItemDetour); - DestroyDetour(AddAccountDetour); - DestroyDetour(CanPlayerBuyDetour); - DestroyDetour(CanBuyThisDetour); + if (HasReGameDll) + { + ReGameHookchains->CBasePlayer_HasRestrictItem()->unregisterHook(CBasePlayer_HasRestrictItem_RH); + ReGameHookchains->BuyGunAmmo()->unregisterHook(BuyGunAmmo_RH); + HasRestricteditem_Enabled = false; + } + else + { + DestroyDetour(BuyGunAmmoDetour); + DestroyDetour(GiveNamedItemDetour); + DestroyDetour(AddAccountDetour); + DestroyDetour(CanPlayerBuyDetour); + DestroyDetour(CanBuyThisDetour); + } } } -void ToggleDetour_BuyCommands(bool enable) +void ToggleHook_BuyCommands(bool enable) { - ToggleDetour(BuyGunAmmoDetour, enable); - ToggleDetour(GiveNamedItemDetour, enable); - ToggleDetour(AddAccountDetour, enable); - ToggleDetour(CanPlayerBuyDetour, enable); - ToggleDetour(CanBuyThisDetour, enable); + if (HasReGameDll) + { + CtrlDetours_BuyCommands(enable); + } + else + { + ToggleDetour(BuyGunAmmoDetour, enable); + ToggleDetour(GiveNamedItemDetour, enable); + ToggleDetour(AddAccountDetour, enable); + ToggleDetour(CanPlayerBuyDetour, enable); + ToggleDetour(CanBuyThisDetour, enable); + } } @@ -501,54 +622,94 @@ void CtrlDetours_Natives(bool set) { if (set) { - void *address = nullptr; - - if (MainConfig->GetMemSig("GiveDefaultItems", &address)) + if (HasReGameDll) { - GiveDefaultItemsDetour = DETOUR_CREATE_MEMBER_FIXED(GiveDefaultItems, address); + if (!GiveDefaultItems_Enabled) + { + ReGameHookchains->CBasePlayer_GiveDefaultItems()->registerHook(GiveDefaultItems_RH); + GiveDefaultItems_Enabled = true; + } } - - if (!GiveDefaultItemsDetour) + else { - MF_Log("GiveDefaultItems is not available - native cs_set_no_knives has been disabled"); + void *address = nullptr; + + if (MainConfig->GetMemSig("GiveDefaultItems", &address)) + { + GiveDefaultItemsDetour = DETOUR_CREATE_MEMBER_FIXED(GiveDefaultItems, address); + } + + if (!GiveDefaultItemsDetour) + { + MF_Log("GiveDefaultItems is not available - native cs_set_no_knives has been disabled"); + } } } else { - DestroyDetour(GiveDefaultItemsDetour); + if (HasReGameDll) + { + ReGameHookchains->CBasePlayer_GiveDefaultItems()->unregisterHook(GiveDefaultItems_RH); + GiveDefaultItems_Enabled = false; + } + else + { + DestroyDetour(GiveDefaultItemsDetour); + } + } +} + +void ToggleHook_GiveDefaultItems(bool enable) +{ + if (HasReGameDll) + { + CtrlDetours_Natives(enable); + } + else + { + ToggleDetour(GiveDefaultItemsDetour, enable); } } void InitFuncsAddresses() { - void *address = nullptr; - - if (MainConfig->GetMemSig("CreateNamedEntity", &address)) // cs_create_entity() + if (HasReGameDll) { - CS_CreateNamedEntity = reinterpret_cast(address); + RemoveEntityHashValue = ReGameFuncs->RemoveEntityHashValue; + CS_CreateNamedEntity = ReGameFuncs->CREATE_NAMED_ENTITY2; + CS_UTIL_FindEntityByString = ReGameFuncs->UTIL_FindEntityByString; + AddEntityHashValue = ReGameFuncs->AddEntityHashValue; } - - if (MainConfig->GetMemSig("FindEntityByString", &address)) // cs_find_ent_by_class() + else { - CS_UTIL_FindEntityByString = reinterpret_cast(address); - } + void *address = nullptr; - if (MainConfig->GetMemSig("GetWeaponInfo", &address)) // cs_get_weapon_info() - { - GetWeaponInfo = reinterpret_cast(address); - } + if (MainConfig->GetMemSig("CreateNamedEntity", &address)) // cs_create_entity() + { + CS_CreateNamedEntity = reinterpret_cast(address); + } - if (MainConfig->GetMemSig("AddEntityHashValue", &address)) // cs_set_ent_class() - { - AddEntityHashValue = reinterpret_cast(address); - } + if (MainConfig->GetMemSig("FindEntityByString", &address)) // cs_find_ent_by_class() + { + CS_UTIL_FindEntityByString = reinterpret_cast(address); + } - if (MainConfig->GetMemSig("RemoveEntityHashValue", &address)) // cs_set_ent_class() - { - RemoveEntityHashValue = reinterpret_cast(address); - } + if (MainConfig->GetMemSig("GetWeaponInfo", &address)) // cs_get_weapon_info() + { + GetWeaponInfo = reinterpret_cast(address); + } + if (MainConfig->GetMemSig("AddEntityHashValue", &address)) // cs_set_ent_class() + { + AddEntityHashValue = reinterpret_cast(address); + } + + if (MainConfig->GetMemSig("RemoveEntityHashValue", &address)) // cs_set_ent_class() + { + RemoveEntityHashValue = reinterpret_cast(address); + } + } if (!CS_CreateNamedEntity) { @@ -560,7 +721,12 @@ void InitFuncsAddresses() MF_Log("UTIL_FindEntByString is not available - native cs_find_ent_by_class() has been disabled"); } - if (!GetWeaponInfo) + if (!AddEntityHashValue || !AddEntityHashValue) + { + MF_Log("AddEntityHashValue or AddEntityHashValue is not available - native cs_set_ent_class() has been disabled"); + } + + if (!HasReGameDll && !GetWeaponInfo) { MF_Log("GetWeaponInfo is not available - native cs_get_weapon_info() and forward CS_OnBuy have been disabled"); CtrlDetours_BuyCommands(false); @@ -584,66 +750,86 @@ void InitClassMembers() !MoneyDesc.fieldOffset) { MF_Log("Invalid or missing entity gamedata files - forwards CS_OnBuy[Attempt] have been disabled"); - CtrlDetours_BuyCommands(false); + ToggleHook_BuyCommands(false); } } +CGameRules* InstallGameRules(IReGameHook_InstallGameRules *chain) +{ + GameRulesRH = chain->callNext(); + return static_cast(GameRulesRH); +} + void InitGlobalVars() { void *address = nullptr; + if (!HasReHlds) + { #if defined(KE_WINDOWS) + TypeDescription typeDesc; - TypeDescription typeDesc; - - if (CommonConfig->GetOffset("svs", &typeDesc)) - { - uintptr_t base = *reinterpret_cast(reinterpret_cast(g_engfuncs.pfnGetCurrentPlayer) + typeDesc.fieldOffset); - ServerStatic = reinterpret_cast(base - 4); - } - - if (CommonConfig->GetAddress("sv", &address)) - { - Server = *reinterpret_cast(address); - } - - if (CommonConfig->GetAddress("g_pGameRules", &address)) - { - GameRules = *reinterpret_cast(address); - } + if (CommonConfig->GetOffset("svs", &typeDesc)) + { + uintptr_t base = *reinterpret_cast(reinterpret_cast(g_engfuncs.pfnGetCurrentPlayer) + typeDesc.fieldOffset); + ServerStatic = reinterpret_cast(base - 4); + } + if (CommonConfig->GetAddress("sv", &address)) + { + Server = *reinterpret_cast(address); + } #else + if (CommonConfig->GetMemSig("svs", &address)) + { + ServerStatic = reinterpret_cast(address); + } - if (CommonConfig->GetMemSig("svs", &address)) - { - ServerStatic = reinterpret_cast(address); - } - - if (CommonConfig->GetMemSig("sv", &address)) - { - Server = reinterpret_cast(address); - } - - if (CommonConfig->GetMemSig("g_pGameRules", &address)) - { - GameRules = reinterpret_cast(address); - } - + if (CommonConfig->GetMemSig("sv", &address)) + { + Server = reinterpret_cast(address); + } #endif - - if (!ServerStatic) - { - MF_Log("svs global variable is not available"); } - if (!Server) + if (HasReGameDll) { - MF_Log("sv global variable is not available"); + ReGameHookchains->InstallGameRules()->registerHook(InstallGameRules); + } + else + { +#if defined(KE_WINDOWS) + if (CommonConfig->GetAddress("g_pGameRules", &address)) + { + GameRules = *reinterpret_cast(address); + } +#else + if (CommonConfig->GetMemSig("g_pGameRules", &address)) + { + GameRules = reinterpret_cast(address); + } +#endif } - if (!GameRules) + if (!HasReHlds) { - MF_Log("g_pGameRules is not available - Forward CS_OnBuy has been disabled"); - CtrlDetours_BuyCommands(false); + if (!ServerStatic) + { + MF_Log("svs global variable is not available"); + } + + if (!Server) + { + MF_Log("sv global variable is not available"); + } + } + + if (!HasReGameDll) + { + if (!GameRules) + { + MF_Log("g_pGameRules is not available - Forward CS_OnBuy has been disabled"); + CtrlDetours_BuyCommands(false); + } } } diff --git a/modules/cstrike/cstrike/CstrikeHacks.h b/modules/cstrike/cstrike/CstrikeHacks.h index 26ca7e76..250b2884 100644 --- a/modules/cstrike/cstrike/CstrikeHacks.h +++ b/modules/cstrike/cstrike/CstrikeHacks.h @@ -19,6 +19,7 @@ #include #include #include "CstrikeDatas.h" +#include void InitializeHacks(); void InitFuncsAddresses(); @@ -30,8 +31,9 @@ void CtrlDetours_ClientCommand(bool set); void CtrlDetours_BuyCommands(bool set); void CtrlDetours_Natives(bool set); -void ToggleDetour_ClientCommands(bool enable); -void ToggleDetour_BuyCommands(bool enable); +void ToggleHook_ClientCommands(bool enable); +void ToggleHook_BuyCommands(bool enable); +void ToggleHook_GiveDefaultItems(bool enable); extern AMX_NATIVE_INFO CstrikeNatives[]; @@ -60,10 +62,10 @@ enum class HashType }; typedef edict_t* (*CreateNamedEntityFunc)(string_t iszClassname); -typedef void* (*UTIL_FindEntityByStringFunc)(void* pStartEntity, const char *szKeyword, const char *szValue); +typedef class CBaseEntity* (*UTIL_FindEntityByStringFunc)(class CBaseEntity *pStartEntity, const char *szKeyword, const char *szValue); typedef WeaponInfoStruct* (*GetWeaponInfoFunc)(int id); -typedef void (*AddEntityHashValueFunc)(struct entvars_s *pev, const char *value, HashType fieldType); -typedef void (*RemoveEntityHashValueFunc)(struct entvars_s *pev, const char *value, HashType fieldType); +typedef void (*AddEntityHashValueFunc)(entvars_s *pev, const char *value, hash_types_e fieldType); +typedef void (*RemoveEntityHashValueFunc)(entvars_t *pev, const char *value, hash_types_e fieldType); extern CreateNamedEntityFunc CS_CreateNamedEntity; extern UTIL_FindEntityByStringFunc CS_UTIL_FindEntityByString; @@ -79,8 +81,12 @@ extern bool NoKnivesMode; extern server_static_t *ServerStatic; extern server_t *Server; extern void **GameRules; +extern void *GameRulesRH; extern int *UseBotArgs; extern const char **BotArgs; +extern bool HasReHlds; +extern bool HasReGameDll; + #endif // CSTRIKE_HACKS_H diff --git a/modules/cstrike/cstrike/CstrikeItemsInfos.cpp b/modules/cstrike/cstrike/CstrikeItemsInfos.cpp index fc3d4ab1..72934985 100644 --- a/modules/cstrike/cstrike/CstrikeItemsInfos.cpp +++ b/modules/cstrike/cstrike/CstrikeItemsInfos.cpp @@ -14,6 +14,7 @@ #include "CstrikeItemsInfos.h" #include "CstrikeHacks.h" #include +#include CsItemInfo ItemsManager; ItemInfo WeaponsList[MAX_WEAPONS]; @@ -102,7 +103,7 @@ SMCResult CsItemInfo::ReadSMC_KeyValue(const SMCStates *states, const char *key, CSI_NONE, CSI_VEST, CSI_VESTHELM, CSI_FLASHBANG, CSI_HEGRENADE, CSI_SMOKEGRENADE, CSI_NVGS, CSI_DEFUSER }; - for (int i = 0; i < ARRAY_LENGTH(equipmentsList); ++i) + for (size_t i = 0; i < ARRAY_LENGTH(equipmentsList); ++i) { if (m_AliasInfo.itemid == equipmentsList[i]) { @@ -172,7 +173,7 @@ bool CsItemInfo::GetAliasFromId(size_t id, ke::AString &name, ke::AString &altna { for (auto iter = m_BuyAliasesList.iter(); !iter.empty(); iter.next()) { - if (iter->value.itemid == id) + if (iter->value.itemid == (int)id) { name = iter->key; altname = iter->value.alt_alias; @@ -272,5 +273,10 @@ int CsItemInfo::GetItemPrice(int itemId) return m_EquipmentsPrice[static_cast(id)]; } + if (HasReGameDll) + { + return ReGameApi->GetWeaponInfo(itemId == CSI_SHIELD ? CSI_SHIELDGUN : itemId)->cost; + } + return GetWeaponInfo(itemId == CSI_SHIELD ? CSI_SHIELDGUN : itemId)->cost; } diff --git a/modules/cstrike/cstrike/CstrikeMain.cpp b/modules/cstrike/cstrike/CstrikeMain.cpp index b5cd94a9..be63441a 100644 --- a/modules/cstrike/cstrike/CstrikeMain.cpp +++ b/modules/cstrike/cstrike/CstrikeMain.cpp @@ -17,6 +17,7 @@ #include "CstrikeItemsInfos.h" #include "CstrikeUserMessages.h" #include +#include IGameConfig *MainConfig; IGameConfig *CommonConfig; @@ -24,6 +25,8 @@ IGameConfigManager *ConfigManager; HLTypeConversion TypeConversion; +extern StringHashMap ModelsList; + int AmxxCheckGame(const char *game) { if (strcasecmp(game, "cstrike") == 0 || @@ -34,6 +37,30 @@ int AmxxCheckGame(const char *game) return AMXX_GAME_BAD; } +void SV_ActivateServer_RH(IRehldsHook_SV_ActivateServer *chain, int runPhysics) +{ + chain->callNext(runPhysics); + + auto numResources = RehldsData->GetResourcesNum(); + + if (!numResources) + { + return; + } + + ModelsList.clear(); + + for (auto i = 0; i < numResources; ++i) // Saves all the precached models into a list. + { + auto resource = RehldsData->GetResource(i); + + if (resource->type == t_model) + { + ModelsList.insert(resource->szFileName, i); + } + } +} + void OnAmxxAttach() { MF_AddNatives(CstrikeNatives); @@ -58,6 +85,11 @@ void OnAmxxAttach() } InitializeHacks(); + + if (HasReHlds) + { + RehldsHookchains->SV_ActivateServer()->registerHook(SV_ActivateServer_RH); + } } void OnPluginsLoaded() @@ -74,23 +106,30 @@ void OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax) // Used to catch WeaponList message at map change. EnableMessageHooks(); - if (!ClientCommandDetour) // All CS_* forwards requires ClientCommand. Unlikely to fail. + if (!HasReGameDll && !ClientCommandDetour) // All CS_* forwards requires ClientCommand. Unlikely to fail. { - ToggleDetour_ClientCommands(false); - ToggleDetour_BuyCommands(false); + ToggleHook_ClientCommands(false); + ToggleHook_BuyCommands(false); RETURN_META(MRES_IGNORED); } - auto haveBotDetours = UseBotArgs && BotArgs; - auto haveBuyDetours = BuyGunAmmoDetour && GiveNamedItemDetour && AddAccountDetour && CanPlayerBuyDetour && CanBuyThisDetour; + auto haveBotHooks = true; + auto haveBuyHooks = true; - HasInternalCommandForward = haveBotDetours && UTIL_CheckForPublic("CS_InternalCommand"); - HasOnBuyAttemptForward = haveBuyDetours && UTIL_CheckForPublic("CS_OnBuyAttempt"); - HasOnBuyForward = haveBuyDetours && UTIL_CheckForPublic("CS_OnBuy"); + if (!HasReGameDll) + { + haveBotHooks = UseBotArgs && BotArgs; + haveBuyHooks = BuyGunAmmoDetour && GiveNamedItemDetour && AddAccountDetour && CanPlayerBuyDetour && CanBuyThisDetour; + } - ToggleDetour_ClientCommands(HasInternalCommandForward || HasOnBuyAttemptForward || HasOnBuyForward); - ToggleDetour_BuyCommands(HasOnBuyForward); + HasInternalCommandForward = haveBotHooks && UTIL_CheckForPublic("CS_InternalCommand"); + HasOnBuyAttemptForward = haveBuyHooks && UTIL_CheckForPublic("CS_OnBuyAttempt"); + HasOnBuyForward = haveBuyHooks && UTIL_CheckForPublic("CS_OnBuy"); + + ToggleHook_ClientCommands(HasInternalCommandForward || HasOnBuyAttemptForward || HasOnBuyForward); + ToggleHook_BuyCommands(HasOnBuyForward); + ToggleHook_GiveDefaultItems(false); RETURN_META(MRES_IGNORED); } @@ -104,13 +143,15 @@ void OnServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax) void OnServerDeactivate() { - if (!ClientCommandDetour) + if (!HasReGameDll && !ClientCommandDetour) { RETURN_META(MRES_IGNORED); } - ToggleDetour_ClientCommands(false); - ToggleDetour_BuyCommands(false); + GameRulesRH = nullptr; + + ToggleHook_ClientCommands(false); + ToggleHook_BuyCommands(false); RETURN_META(MRES_IGNORED); } diff --git a/modules/cstrike/cstrike/CstrikeNatives.cpp b/modules/cstrike/cstrike/CstrikeNatives.cpp index 285cb053..004b0c5a 100644 --- a/modules/cstrike/cstrike/CstrikeNatives.cpp +++ b/modules/cstrike/cstrike/CstrikeNatives.cpp @@ -19,8 +19,10 @@ #include "CstrikeItemsInfos.h" #include #include +#include bool NoKnivesMode = false; +StringHashMap ModelsList; // native cs_set_user_money(index, money, flash = 1); static cell AMX_NATIVE_CALL cs_set_user_money(AMX *amx, cell *params) @@ -865,18 +867,17 @@ static cell AMX_NATIVE_CALL cs_set_user_model(AMX *amx, cell *params) char modelpath[260]; ke::SafeSprintf(modelpath, sizeof(modelpath), "models/player/%s/%s.mdl", newModel, newModel); - for (size_t i = 0; i < HL_MODEL_MAX; ++i) - { - if (Server->model_precache[i] && !strcmp(Server->model_precache[i], modelpath)) - { - if (pPlayer->v.modelindex != i) - { - SET_MODEL(pPlayer, STRING(ALLOC_STRING(modelpath))); - } + auto modelIndex = 0; - set_pdata(pPlayer, m_modelIndexPlayer, i); - return 1; + if (ModelsList.retrieve(modelpath, &modelIndex)) + { + if (pPlayer->v.modelindex != modelIndex) + { + SET_MODEL(pPlayer, STRING(ALLOC_STRING(modelpath))); } + + set_pdata(pPlayer, m_modelIndexPlayer, modelIndex); + return 1; } MF_Log("Model must be precached using cs_set_user_model with update_index parameter set"); @@ -1044,7 +1045,7 @@ static cell AMX_NATIVE_CALL cs_get_no_knives(AMX *amx, cell *params) // native cs_set_no_knives(noknives = 0); static cell AMX_NATIVE_CALL cs_set_no_knives(AMX *amx, cell *params) { - if (!GiveDefaultItemsDetour) + if (!HasReGameDll && !GiveDefaultItemsDetour) { MF_LogError(amx, AMX_ERR_NATIVE, "Native cs_set_no_knives() is disabled. Check your amxx logs."); return 0; @@ -1052,14 +1053,7 @@ static cell AMX_NATIVE_CALL cs_set_no_knives(AMX *amx, cell *params) NoKnivesMode = params[1] != 0; - if (NoKnivesMode) - { - GiveDefaultItemsDetour->EnableDetour(); - } - else - { - GiveDefaultItemsDetour->DisableDetour(); - } + ToggleHook_GiveDefaultItems(NoKnivesMode); return 1; } @@ -1698,7 +1692,7 @@ static cell AMX_NATIVE_CALL cs_find_ent_by_class(AMX* amx, cell* params) } int len; - void* pEntity = TypeConversion.id_to_cbase(params[1]); + auto pEntity = (CBaseEntity*)TypeConversion.id_to_cbase(params[1]); const char* value = MF_GetAmxString(amx, params[2], 0, &len); int index = TypeConversion.cbase_to_id(CS_UTIL_FindEntityByString(pEntity, "classname", value)); @@ -1724,7 +1718,7 @@ static cell AMX_NATIVE_CALL cs_find_ent_by_owner(AMX* amx, cell* params) CHECK_ENTITY_SIMPLE(owner); int length; - void* pEntity = TypeConversion.id_to_cbase(params[1]); + auto pEntity = (CBaseEntity*)TypeConversion.id_to_cbase(params[1]); const char* value = MF_GetAmxString(amx, params[2], 0, &length); edict_t *pOwner = TypeConversion.id_to_edict(owner); @@ -1763,14 +1757,14 @@ static cell AMX_NATIVE_CALL cs_set_ent_class(AMX* amx, cell* params) if (pev->classname) { - RemoveEntityHashValue(pev, STRING(pev->classname), HashType::Classname); + RemoveEntityHashValue(pev, STRING(pev->classname), CLASSNAME); } int length; auto new_classname = MF_GetAmxString(amx, params[2], 0, &length); pev->classname = ALLOC_STRING(new_classname); - AddEntityHashValue(pev, STRING(pev->classname), HashType::Classname); + AddEntityHashValue(pev, STRING(pev->classname), CLASSNAME); return 1; } @@ -1882,7 +1876,7 @@ static cell AMX_NATIVE_CALL cs_get_translated_item_alias(AMX* amx, cell* params) // native cs_get_weapon_info(weapon_id, CsWeaponInfo:type); static cell AMX_NATIVE_CALL cs_get_weapon_info(AMX* amx, cell* params) { - if (GetWeaponInfo <= 0) + if (!HasReGameDll && GetWeaponInfo <= 0) { MF_LogError(amx, AMX_ERR_NATIVE, "Native cs_get_weapon_info() is disabled. Check your amxx logs."); return 0; @@ -1891,9 +1885,9 @@ static cell AMX_NATIVE_CALL cs_get_weapon_info(AMX* amx, cell* params) int weapon_id = params[1]; int info_type = params[2]; - WeaponInfoStruct *info; + WeaponInfoStruct *info; - if (weapon_id <= CSW_NONE || weapon_id > CSW_LAST_WEAPON || !(info = GetWeaponInfo(weapon_id))) + if (weapon_id <= CSW_NONE || weapon_id > CSW_LAST_WEAPON || !(info = HasReGameDll ? ReGameApi->GetWeaponInfo(weapon_id) : GetWeaponInfo(weapon_id))) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id: %d", weapon_id); return 0; @@ -1925,6 +1919,7 @@ static cell AMX_NATIVE_CALL cs_get_weapon_info(AMX* amx, cell* params) { return info->ammoType; } + // TODO: Ammo name (custom) } MF_LogError(amx, AMX_ERR_NATIVE, "Invalid info type: %d", info_type); diff --git a/modules/cstrike/cstrike/CstrikePlayer.cpp b/modules/cstrike/cstrike/CstrikePlayer.cpp index 690d1a90..2cd0ba50 100644 --- a/modules/cstrike/cstrike/CstrikePlayer.cpp +++ b/modules/cstrike/cstrike/CstrikePlayer.cpp @@ -52,7 +52,7 @@ void StartFrame() { g_pFunctionTable->pfnStartFrame = nullptr; - for (int i = 1; i < gpGlobals->maxClients; ++i) + for (int i = 1; i <= gpGlobals->maxClients; ++i) { if (Players[i].HasModel()) { diff --git a/modules/cstrike/cstrike/CstrikePlayer.h b/modules/cstrike/cstrike/CstrikePlayer.h index c3bf2e60..b4ef198a 100644 --- a/modules/cstrike/cstrike/CstrikePlayer.h +++ b/modules/cstrike/cstrike/CstrikePlayer.h @@ -18,6 +18,7 @@ #include "CstrikeUtils.h" #include "CstrikeHacks.h" #include +#include extern ke::Vector ModelsUpdateQueue; @@ -119,6 +120,11 @@ class CPlayer g_pengfuncsTable->pfnSetClientKeyValue = SetClientKeyValue; } + if (HasReHlds) + { + return; + } + if (!ServerStatic) { MF_Log("Postponing of model update disabled, check your gamedata files"); diff --git a/modules/cstrike/cstrike/msvc12/cstrike.vcxproj b/modules/cstrike/cstrike/msvc12/cstrike.vcxproj index e15df551..a6cafce3 100644 --- a/modules/cstrike/cstrike/msvc12/cstrike.vcxproj +++ b/modules/cstrike/cstrike/msvc12/cstrike.vcxproj @@ -144,6 +144,8 @@ + + @@ -158,6 +160,14 @@ + + + + + + + + diff --git a/modules/cstrike/cstrike/msvc12/cstrike.vcxproj.filters b/modules/cstrike/cstrike/msvc12/cstrike.vcxproj.filters index 89db5505..784cc11c 100644 --- a/modules/cstrike/cstrike/msvc12/cstrike.vcxproj.filters +++ b/modules/cstrike/cstrike/msvc12/cstrike.vcxproj.filters @@ -27,6 +27,18 @@ {4f3c4a13-065a-49b1-83a1-f646a3ec3678} + + {7f37b35a-6ac7-4269-81a1-60dab5abbee4} + + + {bcfa2fd6-45a9-4671-a48e-f9ae4fdd3a9a} + + + {d192d10f-9ccb-4357-a360-875a563b016a} + + + {ba0b72ba-25d8-48c3-af84-c1d4d7436636} + @@ -62,6 +74,12 @@ Source Files + + ReSDK + + + ReSDK + @@ -100,6 +118,30 @@ Header Files + + ReSDK\common + + + ReSDK\cstrike + + + ReSDK\cstrike + + + ReSDK\cstrike + + + ReSDK\engine + + + ReSDK\engine + + + ReSDK + + + ReSDK + diff --git a/modules/fakemeta/AMBuilder b/modules/fakemeta/AMBuilder index 7b83a3f4..92dde599 100644 --- a/modules/fakemeta/AMBuilder +++ b/modules/fakemeta/AMBuilder @@ -10,6 +10,7 @@ binary.compiler.defines += [ binary.sources = [ '../../public/sdk/amxxmodule.cpp', '../../public/memtools/MemoryUtils.cpp', + '../../public/resdk/mod_regamedll_api.cpp', 'dllfunc.cpp', 'engfunc.cpp', 'fakemeta_amxx.cpp', diff --git a/modules/fakemeta/fakemeta_amxx.cpp b/modules/fakemeta/fakemeta_amxx.cpp index 2ff4d590..d27ed422 100644 --- a/modules/fakemeta/fakemeta_amxx.cpp +++ b/modules/fakemeta/fakemeta_amxx.cpp @@ -13,14 +13,24 @@ #include "fakemeta_amxx.h" #include "sh_stack.h" +#include IGameConfig *CommonConfig; IGameConfig *GamerulesConfig; IGameConfigManager *ConfigManager; +bool HasRegameDll; HLTypeConversion TypeConversion; + +void *GameRulesRH; void **GameRulesAddress; +CGameRules* InstallGameRules(IReGameHook_InstallGameRules *chain) +{ + GameRulesRH = chain->callNext(); + return static_cast(GameRulesRH); +} + void OnAmxxAttach() { initialze_offsets(); @@ -61,19 +71,26 @@ void OnAmxxAttach() return; } - void *address = nullptr; - - if (!CommonConfig->GetAddress("g_pGameRules", &address) || !address) + if ((HasRegameDll = RegamedllApi_Init())) { - MF_Log("get/set_gamerules_* natives have been disabled because g_pGameRules address could not be found. "); - return; + ReGameHookchains->InstallGameRules()->registerHook(InstallGameRules); } + else + { + void *address = nullptr; + + if (!CommonConfig->GetAddress("g_pGameRules", &address) || !address) + { + MF_Log("get/set_gamerules_* natives have been disabled because g_pGameRules address could not be found. "); + return; + } #if defined(KE_WINDOWS) - GameRulesAddress = *reinterpret_cast(address); + GameRulesAddress = *reinterpret_cast(address); #else - GameRulesAddress = reinterpret_cast(address); + GameRulesAddress = reinterpret_cast(address); #endif + } } void OnPluginsLoaded() @@ -135,6 +152,11 @@ void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) void FMH_ServerDeactivate_Post() { + if (HasRegameDll) + { + GameRulesRH = nullptr; + } + // Reset all call lists here. // NULL all function tables RESETE(PrecacheModel); diff --git a/modules/fakemeta/fakemeta_amxx.h b/modules/fakemeta/fakemeta_amxx.h index fad11f14..9b7b084b 100644 --- a/modules/fakemeta/fakemeta_amxx.h +++ b/modules/fakemeta/fakemeta_amxx.h @@ -79,7 +79,9 @@ extern IGameConfig *CommonConfig; extern IGameConfig *GamerulesConfig; extern IGameConfigManager *ConfigManager; +extern bool HasRegameDll; extern HLTypeConversion TypeConversion; +extern void *GameRulesRH; extern void **GameRulesAddress; #endif //_FAKEMETA_INCLUDE_H diff --git a/modules/fakemeta/msvc12/fakemeta.vcxproj b/modules/fakemeta/msvc12/fakemeta.vcxproj index 68d2e4a6..8b1a6fed 100644 --- a/modules/fakemeta/msvc12/fakemeta.vcxproj +++ b/modules/fakemeta/msvc12/fakemeta.vcxproj @@ -55,7 +55,7 @@ Disabled ..\;..\..\..\public;..\..\..\public\sdk;..\..\..\public\amtl;..\..\third_party;..\..\third_party\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;FAKEMETA_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FAKEMETA_EXPORTS;HAVE_STDINT_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebug @@ -78,7 +78,7 @@ ..\;..\..\..\public;..\..\..\public\sdk;..\..\..\public\amtl;..\..\third_party;..\..\third_party\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;FAKEMETA_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FAKEMETA_EXPORTS;HAVE_STDINT_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) MultiThreaded false @@ -97,6 +97,7 @@ + @@ -114,6 +115,12 @@ + + + + + + diff --git a/modules/fakemeta/msvc12/fakemeta.vcxproj.filters b/modules/fakemeta/msvc12/fakemeta.vcxproj.filters index 67380042..4c16bd55 100644 --- a/modules/fakemeta/msvc12/fakemeta.vcxproj.filters +++ b/modules/fakemeta/msvc12/fakemeta.vcxproj.filters @@ -36,6 +36,15 @@ {e1b28b22-6fde-4e1f-a982-f37dec584571} + + {395f243b-8294-49ad-a959-d3d9ca6b79db} + + + {87a7e30d-f917-4853-b5b9-56782049cee6} + + + {0d1c5025-071d-43aa-b19a-2eee0d34a906} + @@ -80,6 +89,9 @@ Source Files + + ReSDK + @@ -124,6 +136,24 @@ Header Files + + ReSDK\common + + + ReSDK\cstrike + + + ReSDK\cstrike + + + ReSDK\cstrike + + + ReSDK + + + ReSDK + diff --git a/modules/fakemeta/pdata_gamerules.cpp b/modules/fakemeta/pdata_gamerules.cpp index fb854a2f..2f829252 100644 --- a/modules/fakemeta/pdata_gamerules.cpp +++ b/modules/fakemeta/pdata_gamerules.cpp @@ -25,7 +25,7 @@ static cell AMX_NATIVE_CALL get_gamerules_int(AMX *amx, cell *params) int element = params[3]; CHECK_DATA(data, element, BaseFieldType::Integer); - return PvData::GetInt(*GameRulesAddress, data, element); + return PvData::GetInt(HasRegameDll ? GameRulesRH : *GameRulesAddress, data, element); } // native set_gamerules_int(const class[], const member[], any:value, element = 0); @@ -45,7 +45,7 @@ static cell AMX_NATIVE_CALL set_gamerules_int(AMX *amx, cell *params) return 0; } - PvData::SetInt(*GameRulesAddress, data, params[3], element); + PvData::SetInt(HasRegameDll ? GameRulesRH : *GameRulesAddress, data, params[3], element); return 0; } @@ -62,7 +62,7 @@ static cell AMX_NATIVE_CALL get_gamerules_float(AMX *amx, cell *params) int element = params[3]; CHECK_DATA(data, element, BaseFieldType::Float); - return PvData::GetFloat(*GameRulesAddress, data, element); + return PvData::GetFloat(HasRegameDll ? GameRulesRH : *GameRulesAddress, data, element); } // native set_gamerules_float(const class[], const member[], Float:value, element = 0); @@ -76,7 +76,7 @@ static cell AMX_NATIVE_CALL set_gamerules_float(AMX *amx, cell *params) int element = params[4]; CHECK_DATA(data, element, BaseFieldType::Float); - PvData::SetFloat(*GameRulesAddress, data, amx_ctof(params[3]), element); + PvData::SetFloat(HasRegameDll ? GameRulesRH : *GameRulesAddress, data, amx_ctof(params[3]), element); return 1; } @@ -93,7 +93,7 @@ static cell AMX_NATIVE_CALL get_gamerules_vector(AMX *amx, cell *params) int element = params[4]; CHECK_DATA(data, element, BaseFieldType::Vector); - PvData::GetVector(*GameRulesAddress, data, MF_GetAmxAddr(amx, params[3]), element); + PvData::GetVector(HasRegameDll ? GameRulesRH : *GameRulesAddress, data, MF_GetAmxAddr(amx, params[3]), element); return 1; } @@ -109,7 +109,7 @@ static cell AMX_NATIVE_CALL set_gamerules_vector(AMX *amx, cell *params) int element = params[4]; CHECK_DATA(data, element, BaseFieldType::Vector); - PvData::GetVector(*GameRulesAddress, data, MF_GetAmxAddr(amx, params[3]), element); + PvData::GetVector(HasRegameDll ? GameRulesRH : *GameRulesAddress, data, MF_GetAmxAddr(amx, params[3]), element); return 1; } @@ -126,7 +126,7 @@ static cell AMX_NATIVE_CALL get_gamerules_entity(AMX *amx, cell *params) int element = params[3]; CHECK_DATA(data, element, BaseFieldType::Entity); - return PvData::GetEntity(*GameRulesAddress, data, element); + return PvData::GetEntity(HasRegameDll ? GameRulesRH : *GameRulesAddress, data, element); } // native set_gamerules_entity(const class[], const member[], value, element = 0); @@ -147,7 +147,7 @@ static cell AMX_NATIVE_CALL set_gamerules_entity(AMX *amx, cell *params) int element = params[4]; CHECK_DATA(data, element, BaseFieldType::Entity); - PvData::SetEntity(*GameRulesAddress, data, params[3], element); + PvData::SetEntity(HasRegameDll ? GameRulesRH : *GameRulesAddress, data, params[3], element); return 0; } @@ -167,7 +167,7 @@ static cell AMX_NATIVE_CALL get_gamerules_string(AMX *amx, cell *params) auto buffer = params[3]; auto maxlen = params[4]; - auto string = PvData::GetString(*GameRulesAddress, data, element); + auto string = PvData::GetString(HasRegameDll ? GameRulesRH : *GameRulesAddress, data, element); if (data.fieldSize) { @@ -191,7 +191,7 @@ static cell AMX_NATIVE_CALL set_gamerules_string(AMX *amx, cell *params) int length; const char *value = MF_GetAmxString(amx, params[3], 0, &length); - return PvData::SetString(*GameRulesAddress, data, value, length, element); + return PvData::SetString(HasRegameDll ? GameRulesRH : *GameRulesAddress, data, value, length, element); } diff --git a/modules/fakemeta/pdata_shared.h b/modules/fakemeta/pdata_shared.h index 8384fa73..b1b7d688 100644 --- a/modules/fakemeta/pdata_shared.h +++ b/modules/fakemeta/pdata_shared.h @@ -63,11 +63,11 @@ enum class BaseFieldType return 0; \ } -#define CHECK_GAMERULES() \ - if (!GameRulesAddress) \ - { \ - MF_LogError(amx, AMX_ERR_NATIVE, "%s is disabled. Check your AMXX log.", __FUNCTION__); \ - return 0; \ +#define CHECK_GAMERULES() \ + if ((HasRegameDll && !GameRulesRH) || (!HasRegameDll && (!GameRulesAddress || !*GameRulesAddress))) \ + { \ + MF_LogError(amx, AMX_ERR_NATIVE, "%s is disabled. Check your AMXX log.", __FUNCTION__); \ + return 0; \ } class PvData diff --git a/modules/hamsandwich/config_parser.cpp b/modules/hamsandwich/config_parser.cpp index 42ef7e1a..a2b54b94 100644 --- a/modules/hamsandwich/config_parser.cpp +++ b/modules/hamsandwich/config_parser.cpp @@ -242,7 +242,7 @@ int read_number(char *input) char *end; /* Temporary pointer, needed for strtoul(). */ // if begins with 0x or 0X it's to be interpretted as hex - if (*input=='0' && + if (*input=='0' && (*(input+1)=='x' || *(input+1)=='X')) { return strtoul(input,&end,16); @@ -307,7 +307,7 @@ int ReadConfig(void) { char FileName[512]; - MF_BuildPathnameR(FileName,sizeof(FileName)-1,"%s",get_localinfo("amxx_configsdir","addons/amxmodx/configs")); + MF_BuildPathnameR(FileName,sizeof(FileName),"%s",get_localinfo("amxx_configsdir","addons/amxmodx/configs")); strncat(FileName,"/hamdata.ini",sizeof(FileName)-1); diff --git a/modules/nvault/amxxapi.cpp b/modules/nvault/amxxapi.cpp index f5f76ef6..959b8271 100644 --- a/modules/nvault/amxxapi.cpp +++ b/modules/nvault/amxxapi.cpp @@ -14,7 +14,6 @@ #include #include "amxxapi.h" #include "NVault.h" -#include #ifdef WIN32 #define MKDIR(p) mkdir(p) @@ -31,7 +30,7 @@ #endif ke::Vector g_Vaults; -Queue g_OldVaults; +ke::Deque g_OldVaults; VaultMngr g_VaultMngr; @@ -46,13 +45,13 @@ static cell nvault_open(AMX *amx, cell *params) int len, id=-1; char *name = MF_GetAmxString(amx, params[1], 0, &len); char path[255], file[255]; - MF_BuildPathnameR(path, sizeof(path)-1, "%s/vault", MF_GetLocalInfo("amxx_datadir", "addons/amxmodx/data")); + MF_BuildPathnameR(path, sizeof(path), "%s/vault", MF_GetLocalInfo("amxx_datadir", "addons/amxmodx/data")); sprintf(file, "%s/%s.vault", path, name); for (size_t i=0; iGetFilename(), file) == 0) + if (strcmp(g_Vaults.at(i)->GetFilename(), file) == 0) return i; } NVault *v = (NVault *)g_VaultMngr.OpenVault(file); @@ -63,8 +62,7 @@ static cell nvault_open(AMX *amx, cell *params) } if (!g_OldVaults.empty()) { - id = g_OldVaults.first(); - g_OldVaults.pop(); + id = g_OldVaults.popFrontCopy(); } if (id != -1) { @@ -210,7 +208,7 @@ static cell nvault_close(AMX *amx, cell *params) pVault->Close(); delete pVault; g_Vaults[id] = NULL; - g_OldVaults.push(id); + g_OldVaults.append(id); return 1; } @@ -268,7 +266,7 @@ void OnPluginsUnloaded() } g_Vaults.clear(); while (!g_OldVaults.empty()) - g_OldVaults.pop(); + g_OldVaults.popFront(); } AMX_NATIVE_INFO nVault_natives[] = { diff --git a/modules/nvault/amxxapi.h b/modules/nvault/amxxapi.h index 3039350d..027eb1f4 100644 --- a/modules/nvault/amxxapi.h +++ b/modules/nvault/amxxapi.h @@ -17,9 +17,8 @@ #include "amxxmodule.h" #include #include -#include +#include extern AMX_NATIVE_INFO nVault_natives[]; #endif //_INCLUDE_AMXXAPI_H - diff --git a/modules/sockets/AMBuilder b/modules/sockets/AMBuilder index f14c8512..1057c769 100644 --- a/modules/sockets/AMBuilder +++ b/modules/sockets/AMBuilder @@ -8,9 +8,13 @@ binary.sources = [ 'sockets.cpp', ] +binary.compiler.defines += [ + 'HAVE_STDINT_H', +] + if builder.target_platform == 'windows': binary.sources += ['version.rc'] - + if builder.target_platform == 'windows': binary.compiler.postlink += ['wsock32.lib', 'ws2_32.lib'] diff --git a/modules/sockets/moduleconfig.h b/modules/sockets/moduleconfig.h index 103be9ee..0c8e3850 100644 --- a/modules/sockets/moduleconfig.h +++ b/modules/sockets/moduleconfig.h @@ -19,9 +19,9 @@ // Module info #define MODULE_NAME "Sockets" #define MODULE_VERSION AMXX_VERSION -#define MODULE_AUTHOR "HLSW Dev Team" -#define MODULE_URL "http://www.hlsw.net/" -#define MODULE_LOGTAG "SOCKET" +#define MODULE_AUTHOR "AMX Mod X Dev Team" +#define MODULE_URL "http://www.amxmodx.org" +#define MODULE_LOGTAG "SOCKETS" #define MODULE_LIBRARY "sockets" #define MODULE_LIBCLASS "" // If you want the module not to be reloaded on mapchange, remove / comment out the next line diff --git a/modules/sockets/msvc12/sockets.vcxproj b/modules/sockets/msvc12/sockets.vcxproj index 0524e6d4..8920980e 100644 --- a/modules/sockets/msvc12/sockets.vcxproj +++ b/modules/sockets/msvc12/sockets.vcxproj @@ -55,7 +55,7 @@ Disabled ..\;..\..\..\public;..\..\..\public\sdk;..\..\..\public\amtl;..\..\third_party;..\..\third_party\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;SOCKETS_EXPORTS;%(PreprocessorDefinitions) + WIN32;HAVE_STDINT_H;_DEBUG;_WINDOWS;_USRDLL;SOCKETS_EXPORTS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebug @@ -66,7 +66,7 @@ EditAndContinue - wsock32.lib;%(AdditionalDependencies) + ws2_32.lib;%(AdditionalDependencies) true $(OutDir)sockets.pdb Windows @@ -79,7 +79,7 @@ ..\;..\..\..\public;..\..\..\public\sdk;..\..\..\public\amtl;..\..\third_party;..\..\third_party\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;SOCKETS_EXPORTS;%(PreprocessorDefinitions) + WIN32;HAVE_STDINT_H;NDEBUG;_WINDOWS;_USRDLL;SOCKETS_EXPORTS;%(PreprocessorDefinitions) MultiThreaded false @@ -88,7 +88,7 @@ ProgramDatabase - wsock32.lib;%(AdditionalDependencies) + ws2_32.lib;%(AdditionalDependencies) true Windows true diff --git a/modules/sockets/sockets.cpp b/modules/sockets/sockets.cpp index 2ff14e4c..7b3ed877 100644 --- a/modules/sockets/sockets.cpp +++ b/modules/sockets/sockets.cpp @@ -3,10 +3,6 @@ // AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). // Copyright (C) The AMX Mod X Development Team. // -// Codebase from Ivan, -g-s-ivan@web.de (AMX 0.9.3) -// Modification by Olaf Reusch, kenterfie@hlsw.de (AMXX 0.16, AMX 0.96) -// Modification by David Anderson, dvander@tcwonline.org (AMXx 0.20) -// // This software is licensed under the GNU General Public License, version 3 or higher. // Additional exceptions apply. For full license details, see LICENSE.txt or visit: // https://alliedmods.net/amxmodx-license @@ -15,233 +11,335 @@ // Sockets Module // -#include -#include -#include -#include +#include "amxxmodule.h" +#include #ifdef _WIN32 -/* Windows */ -#include -#include -#define socklen_t int + #include + #include + + #undef errno + #undef close + + #define errno WSAGetLastError() + #define close(sockfd) closesocket(sockfd) + + #define EINPROGRESS WSAEINPROGRESS + #define EWOULDBLOCK WSAEWOULDBLOCK #else -/* Unix/Linux */ -#include -#include -#include -#include -#include -#include -#define closesocket(s) close(s) + #include + #include + #include + #include + #include + #include + #include + #include #endif -// AMX Headers -#include "amxxmodule.h" +#ifdef _WIN32 + bool g_winsock_initialized = false; +#endif -#define SOCKET_TCP 1 -#define SOCKET_UDP 2 +static char *g_send2_buffer = nullptr; +static int g_send2_buffer_length = 0; -// And global Variables: -// native socket_open(_hostname[], _port, _protocol = SOCKET_TCP, &_error); -static cell AMX_NATIVE_CALL socket_open(AMX *amx, cell *params) /* 2 param */ -{ - unsigned int port = params[2]; - int len; - char* hostname = MF_GetAmxString(amx,params[1],0,&len); // Get the hostname from AMX - cell *err = MF_GetAmxAddr(amx, params[4]); - if(len == 0) { // just to prevent to work with a nonset hostname - *err = 2; // server unknown - return -1; - } - *err = 0; // params[4] is error backchannel - struct sockaddr_in server; - struct hostent *host_info; - unsigned long addr; - int sock=-1; - int contr; - // Create a Socket - sock = socket(AF_INET, params[3]==SOCKET_TCP?SOCK_STREAM:SOCK_DGRAM, 0); - if (sock < 0) { - // Error, couldn't create a socket, so set an error and return. - *err = 1; - return -1; - } - - // Clear the server structure (set everything to 0) - memset( &server, 0, sizeof (server)); - // Test the hostname, and resolve if needed - if ((addr = inet_addr(hostname)) != INADDR_NONE) { - // seems like hostname is a numeric ip, so put it into the structure - memcpy( (char *)&server.sin_addr, &addr, sizeof(addr)); - } - else { - // hostname is a domain, so resolve it to an ip - host_info = gethostbyname(hostname); - if (host_info == NULL) { - // an error occured, the hostname is unknown - *err = 2; // server unknown - return -1; - } - // If not, put it in the Server structure - memcpy( (char *)&server.sin_addr, host_info->h_addr, host_info->h_length); - } - // Set the type of the Socket - server.sin_family = AF_INET; - // Change the port to network byte order, and put it into the structure - server.sin_port = htons(port); - - // Not, let's try to open a connection to the server - contr = connect(sock, (struct sockaddr*)&server, sizeof( server)); - if (contr < 0) { - // If an error occured cancel - *err = 3; //error while connecting - return -1; - } - // Everything went well, so return the socket - return sock; +bool setnonblocking(int sockfd) +{ +#ifdef _WIN32 + unsigned long flags = 1; + + return (ioctlsocket(sockfd, FIONBIO, &flags) == 0); +#else + + int flags = -1; + + if((flags = fcntl(sockfd, F_GETFL, 0)) == -1) + return false; + + if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) + return false; + + return true; +#endif +} + +// native socket_open(_hostname[], _port, _protocol = SOCKET_TCP, &_error, _flags = 0); +static cell AMX_NATIVE_CALL socket_open(AMX *amx, cell *params) +{ + // Socket flags and backwards compatibility + enum + { + SOCK_NON_BLOCKING = (1 << 0), + SOCK_LIBC_ERRORS = (1 << 1) + }; + + #define SOCK_ERROR_OK 0 // No error + #define SOCK_ERROR_CREATE_SOCKET 1 // Couldn't create a socket + #define SOCK_ERROR_SERVER_UNKNOWN 2 // Server unknown + #define SOCK_ERROR_WHILE_CONNECTING 3 // Error while connecting + #define ERROR_EHOSTUNREACH 113 // libc error code: No route to host + + int hostname_length = 0; + char *hostname = MF_GetAmxString(amx, params[1], 0, &hostname_length); + + cell *error = MF_GetAmxAddr(amx, params[4]); + *error = 0; + + unsigned int flags = 0; + bool libc_errors = false, nonblocking_socket = false; + + if((*params / sizeof(cell)) == 5) + { + flags = params[5]; + + nonblocking_socket = (flags & SOCK_NON_BLOCKING) != 0; + libc_errors = (flags & SOCK_LIBC_ERRORS) != 0; + } + + if(hostname_length == 0) + { + *error = libc_errors ? ERROR_EHOSTUNREACH : SOCK_ERROR_SERVER_UNKNOWN; + return -1; + } + + char port_number[6]; + ke::SafeSprintf(port_number, sizeof(port_number), "%d", params[2]); + + int sockfd = -1, getaddrinfo_status = -1, connect_status = -1; + bool setnonblocking_status = false, connect_inprogress = false; + struct addrinfo hints, *server_info, *server; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = params[3]; + + if((getaddrinfo_status = getaddrinfo(hostname, port_number, &hints, &server_info)) != 0) + { + *error = libc_errors ? getaddrinfo_status : SOCK_ERROR_SERVER_UNKNOWN; + return -1; + } + + server = server_info; + + do + { + if((sockfd = socket(server->ai_family, server->ai_socktype, server->ai_protocol)) != -1) + { + if(nonblocking_socket) + setnonblocking_status = setnonblocking(sockfd); + + if(nonblocking_socket == false || (nonblocking_socket && setnonblocking_status == true)) + { + if((connect_status = connect(sockfd, server->ai_addr, server->ai_addrlen)) == -1) + { + *error = libc_errors ? errno : SOCK_ERROR_WHILE_CONNECTING; + + if(nonblocking_socket && (errno == EINPROGRESS || errno == EWOULDBLOCK)) + connect_inprogress = true; + else + close(sockfd); + } + else + { + *error = 0; + } + } + else + { + if(*error == 0) + *error = libc_errors ? errno : SOCK_ERROR_CREATE_SOCKET; + } + } + else + { + if(*error == 0) + *error = errno; + } + + } while((nonblocking_socket && connect_inprogress == false) && connect_status != 0 && (server = server->ai_next) != nullptr); + + freeaddrinfo(server_info); + + if(sockfd == -1 || server == nullptr) + return -1; + + return sockfd; } // native socket_close(_socket); -static cell AMX_NATIVE_CALL socket_close(AMX *amx, cell *params) /* 2 param */ +static cell AMX_NATIVE_CALL socket_close(AMX *amx, cell *params) { - int socket = params[1]; - //PRINT_CONSOLE("Function: Close | Socket: %i\n", socket); - #ifdef _WIN32 // On windows, check whether the sockets are initialized correctly - closesocket(socket); - #else - // Close the socket (linux/unix styled systems) - close(socket); - #endif - return 0; -} - -// native socket_change(_socket, _timeout=100000); -// 1 sec =1000000 usec -static cell AMX_NATIVE_CALL socket_change(AMX *amx, cell *params) /* 2 param */ -{ - int socket = params[1]; - unsigned int timeout = params[2]; - //PRINT_CONSOLE("Function: Change | Socket: %i | Timeout: %i\n", socket, timeout); - // We need both a timeout structure and a fdset for our filedescriptor - fd_set rfds; - struct timeval tv; - // Fill in ... - FD_ZERO(&rfds); - FD_SET(socket, &rfds); - tv.tv_sec = 0; - tv.tv_usec = timeout; - // Now we "select", which will show us if new data is waiting in the socket's buffer - if (select(socket+1, &rfds, NULL, NULL, &tv) > 0) - return 1; // Ok, new data, return it - else - return 0; // No new data, return it + return (close(params[1]) == -1) ? 0 : 1; } // native socket_recv(_socket, _data[], _length); -static cell AMX_NATIVE_CALL socket_recv(AMX *amx, cell *params) /* 2 param */ +static cell AMX_NATIVE_CALL socket_recv(AMX *amx, cell *params) { - int socket = params[1]; - int length = params[3]; - int tmp = -1; - // First we dynamicly allocate a block of heap memory for recieving our data - char *tmpchar = new char[length]; - if(tmpchar == NULL) return -1; // If we didn't got a block, we have to quit here to avoid sigsegv - // And set it all to 0, because the memory could contain old trash - memset(tmpchar, 0, length); - // Now we recieve - tmp = recv(socket, tmpchar, length-1, 0); - if (tmp == -1) + int sockfd = params[1]; + int length = params[3]; + + char *recv_buffer = new char[length]; + + if(recv_buffer == nullptr) + return -1; + + memset(recv_buffer, 0, length); + + int bytes_received = -1; + bytes_received = recv(sockfd, recv_buffer, length - 1, 0); + + if(bytes_received == -1) { - delete [] tmpchar; + delete[] recv_buffer; return -1; } - // And put a copy of our recieved data into amx's string - tmpchar[tmp]='\0'; - int nlen = 0; - //int max = params[3]; - int max = length-1; - const char* src = tmpchar; - cell* dest = MF_GetAmxAddr(amx,params[2]); - while(max--&&nlen g_buflen) + int sockfd = params[1]; + int length = params[3]; + + if(length > g_send2_buffer_length) { - delete [] g_buffer; - g_buffer = new char[len+1]; - g_buflen = len; + delete[] g_send2_buffer; + + g_send2_buffer = new char[length + 1]; + + if(g_send2_buffer == nullptr) + { + g_send2_buffer_length = 0; + return -1; + } + + g_send2_buffer_length = length; } - cell *pData = MF_GetAmxAddr(amx, params[2]); - char *pBuffer = g_buffer; + cell *data = MF_GetAmxAddr(amx, params[2]); + char *buffer = g_send2_buffer; - while (len--) - *pBuffer++ = (char)*pData++; + while(length--) + *buffer++ = (char)*data++; - // And send it to the socket - return send(socket, g_buffer, params[3], 0); + return send(sockfd, g_send2_buffer, params[3], 0); } -AMX_NATIVE_INFO sockets_natives[] = { +// native socket_change(_socket, _timeout = 100000); +static cell AMX_NATIVE_CALL socket_change(AMX *amx, cell *params) +{ + int sockfd = params[1]; + unsigned int timeout = params[2]; + + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = timeout; + + fd_set readfds; + FD_ZERO(&readfds); + FD_SET(sockfd, &readfds); + + return (select(sockfd + 1, &readfds, nullptr, nullptr, &tv) > 0) ? 1 : 0; +} + +// native socket_is_readable(_socket, _timeout = 100000); +static cell AMX_NATIVE_CALL socket_is_readable(AMX *amx, cell *params) +{ + return socket_change(amx, params); +} + +// native socket_is_writable(_socket, _timeout = 100000); +static cell AMX_NATIVE_CALL socket_is_writable(AMX *amx, cell *params) +{ + int sockfd = params[1]; + unsigned int timeout = params[2]; + + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = timeout; + + fd_set writefds; + FD_ZERO(&writefds); + FD_SET(sockfd, &writefds); + + return (select(sockfd + 1, nullptr, &writefds, nullptr, &tv) > 0) ? 1 : 0; +} + +AMX_NATIVE_INFO sockets_natives[] = +{ {"socket_open", socket_open}, + {"socket_close", socket_close}, - {"socket_change", socket_change}, + {"socket_recv", socket_recv}, + {"socket_send", socket_send}, {"socket_send2", socket_send2}, + + {"socket_change", socket_change}, + {"socket_is_readable", socket_is_readable}, + {"socket_is_writable", socket_is_writable}, + {NULL, NULL} }; void OnAmxxAttach() { +#ifdef _WIN32 + WSADATA WSAData; + int errorcode = WSAStartup(MAKEWORD(2, 2), &WSAData); + + if(errorcode != 0) + { + MF_Log("[%s]: WSAStartup failed with error code %d. Natives will not be available.", MODULE_LOGTAG, errorcode); + return; + } + + g_winsock_initialized = true; +#endif + MF_AddNatives(sockets_natives); - // And, if win32, we have to specially start up the winsock environment - #ifdef _WIN32 - short wVersionRequested; - WSADATA wsaData; - wVersionRequested = MAKEWORD (1, 1); - if (WSAStartup (wVersionRequested, &wsaData) != 0) { - MF_Log("Sockets Module: Error while starting up winsock environment.!"); - } - #endif - return; } void OnAmxxDetach() { - #ifdef _WIN32 - WSACleanup(); - #endif - delete [] g_buffer; - return; +#ifdef _WIN32 + if(g_winsock_initialized) + WSACleanup(); +#endif + + delete[] g_send2_buffer; } diff --git a/modules/sqlite/basic_sql.cpp b/modules/sqlite/basic_sql.cpp index a4ae8a20..acbe7491 100644 --- a/modules/sqlite/basic_sql.cpp +++ b/modules/sqlite/basic_sql.cpp @@ -59,13 +59,13 @@ static cell AMX_NATIVE_CALL SQL_MakeDbTuple(AMX *amx, cell *params) char path[255]; FILE *fp; - MF_BuildPathnameR(path, sizeof(path)-1, "%s", db); + MF_BuildPathnameR(path, sizeof(path), "%s", db); if ((fp=fopen(path, "rb"))) { fclose(fp); sql->db = strdup(path); } else { - MF_BuildPathnameR(path, sizeof(path)-1, "%s/sqlite3/%s.sq3", + MF_BuildPathnameR(path, sizeof(path), "%s/sqlite3/%s.sq3", MF_GetLocalInfo("amxx_datadir", "addons/amxmodx/data"), db); sql->db = strdup(path); @@ -601,7 +601,7 @@ static cell AMX_NATIVE_CALL SQL_SetCharset(AMX *amx, cell *params) return 0; } -AMX_NATIVE_INFO g_BaseSqlNatives[] = +AMX_NATIVE_INFO g_BaseSqlNatives[] = { {"SQL_MakeDbTuple", SQL_MakeDbTuple}, {"SQL_FreeHandle", SQL_FreeHandle}, @@ -630,4 +630,3 @@ AMX_NATIVE_INFO g_BaseSqlNatives[] = {NULL, NULL}, }; - diff --git a/modules/sqlite/module.cpp b/modules/sqlite/module.cpp index 7fb83cd8..7ae9d81a 100644 --- a/modules/sqlite/module.cpp +++ b/modules/sqlite/module.cpp @@ -17,7 +17,7 @@ static int g_ident = 0; -SqlFunctions g_SqliteFuncs = +SqlFunctions g_SqliteFuncs = { &g_Sqlite, SetMysqlAffinity, @@ -69,7 +69,7 @@ void OnAmxxAttach() MF_OverrideNatives(g_OldCompatNatives, MODULE_NAME); char path[255]; - MF_BuildPathnameR(path, sizeof(path)-1, "%s/sqlite3", MF_GetLocalInfo("amxx_datadir", "addons/amxmodx/data")); + MF_BuildPathnameR(path, sizeof(path), "%s/sqlite3", MF_GetLocalInfo("amxx_datadir", "addons/amxmodx/data")); if (!DirExists(path)) { mkdir(path @@ -96,4 +96,3 @@ void OnPluginsUnloaded() extern "C" void __cxa_pure_virtual(void) { } - diff --git a/modules/sqlite/oldcompat_sql.cpp b/modules/sqlite/oldcompat_sql.cpp index 0c2c6b6f..1b019ea5 100644 --- a/modules/sqlite/oldcompat_sql.cpp +++ b/modules/sqlite/oldcompat_sql.cpp @@ -73,14 +73,14 @@ static cell AMX_NATIVE_CALL dbi_connect(AMX *amx, cell *params) int err; char error[512]; /** if there is an older database, read there instead of the new path */ - MF_BuildPathnameR(path, sizeof(path)-1, "%s", info.database); + MF_BuildPathnameR(path, sizeof(path), "%s", info.database); FILE *fp = fopen(path, "rb"); if (fp) { fclose(fp); info.database = path; } else { - MF_BuildPathnameR(path, sizeof(path)-1, "%s/sqlite3/%s.sq3", + MF_BuildPathnameR(path, sizeof(path), "%s/sqlite3/%s.sq3", MF_GetLocalInfo("amxx_datadir", "addons/amxmodx/data"), info.database); info.database = path; @@ -439,14 +439,14 @@ static cell AMX_NATIVE_CALL dbi_field_name(AMX *amx, cell *params) return 1; } -AMX_NATIVE_INFO g_OldCompatNatives[] = +AMX_NATIVE_INFO g_OldCompatNatives[] = { { "dbi_connect", dbi_connect }, { "dbi_query", dbi_query }, { "dbi_query2", dbi_query2 }, - { "dbi_field", dbi_field }, - { "dbi_nextrow", dbi_nextrow }, - { "dbi_close", dbi_close }, + { "dbi_field", dbi_field }, + { "dbi_nextrow", dbi_nextrow }, + { "dbi_close", dbi_close }, { "dbi_error", dbi_error }, { "dbi_type", dbi_type }, { "dbi_free_result", dbi_free_result }, diff --git a/plugins/include/datapack.inc b/plugins/include/datapack.inc index 91164ef8..8c9f86f4 100644 --- a/plugins/include/datapack.inc +++ b/plugins/include/datapack.inc @@ -120,10 +120,10 @@ native ResetPack(DataPack:pack, bool:clear = false); * * @param pack Datapack handle * - * @return Position in the datapack + * @return Position in the datapack, only usable with calls to SetPackPosition * @error If an invalid handle is provided, an error will be thrown. */ -native GetPackPosition(DataPack:pack); +native DataPackPos:GetPackPosition(DataPack:pack); /** * Sets the datapack read/write position. @@ -139,7 +139,7 @@ native GetPackPosition(DataPack:pack); * @error If an invalid handle is provided, or the new position is * out of datapack bounds, an error will be thrown. */ -native SetPackPosition(DataPack:pack, position); +native SetPackPosition(DataPack:pack, DataPackPos:position); /** * Returns if the datapack has reached its end and no more data can be read. diff --git a/plugins/include/newmenus.inc b/plugins/include/newmenus.inc index dc2259b9..2079d5ba 100644 --- a/plugins/include/newmenus.inc +++ b/plugins/include/newmenus.inc @@ -27,6 +27,9 @@ #define MPROP_EXIT 6 /* Exit functionality (param1 = number, see MEXIT constants) */ #define MPROP_NOCOLORS 8 /* Sets whether colors are not auto (param1 = number, 0=default) */ #define MPROP_NUMBER_COLOR 10 /* Color indicator to use for numbers (param1 = string, "\r"=default) */ +#define MPROP_PAGE_CALLBACK 11 /* Function to be called on Back and Next (param1 = string) */ + /* public function(id, status); where status is either MENU_BACK or MENU_MORE */ + /* Pass NULL_STRING to disable the callback */ #define MEXIT_NORMAL 0 /* DEPRECATED, do not use (has no effect) */ #define MENUPAD_NONE 0 /* DEPRECATED, do not use (has no effect) */ diff --git a/plugins/include/sockets.inc b/plugins/include/sockets.inc index 42bd4d9c..25718cf8 100755 --- a/plugins/include/sockets.inc +++ b/plugins/include/sockets.inc @@ -3,9 +3,6 @@ // AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). // Copyright (C) The AMX Mod X Development Team. // -// Codebase from Ivan, -g-s-ivan@web.de (AMX 0.9.3) -// Modification by Olaf Reusch, kenterfie@hlsw.de (AMXX 0.16, AMX 0.96) -// // This software is licensed under the GNU General Public License, version 3 or higher. // Additional exceptions apply. For full license details, see LICENSE.txt or visit: // https://alliedmods.net/amxmodx-license @@ -24,43 +21,159 @@ #pragma loadlib sockets #endif -// Use SOCKET_TCP for TCP Socket connections - +/** + * Socket connection type (TCP/UDP) + */ #define SOCKET_TCP 1 - -// Use SOCKET_UDP for UDP Socket connections - #define SOCKET_UDP 2 -/* Opens a new connection to hostname:port via protocol (either SOCKET_TCP or SOCKET_UDP), - * returns a socket (positive) or negative or zero on error. - * States of error: - * 0 - no error - * 1 - error while creating socket - * 2 - couldn't resolve hostname - * 3 - couldn't connect to given hostname:port +/** + * Socket flags + */ +#define SOCK_NON_BLOCKING (1 << 0) /* Set the socket a nonblocking */ +#define SOCK_LIBC_ERRORS (1 << 1) /* Enable libc error reporting */ + +/** + * Error reporting + */ +#define SOCK_ERROR_OK 0 /* No error */ +#define SOCK_ERROR_CREATE_SOCKET 1 /* Couldn't create a socket */ +#define SOCK_ERROR_SERVER_UNKNOWN 2 /* Server unknown */ +#define SOCK_ERROR_WHILE_CONNECTING 3 /* Error while connecting */ + +/** + * Connects to the given node and service via TCP/UDP. + * + * @note There's 2 types of error reporting on this function that you can use. + * @note Default error codes: + * 0 - No error + * 1 - Error while creating socket + * 2 - Couldn't resolve hostname + * 3 - Couldn't connect + * @note New, more expressive libc error codes: + * https://www.gnu.org/software/libc/manual/html_node/Error-Codes.html + * https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/errno.h + * https://msdn.microsoft.com/en-us/library/ms740668.aspx + * + * @note The currently available bit flags are: + * - SOCK_NON_BLOCKING : if set, the socket will be on nonblocking mode + * - SOCK_LIBC_ERRORS : if set, the new libc errors will be seen on _error + * + * @note If no flags are set, the behaviour of the function will not be modified. + * + * @note Multiple flags may be set at the same time using the | operator. + * For example, SOCK_NON_BLOCKING|SOCK_LIBC_ERRORS will create a nonblocking socket with libc error codes. + * + * @note If you're creating a new nonblocking socket, _hostname should be numeric to avoid calling the + * name resolution server and potentially blocking the call. + * + * @note If the socket is a nonblocking one, the returned socket descriptor may be still connecting and + * further checks should be done with socket_is_writable() before trying to send data. + * + * @param _hostname Node to connect to + * @param _port Service to connect to + * @param _protocol Connect via SOCKET_TCP or SOCKET_UDP + * @param _error Set an error code here if anything goes wrong + * @param _flags Optional bit flags that change the behaviour of the function + * + * @return A socket descriptor (a positive integer) on success + * -1 on failure */ +native socket_open(const _hostname[], _port, _protocol = SOCKET_TCP, &_error, _flags = 0); -native socket_open(const _hostname[], _port, _protocol = SOCKET_TCP, &_error); - -/* Closes a Socket */ - +/** + * Closes a socket. + * + * @param _socket Socket descriptor + * + * @return 1 on success + * 0 on failure + */ native socket_close(_socket); -/* Recieves Data to string with the given length */ - +/** + * Receives data. + * + * @note The amount of bytes than you end up receiving can be less than the one you expected. + * + * @param _socket Socket descriptor + * @param _data Array to save the data + * @param _length Length of the array + * + * @return Amount of bytes received + * 0 if the peer closed the connection + * -1 on failure + */ native socket_recv(_socket, _data[], _length); -/* Sends data to the Socket */ - +/** + * Sends data. + * + * @note The amount of bytes that end up being sent may be lower than the total length of the array, + * check the return value and send the rest if needed. + * + * @param _socket Socket descriptor + * @param _data Array with the data to send + * @param _length Length of the array + * + * @return Amount of bytes sent + * -1 on failure + */ native socket_send(_socket, const _data[], _length); -/* Same as socket_send but Data can contain null bytes */ - +/** + * Sends data that can contain null bytes. + * + * @note The amount of bytes that end up being sent may be lower than the total length of the array, + * check the return value and send the rest if needed. + * + * @note strlen(_data) will return the wrong length if the array contains null bytes. + * + * @param _socket Socket descriptor + * @param _data Array with the data to send + * @param _length Length of the array + * + * @return Amount of bytes sent + * -1 on failure + */ native socket_send2(_socket, const _data[], _length); -/* This function will return true if the state (buffer content) have changed within the last recieve or -* the timeout, where timeout is a value in µSeconds, (1 sec =1000000 µsec). -* Use to check if new data is in your socket. */ +/** + * Backwards compatible function. + * + * @deprecated Renamed to socket_is_readable() + */ +#pragma deprecated Use socket_is_readable() instead +native socket_change(_socket, _timeout = 100000); -native socket_change(_socket, _timeout=100000); +/** + * Checks if a socket is marked as readable. + * + * @note You can use this function to make sure there's something on the socket and avoid a blocking call. + * @note Set _timeout to 0 avoid blocking the call. + * @note A socket will become readable if there's any data or an EOF. + * + * @param _socket Socket descriptor + * @param _timeout Amount of time to block the call waiting for the socket to be marked as readable or + * for the timeout to expire, in µSeconds (1 sec = 1000000 µsec) + * + * @return 1 if the socket is marked as readable + * 0 otherwise + */ +native socket_is_readable(_socket, _timeout = 100000); + +/** + * Checks if a socket is marked as writable. + * + * @note Use this function to check if a nonblocking socket is ready to be used. + * @note Set _timeout to 0 avoid blocking the call. + * @note An UDP socket is always writable. + * + * @param _socket Socket descriptor + * @param _timeout Amount of time to block the call waiting for the socket to be marked as writable or + * for the timeout to expire, in µSeconds (1 sec = 1000000 µsec) + * + * @return 1 if the socket is marked as writable + * 0 otherwise + */ +native socket_is_writable(_socket, _timeout = 100000); diff --git a/plugins/include/xs.inc b/plugins/include/xs.inc index bde3e265..a7ca0550 100755 --- a/plugins/include/xs.inc +++ b/plugins/include/xs.inc @@ -369,6 +369,24 @@ stock xs_vec_sub(const Float:in1[], const Float:in2[], Float:out[]) out[2] = in1[2] - in2[2]; } +// Adds the second vector scaled by a scalar to the first +// tested +stock xs_vec_add_scaled(const Float:in1[], const Float:in2[], Float:scalar, Float:out[]) +{ + out[0] = in1[0] + in2[0] * scalar; + out[1] = in1[1] + in2[1] * scalar; + out[2] = in1[2] + in2[2] * scalar; +} + +// Subtracts the second vector scaled by a scalar to the first +// tested +stock xs_vec_sub_scaled(const Float:in1[], const Float:in2[], Float:scalar, Float:out[]) +{ + out[0] = in1[0] - in2[0] * scalar; + out[1] = in1[1] - in2[1] * scalar; + out[2] = in1[2] - in2[2] * scalar; +} + // Are vectors equal? // untested, but should work stock bool:xs_vec_equal(const Float:vec1[], const Float:vec2[]) @@ -409,6 +427,30 @@ stock Float:xs_vec_len(const Float:vec[]) return xs_sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]); } +// Compute 2D vector length +// tested +stock Float:xs_vec_len_2d(const Float:vec[]) +{ + return xs_sqrt(vec[0]*vec[0] + vec[1]*vec[1]); +} + +// Compute distance between two vectors +// tested +stock Float:xs_vec_distance(const Float:vec1[], const Float:vec2[]) +{ + return xs_sqrt((vec1[0]-vec2[0]) * (vec1[0]-vec2[0]) + + (vec1[1]-vec2[1]) * (vec1[1]-vec2[1]) + + (vec1[2]-vec2[2]) * (vec1[2]-vec2[2])); +} + +// Compute distance between two 2D vectors +// tested +stock Float:xs_vec_distance_2d(const Float:vec1[], const Float:vec2[]) +{ + return xs_sqrt((vec1[0]-vec2[0]) * (vec1[0]-vec2[0]) + + (vec1[1]-vec2[1]) * (vec1[1]-vec2[1])); +} + // Normalize vec // tested stock xs_vec_normalize(const Float:vec[], Float:out[]) diff --git a/plugins/plmenu.sma b/plugins/plmenu.sma index 848aa369..bf96d873 100755 --- a/plugins/plmenu.sma +++ b/plugins/plmenu.sma @@ -37,7 +37,7 @@ new g_clcmdNum; new g_coloredMenus; new bool:g_cstrike = false; -new bool:g_fakemeta = false, m_iMenu, m_bTeamChanged, Menu_ChooseAppearance; +new bool:g_fakemeta = false; new Array:g_bantimes; new Array:g_slapsettings; @@ -127,9 +127,6 @@ public plugin_init() if (LibraryExists("fakemeta", LibType_Library)) { g_fakemeta = true; - m_iMenu = 205; - m_bTeamChanged = 501; - Menu_ChooseAppearance = 3; } new modname[9]; @@ -831,7 +828,7 @@ public actionTeamMenu(id, key) { if (g_fakemeta) { - if (get_pdata_int(player, m_iMenu) == Menu_ChooseAppearance) + if (get_ent_data(player, "CBasePlayer", "m_iMenu") == CS_Menu_ChooseAppearance) { // works for both vgui and old style menus, and send menuselect could close other menus (and since get_user_menu fails to return VGUI and old style classes menus...) engclient_cmd(player, "joinclass", "6"); @@ -863,7 +860,7 @@ public actionTeamMenu(id, key) } if (g_fakemeta) { - set_pdata_bool(player, m_bTeamChanged, true); + set_ent_data(player, "CBasePlayer", "m_bTeamChanged", true); } new limit_setting; if (mp_limitteams) @@ -906,7 +903,7 @@ public actionTeamMenu(id, key) } if (g_fakemeta) { - set_pdata_bool(player, m_bTeamChanged, true); + set_ent_data(player, "CBasePlayer", "m_bTeamChanged", true); } g_transferingAdmin = 0; diff --git a/plugins/testsuite/menu_page_callback_test.sma b/plugins/testsuite/menu_page_callback_test.sma new file mode 100644 index 00000000..fa116b70 --- /dev/null +++ b/plugins/testsuite/menu_page_callback_test.sma @@ -0,0 +1,76 @@ +#include + +new g_menuHandle; +new bool:g_isCallbackSet = false; + +public plugin_init() +{ + register_plugin("Menu Pagination Callback Test", "1.0.0", "KliPPy"); + + register_clcmd("say testmenu", "@Command_TestMenu"); + register_clcmd("say togglecallback", "@Command_ToggleCallback"); + + g_menuHandle = menu_create("Test menu", "@MenuHandler_TestMenu"); + menu_additem(g_menuHandle, "Item 1"); + menu_additem(g_menuHandle, "Item 2"); + menu_additem(g_menuHandle, "Item 3"); + menu_additem(g_menuHandle, "Item 4"); + menu_additem(g_menuHandle, "Item 5"); + menu_additem(g_menuHandle, "Item 6"); + menu_additem(g_menuHandle, "Item 7"); + menu_additem(g_menuHandle, "item 8"); + + menu_setprop(g_menuHandle, MPROP_PERPAGE, 2); +} + +public plugin_end() +{ + menu_destroy(g_menuHandle); +} + +@MenuHandler_TestMenu(id, menu, item) +{ + if(item == MENU_EXIT) + return PLUGIN_HANDLED; + + new dump1, dump2[1], dump3; + new itemName[32]; + menu_item_getinfo(menu, item, dump1, dump2, 0, itemName, charsmax(itemName), dump3); + + client_print(id, print_chat, "Selected: %s", itemName); + + return PLUGIN_HANDLED; +} + +@PageCallback_TestMenu(id, status) +{ + if(status == MENU_BACK) + client_print(id, print_chat, "Selected: MENU_BACK"); + else + client_print(id, print_chat, "Selected: MENU_MORE"); +} + +@Command_TestMenu(id) +{ + menu_display(id, g_menuHandle); + + return PLUGIN_HANDLED; +} + +@Command_ToggleCallback(id) +{ + if(g_isCallbackSet) + { + menu_setprop(g_menuHandle, MPROP_PAGE_CALLBACK, NULL_STRING); + g_isCallbackSet = false; + + client_print(id, print_chat, "Callback set to OFF"); + } + else + { + menu_setprop(g_menuHandle, MPROP_PAGE_CALLBACK, "@PageCallback_TestMenu"); + g_isCallbackSet = true; + + client_print(id, print_chat, "Callback set to ON"); + } +} \ No newline at end of file diff --git a/public/amtl b/public/amtl index b0550fd4..c91e8560 160000 --- a/public/amtl +++ b/public/amtl @@ -1 +1 @@ -Subproject commit b0550fd444f7e0cc4f071ee587fc85ff82671502 +Subproject commit c91e8560fb00984465a1a916172123b80a76dd04 diff --git a/public/auto-string.h b/public/auto-string.h index 677667a9..ead7680a 100644 --- a/public/auto-string.h +++ b/public/auto-string.h @@ -23,6 +23,7 @@ #include #include #include +#include namespace ke { diff --git a/public/engine_strucs.h b/public/engine_strucs.h index ad7a3d4d..c426466d 100644 --- a/public/engine_strucs.h +++ b/public/engine_strucs.h @@ -66,6 +66,12 @@ // This is the packet payload without any header bytes (which are attached for actual sending) #define NET_MAX_PAYLOAD 3990 +typedef enum sv_delta_s +{ + sv_packet_nodelta, + sv_packet_delta, +} sv_delta_t; + typedef enum netsrc_s { NS_CLIENT, diff --git a/public/interface_helpers.h b/public/interface_helpers.h new file mode 100644 index 00000000..889df935 --- /dev/null +++ b/public/interface_helpers.h @@ -0,0 +1,44 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +#pragma once + +#include "platform_helpers.h" +#include +#include + +template +bool GET_IFACE(const char* library, T*& var, const char* version, bool add_ext = true) +{ + char file[PLATFORM_MAX_PATH]; + + if (add_ext) + ke::path::Format(file, sizeof(file), "%s.%s", library, PLATFORM_LIB_EXT); + else + ke::SafeStrcpy(file, sizeof(file), library); + + auto lib = ke::SharedLib::Open(file); + + if (!lib || !lib->valid()) + { + return false; + } + + auto factory = reinterpret_cast(lib->lookup(CREATEINTERFACE_PROCNAME)); + + if (factory) + { + var = reinterpret_cast(factory(version, nullptr)); + return true; + } + + var = nullptr; + + return false; +} diff --git a/public/platform_helpers.h b/public/platform_helpers.h new file mode 100644 index 00000000..c53a1eef --- /dev/null +++ b/public/platform_helpers.h @@ -0,0 +1,70 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +#pragma once + +#include // Interface (HLSDK) + +#define PLATFORM_WINDOWNS_NAME "windows" +#define PLATFORM_LINUX_NAME "linux" +#define PLATFORM_MAC_NAME "mac" +#if defined(WIN32) +# ifndef PLATFORM_WINDOWS +# define PLATFORM_WINDOWS 1 +# endif +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# include +# include +# define PLATFORM_LIB_EXT "dll" +# define PLATFORM_NAME PLATFORM_WINDOWNS_NAME +# define PLATFORM_SEP_CHAR '\\' +# define PLATFORM_SEP_ALTCHAR '/' +# define PLATFORM_EXTERN_C extern "C" __declspec(dllexport) +#elif defined(__linux__) || defined(__APPLE__) +# if defined(__linux__) +# define PLATFORM_LINUX 1 +# define PLATFORM_LIB_EXT "so" +# define PLATFORM_NAME PLATFORM_LINUX_NAME +# define PLATFORM_COMPAT_ALT PLATFORM_MAC_NAME +# elif defined(__APPLE__) +# define PLATFORM_APPLE 1 +# define PLATFORM_LIB_EXT "dylib" +# define PLATFORM_NAME PLATFORM_MAC_NAME +# define PLATFORM_COMPAT_ALT PLATFORM_LINUX_NAME +# endif +# ifndef PLATFORM_POSIX +# define PLATFORM_POSIX 1 +# endif +# include +# include +# include +# include +# include +# include +# include +# if defined(PLATFORM_APPLE) +# include +# endif +# define PLATFORM_SEP_CHAR '/' +# define PLATFORM_SEP_ALTCHAR '\\' +# define PLATFORM_EXTERN_C extern "C" __attribute__((visibility("default"))) +# define WINAPI +#endif + +#define PLATFORM_MAX_PATH 260 + +#if defined PLATFORM_WINDOWS + typedef HANDLE DirHandle; +#elif defined PLATFORM_POSIX + typedef DIR* DirHandle; +#endif + diff --git a/public/resdk/common/hookchains.h b/public/resdk/common/hookchains.h new file mode 100644 index 00000000..7ea472a6 --- /dev/null +++ b/public/resdk/common/hookchains.h @@ -0,0 +1,121 @@ +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +* +*/ +#pragma once + +template +class IHookChain { +protected: + virtual ~IHookChain() {} + +public: + virtual t_ret callNext(t_args... args) = 0; + virtual t_ret callOriginal(t_args... args) = 0; +}; + +template +class IHookChainClass { +protected: + virtual ~IHookChainClass() {} + +public: + virtual t_ret callNext(t_class *, t_args... args) = 0; + virtual t_ret callOriginal(t_class *, t_args... args) = 0; +}; + +template +class IVoidHookChain +{ +protected: + virtual ~IVoidHookChain() {} + +public: + virtual void callNext(t_args... args) = 0; + virtual void callOriginal(t_args... args) = 0; +}; + +template +class IVoidHookChainClass +{ +protected: + virtual ~IVoidHookChainClass() {} + +public: + virtual void callNext(t_class *, t_args... args) = 0; + virtual void callOriginal(t_class *, t_args... args) = 0; +}; + +// Specifies priorities for hooks call order in the chain. +// For equal priorities first registered hook will be called first. +enum HookChainPriority +{ + HC_PRIORITY_UNINTERRUPTABLE = 255, // Hook will be called before other hooks. + HC_PRIORITY_HIGH = 192, // Hook will be called before hooks with default priority. + HC_PRIORITY_DEFAULT = 128, // Default hook call priority. + HC_PRIORITY_MEDIUM = 64, // Hook will be called after hooks with default priority. + HC_PRIORITY_LOW = 0, // Hook will be called after all other hooks. +}; + +// Hook chain registry(for hooks [un]registration) +template +class IHookChainRegistry { +public: + typedef t_ret(*hookfunc_t)(IHookChain*, t_args...); + + virtual void registerHook(hookfunc_t hook, int priority = HC_PRIORITY_DEFAULT) = 0; + virtual void unregisterHook(hookfunc_t hook) = 0; +}; + +// Hook chain registry(for hooks [un]registration) +template +class IHookChainRegistryClass { +public: + typedef t_ret(*hookfunc_t)(IHookChainClass*, t_class *, t_args...); + + virtual void registerHook(hookfunc_t hook, int priority = HC_PRIORITY_DEFAULT) = 0; + virtual void unregisterHook(hookfunc_t hook) = 0; +}; + +// Hook chain registry(for hooks [un]registration) +template +class IVoidHookChainRegistry { +public: + typedef void(*hookfunc_t)(IVoidHookChain*, t_args...); + + virtual void registerHook(hookfunc_t hook, int priority = HC_PRIORITY_DEFAULT) = 0; + virtual void unregisterHook(hookfunc_t hook) = 0; +}; + +// Hook chain registry(for hooks [un]registration) +template +class IVoidHookChainRegistryClass { +public: + typedef void(*hookfunc_t)(IVoidHookChainClass*, t_class *, t_args...); + + virtual void registerHook(hookfunc_t hook, int priority = HC_PRIORITY_DEFAULT) = 0; + virtual void unregisterHook(hookfunc_t hook) = 0; +}; diff --git a/public/resdk/cstrike/regamedll_api.h b/public/resdk/cstrike/regamedll_api.h new file mode 100644 index 00000000..81999943 --- /dev/null +++ b/public/resdk/cstrike/regamedll_api.h @@ -0,0 +1,482 @@ +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +* +*/ +#pragma once + +#include +#include "regamedll_interfaces.h" +#include "regamedll_const.h" +#include "../common/hookchains.h" + +#define REGAMEDLL_API_VERSION_MAJOR 5 +#define REGAMEDLL_API_VERSION_MINOR 1 + +// CBasePlayer::Spawn hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_Spawn; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_Spawn; + +// CBasePlayer::Precache hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_Precache; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_Precache; + +// CBasePlayer::ObjectCaps hook +typedef IHookChainClass IReGameHook_CBasePlayer_ObjectCaps; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_ObjectCaps; + +// CBasePlayer::Classify hook +typedef IHookChainClass IReGameHook_CBasePlayer_Classify; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_Classify; + +// CBasePlayer::TraceAttack hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_TraceAttack; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_TraceAttack; + +// CBasePlayer::TakeDamage hook +typedef IHookChainClass IReGameHook_CBasePlayer_TakeDamage; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_TakeDamage; + +// CBasePlayer::TakeHealth hook +typedef IHookChainClass IReGameHook_CBasePlayer_TakeHealth; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_TakeHealth; + +// CBasePlayer::Killed hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_Killed; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_Killed; + +// CBasePlayer::AddPoints hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_AddPoints; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_AddPoints; + +// CBasePlayer::AddPointsToTeam hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_AddPointsToTeam; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_AddPointsToTeam; + +// CBasePlayer::AddPlayerItem hook +typedef IHookChainClass IReGameHook_CBasePlayer_AddPlayerItem; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_AddPlayerItem; + +// CBasePlayer::RemovePlayerItem hook +typedef IHookChainClass IReGameHook_CBasePlayer_RemovePlayerItem; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_RemovePlayerItem; + +// CBasePlayer::GiveAmmo hook +typedef IHookChainClass IReGameHook_CBasePlayer_GiveAmmo; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_GiveAmmo; + +// CBasePlayer::ResetMaxSpeed hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_ResetMaxSpeed; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_ResetMaxSpeed; + +// CBasePlayer::Jump hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_Jump; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_Jump; + +// CBasePlayer::Duck hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_Duck; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_Duck; + +// CBasePlayer::PreThink hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_PreThink; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_PreThink; + +// CBasePlayer::PostThink hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_PostThink; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_PostThink; + +// CBasePlayer::UpdateClientData hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_UpdateClientData; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_UpdateClientData; + +// CBasePlayer::ImpulseCommands hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_ImpulseCommands; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_ImpulseCommands; + +// CBasePlayer::RoundRespawn hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_RoundRespawn; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_RoundRespawn; + +// CBasePlayer::Blind hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_Blind; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_Blind; + +// CBasePlayer::Observer_IsValidTarget hook +typedef IHookChainClass IReGameHook_CBasePlayer_Observer_IsValidTarget; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_Observer_IsValidTarget; + +// CBasePlayer::SetAnimation hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_SetAnimation; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_SetAnimation; + +// CBasePlayer::GiveDefaultItems hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_GiveDefaultItems; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_GiveDefaultItems; + +// CBasePlayer::GiveNamedItem hook +typedef IHookChainClass IReGameHook_CBasePlayer_GiveNamedItem; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_GiveNamedItem; + +// CBasePlayer::AddAccount hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_AddAccount; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_AddAccount; + +// CBasePlayer::GiveShield hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_GiveShield; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_GiveShield; + +// CBasePlayer:SetClientUserInfoModel hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_SetClientUserInfoModel; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_SetClientUserInfoModel; + +// CBasePlayer:SetClientUserInfoName hook +typedef IHookChainClass IReGameHook_CBasePlayer_SetClientUserInfoName; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_SetClientUserInfoName; + +// CBasePlayer::HasRestrictItem hook +typedef IHookChainClass IReGameHook_CBasePlayer_HasRestrictItem; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_HasRestrictItem; + +// CBasePlayer::DropPlayerItem hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_DropPlayerItem; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_DropPlayerItem; + +// CBasePlayer::DropShield hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_DropShield; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_DropShield; + +// CBasePlayer::OnSpawnEquip hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_OnSpawnEquip; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_OnSpawnEquip; + +// CBasePlayer::Radio hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_Radio; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_Radio; + +// CBasePlayer::Disappear hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_Disappear; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_Disappear; + +// CBasePlayer::MakeVIP hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_MakeVIP; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_MakeVIP; + +// CBasePlayer::MakeBomber hook +typedef IHookChainClass IReGameHook_CBasePlayer_MakeBomber; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_MakeBomber; + +// CBasePlayer::StartObserver hook +typedef IVoidHookChainClass IReGameHook_CBasePlayer_StartObserver; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBasePlayer_StartObserver; + +// CBasePlayer::GetIntoGame hook +typedef IHookChainClass IReGameHook_CBasePlayer_GetIntoGame; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_GetIntoGame; + +// CBaseAnimating::ResetSequenceInfo hook +typedef IVoidHookChainClass IReGameHook_CBaseAnimating_ResetSequenceInfo; +typedef IVoidHookChainRegistryClass IReGameHookRegistry_CBaseAnimating_ResetSequenceInfo; + +// GetForceCamera hook +typedef IHookChain IReGameHook_GetForceCamera; +typedef IHookChainRegistry IReGameHookRegistry_GetForceCamera; + +// PlayerBlind hook +typedef IVoidHookChain IReGameHook_PlayerBlind; +typedef IVoidHookChainRegistry IReGameHookRegistry_PlayerBlind; + +// RadiusFlash_TraceLine hook +typedef IVoidHookChain IReGameHook_RadiusFlash_TraceLine; +typedef IVoidHookChainRegistry IReGameHookRegistry_RadiusFlash_TraceLine; + +// RoundEnd hook +typedef IHookChain IReGameHook_RoundEnd; +typedef IHookChainRegistry IReGameHookRegistry_RoundEnd; + +// InstallGameRules hook +typedef IHookChain IReGameHook_InstallGameRules; +typedef IHookChainRegistry IReGameHookRegistry_InstallGameRules; + +// PM_Init hook +typedef IVoidHookChain IReGameHook_PM_Init; +typedef IVoidHookChainRegistry IReGameHookRegistry_PM_Init; + +// PM_Move hook +typedef IVoidHookChain IReGameHook_PM_Move; +typedef IVoidHookChainRegistry IReGameHookRegistry_PM_Move; + +// PM_AirMove hook +typedef IVoidHookChain IReGameHook_PM_AirMove; +typedef IVoidHookChainRegistry IReGameHookRegistry_PM_AirMove; + +// HandleMenu_ChooseAppearance hook +typedef IVoidHookChain IReGameHook_HandleMenu_ChooseAppearance; +typedef IVoidHookChainRegistry IReGameHookRegistry_HandleMenu_ChooseAppearance; + +// HandleMenu_ChooseTeam hook +typedef IHookChain IReGameHook_HandleMenu_ChooseTeam; +typedef IHookChainRegistry IReGameHookRegistry_HandleMenu_ChooseTeam; + +// ShowMenu hook +typedef IVoidHookChain IReGameHook_ShowMenu; +typedef IVoidHookChainRegistry IReGameHookRegistry_ShowMenu; + +// ShowVGUIMenu hook +typedef IVoidHookChain IReGameHook_ShowVGUIMenu; +typedef IVoidHookChainRegistry IReGameHookRegistry_ShowVGUIMenu; + +// BuyGunAmmo hook +typedef IHookChain IReGameHook_BuyGunAmmo; +typedef IHookChainRegistry IReGameHookRegistry_BuyGunAmmo; + +// BuyWeaponByWeaponID hook +typedef IHookChain IReGameHook_BuyWeaponByWeaponID; +typedef IHookChainRegistry IReGameHookRegistry_BuyWeaponByWeaponID; + +// InternalCommand hook +typedef IVoidHookChain IReGameHook_InternalCommand; +typedef IVoidHookChainRegistry IReGameHookRegistry_InternalCommand; + +// CHalfLifeMultiplay::FShouldSwitchWeapon hook +typedef IHookChain IReGameHook_CSGameRules_FShouldSwitchWeapon; +typedef IHookChainRegistry IReGameHookRegistry_CSGameRules_FShouldSwitchWeapon; + +// CHalfLifeMultiplay::GetNextBestWeapon hook +typedef IHookChain IReGameHook_CSGameRules_GetNextBestWeapon; +typedef IHookChainRegistry IReGameHookRegistry_CSGameRules_GetNextBestWeapon; + +// CHalfLifeMultiplay::FlPlayerFallDamage hook +typedef IHookChain IReGameHook_CSGameRules_FlPlayerFallDamage; +typedef IHookChainRegistry IReGameHookRegistry_CSGameRules_FlPlayerFallDamage; + +// CHalfLifeMultiplay::FPlayerCanTakeDamage hook +typedef IHookChain IReGameHook_CSGameRules_FPlayerCanTakeDamage; +typedef IHookChainRegistry IReGameHookRegistry_CSGameRules_FPlayerCanTakeDamage; + +// CHalfLifeMultiplay::PlayerSpawn hook +typedef IVoidHookChain IReGameHook_CSGameRules_PlayerSpawn; +typedef IVoidHookChainRegistry IReGameHookRegistry_CSGameRules_PlayerSpawn; + +// CHalfLifeMultiplay::FPlayerCanRespawn hook +typedef IHookChain IReGameHook_CSGameRules_FPlayerCanRespawn; +typedef IHookChainRegistry IReGameHookRegistry_CSGameRules_FPlayerCanRespawn; + +// CHalfLifeMultiplay::GetPlayerSpawnSpot hook +typedef IHookChain IReGameHook_CSGameRules_GetPlayerSpawnSpot; +typedef IHookChainRegistry IReGameHookRegistry_CSGameRules_GetPlayerSpawnSpot; + +// CHalfLifeMultiplay::ClientUserInfoChanged hook +typedef IVoidHookChain IReGameHook_CSGameRules_ClientUserInfoChanged; +typedef IVoidHookChainRegistry IReGameHookRegistry_CSGameRules_ClientUserInfoChanged; + +// CHalfLifeMultiplay::PlayerKilled hook +typedef IVoidHookChain IReGameHook_CSGameRules_PlayerKilled; +typedef IVoidHookChainRegistry IReGameHookRegistry_CSGameRules_PlayerKilled; + +// CHalfLifeMultiplay::DeathNotice hook +typedef IVoidHookChain IReGameHook_CSGameRules_DeathNotice; +typedef IVoidHookChainRegistry IReGameHookRegistry_CSGameRules_DeathNotice; + +// CHalfLifeMultiplay::CanHavePlayerItem hook +typedef IHookChain IReGameHook_CSGameRules_CanHavePlayerItem; +typedef IHookChainRegistry IReGameHookRegistry_CSGameRules_CanHavePlayerItem; + +// CHalfLifeMultiplay::DeadPlayerWeapons hook +typedef IHookChain IReGameHook_CSGameRules_DeadPlayerWeapons; +typedef IHookChainRegistry IReGameHookRegistry_CSGameRules_DeadPlayerWeapons; + +// CHalfLifeMultiplay::ServerDeactivate hook +typedef IVoidHookChain<> IReGameHook_CSGameRules_ServerDeactivate; +typedef IVoidHookChainRegistry<> IReGameHookRegistry_CSGameRules_ServerDeactivate; + +// CHalfLifeMultiplay::CheckMapConditions hook +typedef IVoidHookChain<> IReGameHook_CSGameRules_CheckMapConditions; +typedef IVoidHookChainRegistry<> IReGameHookRegistry_CSGameRules_CheckMapConditions; + +// CHalfLifeMultiplay::CleanUpMap hook +typedef IVoidHookChain<> IReGameHook_CSGameRules_CleanUpMap; +typedef IVoidHookChainRegistry<> IReGameHookRegistry_CSGameRules_CleanUpMap; + +// CHalfLifeMultiplay::RestartRound hook +typedef IVoidHookChain<> IReGameHook_CSGameRules_RestartRound; +typedef IVoidHookChainRegistry<> IReGameHookRegistry_CSGameRules_RestartRound; + +// CHalfLifeMultiplay::CheckWinConditions hook +typedef IVoidHookChain<> IReGameHook_CSGameRules_CheckWinConditions; +typedef IVoidHookChainRegistry<> IReGameHookRegistry_CSGameRules_CheckWinConditions; + +// CHalfLifeMultiplay::RemoveGuns hook +typedef IVoidHookChain<> IReGameHook_CSGameRules_RemoveGuns; +typedef IVoidHookChainRegistry<> IReGameHookRegistry_CSGameRules_RemoveGuns; + +// CHalfLifeMultiplay::GiveC4 hook +typedef IVoidHookChain<> IReGameHook_CSGameRules_GiveC4; +typedef IVoidHookChainRegistry<> IReGameHookRegistry_CSGameRules_GiveC4; + +// CHalfLifeMultiplay::ChangeLevel hook +typedef IVoidHookChain<> IReGameHook_CSGameRules_ChangeLevel; +typedef IVoidHookChainRegistry<> IReGameHookRegistry_CSGameRules_ChangeLevel; + +// CHalfLifeMultiplay::GoToIntermission hook +typedef IVoidHookChain<> IReGameHook_CSGameRules_GoToIntermission; +typedef IVoidHookChainRegistry<> IReGameHookRegistry_CSGameRules_GoToIntermission; + +// CHalfLifeMultiplay::BalanceTeams hook +typedef IVoidHookChain<> IReGameHook_CSGameRules_BalanceTeams; +typedef IVoidHookChainRegistry<> IReGameHookRegistry_CSGameRules_BalanceTeams; + +// CHalfLifeMultiplay::OnRoundFreezeEnd hook +typedef IVoidHookChain<> IReGameHook_CSGameRules_OnRoundFreezeEnd; +typedef IVoidHookChainRegistry<> IReGameHookRegistry_CSGameRules_OnRoundFreezeEnd; + +// PM_UpdateStepSound hook +typedef IVoidHookChain<> IReGameHook_PM_UpdateStepSound; +typedef IVoidHookChainRegistry<> IReGameHookRegistry_PM_UpdateStepSound; + +class IReGameHookchains { +public: + virtual ~IReGameHookchains() {} + + // CBasePlayer virtual + virtual IReGameHookRegistry_CBasePlayer_Spawn* CBasePlayer_Spawn() = 0; + virtual IReGameHookRegistry_CBasePlayer_Precache* CBasePlayer_Precache() = 0; + virtual IReGameHookRegistry_CBasePlayer_ObjectCaps* CBasePlayer_ObjectCaps() = 0; + virtual IReGameHookRegistry_CBasePlayer_Classify* CBasePlayer_Classify() = 0; + virtual IReGameHookRegistry_CBasePlayer_TraceAttack* CBasePlayer_TraceAttack() = 0; + virtual IReGameHookRegistry_CBasePlayer_TakeDamage* CBasePlayer_TakeDamage() = 0; + virtual IReGameHookRegistry_CBasePlayer_TakeHealth* CBasePlayer_TakeHealth() = 0; + virtual IReGameHookRegistry_CBasePlayer_Killed* CBasePlayer_Killed() = 0; + virtual IReGameHookRegistry_CBasePlayer_AddPoints* CBasePlayer_AddPoints() = 0; + virtual IReGameHookRegistry_CBasePlayer_AddPointsToTeam* CBasePlayer_AddPointsToTeam() = 0; + virtual IReGameHookRegistry_CBasePlayer_AddPlayerItem* CBasePlayer_AddPlayerItem() = 0; + virtual IReGameHookRegistry_CBasePlayer_RemovePlayerItem* CBasePlayer_RemovePlayerItem() = 0; + virtual IReGameHookRegistry_CBasePlayer_GiveAmmo* CBasePlayer_GiveAmmo() = 0; + virtual IReGameHookRegistry_CBasePlayer_ResetMaxSpeed* CBasePlayer_ResetMaxSpeed() = 0; + virtual IReGameHookRegistry_CBasePlayer_Jump* CBasePlayer_Jump() = 0; + virtual IReGameHookRegistry_CBasePlayer_Duck* CBasePlayer_Duck() = 0; + virtual IReGameHookRegistry_CBasePlayer_PreThink* CBasePlayer_PreThink() = 0; + virtual IReGameHookRegistry_CBasePlayer_PostThink* CBasePlayer_PostThink() = 0; + virtual IReGameHookRegistry_CBasePlayer_UpdateClientData* CBasePlayer_UpdateClientData() = 0; + virtual IReGameHookRegistry_CBasePlayer_ImpulseCommands* CBasePlayer_ImpulseCommands() = 0; + virtual IReGameHookRegistry_CBasePlayer_RoundRespawn* CBasePlayer_RoundRespawn() = 0; + virtual IReGameHookRegistry_CBasePlayer_Blind* CBasePlayer_Blind() = 0; + + virtual IReGameHookRegistry_CBasePlayer_Observer_IsValidTarget* CBasePlayer_Observer_IsValidTarget() = 0; + virtual IReGameHookRegistry_CBasePlayer_SetAnimation* CBasePlayer_SetAnimation() = 0; + virtual IReGameHookRegistry_CBasePlayer_GiveDefaultItems* CBasePlayer_GiveDefaultItems() = 0; + virtual IReGameHookRegistry_CBasePlayer_GiveNamedItem* CBasePlayer_GiveNamedItem() = 0; + virtual IReGameHookRegistry_CBasePlayer_AddAccount* CBasePlayer_AddAccount() = 0; + virtual IReGameHookRegistry_CBasePlayer_GiveShield* CBasePlayer_GiveShield() = 0; + virtual IReGameHookRegistry_CBasePlayer_SetClientUserInfoModel* CBasePlayer_SetClientUserInfoModel() = 0; + virtual IReGameHookRegistry_CBasePlayer_SetClientUserInfoName* CBasePlayer_SetClientUserInfoName() = 0; + virtual IReGameHookRegistry_CBasePlayer_HasRestrictItem* CBasePlayer_HasRestrictItem() = 0; + virtual IReGameHookRegistry_CBasePlayer_DropPlayerItem* CBasePlayer_DropPlayerItem() = 0; + virtual IReGameHookRegistry_CBasePlayer_DropShield* CBasePlayer_DropShield() = 0; + virtual IReGameHookRegistry_CBasePlayer_OnSpawnEquip* CBasePlayer_OnSpawnEquip() = 0; + virtual IReGameHookRegistry_CBasePlayer_Radio* CBasePlayer_Radio() = 0; + virtual IReGameHookRegistry_CBasePlayer_Disappear* CBasePlayer_Disappear() = 0; + virtual IReGameHookRegistry_CBasePlayer_MakeVIP* CBasePlayer_MakeVIP() = 0; + virtual IReGameHookRegistry_CBasePlayer_MakeBomber* CBasePlayer_MakeBomber() = 0; + virtual IReGameHookRegistry_CBasePlayer_StartObserver* CBasePlayer_StartObserver() = 0; + virtual IReGameHookRegistry_CBasePlayer_GetIntoGame* CBasePlayer_GetIntoGame() = 0; + + virtual IReGameHookRegistry_CBaseAnimating_ResetSequenceInfo* CBaseAnimating_ResetSequenceInfo() = 0; + + virtual IReGameHookRegistry_GetForceCamera* GetForceCamera() = 0; + virtual IReGameHookRegistry_PlayerBlind* PlayerBlind() = 0; + virtual IReGameHookRegistry_RadiusFlash_TraceLine* RadiusFlash_TraceLine() = 0; + virtual IReGameHookRegistry_RoundEnd* RoundEnd() = 0; + virtual IReGameHookRegistry_InstallGameRules* InstallGameRules() = 0; + virtual IReGameHookRegistry_PM_Init* PM_Init() = 0; + virtual IReGameHookRegistry_PM_Move* PM_Move() = 0; + virtual IReGameHookRegistry_PM_AirMove* PM_AirMove() = 0; + virtual IReGameHookRegistry_HandleMenu_ChooseAppearance* HandleMenu_ChooseAppearance() = 0; + virtual IReGameHookRegistry_HandleMenu_ChooseTeam* HandleMenu_ChooseTeam() = 0; + virtual IReGameHookRegistry_ShowMenu* ShowMenu() = 0; + virtual IReGameHookRegistry_ShowVGUIMenu* ShowVGUIMenu() = 0; + virtual IReGameHookRegistry_BuyGunAmmo* BuyGunAmmo() = 0; + virtual IReGameHookRegistry_BuyWeaponByWeaponID* BuyWeaponByWeaponID() = 0; + virtual IReGameHookRegistry_InternalCommand* InternalCommand() = 0; + + virtual IReGameHookRegistry_CSGameRules_FShouldSwitchWeapon* CSGameRules_FShouldSwitchWeapon() = 0; + virtual IReGameHookRegistry_CSGameRules_GetNextBestWeapon* CSGameRules_GetNextBestWeapon() = 0; + virtual IReGameHookRegistry_CSGameRules_FlPlayerFallDamage* CSGameRules_FlPlayerFallDamage() = 0; + virtual IReGameHookRegistry_CSGameRules_FPlayerCanTakeDamage* CSGameRules_FPlayerCanTakeDamage() = 0; + virtual IReGameHookRegistry_CSGameRules_PlayerSpawn* CSGameRules_PlayerSpawn() = 0; + virtual IReGameHookRegistry_CSGameRules_FPlayerCanRespawn* CSGameRules_FPlayerCanRespawn() = 0; + virtual IReGameHookRegistry_CSGameRules_GetPlayerSpawnSpot* CSGameRules_GetPlayerSpawnSpot() = 0; + virtual IReGameHookRegistry_CSGameRules_ClientUserInfoChanged* CSGameRules_ClientUserInfoChanged() = 0; + virtual IReGameHookRegistry_CSGameRules_PlayerKilled* CSGameRules_PlayerKilled() = 0; + virtual IReGameHookRegistry_CSGameRules_DeathNotice* CSGameRules_DeathNotice() = 0; + virtual IReGameHookRegistry_CSGameRules_CanHavePlayerItem* CSGameRules_CanHavePlayerItem() = 0; + virtual IReGameHookRegistry_CSGameRules_DeadPlayerWeapons* CSGameRules_DeadPlayerWeapons() = 0; + virtual IReGameHookRegistry_CSGameRules_ServerDeactivate* CSGameRules_ServerDeactivate() = 0; + virtual IReGameHookRegistry_CSGameRules_CheckMapConditions* CSGameRules_CheckMapConditions() = 0; + virtual IReGameHookRegistry_CSGameRules_CleanUpMap* CSGameRules_CleanUpMap() = 0; + virtual IReGameHookRegistry_CSGameRules_RestartRound* CSGameRules_RestartRound() = 0; + virtual IReGameHookRegistry_CSGameRules_CheckWinConditions* CSGameRules_CheckWinConditions() = 0; + virtual IReGameHookRegistry_CSGameRules_RemoveGuns* CSGameRules_RemoveGuns() = 0; + virtual IReGameHookRegistry_CSGameRules_GiveC4* CSGameRules_GiveC4() = 0; + virtual IReGameHookRegistry_CSGameRules_ChangeLevel* CSGameRules_ChangeLevel() = 0; + virtual IReGameHookRegistry_CSGameRules_GoToIntermission* CSGameRules_GoToIntermission() = 0; + virtual IReGameHookRegistry_CSGameRules_BalanceTeams* CSGameRules_BalanceTeams() = 0; + virtual IReGameHookRegistry_CSGameRules_OnRoundFreezeEnd* CSGameRules_OnRoundFreezeEnd() = 0; + virtual IReGameHookRegistry_PM_UpdateStepSound* PM_UpdateStepSound() = 0; +}; + +struct ReGameFuncs_t { + struct edict_s *(*CREATE_NAMED_ENTITY2)(string_t iClass); + void (*ChangeString)(char *&dest, const char *source); + void (*RadiusDamage)(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType); + void (*ClearMultiDamage)(); + void (*ApplyMultiDamage)(entvars_t *pevInflictor, entvars_t *pevAttacker); + void (*AddMultiDamage)(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType); + class CBaseEntity *(*UTIL_FindEntityByString)(class CBaseEntity *pStartEntity, const char *szKeyword, const char *szValue); + void (*AddEntityHashValue)(entvars_t *pev, const char *value, hash_types_e fieldType); + void (*RemoveEntityHashValue)(entvars_t *pev, const char *value, hash_types_e fieldType); + int (*Cmd_Argc)(); + const char *(*Cmd_Argv)(int i); +}; + +class IReGameApi { +public: + virtual ~IReGameApi() {} + + virtual int GetMajorVersion() = 0; + virtual int GetMinorVersion() = 0; + virtual const ReGameFuncs_t* GetFuncs() = 0; + virtual IReGameHookchains* GetHookchains() = 0; + + virtual class CGameRules* GetGameRules() = 0; + virtual struct WeaponInfoStruct* GetWeaponInfo(int weaponID) = 0; + virtual struct WeaponInfoStruct* GetWeaponInfo(const char* weaponName) = 0; + virtual struct playermove_s* GetPlayerMove() = 0; + virtual struct WeaponSlotInfo* GetWeaponSlot(WeaponIdType weaponID) = 0; + virtual struct WeaponSlotInfo* GetWeaponSlot(const char* weaponName) = 0; + virtual struct ItemInfo* GetItemInfo(WeaponIdType weaponID) = 0; + virtual struct AmmoInfo* GetAmmoInfo(AmmoType ammoID) = 0; +}; + +#define VRE_GAMEDLL_API_VERSION "VRE_GAMEDLL_API_VERSION001" diff --git a/public/resdk/cstrike/regamedll_const.h b/public/resdk/cstrike/regamedll_const.h new file mode 100644 index 00000000..0a6bd784 --- /dev/null +++ b/public/resdk/cstrike/regamedll_const.h @@ -0,0 +1,740 @@ +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +* +*/ +#pragma once + +// custom enum +enum ArmorType +{ + ARMOR_NONE, // no armor + ARMOR_KEVLAR, // body vest only + ARMOR_VESTHELM, // vest and helmet +}; + +enum ArmouryItemPack +{ + ARMOURY_MP5NAVY, + ARMOURY_TMP, + ARMOURY_P90, + ARMOURY_MAC10, + ARMOURY_AK47, + ARMOURY_SG552, + ARMOURY_M4A1, + ARMOURY_AUG, + ARMOURY_SCOUT, + ARMOURY_G3SG1, + ARMOURY_AWP, + ARMOURY_M3, + ARMOURY_XM1014, + ARMOURY_M249, + ARMOURY_FLASHBANG, + ARMOURY_HEGRENADE, + ARMOURY_KEVLAR, + ARMOURY_ASSAULT, + ARMOURY_SMOKEGRENADE, + ARMOURY_GLOCK18, + ARMOURY_USP, + ARMOURY_ELITE, + ARMOURY_FIVESEVEN, + ARMOURY_P228, + ARMOURY_DEAGLE, + ARMOURY_FAMAS, + ARMOURY_SG550, + ARMOURY_GALIL, + ARMOURY_UMP45, + ARMOURY_SHIELD +}; + +struct AmmoInfo +{ + const char *pszName; + int iId; +}; + +struct MULTIDAMAGE +{ + CBaseEntity *pEntity; + float amount; + int type; +}; + + + +enum ItemRestType +{ + ITEM_TYPE_BUYING, // when a player buying items + ITEM_TYPE_TOUCHED, // when the player touches with a weaponbox or armoury_entity + ITEM_TYPE_EQUIPPED // when a entity game_player_equip gives item to player or default item's on player spawn +}; + +// constant items +#define ITEM_ID_ANTIDOTE 2 +#define ITEM_ID_SECURITY 3 + +enum ItemID +{ + ITEM_NONE = -1, + ITEM_SHIELDGUN, + ITEM_P228, + ITEM_GLOCK, + ITEM_SCOUT, + ITEM_HEGRENADE, + ITEM_XM1014, + ITEM_C4, + ITEM_MAC10, + ITEM_AUG, + ITEM_SMOKEGRENADE, + ITEM_ELITE, + ITEM_FIVESEVEN, + ITEM_UMP45, + ITEM_SG550, + ITEM_GALIL, + ITEM_FAMAS, + ITEM_USP, + ITEM_GLOCK18, + ITEM_AWP, + ITEM_MP5N, + ITEM_M249, + ITEM_M3, + ITEM_M4A1, + ITEM_TMP, + ITEM_G3SG1, + ITEM_FLASHBANG, + ITEM_DEAGLE, + ITEM_SG552, + ITEM_AK47, + ITEM_KNIFE, + ITEM_P90, + ITEM_NVG, + ITEM_DEFUSEKIT, + ITEM_KEVLAR, + ITEM_ASSAULT, + ITEM_LONGJUMP, + ITEM_SODACAN, + ITEM_HEALTHKIT, + ITEM_ANTIDOTE, + ITEM_BATTERY +}; + +// custom enum +enum RewardType +{ + RT_NONE, + RT_ROUND_BONUS, + RT_PLAYER_RESET, + RT_PLAYER_JOIN, + RT_PLAYER_SPEC_JOIN, + RT_PLAYER_BOUGHT_SOMETHING, + RT_HOSTAGE_TOOK, + RT_HOSTAGE_RESCUED, + RT_HOSTAGE_DAMAGED, + RT_HOSTAGE_KILLED, + RT_TEAMMATES_KILLED, + RT_ENEMY_KILLED, + RT_INTO_GAME, + RT_VIP_KILLED, + RT_VIP_RESCUED_MYSELF +}; + +enum PLAYER_ANIM +{ + PLAYER_IDLE, + PLAYER_WALK, + PLAYER_JUMP, + PLAYER_SUPERJUMP, + PLAYER_DIE, + PLAYER_ATTACK1, + PLAYER_ATTACK2, + PLAYER_FLINCH, + PLAYER_LARGE_FLINCH, + PLAYER_RELOAD, + PLAYER_HOLDBOMB +}; + +enum TeamName +{ + UNASSIGNED, + TERRORIST, + CT, + SPECTATOR, +}; + +enum ModelName +{ + MODEL_UNASSIGNED, + MODEL_URBAN, + MODEL_TERROR, + MODEL_LEET, + MODEL_ARCTIC, + MODEL_GSG9, + MODEL_GIGN, + MODEL_SAS, + MODEL_GUERILLA, + MODEL_VIP, + MODEL_MILITIA, + MODEL_SPETSNAZ, + MODEL_AUTO +}; + +enum JoinState +{ + JOINED, + SHOWLTEXT, + READINGLTEXT, + SHOWTEAMSELECT, + PICKINGTEAM, + GETINTOGAME +}; + +enum TrackCommands +{ + CMD_SAY = 0, + CMD_SAYTEAM, + CMD_FULLUPDATE, + CMD_VOTE, + CMD_VOTEMAP, + CMD_LISTMAPS, + CMD_LISTPLAYERS, + CMD_NIGHTVISION, + COMMANDS_TO_TRACK, +}; + +struct RebuyStruct +{ + int m_primaryWeapon; + int m_primaryAmmo; + int m_secondaryWeapon; + int m_secondaryAmmo; + int m_heGrenade; + int m_flashbang; + int m_smokeGrenade; + int m_defuser; + int m_nightVision; + ArmorType m_armor; +}; + +enum ThrowDirection +{ + THROW_NONE, + THROW_FORWARD, + THROW_BACKWARD, + THROW_HITVEL, + THROW_BOMB, + THROW_GRENADE, + THROW_HITVEL_MINUS_AIRVEL +}; + +enum sbar_data +{ + SBAR_ID_TARGETTYPE = 1, + SBAR_ID_TARGETNAME, + SBAR_ID_TARGETHEALTH, + SBAR_END +}; + +enum +{ + WINSTATUS_CTS = 1, + WINSTATUS_TERRORISTS, + WINSTATUS_DRAW, +}; + +// custom enum +// used for EndRoundMessage() logged messages +enum ScenarioEventEndRound +{ + ROUND_NONE, + ROUND_TARGET_BOMB, + ROUND_VIP_ESCAPED, + ROUND_VIP_ASSASSINATED, + ROUND_TERRORISTS_ESCAPED, + ROUND_CTS_PREVENT_ESCAPE, + ROUND_ESCAPING_TERRORISTS_NEUTRALIZED, + ROUND_BOMB_DEFUSED, + ROUND_CTS_WIN, + ROUND_TERRORISTS_WIN, + ROUND_END_DRAW, + ROUND_ALL_HOSTAGES_RESCUED, + ROUND_TARGET_SAVED, + ROUND_HOSTAGE_NOT_RESCUED, + ROUND_TERRORISTS_NOT_ESCAPED, + ROUND_VIP_NOT_ESCAPED, + ROUND_GAME_COMMENCE, + ROUND_GAME_RESTART, + ROUND_GAME_OVER +}; + +enum RewardRules +{ + RR_CTS_WIN, + RR_TERRORISTS_WIN, + RR_TARGET_BOMB, + RR_VIP_ESCAPED, + RR_VIP_ASSASSINATED, + RR_TERRORISTS_ESCAPED, + RR_CTS_PREVENT_ESCAPE, + RR_ESCAPING_TERRORISTS_NEUTRALIZED, + RR_BOMB_DEFUSED, + RR_BOMB_PLANTED, + RR_BOMB_EXPLODED, + RR_ALL_HOSTAGES_RESCUED, + RR_TARGET_BOMB_SAVED, + RR_HOSTAGE_NOT_RESCUED, + RR_VIP_NOT_ESCAPED, + RR_LOSER_BONUS_DEFAULT, + RR_LOSER_BONUS_MIN, + RR_LOSER_BONUS_MAX, + RR_LOSER_BONUS_ADD, + RR_RESCUED_HOSTAGE, + RR_TOOK_HOSTAGE_ACC, + RR_TOOK_HOSTAGE, + RR_END +}; + +// custom enum +enum RewardAccount +{ + REWARD_TARGET_BOMB = 3500, + REWARD_VIP_ESCAPED = 3500, + REWARD_VIP_ASSASSINATED = 3250, + REWARD_TERRORISTS_ESCAPED = 3150, + REWARD_CTS_PREVENT_ESCAPE = 3500, + REWARD_ESCAPING_TERRORISTS_NEUTRALIZED = 3250, + REWARD_BOMB_DEFUSED = 3250, + REWARD_BOMB_PLANTED = 800, + REWARD_BOMB_EXPLODED = 3250, + REWARD_CTS_WIN = 3000, + REWARD_TERRORISTS_WIN = 3000, + REWARD_ALL_HOSTAGES_RESCUED = 2500, + + // the end round was by the expiration time + REWARD_TARGET_BOMB_SAVED = 3250, + REWARD_HOSTAGE_NOT_RESCUED = 3250, + REWARD_VIP_NOT_ESCAPED = 3250, + + // loser bonus + REWARD_LOSER_BONUS_DEFAULT = 1400, + REWARD_LOSER_BONUS_MIN = 1500, + REWARD_LOSER_BONUS_MAX = 3000, + REWARD_LOSER_BONUS_ADD = 500, + + REWARD_RESCUED_HOSTAGE = 750, + REWARD_KILLED_ENEMY = 300, + REWARD_KILLED_VIP = 2500, + REWARD_VIP_HAVE_SELF_RESCUED = 2500, + + REWARD_TAKEN_HOSTAGE = 1000, + REWARD_TOOK_HOSTAGE_ACC = 100, + REWARD_TOOK_HOSTAGE = 150, +}; + +// custom enum +enum PaybackForBadThing +{ + PAYBACK_FOR_KILLED_TEAMMATES = -3300, +}; + +// custom enum +enum InfoMapBuyParam +{ + BUYING_EVERYONE = 0, + BUYING_ONLY_CTS, + BUYING_ONLY_TERRORISTS, + BUYING_NO_ONE, +}; + +// weapon respawning return codes +enum +{ + GR_NONE = 0, + + GR_WEAPON_RESPAWN_YES, + GR_WEAPON_RESPAWN_NO, + + GR_AMMO_RESPAWN_YES, + GR_AMMO_RESPAWN_NO, + + GR_ITEM_RESPAWN_YES, + GR_ITEM_RESPAWN_NO, + + GR_PLR_DROP_GUN_ALL, + GR_PLR_DROP_GUN_ACTIVE, + GR_PLR_DROP_GUN_NO, + + GR_PLR_DROP_AMMO_ALL, + GR_PLR_DROP_AMMO_ACTIVE, + GR_PLR_DROP_AMMO_NO, +}; + +// custom enum +enum +{ + SCENARIO_BLOCK_TIME_EXPRIRED = (1 << 0), // flag "a" + SCENARIO_BLOCK_NEED_PLAYERS = (1 << 1), // flag "b" + SCENARIO_BLOCK_VIP_ESCAPE = (1 << 2), // flag "c" + SCENARIO_BLOCK_PRISON_ESCAPE = (1 << 3), // flag "d" + SCENARIO_BLOCK_BOMB = (1 << 4), // flag "e" + SCENARIO_BLOCK_TEAM_EXTERMINATION = (1 << 5), // flag "f" + SCENARIO_BLOCK_HOSTAGE_RESCUE = (1 << 6), // flag "g" +}; + +// Player relationship return codes +enum +{ + GR_NOTTEAMMATE = 0, + GR_TEAMMATE, + GR_ENEMY, + GR_ALLY, + GR_NEUTRAL, +}; + +enum WeaponIdType +{ + WEAPON_NONE, + WEAPON_P228, + WEAPON_GLOCK, + WEAPON_SCOUT, + WEAPON_HEGRENADE, + WEAPON_XM1014, + WEAPON_C4, + WEAPON_MAC10, + WEAPON_AUG, + WEAPON_SMOKEGRENADE, + WEAPON_ELITE, + WEAPON_FIVESEVEN, + WEAPON_UMP45, + WEAPON_SG550, + WEAPON_GALIL, + WEAPON_FAMAS, + WEAPON_USP, + WEAPON_GLOCK18, + WEAPON_AWP, + WEAPON_MP5N, + WEAPON_M249, + WEAPON_M3, + WEAPON_M4A1, + WEAPON_TMP, + WEAPON_G3SG1, + WEAPON_FLASHBANG, + WEAPON_DEAGLE, + WEAPON_SG552, + WEAPON_AK47, + WEAPON_KNIFE, + WEAPON_P90, + WEAPON_SHIELDGUN = 99 +}; + +enum AutoBuyClassType +{ + AUTOBUYCLASS_NONE = 0, + AUTOBUYCLASS_PRIMARY = (1 << 0), + AUTOBUYCLASS_SECONDARY = (1 << 1), + AUTOBUYCLASS_AMMO = (1 << 2), + AUTOBUYCLASS_ARMOR = (1 << 3), + AUTOBUYCLASS_DEFUSER = (1 << 4), + AUTOBUYCLASS_PISTOL = (1 << 5), + AUTOBUYCLASS_SMG = (1 << 6), + AUTOBUYCLASS_RIFLE = (1 << 7), + AUTOBUYCLASS_SNIPERRIFLE = (1 << 8), + AUTOBUYCLASS_SHOTGUN = (1 << 9), + AUTOBUYCLASS_MACHINEGUN = (1 << 10), + AUTOBUYCLASS_GRENADE = (1 << 11), + AUTOBUYCLASS_NIGHTVISION = (1 << 12), + AUTOBUYCLASS_SHIELD = (1 << 13), +}; + +enum AmmoCostType +{ + AMMO_338MAG_PRICE = 125, + AMMO_357SIG_PRICE = 50, + AMMO_45ACP_PRICE = 25, + AMMO_50AE_PRICE = 40, + AMMO_556MM_PRICE = 60, + AMMO_57MM_PRICE = 50, + AMMO_762MM_PRICE = 80, + AMMO_9MM_PRICE = 20, + AMMO_BUCKSHOT_PRICE = 65, +}; + +// custom enum +// the default amount of ammo that comes with each gun when it spawns +enum ClipGiveDefault +{ + P228_DEFAULT_GIVE = 13, + GLOCK18_DEFAULT_GIVE = 20, + SCOUT_DEFAULT_GIVE = 10, + HEGRENADE_DEFAULT_GIVE = 1, + XM1014_DEFAULT_GIVE = 7, + C4_DEFAULT_GIVE = 1, + MAC10_DEFAULT_GIVE = 30, + AUG_DEFAULT_GIVE = 30, + SMOKEGRENADE_DEFAULT_GIVE = 1, + ELITE_DEFAULT_GIVE = 30, + FIVESEVEN_DEFAULT_GIVE = 20, + UMP45_DEFAULT_GIVE = 25, + SG550_DEFAULT_GIVE = 30, + GALIL_DEFAULT_GIVE = 35, + FAMAS_DEFAULT_GIVE = 25, + USP_DEFAULT_GIVE = 12, + AWP_DEFAULT_GIVE = 10, + MP5NAVY_DEFAULT_GIVE = 30, + M249_DEFAULT_GIVE = 100, + M3_DEFAULT_GIVE = 8, + M4A1_DEFAULT_GIVE = 30, + TMP_DEFAULT_GIVE = 30, + G3SG1_DEFAULT_GIVE = 20, + FLASHBANG_DEFAULT_GIVE = 1, + DEAGLE_DEFAULT_GIVE = 7, + SG552_DEFAULT_GIVE = 30, + AK47_DEFAULT_GIVE = 30, + /*KNIFE_DEFAULT_GIVE = 1,*/ + P90_DEFAULT_GIVE = 50, +}; + +enum ClipSizeType +{ + P228_MAX_CLIP = 13, + GLOCK18_MAX_CLIP = 20, + SCOUT_MAX_CLIP = 10, + XM1014_MAX_CLIP = 7, + MAC10_MAX_CLIP = 30, + AUG_MAX_CLIP = 30, + ELITE_MAX_CLIP = 30, + FIVESEVEN_MAX_CLIP = 20, + UMP45_MAX_CLIP = 25, + SG550_MAX_CLIP = 30, + GALIL_MAX_CLIP = 35, + FAMAS_MAX_CLIP = 25, + USP_MAX_CLIP = 12, + AWP_MAX_CLIP = 10, + MP5N_MAX_CLIP = 30, + M249_MAX_CLIP = 100, + M3_MAX_CLIP = 8, + M4A1_MAX_CLIP = 30, + TMP_MAX_CLIP = 30, + G3SG1_MAX_CLIP = 20, + DEAGLE_MAX_CLIP = 7, + SG552_MAX_CLIP = 30, + AK47_MAX_CLIP = 30, + P90_MAX_CLIP = 50, +}; + +enum WeightWeapon +{ + P228_WEIGHT = 5, + GLOCK18_WEIGHT = 5, + SCOUT_WEIGHT = 30, + HEGRENADE_WEIGHT = 2, + XM1014_WEIGHT = 20, + C4_WEIGHT = 3, + MAC10_WEIGHT = 25, + AUG_WEIGHT = 25, + SMOKEGRENADE_WEIGHT = 1, + ELITE_WEIGHT = 5, + FIVESEVEN_WEIGHT = 5, + UMP45_WEIGHT = 25, + SG550_WEIGHT = 20, + GALIL_WEIGHT = 25, + FAMAS_WEIGHT = 75, + USP_WEIGHT = 5, + AWP_WEIGHT = 30, + MP5NAVY_WEIGHT = 25, + M249_WEIGHT = 25, + M3_WEIGHT = 20, + M4A1_WEIGHT = 25, + TMP_WEIGHT = 25, + G3SG1_WEIGHT = 20, + FLASHBANG_WEIGHT = 1, + DEAGLE_WEIGHT = 7, + SG552_WEIGHT = 25, + AK47_WEIGHT = 25, + P90_WEIGHT = 26, + KNIFE_WEIGHT = 0, +}; + +enum MaxAmmoType +{ + MAX_AMMO_BUCKSHOT = 32, + MAX_AMMO_9MM = 120, + MAX_AMMO_556NATO = 90, + MAX_AMMO_556NATOBOX = 200, + MAX_AMMO_762NATO = 90, + MAX_AMMO_45ACP = 100, + MAX_AMMO_50AE = 35, + MAX_AMMO_338MAGNUM = 30, + MAX_AMMO_57MM = 100, + MAX_AMMO_357SIG = 52, + + // custom + MAX_AMMO_SMOKEGRENADE = 1, + MAX_AMMO_HEGRENADE = 1, + MAX_AMMO_FLASHBANG = 2, +}; + +enum AmmoType +{ + AMMO_NONE, + AMMO_338MAGNUM, + AMMO_762NATO, + AMMO_556NATOBOX, + AMMO_556NATO, + AMMO_BUCKSHOT, + AMMO_45ACP, + AMMO_57MM, + AMMO_50AE, + AMMO_357SIG, + AMMO_9MM, + AMMO_FLASHBANG, + AMMO_HEGRENADE, + AMMO_SMOKEGRENADE, + AMMO_C4, + + AMMO_MAX_TYPES +}; + +enum WeaponClassType +{ + WEAPONCLASS_NONE, + WEAPONCLASS_KNIFE, + WEAPONCLASS_PISTOL, + WEAPONCLASS_GRENADE, + WEAPONCLASS_SUBMACHINEGUN, + WEAPONCLASS_SHOTGUN, + WEAPONCLASS_MACHINEGUN, + WEAPONCLASS_RIFLE, + WEAPONCLASS_SNIPERRIFLE, + WEAPONCLASS_MAX, +}; + +enum AmmoBuyAmount +{ + AMMO_338MAG_BUY = 10, + AMMO_357SIG_BUY = 13, + AMMO_45ACP_BUY = 12, + AMMO_50AE_BUY = 7, + AMMO_556NATO_BUY = 30, + AMMO_556NATOBOX_BUY = 30, + AMMO_57MM_BUY = 50, + AMMO_762NATO_BUY = 30, + AMMO_9MM_BUY = 30, + AMMO_BUCKSHOT_BUY = 8, +}; + +enum shieldgun_e +{ + SHIELDGUN_IDLE, + SHIELDGUN_SHOOT1, + SHIELDGUN_SHOOT2, + SHIELDGUN_SHOOT_EMPTY, + SHIELDGUN_RELOAD, + SHIELDGUN_DRAW, + SHIELDGUN_DRAWN_IDLE, + SHIELDGUN_UP, + SHIELDGUN_DOWN, +}; + +// custom +enum shieldgren_e +{ + SHIELDREN_IDLE = 4, + SHIELDREN_UP, + SHIELDREN_DOWN +}; + +enum InventorySlotType +{ + NONE_SLOT, + PRIMARY_WEAPON_SLOT, + PISTOL_SLOT, + KNIFE_SLOT, + GRENADE_SLOT, + C4_SLOT, +}; + +enum Bullet +{ + BULLET_NONE, + BULLET_PLAYER_9MM, + BULLET_PLAYER_MP5, + BULLET_PLAYER_357, + BULLET_PLAYER_BUCKSHOT, + BULLET_PLAYER_CROWBAR, + BULLET_MONSTER_9MM, + BULLET_MONSTER_MP5, + BULLET_MONSTER_12MM, + BULLET_PLAYER_45ACP, + BULLET_PLAYER_338MAG, + BULLET_PLAYER_762MM, + BULLET_PLAYER_556MM, + BULLET_PLAYER_50AE, + BULLET_PLAYER_57MM, + BULLET_PLAYER_357SIG, +}; + +struct WeaponStruct +{ + int m_type; + int m_price; + int m_side; + int m_slot; + int m_ammoPrice; +}; + +struct AutoBuyInfoStruct +{ + AutoBuyClassType m_class; + char *m_command; + char *m_classname; +}; + +struct WeaponAliasInfo +{ + char *alias; + WeaponIdType id; +}; + +struct WeaponBuyAliasInfo +{ + char *alias; + WeaponIdType id; + char *failName; +}; + +struct WeaponClassAliasInfo +{ + char *alias; + WeaponClassType id; +}; + +struct WeaponSlotInfo +{ + WeaponIdType id; + InventorySlotType slot; + const char *weaponName; +}; + +enum hash_types_e { CLASSNAME }; \ No newline at end of file diff --git a/public/resdk/cstrike/regamedll_interfaces.h b/public/resdk/cstrike/regamedll_interfaces.h new file mode 100644 index 00000000..cf49c325 --- /dev/null +++ b/public/resdk/cstrike/regamedll_interfaces.h @@ -0,0 +1,303 @@ +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +* +*/ + +#pragma once + +#include "regamedll_const.h" + +class CBaseEntity; +class CBasePlayer; + +// Implementation wrapper +class CCSEntity { +public: + virtual ~CCSEntity() {} + virtual void FireBullets(int iShots, Vector &vecSrc, Vector &vecDirShooting, Vector &vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker); + virtual Vector FireBullets3(Vector &vecSrc, Vector &vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand); +public: + CBaseEntity *m_pContainingEntity; +}; + +class CCSDelay: public CCSEntity {}; +class CCSAnimating: public CCSDelay {}; +class CCSPlayerItem: public CCSAnimating {}; +class CCSToggle: public CCSAnimating {}; +class CCSMonster: public CCSToggle {}; +class CCSWeaponBox: public CCSEntity {}; +class CCSArmoury: public CCSEntity {}; + +class CCSPlayer: public CCSMonster { +public: + CCSPlayer() : m_bForceShowMenu(false) + { + m_szModel[0] = '\0'; + } + + virtual bool IsConnected() const; + virtual void SetAnimation(PLAYER_ANIM playerAnim); + virtual void AddAccount(int amount, RewardType type = RT_NONE, bool bTrackChange = true); + virtual CBaseEntity *GiveNamedItem(const char *pszName); + virtual CBaseEntity *GiveNamedItemEx(const char *pszName); + virtual void GiveDefaultItems(); + virtual void GiveShield(bool bDeploy = true); + virtual void DropShield(bool bDeploy = true); + virtual void DropPlayerItem(const char *pszItemName); + virtual void RemoveShield(); + virtual void RemoveAllItems(bool bRemoveSuit); + virtual bool RemovePlayerItem(const char* pszItemName); + virtual void SetPlayerModel(bool bHasC4); + virtual void SetPlayerModelEx(const char *modelName); + virtual void SetNewPlayerModel(const char *modelName); + virtual void ClientCommand(const char *cmd, const char *arg1 = nullptr, const char *arg2 = nullptr, const char *arg3 = nullptr); + virtual void SetProgressBarTime(int time); + virtual void SetProgressBarTime2(int time, float timeElapsed); + virtual struct edict_s *EntSelectSpawnPoint(); + virtual void SetBombIcon(bool bFlash = false); + virtual void SetScoreAttrib(CBasePlayer *dest); + virtual void SendItemStatus(); + virtual void ReloadWeapons(CBasePlayerItem *pWeapon = nullptr, bool bForceReload = false, bool bForceRefill = false); + virtual void Observer_SetMode(int iMode); + virtual bool SelectSpawnSpot(const char *pEntClassName, CBaseEntity* &pSpot); + virtual bool SwitchWeapon(CBasePlayerItem *pWeapon); + virtual void SwitchTeam(); + virtual bool JoinTeam(TeamName team); + virtual void StartObserver(Vector& vecPosition, Vector& vecViewAngle); + virtual void TeamChangeUpdate(); + virtual void DropSecondary(); + virtual void DropPrimary(); + virtual bool HasPlayerItem(CBasePlayerItem *pCheckItem); + virtual bool HasNamedPlayerItem(const char *pszItemName); + virtual CBasePlayerItem *GetItemById(WeaponIdType weaponID); + virtual CBasePlayerItem *GetItemByName(const char *itemName); + virtual void Disappear(); + virtual void MakeVIP(); + virtual bool MakeBomber(); + + CBasePlayer *BasePlayer() const; +public: + char m_szModel[32]; + bool m_bForceShowMenu; +}; + +class CAPI_Bot: public CCSPlayer {}; +class CAPI_CSBot: public CAPI_Bot {}; +class CCSShield: public CCSEntity {}; +class CCSDeadHEV: public CCSMonster {}; +class CCSSprayCan: public CCSEntity {}; +class CCSBloodSplat: public CCSEntity {}; +class CCSPlayerWeapon: public CCSPlayerItem {}; +class CCSWorld: public CCSEntity {}; +class CCSDecal: public CCSEntity {}; +class CCSCorpse: public CCSEntity {}; +class CCSGrenade: public CCSMonster {}; +class CCSAirtank: public CCSGrenade {}; +class CCSPlayerAmmo: public CCSEntity {}; +class CCS9MMAmmo: public CCSPlayerAmmo {}; +class CCSBuckShotAmmo: public CCSPlayerAmmo {}; +class CCS556NatoAmmo: public CCSPlayerAmmo {}; +class CCS556NatoBoxAmmo: public CCSPlayerAmmo {}; +class CCS762NatoAmmo: public CCSPlayerAmmo {}; +class CCS45ACPAmmo: public CCSPlayerAmmo {}; +class CCS50AEAmmo: public CCSPlayerAmmo {}; +class CCS338MagnumAmmo: public CCSPlayerAmmo {}; +class CCS57MMAmmo: public CCSPlayerAmmo {}; +class CCS357SIGAmmo: public CCSPlayerAmmo {}; +class CCSFuncWall: public CCSEntity {}; +class CCSFuncWallToggle: public CCSFuncWall {}; +class CCSFuncConveyor: public CCSFuncWall {}; +class CCSFuncIllusionary: public CCSToggle {}; +class CCSFuncMonsterClip: public CCSFuncWall {}; +class CCSFuncRotating: public CCSEntity {}; +class CCSPendulum: public CCSEntity {}; +class CCSPointEntity: public CCSEntity {}; +class CCSStripWeapons: public CCSPointEntity {}; +class CCSInfoIntermission: public CCSPointEntity {}; +class CCSRevertSaved: public CCSPointEntity {}; +class CCSEnvGlobal: public CCSPointEntity {}; +class CCSMultiSource: public CCSPointEntity {}; +class CCSButton: public CCSToggle {}; +class CCSRotButton: public CCSButton {}; +class CCSMomentaryRotButton: public CCSToggle {}; +class CCSEnvSpark: public CCSEntity {}; +class CCSButtonTarget: public CCSEntity {}; +class CCSDoor: public CCSToggle {}; +class CCSRotDoor: public CCSDoor {}; +class CCSMomentaryDoor: public CCSToggle {}; +class CCSGib: public CCSEntity {}; +class CCSBubbling: public CCSEntity {}; +class CCSBeam: public CCSEntity {}; +class CCSLightning: public CCSBeam {}; +class CCSLaser: public CCSBeam {}; +class CCSGlow: public CCSPointEntity {}; +class CCSSprite: public CCSPointEntity {}; +class CCSBombGlow: public CCSSprite {}; +class CCSGibShooter: public CCSDelay {}; +class CCSEnvShooter: public CCSGibShooter {}; +class CCSTestEffect: public CCSDelay {}; +class CCSBlood: public CCSPointEntity {}; +class CCSShake: public CCSPointEntity {}; +class CCSFade: public CCSPointEntity {}; +class CCSMessage: public CCSPointEntity {}; +class CCSEnvFunnel: public CCSDelay {}; +class CCSEnvBeverage: public CCSDelay {}; +class CCSItemSoda: public CCSEntity {}; +class CCSShower: public CCSEntity {}; +class CCSEnvExplosion: public CCSMonster {}; +class CCSBreakable: public CCSDelay {}; +class CCSPushable: public CCSBreakable {}; +class CCSFuncTank: public CCSEntity {}; +class CCSFuncTankGun: public CCSFuncTank {}; +class CCSFuncTankLaser: public CCSFuncTank {}; +class CCSFuncTankRocket: public CCSFuncTank {}; +class CCSFuncTankMortar: public CCSFuncTank {}; +class CCSFuncTankControls: public CCSEntity {}; +class CCSRecharge: public CCSToggle {}; +class CCSCycler: public CCSMonster {}; +class CCSGenericCycler: public CCSCycler {}; +class CCSCyclerProbe: public CCSCycler {}; +class CCSCyclerSprite: public CCSEntity {}; +class CCSWeaponCycler: public CCSPlayerWeapon {}; +class CCSWreckage: public CCSMonster {}; +class CCSWorldItem: public CCSEntity {}; +class CCSItem: public CCSEntity {}; +class CCSHealthKit: public CCSItem {}; +class CCSWallHealth: public CCSToggle {}; +class CCSItemSuit: public CCSItem {}; +class CCSItemBattery: public CCSItem {}; +class CCSItemAntidote: public CCSItem {}; +class CCSItemSecurity: public CCSItem {}; +class CCSItemLongJump: public CCSItem {}; +class CCSItemKevlar: public CCSItem {}; +class CCSItemAssaultSuit: public CCSItem {}; +class CCSItemThighPack: public CCSItem {}; +class CCSGrenCatch: public CCSEntity {}; +class CCSFuncWeaponCheck: public CCSEntity {}; +class CCSHostage: public CCSMonster {}; +class CCSLight: public CCSPointEntity {}; +class CCSEnvLight: public CCSLight {}; +class CCSRuleEntity: public CCSEntity {}; +class CCSRulePointEntity: public CCSRuleEntity {}; +class CCSRuleBrushEntity: public CCSRuleEntity {}; +class CCSGameScore: public CCSRulePointEntity {}; +class CCSGameEnd: public CCSRulePointEntity {}; +class CCSGameText: public CCSRulePointEntity {}; +class CCSGameTeamMaster: public CCSRulePointEntity {}; +class CCSGameTeamSet: public CCSRulePointEntity {}; +class CCSGamePlayerZone: public CCSRuleBrushEntity {}; +class CCSGamePlayerHurt: public CCSRulePointEntity {}; +class CCSGameCounter: public CCSRulePointEntity {}; +class CCSGameCounterSet: public CCSRulePointEntity {}; +class CCSGamePlayerEquip: public CCSRulePointEntity {}; +class CCSGamePlayerTeam: public CCSRulePointEntity {}; +class CCSFuncMortarField: public CCSToggle {}; +class CCSMortar: public CCSGrenade {}; +class CCSMapInfo: public CCSPointEntity {}; +class CCSPathCorner: public CCSPointEntity {}; +class CCSPathTrack: public CCSPointEntity {}; +class CCSFuncTrackTrain: public CCSEntity {}; +class CCSFuncVehicleControls: public CCSEntity {}; +class CCSFuncVehicle: public CCSEntity {}; +class CCSPlatTrain: public CCSToggle {}; +class CCSFuncPlat: public CCSPlatTrain {}; +class CCSPlatTrigger: public CCSEntity {}; +class CCSFuncPlatRot: public CCSFuncPlat {}; +class CCSFuncTrain: public CCSPlatTrain {}; +class CCSFuncTrainControls: public CCSEntity {}; +class CCSFuncTrackChange: public CCSFuncPlatRot {}; +class CCSFuncTrackAuto: public CCSFuncTrackChange {}; +class CCSGunTarget: public CCSMonster {}; +class CCSAmbientGeneric: public CCSEntity {}; +class CCSEnvSound: public CCSPointEntity {}; +class CCSSpeaker: public CCSEntity {}; +class CCSSoundEnt: public CCSEntity {}; +class CCSUSP: public CCSPlayerWeapon {}; +class CCSMP5N: public CCSPlayerWeapon {}; +class CCSSG552: public CCSPlayerWeapon {}; +class CCSAK47: public CCSPlayerWeapon {}; +class CCSAUG: public CCSPlayerWeapon {}; +class CCSAWP: public CCSPlayerWeapon {}; +class CCSC4: public CCSPlayerWeapon {}; +class CCSDEAGLE: public CCSPlayerWeapon {}; +class CCSFlashbang: public CCSPlayerWeapon {}; +class CCSG3SG1: public CCSPlayerWeapon {}; +class CCSGLOCK18: public CCSPlayerWeapon {}; +class CCSHEGrenade: public CCSPlayerWeapon {}; +class CCSKnife: public CCSPlayerWeapon {}; +class CCSM249: public CCSPlayerWeapon {}; +class CCSM3: public CCSPlayerWeapon {}; +class CCSM4A1: public CCSPlayerWeapon {}; +class CCSMAC10: public CCSPlayerWeapon {}; +class CCSP228: public CCSPlayerWeapon {}; +class CCSP90: public CCSPlayerWeapon {}; +class CCSSCOUT: public CCSPlayerWeapon {}; +class CCSSmokeGrenade: public CCSPlayerWeapon {}; +class CCSTMP: public CCSPlayerWeapon {}; +class CCSXM1014: public CCSPlayerWeapon {}; +class CCSELITE: public CCSPlayerWeapon {}; +class CCSFiveSeven: public CCSPlayerWeapon {}; +class CCSUMP45: public CCSPlayerWeapon {}; +class CCSSG550: public CCSPlayerWeapon {}; +class CCSGalil: public CCSPlayerWeapon {}; +class CCSFamas: public CCSPlayerWeapon {}; +class CCSNullEntity: public CCSEntity {}; +class CCSDMStart: public CCSPointEntity {}; +class CCSFrictionModifier: public CCSEntity {}; +class CCSAutoTrigger: public CCSDelay {}; +class CCSTriggerRelay: public CCSDelay {}; +class CCSMultiManager: public CCSToggle {}; +class CCSRenderFxManager: public CCSEntity {}; +class CCSTrigger: public CCSToggle {}; +class CCSTriggerHurt: public CCSTrigger {}; +class CCSTriggerMonsterJump: public CCSTrigger {}; +class CCSTriggerCDAudio: public CCSTrigger {}; +class CCSTargetCDAudio: public CCSPointEntity {}; +class CCSTriggerMultiple: public CCSTrigger {}; +class CCSTriggerOnce: public CCSTriggerMultiple {}; +class CCSTriggerCounter: public CCSTrigger {}; +class CCSTriggerVolume: public CCSPointEntity {}; +class CCSFireAndDie: public CCSDelay {}; +class CCSChangeLevel: public CCSTrigger {}; +class CCSLadder: public CCSTrigger {}; +class CCSTriggerPush: public CCSTrigger {}; +class CCSTriggerTeleport: public CCSTrigger {}; +class CCSBuyZone: public CCSTrigger {}; +class CCSBombTarget: public CCSTrigger {}; +class CCSHostageRescue: public CCSTrigger {}; +class CCSEscapeZone: public CCSTrigger {}; +class CCSVIP_SafetyZone: public CCSTrigger {}; +class CCSTriggerSave: public CCSTrigger {}; +class CCSTriggerEndSection: public CCSTrigger {}; +class CCSTriggerGravity: public CCSTrigger {}; +class CCSTriggerChangeTarget: public CCSDelay {}; +class CCSTriggerCamera: public CCSDelay {}; +class CCSWeather: public CCSTrigger {}; +class CCSClientFog: public CCSEntity {}; + +inline CBasePlayer *CCSPlayer::BasePlayer() const { + return reinterpret_cast(this->m_pContainingEntity); +} diff --git a/public/resdk/engine/FlightRecorder.h b/public/resdk/engine/FlightRecorder.h new file mode 100644 index 00000000..01243b83 --- /dev/null +++ b/public/resdk/engine/FlightRecorder.h @@ -0,0 +1,61 @@ +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +* +*/ +#pragma once + +#include + +class IRehldsFlightRecorder +{ +public: + virtual ~IRehldsFlightRecorder() { } + + virtual uint16 RegisterMessage(const char* module, const char *message, unsigned int version, bool inOut) = 0; + + virtual void StartMessage(uint16 msg, bool entrance) = 0; + virtual void EndMessage(uint16 msg, bool entrance) = 0; + + virtual void WriteInt8(int8 v) = 0; + virtual void WriteUInt8(uint8 v) = 0; + + virtual void WriteInt16(int16 v) = 0; + virtual void WriteUInt16(uint16 v) = 0; + + virtual void WriteInt32(int32 v) = 0; + virtual void WriteUInt32(uint32 v) = 0; + + virtual void WriteInt64(int64 v) = 0; + virtual void WriteUInt64(uint64 v) = 0; + + virtual void WriteFloat(float v) = 0; + virtual void WriteDouble(double v) = 0; + + virtual void WriteString(const char* s) = 0; + + virtual void WriteBuffer(const void* data ,unsigned int len) = 0; + +}; diff --git a/public/resdk/engine/cmd_rehlds.h b/public/resdk/engine/cmd_rehlds.h new file mode 100644 index 00000000..7660e561 --- /dev/null +++ b/public/resdk/engine/cmd_rehlds.h @@ -0,0 +1,47 @@ +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +* +*/ +#pragma once + +typedef void(*xcommand_t)(void); +typedef struct cmd_function_s +{ + struct cmd_function_s *next; + char *name; + xcommand_t function; + int flags; +} cmd_function_t; + +typedef enum cmd_source_s +{ + src_client = 0, // came in over a net connection as a clc_stringcmd. host_client will be valid during this state. + src_command = 1, // from the command buffer. +} cmd_source_t; + +#define FCMD_HUD_COMMAND BIT(0) +#define FCMD_GAME_COMMAND BIT(1) +#define FCMD_WRAPPER_COMMAND BIT(2) diff --git a/public/resdk/engine/rehlds_api.h b/public/resdk/engine/rehlds_api.h new file mode 100644 index 00000000..a6d8ebb3 --- /dev/null +++ b/public/resdk/engine/rehlds_api.h @@ -0,0 +1,300 @@ +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +* +*/ +#pragma once + +#include +#include +#include "cmd_rehlds.h" +#include "rehlds_interfaces.h" +#include "FlightRecorder.h" +#include "../common/hookchains.h" + +#define REHLDS_API_VERSION_MAJOR 3 +#define REHLDS_API_VERSION_MINOR 0 + +//Steam_NotifyClientConnect hook +typedef IHookChain IRehldsHook_Steam_NotifyClientConnect; +typedef IHookChainRegistry IRehldsHookRegistry_Steam_NotifyClientConnect; + +//SV_ConnectClient hook +typedef IVoidHookChain<> IRehldsHook_SV_ConnectClient; +typedef IVoidHookChainRegistry<> IRehldsHookRegistry_SV_ConnectClient; + +//SV_GetIDString hook +typedef IHookChain IRehldsHook_SV_GetIDString; +typedef IHookChainRegistry IRehldsHookRegistry_SV_GetIDString; + +//SV_SendServerinfo hook +typedef IVoidHookChain IRehldsHook_SV_SendServerinfo; +typedef IVoidHookChainRegistry IRehldsHookRegistry_SV_SendServerinfo; + +//SV_CheckProtocol hook +typedef IHookChain IRehldsHook_SV_CheckProtocol; +typedef IHookChainRegistry IRehldsHookRegistry_SV_CheckProtocol; + +//SVC_GetChallenge_mod hook +typedef IVoidHookChain IRehldsHook_SVC_GetChallenge_mod; +typedef IVoidHookChainRegistry IRehldsHookRegistry_SVC_GetChallenge_mod; + +//SV_CheckKeyInfo hook +typedef IHookChain IRehldsHook_SV_CheckKeyInfo; +typedef IHookChainRegistry IRehldsHookRegistry_SV_CheckKeyInfo; + +//SV_CheckIPRestrictions hook +typedef IHookChain IRehldsHook_SV_CheckIPRestrictions; +typedef IHookChainRegistry IRehldsHookRegistry_SV_CheckIPRestrictions; + +//SV_FinishCertificateCheck hook +typedef IHookChain IRehldsHook_SV_FinishCertificateCheck; +typedef IHookChainRegistry IRehldsHookRegistry_SV_FinishCertificateCheck; + +//Steam_NotifyBotConnect hook +typedef IHookChain IRehldsHook_Steam_NotifyBotConnect; +typedef IHookChainRegistry IRehldsHookRegistry_Steam_NotifyBotConnect; + +//SerializeSteamId +typedef IVoidHookChain IRehldsHook_SerializeSteamId; +typedef IVoidHookChainRegistry IRehldsHookRegistry_SerializeSteamId; + +//SV_CompareUserID hook +typedef IHookChain IRehldsHook_SV_CompareUserID; +typedef IHookChainRegistry IRehldsHookRegistry_SV_CompareUserID; + +//Steam_NotifyClientDisconnect +typedef IVoidHookChain IRehldsHook_Steam_NotifyClientDisconnect; +typedef IVoidHookChainRegistry IRehldsHookRegistry_Steam_NotifyClientDisconnect; + +//PreProcessPacket +typedef IHookChain IRehldsHook_PreprocessPacket; +typedef IHookChainRegistry IRehldsHookRegistry_PreprocessPacket; + +//ValidateCommand +typedef IHookChain IRehldsHook_ValidateCommand; +typedef IHookChainRegistry IRehldsHookRegistry_ValidateCommand; + +//ExecuteServerStringCmd +typedef IVoidHookChain IRehldsHook_ExecuteServerStringCmd; +typedef IVoidHookChainRegistry IRehldsHookRegistry_ExecuteServerStringCmd; + +//ClientConnected +typedef IVoidHookChain IRehldsHook_ClientConnected; +typedef IVoidHookChainRegistry IRehldsHookRegistry_ClientConnected; + +//HandleNetCommand +typedef IVoidHookChain IRehldsHook_HandleNetCommand; +typedef IVoidHookChainRegistry IRehldsHookRegistry_HandleNetCommand; + +//Mod_LoadBrushModel +typedef IVoidHookChain IRehldsHook_Mod_LoadBrushModel; +typedef IVoidHookChainRegistry IRehldsHookRegistry_Mod_LoadBrushModel; + +//Mod_LoadStudioModel +typedef IVoidHookChain IRehldsHook_Mod_LoadStudioModel; +typedef IVoidHookChainRegistry IRehldsHookRegistry_Mod_LoadStudioModel; + +//SV_EmitEvents hook +typedef IVoidHookChain IRehldsHook_SV_EmitEvents; +typedef IVoidHookChainRegistry IRehldsHookRegistry_SV_EmitEvents; + +//EV_PlayReliableEvent hook +typedef IVoidHookChain IRehldsHook_EV_PlayReliableEvent; +typedef IVoidHookChainRegistry IRehldsHookRegistry_EV_PlayReliableEvent; + +//SV_StartSound hook +typedef IVoidHookChain IRehldsHook_SV_StartSound; +typedef IVoidHookChainRegistry IRehldsHookRegistry_SV_StartSound; + +//PF_Remove_I hook +typedef IVoidHookChain IRehldsHook_PF_Remove_I; +typedef IVoidHookChainRegistry IRehldsHookRegistry_PF_Remove_I; + +//PF_BuildSoundMsg_I hook +typedef IVoidHookChain IRehldsHook_PF_BuildSoundMsg_I; +typedef IVoidHookChainRegistry IRehldsHookRegistry_PF_BuildSoundMsg_I; + +//SV_WriteFullClientUpdate hook +typedef IVoidHookChain IRehldsHook_SV_WriteFullClientUpdate; +typedef IVoidHookChainRegistry IRehldsHookRegistry_SV_WriteFullClientUpdate; + +//SV_CheckConsistencyResponse hook +typedef IHookChain IRehldsHook_SV_CheckConsistencyResponse; +typedef IHookChainRegistry IRehldsHookRegistry_SV_CheckConsistencyResponse; + +//SV_DropClient hook +typedef IVoidHookChain IRehldsHook_SV_DropClient; +typedef IVoidHookChainRegistry IRehldsHookRegistry_SV_DropClient; + +//SV_ActivateServer hook +typedef IVoidHookChain IRehldsHook_SV_ActivateServer; +typedef IVoidHookChainRegistry IRehldsHookRegistry_SV_ActivateServer; + +//SV_WriteVoiceCodec hook +typedef IVoidHookChain IRehldsHook_SV_WriteVoiceCodec; +typedef IVoidHookChainRegistry IRehldsHookRegistry_SV_WriteVoiceCodec; + +//Steam_GSGetSteamID hook +typedef IHookChain IRehldsHook_Steam_GSGetSteamID; +typedef IHookChainRegistry IRehldsHookRegistry_Steam_GSGetSteamID; + +//SV_TransferConsistencyInfo hook +typedef IHookChain IRehldsHook_SV_TransferConsistencyInfo; +typedef IHookChainRegistry IRehldsHookRegistry_SV_TransferConsistencyInfo; + +//Steam_GSBUpdateUserData hook +typedef IHookChain IRehldsHook_Steam_GSBUpdateUserData; +typedef IHookChainRegistry IRehldsHookRegistry_Steam_GSBUpdateUserData; + +//Cvar_DirectSet hook +typedef IVoidHookChain IRehldsHook_Cvar_DirectSet; +typedef IVoidHookChainRegistry IRehldsHookRegistry_Cvar_DirectSet; + +//SV_EstablishTimeBase hook +typedef IVoidHookChain IRehldsHook_SV_EstablishTimeBase; +typedef IVoidHookChainRegistry IRehldsHookRegistry_SV_EstablishTimeBase; + +//SV_Spawn_f hook +typedef IVoidHookChain<> IRehldsHook_SV_Spawn_f; +typedef IVoidHookChainRegistry<> IRehldsHookRegistry_SV_Spawn_f; + +//SV_CreatePacketEntities hook +typedef IHookChain IRehldsHook_SV_CreatePacketEntities; +typedef IHookChainRegistry IRehldsHookRegistry_SV_CreatePacketEntities; + +//SV_EmitSound2 hook +typedef IHookChain IRehldsHook_SV_EmitSound2; +typedef IHookChainRegistry IRehldsHookRegistry_SV_EmitSound2; + +class IRehldsHookchains { +public: + virtual ~IRehldsHookchains() { } + + virtual IRehldsHookRegistry_Steam_NotifyClientConnect* Steam_NotifyClientConnect() = 0; + virtual IRehldsHookRegistry_SV_ConnectClient* SV_ConnectClient() = 0; + virtual IRehldsHookRegistry_SV_GetIDString* SV_GetIDString() = 0; + virtual IRehldsHookRegistry_SV_SendServerinfo* SV_SendServerinfo() = 0; + virtual IRehldsHookRegistry_SV_CheckProtocol* SV_CheckProtocol() = 0; + virtual IRehldsHookRegistry_SVC_GetChallenge_mod* SVC_GetChallenge_mod() = 0; + virtual IRehldsHookRegistry_SV_CheckKeyInfo* SV_CheckKeyInfo() = 0; + virtual IRehldsHookRegistry_SV_CheckIPRestrictions* SV_CheckIPRestrictions() = 0; + virtual IRehldsHookRegistry_SV_FinishCertificateCheck* SV_FinishCertificateCheck() = 0; + virtual IRehldsHookRegistry_Steam_NotifyBotConnect* Steam_NotifyBotConnect() = 0; + virtual IRehldsHookRegistry_SerializeSteamId* SerializeSteamId() = 0; + virtual IRehldsHookRegistry_SV_CompareUserID* SV_CompareUserID() = 0; + virtual IRehldsHookRegistry_Steam_NotifyClientDisconnect* Steam_NotifyClientDisconnect() = 0; + virtual IRehldsHookRegistry_PreprocessPacket* PreprocessPacket() = 0; + virtual IRehldsHookRegistry_ValidateCommand* ValidateCommand() = 0; + virtual IRehldsHookRegistry_ClientConnected* ClientConnected() = 0; + virtual IRehldsHookRegistry_HandleNetCommand* HandleNetCommand() = 0; + virtual IRehldsHookRegistry_Mod_LoadBrushModel* Mod_LoadBrushModel() = 0; + virtual IRehldsHookRegistry_Mod_LoadStudioModel* Mod_LoadStudioModel() = 0; + virtual IRehldsHookRegistry_ExecuteServerStringCmd* ExecuteServerStringCmd() = 0; + virtual IRehldsHookRegistry_SV_EmitEvents* SV_EmitEvents() = 0; + virtual IRehldsHookRegistry_EV_PlayReliableEvent* EV_PlayReliableEvent() = 0; + virtual IRehldsHookRegistry_SV_StartSound* SV_StartSound() = 0; + virtual IRehldsHookRegistry_PF_Remove_I* PF_Remove_I() = 0; + virtual IRehldsHookRegistry_PF_BuildSoundMsg_I* PF_BuildSoundMsg_I() = 0; + virtual IRehldsHookRegistry_SV_WriteFullClientUpdate* SV_WriteFullClientUpdate() = 0; + virtual IRehldsHookRegistry_SV_CheckConsistencyResponse* SV_CheckConsistencyResponse() = 0; + virtual IRehldsHookRegistry_SV_DropClient* SV_DropClient() = 0; + virtual IRehldsHookRegistry_SV_ActivateServer* SV_ActivateServer() = 0; + virtual IRehldsHookRegistry_SV_WriteVoiceCodec* SV_WriteVoiceCodec() = 0; + virtual IRehldsHookRegistry_Steam_GSGetSteamID* Steam_GSGetSteamID() = 0; + virtual IRehldsHookRegistry_SV_TransferConsistencyInfo* SV_TransferConsistencyInfo() = 0; + virtual IRehldsHookRegistry_Steam_GSBUpdateUserData* Steam_GSBUpdateUserData() = 0; + virtual IRehldsHookRegistry_Cvar_DirectSet* Cvar_DirectSet() = 0; + virtual IRehldsHookRegistry_SV_EstablishTimeBase* SV_EstablishTimeBase() = 0; + virtual IRehldsHookRegistry_SV_Spawn_f* SV_Spawn_f() = 0; + virtual IRehldsHookRegistry_SV_CreatePacketEntities* SV_CreatePacketEntities() = 0; + virtual IRehldsHookRegistry_SV_EmitSound2* SV_EmitSound2() = 0; +}; + +struct RehldsFuncs_t { + void(*DropClient)(IGameClient* cl, bool crash, const char* fmt, ...); + void(*RejectConnection)(netadr_t *adr, char *fmt, ...); + qboolean(*SteamNotifyBotConnect)(IGameClient* cl); + sizebuf_t*(*GetNetMessage)(); + IGameClient*(*GetHostClient)(); + int*(*GetMsgReadCount)(); + qboolean(*FilterUser)(USERID_t*); + void(*NET_SendPacket)(unsigned int length, void *data, const netadr_t &to); + void(*TokenizeString)(char* s); + bool(*CheckChallenge)(const netadr_t& adr, int challenge); + void(*SendUserReg)(sizebuf_t* msg); + void(*WriteDeltaDescriptionsToClient)(sizebuf_t* msg); + void(*SetMoveVars)(); + void(*WriteMovevarsToClient)(sizebuf_t* msg); + char*(*GetClientFallback)(); + int*(*GetAllowCheats)(); + bool(*GSBSecure)(); + int(*GetBuildNumber)(); + double(*GetRealTime)(); + int*(*GetMsgBadRead)(); + cmd_source_t*(*GetCmdSource)(); + void(*Log)(const char* prefix, const char* msg); + DLL_FUNCTIONS *(*GetEntityInterface)(); + void(*EV_PlayReliableEvent)(IGameClient *cl, int entindex, unsigned short eventindex, float delay, struct event_args_s *pargs); + int(*SV_LookupSoundIndex)(const char *sample); + void(*MSG_StartBitWriting)(sizebuf_t *buf); + void(*MSG_WriteBits)(uint32 data, int numbits); + void(*MSG_WriteBitVec3Coord)(const float *fa); + void(*MSG_EndBitWriting)(sizebuf_t *buf); + void*(*SZ_GetSpace)(sizebuf_t *buf, int length); + cvar_t*(*GetCvarVars)(); + int (*SV_GetChallenge)(const netadr_t& adr); + void (*SV_AddResource)(resourcetype_t type, const char *name, int size, unsigned char flags, int index); + int(*MSG_ReadShort)(void); + int(*MSG_ReadBuf)(int iSize, void *pbuf); + void(*MSG_WriteBuf)(sizebuf_t *sb, int iSize, void *buf); + void(*MSG_WriteByte)(sizebuf_t *sb, int c); + void(*MSG_WriteShort)(sizebuf_t *sb, int c); + void(*MSG_WriteString)(sizebuf_t *sb, const char *s); + void*(*GetPluginApi)(const char *name); + void(*RegisterPluginApi)(const char *name, void *impl); + qboolean(*SV_FileInConsistencyList)(const char *filename, struct consistency_s **ppconsist); + qboolean(*Steam_NotifyClientConnect)(IGameClient *cl, const void *pvSteam2Key, unsigned int ucbSteam2Key); + void(*Steam_NotifyClientDisconnect)(IGameClient* cl); + void(*SV_StartSound)(int recipients, edict_t *entity, int channel, const char *sample, int volume, float attenuation, int flags, int pitch); + bool(*SV_EmitSound2)(edict_t *entity, IGameClient *receiver, int channel, const char *sample, float volume, float attenuation, int flags, int pitch, int emitFlags, const float *pOrigin); + void(*SV_UpdateUserInfo)(IGameClient *pGameClient); + bool(*StripUnprintableAndSpace)(char *pch); +}; + +class IRehldsApi { +public: + virtual ~IRehldsApi() { } + + virtual int GetMajorVersion() = 0; + virtual int GetMinorVersion() = 0; + virtual const RehldsFuncs_t* GetFuncs() = 0; + virtual IRehldsHookchains* GetHookchains() = 0; + virtual IRehldsServerStatic* GetServerStatic() = 0; + virtual IRehldsServerData* GetServerData() = 0; + virtual IRehldsFlightRecorder* GetFlightRecorder() = 0; +}; + +#define VREHLDS_HLDS_API_VERSION "VREHLDS_HLDS_API_VERSION001" \ No newline at end of file diff --git a/public/resdk/engine/rehlds_interfaces.h b/public/resdk/engine/rehlds_interfaces.h new file mode 100644 index 00000000..4ad70346 --- /dev/null +++ b/public/resdk/engine/rehlds_interfaces.h @@ -0,0 +1,109 @@ +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +* +*/ +#pragma once + +class INetChan; +class IGameClient; + +#include +#include + +class INetChan; +class IGameClient; + +class IGameClient { +public: + virtual int GetId() = 0; + + virtual bool IsActive() = 0; + virtual void SetActive(bool active) = 0; + + virtual bool IsSpawned() = 0; + virtual void SetSpawned(bool spawned) = 0; + + virtual INetChan* GetNetChan() = 0; + + virtual sizebuf_t* GetDatagram() = 0; + + virtual edict_t* GetEdict() = 0; + + virtual USERID_t* GetNetworkUserID() = 0; + + virtual const char* GetName() = 0; + + virtual bool IsConnected() = 0; + virtual void SetConnected(bool connected) = 0; + + virtual uint32 GetVoiceStream(int stream_id) = 0; + virtual void SetLastVoiceTime(double time) = 0; + virtual double GetLastVoiceTime() = 0; + virtual bool GetLoopback() = 0; + virtual struct usercmd_s *GetLastCmd() = 0; +}; + +class INetChan { +public: + virtual const netadr_t* GetRemoteAdr() = 0; + virtual sizebuf_t* GetMessageBuf() = 0; +}; + +class IRehldsServerStatic { +public: + virtual ~IRehldsServerStatic() { } + + virtual int GetMaxClients() = 0; + virtual bool IsLogActive() = 0; + virtual IGameClient* GetClient(int id) = 0; + virtual client_t* GetClient_t(int id) = 0; + virtual int GetIndexOfClient_t(client_t* client) = 0; +}; + +class IRehldsServerData { +public: + virtual ~IRehldsServerData() { } + + virtual const char* GetModelName() = 0; + virtual const char* GetName() = 0; + virtual uint32 GetWorldmapCrc() = 0; + virtual uint8* GetClientDllMd5() = 0; + virtual sizebuf_t* GetDatagram() = 0; + virtual sizebuf_t* GetReliableDatagram() = 0; + + virtual void SetModelName(const char* modelname) = 0; + virtual void SetConsistencyNum(int num) = 0; + virtual int GetConsistencyNum() = 0; + virtual int GetResourcesNum() = 0; + virtual int GetDecalNameNum() = 0; + + virtual double GetTime() = 0; + virtual void SetResourcesNum(int num) = 0; + virtual struct resource_s *GetResource(int index) = 0; + virtual void SetName(const char* name) = 0; + virtual class ISteamGameServer *GetSteamGameServer() = 0; + virtual struct netadr_s *GetNetFrom() = 0; +}; diff --git a/public/resdk/mod_regamedll_api.cpp b/public/resdk/mod_regamedll_api.cpp new file mode 100644 index 00000000..0139fc71 --- /dev/null +++ b/public/resdk/mod_regamedll_api.cpp @@ -0,0 +1,29 @@ + +#include "mod_regamedll_api.h" + +IReGameApi* ReGameApi; +const ReGameFuncs_t* ReGameFuncs; +IReGameHookchains * ReGameHookchains; + +bool RegamedllApi_Init() +{ + auto library = GET_GAME_INFO(PLID, GINFO_DLL_FULLPATH); + + if (!library || !GET_IFACE(library, ReGameApi, VRE_GAMEDLL_API_VERSION, false) || !ReGameApi) + { + return false; + } + + auto majorVersion = ReGameApi->GetMajorVersion(); + auto minorVersion = ReGameApi->GetMinorVersion(); + + if (majorVersion != REGAMEDLL_API_VERSION_MAJOR || minorVersion < REGAMEDLL_API_VERSION_MINOR) + { + return false; + } + + ReGameFuncs = ReGameApi->GetFuncs(); + ReGameHookchains = ReGameApi->GetHookchains(); + + return true; +} \ No newline at end of file diff --git a/public/resdk/mod_regamedll_api.h b/public/resdk/mod_regamedll_api.h new file mode 100644 index 00000000..1a79915d --- /dev/null +++ b/public/resdk/mod_regamedll_api.h @@ -0,0 +1,11 @@ + +#pragma once + +#include +#include + +extern IReGameApi* ReGameApi; +extern const ReGameFuncs_t* ReGameFuncs; +extern IReGameHookchains* ReGameHookchains; + +extern bool RegamedllApi_Init(); diff --git a/public/resdk/mod_rehlds_api.cpp b/public/resdk/mod_rehlds_api.cpp new file mode 100644 index 00000000..8312e771 --- /dev/null +++ b/public/resdk/mod_rehlds_api.cpp @@ -0,0 +1,42 @@ + +#include "mod_rehlds_api.h" + +IRehldsApi* RehldsApi; +const RehldsFuncs_t* RehldsFuncs; +IRehldsServerData* RehldsData; +IRehldsHookchains* RehldsHookchains; +IRehldsServerStatic* RehldsSvs; + +bool RehldsApi_Init() +{ + if (!IS_DEDICATED_SERVER()) + { + return false; + } + +#if defined(PLATFORM_WINDOWS) + auto library = "swds"; +#elif defined(PLATFORM_POSIX) + auto library = "engine_i486"; +#endif + + if (!GET_IFACE(library, RehldsApi, VREHLDS_HLDS_API_VERSION) || !RehldsApi) + { + return false; + } + + auto majorVersion = RehldsApi->GetMajorVersion(); + auto minorVersion = RehldsApi->GetMinorVersion(); + + if (majorVersion != REHLDS_API_VERSION_MAJOR || minorVersion < REHLDS_API_VERSION_MINOR) + { + return false; + } + + RehldsFuncs = RehldsApi->GetFuncs(); + RehldsData = RehldsApi->GetServerData(); + RehldsHookchains = RehldsApi->GetHookchains(); + RehldsSvs = RehldsApi->GetServerStatic(); + + return true; +} diff --git a/public/resdk/mod_rehlds_api.h b/public/resdk/mod_rehlds_api.h new file mode 100644 index 00000000..341a96cb --- /dev/null +++ b/public/resdk/mod_rehlds_api.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include "engine/rehlds_api.h" + +extern IRehldsApi* RehldsApi; +extern const RehldsFuncs_t* RehldsFuncs; +extern IRehldsServerData* RehldsData; +extern IRehldsHookchains* RehldsHookchains; +extern IRehldsServerStatic* RehldsSvs; + +extern bool RehldsApi_Init(); \ No newline at end of file diff --git a/public/sh_string.h b/public/sh_string.h deleted file mode 100644 index 01eef29a..00000000 --- a/public/sh_string.h +++ /dev/null @@ -1,367 +0,0 @@ -/* ======== SourceMM ======== -* Copyright (C) 2004-2005 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): David "BAILOPAN" Anderson -* ============================ -*/ - -/* AMX Mod X - * - * by the AMX Mod X Development Team - */ - -#ifndef _INCLUDE_CSTRING_H -#define _INCLUDE_CSTRING_H - -#include -#include - -//namespace SourceHook -//{ -class String -{ -public: - String() - { - v = NULL; - a_size = 0; - //assign(""); - } - - ~String() - { - if (v) - delete [] v; - } - - String(const char *src) - { - v = NULL; - a_size = 0; - assign(src); - } - - String(const String &src) - { - v = NULL; - a_size = 0; - assign(src.c_str()); - } - - const char *c_str() { return v?v:""; } - - const char *c_str() const { return v?v:""; } - - void append(const char *t) - { - Grow(size() + strlen(t) + 1); - strcat(v, t); - } - - void append(const char c) - { - size_t len = size(); - Grow(len + 2); - v[len] = c; - v[len + 1] = '\0'; - } - - void append(String &d) - { - append(d.c_str()); - } - - void assign(const String &src) - { - assign(src.c_str()); - } - - void assign(const char *d) - { - if (!d) - { - clear(); - } else { - Grow(strlen(d) + 1, false); - strcpy(v, d); - } - } - - void clear() - { - if (v) - v[0] = '\0'; - } - - int compare (const char *d) - { - if (!v) - return strcmp("", d); - else - return strcmp(v, d); - } - - //Added this for amxx inclusion - bool empty() - { - if (!v) - return true; - - if (v[0] == '\0') - return true; - - return false; - } - - size_t size() - { - if (v) - return strlen(v); - else - return 0; - } - - int find(const char c, int index = 0) - { - int len = static_cast(size()); - if (len < 1) - return npos; - if (index >= len || index < 0) - return npos; - int i = 0; - for (i=index; i len-start) - num = len - start; - //do the erasing - bool copyflag = false; - for (i=0; i=start && i= len || !v) - return ns; - - if (num == npos) - { - num = len - index; - } else if (index+num >= len) { - num = len - index; - } - - unsigned int i = 0; - unsigned int nslen = num + 2; - - ns.Grow(nslen); - - for (i=index; i= 65 && v[i] <= 90) - v[i] &= ~(1<<5); - } - } - - String & operator = (const String &src) - { - assign(src); - return *this; - } - - String & operator = (const char *src) - { - assign(src); - return *this; - - } - - char operator [] (unsigned int index) - { - if (index > size() || !v) - { - return -1; - } else { - return v[index]; - } - } - - int at(int a) - { - if (a < 0 || a >= (int)size() || !v) - return -1; - - return v[a]; - } - - bool at(int at, char c) - { - if (at < 0 || at >= (int)size() || !v) - return false; - - v[at] = c; - - return true; - } - -private: - void Grow(unsigned int d, bool copy=true) - { - if (d <= a_size) - return; - char *n = new char[d + 1]; - if (copy && v) - strcpy(n, v); - if (v) - delete [] v; - else - strcpy(n, ""); - v = n; - a_size = d + 1; - } - - char *v; - unsigned int a_size; -public: - static const int npos = -1; -}; - -//}; //NAMESPACE - -#endif //_INCLUDE_CSTRING_H diff --git a/amxmodx/sh_tinyhash.h b/public/sh_tinyhash.h similarity index 100% rename from amxmodx/sh_tinyhash.h rename to public/sh_tinyhash.h diff --git a/public/sm_queue.h b/public/sm_queue.h deleted file mode 100644 index 21c3b7eb..00000000 --- a/public/sm_queue.h +++ /dev/null @@ -1,333 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SM_QUEUE_H -#define _INCLUDE_SM_QUEUE_H - -#include -#include -#include - -//using namespace SourceHook; - -/* - A circular, doubly-linked List with one sentinel node - - Empty: - m_Head = sentinel - m_Head->next = m_Head; - m_Head->prev = m_Head; - One element: - m_Head = sentinel - m_Head->next = node1 - m_Head->prev = node1 - node1->next = m_Head - node1->prev = m_Head - Two elements: - m_Head = sentinel - m_Head->next = node1 - m_Head->prev = node2 - node1->next = node2 - node1->prev = m_Head - node2->next = m_Head - node2->prev = node1 -*/ -template -class Queue -{ -public: - class iterator; - friend class iterator; - class QueueNode - { - public: - T obj; - QueueNode *next; - QueueNode *prev; - }; -private: - // Initializes the sentinel node. - QueueNode *_Initialize() - { - QueueNode *n = (QueueNode *)malloc(sizeof(QueueNode)); - n->next = n; - n->prev = n; - return n; - } -public: - Queue() : m_Head(_Initialize()), m_Size(0) - { - } - - Queue(const Queue &src) : m_Head(_Initialize()), m_Size(0) - { - iterator iter; - for (iter=src.begin(); iter!=src.end(); iter++) - { - push_back( (*iter) ); - } - } - - ~Queue() - { - clear(); - - // Don't forget to free the sentinel - if (m_Head) - { - free(m_Head); - m_Head = NULL; - } - - while (!m_FreeNodes.empty()) - { - free(m_FreeNodes.front()); - m_FreeNodes.pop(); - } - } - - void push(const T &obj) - { - QueueNode *node; - - if (m_FreeNodes.empty()) - { - node = (QueueNode *)malloc(sizeof(QueueNode)); - } else { - node = m_FreeNodes.front(); - m_FreeNodes.pop(); - } - - /* Copy the object */ - new (&node->obj) T(obj); - - /* Install into the Queue */ - node->prev = m_Head->prev; - node->next = m_Head; - m_Head->prev->next = node; - m_Head->prev = node; - - m_Size++; - } - - size_t size() const - { - return m_Size; - } - - void clear() - { - QueueNode *node = m_Head->next; - QueueNode *temp; - m_Head->next = m_Head; - m_Head->prev = m_Head; - - // Iterate through the nodes until we find g_Head (the sentinel) again - while (node != m_Head) - { - temp = node->next; - node->obj.~T(); - m_FreeNodes.push(node); - node = temp; - } - m_Size = 0; - } - - bool empty() const - { - return (m_Size == 0); - } - -private: - QueueNode *m_Head; - size_t m_Size; - CStack m_FreeNodes; -public: - class iterator - { - friend class Queue; - public: - iterator() - { - m_This = NULL; - } - iterator(const Queue &src) - { - m_This = src.m_Head; - } - iterator(QueueNode *n) : m_This(n) - { - } - iterator(const iterator &where) - { - m_This = where.m_This; - } - //pre decrement - iterator & operator--() - { - if (m_This) - m_This = m_This->prev; - return *this; - } - //post decrement - iterator operator--(int) - { - iterator old(*this); - if (m_This) - m_This = m_This->prev; - return old; - } - - //pre increment - iterator & operator++() - { - if (m_This) - m_This = m_This->next; - return *this; - } - //post increment - iterator operator++(int) - { - iterator old(*this); - if (m_This) - m_This = m_This->next; - return old; - } - - const T & operator * () const - { - return m_This->obj; - } - T & operator * () - { - return m_This->obj; - } - - T * operator -> () - { - return &(m_This->obj); - } - const T * operator -> () const - { - return &(m_This->obj); - } - - bool operator != (const iterator &where) const - { - return (m_This != where.m_This); - } - bool operator ==(const iterator &where) const - { - return (m_This == where.m_This); - } - private: - QueueNode *m_This; - }; -public: - iterator begin() const - { - return iterator(m_Head->next); - } - - iterator end() const - { - return iterator(m_Head); - } - - iterator erase(iterator &where) - { - QueueNode *pNode = where.m_This; - iterator iter(where); - iter++; - - - // Works for all cases: empty Queue, erasing first element, erasing tail, erasing in the middle... - pNode->prev->next = pNode->next; - pNode->next->prev = pNode->prev; - - pNode->obj.~T(); - m_FreeNodes.push(pNode); - m_Size--; - - return iter; - } -public: - void remove(const T & obj) - { - iterator b; - for (b=begin(); b!=end(); b++) - { - if ( (*b) == obj ) - { - erase( b ); - break; - } - } - } - template - iterator find(const U & equ) const - { - iterator iter; - for (iter=begin(); iter!=end(); iter++) - { - if ( (*iter) == equ ) - { - return iter; - } - } - return end(); - } - Queue & operator =(const Queue &src) - { - clear(); - iterator iter; - for (iter=src.begin(); iter!=src.end(); iter++) - { - push_back( (*iter) ); - } - return *this; - } -public: - T & first() const - { - iterator i = begin(); - - return (*i); - } - - void pop() - { - iterator iter = begin(); - erase(iter); - } -}; - -#endif //_INCLUDE_SM_QUEUE_H diff --git a/support/PackageScript b/support/PackageScript index 6f4ae94c..e6986d4e 100644 --- a/support/PackageScript +++ b/support/PackageScript @@ -268,6 +268,7 @@ scripting_files = [ 'testsuite/textparse_test.cfg', 'testsuite/textparse_test.ini', 'testsuite/request_frame_test.sma', + 'testsuite/menu_page_callback_test.sma', 'include/amxconst.inc', 'include/amxmisc.inc', 'include/amxmodx.inc',