diff --git a/extensions/cstrike/svn_version.h b/extensions/cstrike/svn_version.h index 74e4716b..465e6da5 100644 --- a/extensions/cstrike/svn_version.h +++ b/extensions/cstrike/svn_version.h @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod SDKTools Extension + * SourceMod Counter-Strike:Source Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/extensions/cstrike/svn_version.tpl b/extensions/cstrike/svn_version.tpl index 08a4c47d..58f12022 100644 --- a/extensions/cstrike/svn_version.tpl +++ b/extensions/cstrike/svn_version.tpl @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod SDKTools Extension + * SourceMod Counter-Strike:Source Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/extensions/regex/CRegEx.cpp b/extensions/regex/CRegEx.cpp index d056b09a..2af6012d 100644 --- a/extensions/regex/CRegEx.cpp +++ b/extensions/regex/CRegEx.cpp @@ -1,155 +1,155 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SQLite Extension - * 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$ - */ - -#include "pcre.h" -#include "CRegEx.h" -#include -#include "extension.h" - -RegEx::RegEx() -{ - mErrorOffset = 0; - mError = NULL; - re = NULL; - mFree = true; - subject = NULL; - mSubStrings = 0; -} - -void RegEx::Clear () -{ - mErrorOffset = 0; - mError = NULL; - if (re) - pcre_free(re); - re = NULL; - mFree = true; - if (subject) - delete [] subject; - subject = NULL; - mSubStrings = 0; -} - -RegEx::~RegEx() -{ - Clear(); -} - -bool RegEx::isFree(bool set, bool val) -{ - if (set) - { - mFree = val; - return true; - } else { - return mFree; - } -} - -int RegEx::Compile(const char *pattern, int iFlags) -{ - if (!mFree) - Clear(); - - re = pcre_compile(pattern, iFlags, &mError, &mErrorOffset, NULL); - - if (re == NULL) - { - return 0; - } - - mFree = false; - - return 1; -} - -int RegEx::Match(const char *str) -{ - int rc = 0; - - if (mFree || re == NULL) - return -1; - - this->ClearMatch(); - - //save str - subject = new char[strlen(str)+1]; - strcpy(subject, str); - - rc = pcre_exec(re, NULL, subject, (int)strlen(subject), 0, 0, ovector, 30); - - if (rc < 0) - { - if (rc == PCRE_ERROR_NOMATCH) - { - return 0; - } else { - mErrorOffset = rc; - return -1; - } - } - - mSubStrings = rc; - - return 1; -} -void RegEx::ClearMatch() -{ - // Clears match results - mErrorOffset = 0; - mError = NULL; - if (subject) - delete [] subject; - subject = NULL; - mSubStrings = 0; -} - -const char *RegEx::GetSubstring(int s, char buffer[], int max) -{ - int i = 0; - if (s >= mSubStrings || s < 0) - return NULL; - - char *substr_a = subject + ovector[2*s]; - int substr_l = ovector[2*s+1] - ovector[2*s]; - - for (i = 0; i= max) - break; - buffer[i] = substr_a[i]; - } - - buffer[i] = '\0'; - - return buffer; -} - +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Regular Expressions Extension + * 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$ + */ + +#include "pcre.h" +#include "CRegEx.h" +#include +#include "extension.h" + +RegEx::RegEx() +{ + mErrorOffset = 0; + mError = NULL; + re = NULL; + mFree = true; + subject = NULL; + mSubStrings = 0; +} + +void RegEx::Clear () +{ + mErrorOffset = 0; + mError = NULL; + if (re) + pcre_free(re); + re = NULL; + mFree = true; + if (subject) + delete [] subject; + subject = NULL; + mSubStrings = 0; +} + +RegEx::~RegEx() +{ + Clear(); +} + +bool RegEx::isFree(bool set, bool val) +{ + if (set) + { + mFree = val; + return true; + } else { + return mFree; + } +} + +int RegEx::Compile(const char *pattern, int iFlags) +{ + if (!mFree) + Clear(); + + re = pcre_compile(pattern, iFlags, &mError, &mErrorOffset, NULL); + + if (re == NULL) + { + return 0; + } + + mFree = false; + + return 1; +} + +int RegEx::Match(const char *str) +{ + int rc = 0; + + if (mFree || re == NULL) + return -1; + + this->ClearMatch(); + + //save str + subject = new char[strlen(str)+1]; + strcpy(subject, str); + + rc = pcre_exec(re, NULL, subject, (int)strlen(subject), 0, 0, ovector, 30); + + if (rc < 0) + { + if (rc == PCRE_ERROR_NOMATCH) + { + return 0; + } else { + mErrorOffset = rc; + return -1; + } + } + + mSubStrings = rc; + + return 1; +} +void RegEx::ClearMatch() +{ + // Clears match results + mErrorOffset = 0; + mError = NULL; + if (subject) + delete [] subject; + subject = NULL; + mSubStrings = 0; +} + +const char *RegEx::GetSubstring(int s, char buffer[], int max) +{ + int i = 0; + if (s >= mSubStrings || s < 0) + return NULL; + + char *substr_a = subject + ovector[2*s]; + int substr_l = ovector[2*s+1] - ovector[2*s]; + + for (i = 0; i= max) + break; + buffer[i] = substr_a[i]; + } + + buffer[i] = '\0'; + + return buffer; +} + diff --git a/extensions/regex/CRegEx.h b/extensions/regex/CRegEx.h index a89e4e25..4cf0c4fd 100644 --- a/extensions/regex/CRegEx.h +++ b/extensions/regex/CRegEx.h @@ -1,59 +1,59 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SQLite Extension - * 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_CREGEX_H -#define _INCLUDE_CREGEX_H - -class RegEx -{ -public: - RegEx(); - ~RegEx(); - bool isFree(bool set=false, bool val=false); - void Clear(); - - int Compile(const char *pattern, int iFlags); - int Match(const char *str); - void ClearMatch(); - const char *GetSubstring(int s, char buffer[], int max); -public: - int mErrorOffset; - const char *mError; - int mSubStrings; -private: - pcre *re; - bool mFree; - int ovector[30]; - char *subject; -}; - -#endif //_INCLUDE_CREGEX_H - +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Regular Expressions Extension + * 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_CREGEX_H +#define _INCLUDE_CREGEX_H + +class RegEx +{ +public: + RegEx(); + ~RegEx(); + bool isFree(bool set=false, bool val=false); + void Clear(); + + int Compile(const char *pattern, int iFlags); + int Match(const char *str); + void ClearMatch(); + const char *GetSubstring(int s, char buffer[], int max); +public: + int mErrorOffset; + const char *mError; + int mSubStrings; +private: + pcre *re; + bool mFree; + int ovector[30]; + char *subject; +}; + +#endif //_INCLUDE_CREGEX_H + diff --git a/extensions/regex/extension.cpp b/extensions/regex/extension.cpp index 5f86d564..ee7d173a 100644 --- a/extensions/regex/extension.cpp +++ b/extensions/regex/extension.cpp @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod Sample Extension + * SourceMod Regular Expressions Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * @@ -38,7 +38,7 @@ using namespace SourceHook; /** * @file extension.cpp - * @brief Implement extension code here. + * @brief Implement Regex extension code here. */ RegexExtension g_RegexExtension; /**< Global singleton for extension's main interface */ diff --git a/extensions/regex/extension.h b/extensions/regex/extension.h index 25b0785a..681dade1 100644 --- a/extensions/regex/extension.h +++ b/extensions/regex/extension.h @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod Sample Extension + * SourceMod Regular Expressions Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * @@ -34,7 +34,7 @@ /** * @file extension.h - * @brief Sample extension code header. + * @brief Regex extension code header. */ #include "smsdk_ext.h" diff --git a/extensions/regex/sdk/smsdk_config.h b/extensions/regex/sdk/smsdk_config.h index 21a8e4d3..294cd992 100644 --- a/extensions/regex/sdk/smsdk_config.h +++ b/extensions/regex/sdk/smsdk_config.h @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod Sample Extension + * SourceMod Regular Expressions Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/extensions/regex/svn_version.h b/extensions/regex/svn_version.h index 5b4d6bc8..e3b80bba 100644 --- a/extensions/regex/svn_version.h +++ b/extensions/regex/svn_version.h @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod SQLite Extension + * SourceMod Regular Expressions Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/extensions/regex/svn_version.tpl b/extensions/regex/svn_version.tpl index 1d3f09b3..158a66a3 100644 --- a/extensions/regex/svn_version.tpl +++ b/extensions/regex/svn_version.tpl @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod SQLite Extension + * SourceMod Regular Expressions Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/extensions/sdktools/detours.h b/extensions/sdktools/detours.h index 325a4ecb..ab7a30c6 100644 --- a/extensions/sdktools/detours.h +++ b/extensions/sdktools/detours.h @@ -2,7 +2,7 @@ * vim: set ts=4 : * ============================================================================= * SourceMod SDKTools Extension - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. + * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * * This program is free software; you can redistribute it and/or modify it under diff --git a/extensions/sdktools/output.cpp b/extensions/sdktools/output.cpp index a8ec86d6..1f69edcf 100644 --- a/extensions/sdktools/output.cpp +++ b/extensions/sdktools/output.cpp @@ -2,7 +2,7 @@ * vim: set ts=4 : * ============================================================================= * SourceMod SDKTools Extension - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. + * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * * This program is free software; you can redistribute it and/or modify it under diff --git a/extensions/sdktools/output.h b/extensions/sdktools/output.h index 62158b22..8c28f78b 100644 --- a/extensions/sdktools/output.h +++ b/extensions/sdktools/output.h @@ -2,7 +2,7 @@ * vim: set ts=4 : * ============================================================================= * SourceMod SDKTools Extension - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. + * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * * This program is free software; you can redistribute it and/or modify it under diff --git a/extensions/sdktools/outputnatives.cpp b/extensions/sdktools/outputnatives.cpp index 84017a56..bea961ff 100644 --- a/extensions/sdktools/outputnatives.cpp +++ b/extensions/sdktools/outputnatives.cpp @@ -2,7 +2,7 @@ * vim: set ts=4 : * ============================================================================= * SourceMod SDKTools Extension - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. + * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * * This program is free software; you can redistribute it and/or modify it under diff --git a/extensions/sqlite/Makefile b/extensions/sqlite/Makefile index 03a286e3..cf8ee596 100644 --- a/extensions/sqlite/Makefile +++ b/extensions/sqlite/Makefile @@ -17,7 +17,7 @@ PROJECT = dbi.sqlite #Uncomment for Metamod: Source enabled extension #USEMETA = true -OBJECTS = sdk/smsdk_ext.cpp extension.cpp sm_memtable.cpp \ +OBJECTS = sdk/smsdk_ext.cpp sdk/sm_memtable.cpp extension.cpp \ driver/SqDatabase.cpp driver/SqDriver.cpp driver/SqQuery.cpp \ driver/SqResults.cpp diff --git a/extensions/sqlite/msvc8/sm_sqlite.vcproj b/extensions/sqlite/msvc8/sm_sqlite.vcproj index 1f23bacc..cfe66a8b 100644 --- a/extensions/sqlite/msvc8/sm_sqlite.vcproj +++ b/extensions/sqlite/msvc8/sm_sqlite.vcproj @@ -189,10 +189,6 @@ RelativePath="..\extension.cpp" > - - - - + + + + diff --git a/extensions/sqlite/sm_memtable.cpp b/extensions/sqlite/sdk/sm_memtable.cpp similarity index 100% rename from extensions/sqlite/sm_memtable.cpp rename to extensions/sqlite/sdk/sm_memtable.cpp diff --git a/extensions/sqlite/sm_memtable.h b/extensions/sqlite/sdk/sm_memtable.h similarity index 100% rename from extensions/sqlite/sm_memtable.h rename to extensions/sqlite/sdk/sm_memtable.h diff --git a/extensions/tf2/criticals.cpp b/extensions/tf2/criticals.cpp index 8767caf3..e0ca46ae 100644 --- a/extensions/tf2/criticals.cpp +++ b/extensions/tf2/criticals.cpp @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod TF2 Extension + * SourceMod Team Fortress 2 Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/extensions/tf2/criticals.h b/extensions/tf2/criticals.h index 8c89113d..604647fc 100644 --- a/extensions/tf2/criticals.h +++ b/extensions/tf2/criticals.h @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod TF2 Extension + * SourceMod Team Fortress 2 Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/extensions/tf2/detours.h b/extensions/tf2/detours.h index 325a4ecb..6ed0cc01 100644 --- a/extensions/tf2/detours.h +++ b/extensions/tf2/detours.h @@ -1,8 +1,8 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. + * SourceMod Team Fortress 2 Extension + * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * * This program is free software; you can redistribute it and/or modify it under diff --git a/extensions/tf2/sdk/smsdk_ext.cpp b/extensions/tf2/sdk/smsdk_ext.cpp index cc9bee0e..37733333 100644 --- a/extensions/tf2/sdk/smsdk_ext.cpp +++ b/extensions/tf2/sdk/smsdk_ext.cpp @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod Team Fortress 2 Extension + * SourceMod Base Extension Code * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/extensions/tf2/sdk/smsdk_ext.h b/extensions/tf2/sdk/smsdk_ext.h index f2dae105..3d5a229d 100644 --- a/extensions/tf2/sdk/smsdk_ext.h +++ b/extensions/tf2/sdk/smsdk_ext.h @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod Team Fortress 2 Extension + * SourceMod Base Extension Code * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/extensions/tf2/svn_version.h b/extensions/tf2/svn_version.h index 1314640b..b1eff81c 100644 --- a/extensions/tf2/svn_version.h +++ b/extensions/tf2/svn_version.h @@ -1,8 +1,8 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. + * SourceMod Team Fortress 2 Extension + * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * * This program is free software; you can redistribute it and/or modify it under diff --git a/extensions/tf2/svn_version.tpl b/extensions/tf2/svn_version.tpl index ad458193..381e026e 100644 --- a/extensions/tf2/svn_version.tpl +++ b/extensions/tf2/svn_version.tpl @@ -1,8 +1,8 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. + * SourceMod Team Fortress 2 Extension + * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * * This program is free software; you can redistribute it and/or modify it under diff --git a/extensions/topmenus/Makefile b/extensions/topmenus/Makefile index 133b68c8..de617dad 100644 --- a/extensions/topmenus/Makefile +++ b/extensions/topmenus/Makefile @@ -17,8 +17,8 @@ PROJECT = topmenus #Uncomment for Metamod: Source enabled extension #USEMETA = true -OBJECTS = sdk/smsdk_ext.cpp extension.cpp TopMenuManager.cpp TopMenu.cpp \ - sdk/sm_memtable.cpp smn_topmenus.cpp +OBJECTS = sdk/smsdk_ext.cpp sdk/sm_memtable.cpp extension.cpp TopMenuManager.cpp \ + TopMenu.cpp smn_topmenus.cpp ############################################## ### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ### diff --git a/extensions/topmenus/TopMenu.cpp b/extensions/topmenus/TopMenu.cpp index a342e870..920a58e8 100644 --- a/extensions/topmenus/TopMenu.cpp +++ b/extensions/topmenus/TopMenu.cpp @@ -1,1142 +1,1142 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod Sample Extension - * 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$ - */ - -#include -#include -#include "TopMenu.h" - -struct obj_by_name_t -{ - unsigned int obj_index; - char name[64]; -}; - -int _SortObjectNamesDescending(const void *ptr1, const void *ptr2); -unsigned int strncopy(char *dest, const char *src, size_t count); -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...); - -TopMenu::TopMenu(ITopMenuObjectCallbacks *callbacks) -{ - m_clients = NULL; - m_SerialNo = 1; - m_pTitle = callbacks; - m_max_clients = 0; - - if (playerhelpers->IsServerActivated()) - { - CreatePlayers(playerhelpers->GetMaxClients()); - } -} - -TopMenu::~TopMenu() -{ - /* Delete all categories */ - while (m_Categories.size()) - { - RemoveFromMenu(m_Categories[0]->obj->object_id); - } - - /* Remove all objects */ - for (size_t i = 0; i < m_Objects.size(); i++) - { - assert(m_Objects[i]->is_free == true); - delete m_Objects[i]; - } - - m_pTitle->OnTopMenuObjectRemoved(this, 0); - - /* Delete all cached config entries */ - for (size_t i = 0; i < m_Config.cats.size(); i++) - { - delete m_Config.cats[i]; - } - - /* Sweep players */ - for (size_t i = 0; i <= (size_t)m_max_clients; i++) - { - TearDownClient(&m_clients[i]); - } - delete [] m_clients; -} - -unsigned int TopMenu::CalcMemUsage() -{ - unsigned int size = sizeof(TopMenu); - - size += m_Config.strings.GetMemTable()->MemUsage(); - size += (m_Config.cats.size() * sizeof(int)); - size += (sizeof(topmenu_player_t) * m_max_clients); - size += (m_SortedCats.size() * sizeof(unsigned int)); - size += (m_UnsortedCats.size() * sizeof(unsigned int)); - size += (m_Categories.size() * (sizeof(topmenu_category_t *) + sizeof(topmenu_category_t))); - size += (m_Objects.size() * (sizeof(topmenu_object_t *) + sizeof(topmenu_object_t))); - size += m_ObjLookup.mem_usage(); - - for (size_t i = 0; i < m_Categories.size(); i++) - { - size += m_Categories[i]->obj_list.size() * sizeof(topmenu_object_t *); - size += m_Categories[i]->sorted.size() * sizeof(topmenu_object_t *); - size += m_Categories[i]->unsorted.size() * sizeof(topmenu_object_t *); - } - - return size; -} - -void TopMenu::OnClientConnected(int client) -{ - if (m_clients == NULL) - { - return; - } - - topmenu_player_t *player = &m_clients[client]; - TearDownClient(player); -} - -void TopMenu::OnClientDisconnected(int client) -{ - if (m_clients == NULL) - { - return; - } - - topmenu_player_t *player = &m_clients[client]; - TearDownClient(player); -} - -void TopMenu::OnServerActivated(int max_clients) -{ - if (m_clients == NULL) - { - CreatePlayers(max_clients); - } -} - -unsigned int TopMenu::AddToMenu(const char *name, - TopMenuObjectType type, - ITopMenuObjectCallbacks *callbacks, - IdentityToken_t *owner, - const char *cmdname, - FlagBits flags, - unsigned int parent) -{ - return AddToMenu2(name, type, callbacks, owner, cmdname, flags, parent, NULL); -} - -unsigned int TopMenu::AddToMenu2(const char *name, - TopMenuObjectType type, - ITopMenuObjectCallbacks *callbacks, - IdentityToken_t *owner, - const char *cmdname, - FlagBits flags, - unsigned int parent, - const char *info_string) -{ - /* Sanity checks */ - if (type == TopMenuObject_Category && parent != 0) - { - return 0; - } - else if (type == TopMenuObject_Item && parent == 0) - { - return 0; - } - else if (m_ObjLookup.retrieve(name) != NULL) - { - return 0; - } - else if (type != TopMenuObject_Item && type != TopMenuObject_Category) - { - return 0; - } - - /* If we're adding an item, make sure the parent is valid, - * and that the parent is a category. - */ - topmenu_object_t *parent_obj = NULL; - topmenu_category_t *parent_cat = NULL; - if (type == TopMenuObject_Item) - { - /* Check parent index. Note it will be >= 1 here. */ - if (parent > m_Objects.size() || m_Objects[parent - 1]->is_free) - { - return 0; - } - parent_obj = m_Objects[parent - 1]; - - /* Find an equivalent pointer in the category array. */ - for (size_t i = 0; i < m_Categories.size(); i++) - { - if (m_Categories[i]->obj == parent_obj) - { - parent_cat = m_Categories[i]; - break; - } - } - - /* If none was found, leave. */ - if (parent_cat == NULL) - { - return 0; - } - } - - /* Re-use an old object pointer if we can. */ - topmenu_object_t *obj = NULL; - for (size_t i = 0; i < m_Objects.size(); i++) - { - if (m_Objects[i]->is_free == true) - { - obj = m_Objects[i]; - break; - } - } - - /* Otherwise, allocate a new one. */ - if (obj == NULL) - { - obj = new topmenu_object_t; - obj->object_id = ((unsigned int)m_Objects.size()) + 1; - m_Objects.push_back(obj); - } - - /* Initialize the object's properties. */ - obj->callbacks = callbacks; - obj->flags = flags; - obj->owner = owner; - obj->type = type; - obj->is_free = false; - obj->parent = parent_obj; - strncopy(obj->name, name, sizeof(obj->name)); - strncopy(obj->cmdname, cmdname ? cmdname : "", sizeof(obj->cmdname)); - strncopy(obj->info, info_string ? info_string : "", sizeof(obj->info)); - - if (obj->type == TopMenuObject_Category) - { - /* Create a new category entry */ - topmenu_category_t *cat = new topmenu_category_t; - cat->obj = obj; - cat->reorder = false; - cat->serial = 1; - - /* Add it, then update our serial change number. */ - m_Categories.push_back(cat); - m_SerialNo++; - - /* Updating sorting info */ - m_bCatsNeedResort = true; - } - else if (obj->type == TopMenuObject_Item) - { - /* Update the category, mark it as needing changes */ - parent_cat->obj_list.push_back(obj); - parent_cat->reorder = true; - parent_cat->serial++; - - /* If the category just went from 0 to 1 items, mark it as - * changed, so clients get the category drawn. - */ - if (parent_cat->obj_list.size() == 1) - { - m_SerialNo++; - } - } - - m_ObjLookup.insert(name, obj); - - return obj->object_id; -} - -const char *TopMenu::GetObjectInfoString(unsigned int object_id) -{ - if (object_id == 0 - || object_id > m_Objects.size() - || m_Objects[object_id - 1]->is_free) - { - return NULL; - } - - topmenu_object_t *obj = m_Objects[object_id - 1]; - - return obj->info; -} - -const char *TopMenu::GetObjectName(unsigned int object_id) -{ - if (object_id == 0 - || object_id > m_Objects.size() - || m_Objects[object_id - 1]->is_free) - { - return NULL; - } - - topmenu_object_t *obj = m_Objects[object_id - 1]; - - return obj->name; -} - -void TopMenu::RemoveFromMenu(unsigned int object_id) -{ - if (object_id == 0 - || object_id > m_Objects.size() - || m_Objects[object_id - 1]->is_free) - { - return; - } - - topmenu_object_t *obj = m_Objects[object_id - 1]; - - m_ObjLookup.remove(obj->name); - - if (obj->type == TopMenuObject_Category) - { - /* Find it in the category list. */ - for (size_t i = 0; i < m_Categories.size(); i++) - { - if (m_Categories[i]->obj == obj) - { - /* Mark all children as removed + free. Note we could - * call into RemoveMenuItem() for this, but it'd be very - * inefficient! - */ - topmenu_category_t *cat = m_Categories[i]; - for (size_t j = 0; j < m_Categories[i]->obj_list.size(); j++) - { - cat->obj_list[j]->callbacks->OnTopMenuObjectRemoved(this, cat->obj_list[j]->object_id); - cat->obj_list[j]->is_free = true; - } - - /* Remove the category from the list, then delete it. */ - m_Categories.erase(m_Categories.iterAt(i)); - delete cat; - break; - } - } - - /* Update the root as changed. */ - m_SerialNo++; - m_bCatsNeedResort = true; - } - else if (obj->type == TopMenuObject_Item) - { - /* Find the category this item is in. */ - topmenu_category_t *parent_cat = NULL; - for (size_t i = 0; i < m_Categories.size(); i++) - { - if (m_Categories[i]->obj == obj->parent) - { - parent_cat = m_Categories[i]; - break; - } - } - - /* Erase it from the category's lists. */ - if (parent_cat) - { - for (size_t i = 0; i < parent_cat->obj_list.size(); i++) - { - if (parent_cat->obj_list[i] == obj) - { - parent_cat->obj_list.erase(parent_cat->obj_list.iterAt(i)); - - /* If this category now has no items, mark root as changed - * so clients won't get the category drawn anymore. - */ - if (parent_cat->obj_list.size() == 0) - { - m_SerialNo++; - } - break; - } - } - - /* Update the category as changed. */ - parent_cat->reorder = true; - parent_cat->serial++; - } - } - - /* The callbacks pointer is still valid, so fire away! */ - obj->callbacks->OnTopMenuObjectRemoved(this, object_id); - - /* Finally, mark the object as free. */ - obj->is_free = true; -} - -bool TopMenu::DisplayMenu(int client, unsigned int hold_time, TopMenuPosition position) -{ - if (m_clients == NULL) - { - return false; - } - - IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client); - if (!pPlayer->IsInGame()) - { - return false; - } - - UpdateClientRoot(client, pPlayer); - - topmenu_player_t *pClient = &m_clients[client]; - if (pClient->root == NULL) - { - return false; - } - - bool return_value = false; - - if (position == TopMenuPosition_LastCategory && - pClient->last_category < m_Categories.size()) - { - return_value = DisplayCategory(client, pClient->last_category, hold_time, true); - if (!return_value) - { - return_value = pClient->root->DisplayAtItem(client, hold_time, pClient->last_root_pos); - } - } - else if (position == TopMenuPosition_LastRoot) - { - pClient->root->DisplayAtItem(client, hold_time, pClient->last_root_pos); - } - else if (position == TopMenuPosition_Start) - { - pClient->last_position = 0; - pClient->last_category = 0; - return_value = pClient->root->Display(client, hold_time); - } - - return return_value; -} - -bool TopMenu::DisplayCategory(int client, unsigned int category, unsigned int hold_time, bool last_position) -{ - UpdateClientCategory(client, category); - - topmenu_player_t *pClient = &m_clients[client]; - if (category >= pClient->cat_count - || pClient->cats[category].menu == NULL) - { - return false; - } - - bool return_value = false; - - topmenu_player_category_t *player_cat = &(pClient->cats[category]); - - pClient->last_category = category; - if (last_position) - { - return_value = player_cat->menu->DisplayAtItem(client, hold_time, pClient->last_position); - } - else - { - return_value = player_cat->menu->Display(client, hold_time); - } - - return return_value; -} - -void TopMenu::OnMenuSelect2(IBaseMenu *menu, int client, unsigned int item, unsigned int item_on_page) -{ - const char *item_name = menu->GetItemInfo(item, NULL); - if (!item_name) - { - return; - } - - topmenu_object_t *obj; - topmenu_player_t *pClient = &m_clients[client]; - topmenu_object_t **pObject = m_ObjLookup.retrieve(item_name); - if (pObject == NULL) - { - return; - } - - obj = *pObject; - - /* We now have the object... what do we do with it? */ - if (obj->type == TopMenuObject_Category) - { - /* If it's a category, the user wants to view it.. */ - for (size_t i = 0; i < m_Categories.size(); i++) - { - if (m_Categories[i]->obj == obj) - { - pClient->last_root_pos = item_on_page; - if (!DisplayCategory(client, (unsigned int)i, MENU_TIME_FOREVER, false)) - { - /* If we can't display the category, re-display the root menu */ - DisplayMenu(client, MENU_TIME_FOREVER, TopMenuPosition_LastRoot); - } - break; - } - } - } - else - { - pClient->last_position = item_on_page; - - /* Re-check access in case this user had their credentials revoked */ - if (obj->cmdname[0] != '\0' && !adminsys->CheckAccess(client, obj->cmdname, obj->flags, false)) - { - DisplayMenu(client, 0, TopMenuPosition_LastCategory); - return; - } - - /* Pass the information on to the callback */ - obj->callbacks->OnTopMenuSelectOption(this, client, obj->object_id); - } -} - -void TopMenu::OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style) -{ - const char *item_name = menu->GetItemInfo(item, NULL); - if (!item_name) - { - return; - } - - topmenu_object_t *obj; - topmenu_object_t **pObject = m_ObjLookup.retrieve(item_name); - if (pObject == NULL) - { - return; - } - - obj = *pObject; - - style = obj->callbacks->OnTopMenuDrawOption(this, client, obj->object_id); - if (style != ITEMDRAW_DEFAULT) - { - return; - } - - if (obj->cmdname[0] == '\0') - { - return; - } - - if (!adminsys->CheckAccess(client, obj->cmdname, obj->flags, false)) - { - style = ITEMDRAW_IGNORE; - } -} - -unsigned int TopMenu::OnMenuDisplayItem(IBaseMenu *menu, - int client, - IMenuPanel *panel, - unsigned int item, - const ItemDrawInfo &dr) -{ - const char *item_name = menu->GetItemInfo(item, NULL); - if (!item_name) - { - return 0; - } - - topmenu_object_t *obj; - topmenu_object_t **pObject = m_ObjLookup.retrieve(item_name); - if (pObject == NULL) - { - return 0; - } - - obj = *pObject; - - /* Ask the object to render the text for this client */ - char renderbuf[64]; - obj->callbacks->OnTopMenuDisplayOption(this, client, obj->object_id, renderbuf, sizeof(renderbuf)); - - /* Build the new draw info */ - ItemDrawInfo new_dr = dr; - new_dr.display = renderbuf; - - /* Man I love the menu API. Ask the panel to draw the item and give the position - * back to Core's renderer. This way we don't have to worry about keeping the - * render buffer static! - */ - return panel->DrawItem(new_dr); -} - -void TopMenu::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason) -{ - if (reason == MenuCancel_ExitBack) - { - /* If the client chose exit back, they were on a category menu, and we can - * now display the root menu from the last known position. - */ - DisplayMenu(client, 0, TopMenuPosition_LastRoot); - } -} - -void TopMenu::UpdateClientRoot(int client, IGamePlayer *pGamePlayer) -{ - topmenu_player_t *pClient = &m_clients[client]; - IGamePlayer *pPlayer = pGamePlayer ? pGamePlayer : playerhelpers->GetGamePlayer(client); - - /* Determine if an update is necessary */ - bool is_update_needed = false; - if (pClient->menu_serial != m_SerialNo) - { - is_update_needed = true; - } - else if (pPlayer->GetUserId() != pClient->user_id) - { - is_update_needed = true; - } - - /* If no update is needed at the root level, just leave now */ - if (!is_update_needed) - { - return; - } - - /* First we need to flush the cache... */ - TearDownClient(pClient); - - /* Now, rebuild the category list, but don't create menus */ - if (m_Categories.size() == 0) - { - pClient->cat_count = 0; - pClient->cats = NULL; - } - else - { - pClient->cat_count = (unsigned int)m_Categories.size(); - pClient->cats = new topmenu_player_category_t[pClient->cat_count]; - memset(pClient->cats, 0, sizeof(topmenu_player_category_t) * pClient->cat_count); - } - - /* Re-sort the root categories if needed */ - SortCategoriesIfNeeded(); - - /* Build the root menu */ - IBaseMenu *root_menu = menus->GetDefaultStyle()->CreateMenu(this, myself->GetIdentity()); - - /* Add the sorted items */ - for (size_t i = 0; i < m_SortedCats.size(); i++) - { - if (m_Categories[m_SortedCats[i]]->obj_list.size() == 0) - { - continue; - } - root_menu->AppendItem(m_Categories[m_SortedCats[i]]->obj->name, ItemDrawInfo("")); - } - - /* Now we need to handle un-sorted items. This is slightly trickier, as we need to - * pre-render each category name, and cache those names. Phew! - */ - if (m_UnsortedCats.size()) - { - obj_by_name_t *item_list = new obj_by_name_t[m_UnsortedCats.size()]; - for (size_t i = 0; i < m_UnsortedCats.size(); i++) - { - obj_by_name_t *temp_obj = &item_list[i]; - topmenu_object_t *obj = m_Categories[m_UnsortedCats[i]]->obj; - obj->callbacks->OnTopMenuDisplayOption(this, - client, - obj->object_id, - temp_obj->name, - sizeof(temp_obj->name)); - temp_obj->obj_index = m_UnsortedCats[i]; - } - - /* Sort our temp list */ - qsort(item_list, m_UnsortedCats.size(), sizeof(obj_by_name_t), _SortObjectNamesDescending); - - /* Add the new sorted categories */ - for (size_t i = 0; i < m_UnsortedCats.size(); i++) - { - if (m_Categories[item_list[i].obj_index]->obj_list.size() == 0) - { - continue; - } - root_menu->AppendItem(m_Categories[item_list[i].obj_index]->obj->name, ItemDrawInfo("")); - } - - delete [] item_list; - } - - /* Set the menu's title */ - char renderbuf[128]; - m_pTitle->OnTopMenuDisplayTitle(this, client, 0, renderbuf, sizeof(renderbuf)); - root_menu->SetDefaultTitle(renderbuf); - - /* The client is now fully updated */ - pClient->root = root_menu; - pClient->user_id = pPlayer->GetUserId(); - pClient->menu_serial = m_SerialNo; - pClient->last_position = 0; - pClient->last_category = 0; - pClient->last_root_pos = 0; -} - -void TopMenu::UpdateClientCategory(int client, unsigned int category) -{ - /* Update the client's root menu just in case it needs it. This - * will validate that we have both a valid client and a valid - * category structure for that client. - */ - UpdateClientRoot(client); - - /* Now it's guaranteed that our category tables will be usable */ - topmenu_player_t *pClient = &m_clients[client]; - topmenu_category_t *cat = m_Categories[category]; - topmenu_player_category_t *player_cat = &(pClient->cats[category]); - - /* Does the category actually need updating? */ - if (player_cat->serial == cat->serial) - { - return; - } - - /* Destroy any existing menu */ - if (player_cat->menu) - { - player_cat->menu->Destroy(); - player_cat->menu = NULL; - } - - if (pClient->last_category == category) - { - pClient->last_position = 0; - } - - IBaseMenu *cat_menu = menus->GetDefaultStyle()->CreateMenu(this, myself->GetIdentity()); - - /* Categories get an "exit back" button */ - cat_menu->SetMenuOptionFlags(cat_menu->GetMenuOptionFlags() | MENUFLAG_BUTTON_EXITBACK); - - /* Re-sort the category if needed */ - SortCategoryIfNeeded(category); - - /* Build the menu with the sorted items first */ - for (size_t i = 0; i < cat->sorted.size(); i++) - { - cat_menu->AppendItem(cat->sorted[i]->name, ItemDrawInfo("")); - } - - /* Now handle unsorted items */ - if (cat->unsorted.size()) - { - /* Build a list of the item names */ - obj_by_name_t *item_list = new obj_by_name_t[cat->unsorted.size()]; - for (size_t i = 0; i < cat->unsorted.size(); i++) - { - obj_by_name_t *item = &item_list[i]; - topmenu_object_t *obj = cat->unsorted[i]; - obj->callbacks->OnTopMenuDisplayOption(this, - client, - obj->object_id, - item->name, - sizeof(item->name)); - item->obj_index = (unsigned int)i; - } - - /* Sort the names */ - qsort(item_list, cat->unsorted.size(), sizeof(obj_by_name_t), _SortObjectNamesDescending); - - /* Add to the menu */ - for (size_t i = 0; i < cat->unsorted.size(); i++) - { - cat_menu->AppendItem(cat->unsorted[item_list[i].obj_index]->name, ItemDrawInfo("")); - } - - delete [] item_list; - } - - /* Set the menu's title */ - char renderbuf[128]; - cat->obj->callbacks->OnTopMenuDisplayTitle(this, - client, - cat->obj->object_id, - renderbuf, - sizeof(renderbuf)); - cat_menu->SetDefaultTitle(renderbuf); - - /* We're done! */ - player_cat->menu = cat_menu; - player_cat->serial = cat->serial; -} - -void TopMenu::SortCategoryIfNeeded(unsigned int category) -{ - topmenu_category_t *cat = m_Categories[category]; - if (!cat->reorder) - { - return; - } - - cat->sorted.clear(); - cat->unsorted.clear(); - - if (cat->obj_list.size() == 0) - { - cat->reorder = false; - return; - } - - CVector to_sort; - for (size_t i = 0; i < cat->obj_list.size(); i++) - { - to_sort.push_back(i); - } - - /* Find a matching category in the configs */ - config_category_t *config_cat = NULL; - for (size_t i = 0; i < m_Config.cats.size(); i++) - { - if (strcmp(m_Config.strings.GetString(m_Config.cats[i]->name), cat->obj->name) == 0) - { - config_cat = m_Config.cats[i]; - break; - } - } - - /* If there is a matching category, build a pre-sorted item list */ - if (config_cat != NULL) - { - /* Find matching objects in this category */ - for (size_t i = 0; i < config_cat->commands.size(); i++) - { - const char *config_name = m_Config.strings.GetString(config_cat->commands[i]); - for (size_t j = 0; j < to_sort.size(); j++) - { - if (strcmp(config_name, cat->obj_list[to_sort[j]]->name) == 0) - { - /* Place in the final list, then remove from the temporary list */ - cat->sorted.push_back(cat->obj_list[to_sort[j]]); - to_sort.erase(to_sort.iterAt(j)); - break; - } - } - } - } - - /* Push any remaining items onto the unsorted list */ - for (size_t i = 0; i < to_sort.size(); i++) - { - cat->unsorted.push_back(cat->obj_list[to_sort[i]]); - } - - cat->reorder = false; -} - -void TopMenu::SortCategoriesIfNeeded() -{ - if (!m_bCatsNeedResort) - { - return; - } - - /* Clear sort results */ - m_SortedCats.clear(); - m_UnsortedCats.clear(); - - if (m_Categories.size() == 0) - { - m_bCatsNeedResort = false; - return; - } - - CVector to_sort; - for (unsigned int i = 0; i < (unsigned int)m_Categories.size(); i++) - { - to_sort.push_back(i); - } - - /* If we have any predefined categories, add them in as they appear. */ - for (size_t i= 0; i < m_Config.cats.size(); i++) - { - /* Find this category and map it in if we can */ - for (size_t j = 0; j < to_sort.size(); j++) - { - if (strcmp(m_Config.strings.GetString(m_Config.cats[i]->name), - m_Categories[to_sort[j]]->obj->name) == 0) - { - /* Add to the real list and remove from the temporary */ - m_SortedCats.push_back(to_sort[j]); - to_sort.erase(to_sort.iterAt(j)); - break; - } - } - } - - /* Push any remaining items onto the unsorted list */ - for (size_t i = 0; i < to_sort.size(); i++) - { - m_UnsortedCats.push_back(to_sort[i]); - } - - m_bCatsNeedResort = false; -} - -void TopMenu::CreatePlayers(int max_clients) -{ - m_max_clients = max_clients; - m_clients = (topmenu_player_t *)malloc(sizeof(topmenu_player_t) * (max_clients + 1)); - memset(m_clients, 0, sizeof(topmenu_player_t) * (max_clients + 1)); -} - -void TopMenu::TearDownClient(topmenu_player_t *player) -{ - if (player->cats != NULL) - { - for (unsigned int i = 0; i < player->cat_count; i++) - { - topmenu_player_category_t *player_cat = &(player->cats[i]); - if (player_cat->menu != NULL) - { - player_cat->menu->Destroy(); - } - } - delete [] player->cats; - } - - if (player->root != NULL) - { - player->root->Destroy(); - } - - memset(player, 0, sizeof(topmenu_player_t)); -} - -bool TopMenu::LoadConfiguration(const char *file, char *error, size_t maxlength) -{ - SMCError err; - SMCStates states; - - if ((err = textparsers->ParseFile_SMC(file, this, &states)) - != SMCError_Okay) - { - const char *err_string = textparsers->GetSMCErrorString(err); - if (!err_string) - { - err_string = "Unknown"; - } - - UTIL_Format(error, maxlength, "%s", err_string); - - return false; - } - - return true; -} - -bool TopMenu::OnIdentityRemoval(IdentityToken_t *owner) -{ - /* First sweep the categories owned by us */ - CVector obj_list; - for (size_t i = 0; i < m_Categories.size(); i++) - { - if (m_Categories[i]->obj->owner == owner) - { - obj_list.push_back(m_Categories[i]->obj->object_id); - } - } - - for (size_t i = 0; i < obj_list.size(); i++) - { - RemoveFromMenu(obj_list[i]); - } - - /* Now we can look for actual items */ - for (size_t i = 0; i < m_Objects.size(); i++) - { - if (m_Objects[i]->is_free) - { - continue; - } - if (m_Objects[i]->owner == owner) - { - assert(m_Objects[i]->type != TopMenuObject_Category); - RemoveFromMenu(m_Objects[i]->object_id); - } - } - - return true; -} - -#define PARSE_STATE_NONE 0 -#define PARSE_STATE_MAIN 1 -#define PARSE_STATE_CATEGORY 2 -unsigned int ignore_parse_level = 0; -unsigned int current_parse_state = 0; -config_category_t *cur_cat = NULL; - -void TopMenu::ReadSMC_ParseStart() -{ - current_parse_state = PARSE_STATE_NONE; - ignore_parse_level = 0; - cur_cat = NULL; - - /* Reset the old config */ - m_Config.strings.Reset(); - for (size_t i = 0; i < m_Config.cats.size(); i++) - { - delete m_Config.cats[i]; - } - m_Config.cats.clear(); -} - -SMCResult TopMenu::ReadSMC_NewSection(const SMCStates *states, const char *name) -{ - if (ignore_parse_level) - { - ignore_parse_level++; - } - else - { - if (current_parse_state == PARSE_STATE_NONE) - { - if (strcmp(name, "Menu") == 0) - { - current_parse_state = PARSE_STATE_MAIN; - } - else - { - ignore_parse_level = 1; - } - } - else if (current_parse_state == PARSE_STATE_MAIN) - { - cur_cat = new config_category_t; - cur_cat->name = m_Config.strings.AddString(name); - m_Config.cats.push_back(cur_cat); - current_parse_state = PARSE_STATE_CATEGORY; - } - else - { - ignore_parse_level = 1; - } - } - - return SMCResult_Continue; -} - -SMCResult TopMenu::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value) -{ - if (ignore_parse_level > 0 - || current_parse_state != PARSE_STATE_CATEGORY - || cur_cat == NULL) - { - return SMCResult_Continue; - } - - if (strcmp(key, "item") == 0) - { - cur_cat->commands.push_back(m_Config.strings.AddString(value)); - } - - return SMCResult_Continue; -} - -SMCResult TopMenu::ReadSMC_LeavingSection(const SMCStates *states) -{ - if (ignore_parse_level) - { - ignore_parse_level--; - } - else - { - if (current_parse_state == PARSE_STATE_CATEGORY) - { - cur_cat = NULL; - current_parse_state = PARSE_STATE_MAIN; - } - else if (current_parse_state == PARSE_STATE_MAIN) - { - current_parse_state = PARSE_STATE_NONE; - } - } - - return SMCResult_Continue; -} - -unsigned int TopMenu::FindCategory(const char *name) -{ - topmenu_object_t **p_obj = m_ObjLookup.retrieve(name); - if (!p_obj) - { - return 0; - } - - topmenu_object_t *obj = *p_obj; - if (obj->type != TopMenuObject_Category) - { - return 0; - } - - return obj->object_id; -} - -int _SortObjectNamesDescending(const void *ptr1, const void *ptr2) -{ - obj_by_name_t *obj1 = (obj_by_name_t *)ptr1; - obj_by_name_t *obj2 = (obj_by_name_t *)ptr2; - return strcmp(obj1->name, obj2->name); -} - -unsigned int strncopy(char *dest, const char *src, size_t count) -{ - if (!count) - { - return 0; - } - - char *start = dest; - while ((*src) && (--count)) - { - *dest++ = *src++; - } - *dest = '\0'; - - return (dest - start); -} - -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - size_t len = vsnprintf(buffer, maxlength, fmt, ap); - va_end(ap); - - if (len >= maxlength) - { - buffer[maxlength - 1] = '\0'; - return (maxlength - 1); - } - else - { - return len; - } -} +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod TopMenus Extension + * 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$ + */ + +#include +#include +#include "TopMenu.h" + +struct obj_by_name_t +{ + unsigned int obj_index; + char name[64]; +}; + +int _SortObjectNamesDescending(const void *ptr1, const void *ptr2); +unsigned int strncopy(char *dest, const char *src, size_t count); +size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...); + +TopMenu::TopMenu(ITopMenuObjectCallbacks *callbacks) +{ + m_clients = NULL; + m_SerialNo = 1; + m_pTitle = callbacks; + m_max_clients = 0; + + if (playerhelpers->IsServerActivated()) + { + CreatePlayers(playerhelpers->GetMaxClients()); + } +} + +TopMenu::~TopMenu() +{ + /* Delete all categories */ + while (m_Categories.size()) + { + RemoveFromMenu(m_Categories[0]->obj->object_id); + } + + /* Remove all objects */ + for (size_t i = 0; i < m_Objects.size(); i++) + { + assert(m_Objects[i]->is_free == true); + delete m_Objects[i]; + } + + m_pTitle->OnTopMenuObjectRemoved(this, 0); + + /* Delete all cached config entries */ + for (size_t i = 0; i < m_Config.cats.size(); i++) + { + delete m_Config.cats[i]; + } + + /* Sweep players */ + for (size_t i = 0; i <= (size_t)m_max_clients; i++) + { + TearDownClient(&m_clients[i]); + } + delete [] m_clients; +} + +unsigned int TopMenu::CalcMemUsage() +{ + unsigned int size = sizeof(TopMenu); + + size += m_Config.strings.GetMemTable()->MemUsage(); + size += (m_Config.cats.size() * sizeof(int)); + size += (sizeof(topmenu_player_t) * m_max_clients); + size += (m_SortedCats.size() * sizeof(unsigned int)); + size += (m_UnsortedCats.size() * sizeof(unsigned int)); + size += (m_Categories.size() * (sizeof(topmenu_category_t *) + sizeof(topmenu_category_t))); + size += (m_Objects.size() * (sizeof(topmenu_object_t *) + sizeof(topmenu_object_t))); + size += m_ObjLookup.mem_usage(); + + for (size_t i = 0; i < m_Categories.size(); i++) + { + size += m_Categories[i]->obj_list.size() * sizeof(topmenu_object_t *); + size += m_Categories[i]->sorted.size() * sizeof(topmenu_object_t *); + size += m_Categories[i]->unsorted.size() * sizeof(topmenu_object_t *); + } + + return size; +} + +void TopMenu::OnClientConnected(int client) +{ + if (m_clients == NULL) + { + return; + } + + topmenu_player_t *player = &m_clients[client]; + TearDownClient(player); +} + +void TopMenu::OnClientDisconnected(int client) +{ + if (m_clients == NULL) + { + return; + } + + topmenu_player_t *player = &m_clients[client]; + TearDownClient(player); +} + +void TopMenu::OnServerActivated(int max_clients) +{ + if (m_clients == NULL) + { + CreatePlayers(max_clients); + } +} + +unsigned int TopMenu::AddToMenu(const char *name, + TopMenuObjectType type, + ITopMenuObjectCallbacks *callbacks, + IdentityToken_t *owner, + const char *cmdname, + FlagBits flags, + unsigned int parent) +{ + return AddToMenu2(name, type, callbacks, owner, cmdname, flags, parent, NULL); +} + +unsigned int TopMenu::AddToMenu2(const char *name, + TopMenuObjectType type, + ITopMenuObjectCallbacks *callbacks, + IdentityToken_t *owner, + const char *cmdname, + FlagBits flags, + unsigned int parent, + const char *info_string) +{ + /* Sanity checks */ + if (type == TopMenuObject_Category && parent != 0) + { + return 0; + } + else if (type == TopMenuObject_Item && parent == 0) + { + return 0; + } + else if (m_ObjLookup.retrieve(name) != NULL) + { + return 0; + } + else if (type != TopMenuObject_Item && type != TopMenuObject_Category) + { + return 0; + } + + /* If we're adding an item, make sure the parent is valid, + * and that the parent is a category. + */ + topmenu_object_t *parent_obj = NULL; + topmenu_category_t *parent_cat = NULL; + if (type == TopMenuObject_Item) + { + /* Check parent index. Note it will be >= 1 here. */ + if (parent > m_Objects.size() || m_Objects[parent - 1]->is_free) + { + return 0; + } + parent_obj = m_Objects[parent - 1]; + + /* Find an equivalent pointer in the category array. */ + for (size_t i = 0; i < m_Categories.size(); i++) + { + if (m_Categories[i]->obj == parent_obj) + { + parent_cat = m_Categories[i]; + break; + } + } + + /* If none was found, leave. */ + if (parent_cat == NULL) + { + return 0; + } + } + + /* Re-use an old object pointer if we can. */ + topmenu_object_t *obj = NULL; + for (size_t i = 0; i < m_Objects.size(); i++) + { + if (m_Objects[i]->is_free == true) + { + obj = m_Objects[i]; + break; + } + } + + /* Otherwise, allocate a new one. */ + if (obj == NULL) + { + obj = new topmenu_object_t; + obj->object_id = ((unsigned int)m_Objects.size()) + 1; + m_Objects.push_back(obj); + } + + /* Initialize the object's properties. */ + obj->callbacks = callbacks; + obj->flags = flags; + obj->owner = owner; + obj->type = type; + obj->is_free = false; + obj->parent = parent_obj; + strncopy(obj->name, name, sizeof(obj->name)); + strncopy(obj->cmdname, cmdname ? cmdname : "", sizeof(obj->cmdname)); + strncopy(obj->info, info_string ? info_string : "", sizeof(obj->info)); + + if (obj->type == TopMenuObject_Category) + { + /* Create a new category entry */ + topmenu_category_t *cat = new topmenu_category_t; + cat->obj = obj; + cat->reorder = false; + cat->serial = 1; + + /* Add it, then update our serial change number. */ + m_Categories.push_back(cat); + m_SerialNo++; + + /* Updating sorting info */ + m_bCatsNeedResort = true; + } + else if (obj->type == TopMenuObject_Item) + { + /* Update the category, mark it as needing changes */ + parent_cat->obj_list.push_back(obj); + parent_cat->reorder = true; + parent_cat->serial++; + + /* If the category just went from 0 to 1 items, mark it as + * changed, so clients get the category drawn. + */ + if (parent_cat->obj_list.size() == 1) + { + m_SerialNo++; + } + } + + m_ObjLookup.insert(name, obj); + + return obj->object_id; +} + +const char *TopMenu::GetObjectInfoString(unsigned int object_id) +{ + if (object_id == 0 + || object_id > m_Objects.size() + || m_Objects[object_id - 1]->is_free) + { + return NULL; + } + + topmenu_object_t *obj = m_Objects[object_id - 1]; + + return obj->info; +} + +const char *TopMenu::GetObjectName(unsigned int object_id) +{ + if (object_id == 0 + || object_id > m_Objects.size() + || m_Objects[object_id - 1]->is_free) + { + return NULL; + } + + topmenu_object_t *obj = m_Objects[object_id - 1]; + + return obj->name; +} + +void TopMenu::RemoveFromMenu(unsigned int object_id) +{ + if (object_id == 0 + || object_id > m_Objects.size() + || m_Objects[object_id - 1]->is_free) + { + return; + } + + topmenu_object_t *obj = m_Objects[object_id - 1]; + + m_ObjLookup.remove(obj->name); + + if (obj->type == TopMenuObject_Category) + { + /* Find it in the category list. */ + for (size_t i = 0; i < m_Categories.size(); i++) + { + if (m_Categories[i]->obj == obj) + { + /* Mark all children as removed + free. Note we could + * call into RemoveMenuItem() for this, but it'd be very + * inefficient! + */ + topmenu_category_t *cat = m_Categories[i]; + for (size_t j = 0; j < m_Categories[i]->obj_list.size(); j++) + { + cat->obj_list[j]->callbacks->OnTopMenuObjectRemoved(this, cat->obj_list[j]->object_id); + cat->obj_list[j]->is_free = true; + } + + /* Remove the category from the list, then delete it. */ + m_Categories.erase(m_Categories.iterAt(i)); + delete cat; + break; + } + } + + /* Update the root as changed. */ + m_SerialNo++; + m_bCatsNeedResort = true; + } + else if (obj->type == TopMenuObject_Item) + { + /* Find the category this item is in. */ + topmenu_category_t *parent_cat = NULL; + for (size_t i = 0; i < m_Categories.size(); i++) + { + if (m_Categories[i]->obj == obj->parent) + { + parent_cat = m_Categories[i]; + break; + } + } + + /* Erase it from the category's lists. */ + if (parent_cat) + { + for (size_t i = 0; i < parent_cat->obj_list.size(); i++) + { + if (parent_cat->obj_list[i] == obj) + { + parent_cat->obj_list.erase(parent_cat->obj_list.iterAt(i)); + + /* If this category now has no items, mark root as changed + * so clients won't get the category drawn anymore. + */ + if (parent_cat->obj_list.size() == 0) + { + m_SerialNo++; + } + break; + } + } + + /* Update the category as changed. */ + parent_cat->reorder = true; + parent_cat->serial++; + } + } + + /* The callbacks pointer is still valid, so fire away! */ + obj->callbacks->OnTopMenuObjectRemoved(this, object_id); + + /* Finally, mark the object as free. */ + obj->is_free = true; +} + +bool TopMenu::DisplayMenu(int client, unsigned int hold_time, TopMenuPosition position) +{ + if (m_clients == NULL) + { + return false; + } + + IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client); + if (!pPlayer->IsInGame()) + { + return false; + } + + UpdateClientRoot(client, pPlayer); + + topmenu_player_t *pClient = &m_clients[client]; + if (pClient->root == NULL) + { + return false; + } + + bool return_value = false; + + if (position == TopMenuPosition_LastCategory && + pClient->last_category < m_Categories.size()) + { + return_value = DisplayCategory(client, pClient->last_category, hold_time, true); + if (!return_value) + { + return_value = pClient->root->DisplayAtItem(client, hold_time, pClient->last_root_pos); + } + } + else if (position == TopMenuPosition_LastRoot) + { + pClient->root->DisplayAtItem(client, hold_time, pClient->last_root_pos); + } + else if (position == TopMenuPosition_Start) + { + pClient->last_position = 0; + pClient->last_category = 0; + return_value = pClient->root->Display(client, hold_time); + } + + return return_value; +} + +bool TopMenu::DisplayCategory(int client, unsigned int category, unsigned int hold_time, bool last_position) +{ + UpdateClientCategory(client, category); + + topmenu_player_t *pClient = &m_clients[client]; + if (category >= pClient->cat_count + || pClient->cats[category].menu == NULL) + { + return false; + } + + bool return_value = false; + + topmenu_player_category_t *player_cat = &(pClient->cats[category]); + + pClient->last_category = category; + if (last_position) + { + return_value = player_cat->menu->DisplayAtItem(client, hold_time, pClient->last_position); + } + else + { + return_value = player_cat->menu->Display(client, hold_time); + } + + return return_value; +} + +void TopMenu::OnMenuSelect2(IBaseMenu *menu, int client, unsigned int item, unsigned int item_on_page) +{ + const char *item_name = menu->GetItemInfo(item, NULL); + if (!item_name) + { + return; + } + + topmenu_object_t *obj; + topmenu_player_t *pClient = &m_clients[client]; + topmenu_object_t **pObject = m_ObjLookup.retrieve(item_name); + if (pObject == NULL) + { + return; + } + + obj = *pObject; + + /* We now have the object... what do we do with it? */ + if (obj->type == TopMenuObject_Category) + { + /* If it's a category, the user wants to view it.. */ + for (size_t i = 0; i < m_Categories.size(); i++) + { + if (m_Categories[i]->obj == obj) + { + pClient->last_root_pos = item_on_page; + if (!DisplayCategory(client, (unsigned int)i, MENU_TIME_FOREVER, false)) + { + /* If we can't display the category, re-display the root menu */ + DisplayMenu(client, MENU_TIME_FOREVER, TopMenuPosition_LastRoot); + } + break; + } + } + } + else + { + pClient->last_position = item_on_page; + + /* Re-check access in case this user had their credentials revoked */ + if (obj->cmdname[0] != '\0' && !adminsys->CheckAccess(client, obj->cmdname, obj->flags, false)) + { + DisplayMenu(client, 0, TopMenuPosition_LastCategory); + return; + } + + /* Pass the information on to the callback */ + obj->callbacks->OnTopMenuSelectOption(this, client, obj->object_id); + } +} + +void TopMenu::OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style) +{ + const char *item_name = menu->GetItemInfo(item, NULL); + if (!item_name) + { + return; + } + + topmenu_object_t *obj; + topmenu_object_t **pObject = m_ObjLookup.retrieve(item_name); + if (pObject == NULL) + { + return; + } + + obj = *pObject; + + style = obj->callbacks->OnTopMenuDrawOption(this, client, obj->object_id); + if (style != ITEMDRAW_DEFAULT) + { + return; + } + + if (obj->cmdname[0] == '\0') + { + return; + } + + if (!adminsys->CheckAccess(client, obj->cmdname, obj->flags, false)) + { + style = ITEMDRAW_IGNORE; + } +} + +unsigned int TopMenu::OnMenuDisplayItem(IBaseMenu *menu, + int client, + IMenuPanel *panel, + unsigned int item, + const ItemDrawInfo &dr) +{ + const char *item_name = menu->GetItemInfo(item, NULL); + if (!item_name) + { + return 0; + } + + topmenu_object_t *obj; + topmenu_object_t **pObject = m_ObjLookup.retrieve(item_name); + if (pObject == NULL) + { + return 0; + } + + obj = *pObject; + + /* Ask the object to render the text for this client */ + char renderbuf[64]; + obj->callbacks->OnTopMenuDisplayOption(this, client, obj->object_id, renderbuf, sizeof(renderbuf)); + + /* Build the new draw info */ + ItemDrawInfo new_dr = dr; + new_dr.display = renderbuf; + + /* Man I love the menu API. Ask the panel to draw the item and give the position + * back to Core's renderer. This way we don't have to worry about keeping the + * render buffer static! + */ + return panel->DrawItem(new_dr); +} + +void TopMenu::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason) +{ + if (reason == MenuCancel_ExitBack) + { + /* If the client chose exit back, they were on a category menu, and we can + * now display the root menu from the last known position. + */ + DisplayMenu(client, 0, TopMenuPosition_LastRoot); + } +} + +void TopMenu::UpdateClientRoot(int client, IGamePlayer *pGamePlayer) +{ + topmenu_player_t *pClient = &m_clients[client]; + IGamePlayer *pPlayer = pGamePlayer ? pGamePlayer : playerhelpers->GetGamePlayer(client); + + /* Determine if an update is necessary */ + bool is_update_needed = false; + if (pClient->menu_serial != m_SerialNo) + { + is_update_needed = true; + } + else if (pPlayer->GetUserId() != pClient->user_id) + { + is_update_needed = true; + } + + /* If no update is needed at the root level, just leave now */ + if (!is_update_needed) + { + return; + } + + /* First we need to flush the cache... */ + TearDownClient(pClient); + + /* Now, rebuild the category list, but don't create menus */ + if (m_Categories.size() == 0) + { + pClient->cat_count = 0; + pClient->cats = NULL; + } + else + { + pClient->cat_count = (unsigned int)m_Categories.size(); + pClient->cats = new topmenu_player_category_t[pClient->cat_count]; + memset(pClient->cats, 0, sizeof(topmenu_player_category_t) * pClient->cat_count); + } + + /* Re-sort the root categories if needed */ + SortCategoriesIfNeeded(); + + /* Build the root menu */ + IBaseMenu *root_menu = menus->GetDefaultStyle()->CreateMenu(this, myself->GetIdentity()); + + /* Add the sorted items */ + for (size_t i = 0; i < m_SortedCats.size(); i++) + { + if (m_Categories[m_SortedCats[i]]->obj_list.size() == 0) + { + continue; + } + root_menu->AppendItem(m_Categories[m_SortedCats[i]]->obj->name, ItemDrawInfo("")); + } + + /* Now we need to handle un-sorted items. This is slightly trickier, as we need to + * pre-render each category name, and cache those names. Phew! + */ + if (m_UnsortedCats.size()) + { + obj_by_name_t *item_list = new obj_by_name_t[m_UnsortedCats.size()]; + for (size_t i = 0; i < m_UnsortedCats.size(); i++) + { + obj_by_name_t *temp_obj = &item_list[i]; + topmenu_object_t *obj = m_Categories[m_UnsortedCats[i]]->obj; + obj->callbacks->OnTopMenuDisplayOption(this, + client, + obj->object_id, + temp_obj->name, + sizeof(temp_obj->name)); + temp_obj->obj_index = m_UnsortedCats[i]; + } + + /* Sort our temp list */ + qsort(item_list, m_UnsortedCats.size(), sizeof(obj_by_name_t), _SortObjectNamesDescending); + + /* Add the new sorted categories */ + for (size_t i = 0; i < m_UnsortedCats.size(); i++) + { + if (m_Categories[item_list[i].obj_index]->obj_list.size() == 0) + { + continue; + } + root_menu->AppendItem(m_Categories[item_list[i].obj_index]->obj->name, ItemDrawInfo("")); + } + + delete [] item_list; + } + + /* Set the menu's title */ + char renderbuf[128]; + m_pTitle->OnTopMenuDisplayTitle(this, client, 0, renderbuf, sizeof(renderbuf)); + root_menu->SetDefaultTitle(renderbuf); + + /* The client is now fully updated */ + pClient->root = root_menu; + pClient->user_id = pPlayer->GetUserId(); + pClient->menu_serial = m_SerialNo; + pClient->last_position = 0; + pClient->last_category = 0; + pClient->last_root_pos = 0; +} + +void TopMenu::UpdateClientCategory(int client, unsigned int category) +{ + /* Update the client's root menu just in case it needs it. This + * will validate that we have both a valid client and a valid + * category structure for that client. + */ + UpdateClientRoot(client); + + /* Now it's guaranteed that our category tables will be usable */ + topmenu_player_t *pClient = &m_clients[client]; + topmenu_category_t *cat = m_Categories[category]; + topmenu_player_category_t *player_cat = &(pClient->cats[category]); + + /* Does the category actually need updating? */ + if (player_cat->serial == cat->serial) + { + return; + } + + /* Destroy any existing menu */ + if (player_cat->menu) + { + player_cat->menu->Destroy(); + player_cat->menu = NULL; + } + + if (pClient->last_category == category) + { + pClient->last_position = 0; + } + + IBaseMenu *cat_menu = menus->GetDefaultStyle()->CreateMenu(this, myself->GetIdentity()); + + /* Categories get an "exit back" button */ + cat_menu->SetMenuOptionFlags(cat_menu->GetMenuOptionFlags() | MENUFLAG_BUTTON_EXITBACK); + + /* Re-sort the category if needed */ + SortCategoryIfNeeded(category); + + /* Build the menu with the sorted items first */ + for (size_t i = 0; i < cat->sorted.size(); i++) + { + cat_menu->AppendItem(cat->sorted[i]->name, ItemDrawInfo("")); + } + + /* Now handle unsorted items */ + if (cat->unsorted.size()) + { + /* Build a list of the item names */ + obj_by_name_t *item_list = new obj_by_name_t[cat->unsorted.size()]; + for (size_t i = 0; i < cat->unsorted.size(); i++) + { + obj_by_name_t *item = &item_list[i]; + topmenu_object_t *obj = cat->unsorted[i]; + obj->callbacks->OnTopMenuDisplayOption(this, + client, + obj->object_id, + item->name, + sizeof(item->name)); + item->obj_index = (unsigned int)i; + } + + /* Sort the names */ + qsort(item_list, cat->unsorted.size(), sizeof(obj_by_name_t), _SortObjectNamesDescending); + + /* Add to the menu */ + for (size_t i = 0; i < cat->unsorted.size(); i++) + { + cat_menu->AppendItem(cat->unsorted[item_list[i].obj_index]->name, ItemDrawInfo("")); + } + + delete [] item_list; + } + + /* Set the menu's title */ + char renderbuf[128]; + cat->obj->callbacks->OnTopMenuDisplayTitle(this, + client, + cat->obj->object_id, + renderbuf, + sizeof(renderbuf)); + cat_menu->SetDefaultTitle(renderbuf); + + /* We're done! */ + player_cat->menu = cat_menu; + player_cat->serial = cat->serial; +} + +void TopMenu::SortCategoryIfNeeded(unsigned int category) +{ + topmenu_category_t *cat = m_Categories[category]; + if (!cat->reorder) + { + return; + } + + cat->sorted.clear(); + cat->unsorted.clear(); + + if (cat->obj_list.size() == 0) + { + cat->reorder = false; + return; + } + + CVector to_sort; + for (size_t i = 0; i < cat->obj_list.size(); i++) + { + to_sort.push_back(i); + } + + /* Find a matching category in the configs */ + config_category_t *config_cat = NULL; + for (size_t i = 0; i < m_Config.cats.size(); i++) + { + if (strcmp(m_Config.strings.GetString(m_Config.cats[i]->name), cat->obj->name) == 0) + { + config_cat = m_Config.cats[i]; + break; + } + } + + /* If there is a matching category, build a pre-sorted item list */ + if (config_cat != NULL) + { + /* Find matching objects in this category */ + for (size_t i = 0; i < config_cat->commands.size(); i++) + { + const char *config_name = m_Config.strings.GetString(config_cat->commands[i]); + for (size_t j = 0; j < to_sort.size(); j++) + { + if (strcmp(config_name, cat->obj_list[to_sort[j]]->name) == 0) + { + /* Place in the final list, then remove from the temporary list */ + cat->sorted.push_back(cat->obj_list[to_sort[j]]); + to_sort.erase(to_sort.iterAt(j)); + break; + } + } + } + } + + /* Push any remaining items onto the unsorted list */ + for (size_t i = 0; i < to_sort.size(); i++) + { + cat->unsorted.push_back(cat->obj_list[to_sort[i]]); + } + + cat->reorder = false; +} + +void TopMenu::SortCategoriesIfNeeded() +{ + if (!m_bCatsNeedResort) + { + return; + } + + /* Clear sort results */ + m_SortedCats.clear(); + m_UnsortedCats.clear(); + + if (m_Categories.size() == 0) + { + m_bCatsNeedResort = false; + return; + } + + CVector to_sort; + for (unsigned int i = 0; i < (unsigned int)m_Categories.size(); i++) + { + to_sort.push_back(i); + } + + /* If we have any predefined categories, add them in as they appear. */ + for (size_t i= 0; i < m_Config.cats.size(); i++) + { + /* Find this category and map it in if we can */ + for (size_t j = 0; j < to_sort.size(); j++) + { + if (strcmp(m_Config.strings.GetString(m_Config.cats[i]->name), + m_Categories[to_sort[j]]->obj->name) == 0) + { + /* Add to the real list and remove from the temporary */ + m_SortedCats.push_back(to_sort[j]); + to_sort.erase(to_sort.iterAt(j)); + break; + } + } + } + + /* Push any remaining items onto the unsorted list */ + for (size_t i = 0; i < to_sort.size(); i++) + { + m_UnsortedCats.push_back(to_sort[i]); + } + + m_bCatsNeedResort = false; +} + +void TopMenu::CreatePlayers(int max_clients) +{ + m_max_clients = max_clients; + m_clients = (topmenu_player_t *)malloc(sizeof(topmenu_player_t) * (max_clients + 1)); + memset(m_clients, 0, sizeof(topmenu_player_t) * (max_clients + 1)); +} + +void TopMenu::TearDownClient(topmenu_player_t *player) +{ + if (player->cats != NULL) + { + for (unsigned int i = 0; i < player->cat_count; i++) + { + topmenu_player_category_t *player_cat = &(player->cats[i]); + if (player_cat->menu != NULL) + { + player_cat->menu->Destroy(); + } + } + delete [] player->cats; + } + + if (player->root != NULL) + { + player->root->Destroy(); + } + + memset(player, 0, sizeof(topmenu_player_t)); +} + +bool TopMenu::LoadConfiguration(const char *file, char *error, size_t maxlength) +{ + SMCError err; + SMCStates states; + + if ((err = textparsers->ParseFile_SMC(file, this, &states)) + != SMCError_Okay) + { + const char *err_string = textparsers->GetSMCErrorString(err); + if (!err_string) + { + err_string = "Unknown"; + } + + UTIL_Format(error, maxlength, "%s", err_string); + + return false; + } + + return true; +} + +bool TopMenu::OnIdentityRemoval(IdentityToken_t *owner) +{ + /* First sweep the categories owned by us */ + CVector obj_list; + for (size_t i = 0; i < m_Categories.size(); i++) + { + if (m_Categories[i]->obj->owner == owner) + { + obj_list.push_back(m_Categories[i]->obj->object_id); + } + } + + for (size_t i = 0; i < obj_list.size(); i++) + { + RemoveFromMenu(obj_list[i]); + } + + /* Now we can look for actual items */ + for (size_t i = 0; i < m_Objects.size(); i++) + { + if (m_Objects[i]->is_free) + { + continue; + } + if (m_Objects[i]->owner == owner) + { + assert(m_Objects[i]->type != TopMenuObject_Category); + RemoveFromMenu(m_Objects[i]->object_id); + } + } + + return true; +} + +#define PARSE_STATE_NONE 0 +#define PARSE_STATE_MAIN 1 +#define PARSE_STATE_CATEGORY 2 +unsigned int ignore_parse_level = 0; +unsigned int current_parse_state = 0; +config_category_t *cur_cat = NULL; + +void TopMenu::ReadSMC_ParseStart() +{ + current_parse_state = PARSE_STATE_NONE; + ignore_parse_level = 0; + cur_cat = NULL; + + /* Reset the old config */ + m_Config.strings.Reset(); + for (size_t i = 0; i < m_Config.cats.size(); i++) + { + delete m_Config.cats[i]; + } + m_Config.cats.clear(); +} + +SMCResult TopMenu::ReadSMC_NewSection(const SMCStates *states, const char *name) +{ + if (ignore_parse_level) + { + ignore_parse_level++; + } + else + { + if (current_parse_state == PARSE_STATE_NONE) + { + if (strcmp(name, "Menu") == 0) + { + current_parse_state = PARSE_STATE_MAIN; + } + else + { + ignore_parse_level = 1; + } + } + else if (current_parse_state == PARSE_STATE_MAIN) + { + cur_cat = new config_category_t; + cur_cat->name = m_Config.strings.AddString(name); + m_Config.cats.push_back(cur_cat); + current_parse_state = PARSE_STATE_CATEGORY; + } + else + { + ignore_parse_level = 1; + } + } + + return SMCResult_Continue; +} + +SMCResult TopMenu::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value) +{ + if (ignore_parse_level > 0 + || current_parse_state != PARSE_STATE_CATEGORY + || cur_cat == NULL) + { + return SMCResult_Continue; + } + + if (strcmp(key, "item") == 0) + { + cur_cat->commands.push_back(m_Config.strings.AddString(value)); + } + + return SMCResult_Continue; +} + +SMCResult TopMenu::ReadSMC_LeavingSection(const SMCStates *states) +{ + if (ignore_parse_level) + { + ignore_parse_level--; + } + else + { + if (current_parse_state == PARSE_STATE_CATEGORY) + { + cur_cat = NULL; + current_parse_state = PARSE_STATE_MAIN; + } + else if (current_parse_state == PARSE_STATE_MAIN) + { + current_parse_state = PARSE_STATE_NONE; + } + } + + return SMCResult_Continue; +} + +unsigned int TopMenu::FindCategory(const char *name) +{ + topmenu_object_t **p_obj = m_ObjLookup.retrieve(name); + if (!p_obj) + { + return 0; + } + + topmenu_object_t *obj = *p_obj; + if (obj->type != TopMenuObject_Category) + { + return 0; + } + + return obj->object_id; +} + +int _SortObjectNamesDescending(const void *ptr1, const void *ptr2) +{ + obj_by_name_t *obj1 = (obj_by_name_t *)ptr1; + obj_by_name_t *obj2 = (obj_by_name_t *)ptr2; + return strcmp(obj1->name, obj2->name); +} + +unsigned int strncopy(char *dest, const char *src, size_t count) +{ + if (!count) + { + return 0; + } + + char *start = dest; + while ((*src) && (--count)) + { + *dest++ = *src++; + } + *dest = '\0'; + + return (dest - start); +} + +size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + size_t len = vsnprintf(buffer, maxlength, fmt, ap); + va_end(ap); + + if (len >= maxlength) + { + buffer[maxlength - 1] = '\0'; + return (maxlength - 1); + } + else + { + return len; + } +} diff --git a/extensions/topmenus/TopMenu.h b/extensions/topmenus/TopMenu.h index 13631c74..3177434d 100644 --- a/extensions/topmenus/TopMenu.h +++ b/extensions/topmenus/TopMenu.h @@ -1,181 +1,181 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod Sample Extension - * 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_SOURCEMOD_TOP_MENU_H_ -#define _INCLUDE_SOURCEMOD_TOP_MENU_H_ - -#include -#include -#include -#include -#include "smsdk_ext.h" -#include "sm_memtable.h" - -using namespace SourceHook; -using namespace SourceMod; - -struct config_category_t -{ - int name; - CVector commands; -}; - -struct config_root_t -{ - config_root_t() : strings(1024) - { - } - BaseStringTable strings; - CVector cats; -}; - -struct topmenu_object_t -{ - char name[64]; /** Name */ - char cmdname[64]; /** Command name */ - FlagBits flags; /** Admin flags */ - ITopMenuObjectCallbacks *callbacks; /** Callbacks */ - IdentityToken_t *owner; /** Owner */ - unsigned int object_id; /** Object ID */ - topmenu_object_t *parent; /** Parent, if any */ - TopMenuObjectType type; /** Object Type */ - bool is_free; /** Free or not? */ - char info[255]; /** Info string */ -}; - -struct topmenu_category_t -{ - CVector obj_list; /** Full object list */ - CVector sorted; /** Sorted items */ - CVector unsorted; /** Unsorted items */ - topmenu_object_t *obj; /** Bound object */ - unsigned int serial; /** Serial number */ - bool reorder; /** Whether ordering needs updating */ -}; - -struct topmenu_player_category_t -{ - IBaseMenu *menu; /** menu pointer */ - unsigned int serial; /** last known serial */ -}; - -struct topmenu_player_t -{ - int user_id; /** userid on server */ - unsigned int menu_serial; /** menu serial no */ - IBaseMenu *root; /** root menu display */ - topmenu_player_category_t *cats; /** category display */ - unsigned int cat_count; /** number of categories */ - unsigned int last_category; /** last category they selected */ - unsigned int last_position; /** last position in that category */ - unsigned int last_root_pos; /** last page in the root menu */ -}; - -class TopMenu : - public ITopMenu, - public IMenuHandler, - public ITextListener_SMC -{ - friend class TopMenuManager; -public: - TopMenu(ITopMenuObjectCallbacks *callbacks); - ~TopMenu(); -public: //ITopMenu - virtual unsigned int AddToMenu(const char *name, - TopMenuObjectType type, - ITopMenuObjectCallbacks *callbacks, - IdentityToken_t *owner, - const char *cmdname, - FlagBits flags, - unsigned int parent); - unsigned int AddToMenu2(const char *name, - TopMenuObjectType type, - ITopMenuObjectCallbacks *callbacks, - IdentityToken_t *owner, - const char *cmdname, - FlagBits flags, - unsigned int parent, - const char *info_string); - virtual void RemoveFromMenu(unsigned int object_id); - virtual bool DisplayMenu(int client, - unsigned int hold_time, - TopMenuPosition position); - virtual bool LoadConfiguration(const char *file, char *error, size_t maxlength); - virtual unsigned int FindCategory(const char *name); - const char *GetObjectInfoString(unsigned int object_id); - const char *GetObjectName(unsigned int object_id); -public: //IMenuHandler - virtual void OnMenuSelect2(IBaseMenu *menu, int client, unsigned int item, unsigned int item_on_page); - virtual void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style); - virtual unsigned int OnMenuDisplayItem(IBaseMenu *menu, - int client, - IMenuPanel *panel, - unsigned int item, - const ItemDrawInfo &dr); - virtual void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason); -public: //ITextListener_SMC - void ReadSMC_ParseStart(); - SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name); - SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value); - SMCResult ReadSMC_LeavingSection(const SMCStates *states); -public: - unsigned int CalcMemUsage(); -private: - void SortCategoriesIfNeeded(); - void SortCategoryIfNeeded(unsigned int category); -private: - bool DisplayCategory(int client, unsigned int category, unsigned int hold_time, bool last_position); - void CreatePlayers(int max_clients); - void UpdateClientRoot(int client, IGamePlayer *pGamePlayer=NULL); - void UpdateClientCategory(int client, unsigned int category); - void TearDownClient(topmenu_player_t *player); -private: - void OnClientConnected(int client); - void OnClientDisconnected(int client); - void OnServerActivated(int max_clients); - bool OnIdentityRemoval(IdentityToken_t *owner); -private: - config_root_t m_Config; /* Configuration from file */ - topmenu_player_t *m_clients; /* Client array */ - CVector m_SortedCats; /* Sorted categories */ - CVector m_UnsortedCats; /* Un-sorted categories */ - CVector m_Categories; /* Category array */ - CVector m_Objects; /* Object array */ - KTrie m_ObjLookup; /* Object lookup trie */ - unsigned int m_SerialNo; /* Serial number for updating */ - ITopMenuObjectCallbacks *m_pTitle; /* Title callbacks */ - int m_max_clients; /* Maximum number of clients */ - bool m_bCatsNeedResort; /* True if categories need a resort */ -}; - -unsigned int strncopy(char *dest, const char *src, size_t count); - -#endif //_INCLUDE_SOURCEMOD_TOP_MENU_H_ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod TopMenus Extension + * 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_SOURCEMOD_TOP_MENU_H_ +#define _INCLUDE_SOURCEMOD_TOP_MENU_H_ + +#include +#include +#include +#include +#include "smsdk_ext.h" +#include "sm_memtable.h" + +using namespace SourceHook; +using namespace SourceMod; + +struct config_category_t +{ + int name; + CVector commands; +}; + +struct config_root_t +{ + config_root_t() : strings(1024) + { + } + BaseStringTable strings; + CVector cats; +}; + +struct topmenu_object_t +{ + char name[64]; /** Name */ + char cmdname[64]; /** Command name */ + FlagBits flags; /** Admin flags */ + ITopMenuObjectCallbacks *callbacks; /** Callbacks */ + IdentityToken_t *owner; /** Owner */ + unsigned int object_id; /** Object ID */ + topmenu_object_t *parent; /** Parent, if any */ + TopMenuObjectType type; /** Object Type */ + bool is_free; /** Free or not? */ + char info[255]; /** Info string */ +}; + +struct topmenu_category_t +{ + CVector obj_list; /** Full object list */ + CVector sorted; /** Sorted items */ + CVector unsorted; /** Unsorted items */ + topmenu_object_t *obj; /** Bound object */ + unsigned int serial; /** Serial number */ + bool reorder; /** Whether ordering needs updating */ +}; + +struct topmenu_player_category_t +{ + IBaseMenu *menu; /** menu pointer */ + unsigned int serial; /** last known serial */ +}; + +struct topmenu_player_t +{ + int user_id; /** userid on server */ + unsigned int menu_serial; /** menu serial no */ + IBaseMenu *root; /** root menu display */ + topmenu_player_category_t *cats; /** category display */ + unsigned int cat_count; /** number of categories */ + unsigned int last_category; /** last category they selected */ + unsigned int last_position; /** last position in that category */ + unsigned int last_root_pos; /** last page in the root menu */ +}; + +class TopMenu : + public ITopMenu, + public IMenuHandler, + public ITextListener_SMC +{ + friend class TopMenuManager; +public: + TopMenu(ITopMenuObjectCallbacks *callbacks); + ~TopMenu(); +public: //ITopMenu + virtual unsigned int AddToMenu(const char *name, + TopMenuObjectType type, + ITopMenuObjectCallbacks *callbacks, + IdentityToken_t *owner, + const char *cmdname, + FlagBits flags, + unsigned int parent); + unsigned int AddToMenu2(const char *name, + TopMenuObjectType type, + ITopMenuObjectCallbacks *callbacks, + IdentityToken_t *owner, + const char *cmdname, + FlagBits flags, + unsigned int parent, + const char *info_string); + virtual void RemoveFromMenu(unsigned int object_id); + virtual bool DisplayMenu(int client, + unsigned int hold_time, + TopMenuPosition position); + virtual bool LoadConfiguration(const char *file, char *error, size_t maxlength); + virtual unsigned int FindCategory(const char *name); + const char *GetObjectInfoString(unsigned int object_id); + const char *GetObjectName(unsigned int object_id); +public: //IMenuHandler + virtual void OnMenuSelect2(IBaseMenu *menu, int client, unsigned int item, unsigned int item_on_page); + virtual void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style); + virtual unsigned int OnMenuDisplayItem(IBaseMenu *menu, + int client, + IMenuPanel *panel, + unsigned int item, + const ItemDrawInfo &dr); + virtual void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason); +public: //ITextListener_SMC + void ReadSMC_ParseStart(); + SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name); + SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value); + SMCResult ReadSMC_LeavingSection(const SMCStates *states); +public: + unsigned int CalcMemUsage(); +private: + void SortCategoriesIfNeeded(); + void SortCategoryIfNeeded(unsigned int category); +private: + bool DisplayCategory(int client, unsigned int category, unsigned int hold_time, bool last_position); + void CreatePlayers(int max_clients); + void UpdateClientRoot(int client, IGamePlayer *pGamePlayer=NULL); + void UpdateClientCategory(int client, unsigned int category); + void TearDownClient(topmenu_player_t *player); +private: + void OnClientConnected(int client); + void OnClientDisconnected(int client); + void OnServerActivated(int max_clients); + bool OnIdentityRemoval(IdentityToken_t *owner); +private: + config_root_t m_Config; /* Configuration from file */ + topmenu_player_t *m_clients; /* Client array */ + CVector m_SortedCats; /* Sorted categories */ + CVector m_UnsortedCats; /* Un-sorted categories */ + CVector m_Categories; /* Category array */ + CVector m_Objects; /* Object array */ + KTrie m_ObjLookup; /* Object lookup trie */ + unsigned int m_SerialNo; /* Serial number for updating */ + ITopMenuObjectCallbacks *m_pTitle; /* Title callbacks */ + int m_max_clients; /* Maximum number of clients */ + bool m_bCatsNeedResort; /* True if categories need a resort */ +}; + +unsigned int strncopy(char *dest, const char *src, size_t count); + +#endif //_INCLUDE_SOURCEMOD_TOP_MENU_H_ diff --git a/extensions/topmenus/TopMenuManager.cpp b/extensions/topmenus/TopMenuManager.cpp index 0cec8baf..fb55f1bf 100644 --- a/extensions/topmenus/TopMenuManager.cpp +++ b/extensions/topmenus/TopMenuManager.cpp @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod Sample Extension + * SourceMod TopMenus Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/extensions/topmenus/TopMenuManager.h b/extensions/topmenus/TopMenuManager.h index 18a2c2c4..5e03b71e 100644 --- a/extensions/topmenus/TopMenuManager.h +++ b/extensions/topmenus/TopMenuManager.h @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod Sample Extension + * SourceMod TopMenus Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/extensions/topmenus/extension.cpp b/extensions/topmenus/extension.cpp index 8741dbf9..eb2e7579 100644 --- a/extensions/topmenus/extension.cpp +++ b/extensions/topmenus/extension.cpp @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod Sample Extension + * SourceMod TopMenus Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/extensions/topmenus/extension.h b/extensions/topmenus/extension.h index 7efb0419..f5d94769 100644 --- a/extensions/topmenus/extension.h +++ b/extensions/topmenus/extension.h @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod Sample Extension + * SourceMod TopMenus Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/extensions/topmenus/sdk/smsdk_config.h b/extensions/topmenus/sdk/smsdk_config.h index 029e786f..078aca75 100644 --- a/extensions/topmenus/sdk/smsdk_config.h +++ b/extensions/topmenus/sdk/smsdk_config.h @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod Sample Extension + * SourceMod TopMenus Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/extensions/topmenus/smn_topmenus.cpp b/extensions/topmenus/smn_topmenus.cpp index 0457afdc..d0d74289 100644 --- a/extensions/topmenus/smn_topmenus.cpp +++ b/extensions/topmenus/smn_topmenus.cpp @@ -1,388 +1,388 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod Sample Extension - * 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$ - */ - -#include "extension.h" -#include "TopMenuManager.h" -#include "TopMenu.h" - -HandleType_t hTopMenuType; - -class TopMenuHandle : public IHandleTypeDispatch -{ -public: - void OnHandleDestroy(HandleType_t type, void *object) - { - ITopMenu *pTopMenu = (ITopMenu *)object; - g_TopMenus.DestroyTopMenu(pTopMenu); - } - bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize) - { - *pSize = ((TopMenu *)object)->CalcMemUsage(); - return true; - } -} s_TopMenuHandle; - -void Initialize_Natives() -{ - hTopMenuType = handlesys->CreateType("ITopMenu", - &s_TopMenuHandle, - 0, - NULL, - NULL, - myself->GetIdentity(), - NULL); -} - -void Shutdown_Natives() -{ - handlesys->RemoveType(hTopMenuType, myself->GetIdentity()); -} - -enum TopMenuAction -{ - TopMenuAction_DisplayOption = 0, - TopMenuAction_DisplayTitle = 1, - TopMenuAction_SelectOption = 2, - TopMenuAction_DrawOption = 3, - TopMenuAction_RemoveObject = 4, -}; - -class TopMenuCallbacks : public ITopMenuObjectCallbacks -{ -public: - TopMenuCallbacks(IPluginFunction *pFunction) : m_pFunction(pFunction) - { - } - - unsigned int OnTopMenuDrawOption(ITopMenu *menu, - int client, - unsigned int object_id) - { - char buffer[2] = {ITEMDRAW_DEFAULT, 0x0}; - m_pFunction->PushCell(m_hMenuHandle); - m_pFunction->PushCell(TopMenuAction_DrawOption); - m_pFunction->PushCell(object_id); - m_pFunction->PushCell(client); - m_pFunction->PushStringEx(buffer, sizeof(buffer), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); - m_pFunction->PushCell(sizeof(buffer)); - m_pFunction->Execute(NULL); - return (unsigned int)buffer[0]; - } - - void OnTopMenuDisplayOption(ITopMenu *menu, - int client, - unsigned int object_id, - char buffer[], - size_t maxlength) - { - m_pFunction->PushCell(m_hMenuHandle); - m_pFunction->PushCell(TopMenuAction_DisplayOption); - m_pFunction->PushCell(object_id); - m_pFunction->PushCell(client); - m_pFunction->PushStringEx(buffer, maxlength, 0, SM_PARAM_COPYBACK); - m_pFunction->PushCell(maxlength); - m_pFunction->Execute(NULL); - } - - void OnTopMenuDisplayTitle(ITopMenu *menu, - int client, - unsigned int object_id, - char buffer[], - size_t maxlength) - { - m_pFunction->PushCell(m_hMenuHandle); - m_pFunction->PushCell(TopMenuAction_DisplayTitle); - m_pFunction->PushCell(object_id); - m_pFunction->PushCell(client); - m_pFunction->PushStringEx(buffer, maxlength, 0, SM_PARAM_COPYBACK); - m_pFunction->PushCell(maxlength); - m_pFunction->Execute(NULL); - } - - void OnTopMenuSelectOption(ITopMenu *menu, - int client, - unsigned int object_id) - { - unsigned int old_reply = playerhelpers->SetReplyTo(SM_REPLY_CHAT); - m_pFunction->PushCell(m_hMenuHandle); - m_pFunction->PushCell(TopMenuAction_SelectOption); - m_pFunction->PushCell(object_id); - m_pFunction->PushCell(client); - m_pFunction->PushString(""); - m_pFunction->PushCell(0); - m_pFunction->Execute(NULL); - playerhelpers->SetReplyTo(old_reply); - } - - void OnTopMenuObjectRemoved(ITopMenu *menu, unsigned int object_id) - { - m_pFunction->PushCell(m_hMenuHandle); - m_pFunction->PushCell(TopMenuAction_RemoveObject); - m_pFunction->PushCell(object_id); - m_pFunction->PushCell(0); - m_pFunction->PushString(""); - m_pFunction->PushCell(0); - m_pFunction->Execute(NULL); - - delete this; - } - - Handle_t m_hMenuHandle; - IPluginFunction *m_pFunction; -}; - -static cell_t CreateTopMenu(IPluginContext *pContext, const cell_t *params) -{ - IPluginFunction *func = pContext->GetFunctionById(params[1]); - if (func == NULL) - { - return pContext ->ThrowNativeError("Invalid function specified"); - } - - TopMenuCallbacks *cb = new TopMenuCallbacks(func); - - ITopMenu *pMenu = g_TopMenus.CreateTopMenu(cb); - - if (!pMenu) - { - delete cb; - return BAD_HANDLE; - } - - Handle_t hndl = handlesys->CreateHandle(hTopMenuType, - pMenu, - pContext->GetIdentity(), - myself->GetIdentity(), - NULL); - if (hndl == 0) - { - g_TopMenus.DestroyTopMenu(pMenu); - return BAD_HANDLE; - } - - cb->m_hMenuHandle = hndl; - - return hndl; -} - -static cell_t LoadTopMenuConfig(IPluginContext *pContext, const cell_t *params) -{ - HandleError err; - ITopMenu *pMenu; - HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); - - if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); - } - - char *file, *err_buf; - pContext->LocalToString(params[2], &file); - pContext->LocalToString(params[3], &err_buf); - - char path[PLATFORM_MAX_PATH]; - g_pSM->BuildPath(Path_Game, path, sizeof(path), "%s", file); - - return pMenu->LoadConfiguration(path, err_buf, params[4]) ? 1 : 0; -} - -static cell_t AddToTopMenu(IPluginContext *pContext, const cell_t *params) -{ - HandleError err; - ITopMenu *pMenu; - HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); - - if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); - } - - IPluginFunction *func = pContext->GetFunctionById(params[4]); - if (func == NULL) - { - return pContext ->ThrowNativeError("Invalid function specified"); - } - - TopMenuCallbacks *cb = new TopMenuCallbacks(func); - - char *name, *cmdname, *info_string = NULL; - pContext->LocalToString(params[2], &name); - pContext->LocalToString(params[6], &cmdname); - - if (params[0] >= 8) - { - pContext->LocalToString(params[8], &info_string); - } - - TopMenuObjectType obj_type = (TopMenuObjectType)params[3]; - - unsigned int object_id; - if ((object_id = pMenu->AddToMenu2(name, - obj_type, - cb, - pContext->GetIdentity(), - cmdname, - params[7], - params[5], - info_string)) == 0) - { - delete cb; - return 0; - } - - cb->m_hMenuHandle = params[1]; - - return object_id; -} - -static cell_t RemoveFromTopMenu(IPluginContext *pContext, const cell_t *params) -{ - HandleError err; - ITopMenu *pMenu; - HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); - - if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); - } - - pMenu->RemoveFromMenu(params[2]); - - return 1; -} - -static cell_t FindTopMenuCategory(IPluginContext *pContext, const cell_t *params) -{ - HandleError err; - ITopMenu *pMenu; - HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); - - if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); - } - - char *name; - pContext->LocalToString(params[2], &name); - - return pMenu->FindCategory(name); -} - -static cell_t DisplayTopMenu(IPluginContext *pContext, const cell_t *params) -{ - HandleError err; - ITopMenu *pMenu; - HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); - - if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); - } - - int client = params[2]; - IGamePlayer *player = playerhelpers->GetGamePlayer(client); - if (!player) - { - return pContext->ThrowNativeError("Invalid client index %d", client); - } - else if (!player->IsInGame()) - { - return pContext->ThrowNativeError("Client %d is not in game", client); - } - - return pMenu->DisplayMenu(client, 0, (TopMenuPosition)params[3]); -} - -static cell_t GetTopMenuInfoString(IPluginContext *pContext, const cell_t *params) -{ - HandleError err; - ITopMenu *pMenu; - HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); - - if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); - } - - const char *str; - if ((str = pMenu->GetObjectInfoString(params[2])) == NULL) - { - return pContext->ThrowNativeError("Invalid menu object %d", params[2]); - } - - char *buffer; - pContext->LocalToString(params[3], &buffer); - - return strncopy(buffer, str, params[4]); -} - -static cell_t GetTopMenuName(IPluginContext *pContext, const cell_t *params) -{ - HandleError err; - ITopMenu *pMenu; - HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); - - if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); - } - - const char *str; - if ((str = pMenu->GetObjectName(params[2])) == NULL) - { - return pContext->ThrowNativeError("Invalid menu object %d", params[2]); - } - - char *buffer; - pContext->LocalToString(params[3], &buffer); - - return strncopy(buffer, str, params[4]); -} - -sp_nativeinfo_t g_TopMenuNatives[] = -{ - {"AddToTopMenu", AddToTopMenu}, - {"CreateTopMenu", CreateTopMenu}, - {"DisplayTopMenu", DisplayTopMenu}, - {"LoadTopMenuConfig", LoadTopMenuConfig}, - {"RemoveFromTopMenu", RemoveFromTopMenu}, - {"FindTopMenuCategory", FindTopMenuCategory}, - {"GetTopMenuInfoString", GetTopMenuInfoString}, - {"GetTopMenuObjName", GetTopMenuName}, - {NULL, NULL}, -}; +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod TopMenus Extension + * 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$ + */ + +#include "extension.h" +#include "TopMenuManager.h" +#include "TopMenu.h" + +HandleType_t hTopMenuType; + +class TopMenuHandle : public IHandleTypeDispatch +{ +public: + void OnHandleDestroy(HandleType_t type, void *object) + { + ITopMenu *pTopMenu = (ITopMenu *)object; + g_TopMenus.DestroyTopMenu(pTopMenu); + } + bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize) + { + *pSize = ((TopMenu *)object)->CalcMemUsage(); + return true; + } +} s_TopMenuHandle; + +void Initialize_Natives() +{ + hTopMenuType = handlesys->CreateType("ITopMenu", + &s_TopMenuHandle, + 0, + NULL, + NULL, + myself->GetIdentity(), + NULL); +} + +void Shutdown_Natives() +{ + handlesys->RemoveType(hTopMenuType, myself->GetIdentity()); +} + +enum TopMenuAction +{ + TopMenuAction_DisplayOption = 0, + TopMenuAction_DisplayTitle = 1, + TopMenuAction_SelectOption = 2, + TopMenuAction_DrawOption = 3, + TopMenuAction_RemoveObject = 4, +}; + +class TopMenuCallbacks : public ITopMenuObjectCallbacks +{ +public: + TopMenuCallbacks(IPluginFunction *pFunction) : m_pFunction(pFunction) + { + } + + unsigned int OnTopMenuDrawOption(ITopMenu *menu, + int client, + unsigned int object_id) + { + char buffer[2] = {ITEMDRAW_DEFAULT, 0x0}; + m_pFunction->PushCell(m_hMenuHandle); + m_pFunction->PushCell(TopMenuAction_DrawOption); + m_pFunction->PushCell(object_id); + m_pFunction->PushCell(client); + m_pFunction->PushStringEx(buffer, sizeof(buffer), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); + m_pFunction->PushCell(sizeof(buffer)); + m_pFunction->Execute(NULL); + return (unsigned int)buffer[0]; + } + + void OnTopMenuDisplayOption(ITopMenu *menu, + int client, + unsigned int object_id, + char buffer[], + size_t maxlength) + { + m_pFunction->PushCell(m_hMenuHandle); + m_pFunction->PushCell(TopMenuAction_DisplayOption); + m_pFunction->PushCell(object_id); + m_pFunction->PushCell(client); + m_pFunction->PushStringEx(buffer, maxlength, 0, SM_PARAM_COPYBACK); + m_pFunction->PushCell(maxlength); + m_pFunction->Execute(NULL); + } + + void OnTopMenuDisplayTitle(ITopMenu *menu, + int client, + unsigned int object_id, + char buffer[], + size_t maxlength) + { + m_pFunction->PushCell(m_hMenuHandle); + m_pFunction->PushCell(TopMenuAction_DisplayTitle); + m_pFunction->PushCell(object_id); + m_pFunction->PushCell(client); + m_pFunction->PushStringEx(buffer, maxlength, 0, SM_PARAM_COPYBACK); + m_pFunction->PushCell(maxlength); + m_pFunction->Execute(NULL); + } + + void OnTopMenuSelectOption(ITopMenu *menu, + int client, + unsigned int object_id) + { + unsigned int old_reply = playerhelpers->SetReplyTo(SM_REPLY_CHAT); + m_pFunction->PushCell(m_hMenuHandle); + m_pFunction->PushCell(TopMenuAction_SelectOption); + m_pFunction->PushCell(object_id); + m_pFunction->PushCell(client); + m_pFunction->PushString(""); + m_pFunction->PushCell(0); + m_pFunction->Execute(NULL); + playerhelpers->SetReplyTo(old_reply); + } + + void OnTopMenuObjectRemoved(ITopMenu *menu, unsigned int object_id) + { + m_pFunction->PushCell(m_hMenuHandle); + m_pFunction->PushCell(TopMenuAction_RemoveObject); + m_pFunction->PushCell(object_id); + m_pFunction->PushCell(0); + m_pFunction->PushString(""); + m_pFunction->PushCell(0); + m_pFunction->Execute(NULL); + + delete this; + } + + Handle_t m_hMenuHandle; + IPluginFunction *m_pFunction; +}; + +static cell_t CreateTopMenu(IPluginContext *pContext, const cell_t *params) +{ + IPluginFunction *func = pContext->GetFunctionById(params[1]); + if (func == NULL) + { + return pContext ->ThrowNativeError("Invalid function specified"); + } + + TopMenuCallbacks *cb = new TopMenuCallbacks(func); + + ITopMenu *pMenu = g_TopMenus.CreateTopMenu(cb); + + if (!pMenu) + { + delete cb; + return BAD_HANDLE; + } + + Handle_t hndl = handlesys->CreateHandle(hTopMenuType, + pMenu, + pContext->GetIdentity(), + myself->GetIdentity(), + NULL); + if (hndl == 0) + { + g_TopMenus.DestroyTopMenu(pMenu); + return BAD_HANDLE; + } + + cb->m_hMenuHandle = hndl; + + return hndl; +} + +static cell_t LoadTopMenuConfig(IPluginContext *pContext, const cell_t *params) +{ + HandleError err; + ITopMenu *pMenu; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); + } + + char *file, *err_buf; + pContext->LocalToString(params[2], &file); + pContext->LocalToString(params[3], &err_buf); + + char path[PLATFORM_MAX_PATH]; + g_pSM->BuildPath(Path_Game, path, sizeof(path), "%s", file); + + return pMenu->LoadConfiguration(path, err_buf, params[4]) ? 1 : 0; +} + +static cell_t AddToTopMenu(IPluginContext *pContext, const cell_t *params) +{ + HandleError err; + ITopMenu *pMenu; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); + } + + IPluginFunction *func = pContext->GetFunctionById(params[4]); + if (func == NULL) + { + return pContext ->ThrowNativeError("Invalid function specified"); + } + + TopMenuCallbacks *cb = new TopMenuCallbacks(func); + + char *name, *cmdname, *info_string = NULL; + pContext->LocalToString(params[2], &name); + pContext->LocalToString(params[6], &cmdname); + + if (params[0] >= 8) + { + pContext->LocalToString(params[8], &info_string); + } + + TopMenuObjectType obj_type = (TopMenuObjectType)params[3]; + + unsigned int object_id; + if ((object_id = pMenu->AddToMenu2(name, + obj_type, + cb, + pContext->GetIdentity(), + cmdname, + params[7], + params[5], + info_string)) == 0) + { + delete cb; + return 0; + } + + cb->m_hMenuHandle = params[1]; + + return object_id; +} + +static cell_t RemoveFromTopMenu(IPluginContext *pContext, const cell_t *params) +{ + HandleError err; + ITopMenu *pMenu; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); + } + + pMenu->RemoveFromMenu(params[2]); + + return 1; +} + +static cell_t FindTopMenuCategory(IPluginContext *pContext, const cell_t *params) +{ + HandleError err; + ITopMenu *pMenu; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); + } + + char *name; + pContext->LocalToString(params[2], &name); + + return pMenu->FindCategory(name); +} + +static cell_t DisplayTopMenu(IPluginContext *pContext, const cell_t *params) +{ + HandleError err; + ITopMenu *pMenu; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); + } + + int client = params[2]; + IGamePlayer *player = playerhelpers->GetGamePlayer(client); + if (!player) + { + return pContext->ThrowNativeError("Invalid client index %d", client); + } + else if (!player->IsInGame()) + { + return pContext->ThrowNativeError("Client %d is not in game", client); + } + + return pMenu->DisplayMenu(client, 0, (TopMenuPosition)params[3]); +} + +static cell_t GetTopMenuInfoString(IPluginContext *pContext, const cell_t *params) +{ + HandleError err; + ITopMenu *pMenu; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); + } + + const char *str; + if ((str = pMenu->GetObjectInfoString(params[2])) == NULL) + { + return pContext->ThrowNativeError("Invalid menu object %d", params[2]); + } + + char *buffer; + pContext->LocalToString(params[3], &buffer); + + return strncopy(buffer, str, params[4]); +} + +static cell_t GetTopMenuName(IPluginContext *pContext, const cell_t *params) +{ + HandleError err; + ITopMenu *pMenu; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); + } + + const char *str; + if ((str = pMenu->GetObjectName(params[2])) == NULL) + { + return pContext->ThrowNativeError("Invalid menu object %d", params[2]); + } + + char *buffer; + pContext->LocalToString(params[3], &buffer); + + return strncopy(buffer, str, params[4]); +} + +sp_nativeinfo_t g_TopMenuNatives[] = +{ + {"AddToTopMenu", AddToTopMenu}, + {"CreateTopMenu", CreateTopMenu}, + {"DisplayTopMenu", DisplayTopMenu}, + {"LoadTopMenuConfig", LoadTopMenuConfig}, + {"RemoveFromTopMenu", RemoveFromTopMenu}, + {"FindTopMenuCategory", FindTopMenuCategory}, + {"GetTopMenuInfoString", GetTopMenuInfoString}, + {"GetTopMenuObjName", GetTopMenuName}, + {NULL, NULL}, +}; diff --git a/extensions/topmenus/smn_topmenus.h b/extensions/topmenus/smn_topmenus.h index dd216b3c..120bfbed 100644 --- a/extensions/topmenus/smn_topmenus.h +++ b/extensions/topmenus/smn_topmenus.h @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod Sample Extension + * SourceMod TopMenus Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/extensions/topmenus/svn_version.h b/extensions/topmenus/svn_version.h index 6cd85684..cf0fc49d 100644 --- a/extensions/topmenus/svn_version.h +++ b/extensions/topmenus/svn_version.h @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod SQLite Extension + * SourceMod TopMenus Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/extensions/topmenus/svn_version.tpl b/extensions/topmenus/svn_version.tpl index 2473a102..8d0d91e6 100644 --- a/extensions/topmenus/svn_version.tpl +++ b/extensions/topmenus/svn_version.tpl @@ -1,7 +1,7 @@ /** * vim: set ts=4 : * ============================================================================= - * SourceMod SQLite Extension + * SourceMod TopMenus Extension * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * diff --git a/plugins/basebans/ban.sp b/plugins/basebans/ban.sp index 9efdb4db..28abb15a 100644 --- a/plugins/basebans/ban.sp +++ b/plugins/basebans/ban.sp @@ -28,7 +28,7 @@ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * or . * - * Version: $Id: admin-flatfile.sp 1438 2007-09-16 03:45:06Z dvander $ + * Version: $Id$ */ PrepareBan(client, target, time, const String:reason[]) diff --git a/plugins/basecomm/gag.sp b/plugins/basecomm/gag.sp index f29753db..5299a0d6 100644 --- a/plugins/basecomm/gag.sp +++ b/plugins/basecomm/gag.sp @@ -28,7 +28,7 @@ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * or . * - * Version: $Id: admin-flatfile.sp 1438 2007-09-16 03:45:06Z dvander $ + * Version: $Id$ */ enum CommType diff --git a/plugins/basecommands/cancelvote.sp b/plugins/basecommands/cancelvote.sp index 106e3dc4..58029793 100644 --- a/plugins/basecommands/cancelvote.sp +++ b/plugins/basecommands/cancelvote.sp @@ -1,75 +1,75 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod Basecommands Plugin - * Provides cancelvote functionality. - * - * SourceMod (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: admin-flatfile.sp 1438 2007-09-16 03:45:06Z dvander $ - */ - -PerformCancelVote(client) -{ - if (!IsVoteInProgress()) - { - ReplyToCommand(client, "[SM] %t", "Vote Not In Progress"); - return; - } - - ShowActivity2(client, "[SM] ", "%t", "Cancelled Vote"); - - CancelVote(); -} - -public AdminMenu_CancelVote(Handle:topmenu, - TopMenuAction:action, - TopMenuObject:object_id, - param, - String:buffer[], - maxlength) -{ - if (action == TopMenuAction_DisplayOption) - { - Format(buffer, maxlength, "%T", "Cancel vote", param); - } - else if (action == TopMenuAction_SelectOption) - { - PerformCancelVote(param); - RedisplayAdminMenu(topmenu, param); - } - else if (action == TopMenuAction_DrawOption) - { - buffer[0] = IsVoteInProgress() ? ITEMDRAW_DEFAULT : ITEMDRAW_IGNORE; - } -} - -public Action:Command_CancelVote(client, args) -{ - PerformCancelVote(client); - - return Plugin_Handled; -} - +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Basecommands Plugin + * Provides cancelvote functionality. + * + * SourceMod (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$ + */ + +PerformCancelVote(client) +{ + if (!IsVoteInProgress()) + { + ReplyToCommand(client, "[SM] %t", "Vote Not In Progress"); + return; + } + + ShowActivity2(client, "[SM] ", "%t", "Cancelled Vote"); + + CancelVote(); +} + +public AdminMenu_CancelVote(Handle:topmenu, + TopMenuAction:action, + TopMenuObject:object_id, + param, + String:buffer[], + maxlength) +{ + if (action == TopMenuAction_DisplayOption) + { + Format(buffer, maxlength, "%T", "Cancel vote", param); + } + else if (action == TopMenuAction_SelectOption) + { + PerformCancelVote(param); + RedisplayAdminMenu(topmenu, param); + } + else if (action == TopMenuAction_DrawOption) + { + buffer[0] = IsVoteInProgress() ? ITEMDRAW_DEFAULT : ITEMDRAW_IGNORE; + } +} + +public Action:Command_CancelVote(client, args) +{ + PerformCancelVote(client); + + return Plugin_Handled; +} + diff --git a/plugins/basecommands/execcfg.sp b/plugins/basecommands/execcfg.sp index 9b1af7f1..8feb56d3 100644 --- a/plugins/basecommands/execcfg.sp +++ b/plugins/basecommands/execcfg.sp @@ -28,7 +28,7 @@ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * or . * - * Version: $Id: admin-flatfile.sp 1438 2007-09-16 03:45:06Z dvander $ + * Version: $Id$ */ new Handle:g_ConfigMenu = INVALID_HANDLE; diff --git a/plugins/basecommands/map.sp b/plugins/basecommands/map.sp index 3779c11c..1e003c78 100644 --- a/plugins/basecommands/map.sp +++ b/plugins/basecommands/map.sp @@ -28,7 +28,7 @@ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * or . * - * Version: $Id: admin-flatfile.sp 1438 2007-09-16 03:45:06Z dvander $ + * Version: $Id$ */ public MenuHandler_ChangeMap(Handle:menu, MenuAction:action, param1, param2) diff --git a/plugins/basecommands/who.sp b/plugins/basecommands/who.sp index a9e64b5a..d3766640 100644 --- a/plugins/basecommands/who.sp +++ b/plugins/basecommands/who.sp @@ -28,7 +28,7 @@ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * or . * - * Version: $Id: admin-flatfile.sp 1438 2007-09-16 03:45:06Z dvander $ + * Version: $Id$ */ PerformWho(client, target, ReplySource:reply, bool:is_admin) diff --git a/plugins/basevotes/voteban.sp b/plugins/basevotes/voteban.sp index 10cc11fb..80c28a18 100644 --- a/plugins/basevotes/voteban.sp +++ b/plugins/basevotes/voteban.sp @@ -28,7 +28,7 @@ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * or . * - * Version: $Id: admin-flatfile.sp 1438 2007-09-16 03:45:06Z dvander $ + * Version: $Id$ */ DisplayVoteBanMenu(client, target) diff --git a/plugins/basevotes/votekick.sp b/plugins/basevotes/votekick.sp index e3213b47..8f7d2e4f 100644 --- a/plugins/basevotes/votekick.sp +++ b/plugins/basevotes/votekick.sp @@ -28,7 +28,7 @@ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * or . * - * Version: $Id: admin-flatfile.sp 1438 2007-09-16 03:45:06Z dvander $ + * Version: $Id$ */ diff --git a/plugins/basevotes/votemap.sp b/plugins/basevotes/votemap.sp index 968d7074..9e16930a 100644 --- a/plugins/basevotes/votemap.sp +++ b/plugins/basevotes/votemap.sp @@ -28,7 +28,7 @@ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * or . * - * Version: $Id: admin-flatfile.sp 1438 2007-09-16 03:45:06Z dvander $ + * Version: $Id$ */ new Handle:g_MapList = INVALID_HANDLE; diff --git a/plugins/funvotes/votealltalk.sp b/plugins/funvotes/votealltalk.sp index 43bd15c3..561b2274 100644 --- a/plugins/funvotes/votealltalk.sp +++ b/plugins/funvotes/votealltalk.sp @@ -28,7 +28,7 @@ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * or . * - * Version: $Id: admin-flatfile.sp 1438 2007-09-16 03:45:06Z dvander $ + * Version: $Id$ */ DisplayVoteAllTalkMenu(client) diff --git a/plugins/funvotes/voteburn.sp b/plugins/funvotes/voteburn.sp index 403da2e5..42573a17 100644 --- a/plugins/funvotes/voteburn.sp +++ b/plugins/funvotes/voteburn.sp @@ -28,7 +28,7 @@ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * or . * - * Version: $Id: admin-flatfile.sp 1438 2007-09-16 03:45:06Z dvander $ + * Version: $Id$ */ DisplayVoteBurnMenu(client, target, String:name[]) diff --git a/plugins/funvotes/voteff.sp b/plugins/funvotes/voteff.sp index b032c3c2..e12934cc 100644 --- a/plugins/funvotes/voteff.sp +++ b/plugins/funvotes/voteff.sp @@ -28,7 +28,7 @@ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * or . * - * Version: $Id: admin-flatfile.sp 1438 2007-09-16 03:45:06Z dvander $ + * Version: $Id$ */ DisplayVoteFFMenu(client) diff --git a/plugins/funvotes/votegravity.sp b/plugins/funvotes/votegravity.sp index 63086da6..d3de3572 100644 --- a/plugins/funvotes/votegravity.sp +++ b/plugins/funvotes/votegravity.sp @@ -28,7 +28,7 @@ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * or . * - * Version: $Id: admin-flatfile.sp 1438 2007-09-16 03:45:06Z dvander $ + * Version: $Id$ */ diff --git a/plugins/funvotes/voteslay.sp b/plugins/funvotes/voteslay.sp index e0637cea..395b9e31 100644 --- a/plugins/funvotes/voteslay.sp +++ b/plugins/funvotes/voteslay.sp @@ -28,7 +28,7 @@ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * or . * - * Version: $Id: admin-flatfile.sp 1438 2007-09-16 03:45:06Z dvander $ + * Version: $Id$ */ diff --git a/plugins/include/bitbuffer.inc b/plugins/include/bitbuffer.inc index fd1c18ec..4326d561 100644 --- a/plugins/include/bitbuffer.inc +++ b/plugins/include/bitbuffer.inc @@ -1,325 +1,325 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This file is part of the SourceMod/SourcePawn SDK. - * - * 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$ - */ - -#if defined _bitbuffer_included - #endinput -#endif -#define _bitbuffer_included - -/** - * Writes a single bit to a writable bitbuffer (bf_write). - * - * @param bf bf_write handle to write to. - * @param bit Bit to write (true for 1, false for 0). - * @noreturn - * @error Invalid or incorrect Handle. - */ -native BfWriteBool(Handle:bf, bool:bit); - -/** - * Writes a byte to a writable bitbuffer (bf_write). - * - * @param bf bf_write handle to write to. - * @param byte Byte to write (value will be written as 8bit). - * @noreturn - * @error Invalid or incorrect Handle. - */ -native BfWriteByte(Handle:bf, byte); - -/** - * Writes a byte to a writable bitbuffer (bf_write). - * - * @param bf bf_write handle to write to. - * @param chr Character to write. - * @noreturn - * @error Invalid or incorrect Handle. - */ -native BfWriteChar(Handle:bf, chr); - -/** - * Writes a 16bit integer to a writable bitbuffer (bf_write). - * - * @param bf bf_write handle to write to. - * @param num Integer to write (value will be written as 16bit). - * @noreturn - * @error Invalid or incorrect Handle. - */ -native BfWriteShort(Handle:bf, num); - -/** - * Writes a 16bit unsigned integer to a writable bitbuffer (bf_write). - * - * @param bf bf_write handle to write to. - * @param num Integer to write (value will be written as 16bit). - * @noreturn - * @error Invalid or incorrect Handle. - */ -native BfWriteWord(Handle:bf, num); - -/** - * Writes a normal integer to a writable bitbuffer (bf_write). - * - * @param bf bf_write handle to write to. - * @param num Integer to write (value will be written as 32bit). - * @noreturn - * @error Invalid or incorrect Handle. - */ -native BfWriteNum(Handle:bf, num); - -/** - * Writes a floating point number to a writable bitbuffer (bf_write). - * - * @param bf bf_write handle to write to. - * @param num Number to write. - * @noreturn - * @error Invalid or incorrect Handle. - */ -native BfWriteFloat(Handle:bf, Float:num); - -/** - * Writes a string to a writable bitbuffer (bf_write). - * - * @param bf bf_write handle to write to. - * @param string Text string to write. - * @noreturn - * @error Invalid or incorrect Handle. - */ -native BfWriteString(Handle:bf, const String:string[]); - -/** - * Writes an entity to a writable bitbuffer (bf_write). - * @note This is a wrapper around BfWriteShort(). - * - * @param bf bf_write handle to write to. - * @param ent Entity index to write. - * @noreturn - * @error Invalid or incorrect Handle, or invalid entity. - */ -native BfWriteEntity(Handle:bf, ent); - -/** - * Writes a bit angle to a writable bitbuffer (bf_write). - * - * @param bf bf_write handle to write to. - * @param angle Angle to write. - * @param numBits Optional number of bits to use. - * @noreturn - * @error Invalid or incorrect Handle. - */ -native BfWriteAngle(Handle:bf, Float:angle, numBits=8); - -/** - * Writes a coordinate to a writable bitbuffer (bf_write). - * - * @param bf bf_write handle to write to. - * @param coord Coordinate to write. - * @noreturn - * @error Invalid or incorrect Handle. - */ -native BfWriteCoord(Handle:bf, Float:coord); - -/** - * Writes a 3D vector of coordinates to a writable bitbuffer (bf_write). - * - * @param bf bf_write handle to write to. - * @param coord Coordinate array to write. - * @noreturn - * @error Invalid or incorrect Handle. - */ -native BfWriteVecCoord(Handle:bf, Float:coord[3]); - -/** - * Writes a 3D normal vector to a writable bitbuffer (bf_write). - * - * @param bf bf_write handle to write to. - * @param vec Vector to write. - * @noreturn - * @error Invalid or incorrect Handle. - */ -native BfWriteVecNormal(Handle:bf, Float:vec[3]); - -/** - * Writes a 3D angle vector to a writable bitbuffer (bf_write). - * - * @param bf bf_write handle to write to. - * @param angles Angle vector to write. - * @noreturn - * @error Invalid or incorrect Handle. - */ -native BfWriteAngles(Handle:bf, Float:angles[3]); - -/** - * Reads a single bit from a readable bitbuffer (bf_read). - * - * @param bf bf_read handle to read from. - * @return Bit value read. - * @error Invalid or incorrect Handle. - */ -native bool:BfReadBool(Handle:bf); - -/** - * Reads a byte from a readable bitbuffer (bf_read). - * - * @param bf bf_read handle to read from. - * @return Byte value read (read as 8bit). - * @error Invalid or incorrect Handle. - */ -native BfReadByte(Handle:bf); - -/** - * Reads a character from a readable bitbuffer (bf_read). - * - * @param bf bf_read handle to read from. - * @return Character value read. - * @error Invalid or incorrect Handle. - */ -native BfReadChar(Handle:bf); - -/** - * Reads a 16bit integer from a readable bitbuffer (bf_read). - * - * @param bf bf_read handle to read from. - * @return Integer value read (read as 16bit). - * @error Invalid or incorrect Handle. - */ -native BfReadShort(Handle:bf); - -/** - * Reads a 16bit unsigned integer from a readable bitbuffer (bf_read). - * - * @param bf bf_read handle to read from. - * @return Integer value read (read as 16bit). - * @error Invalid or incorrect Handle. - */ -native BfReadWord(Handle:bf); - -/** - * Reads a normal integer to a readable bitbuffer (bf_read). - * - * @param bf bf_read handle to read from. - * @return Integer value read (read as 32bit). - * @error Invalid or incorrect Handle. - */ -native BfReadNum(Handle:bf); - -/** - * Reads a floating point number from a readable bitbuffer (bf_read). - * - * @param bf bf_read handle to read from. - * @return Floating point value read. - * @error Invalid or incorrect Handle. - */ -native Float:BfReadFloat(Handle:bf); - -/** - * Reads a string from a readable bitbuffer (bf_read). - * - * @param bf bf_read handle to read from. - * @param buffer Destination string buffer. - * @param maxlength Maximum length of output string buffer. - * @param line If true the buffer will be copied until it reaches a '\n' or a null terminator. - * @return Number of bytes written to the buffer. If the bitbuffer stream overflowed, - * that is, had no terminator before the end of the stream, then a negative - * number will be returned equal to the number of characters written to the - * buffer minus 1. The buffer will be null terminated regardless of the - * return value. - * @error Invalid or incorrect Handle. - */ -native BfReadString(Handle:bf, String:buffer[], maxlength, bool:line=false); - -/** - * Reads an entity from a readable bitbuffer (bf_read). - * @note This is a wrapper around BfReadShort(). - * - * @param bf bf_read handle to read from. - * @return Entity index read. - * @error Invalid or incorrect Handle. - */ -native BfReadEntity(Handle:bf); - -/** - * Reads a bit angle from a readable bitbuffer (bf_read). - * - * @param bf bf_read handle to read from. - * @param numBits Optional number of bits to use. - * @return Angle read. - * @error Invalid or incorrect Handle. - */ -native Float:BfReadAngle(Handle:bf, numBits=8); - -/** - * Reads a coordinate from a readable bitbuffer (bf_read). - * - * @param bf bf_read handle to read from. - * @return Coordinate read. - * @error Invalid or incorrect Handle. - */ -native Float:BfReadCoord(Handle:bf); - -/** - * Reads a 3D vector of coordinates from a readable bitbuffer (bf_read). - * - * @param bf bf_read handle to read from. - * @param coord Destination coordinate array. - * @noreturn - * @error Invalid or incorrect Handle. - */ -native BfReadVecCoord(Handle:bf, Float:coord[3]); - -/** - * Reads a 3D normal vector from a readable bitbuffer (bf_read). - * - * @param bf bf_read handle to read from. - * @param vec Destination vector array. - * @noreturn - * @error Invalid or incorrect Handle. - */ -native BfReadVecNormal(Handle:bf, Float:vec[3]); - -/** - * Reads a 3D angle vector from a readable bitbuffer (bf_read). - * - * @param bf bf_read handle to read from. - * @param angles Destination angle vector. - * @noreturn - * @error Invalid or incorrect Handle. - */ -native BfReadAngles(Handle:bf, Float:angles[3]); - -/** - * Returns the number of bytes left in a readable bitbuffer (bf_read). - * - * @param bf bf_read handle to read from. - * @return Number of bytes left unread. - * @error Invalid or incorrect Handle. - */ -native BfGetNumBytesLeft(Handle:bf); +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This file is part of the SourceMod/SourcePawn SDK. + * + * 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$ + */ + +#if defined _bitbuffer_included + #endinput +#endif +#define _bitbuffer_included + +/** + * Writes a single bit to a writable bitbuffer (bf_write). + * + * @param bf bf_write handle to write to. + * @param bit Bit to write (true for 1, false for 0). + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfWriteBool(Handle:bf, bool:bit); + +/** + * Writes a byte to a writable bitbuffer (bf_write). + * + * @param bf bf_write handle to write to. + * @param byte Byte to write (value will be written as 8bit). + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfWriteByte(Handle:bf, byte); + +/** + * Writes a byte to a writable bitbuffer (bf_write). + * + * @param bf bf_write handle to write to. + * @param chr Character to write. + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfWriteChar(Handle:bf, chr); + +/** + * Writes a 16bit integer to a writable bitbuffer (bf_write). + * + * @param bf bf_write handle to write to. + * @param num Integer to write (value will be written as 16bit). + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfWriteShort(Handle:bf, num); + +/** + * Writes a 16bit unsigned integer to a writable bitbuffer (bf_write). + * + * @param bf bf_write handle to write to. + * @param num Integer to write (value will be written as 16bit). + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfWriteWord(Handle:bf, num); + +/** + * Writes a normal integer to a writable bitbuffer (bf_write). + * + * @param bf bf_write handle to write to. + * @param num Integer to write (value will be written as 32bit). + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfWriteNum(Handle:bf, num); + +/** + * Writes a floating point number to a writable bitbuffer (bf_write). + * + * @param bf bf_write handle to write to. + * @param num Number to write. + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfWriteFloat(Handle:bf, Float:num); + +/** + * Writes a string to a writable bitbuffer (bf_write). + * + * @param bf bf_write handle to write to. + * @param string Text string to write. + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfWriteString(Handle:bf, const String:string[]); + +/** + * Writes an entity to a writable bitbuffer (bf_write). + * @note This is a wrapper around BfWriteShort(). + * + * @param bf bf_write handle to write to. + * @param ent Entity index to write. + * @noreturn + * @error Invalid or incorrect Handle, or invalid entity. + */ +native BfWriteEntity(Handle:bf, ent); + +/** + * Writes a bit angle to a writable bitbuffer (bf_write). + * + * @param bf bf_write handle to write to. + * @param angle Angle to write. + * @param numBits Optional number of bits to use. + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfWriteAngle(Handle:bf, Float:angle, numBits=8); + +/** + * Writes a coordinate to a writable bitbuffer (bf_write). + * + * @param bf bf_write handle to write to. + * @param coord Coordinate to write. + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfWriteCoord(Handle:bf, Float:coord); + +/** + * Writes a 3D vector of coordinates to a writable bitbuffer (bf_write). + * + * @param bf bf_write handle to write to. + * @param coord Coordinate array to write. + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfWriteVecCoord(Handle:bf, Float:coord[3]); + +/** + * Writes a 3D normal vector to a writable bitbuffer (bf_write). + * + * @param bf bf_write handle to write to. + * @param vec Vector to write. + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfWriteVecNormal(Handle:bf, Float:vec[3]); + +/** + * Writes a 3D angle vector to a writable bitbuffer (bf_write). + * + * @param bf bf_write handle to write to. + * @param angles Angle vector to write. + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfWriteAngles(Handle:bf, Float:angles[3]); + +/** + * Reads a single bit from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Bit value read. + * @error Invalid or incorrect Handle. + */ +native bool:BfReadBool(Handle:bf); + +/** + * Reads a byte from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Byte value read (read as 8bit). + * @error Invalid or incorrect Handle. + */ +native BfReadByte(Handle:bf); + +/** + * Reads a character from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Character value read. + * @error Invalid or incorrect Handle. + */ +native BfReadChar(Handle:bf); + +/** + * Reads a 16bit integer from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Integer value read (read as 16bit). + * @error Invalid or incorrect Handle. + */ +native BfReadShort(Handle:bf); + +/** + * Reads a 16bit unsigned integer from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Integer value read (read as 16bit). + * @error Invalid or incorrect Handle. + */ +native BfReadWord(Handle:bf); + +/** + * Reads a normal integer to a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Integer value read (read as 32bit). + * @error Invalid or incorrect Handle. + */ +native BfReadNum(Handle:bf); + +/** + * Reads a floating point number from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Floating point value read. + * @error Invalid or incorrect Handle. + */ +native Float:BfReadFloat(Handle:bf); + +/** + * Reads a string from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @param buffer Destination string buffer. + * @param maxlength Maximum length of output string buffer. + * @param line If true the buffer will be copied until it reaches a '\n' or a null terminator. + * @return Number of bytes written to the buffer. If the bitbuffer stream overflowed, + * that is, had no terminator before the end of the stream, then a negative + * number will be returned equal to the number of characters written to the + * buffer minus 1. The buffer will be null terminated regardless of the + * return value. + * @error Invalid or incorrect Handle. + */ +native BfReadString(Handle:bf, String:buffer[], maxlength, bool:line=false); + +/** + * Reads an entity from a readable bitbuffer (bf_read). + * @note This is a wrapper around BfReadShort(). + * + * @param bf bf_read handle to read from. + * @return Entity index read. + * @error Invalid or incorrect Handle. + */ +native BfReadEntity(Handle:bf); + +/** + * Reads a bit angle from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @param numBits Optional number of bits to use. + * @return Angle read. + * @error Invalid or incorrect Handle. + */ +native Float:BfReadAngle(Handle:bf, numBits=8); + +/** + * Reads a coordinate from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Coordinate read. + * @error Invalid or incorrect Handle. + */ +native Float:BfReadCoord(Handle:bf); + +/** + * Reads a 3D vector of coordinates from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @param coord Destination coordinate array. + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfReadVecCoord(Handle:bf, Float:coord[3]); + +/** + * Reads a 3D normal vector from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @param vec Destination vector array. + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfReadVecNormal(Handle:bf, Float:vec[3]); + +/** + * Reads a 3D angle vector from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @param angles Destination angle vector. + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfReadAngles(Handle:bf, Float:angles[3]); + +/** + * Returns the number of bytes left in a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Number of bytes left unread. + * @error Invalid or incorrect Handle. + */ +native BfGetNumBytesLeft(Handle:bf); diff --git a/plugins/include/sdktools_trace.inc b/plugins/include/sdktools_trace.inc index f27b062c..da44bc4c 100644 --- a/plugins/include/sdktools_trace.inc +++ b/plugins/include/sdktools_trace.inc @@ -1,272 +1,272 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This file is part of the SourceMod/SourcePawn SDK. - * - * 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$ - */ - -#if defined _sdktools_trace_included - #endinput -#endif -#define _sdktools_trace_included - -#define CONTENTS_EMPTY 0 /**< No contents. */ -#define CONTENTS_SOLID 0x1 /**< an eye is never valid in a solid . */ -#define CONTENTS_WINDOW 0x2 /**< translucent, but not watery (glass). */ -#define CONTENTS_AUX 0x4 -#define CONTENTS_GRATE 0x8 /**< alpha-tested "grate" textures. Bullets/sight pass through, but solids don't. */ -#define CONTENTS_SLIME 0x10 -#define CONTENTS_WATER 0x20 -#define CONTENTS_MIST 0x40 -#define CONTENTS_OPAQUE 0x80 /**< things that cannot be seen through (may be non-solid though). */ -#define LAST_VISIBLE_CONTENTS 0x80 -#define ALL_VISIBLE_CONTENTS (LAST_VISIBLE_CONTENTS | (LAST_VISIBLE_CONTENTS-1)) -#define CONTENTS_TESTFOGVOLUME 0x100 -#define CONTENTS_UNUSED5 0x200 -#define CONTENTS_UNUSED6 0x4000 -#define CONTENTS_TEAM1 0x800 /**< per team contents used to differentiate collisions. */ -#define CONTENTS_TEAM2 0x1000 /**< between players and objects on different teams. */ -#define CONTENTS_IGNORE_NODRAW_OPAQUE 0x2000 /**< ignore CONTENTS_OPAQUE on surfaces that have SURF_NODRAW. */ -#define CONTENTS_MOVEABLE 0x4000 /**< hits entities which are MOVETYPE_PUSH (doors, plats, etc) */ -#define CONTENTS_AREAPORTAL 0x8000 /**< remaining contents are non-visible, and don't eat brushes. */ -#define CONTENTS_PLAYERCLIP 0x10000 -#define CONTENTS_MONSTERCLIP 0x20000 - -/** - * @section currents can be added to any other contents, and may be mixed - */ -#define CONTENTS_CURRENT_0 0x40000 -#define CONTENTS_CURRENT_90 0x80000 -#define CONTENTS_CURRENT_180 0x100000 -#define CONTENTS_CURRENT_270 0x200000 -#define CONTENTS_CURRENT_UP 0x400000 -#define CONTENTS_CURRENT_DOWN 0x800000 - -/** - * @endsection - */ - -#define CONTENTS_ORIGIN 0x1000000 /**< removed before bsping an entity. */ -#define CONTENTS_MONSTER 0x2000000 /**< should never be on a brush, only in game. */ -#define CONTENTS_DEBRIS 0x4000000 -#define CONTENTS_DETAIL 0x8000000 /**< brushes to be added after vis leafs. */ -#define CONTENTS_TRANSLUCENT 0x10000000 /**< auto set if any surface has trans. */ -#define CONTENTS_LADDER 0x20000000 -#define CONTENTS_HITBOX 0x40000000 /**< use accurate hitboxes on trace. */ - -/** - * @section Trace masks. - */ -#define MASK_ALL (0xFFFFFFFF) -#define MASK_SOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) /**< everything that is normally solid */ -#define MASK_PLAYERSOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) /**< everything that blocks player movement */ -#define MASK_NPCSOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) /**< blocks npc movement */ -#define MASK_WATER (CONTENTS_WATER|CONTENTS_MOVEABLE|CONTENTS_SLIME) /**< water physics in these contents */ -#define MASK_OPAQUE (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_OPAQUE) /**< everything that blocks line of sight for AI, lighting, etc */ -#define MASK_OPAQUE_AND_NPCS (MASK_OPAQUE|CONTENTS_MONSTER) /**< everything that blocks line of sight for AI, lighting, etc, but with monsters added. */ -#define MASK_VISIBLE (MASK_OPAQUE|CONTENTS_IGNORE_NODRAW_OPAQUE) /**< everything that blocks line of sight for players */ -#define MASK_VISIBLE_AND_NPCS (MASK_OPAQUE_AND_NPCS|CONTENTS_IGNORE_NODRAW_OPAQUE) /**< everything that blocks line of sight for players, but with monsters added. */ -#define MASK_SHOT (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_HITBOX) /**< bullets see these as solid */ -#define MASK_SHOT_HULL (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_GRATE) /**< non-raycasted weapons see this as solid (includes grates) */ -#define MASK_SHOT_PORTAL (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW) /**< hits solids (not grates) and passes through everything else */ -#define MASK_SOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_GRATE) /**< everything normally solid, except monsters (world+brush only) */ -#define MASK_PLAYERSOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_PLAYERCLIP|CONTENTS_GRATE) /**< everything normally solid for player movement, except monsters (world+brush only) */ -#define MASK_NPCSOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE) /**< everything normally solid for npc movement, except monsters (world+brush only) */ -#define MASK_NPCWORLDSTATIC (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE) /**< just the world, used for route rebuilding */ -#define MASK_SPLITAREAPORTAL (CONTENTS_WATER|CONTENTS_SLIME) /**< These are things that can split areaportals */ - -/** - * @endsection - */ - -enum RayType -{ - RayType_EndPoint, /**< The trace ray will go from the start position to the end position. */ - RayType_Infinite /**< The trace ray will go from the start position to infinity using a direction vector. */ -}; - -funcenum TraceEntityFilter -{ - /** - * Called on entity filtering. - * - * @param entity Entity index. - * @param contentsMask Contents Mask. - * @return True to allow the current entity to be hit, otherwise false. - */ - bool:public(entity, contentsMask), - - /** - * Called on entity filtering. - * - * @param entity Entity index. - * @param contentsMask Contents Mask. - * @param data Data value, if used. - * @return True to allow the current entity to be hit, otherwise false. - */ - bool:public(entity, contentsMask, any:data), -}; - -/** - * Get the contents mask and the entity index at the given position. - * - * @param pos World position to test. - * @param entindex Entity index found at the given position (by reference). - * @return Contents mask. - */ -native TR_GetPointContents(const Float:pos[3], &entindex=-1); - -/** - * Get the point contents testing only the given entity index. - * - * @param entindex Entity index to test. - * @param pos World position. - * @return Contents mask. - */ -native TR_GetPointContentsEnt(entindex, const Float:pos[3]); - -/** - * Starts up a new trace ray using a global trace result. - * - * @param pos Starting position of the ray. - * @param vec Depending on RayType, it will be used as the ending point, or the direction angle. - * @param flags Trace flags. - * @param rtype Method to calculate the ray direction. - * @noreturn - */ -native TR_TraceRay(const Float:pos[3], const Float:vec[3], flags, RayType:rtype); - -/** - * Starts up a new trace ray using a global trace result and a customized trace ray filter. - * - * Calling TR_TraceRayFilter or TR_TraceRayFilterEx from inside a filter function is - * currently not allowed and may not work. - * - * @param pos Starting position of the ray. - * @param vec Depending on RayType, it will be used as the ending point, or the direction angle. - * @param flags Trace flags. - * @param rtype Method to calculate the ray direction. - * @param filter Function to use as a filter. - * @param data Arbitrary data value to pass through to the filter function. - * @noreturn - */ -native TR_TraceRayFilter(const Float:pos[3], - const Float:vec[3], - flags, - RayType:rtype, - TraceEntityFilter:filter, - any:data=0); - -/** - * Starts up a new trace ray using a new trace result. - * - * @param pos Starting position of the ray. - * @param vec Depending on RayType, it will be used as the ending point, or the direction angle. - * @param flags Trace flags. - * @param rtype Method to calculate the ray direction. - * @return Ray trace handle, which must be closed via CloseHandle(). - */ -native Handle:TR_TraceRayEx(const Float:pos[3], const Float:vec[3], flags, RayType:rtype); - -/** - * Starts up a new trace ray using a new trace result and a customized trace ray filter. - * - * Calling TR_TraceRayFilter or TR_TraceRayFilterEx from inside a filter function is - * currently not allowed and may not work. - * - * @param pos Starting position of the ray. - * @param vec Depending on RayType, it will be used as the ending point, or the direction angle. - * @param flags Trace flags. - * @param rtype Method to calculate the ray direction. - * @param filter Function to use as a filter. - * @param data Arbitrary data value to pass through to the filter function. - * @return Ray trace handle, which must be closed via CloseHandle(). - */ -native Handle:TR_TraceRayFilterEx(const Float:pos[3], - const Float:vec[3], - flags, - RayType:rtype, - TraceEntityFilter:filter, - any:data=0); - -/** - * Returns the time fraction from a trace result (1.0 means no collision). - * - * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. - * @return Time fraction value of the trace. - * @error Invalid Handle. - */ -native Float:TR_GetFraction(Handle:hndl=INVALID_HANDLE); - -/** - * Returns the collision position of a trace result. - * - * @param pos Vector buffer to store data in. - * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. - * @noreturn - * @error Invalid Handle. - */ -native TR_GetEndPosition(Float:pos[3], Handle:hndl=INVALID_HANDLE); - -/** - * Returns the entity index that collided with the trace. - * - * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. - * @return Entity index or -1 for no collision. - * @error Invalid Handle. - */ -native TR_GetEntityIndex(Handle:hndl=INVALID_HANDLE); - -/** - * Returns if there was any kind of collision along the trace ray. - * - * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. - * @return True if any collision found, otherwise false. - * @error Invalid Handle. - */ -native bool:TR_DidHit(Handle:hndl=INVALID_HANDLE); - -/** - * Returns in which body hit group the trace collided if any. - * - * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. - * @return Body hit group. - * @error Invalid Handle. - */ -native TR_GetHitGroup(Handle:hndl=INVALID_HANDLE); - -/** - * Find the normal vector to the collison plane of a trace. - * - * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. - * @param normal Vector buffer to store the vector normal to the collision plane - * @noreturn - * @error Invalid Handle - */ -native TR_GetPlaneNormal(Handle:hndl, Float:normal[3]); - +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This file is part of the SourceMod/SourcePawn SDK. + * + * 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$ + */ + +#if defined _sdktools_trace_included + #endinput +#endif +#define _sdktools_trace_included + +#define CONTENTS_EMPTY 0 /**< No contents. */ +#define CONTENTS_SOLID 0x1 /**< an eye is never valid in a solid . */ +#define CONTENTS_WINDOW 0x2 /**< translucent, but not watery (glass). */ +#define CONTENTS_AUX 0x4 +#define CONTENTS_GRATE 0x8 /**< alpha-tested "grate" textures. Bullets/sight pass through, but solids don't. */ +#define CONTENTS_SLIME 0x10 +#define CONTENTS_WATER 0x20 +#define CONTENTS_MIST 0x40 +#define CONTENTS_OPAQUE 0x80 /**< things that cannot be seen through (may be non-solid though). */ +#define LAST_VISIBLE_CONTENTS 0x80 +#define ALL_VISIBLE_CONTENTS (LAST_VISIBLE_CONTENTS | (LAST_VISIBLE_CONTENTS-1)) +#define CONTENTS_TESTFOGVOLUME 0x100 +#define CONTENTS_UNUSED5 0x200 +#define CONTENTS_UNUSED6 0x4000 +#define CONTENTS_TEAM1 0x800 /**< per team contents used to differentiate collisions. */ +#define CONTENTS_TEAM2 0x1000 /**< between players and objects on different teams. */ +#define CONTENTS_IGNORE_NODRAW_OPAQUE 0x2000 /**< ignore CONTENTS_OPAQUE on surfaces that have SURF_NODRAW. */ +#define CONTENTS_MOVEABLE 0x4000 /**< hits entities which are MOVETYPE_PUSH (doors, plats, etc) */ +#define CONTENTS_AREAPORTAL 0x8000 /**< remaining contents are non-visible, and don't eat brushes. */ +#define CONTENTS_PLAYERCLIP 0x10000 +#define CONTENTS_MONSTERCLIP 0x20000 + +/** + * @section currents can be added to any other contents, and may be mixed + */ +#define CONTENTS_CURRENT_0 0x40000 +#define CONTENTS_CURRENT_90 0x80000 +#define CONTENTS_CURRENT_180 0x100000 +#define CONTENTS_CURRENT_270 0x200000 +#define CONTENTS_CURRENT_UP 0x400000 +#define CONTENTS_CURRENT_DOWN 0x800000 + +/** + * @endsection + */ + +#define CONTENTS_ORIGIN 0x1000000 /**< removed before bsping an entity. */ +#define CONTENTS_MONSTER 0x2000000 /**< should never be on a brush, only in game. */ +#define CONTENTS_DEBRIS 0x4000000 +#define CONTENTS_DETAIL 0x8000000 /**< brushes to be added after vis leafs. */ +#define CONTENTS_TRANSLUCENT 0x10000000 /**< auto set if any surface has trans. */ +#define CONTENTS_LADDER 0x20000000 +#define CONTENTS_HITBOX 0x40000000 /**< use accurate hitboxes on trace. */ + +/** + * @section Trace masks. + */ +#define MASK_ALL (0xFFFFFFFF) +#define MASK_SOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) /**< everything that is normally solid */ +#define MASK_PLAYERSOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) /**< everything that blocks player movement */ +#define MASK_NPCSOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) /**< blocks npc movement */ +#define MASK_WATER (CONTENTS_WATER|CONTENTS_MOVEABLE|CONTENTS_SLIME) /**< water physics in these contents */ +#define MASK_OPAQUE (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_OPAQUE) /**< everything that blocks line of sight for AI, lighting, etc */ +#define MASK_OPAQUE_AND_NPCS (MASK_OPAQUE|CONTENTS_MONSTER) /**< everything that blocks line of sight for AI, lighting, etc, but with monsters added. */ +#define MASK_VISIBLE (MASK_OPAQUE|CONTENTS_IGNORE_NODRAW_OPAQUE) /**< everything that blocks line of sight for players */ +#define MASK_VISIBLE_AND_NPCS (MASK_OPAQUE_AND_NPCS|CONTENTS_IGNORE_NODRAW_OPAQUE) /**< everything that blocks line of sight for players, but with monsters added. */ +#define MASK_SHOT (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_HITBOX) /**< bullets see these as solid */ +#define MASK_SHOT_HULL (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_GRATE) /**< non-raycasted weapons see this as solid (includes grates) */ +#define MASK_SHOT_PORTAL (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW) /**< hits solids (not grates) and passes through everything else */ +#define MASK_SOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_GRATE) /**< everything normally solid, except monsters (world+brush only) */ +#define MASK_PLAYERSOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_PLAYERCLIP|CONTENTS_GRATE) /**< everything normally solid for player movement, except monsters (world+brush only) */ +#define MASK_NPCSOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE) /**< everything normally solid for npc movement, except monsters (world+brush only) */ +#define MASK_NPCWORLDSTATIC (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE) /**< just the world, used for route rebuilding */ +#define MASK_SPLITAREAPORTAL (CONTENTS_WATER|CONTENTS_SLIME) /**< These are things that can split areaportals */ + +/** + * @endsection + */ + +enum RayType +{ + RayType_EndPoint, /**< The trace ray will go from the start position to the end position. */ + RayType_Infinite /**< The trace ray will go from the start position to infinity using a direction vector. */ +}; + +funcenum TraceEntityFilter +{ + /** + * Called on entity filtering. + * + * @param entity Entity index. + * @param contentsMask Contents Mask. + * @return True to allow the current entity to be hit, otherwise false. + */ + bool:public(entity, contentsMask), + + /** + * Called on entity filtering. + * + * @param entity Entity index. + * @param contentsMask Contents Mask. + * @param data Data value, if used. + * @return True to allow the current entity to be hit, otherwise false. + */ + bool:public(entity, contentsMask, any:data), +}; + +/** + * Get the contents mask and the entity index at the given position. + * + * @param pos World position to test. + * @param entindex Entity index found at the given position (by reference). + * @return Contents mask. + */ +native TR_GetPointContents(const Float:pos[3], &entindex=-1); + +/** + * Get the point contents testing only the given entity index. + * + * @param entindex Entity index to test. + * @param pos World position. + * @return Contents mask. + */ +native TR_GetPointContentsEnt(entindex, const Float:pos[3]); + +/** + * Starts up a new trace ray using a global trace result. + * + * @param pos Starting position of the ray. + * @param vec Depending on RayType, it will be used as the ending point, or the direction angle. + * @param flags Trace flags. + * @param rtype Method to calculate the ray direction. + * @noreturn + */ +native TR_TraceRay(const Float:pos[3], const Float:vec[3], flags, RayType:rtype); + +/** + * Starts up a new trace ray using a global trace result and a customized trace ray filter. + * + * Calling TR_TraceRayFilter or TR_TraceRayFilterEx from inside a filter function is + * currently not allowed and may not work. + * + * @param pos Starting position of the ray. + * @param vec Depending on RayType, it will be used as the ending point, or the direction angle. + * @param flags Trace flags. + * @param rtype Method to calculate the ray direction. + * @param filter Function to use as a filter. + * @param data Arbitrary data value to pass through to the filter function. + * @noreturn + */ +native TR_TraceRayFilter(const Float:pos[3], + const Float:vec[3], + flags, + RayType:rtype, + TraceEntityFilter:filter, + any:data=0); + +/** + * Starts up a new trace ray using a new trace result. + * + * @param pos Starting position of the ray. + * @param vec Depending on RayType, it will be used as the ending point, or the direction angle. + * @param flags Trace flags. + * @param rtype Method to calculate the ray direction. + * @return Ray trace handle, which must be closed via CloseHandle(). + */ +native Handle:TR_TraceRayEx(const Float:pos[3], const Float:vec[3], flags, RayType:rtype); + +/** + * Starts up a new trace ray using a new trace result and a customized trace ray filter. + * + * Calling TR_TraceRayFilter or TR_TraceRayFilterEx from inside a filter function is + * currently not allowed and may not work. + * + * @param pos Starting position of the ray. + * @param vec Depending on RayType, it will be used as the ending point, or the direction angle. + * @param flags Trace flags. + * @param rtype Method to calculate the ray direction. + * @param filter Function to use as a filter. + * @param data Arbitrary data value to pass through to the filter function. + * @return Ray trace handle, which must be closed via CloseHandle(). + */ +native Handle:TR_TraceRayFilterEx(const Float:pos[3], + const Float:vec[3], + flags, + RayType:rtype, + TraceEntityFilter:filter, + any:data=0); + +/** + * Returns the time fraction from a trace result (1.0 means no collision). + * + * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. + * @return Time fraction value of the trace. + * @error Invalid Handle. + */ +native Float:TR_GetFraction(Handle:hndl=INVALID_HANDLE); + +/** + * Returns the collision position of a trace result. + * + * @param pos Vector buffer to store data in. + * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. + * @noreturn + * @error Invalid Handle. + */ +native TR_GetEndPosition(Float:pos[3], Handle:hndl=INVALID_HANDLE); + +/** + * Returns the entity index that collided with the trace. + * + * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. + * @return Entity index or -1 for no collision. + * @error Invalid Handle. + */ +native TR_GetEntityIndex(Handle:hndl=INVALID_HANDLE); + +/** + * Returns if there was any kind of collision along the trace ray. + * + * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. + * @return True if any collision found, otherwise false. + * @error Invalid Handle. + */ +native bool:TR_DidHit(Handle:hndl=INVALID_HANDLE); + +/** + * Returns in which body hit group the trace collided if any. + * + * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. + * @return Body hit group. + * @error Invalid Handle. + */ +native TR_GetHitGroup(Handle:hndl=INVALID_HANDLE); + +/** + * Find the normal vector to the collison plane of a trace. + * + * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. + * @param normal Vector buffer to store the vector normal to the collision plane + * @noreturn + * @error Invalid Handle + */ +native TR_GetPlaneNormal(Handle:hndl, Float:normal[3]); + diff --git a/plugins/include/topmenus.inc b/plugins/include/topmenus.inc index f2b0f950..75dcb94f 100644 --- a/plugins/include/topmenus.inc +++ b/plugins/include/topmenus.inc @@ -1,290 +1,290 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This file is part of the SourceMod/SourcePawn SDK. - * - * 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$ - */ - -#if defined _topmenus_included - #endinput -#endif -#define _topmenus_included - -#include - -/** - * Actions a top menu will take on an object. - */ -enum TopMenuAction -{ - /** - * An option is being drawn for a menu (or for sorting purposes). - * - * INPUT : TopMenu Handle, object ID, client index. - * OUTPUT: Buffer for rendering, maxlength of buffer. - */ - TopMenuAction_DisplayOption = 0, - - /** - * The title of a menu is being drawn for a given object. - * - * Note: The Object ID will be INVALID_TOPMENUOBJECT if drawing the - * root title. Otherwise, the Object ID is a category. - * - * INPUT : TopMenu Handle, object ID, client index. - * OUTPUT: Buffer for rendering, maxlength of buffer. - */ - TopMenuAction_DisplayTitle = 1, - - /** - * A menu option has been selected. - * - * The Object ID will always be an item (not a category). - * - * INPUT : TopMenu Handle, object ID, client index. - */ - TopMenuAction_SelectOption = 2, - - /** - * A menu option is being drawn and its flags can be overridden. - * - * INPUT : TopMenu Handle, object ID, client index. - * OUTPUT: The first byte of the 'buffer' string should be set - * to the desired flags. By default, it will contain - * ITEMDRAW_DEFAULT. - */ - TopMenuAction_DrawOption = 3, - - /** - * Called when an object is being removed from the menu. - * This can be used to clean up data stored in the info string. - * - * INPUT : TopMenu Handle, object ID. - */ - TopMenuAction_RemoveObject = 4, -}; - -/** - * Top menu object types. - */ -enum TopMenuObjectType -{ - TopMenuObject_Category = 0, /**< Category (sub-menu branching from root) */ - TopMenuObject_Item = 1 /**< Item on a sub-menu */ -}; - -/** - * Top menu starting positions for display. - */ -enum TopMenuPosition -{ - TopMenuPosition_Start = 0, /**< Start/root of the menu */ - TopMenuPosition_LastRoot = 1, /**< Last position in the root menu */ - TopMenuPosition_LastCategory = 3, /**< Last position in their last category */ -}; - -/** - * Top menu object tag for type checking. - */ -enum TopMenuObject -{ - INVALID_TOPMENUOBJECT = 0, -} - -/** - * TopMenu callback prototype. - * - * @param topmenu Handle to the TopMenu. - * @param action TopMenuAction being performed. - * @param object_id The object ID (if used). - * @param param Extra parameter (if used). - * @param buffer Output buffer (if used). - * @param maxlength Output buffer (if used). - * @noreturn - */ -functag TopMenuHandler public(Handle:topmenu, - TopMenuAction:action, - TopMenuObject:object_id, - param, - String:buffer[], - maxlength); - -/** - * Creates a TopMenu. - * - * @param handler Handler to use for drawing the root title. - * @return A new TopMenu Handle, or INVALID_HANDLE on failure. - */ -native Handle:CreateTopMenu(TopMenuHandler:handler); - -/** - * Re-sorts the items in a TopMenu via a configuration file. - * - * The format of the configuration file should be a Valve Key-Values - * formatted file that SourceMod can parse. There should be one root - * section, and one sub-section for each category. Each sub-section's - * name should match the category name. - * - * Each sub-section may only contain key/value pairs in the form of: - * key: "item" - * value: Name of the item as passed to AddToTopMenu(). - * - * The TopMenu will draw items in the order declared in the configuration - * file. If items do not appear in the configuration file, they are sorted - * per-player based on how the handler function renders for that player. - * These items appear after the configuration sorted items. - * - * @param topmenu TopMenu Handle. - * @param file File path. - * @param error Error buffer. - * @param maxlength Maximum size of the error buffer. - * Error buffer will be filled with a - * zero-terminated string if false is - * returned. - * @return True on success, false on failure. - * @error Invalid TopMenu Handle. - */ -native bool:LoadTopMenuConfig(Handle:topmenu, const String:file[], String:error[], maxlength); - -/** - * Adds an object to a TopMenu. - * - * @param topmenu TopMenu Handle. - * @param name Object name (MUST be unique). - * @param type Object type. - * @param handler Handler for object. - * @param cmdname Command name (for access overrides). - * @param flags Default access flags. - * @param parent Parent object ID, or INVALID_TOPMENUOBJECT for none. - * Items must have a category parent. - * Categories must not have a parent. - * @param info_string Arbitrary storage (max 255 bytes). - * @return A new TopMenuObject ID, or INVALID_TOPMENUOBJECT on - * failure. - * @error Invalid TopMenu Handle. - */ -native TopMenuObject:AddToTopMenu(Handle:topmenu, - const String:name[], - TopMenuObjectType:type, - TopMenuHandler:handler, - TopMenuObject:parent, - const String:cmdname[]="", - flags=0, - const String:info_string[]=""); - -/** - * Retrieves the info string of a top menu item. - * - * @param topmenu TopMenu Handle. - * @param object TopMenuObject ID. - * @param buffer Buffer to store info string. - * @param maxlength Maximum size of info string. - * @return Number of bytes written, not including the - * null terminator. - * @error Invalid TopMenu Handle or TopMenuObject ID. - */ -native GetTopMenuInfoString(Handle:topmenu, TopMenuObject:parent, String:buffer[], maxlength); - -/** - * Retrieves the name string of a top menu item. - * - * @param topmenu TopMenu Handle. - * @param object TopMenuObject ID. - * @param buffer Buffer to store info string. - * @param maxlength Maximum size of info string. - * @return Number of bytes written, not including the - * null terminator. - * @error Invalid TopMenu Handle or TopMenuObject ID. - */ -native GetTopMenuObjName(Handle:topmenu, TopMenuObject:object, String:buffer[], maxlength); - -/** - * Removes an object from a TopMenu. - * - * Plugins' objects are automatically removed all TopMenus when the given - * plugin unloads or pauses. In the case of unpausing, all items are restored. - * - * @param topmenu TopMenu Handle. - * @param object TopMenuObject ID. - * @noreturn - * @error Invalid TopMenu Handle. - */ -native RemoveFromTopMenu(Handle:topmenu, TopMenuObject:object); - -/** - * Displays a TopMenu to a client. - * - * @param topmenu TopMenu Handle. - * @param client Client index. - * @param position Position to display from. - * @return True on success, false on failure. - * @error Invalid TopMenu Handle or client not in game. - */ -native bool:DisplayTopMenu(Handle:topmenu, client, TopMenuPosition:position); - -/** - * Finds a category's object ID in a TopMenu. - * - * @param topmenu TopMenu Handle. - * @param name Object's unique name. - * @return TopMenuObject ID on success, or - * INVALID_TOPMENUOBJECT on failure. - * @error Invalid TopMenu Handle. - */ -native TopMenuObject:FindTopMenuCategory(Handle:topmenu, const String:name[]); - -/** - * Do not edit below this line! - */ -public Extension:__ext_topmenus = -{ - name = "TopMenus", - file = "topmenus.ext", -#if defined AUTOLOAD_EXTENSIONS - autoload = 1, -#else - autoload = 0, -#endif -#if defined REQUIRE_EXTENSIONS - required = 1, -#else - required = 0, -#endif -}; - -#if !defined REQUIRE_EXTENSIONS -public __ext_topmenus_SetNTVOptional() -{ - MarkNativeAsOptional("CreateTopMenu"); - MarkNativeAsOptional("LoadTopMenuConfig"); - MarkNativeAsOptional("AddToTopMenu"); - MarkNativeAsOptional("RemoveFromTopMenu"); - MarkNativeAsOptional("DisplayTopMenu"); - MarkNativeAsOptional("FindTopMenuCategory"); -} -#endif +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This file is part of the SourceMod/SourcePawn SDK. + * + * 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$ + */ + +#if defined _topmenus_included + #endinput +#endif +#define _topmenus_included + +#include + +/** + * Actions a top menu will take on an object. + */ +enum TopMenuAction +{ + /** + * An option is being drawn for a menu (or for sorting purposes). + * + * INPUT : TopMenu Handle, object ID, client index. + * OUTPUT: Buffer for rendering, maxlength of buffer. + */ + TopMenuAction_DisplayOption = 0, + + /** + * The title of a menu is being drawn for a given object. + * + * Note: The Object ID will be INVALID_TOPMENUOBJECT if drawing the + * root title. Otherwise, the Object ID is a category. + * + * INPUT : TopMenu Handle, object ID, client index. + * OUTPUT: Buffer for rendering, maxlength of buffer. + */ + TopMenuAction_DisplayTitle = 1, + + /** + * A menu option has been selected. + * + * The Object ID will always be an item (not a category). + * + * INPUT : TopMenu Handle, object ID, client index. + */ + TopMenuAction_SelectOption = 2, + + /** + * A menu option is being drawn and its flags can be overridden. + * + * INPUT : TopMenu Handle, object ID, client index. + * OUTPUT: The first byte of the 'buffer' string should be set + * to the desired flags. By default, it will contain + * ITEMDRAW_DEFAULT. + */ + TopMenuAction_DrawOption = 3, + + /** + * Called when an object is being removed from the menu. + * This can be used to clean up data stored in the info string. + * + * INPUT : TopMenu Handle, object ID. + */ + TopMenuAction_RemoveObject = 4, +}; + +/** + * Top menu object types. + */ +enum TopMenuObjectType +{ + TopMenuObject_Category = 0, /**< Category (sub-menu branching from root) */ + TopMenuObject_Item = 1 /**< Item on a sub-menu */ +}; + +/** + * Top menu starting positions for display. + */ +enum TopMenuPosition +{ + TopMenuPosition_Start = 0, /**< Start/root of the menu */ + TopMenuPosition_LastRoot = 1, /**< Last position in the root menu */ + TopMenuPosition_LastCategory = 3, /**< Last position in their last category */ +}; + +/** + * Top menu object tag for type checking. + */ +enum TopMenuObject +{ + INVALID_TOPMENUOBJECT = 0, +} + +/** + * TopMenu callback prototype. + * + * @param topmenu Handle to the TopMenu. + * @param action TopMenuAction being performed. + * @param object_id The object ID (if used). + * @param param Extra parameter (if used). + * @param buffer Output buffer (if used). + * @param maxlength Output buffer (if used). + * @noreturn + */ +functag TopMenuHandler public(Handle:topmenu, + TopMenuAction:action, + TopMenuObject:object_id, + param, + String:buffer[], + maxlength); + +/** + * Creates a TopMenu. + * + * @param handler Handler to use for drawing the root title. + * @return A new TopMenu Handle, or INVALID_HANDLE on failure. + */ +native Handle:CreateTopMenu(TopMenuHandler:handler); + +/** + * Re-sorts the items in a TopMenu via a configuration file. + * + * The format of the configuration file should be a Valve Key-Values + * formatted file that SourceMod can parse. There should be one root + * section, and one sub-section for each category. Each sub-section's + * name should match the category name. + * + * Each sub-section may only contain key/value pairs in the form of: + * key: "item" + * value: Name of the item as passed to AddToTopMenu(). + * + * The TopMenu will draw items in the order declared in the configuration + * file. If items do not appear in the configuration file, they are sorted + * per-player based on how the handler function renders for that player. + * These items appear after the configuration sorted items. + * + * @param topmenu TopMenu Handle. + * @param file File path. + * @param error Error buffer. + * @param maxlength Maximum size of the error buffer. + * Error buffer will be filled with a + * zero-terminated string if false is + * returned. + * @return True on success, false on failure. + * @error Invalid TopMenu Handle. + */ +native bool:LoadTopMenuConfig(Handle:topmenu, const String:file[], String:error[], maxlength); + +/** + * Adds an object to a TopMenu. + * + * @param topmenu TopMenu Handle. + * @param name Object name (MUST be unique). + * @param type Object type. + * @param handler Handler for object. + * @param cmdname Command name (for access overrides). + * @param flags Default access flags. + * @param parent Parent object ID, or INVALID_TOPMENUOBJECT for none. + * Items must have a category parent. + * Categories must not have a parent. + * @param info_string Arbitrary storage (max 255 bytes). + * @return A new TopMenuObject ID, or INVALID_TOPMENUOBJECT on + * failure. + * @error Invalid TopMenu Handle. + */ +native TopMenuObject:AddToTopMenu(Handle:topmenu, + const String:name[], + TopMenuObjectType:type, + TopMenuHandler:handler, + TopMenuObject:parent, + const String:cmdname[]="", + flags=0, + const String:info_string[]=""); + +/** + * Retrieves the info string of a top menu item. + * + * @param topmenu TopMenu Handle. + * @param object TopMenuObject ID. + * @param buffer Buffer to store info string. + * @param maxlength Maximum size of info string. + * @return Number of bytes written, not including the + * null terminator. + * @error Invalid TopMenu Handle or TopMenuObject ID. + */ +native GetTopMenuInfoString(Handle:topmenu, TopMenuObject:parent, String:buffer[], maxlength); + +/** + * Retrieves the name string of a top menu item. + * + * @param topmenu TopMenu Handle. + * @param object TopMenuObject ID. + * @param buffer Buffer to store info string. + * @param maxlength Maximum size of info string. + * @return Number of bytes written, not including the + * null terminator. + * @error Invalid TopMenu Handle or TopMenuObject ID. + */ +native GetTopMenuObjName(Handle:topmenu, TopMenuObject:object, String:buffer[], maxlength); + +/** + * Removes an object from a TopMenu. + * + * Plugins' objects are automatically removed all TopMenus when the given + * plugin unloads or pauses. In the case of unpausing, all items are restored. + * + * @param topmenu TopMenu Handle. + * @param object TopMenuObject ID. + * @noreturn + * @error Invalid TopMenu Handle. + */ +native RemoveFromTopMenu(Handle:topmenu, TopMenuObject:object); + +/** + * Displays a TopMenu to a client. + * + * @param topmenu TopMenu Handle. + * @param client Client index. + * @param position Position to display from. + * @return True on success, false on failure. + * @error Invalid TopMenu Handle or client not in game. + */ +native bool:DisplayTopMenu(Handle:topmenu, client, TopMenuPosition:position); + +/** + * Finds a category's object ID in a TopMenu. + * + * @param topmenu TopMenu Handle. + * @param name Object's unique name. + * @return TopMenuObject ID on success, or + * INVALID_TOPMENUOBJECT on failure. + * @error Invalid TopMenu Handle. + */ +native TopMenuObject:FindTopMenuCategory(Handle:topmenu, const String:name[]); + +/** + * Do not edit below this line! + */ +public Extension:__ext_topmenus = +{ + name = "TopMenus", + file = "topmenus.ext", +#if defined AUTOLOAD_EXTENSIONS + autoload = 1, +#else + autoload = 0, +#endif +#if defined REQUIRE_EXTENSIONS + required = 1, +#else + required = 0, +#endif +}; + +#if !defined REQUIRE_EXTENSIONS +public __ext_topmenus_SetNTVOptional() +{ + MarkNativeAsOptional("CreateTopMenu"); + MarkNativeAsOptional("LoadTopMenuConfig"); + MarkNativeAsOptional("AddToTopMenu"); + MarkNativeAsOptional("RemoveFromTopMenu"); + MarkNativeAsOptional("DisplayTopMenu"); + MarkNativeAsOptional("FindTopMenuCategory"); +} +#endif diff --git a/public/mms_sample_ext/sm_ext.cpp b/public/mms_sample_ext/sm_ext.cpp index e68879ec..a7057766 100644 --- a/public/mms_sample_ext/sm_ext.cpp +++ b/public/mms_sample_ext/sm_ext.cpp @@ -1,145 +1,176 @@ -#include -#include "stub_mm.h" -#include "stub_util.h" -#include "sm_ext.h" - -MyExtension g_SMExt; - -bool SM_LoadExtension(char *error, size_t maxlength) -{ - if ((smexts = (IExtensionManager *)g_SMAPI->MetaFactory( - SOURCEMOD_INTERFACE_EXTENSIONS, - NULL, - NULL)) - == NULL) - { - if (error && maxlength) - { - UTIL_Format(error, maxlength, SOURCEMOD_INTERFACE_EXTENSIONS " interface not found"); - } - return false; - } - - /* This could be more dynamic */ - char path[256]; - g_SMAPI->PathFormat(path, - sizeof(path), - "addons/myplugin/bin/myplugin%s", -#if defined __linux__ - "_i486.so" -#else - ".dll" -#endif - ); - - if ((myself = smexts->LoadExternal(&g_SMExt, - path, - "myplugin_mm.ext", - error, - maxlength)) - == NULL) - { - SM_UnsetInterfaces(); - return false; - } - - return true; -} - -void SM_UnloadExtension() -{ - smexts->UnloadExtension(myself); -} - -bool MyExtension::OnExtensionLoad(IExtension *me, - IShareSys *sys, - char *error, - size_t maxlength, - bool late) -{ - sharesys = sys; - myself = me; - - /* Get the default interfaces from our configured SDK header */ - if (!SM_AcquireInterfaces(error, maxlength)) - { - return false; - } - - return true; -} - -void MyExtension::OnExtensionUnload() -{ - /* Clean up any resources here, and more importantly, make sure - * any listeners/hooks into SourceMod are totally removed, as well - * as data structures like handle types and forwards. - */ - - //... - - /* Make sure our pointers get NULL'd just in case */ - SM_UnsetInterfaces(); -} - -void MyExtension::OnExtensionsAllLoaded() -{ - /* Called once all extensions are marked as loaded. - * This always called, and always called only once. - */ -} - -void MyExtension::OnExtensionPauseChange(bool pause) -{ -} - -bool MyExtension::QueryRunning(char *error, size_t maxlength) -{ - /* if something is required that can't be determined during the initial - * load process, print a message here will show a helpful message to - * users when they view the extension's info. - */ - return true; -} - -bool MyExtension::IsMetamodExtension() -{ - /* Must return false! */ - return false; -} - -const char *MyExtension::GetExtensionName() -{ - return mmsplugin->GetName(); -} - -const char *MyExtension::GetExtensionURL() -{ - return mmsplugin->GetURL(); -} - -const char *MyExtension::GetExtensionTag() -{ - return mmsplugin->GetLogTag(); -} - -const char *MyExtension::GetExtensionAuthor() -{ - return mmsplugin->GetAuthor(); -} - -const char *MyExtension::GetExtensionVerString() -{ - return mmsplugin->GetVersion(); -} - -const char *MyExtension::GetExtensionDescription() -{ - return mmsplugin->GetDescription(); -} - -const char *MyExtension::GetExtensionDateString() -{ - return mmsplugin->GetDate(); -} - +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Extension Code for Metamod:Source + * 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$ + */ + +#include +#include "stub_mm.h" +#include "stub_util.h" +#include "sm_ext.h" + +MyExtension g_SMExt; + +bool SM_LoadExtension(char *error, size_t maxlength) +{ + if ((smexts = (IExtensionManager *)g_SMAPI->MetaFactory( + SOURCEMOD_INTERFACE_EXTENSIONS, + NULL, + NULL)) + == NULL) + { + if (error && maxlength) + { + UTIL_Format(error, maxlength, SOURCEMOD_INTERFACE_EXTENSIONS " interface not found"); + } + return false; + } + + /* This could be more dynamic */ + char path[256]; + g_SMAPI->PathFormat(path, + sizeof(path), + "addons/myplugin/bin/myplugin%s", +#if defined __linux__ + "_i486.so" +#else + ".dll" +#endif + ); + + if ((myself = smexts->LoadExternal(&g_SMExt, + path, + "myplugin_mm.ext", + error, + maxlength)) + == NULL) + { + SM_UnsetInterfaces(); + return false; + } + + return true; +} + +void SM_UnloadExtension() +{ + smexts->UnloadExtension(myself); +} + +bool MyExtension::OnExtensionLoad(IExtension *me, + IShareSys *sys, + char *error, + size_t maxlength, + bool late) +{ + sharesys = sys; + myself = me; + + /* Get the default interfaces from our configured SDK header */ + if (!SM_AcquireInterfaces(error, maxlength)) + { + return false; + } + + return true; +} + +void MyExtension::OnExtensionUnload() +{ + /* Clean up any resources here, and more importantly, make sure + * any listeners/hooks into SourceMod are totally removed, as well + * as data structures like handle types and forwards. + */ + + //... + + /* Make sure our pointers get NULL'd just in case */ + SM_UnsetInterfaces(); +} + +void MyExtension::OnExtensionsAllLoaded() +{ + /* Called once all extensions are marked as loaded. + * This always called, and always called only once. + */ +} + +void MyExtension::OnExtensionPauseChange(bool pause) +{ +} + +bool MyExtension::QueryRunning(char *error, size_t maxlength) +{ + /* if something is required that can't be determined during the initial + * load process, print a message here will show a helpful message to + * users when they view the extension's info. + */ + return true; +} + +bool MyExtension::IsMetamodExtension() +{ + /* Must return false! */ + return false; +} + +const char *MyExtension::GetExtensionName() +{ + return mmsplugin->GetName(); +} + +const char *MyExtension::GetExtensionURL() +{ + return mmsplugin->GetURL(); +} + +const char *MyExtension::GetExtensionTag() +{ + return mmsplugin->GetLogTag(); +} + +const char *MyExtension::GetExtensionAuthor() +{ + return mmsplugin->GetAuthor(); +} + +const char *MyExtension::GetExtensionVerString() +{ + return mmsplugin->GetVersion(); +} + +const char *MyExtension::GetExtensionDescription() +{ + return mmsplugin->GetDescription(); +} + +const char *MyExtension::GetExtensionDateString() +{ + return mmsplugin->GetDate(); +} + diff --git a/public/mms_sample_ext/sm_ext.h b/public/mms_sample_ext/sm_ext.h index 24569822..2317b7da 100644 --- a/public/mms_sample_ext/sm_ext.h +++ b/public/mms_sample_ext/sm_ext.h @@ -1,38 +1,69 @@ -#ifndef _INCLUDE_SAMPLE_MMS_SOURCEMOD_EXTENSION_ -#define _INCLUDE_SAMPLE_MMS_SOURCEMOD_EXTENSION_ - -#include "sm_sdk_config.h" - -using namespace SourceMod; - -class MyExtension : public IExtensionInterface -{ -public: - virtual bool OnExtensionLoad(IExtension *me, - IShareSys *sys, - char *error, - size_t maxlength, - bool late); - virtual void OnExtensionUnload(); - virtual void OnExtensionsAllLoaded(); - virtual void OnExtensionPauseChange(bool pause); - virtual bool QueryRunning(char *error, size_t maxlength); - virtual bool IsMetamodExtension(); - virtual const char *GetExtensionName(); - virtual const char *GetExtensionURL(); - virtual const char *GetExtensionTag(); - virtual const char *GetExtensionAuthor(); - virtual const char *GetExtensionVerString(); - virtual const char *GetExtensionDescription(); - virtual const char *GetExtensionDateString(); -}; - -bool SM_LoadExtension(char *error, size_t maxlength); -void SM_UnloadExtension(); - -extern IShareSys *sharesys; -extern IExtension *myself; -extern MyExtension g_SMExt; - -#endif //_INCLUDE_SAMPLE_MMS_SOURCEMOD_EXTENSION_ - +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Extension Code for Metamod:Source + * 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_SAMPLE_MMS_SOURCEMOD_EXTENSION_ +#define _INCLUDE_SAMPLE_MMS_SOURCEMOD_EXTENSION_ + +#include "sm_sdk_config.h" + +using namespace SourceMod; + +class MyExtension : public IExtensionInterface +{ +public: + virtual bool OnExtensionLoad(IExtension *me, + IShareSys *sys, + char *error, + size_t maxlength, + bool late); + virtual void OnExtensionUnload(); + virtual void OnExtensionsAllLoaded(); + virtual void OnExtensionPauseChange(bool pause); + virtual bool QueryRunning(char *error, size_t maxlength); + virtual bool IsMetamodExtension(); + virtual const char *GetExtensionName(); + virtual const char *GetExtensionURL(); + virtual const char *GetExtensionTag(); + virtual const char *GetExtensionAuthor(); + virtual const char *GetExtensionVerString(); + virtual const char *GetExtensionDescription(); + virtual const char *GetExtensionDateString(); +}; + +bool SM_LoadExtension(char *error, size_t maxlength); +void SM_UnloadExtension(); + +extern IShareSys *sharesys; +extern IExtension *myself; +extern MyExtension g_SMExt; + +#endif //_INCLUDE_SAMPLE_MMS_SOURCEMOD_EXTENSION_ + diff --git a/public/mms_sample_ext/sm_sdk_config.cpp b/public/mms_sample_ext/sm_sdk_config.cpp index 26426c35..6c5f377a 100644 --- a/public/mms_sample_ext/sm_sdk_config.cpp +++ b/public/mms_sample_ext/sm_sdk_config.cpp @@ -1,151 +1,182 @@ -#include "sm_sdk_config.h" - -using namespace SourceMod; - -bool SM_AcquireInterfaces(char *error, size_t maxlength) -{ - SM_FIND_IFACE_OR_FAIL(SOURCEMOD, sm_main, error, maxlength); - -#if defined SMEXT_ENABLE_FORWARDSYS - SM_FIND_IFACE_OR_FAIL(FORWARDMANAGER, sm_forwards, error, maxlength); -#endif -#if defined SMEXT_ENABLE_HANDLESYS - SM_FIND_IFACE_OR_FAIL(HANDLESYSTEM, sm_handlesys, error, maxlength); -#endif -#if defined SMEXT_ENABLE_PLAYERHELPERS - SM_FIND_IFACE_OR_FAIL(PLAYERMANAGER, sm_players, error, maxlength); -#endif -#if defined SMEXT_ENABLE_DBMANAGER - SM_FIND_IFACE_OR_FAIL(DBI, sm_dbi, error, maxlength); -#endif -#if defined SMEXT_ENABLE_GAMECONF - SM_FIND_IFACE_OR_FAIL(GAMECONFIG, sm_gameconfs, error, maxlength); -#endif -#if defined SMEXT_ENABLE_MEMUTILS - SM_FIND_IFACE_OR_FAIL(MEMORYUTILS, sm_memutils, error, maxlength); -#endif -#if defined SMEXT_ENABLE_GAMEHELPERS - SM_FIND_IFACE_OR_FAIL(GAMEHELPERS, sm_gamehelpers, error, maxlength); -#endif -#if defined SMEXT_ENABLE_TIMERSYS - SM_FIND_IFACE_OR_FAIL(TIMERSYS, sm_timersys, error, maxlength); -#endif -#if defined SMEXT_ENABLE_THREADER - SM_FIND_IFACE_OR_FAIL(THREADER, sm_threader, error, maxlength); -#endif -#if defined SMEXT_ENABLE_LIBSYS - SM_FIND_IFACE_OR_FAIL(LIBRARYSYS, sm_libsys, error, maxlength); -#endif -#if defined SMEXT_ENABLE_PLUGINSYS - SM_FIND_IFACE_OR_FAIL(PLUGINSYSTEM, sm_plsys, error, maxlength); -#endif -#if defined SMEXT_ENABLE_MENUS - SM_FIND_IFACE_OR_FAIL(MENUMANAGER, sm_menus, error, maxlength); -#endif -#if defined SMEXT_ENABLE_ADMINSYS - SM_FIND_IFACE_OR_FAIL(ADMINSYS, sm_adminsys, error, maxlength); -#endif -#if defined SMEXT_ENABLE_TEXTPARSERS - SM_FIND_IFACE_OR_FAIL(TEXTPARSERS, sm_text, error, maxlength); -#endif - - return true; -} - -void SM_UnsetInterfaces() -{ - myself = NULL; - smexts = NULL; - sharesys = NULL; - sm_main = NULL; -#if defined SMEXT_ENABLE_FORWARDSYS - sm_forwards = NULL; -#endif -#if defined SMEXT_ENABLE_HANDLESYS - sm_handlesys = NULL; -#endif -#if defined SMEXT_ENABLE_PLAYERHELPERS - sm_players = NULL; -#endif -#if defined SMEXT_ENABLE_DBMANAGER - sm_dbi = NULL; -#endif -#if defined SMEXT_ENABLE_GAMECONF - sm_gameconfs = NULL; -#endif -#if defined SMEXT_ENABLE_MEMUTILS - sm_memutils = NULL; -#endif -#if defined SMEXT_ENABLE_GAMEHELPERS - sm_gamehelpers = NULL; -#endif -#if defined SMEXT_ENABLE_TIMERSYS - sm_timersys = NULL; -#endif -#if defined SMEXT_ENABLE_THREADER - sm_threader = NULL; -#endif -#if defined SMEXT_ENABLE_LIBSYS - sm_libsys = NULL; -#endif -#if defined SMEXT_ENABLE_PLUGINSYS - sm_plsys = NULL; -#endif -#if defined SMEXT_ENABLE_MENUS - sm_menus = NULL; -#endif -#if defined SMEXT_ENABLE_ADMINSYS - sm_adminsys = NULL; -#endif -#if defined SMEXT_ENABLE_TEXTPARSERS - sm_text = NULL; -#endif -} - -IExtension *myself = NULL; -IExtensionManager *smexts = NULL; -IShareSys *sharesys = NULL; -SourceMod::ISourceMod *sm_main = NULL; -#if defined SMEXT_ENABLE_FORWARDSYS -SourceMod::IForwardManager *sm_forwards = NULL; -#endif -#if defined SMEXT_ENABLE_HANDLESYS -SourceMod::IHandleSys *sm_handlesys = NULL; -#endif -#if defined SMEXT_ENABLE_PLAYERHELPERS -SourceMod::IPlayerManager *sm_players = NULL; -#endif -#if defined SMEXT_ENABLE_DBMANAGER -SourceMod::IDBManager *sm_dbi = NULL; -#endif -#if defined SMEXT_ENABLE_GAMECONF -SourceMod::IGameConfigManager *sm_gameconfs = NULL; -#endif -#if defined SMEXT_ENABLE_MEMUTILS -SourceMod::IMemoryUtils *sm_memutils = NULL; -#endif -#if defined SMEXT_ENABLE_GAMEHELPERS -SourceMod::IGameHelpers *sm_gamehelpers = NULL; -#endif -#if defined SMEXT_ENABLE_TIMERSYS -SourceMod::ITimerSystem *sm_timersys = NULL; -#endif -#if defined SMEXT_ENABLE_THREADER -SourceMod::IThreader *sm_threader = NULL; -#endif -#if defined SMEXT_ENABLE_LIBSYS -SourceMod::ILibrarySys *sm_libsys = NULL; -#endif -#if defined SMEXT_ENABLE_PLUGINSYS -SourceMod::IPluginManager *sm_plsys = NULL; -#endif -#if defined SMEXT_ENABLE_MENUS -SourceMod::IMenuManager *sm_menus = NULL; -#endif -#if defined SMEXT_ENABLE_ADMINSYS -SourceMod::IAdminSystem *sm_adminsys = NULL; -#endif -#if defined SMEXT_ENABLE_TEXTPARSERS -SourceMod::ITextParsers *sm_text = NULL; -#endif - +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Extension Code for Metamod:Source + * 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$ + */ + +#include "sm_sdk_config.h" + +using namespace SourceMod; + +bool SM_AcquireInterfaces(char *error, size_t maxlength) +{ + SM_FIND_IFACE_OR_FAIL(SOURCEMOD, sm_main, error, maxlength); + +#if defined SMEXT_ENABLE_FORWARDSYS + SM_FIND_IFACE_OR_FAIL(FORWARDMANAGER, sm_forwards, error, maxlength); +#endif +#if defined SMEXT_ENABLE_HANDLESYS + SM_FIND_IFACE_OR_FAIL(HANDLESYSTEM, sm_handlesys, error, maxlength); +#endif +#if defined SMEXT_ENABLE_PLAYERHELPERS + SM_FIND_IFACE_OR_FAIL(PLAYERMANAGER, sm_players, error, maxlength); +#endif +#if defined SMEXT_ENABLE_DBMANAGER + SM_FIND_IFACE_OR_FAIL(DBI, sm_dbi, error, maxlength); +#endif +#if defined SMEXT_ENABLE_GAMECONF + SM_FIND_IFACE_OR_FAIL(GAMECONFIG, sm_gameconfs, error, maxlength); +#endif +#if defined SMEXT_ENABLE_MEMUTILS + SM_FIND_IFACE_OR_FAIL(MEMORYUTILS, sm_memutils, error, maxlength); +#endif +#if defined SMEXT_ENABLE_GAMEHELPERS + SM_FIND_IFACE_OR_FAIL(GAMEHELPERS, sm_gamehelpers, error, maxlength); +#endif +#if defined SMEXT_ENABLE_TIMERSYS + SM_FIND_IFACE_OR_FAIL(TIMERSYS, sm_timersys, error, maxlength); +#endif +#if defined SMEXT_ENABLE_THREADER + SM_FIND_IFACE_OR_FAIL(THREADER, sm_threader, error, maxlength); +#endif +#if defined SMEXT_ENABLE_LIBSYS + SM_FIND_IFACE_OR_FAIL(LIBRARYSYS, sm_libsys, error, maxlength); +#endif +#if defined SMEXT_ENABLE_PLUGINSYS + SM_FIND_IFACE_OR_FAIL(PLUGINSYSTEM, sm_plsys, error, maxlength); +#endif +#if defined SMEXT_ENABLE_MENUS + SM_FIND_IFACE_OR_FAIL(MENUMANAGER, sm_menus, error, maxlength); +#endif +#if defined SMEXT_ENABLE_ADMINSYS + SM_FIND_IFACE_OR_FAIL(ADMINSYS, sm_adminsys, error, maxlength); +#endif +#if defined SMEXT_ENABLE_TEXTPARSERS + SM_FIND_IFACE_OR_FAIL(TEXTPARSERS, sm_text, error, maxlength); +#endif + + return true; +} + +void SM_UnsetInterfaces() +{ + myself = NULL; + smexts = NULL; + sharesys = NULL; + sm_main = NULL; +#if defined SMEXT_ENABLE_FORWARDSYS + sm_forwards = NULL; +#endif +#if defined SMEXT_ENABLE_HANDLESYS + sm_handlesys = NULL; +#endif +#if defined SMEXT_ENABLE_PLAYERHELPERS + sm_players = NULL; +#endif +#if defined SMEXT_ENABLE_DBMANAGER + sm_dbi = NULL; +#endif +#if defined SMEXT_ENABLE_GAMECONF + sm_gameconfs = NULL; +#endif +#if defined SMEXT_ENABLE_MEMUTILS + sm_memutils = NULL; +#endif +#if defined SMEXT_ENABLE_GAMEHELPERS + sm_gamehelpers = NULL; +#endif +#if defined SMEXT_ENABLE_TIMERSYS + sm_timersys = NULL; +#endif +#if defined SMEXT_ENABLE_THREADER + sm_threader = NULL; +#endif +#if defined SMEXT_ENABLE_LIBSYS + sm_libsys = NULL; +#endif +#if defined SMEXT_ENABLE_PLUGINSYS + sm_plsys = NULL; +#endif +#if defined SMEXT_ENABLE_MENUS + sm_menus = NULL; +#endif +#if defined SMEXT_ENABLE_ADMINSYS + sm_adminsys = NULL; +#endif +#if defined SMEXT_ENABLE_TEXTPARSERS + sm_text = NULL; +#endif +} + +IExtension *myself = NULL; +IExtensionManager *smexts = NULL; +IShareSys *sharesys = NULL; +SourceMod::ISourceMod *sm_main = NULL; +#if defined SMEXT_ENABLE_FORWARDSYS +SourceMod::IForwardManager *sm_forwards = NULL; +#endif +#if defined SMEXT_ENABLE_HANDLESYS +SourceMod::IHandleSys *sm_handlesys = NULL; +#endif +#if defined SMEXT_ENABLE_PLAYERHELPERS +SourceMod::IPlayerManager *sm_players = NULL; +#endif +#if defined SMEXT_ENABLE_DBMANAGER +SourceMod::IDBManager *sm_dbi = NULL; +#endif +#if defined SMEXT_ENABLE_GAMECONF +SourceMod::IGameConfigManager *sm_gameconfs = NULL; +#endif +#if defined SMEXT_ENABLE_MEMUTILS +SourceMod::IMemoryUtils *sm_memutils = NULL; +#endif +#if defined SMEXT_ENABLE_GAMEHELPERS +SourceMod::IGameHelpers *sm_gamehelpers = NULL; +#endif +#if defined SMEXT_ENABLE_TIMERSYS +SourceMod::ITimerSystem *sm_timersys = NULL; +#endif +#if defined SMEXT_ENABLE_THREADER +SourceMod::IThreader *sm_threader = NULL; +#endif +#if defined SMEXT_ENABLE_LIBSYS +SourceMod::ILibrarySys *sm_libsys = NULL; +#endif +#if defined SMEXT_ENABLE_PLUGINSYS +SourceMod::IPluginManager *sm_plsys = NULL; +#endif +#if defined SMEXT_ENABLE_MENUS +SourceMod::IMenuManager *sm_menus = NULL; +#endif +#if defined SMEXT_ENABLE_ADMINSYS +SourceMod::IAdminSystem *sm_adminsys = NULL; +#endif +#if defined SMEXT_ENABLE_TEXTPARSERS +SourceMod::ITextParsers *sm_text = NULL; +#endif + diff --git a/public/mms_sample_ext/sm_sdk_config.h b/public/mms_sample_ext/sm_sdk_config.h index 59f854b5..8cd53d3e 100644 --- a/public/mms_sample_ext/sm_sdk_config.h +++ b/public/mms_sample_ext/sm_sdk_config.h @@ -1,128 +1,159 @@ -#ifndef _INCLUDE_SOURCEMOD_CONFIG_H_ -#define _INCLUDE_SOURCEMOD_CONFIG_H_ - -#include - -/** - * @brief Acquires the interfaces enabled at the bottom of this header. - * - * @param error Buffer to store error message. - * @param maxlength Maximum size of the error buffer. - * @return True on success, false on failure. - * On failure, a null-terminated string will be stored - * in the error buffer, if the buffer is non-NULL and - * greater than 0 bytes in size. - */ -bool SM_AcquireInterfaces(char *error, size_t maxlength); - -/** - * @brief Sets each acquired interface to NULL. - */ -void SM_UnsetInterfaces(); - -/** - * Enable interfaces you want to use here by uncommenting lines. - * These interfaces are all part of SourceMod's core. - */ -//#define SMEXT_ENABLE_FORWARDSYS -//#define SMEXT_ENABLE_HANDLESYS -//#define SMEXT_ENABLE_PLAYERHELPERS -//#define SMEXT_ENABLE_DBMANAGER -//#define SMEXT_ENABLE_GAMECONF -//#define SMEXT_ENABLE_MEMUTILS -//#define SMEXT_ENABLE_GAMEHELPERS -//#define SMEXT_ENABLE_TIMERSYS -//#define SMEXT_ENABLE_THREADER -//#define SMEXT_ENABLE_LIBSYS -//#define SMEXT_ENABLE_MENUS -//#define SMEXT_ENABLE_ADTFACTORY -//#define SMEXT_ENABLE_PLUGINSYS -//#define SMEXT_ENABLE_ADMINSYS -//#define SMEXT_ENABLE_TEXTPARSERS - - -/** - * There is no need to edit below. - */ - -#include -#include -extern SourceMod::IExtension *myself; -extern SourceMod::IExtensionManager *smexts; -extern SourceMod::IShareSys *sharesys; - -#include -extern SourceMod::ISourceMod *sm_main; - -#if defined SMEXT_ENABLE_FORWARDSYS -#include -extern SourceMod::IForwardManager *sm_forwards; -#endif - -#if defined SMEXT_ENABLE_HANDLESYS -#include -extern SourceMod::IHandleSys *sm_handlesys; -#endif - -#if defined SMEXT_ENABLE_PLAYERHELPERS -#include -extern SourceMod::IPlayerManager *sm_players; -#endif - -#if defined SMEXT_ENABLE_DBMANAGER -#include -extern SourceMod::IDBManager *sm_dbi; -#endif - -#if defined SMEXT_ENABLE_GAMECONF -#include -extern SourceMod::IGameConfigManager *sm_gameconfs; -#endif - -#if defined SMEXT_ENABLE_MEMUTILS -#include -extern SourceMod::IMemoryUtils *sm_memutils; -#endif - -#if defined SMEXT_ENABLE_GAMEHELPERS -#include -extern SourceMod::IGameHelpers *sm_gamehelpers; -#endif - -#if defined SMEXT_ENABLE_TIMERSYS -#include -extern SourceMod::ITimerSystem *sm_timersys; -#endif - -#if defined SMEXT_ENABLE_THREADER -#include -extern SourceMod::IThreader *sm_threader; -#endif - -#if defined SMEXT_ENABLE_LIBSYS -#include -extern SourceMod::ILibrarySys *sm_libsys; -#endif - -#if defined SMEXT_ENABLE_PLUGINSYS -#include -extern SourceMod::IPluginManager *sm_plsys; -#endif - -#if defined SMEXT_ENABLE_MENUS -#include -extern SourceMod::IMenuManager *sm_menus; -#endif - -#if defined SMEXT_ENABLE_ADMINSYS -#include -extern SourceMod::IAdminSystem *sm_adminsys; -#endif - -#if defined SMEXT_ENABLE_TEXTPARSERS -#include -extern SourceMod::ITextParsers *sm_text; -#endif - -#endif //_INCLUDE_SOURCEMOD_CONFIG_H_ - +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Extension Code for Metamod:Source + * 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_SOURCEMOD_CONFIG_H_ +#define _INCLUDE_SOURCEMOD_CONFIG_H_ + +#include + +/** + * @brief Acquires the interfaces enabled at the bottom of this header. + * + * @param error Buffer to store error message. + * @param maxlength Maximum size of the error buffer. + * @return True on success, false on failure. + * On failure, a null-terminated string will be stored + * in the error buffer, if the buffer is non-NULL and + * greater than 0 bytes in size. + */ +bool SM_AcquireInterfaces(char *error, size_t maxlength); + +/** + * @brief Sets each acquired interface to NULL. + */ +void SM_UnsetInterfaces(); + +/** + * Enable interfaces you want to use here by uncommenting lines. + * These interfaces are all part of SourceMod's core. + */ +//#define SMEXT_ENABLE_FORWARDSYS +//#define SMEXT_ENABLE_HANDLESYS +//#define SMEXT_ENABLE_PLAYERHELPERS +//#define SMEXT_ENABLE_DBMANAGER +//#define SMEXT_ENABLE_GAMECONF +//#define SMEXT_ENABLE_MEMUTILS +//#define SMEXT_ENABLE_GAMEHELPERS +//#define SMEXT_ENABLE_TIMERSYS +//#define SMEXT_ENABLE_THREADER +//#define SMEXT_ENABLE_LIBSYS +//#define SMEXT_ENABLE_MENUS +//#define SMEXT_ENABLE_ADTFACTORY +//#define SMEXT_ENABLE_PLUGINSYS +//#define SMEXT_ENABLE_ADMINSYS +//#define SMEXT_ENABLE_TEXTPARSERS + + +/** + * There is no need to edit below. + */ + +#include +#include +extern SourceMod::IExtension *myself; +extern SourceMod::IExtensionManager *smexts; +extern SourceMod::IShareSys *sharesys; + +#include +extern SourceMod::ISourceMod *sm_main; + +#if defined SMEXT_ENABLE_FORWARDSYS +#include +extern SourceMod::IForwardManager *sm_forwards; +#endif + +#if defined SMEXT_ENABLE_HANDLESYS +#include +extern SourceMod::IHandleSys *sm_handlesys; +#endif + +#if defined SMEXT_ENABLE_PLAYERHELPERS +#include +extern SourceMod::IPlayerManager *sm_players; +#endif + +#if defined SMEXT_ENABLE_DBMANAGER +#include +extern SourceMod::IDBManager *sm_dbi; +#endif + +#if defined SMEXT_ENABLE_GAMECONF +#include +extern SourceMod::IGameConfigManager *sm_gameconfs; +#endif + +#if defined SMEXT_ENABLE_MEMUTILS +#include +extern SourceMod::IMemoryUtils *sm_memutils; +#endif + +#if defined SMEXT_ENABLE_GAMEHELPERS +#include +extern SourceMod::IGameHelpers *sm_gamehelpers; +#endif + +#if defined SMEXT_ENABLE_TIMERSYS +#include +extern SourceMod::ITimerSystem *sm_timersys; +#endif + +#if defined SMEXT_ENABLE_THREADER +#include +extern SourceMod::IThreader *sm_threader; +#endif + +#if defined SMEXT_ENABLE_LIBSYS +#include +extern SourceMod::ILibrarySys *sm_libsys; +#endif + +#if defined SMEXT_ENABLE_PLUGINSYS +#include +extern SourceMod::IPluginManager *sm_plsys; +#endif + +#if defined SMEXT_ENABLE_MENUS +#include +extern SourceMod::IMenuManager *sm_menus; +#endif + +#if defined SMEXT_ENABLE_ADMINSYS +#include +extern SourceMod::IAdminSystem *sm_adminsys; +#endif + +#if defined SMEXT_ENABLE_TEXTPARSERS +#include +extern SourceMod::ITextParsers *sm_text; +#endif + +#endif //_INCLUDE_SOURCEMOD_CONFIG_H_ + diff --git a/public/mms_sample_ext/stub_mm.cpp b/public/mms_sample_ext/stub_mm.cpp index f058e7da..41a16c61 100644 --- a/public/mms_sample_ext/stub_mm.cpp +++ b/public/mms_sample_ext/stub_mm.cpp @@ -11,7 +11,7 @@ * * This stub plugin is public domain. * - * Version: $Id: stub_mm.cpp 534 2007-10-30 18:22:12Z dvander $ + * Version: $Id$ */ #include diff --git a/public/mms_sample_ext/stub_mm.h b/public/mms_sample_ext/stub_mm.h index b441a52b..6071530f 100644 --- a/public/mms_sample_ext/stub_mm.h +++ b/public/mms_sample_ext/stub_mm.h @@ -11,7 +11,7 @@ * * This stub plugin is public domain. * - * Version: $Id: stub_mm.h 463 2007-10-06 17:01:51Z dvander $ + * Version: $Id$ */ #ifndef _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ diff --git a/public/mms_sample_ext/stub_util.cpp b/public/mms_sample_ext/stub_util.cpp index e62b4909..0ffa402b 100644 --- a/public/mms_sample_ext/stub_util.cpp +++ b/public/mms_sample_ext/stub_util.cpp @@ -1,22 +1,38 @@ -#include -#include -#include "stub_util.h" - -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - size_t len = vsnprintf(buffer, maxlength, fmt, ap); - va_end(ap); - - if (len >= maxlength) - { - len = maxlength - 1; - buffer[len] = '\0'; - } - - return len; -} - - +/** + * vim: set ts=4 : + * ====================================================== + * Metamod:Source Stub Plugin + * Written by AlliedModders LLC. + * ====================================================== + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from + * the use of this software. + * + * This stub plugin is public domain. + * + * Version: $Id$ + */ + +#include +#include +#include "stub_util.h" + +size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + size_t len = vsnprintf(buffer, maxlength, fmt, ap); + va_end(ap); + + if (len >= maxlength) + { + len = maxlength - 1; + buffer[len] = '\0'; + } + + return len; +} + + diff --git a/public/mms_sample_ext/stub_util.h b/public/mms_sample_ext/stub_util.h index 5e9cd3b1..5c69374d 100644 --- a/public/mms_sample_ext/stub_util.h +++ b/public/mms_sample_ext/stub_util.h @@ -1,15 +1,31 @@ -#ifndef _INCLUDE_STUB_UTIL_FUNCTIONS_H_ -#define _INCLUDE_STUB_UTIL_FUNCTIONS_H_ - -#include - -/** - * This is a platform-safe function which fixes weird idiosyncracies - * in the null-termination and return value of snprintf(). It guarantees - * the terminator on overflow cases, and never returns -1 or a value - * not equal to the number of non-terminating bytes written. - */ -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...); - -#endif //_INCLUDE_STUB_UTIL_FUNCTIONS_H_ - +/** + * vim: set ts=4 : + * ====================================================== + * Metamod:Source Stub Plugin + * Written by AlliedModders LLC. + * ====================================================== + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from + * the use of this software. + * + * This stub plugin is public domain. + * + * Version: $Id$ + */ + +#ifndef _INCLUDE_STUB_UTIL_FUNCTIONS_H_ +#define _INCLUDE_STUB_UTIL_FUNCTIONS_H_ + +#include + +/** + * This is a platform-safe function which fixes weird idiosyncracies + * in the null-termination and return value of snprintf(). It guarantees + * the terminator on overflow cases, and never returns -1 or a value + * not equal to the number of non-terminating bytes written. + */ +size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...); + +#endif //_INCLUDE_STUB_UTIL_FUNCTIONS_H_ +