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_
+