Browse Source

Begin pulling in SourceMod faciltiies

nosoop 1 year ago
parent
commit
57e41176c1
7 changed files with 513 additions and 2 deletions
  1. 10 0
      AMBuildScript
  2. 1 0
      AMBuilder
  3. 2 0
      configure.py
  4. 117 1
      mmsplugin.cpp
  5. 28 1
      mmsplugin.h
  6. 190 0
      smsdk_config.cpp
  7. 165 0
      smsdk_config.h

+ 10 - 0
AMBuildScript

@@ -85,6 +85,7 @@ class MMSConfig(object):
     self.binaries = []
     self.generated_headers = None
     self.archs = builder.target.arch.replace('x86_64', 'x64').split(',')
+    self.sm_path = builder.options.sm_path or None
 
   def detectProductVersion(self):
     builder.AddConfigureFile('product.version')
@@ -290,6 +291,15 @@ class MMSConfig(object):
       if builder.target.platform in ['linux', 'mac']:
         compiler.defines += ['NO_HOOK_MALLOC', 'NO_MALLOC_OVERRIDE']
 
+    if not builder.options.sm_path:
+      raise Exception('SourceMod path is missing. Supply a --sm_path flag')
+    paths.extend([
+      [ builder.options.sm_path, 'public' ],
+      [ builder.options.sm_path, 'public', 'amtl' ],
+      [ builder.options.sm_path, 'public', 'amtl', 'amtl' ],
+      [ builder.options.sm_path, 'sourcepawn', 'include' ],
+    ])
+
     for path in paths:
       compiler.cxxincludes += [os.path.join(sdk.path, *path)]
 

+ 1 - 0
AMBuilder

@@ -6,6 +6,7 @@ proj_name = 'tf2dynschema'
 proj_srcs = [
   'mmsplugin.cpp',
   'memscan.cpp',
+  'smsdk_config.cpp',
 ]
 
 proj_c_flags = [

+ 2 - 0
configure.py

@@ -21,6 +21,8 @@ parser.options.add_option('--hl2sdk-root', type=str, dest='hl2sdk_root', default
                        help='Root search folder for HL2SDKs')
 parser.options.add_option('--mms_path', type=str, dest='mms_path', default=None,
                        help='Metamod:Source source tree folder')
+parser.options.add_option('--sm-path', type=str, dest='sm_path', default=None,
+                       help='SourceMod source tree folder')
 parser.options.add_option('--enable-debug', action='store_const', const='1', dest='debug',
                        help='Enable debugging symbols')
 parser.options.add_option('--enable-optimize', action='store_const', const='1', dest='opt',

+ 117 - 1
mmsplugin.cpp

@@ -16,6 +16,10 @@
 
 #include "memscan.h"
 
+void BindToSourceMod();
+bool SM_LoadExtension(char *error, size_t maxlength);
+void SM_UnloadExtension();
+
 SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int);
 SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, 0, bool, char const *, char const *, char const *, char const *, bool, bool);
 
@@ -115,6 +119,7 @@ bool DynSchema::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, boo
 }
 
 bool DynSchema::Unload(char *error, size_t maxlen) {
+	SM_UnloadExtension();
 	SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelInit, server, this, &DynSchema::Hook_LevelInitPost, true);
 	return true;
 }
@@ -221,6 +226,57 @@ void DynSchema::AllPluginsLoaded() {
 	/* This is where we'd do stuff that relies on the mod or other plugins 
 	 * being initialized (for example, cvars added and events registered).
 	 */
+	BindToSourceMod();
+}
+
+void* DynSchema::OnMetamodQuery(const char* iface, int *ret) {
+	if (strcmp(iface, SOURCEMOD_NOTICE_EXTENSIONS) == 0) {
+		BindToSourceMod();
+	}
+	if (ret != NULL) {
+		*ret = IFACE_OK;
+	}
+	return NULL;
+}
+
+void BindToSourceMod() {
+	char error[256];
+	if (!SM_LoadExtension(error, sizeof(error))) {
+		char message[512];
+		snprintf(message, sizeof(message), "Could not load as a SourceMod extension: %s\n", error);
+		engine->LogPrint(message);
+	}
+}
+
+bool SM_LoadExtension(char *error, size_t maxlength) {
+	if ((smexts = (IExtensionManager *)
+			g_SMAPI->MetaFactory(SOURCEMOD_INTERFACE_EXTENSIONS, NULL, NULL)) == NULL) {
+		if (error && maxlength) {
+			snprintf(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/dynattrs/tf2dynschema%s",
+#if defined __linux__
+		"_mm.so"
+#else
+		".dll"
+#endif	
+	);
+
+	if ((myself = smexts->LoadExternal(&g_Plugin, path, "dynschema.ext", error, maxlength))
+			== NULL) {
+		SM_UnsetInterfaces();
+		return false;
+	}
+	return true;
+}
+
+void SM_UnloadExtension() {
+	smexts->UnloadExtension(myself);
 }
 
 bool DynSchema::Pause(char *error, size_t maxlen) {
@@ -232,7 +288,7 @@ bool DynSchema::Unpause(char *error, size_t maxlen) {
 }
 
 const char *DynSchema::GetLicense() {
-	return "Proprietary";
+	return "GPLv3+";
 }
 
 const char *DynSchema::GetVersion() {
@@ -262,3 +318,63 @@ const char *DynSchema::GetName() {
 const char *DynSchema::GetURL() {
 	return "https://git.csrd.science/";
 }
+
+bool DynSchema::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 DynSchema::OnExtensionUnload() {
+	SM_UnsetInterfaces();
+}
+
+void DynSchema::OnExtensionsAllLoaded() {
+	// no-op
+}
+
+void DynSchema::OnExtensionPauseChange(bool pause) {
+	// no-op
+}
+
+bool DynSchema::QueryRunning(char *error, size_t maxlength) {
+	return true;
+}
+
+bool DynSchema::IsMetamodExtension() {
+	return true;
+}
+
+const char *DynSchema::GetExtensionName() {
+	return this->GetName();
+}
+
+const char *DynSchema::GetExtensionURL() {
+	return this->GetURL();
+}
+
+const char *DynSchema::GetExtensionTag() {
+	return this->GetLogTag();
+}
+
+const char *DynSchema::GetExtensionAuthor() {
+	return this->GetAuthor();
+}
+
+const char *DynSchema::GetExtensionVerString() {
+	return this->GetVersion();
+}
+
+const char *DynSchema::GetExtensionDescription() {
+	return this->GetDescription();
+}
+
+const char *DynSchema::GetExtensionDateString() {
+	return this->GetDate();
+}

+ 28 - 1
mmsplugin.h

@@ -16,12 +16,17 @@
 #define _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_
 
 #include <ISmmPlugin.h>
+#include <smsdk_config.h>
 
 #if defined WIN32 && !defined snprintf
 #define snprintf _snprintf
 #endif
 
-class DynSchema : public ISmmPlugin
+using SourceMod::IExtension;
+using SourceMod::IShareSys;
+using SourceMod::IExtensionManager;
+
+class DynSchema : public ISmmPlugin, public SourceMod::IExtensionInterface, public IMetamodListener
 {
 public:
 	bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late);
@@ -32,6 +37,8 @@ public:
 	
 	bool Hook_LevelInitPost(const char *pMapName, char const *pMapEntities, char const *pOldLevel,
 			char const *pLandmarkName, bool loadGame, bool background);
+	
+	void *OnMetamodQuery(const char* iface, int *ret);
 public:
 	const char *GetAuthor();
 	const char *GetName();
@@ -41,10 +48,30 @@ public:
 	const char *GetVersion();
 	const char *GetDate();
 	const char *GetLogTag();
+	
+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();
 };
 
 extern DynSchema g_Plugin;
 
+extern SourceMod::IExtensionManager *smexts;
+
+extern SourceMod::IShareSys *sharesys;
+extern SourceMod::IExtension *myself;
+
 PLUGIN_GLOBALVARS();
 
 #endif //_INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_

+ 190 - 0
smsdk_config.cpp

@@ -0,0 +1,190 @@
+/**
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * 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 <http://www.sourcemod.net/license.php>.
+ *
+ * Version: $Id$
+ */
+
+#include "smsdk_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
+#if defined SMEXT_ENABLE_TRANSLATOR
+	SM_FIND_IFACE_OR_FAIL(TRANSLATOR, sm_translator, 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
+#if defined SMEXT_ENABLE_TRANSLATOR
+	sm_translator = 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
+#if defined SMEXT_ENABLE_TRANSLATOR
+SourceMod::ITranslator *sm_translator = NULL;
+#endif

+ 165 - 0
smsdk_config.h

@@ -0,0 +1,165 @@
+/**
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * 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 <http://www.sourcemod.net/license.php>.
+ *
+ * Version: $Id$
+ */
+
+#ifndef _INCLUDE_SOURCEMOD_CONFIG_H_
+#define _INCLUDE_SOURCEMOD_CONFIG_H_
+
+#include <stdio.h>
+
+/**
+ * @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
+//#define SMEXT_ENABLE_TRANSLATOR
+
+
+/**
+ * There is no need to edit below.
+ */
+
+#include <IShareSys.h>
+#include <IExtensionSys.h>
+extern SourceMod::IExtension *myself;
+extern SourceMod::IExtensionManager *smexts;
+extern SourceMod::IShareSys *sharesys;
+
+#include <ISourceMod.h>
+extern SourceMod::ISourceMod *sm_main;
+
+#if defined SMEXT_ENABLE_FORWARDSYS
+#include <IForwardSys.h>
+extern SourceMod::IForwardManager *sm_forwards;
+#endif
+
+#if defined SMEXT_ENABLE_HANDLESYS
+#include <IHandleSys.h>
+extern SourceMod::IHandleSys *sm_handlesys;
+#endif
+
+#if defined SMEXT_ENABLE_PLAYERHELPERS
+#include <IPlayerHelpers.h>
+extern SourceMod::IPlayerManager *sm_players;
+#endif
+
+#if defined SMEXT_ENABLE_DBMANAGER
+#include <IDBDriver.h>
+extern SourceMod::IDBManager *sm_dbi;
+#endif 
+
+#if defined SMEXT_ENABLE_GAMECONF
+#include <IGameConfigs.h>
+extern SourceMod::IGameConfigManager *sm_gameconfs;
+#endif
+
+#if defined SMEXT_ENABLE_MEMUTILS
+#include <IMemoryUtils.h>
+extern SourceMod::IMemoryUtils *sm_memutils;
+#endif
+
+#if defined SMEXT_ENABLE_GAMEHELPERS
+#include <IGameHelpers.h>
+extern SourceMod::IGameHelpers *sm_gamehelpers;
+#endif
+
+#if defined SMEXT_ENABLE_TIMERSYS
+#include <ITimerSystem.h>
+extern SourceMod::ITimerSystem *sm_timersys;
+#endif
+
+#if defined SMEXT_ENABLE_THREADER
+#include <IThreader.h>
+extern SourceMod::IThreader *sm_threader;
+#endif
+
+#if defined SMEXT_ENABLE_LIBSYS
+#include <ILibrarySys.h>
+extern SourceMod::ILibrarySys *sm_libsys;
+#endif
+
+#if defined SMEXT_ENABLE_PLUGINSYS
+#include <IPluginSys.h>
+extern SourceMod::IPluginManager *sm_plsys;
+#endif 
+
+#if defined SMEXT_ENABLE_MENUS
+#include <IMenuManager.h>
+extern SourceMod::IMenuManager *sm_menus;
+#endif
+
+#if defined SMEXT_ENABLE_ADMINSYS
+#include <IAdminSystem.h>
+extern SourceMod::IAdminSystem *sm_adminsys;
+#endif
+
+#if defined SMEXT_ENABLE_TEXTPARSERS
+#include <ITextParsers.h>
+extern SourceMod::ITextParsers *sm_text;
+#endif
+
+#if defined SMEXT_ENABLE_TRANSLATOR
+#include <ITranslator.h>
+extern SourceMod::ITranslator *sm_translator;
+#endif
+
+#endif //_INCLUDE_SOURCEMOD_CONFIG_H_
+