diff --git a/Forward-event-code-example/Config.cs b/Forward-event-code-example/Config.cs
new file mode 100644
index 0000000..43d6c20
--- /dev/null
+++ b/Forward-event-code-example/Config.cs
@@ -0,0 +1,10 @@
+namespace Module
+{
+ internal static class ModuleConfig
+ {
+ public const string Name = "AmxmodxModule";
+ public const string Version = "";
+ public const string Author = "";
+ public const string Url = "";
+ }
+}
\ No newline at end of file
diff --git a/Forward-event-code-example/Forward-event-code-example.csproj b/Forward-event-code-example/Forward-event-code-example.csproj
new file mode 100644
index 0000000..5bf2bcf
--- /dev/null
+++ b/Forward-event-code-example/Forward-event-code-example.csproj
@@ -0,0 +1,24 @@
+
+
+
+ net8.0
+ enable
+ enable
+ true
+ true
+ Module
+ $(MSBuildProjectName.Replace(".", ""))_amxx
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Forward-event-code-example/Global.cs b/Forward-event-code-example/Global.cs
new file mode 100644
index 0000000..73cb467
--- /dev/null
+++ b/Forward-event-code-example/Global.cs
@@ -0,0 +1,171 @@
+using GoldSrc.Amxmodx.Native;
+using GoldSrc.HLSDK;
+using GoldSrc.HLSDK.Native;
+using GoldSrc.MetaMod;
+using GoldSrc.MetaMod.Native;
+
+using System.Runtime.InteropServices;
+
+#pragma warning disable CS8981
+using cell = int;
+#pragma warning restore CS8981
+using size_t = uint;
+
+namespace Module
+{
+ public unsafe static class Global
+ {
+ public static DLL_FUNCTIONS g_EntityAPI_Table;
+ public static DLL_FUNCTIONS* g_pFunctionTable;
+
+ public static DLL_FUNCTIONS g_EntityAPI_Post_Table;
+ public static DLL_FUNCTIONS* g_pFunctionTable_Post;
+
+ public static NEW_DLL_FUNCTIONS g_NewFuncs_Table;
+ public static NEW_DLL_FUNCTIONS* g_pNewFunctionsTable;
+
+ public static NEW_DLL_FUNCTIONS g_NewFuncs_Post_Table;
+ public static NEW_DLL_FUNCTIONS* g_pNewFunctionsTable_Post;
+
+ public static enginefuncs_t g_EngineFuncs_Table;
+ public static enginefuncs_t* g_pengfuncsTable;
+
+ public static enginefuncs_t g_EngineFuncs_Post_Table;
+ public static enginefuncs_t* g_pEngineFuncs_Post;
+
+ public static enginefuncs_t g_engfuncs;
+ public static globalvars_t* gpGlobals;
+
+ public static meta_globals_t* gpMetaGlobals; // metamod globals
+ public static gamedll_funcs_t* gpGamedllFuncs; // gameDLL function tables
+ public static mutil_funcs_t* gpMetaUtilFuncs;
+
+ public static plugin_info_t* Plugin_info;
+ public static META_FUNCTIONS g_MetaFunctions_Table;
+
+ public static amxx_module_info_t g_ModuleInfo;
+
+ public static delegate* unmanaged[Cdecl] g_fn_RequestFunction;
+
+
+ static Global()
+ {
+ Plugin_info = (plugin_info_t*)Marshal.AllocHGlobal(sizeof(mutil_funcs_t));
+ Plugin_info->ifvers = MetaModInfo.META_INTERFACE_VERSION.GetNativeString();
+ Plugin_info->name = ModuleConfig.Name.GetNativeString();
+ Plugin_info->version = ModuleConfig.Name.GetNativeString();
+ Plugin_info->date = DateTime.Now.ToString().GetNativeString();
+ Plugin_info->author = ModuleConfig.Author.GetNativeString();
+ Plugin_info->url = ModuleConfig.Url.GetNativeString();
+ Plugin_info->logtag = ModuleConfig.Name.GetNativeString();
+ Plugin_info->loadable = PLUG_LOADTIME.PT_ANYTIME;
+ Plugin_info->unloadable = PLUG_LOADTIME.PT_ANYTIME;
+
+ g_ModuleInfo.name = Plugin_info->name;
+ g_ModuleInfo.author = Plugin_info->author;
+ g_ModuleInfo.version = Plugin_info->version;
+ g_ModuleInfo.reload = 1;
+ g_ModuleInfo.library = ModuleConfig.Name.GetNativeString();
+ g_ModuleInfo.libclass = "".GetNativeString();
+
+ }
+
+
+ public const int False = 0;
+ public const int True = 1;
+
+ public const int AMXX_OK = 0; /* no error */
+ public const int AMXX_IFVERS = 1; /* interface version */
+ public const int AMXX_PARAM = 2; /* Invalid parameter */
+ public const int AMXX_FUNC_NOT_PRESENT = 3; /* Function not present */
+
+
+ public const int AMXX_GAME_OK = 0; /* This module can load on the current game mod. */
+ public const int AMXX_GAME_BAD = 1; /* This module can not load on the current game mod. */
+
+
+ #region 隐藏多余的API接口
+ // amxx api
+ public static delegate* unmanaged[Cdecl] g_fn_AddNatives;
+ public static delegate* unmanaged[Cdecl] g_fn_AddNewNatives;
+ public static delegate* unmanaged[Cdecl] g_fn_BuildPathname;
+ public static delegate* unmanaged[Cdecl] g_fn_BuildPathnameR;
+ public static delegate* unmanaged[Cdecl] g_fn_GetAmxAddr;
+ public static delegate* unmanaged[Cdecl] g_fn_PrintSrvConsole;
+ public static delegate* unmanaged[Cdecl] g_fn_GetModname;
+ public static delegate* unmanaged[Cdecl] g_fn_GetAmxScriptName;
+ public static delegate* unmanaged[Cdecl] g_fn_GetAmxScript;
+ public static delegate* unmanaged[Cdecl] g_fn_FindAmxScriptByAmx;
+ public static delegate* unmanaged[Cdecl] g_fn_FindAmxScriptByName;
+ public static delegate* unmanaged[Cdecl] g_fn_SetAmxString;
+ public static delegate* unmanaged[Cdecl] g_fn_GetAmxString;
+ public static delegate* unmanaged[Cdecl] g_fn_GetAmxStringLen;
+ public static delegate* unmanaged[Cdecl] g_fn_FormatAmxString;
+ public static delegate* unmanaged[Cdecl] g_fn_CopyAmxMemory;
+ public static delegate* unmanaged[Cdecl] g_fn_Log;
+ public static delegate* unmanaged[Cdecl] g_fn_LogErrorFunc;
+ public static delegate* unmanaged[Cdecl] g_fn_RaiseAmxError;
+ public static delegate* unmanaged[Cdecl] g_fn_RegisterForward;
+ public static delegate* unmanaged[Cdecl] g_fn_ExecuteForward;
+ public static delegate* unmanaged[Cdecl] g_fn_PrepareCellArray;
+ public static delegate* unmanaged[Cdecl] g_fn_PrepareCharArray;
+ public static delegate* unmanaged[Cdecl] g_fn_PrepareCellArrayA;
+ public static delegate* unmanaged[Cdecl] g_fn_PrepareCharArrayA;
+ public static delegate* unmanaged[Cdecl] g_fn_IsPlayerValid;
+ public static delegate* unmanaged[Cdecl] g_fn_GetPlayerName;
+ public static delegate* unmanaged[Cdecl] g_fn_GetPlayerIP;
+ public static delegate* unmanaged[Cdecl] g_fn_IsPlayerIngame;
+ public static delegate* unmanaged[Cdecl] g_fn_IsPlayerBot;
+ public static delegate* unmanaged[Cdecl] g_fn_IsPlayerAuthorized;
+ public static delegate* unmanaged[Cdecl] g_fn_GetPlayerTime;
+ public static delegate* unmanaged[Cdecl] g_fn_GetPlayerPlayTime;
+ public static delegate* unmanaged[Cdecl] g_fn_GetPlayerFlags;
+ public static delegate* unmanaged[Cdecl] g_fn_GetPlayerCurweapon;
+ public static delegate* unmanaged[Cdecl] g_fn_GetPlayerTeam;
+ public static delegate* unmanaged[Cdecl] g_fn_GetPlayerTeamID;
+ public static delegate* unmanaged[Cdecl] g_fn_GetPlayerDeaths;
+ public static delegate* unmanaged[Cdecl] g_fn_GetPlayerMenu;
+ public static delegate* unmanaged[Cdecl] g_fn_GetPlayerKeys;
+ public static delegate* unmanaged[Cdecl] g_fn_IsPlayerAlive;
+ public static delegate* unmanaged[Cdecl] g_fn_GetPlayerFrags;
+ public static delegate* unmanaged[Cdecl] g_fn_IsPlayerConnecting;
+ public static delegate* unmanaged[Cdecl] g_fn_IsPlayerHLTV;
+ public static delegate* unmanaged[Cdecl] g_fn_GetPlayerArmor;
+ public static delegate* unmanaged[Cdecl] g_fn_GetPlayerHealth;
+ public static delegate* unmanaged[Cdecl] g_fn_AmxExec;
+ public static delegate* unmanaged[Cdecl] g_fn_AmxExecv;
+ public static delegate* unmanaged[Cdecl] g_fn_AmxAllot;
+ public static delegate* unmanaged[Cdecl] g_fn_AmxFindPublic;
+ public static delegate* unmanaged[Cdecl] g_fn_AmxFindNative;
+ public static delegate* unmanaged[Cdecl] g_fn_LoadAmxScript;
+ public static delegate* unmanaged[Cdecl] g_fn_UnloadAmxScript;
+ public static delegate* unmanaged[Cdecl] g_fn_RealToCell;
+ public static delegate* unmanaged[Cdecl]| g_fn_CellToReal;
+ public static delegate* unmanaged[Cdecl] g_fn_RegisterSPForward;
+ public static delegate* unmanaged[Cdecl] g_fn_RegisterSPForwardByName;
+ public static delegate* unmanaged[Cdecl] g_fn_UnregisterSPForward;
+ public static delegate* unmanaged[Cdecl] g_fn_MergeDefinition_File;
+ public static delegate* unmanaged[Cdecl] g_fn_Format;
+ public static delegate* unmanaged[Cdecl] g_fn_RegisterFunction;
+ public static delegate* unmanaged[Cdecl] g_fn_AmxPush;
+ public static delegate* unmanaged[Cdecl] g_fn_SetTeamInfo;
+ public static delegate* unmanaged[Cdecl], void> g_fn_RegAuthFunc;
+ public static delegate* unmanaged[Cdecl], void> g_fn_UnregAuthFunc;
+ public static delegate* unmanaged[Cdecl] g_fn_FindLibrary;
+ public static delegate* unmanaged[Cdecl] g_fn_AddLibraries;
+ public static delegate* unmanaged[Cdecl] g_fn_RemoveLibraries;
+ public static delegate* unmanaged[Cdecl] g_fn_OverrideNatives;
+ public static delegate* unmanaged[Cdecl] g_fn_GetLocalInfo;
+ public static delegate* unmanaged[Cdecl] g_fn_AmxReRegister;
+ public static delegate* unmanaged[Cdecl] g_fn_RegisterFunctionEx;
+ public static delegate* unmanaged[Cdecl] g_fn_MessageBlock;
+ public static delegate* unmanaged[Cdecl] g_fn_GetPlayerEdict;
+ public static delegate* unmanaged[Cdecl] g_fn_PlayerPropAddr;
+ #endregion
+
+
+
+ //添加amxx接口镜像
+ public static delegate* unmanaged[Cdecl] g_fn_skill_get_skill_level;
+ }
+}
diff --git a/Forward-event-code-example/Module.cs b/Forward-event-code-example/Module.cs
new file mode 100644
index 0000000..4b841c8
--- /dev/null
+++ b/Forward-event-code-example/Module.cs
@@ -0,0 +1,510 @@
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+using GoldSrc.Amxmodx;
+using GoldSrc.Amxmodx.Native;
+using GoldSrc.HLSDK;
+using GoldSrc.HLSDK.Native;
+using GoldSrc.MetaMod;
+using GoldSrc.MetaMod.Native;
+
+using static Module.Global;
+
+namespace Module
+{
+ public unsafe static class Module
+ {
+ static Module()
+ {
+ g_MetaFunctions_Table.pfnGetEntityAPI2 = &GetEntityAPI2;
+ g_MetaFunctions_Table.pfnGetEntityAPI2_Post = &GetEntityAPI2_Post;
+ g_MetaFunctions_Table.pfnGetNewDLLFunctions = &GetNewDLLFunctions;
+ g_MetaFunctions_Table.pfnGetNewDLLFunctions_Post = &GetNewDLLFunctions_Post;
+ g_MetaFunctions_Table.pfnGetEngineFunctions = &GetEngineFunctions;
+ g_MetaFunctions_Table.pfnGetEngineFunctions_Post = &GetEngineFunctions_Post;
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "GetEntityAPI2", CallConvs = [typeof(CallConvCdecl)])]
+ public static int GetEntityAPI2(DLL_FUNCTIONS* pFunctionTable, int* interfaceVersion)
+ {
+ if (pFunctionTable == null)
+ return False;
+ if (*interfaceVersion != HLSDKInfo.INTERFACE_VERSION)
+ {
+ *interfaceVersion = HLSDKInfo.INTERFACE_VERSION;
+ return False;
+ }
+ *pFunctionTable = g_EntityAPI_Table;
+ g_pFunctionTable = pFunctionTable;
+ return True;
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "GetEntityAPI2_Post", CallConvs = [typeof(CallConvCdecl)])]
+ public static int GetEntityAPI2_Post(DLL_FUNCTIONS* pFunctionTable, int* interfaceVersion)
+ {
+ if (pFunctionTable == null)
+ return False;
+ if (*interfaceVersion != HLSDKInfo.INTERFACE_VERSION)
+ {
+ *interfaceVersion = HLSDKInfo.INTERFACE_VERSION;
+ return False;
+ }
+ *pFunctionTable = g_EntityAPI_Post_Table;
+ g_pFunctionTable_Post = pFunctionTable;
+ return True;
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "GetEngineFunctions", CallConvs = [typeof(CallConvCdecl)])]
+ public static int GetEngineFunctions(enginefuncs_t* pengfuncsFromEngine, int* interfaceVersion)
+ {
+ if (pengfuncsFromEngine == null)
+ return False;
+ if (*interfaceVersion != MetaModInfo.ENGINE_INTERFACE_VERSION)
+ {
+ *interfaceVersion = MetaModInfo.ENGINE_INTERFACE_VERSION;
+ return False;
+ }
+ *pengfuncsFromEngine = g_EngineFuncs_Table;
+ g_pengfuncsTable = pengfuncsFromEngine;
+ return True;
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "GetEngineFunctions_Post", CallConvs = [typeof(CallConvCdecl)])]
+ public static int GetEngineFunctions_Post(enginefuncs_t* pengfuncsFromEngine, int* interfaceVersion)
+ {
+ if (pengfuncsFromEngine == null)
+ return False;
+ if (*interfaceVersion != MetaModInfo.ENGINE_INTERFACE_VERSION)
+ {
+ *interfaceVersion = MetaModInfo.ENGINE_INTERFACE_VERSION;
+ return False;
+ }
+ *pengfuncsFromEngine = g_EngineFuncs_Post_Table;
+ g_pEngineFuncs_Post = pengfuncsFromEngine;
+ return True;
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "GetNewDLLFunctions", CallConvs = [typeof(CallConvCdecl)])]
+ public static int GetNewDLLFunctions(NEW_DLL_FUNCTIONS* pNewFunctionTable, int* interfaceVersion)
+ {
+ if (pNewFunctionTable == null)
+ return False;
+ if (*interfaceVersion != HLSDKInfo.NEW_DLL_FUNCTIONS_VERSION)
+ {
+ *interfaceVersion = HLSDKInfo.NEW_DLL_FUNCTIONS_VERSION;
+ return False;
+ }
+ *pNewFunctionTable = g_NewFuncs_Table;
+ g_pNewFunctionsTable = pNewFunctionTable;
+ return True;
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "GetNewDLLFunctions_Post", CallConvs = [typeof(CallConvCdecl)])]
+ public static int GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS* pNewFunctionTable, int* interfaceVersion)
+ {
+ if (pNewFunctionTable == null)
+ return False;
+ if (*interfaceVersion != HLSDKInfo.NEW_DLL_FUNCTIONS_VERSION)
+ {
+ *interfaceVersion = HLSDKInfo.NEW_DLL_FUNCTIONS_VERSION;
+ return False;
+ }
+ *pNewFunctionTable = g_NewFuncs_Post_Table;
+ g_pNewFunctionsTable_Post = pNewFunctionTable;
+ return True;
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "Meta_Query", CallConvs = [typeof(CallConvCdecl)])]
+ public static int Meta_Query(sbyte* ifvers, plugin_info_t** pPlugInfo, mutil_funcs_t* pMetaUtilFuncs)
+ {
+ if (pMetaUtilFuncs == null)
+ {
+ return False;
+ }
+ gpMetaUtilFuncs = pMetaUtilFuncs;
+ *pPlugInfo = Plugin_info;
+
+ var frameVersion = Marshal.PtrToStringAnsi((nint)ifvers)!;
+ var list = frameVersion.Split(":");
+ var mmajor = int.Parse(list[0]);
+ var mminor = int.Parse(list[1]);
+
+ list = MetaModInfo.META_INTERFACE_VERSION.Split(":");
+ var pmajor = int.Parse(list[0]);
+ var pminor = int.Parse(list[1]);
+
+ if (pmajor > mmajor || (pmajor == mmajor && pminor > mminor))
+ return False;
+ else if (pmajor < mmajor)
+ return False;
+ return True;
+ }
+
+
+ [UnmanagedCallersOnly(EntryPoint = "Meta_Attach", CallConvs = [typeof(CallConvCdecl)])]
+ public static int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS* pFunctionTable, meta_globals_t* pMGlobals, gamedll_funcs_t* pGamedllFuncs)
+ {
+ if ((int)now > (int)Plugin_info->loadable)
+ return False;
+ if (pMGlobals == null)
+ return False;
+ gpMetaGlobals = pMGlobals;
+ if (pFunctionTable == null)
+ return False;
+ *pFunctionTable = g_MetaFunctions_Table;
+ gpGamedllFuncs = pGamedllFuncs;
+ Plugin.FN_META_ATTACH();
+ return True;
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "Meta_Detach", CallConvs = [typeof(CallConvCdecl)])]
+ public static int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
+ {
+ if (now > Plugin_info->unloadable && reason != PL_UNLOAD_REASON.PNL_CMD_FORCED)
+ return False;
+ Plugin.FN_META_DETACH();
+ return True;
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "GiveFnptrsToDll", CallConvs = [typeof(CallConvStdcall)])]
+ public static void GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t* pGlobals)
+ {
+ g_engfuncs = *pengfuncsFromEngine;
+ gpGlobals = pGlobals;
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "AMXX_Query", CallConvs = [typeof(CallConvCdecl)])]
+ public static int AMXX_Query(int* interfaceVersion, amxx_module_info_t* moduleInfo)
+ {
+ if (interfaceVersion == null || moduleInfo == null)
+ return AMXX_PARAM;
+ if (*interfaceVersion != AmxxInfo.AMXX_INTERFACE_VERSION)
+ {
+ *interfaceVersion = AmxxInfo.AMXX_INTERFACE_VERSION;
+ return AMXX_IFVERS;
+ }
+ *moduleInfo = g_ModuleInfo;
+ Plugin.FN_AMXX_QUERY();
+ return AMXX_OK;
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "AMXX_CheckGame", CallConvs = [typeof(CallConvCdecl)])]
+ public static int AMXX_CheckGame(nint game)
+ {
+ Plugin.FN_AMXX_CHECKGAME((sbyte*)game);
+ return AMXX_GAME_OK;
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "AMXX_Attach", CallConvs = [typeof(CallConvCdecl)])]
+ public static int AMXX_Attach(delegate* unmanaged[Cdecl] reqFnptrFunc)
+ {
+ if (reqFnptrFunc == null)
+ return AMXX_PARAM;
+ var size = sizeof(AMX);
+ g_fn_RequestFunction = reqFnptrFunc;
+ #region 隐藏多余的API映射
+ using (var funName = "BuildPathname".GetNativeString())
+ {
+ g_fn_BuildPathname = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "BuildPathnameR".GetNativeString())
+ {
+ g_fn_BuildPathnameR = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "PrintSrvConsole".GetNativeString())
+ {
+ g_fn_PrintSrvConsole = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetModname".GetNativeString())
+ {
+ g_fn_GetModname = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "Log".GetNativeString())
+ {
+ g_fn_Log = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "LogError".GetNativeString())
+ {
+ g_fn_LogErrorFunc = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "MergeDefinitionFile".GetNativeString())
+ {
+ g_fn_MergeDefinition_File = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "Format".GetNativeString())
+ {
+ g_fn_Format = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "RegisterFunction".GetNativeString())
+ {
+ g_fn_RegisterFunction = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "RegisterFunctionEx".GetNativeString())
+ {
+ g_fn_RegisterFunctionEx = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetAmxScript".GetNativeString())
+ {
+ g_fn_GetAmxScript = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "FindAmxScriptByAmx".GetNativeString())
+ {
+ g_fn_FindAmxScriptByAmx = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "FindAmxScriptByName".GetNativeString())
+ {
+ g_fn_FindAmxScriptByName = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "LoadAmxScript".GetNativeString())
+ {
+ g_fn_LoadAmxScript = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "UnloadAmxScript".GetNativeString())
+ {
+ g_fn_UnloadAmxScript = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetAmxScriptName".GetNativeString())
+ {
+ g_fn_GetAmxScriptName = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "SetAmxString".GetNativeString())
+ {
+ g_fn_SetAmxString = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetAmxString".GetNativeString())
+ {
+ g_fn_GetAmxString = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetAmxStringLen".GetNativeString())
+ {
+ g_fn_GetAmxStringLen = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "FormatAmxString".GetNativeString())
+ {
+ g_fn_FormatAmxString = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "CopyAmxMemory".GetNativeString())
+ {
+ g_fn_CopyAmxMemory = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetAmxAddr".GetNativeString())
+ {
+ g_fn_GetAmxAddr = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "AddNatives".GetNativeString())
+ {
+ g_fn_AddNatives = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "AddNewNatives".GetNativeString())
+ {
+ g_fn_AddNewNatives = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "RaiseAmxError".GetNativeString())
+ {
+ g_fn_RaiseAmxError = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "RegisterForward".GetNativeString())
+ {
+ g_fn_RegisterForward = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "RegisterSPForward".GetNativeString())
+ {
+ g_fn_RegisterSPForward = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "RegisterSPForwardByName".GetNativeString())
+ {
+ g_fn_RegisterSPForwardByName = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "UnregisterSPForward".GetNativeString())
+ {
+ g_fn_UnregisterSPForward = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "ExecuteForward".GetNativeString())
+ {
+ g_fn_ExecuteForward = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "PrepareCharArray".GetNativeString())
+ {
+ g_fn_PrepareCharArray = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "PrepareCellArrayA".GetNativeString())
+ {
+ g_fn_PrepareCellArrayA = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "PrepareCharArrayA".GetNativeString())
+ {
+ g_fn_PrepareCharArrayA = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "IsPlayerValid".GetNativeString())
+ {
+ g_fn_IsPlayerValid = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetPlayerName".GetNativeString())
+ {
+ g_fn_GetPlayerName = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetPlayerIP".GetNativeString())
+ {
+ g_fn_GetPlayerIP = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "IsPlayerInGame".GetNativeString())
+ {
+ g_fn_IsPlayerIngame = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "IsPlayerBot".GetNativeString())
+ {
+ g_fn_IsPlayerBot = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "IsPlayerAuthorized".GetNativeString())
+ {
+ g_fn_IsPlayerAuthorized = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetPlayerTime".GetNativeString())
+ {
+ g_fn_GetPlayerTime = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetPlayerPlayTime".GetNativeString())
+ {
+ g_fn_GetPlayerPlayTime = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetPlayerCurweapon".GetNativeString())
+ {
+ g_fn_GetPlayerCurweapon = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetPlayerTeam".GetNativeString())
+ {
+ g_fn_GetPlayerTeam = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetPlayerDeaths".GetNativeString())
+ {
+ g_fn_GetPlayerDeaths = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetPlayerMenu".GetNativeString())
+ {
+ g_fn_GetPlayerMenu = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetPlayerKeys".GetNativeString())
+ {
+ g_fn_GetPlayerKeys = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "IsPlayerAlive".GetNativeString())
+ {
+ g_fn_IsPlayerAlive = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetPlayerFrags".GetNativeString())
+ {
+ g_fn_GetPlayerFrags = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "IsPlayerConnecting".GetNativeString())
+ {
+ g_fn_IsPlayerConnecting = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "IsPlayerHLTV".GetNativeString())
+ {
+ g_fn_IsPlayerHLTV = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetPlayerArmor".GetNativeString())
+ {
+ g_fn_GetPlayerArmor = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetPlayerHealth".GetNativeString())
+ {
+ g_fn_GetPlayerHealth = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetPlayerFlags".GetNativeString())
+ {
+ g_fn_GetPlayerFlags = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetPlayerEdict".GetNativeString())
+ {
+ g_fn_GetPlayerEdict = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "amx_Push".GetNativeString())
+ {
+ g_fn_AmxPush = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "SetPlayerTeamInfo".GetNativeString())
+ {
+ g_fn_SetTeamInfo = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "PlayerPropAddr".GetNativeString())
+ {
+ g_fn_PlayerPropAddr = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "RegAuthFunc".GetNativeString())
+ {
+ g_fn_RegAuthFunc = (delegate* unmanaged[Cdecl], void>)reqFnptrFunc(funName);
+ }
+ using (var funName = "UnregAuthFunc".GetNativeString())
+ {
+ g_fn_UnregAuthFunc = (delegate* unmanaged[Cdecl], void>)reqFnptrFunc(funName);
+ }
+ using (var funName = "FindLibrary".GetNativeString())
+ {
+ g_fn_FindLibrary = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "AddLibraries".GetNativeString())
+ {
+ g_fn_AddLibraries = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "RemoveLibraries".GetNativeString())
+ {
+ g_fn_RemoveLibraries = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "OverrideNatives".GetNativeString())
+ {
+ g_fn_OverrideNatives = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "GetLocalInfo".GetNativeString())
+ {
+ g_fn_GetLocalInfo = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "AmxReregister".GetNativeString())
+ {
+ g_fn_AmxReRegister = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ using (var funName = "MessageBlock".GetNativeString())
+ {
+ g_fn_MessageBlock = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+ #endregion
+ // 在AMXX_Attach方法中其他函数指针获取之后添加
+ using (var funName = "skill_get_skill_level".GetNativeString())
+ {
+ g_fn_skill_get_skill_level = (delegate* unmanaged[Cdecl])reqFnptrFunc(funName);
+ }
+
+
+
+ Plugin.FN_AMXX_ATTACH();
+ return AMXX_OK;
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "AMXX_Detach", CallConvs = [typeof(CallConvCdecl)])]
+ public static int AMXX_Detach()
+ {
+ Plugin.FN_AMXX_DETACH();
+ return AMXX_OK;
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "AMXX_PluginsLoaded", CallConvs = [typeof(CallConvCdecl)])]
+ public static int AMXX_PluginsLoaded()
+ {
+ Plugin.FN_AMXX_PLUGINSLOADED();
+ return AMXX_OK;
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "AMXX_PluginsUnloaded", CallConvs = [typeof(CallConvCdecl)])]
+ public static void AMXX_PluginsUnloaded()
+ {
+ Plugin.FN_AMXX_PLUGINSUNLOADED();
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "AMXX_PluginsUnloading", CallConvs = [typeof(CallConvCdecl)])]
+ public static void AMXX_PluginsUnloading()
+ {
+ Plugin.FN_AMXX_PLUGINSUNLOADING();
+ }
+
+ }
+}
diff --git a/Forward-event-code-example/Plugin.cs b/Forward-event-code-example/Plugin.cs
new file mode 100644
index 0000000..e673af0
--- /dev/null
+++ b/Forward-event-code-example/Plugin.cs
@@ -0,0 +1,117 @@
+using GoldSrc.Amxmodx.Native;
+using GoldSrc.HLSDK;
+using GoldSrc.HLSDK.Native;
+
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+using static Module.Global;
+
+#pragma warning disable CS8981
+using cell = int;
+
+#pragma warning restore CS8981
+
+
+using GoldSrc.Amxmodx.Framework.Attributes;
+
+namespace Module
+{
+ public unsafe class Plugin
+ {
+ public static AMX_NATIVE_INFO* nativeInfo = null;
+ static Plugin()
+ {
+ nativeInfo = (AMX_NATIVE_INFO*)Marshal.AllocHGlobal(sizeof(AMX_NATIVE_INFO) * 2);
+
+
+
+
+ nativeInfo[1].name = null;
+ nativeInfo[1].func = nint.Zero;
+ }
+
+ public static void FN_META_QUERY()
+ {
+
+ }
+
+ public static void FN_META_ATTACH()
+ {
+
+ }
+
+ public static void FN_META_DETACH()
+ {
+
+ }
+
+ public static void FN_AMXX_QUERY()
+ {
+
+ }
+
+ public static int FN_AMXX_CHECKGAME(sbyte* game)
+ {
+ return AMXX_GAME_OK;
+ }
+
+ public static void FN_AMXX_ATTACH()
+ {
+ // 注册forward监听
+ using var forwardName = "skill_respawn_selected".GetNativeString();
+ g_fwd_skill_respawn_selected = g_fn_RegisterForward(forwardName, ForwardExecType.ET_IGNORE);
+ }
+
+ public static void FN_AMXX_DETACH()
+ {
+ }
+
+ public static void FN_AMXX_PLUGINSLOADED()
+ {
+ }
+
+ public static void FN_AMXX_PLUGINSUNLOADING()
+ {
+
+ }
+ public static void FN_AMXX_PLUGINSUNLOADED()
+ {
+
+ }
+
+
+
+ // Forward句柄
+ public static int g_fwd_skill_respawn_selected = -1;
+
+
+
+ // 调用native函数
+ public static int GetSkillLevel(int index, int itemid)
+ {
+ return g_fn_skill_get_skill_level(index, itemid);
+ }
+
+ // 触发forward事件
+ public static void TriggerSkillRespawnSelected(int id, int itemid)
+ {
+ if (g_fwd_skill_respawn_selected == -1)
+ return;
+
+ g_fn_AmxPush(null, itemid);
+ g_fn_AmxPush(null, id);
+ g_fn_ExecuteForward(g_fwd_skill_respawn_selected);
+ }
+
+ // Forward事件处理器
+ [AmxxForward("skill_respawn_selected")]
+ public static int OnSkillRespawnSelected(int id, int itemid)
+ {
+ using var msg = $"Player {id} skill respawn: {itemid}\n".GetNativeString();
+ g_engfuncs.pfnServerPrint(msg);
+ return 0;
+ }
+ }
+
+}
diff --git a/Forward-event-code-example/amxScript/configs/plugins-LevelMenu.ini b/Forward-event-code-example/amxScript/configs/plugins-LevelMenu.ini
new file mode 100644
index 0000000..b7e4266
--- /dev/null
+++ b/Forward-event-code-example/amxScript/configs/plugins-LevelMenu.ini
@@ -0,0 +1,4 @@
+//ģV1.2
+ZP_LevelBasic.amxx
+
+//--------
diff --git a/Forward-event-code-example/amxScript/plugins/ZP_LevelBasic.amxx b/Forward-event-code-example/amxScript/plugins/ZP_LevelBasic.amxx
new file mode 100644
index 0000000..5bb3851
Binary files /dev/null and b/Forward-event-code-example/amxScript/plugins/ZP_LevelBasic.amxx differ
diff --git a/Forward-event-code-example/amxScript/scripting/ZP_LevelBasic.sma b/Forward-event-code-example/amxScript/scripting/ZP_LevelBasic.sma
new file mode 100644
index 0000000..6b9b614
--- /dev/null
+++ b/Forward-event-code-example/amxScript/scripting/ZP_LevelBasic.sma
@@ -0,0 +1,1197 @@
+/* 本插件由 AMXX-Studio 中文版自动生成*/
+/* UTF-8 func by www.DT-Club.net */
+/*
+* 该技能添加系统游戏金钱版于3月14日完成
+* 添加技能,不用写技能提示类的文字,直接添加内容即可
+* 游戏中$是该升级菜单的升级菜单金钱,游戏中输入/shopmenu打开技能菜单
+* 4月13日修改V1.2beta:优化了数集增加还有介绍
+* 7月12号V1.3beta:进行大部分优化和全面修改,增加插件外添加技能的功能
+* 7月14号V1.31beta:严重BUG修复,修复只显示一个技能名称的BUG
+* 7月15号V1.4正式版:修复inc的部分代码无法使用的bug和开局自动执行技能1的BUG
+* V1.4:增加获取 技能点数,队伍,是否活着才可以升级 的inc代码
+* V1.41:添加限制技能升级次数及其限制技能升级时间时间等类型的inc代码
+* V1.42:添加技能升级的forward,即是client_shop(id,itemid)
+* 注意:Forward内须执行skill_reset_item_hasbuy(id)
+* V1.43:由测试得已知严重BUG。修复活着与死亡显示信息无法正常显示而且有时候报错的BUG。
+* V2.0:技能升级权限及其不用钱和验证直接给予指定玩家技能的inc代码添加
+* V2.1:添加返回指定技能升级所需的权限,添加每个inc函数的具体用法的例子
+* 及其更新inc中的介绍内容,全面让编写者了解此INC代码的用法
+* V2.2:限制开局后多少时间才能开启升级菜单
+* V2.3:技能编号名字的获取及其打开升级菜单无技能的提示
+* V2.31:修复关于开局的时间限制的一些BUG
+*
+* 改版自商场模版V2.31正式版本,Halo-QQ351642983
+* V1.2:添加重置技能点数的选项,头文件中增加获取总技能数的语句,修复少数的BUG,重置技能的Forward的添加
+* v1.21修复观察者BUG
+* v1.22对少数测试所得bug进行修复,技能注册在非预缓存区域等级获取错误的修复,显示菜单的判断更加人性化
+*/
+
+#include
+#include
+#include
+
+
+#define PLUGIN_NAME "技能添加系统"
+#define PLUGIN_VERSION "V1.22"
+#define PLUGIN_AUTHOR "Halo-QQ351642983"
+
+
+//所能支持的最多的技能个数
+#define ITEMNUM 64
+
+//按键的绑定(不要绑定的话删除下面一行即可)
+#define ANJIAN "l"
+
+
+new bool:g_showtrue[33];
+
+//判断需要显示什么东西的变量初始化
+new ItemSF[33]=0,IteamNums=0,ApackPD[33]=0,ITime[ITEMNUM][33],Limit[ITEMNUM][33]
+new bool:g_ShopOpen=true
+
+
+//技能变量初始化
+new g_levelexe[33],g_level[33],g_skilllevel[33][ITEMNUM],g_Maxlevel,g_leveltotalexe[33],g_levelpoint[33]
+
+//CVAR的储存值
+new g_sfOpenTime,g_sfHudChannel,g_sfShowMode,g_sfBasicNum,g_sfBasicExe,g_sfEasyGainexe,g_sfzExeGain,g_sfrMode,g_sfrExe,g_sfrPacks
+
+//Forward的储存id值
+new g_ForwardID,g_ForwardID1,g_ForwardID2,g_ForwardID3,g_ForwardID4,g_ForwardID5,g_ForwardID6,g_ForwardID7
+
+
+//定义死亡是否升级技能时显示的状态
+new const AliveShow[2][]=
+{
+ " 死亡 ",
+ " 活着 "
+};
+
+
+new MenuItem[ITEMNUM][ITEMNUM]
+
+new ItemTeams[ITEMNUM]
+
+new ItemCost[ITEMNUM]
+
+new ItemIfaLive[ITEMNUM]
+
+new Float:TimeLimit[ITEMNUM]
+
+new TimesLimit[ITEMNUM]
+
+new ItemLevel[ITEMNUM]
+
+new ItemMaxLevel[ITEMNUM]
+
+new ItemRespawn[ITEMNUM]
+
+new ItemRestart[ITEMNUM]
+
+new ItemBuy[ITEMNUM]
+
+new ItemOpen[ITEMNUM]
+
+new ItemSkillDamage[ITEMNUM]
+
+new Array:AritemName
+
+new Arid[33]
+
+
+
+
+public plugin_precache()
+{
+ AritemName=ArrayCreate(ITEMNUM,1)
+}
+
+public plugin_init()
+{
+ register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR)
+ register_event("HLTV","resetlimit","a","1=0","2=0")
+ register_event("ResetHUD","Respawn","b")
+ register_logevent("resetRound",2,"1=Round_Start")
+ register_clcmd("say /skillmenu","IMenuShow")
+
+ g_ForwardID=CreateMultiForward("skill_selected", ET_CONTINUE,FP_CELL,FP_CELL)
+ g_ForwardID1=CreateMultiForward("skill_damage_selected", ET_CONTINUE,FP_CELL,FP_CELL,FP_CELL,FP_CELL,FP_CELL,FP_CELL,FP_CELL)
+ g_ForwardID3=CreateMultiForward("skill_restart_selected_pre",ET_IGNORE,FP_CELL,FP_CELL)
+ g_ForwardID4=CreateMultiForward("skill_open_selected", ET_IGNORE,FP_CELL,FP_CELL)
+ g_ForwardID5=CreateMultiForward("skill_respawn_selected", ET_IGNORE,FP_CELL,FP_CELL)
+ g_ForwardID6=CreateMultiForward("skill_restart_selected_post", ET_IGNORE,FP_CELL,FP_CELL)
+ g_ForwardID2=CreateMultiForward("skill_levelup", ET_CONTINUE,FP_CELL)
+ g_ForwardID7=CreateMultiForward("skill_levelreset", ET_CONTINUE,FP_CELL)
+
+ g_sfOpenTime=register_cvar("skill_start_open","0.0")
+ g_sfHudChannel=register_cvar("skill_hud_channel","3")
+ g_sfShowMode=register_cvar("skill_show_mode","3")
+ g_sfBasicNum=register_cvar("skill_basic_num","1.57")
+ g_sfBasicExe=register_cvar("skill_basic_exe","1000")
+
+ //如果有装上保存经验这项建议设置为0.0
+ g_sfEasyGainexe=register_cvar("skill_esaygain_exe","1.0")
+
+
+ g_sfzExeGain=register_cvar("skill_infector_exe","1000")
+ g_sfrMode=register_cvar("skill_reset_mode","1")
+ g_sfrExe=register_cvar("skill_reset_exe","2000")
+ g_sfrPacks=register_cvar("skill_reset_packs","20")
+ set_task(0.5,"getmaxlevel")
+
+
+}
+public getmaxlevel()
+{
+ g_Maxlevel=0
+ for(new i=0;i<=IteamNums-1;i++)
+ g_Maxlevel+=ItemMaxLevel[i]*ItemCost[i]
+ g_Maxlevel++
+}
+public client_putinserver(id)
+{
+ set_task(1.0,"InfoShow",id+1000,_,_,"b")
+}
+public client_connect(id)
+{
+ ApackPD[id]=0
+ ItemSF[id]=0
+ get_all(Limit,ITEMNUM-1,0,id)
+ get_all(ITime,ITEMNUM-1,0,id)
+ for(new i=0;i<=IteamNums-1;i++)
+ g_skilllevel[id][i]=0
+ remove_task(id)
+ remove_task(id+1000)
+
+ g_levelexe[id]=0
+ g_leveltotalexe[id]=get_pcvar_num(g_sfBasicExe)
+ g_level[id]=1
+ g_levelpoint[id]=0
+ #if defined ANJIAN
+ client_cmd(id,"bind %s ^"say /skillmenu",ANJIAN)
+ #endif
+}
+
+public InfoShow(pid)
+{
+ new id=pid-1000
+ if(is_user_connected(id))
+ {
+ if(is_user_alive(id))
+ {
+ if(get_pcvar_num(g_sfShowMode)==1)
+ {
+ set_hudmessage(127, 255, 42, -1.0, 0.05, 0, 6.0, 1.1,_,_,get_pcvar_num(g_sfHudChannel))
+ show_hudmessage(id, "等级:%d/%d^n经验:%d/%d^n技能点数:%d点",g_level[id],g_Maxlevel,g_levelexe[id],g_leveltotalexe[id],g_levelpoint[id])
+ }
+ else if(get_pcvar_num(g_sfShowMode)==2)
+ {
+ client_print(id,print_center, "等级:%d/%d 经验:%d/%d 技能点数:%d点",g_level[id],g_Maxlevel,g_levelexe[id],g_leveltotalexe[id],g_levelpoint[id])
+ }
+ else if(get_pcvar_num(g_sfShowMode)==3)
+ {
+ new szMsg[128]
+ format(szMsg,127,"等级:%d/%d 经验:%d/%d 技能点数:%d点",g_level[id],g_Maxlevel,g_levelexe[id],g_leveltotalexe[id],g_levelpoint[id])
+ message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("StatusText"), _, id)
+ write_byte(0)
+ write_string(szMsg)
+ message_end()
+ }
+ }
+ else
+ {
+ new aid=pev(id,pev_iuser2)
+ if(is_user_alive(aid))
+ {
+
+ static opcion[64],name[33]
+ new hudinfo[1560]
+ get_user_name(aid,name,33)
+ formatex(hudinfo, charsmax(hudinfo),"玩家:^n=== %s ===^n^n等级:%d",name,g_level[aid])
+ ItemSF[aid]=0
+ for(new i=0;i<=(IteamNums-1);i++)
+ {
+ if((zp_get_user_zombie(aid)?1:2)==ItemTeams[i]||ItemTeams[i]==3)
+ {
+ if(ItemCost[i]>0&&ItemIfaLive[i]!=0)
+ {
+ ItemSF[aid]+=1
+ if(ItemLevel[i]==0)
+ {
+ if(g_skilllevel[aid][i]!=ItemMaxLevel[i])
+ formatex(opcion, charsmax(opcion),"%s %d级", MenuItem[i],g_skilllevel[aid][i])
+ else formatex(opcion, charsmax(opcion),"%s MAX!", MenuItem[i])
+ }
+ else{
+ if(g_skilllevel[aid][i]!=ItemMaxLevel[i])
+ formatex(opcion, charsmax(opcion),"%s MAX!", MenuItem[i])
+ }
+ }
+ else if(ItemCost[i]==0&&ItemIfaLive[i]!=0)
+ {
+ ItemSF[aid]+=1
+ if(ItemLevel[i]==0)
+ {
+ if(g_skilllevel[id][i]!=ItemMaxLevel[i])
+ formatex(opcion, charsmax(opcion),"%s %d级", MenuItem[i],g_skilllevel[aid][i])
+ else formatex(opcion, charsmax(opcion),"%s Max!", MenuItem[i])
+ }
+ else{
+ if(g_skilllevel[id][i]!=ItemMaxLevel[i])
+ formatex(opcion, charsmax(opcion),"%s %d级", MenuItem[i],g_skilllevel[aid][i])
+ else formatex(opcion, charsmax(opcion),"%s Max!", MenuItem[i])
+ }
+ }
+ formatex(hudinfo, charsmax(hudinfo),"%s^n%s",hudinfo,opcion)
+ }
+ }
+ if(ItemSF[aid]==0)
+ {
+ formatex(hudinfo, charsmax(hudinfo)," (该队伍无技能菜单)")
+ }
+ set_hudmessage(127, 212, 255, 0.73, 0.12, 1, 6.0, 1.1,_,_,get_pcvar_num(g_sfHudChannel))
+ show_hudmessage(id, "%s",hudinfo)
+
+ }
+ }
+ }
+ else
+ {
+ remove_task(id+1000)
+ }
+}
+
+public client_damage(attacker,victim,damage,weapon,hitplace,ta)
+{
+ if(is_user_connected(attacker)&&is_user_connected(victim))
+ {
+ if(zp_get_user_zombie(attacker)!=zp_get_user_zombie(victim))
+ g_levelexe[attacker]+=floatround(damage*get_pcvar_float(g_sfEasyGainexe))
+
+ for(new i=0;i<=IteamNums-1;i++)
+ {
+ if(ItemSkillDamage[i]==1&&g_skilllevel[attacker][i]>0)
+ {
+ new g_num
+ if(is_user_alive(attacker)&&ItemIfaLive[i]==1||ItemIfaLive[i]==3)
+ {
+ if(zp_get_user_zombie(attacker)&&ItemTeams[i]==1||ItemTeams[i]==3)
+ ExecuteForward(g_ForwardID1,g_num,i,attacker,victim,damage,weapon,hitplace,ta)
+ else if((!zp_get_user_zombie(attacker))&&ItemTeams[i]==2)
+ ExecuteForward(g_ForwardID1,g_num,i,attacker,victim,damage,weapon,hitplace,ta)
+ }
+ else if((!is_user_alive(attacker))&&(ItemIfaLive[i]==2))
+ {
+ if(zp_get_user_zombie(attacker)&&ItemTeams[i]==1||ItemTeams[i]==3)
+ ExecuteForward(g_ForwardID1,g_num,i,attacker,victim,damage,weapon,hitplace,ta)
+ else if((!zp_get_user_zombie(attacker))&&ItemTeams[i]==2)
+ ExecuteForward(g_ForwardID1,g_num,i,attacker,victim,damage,weapon,hitplace,ta)
+ }
+ }
+ else if(ItemSkillDamage[i]==2&&g_skilllevel[victim][i]>0)
+ {
+ new g_num
+ if(is_user_alive(victim)&&ItemIfaLive[i]==1||ItemIfaLive[i]==3)
+ {
+ if(zp_get_user_zombie(victim)&&ItemTeams[i]==1||ItemTeams[i]==3)
+ ExecuteForward(g_ForwardID1,g_num,i,attacker,victim,damage,weapon,hitplace,ta)
+ else if((!zp_get_user_zombie(victim))&&ItemTeams[i]==2)
+ ExecuteForward(g_ForwardID1,g_num,i,attacker,victim,damage,weapon,hitplace,ta)
+ }
+ else if((!is_user_alive(victim))&&(ItemIfaLive[i]==2))
+ {
+ if(zp_get_user_zombie(victim)&&ItemTeams[i]==1||ItemTeams[i]==3)
+ ExecuteForward(g_ForwardID1,g_num,i,attacker,victim,damage,weapon,hitplace,ta)
+ else if((!zp_get_user_zombie(victim))&&ItemTeams[i]==2)
+ ExecuteForward(g_ForwardID1,g_num,i,attacker,victim,damage,weapon,hitplace,ta)
+ }
+ }
+ }
+ }
+}
+
+public zp_user_infected_pre(id,infector)
+{
+ g_levelexe[infector]+=get_pcvar_num(g_sfzExeGain)
+}
+
+public resetlimit()
+{
+ g_ShopOpen=false
+ for(new id=0;id<=get_maxplayers();id++)
+ {
+ if(is_user_connected(id))
+ {
+ remove_task(id)
+ get_all(Limit,ITEMNUM-1,0,id)
+ get_all(ITime,ITEMNUM-1,0,id)
+ for(new i=0;i<=IteamNums-1;i++)
+ {
+ if(g_skilllevel[id][i]>0)
+ if(ItemRestart[i]==1)
+ {
+ new g_num
+ if(is_user_alive(id)&&ItemIfaLive[i]==1||ItemIfaLive[i]==3)
+ {
+ if(zp_get_user_zombie(id)&&ItemTeams[i]==1||ItemTeams[i]==3)
+ ExecuteForward(g_ForwardID3,g_num,id,i)
+ else if((!zp_get_user_zombie(id))&&ItemTeams[i]==2)
+ ExecuteForward(g_ForwardID3,g_num,id,i)
+ }
+ else if((!is_user_alive(id))&&(ItemIfaLive[i]==2))
+ {
+ if(zp_get_user_zombie(id)&&ItemTeams[i]==1||ItemTeams[i]==3)
+ ExecuteForward(g_ForwardID3,g_num,id,i)
+ else if((!zp_get_user_zombie(id))&&ItemTeams[i]==2)
+ ExecuteForward(g_ForwardID3,g_num,id,i)
+ }
+ }
+ }
+ }
+ }
+ set_task(get_pcvar_float(g_sfOpenTime),"OpenShop")
+}
+
+public Respawn(id)
+{
+ if(is_user_connected(id))
+ {
+ for(new i=0;i<=IteamNums-1;i++)
+ {
+ if(g_skilllevel[id][i]>0)
+ if(ItemRespawn[i]==1)
+ {
+ new g_num
+ if(is_user_alive(id)&&ItemIfaLive[i]==1||ItemIfaLive[i]==3)
+ {
+ if(zp_get_user_zombie(id)&&ItemTeams[i]==1||ItemTeams[i]==3)
+ ExecuteForward(g_ForwardID5,g_num,id,i)
+ else if((!zp_get_user_zombie(id))&&ItemTeams[i]==2)
+ ExecuteForward(g_ForwardID5,g_num,id,i)
+ }
+ else if((!is_user_alive(id))&&(ItemIfaLive[i]==2))
+ {
+ if(zp_get_user_zombie(id)&&ItemTeams[i]==1||ItemTeams[i]==3)
+ ExecuteForward(g_ForwardID5,g_num,id,i)
+ else if((!zp_get_user_zombie(id))&&ItemTeams[i]==2)
+ ExecuteForward(g_ForwardID5,g_num,id,i)
+ }
+ }
+ }
+ }
+}
+
+public resetRound()
+{
+ for(new id=1;id<=get_maxplayers();id++)
+ {
+ if(is_user_connected(id))
+ {
+ for(new i=0;i<=IteamNums-1;i++)
+ {
+ if(g_skilllevel[id][i]>0)
+ if(ItemRestart[i]==2)
+ {
+ new g_num
+ if(is_user_alive(id)&&ItemIfaLive[i]==1||ItemIfaLive[i]==3)
+ {
+ if(zp_get_user_zombie(id)&&ItemTeams[i]==1||ItemTeams[i]==3)
+ ExecuteForward(g_ForwardID6,g_num,id,i)
+ else if((!zp_get_user_zombie(id))&&ItemTeams[i]==2)
+ ExecuteForward(g_ForwardID6,g_num,id,i)
+ }
+ else if((!is_user_alive(id))&&(ItemIfaLive[i]==2))
+ {
+ if(zp_get_user_zombie(id)&&ItemTeams[i]==1||ItemTeams[i]==3)
+ ExecuteForward(g_ForwardID6,g_num,id,i)
+ else if((!zp_get_user_zombie(id))&&ItemTeams[i]==2)
+ ExecuteForward(g_ForwardID6,g_num,id,i)
+ }
+ }
+ }
+ }
+ }
+}
+
+public OpenShop()
+{
+ g_ShopOpen=true
+ for(new id=1;id<=get_maxplayers();id++)
+ {
+ if(is_user_connected(id))
+ {
+ for(new i=0;i<=IteamNums-1;i++)
+ {
+ if(g_skilllevel[id][i]>0)
+ if(ItemOpen[i]==1)
+ {
+ new g_num
+ if(is_user_alive(id)&&ItemIfaLive[i]==1||ItemIfaLive[i]==3)
+ {
+ if(zp_get_user_zombie(id)&&ItemTeams[i]==1||ItemTeams[i]==3)
+ ExecuteForward(g_ForwardID4,g_num,id,i)
+ else if((!zp_get_user_zombie(id))&&ItemTeams[i]==2)
+ ExecuteForward(g_ForwardID4,g_num,id,i)
+ }
+ else if((!is_user_alive(id))&&(ItemIfaLive[i]==2))
+ {
+ if(zp_get_user_zombie(id)&&ItemTeams[i]==1||ItemTeams[i]==3)
+ ExecuteForward(g_ForwardID4,g_num,id,i)
+ else if((!zp_get_user_zombie(id))&&ItemTeams[i]==2)
+ ExecuteForward(g_ForwardID4,g_num,id,i)
+ }
+ }
+ }
+ }
+ }
+}
+
+public zp_round_started(gamemode,id)
+{
+ for(new i=1;i<=32&&is_user_connected(i);i++)
+ {
+ if(is_user_connected(i))
+ g_showtrue[i]=true;
+ else g_showtrue[i]=false;
+ }
+
+}
+public client_PreThink(id)
+{
+ if(is_user_connected(id))
+ {
+ if(is_user_alive(id))
+ {
+ if(g_levelexe[id]>=g_leveltotalexe[id]&&g_level[id]0)
+ g_levelpoint[id]-=1
+ g_leveltotalexe[id]=floatround(get_pcvar_num(g_sfBasicExe)*g_level[id]*(g_level[id]==1?1.0:get_pcvar_float(g_sfBasicNum)))
+ }
+ if(g_levelexe[id]>g_leveltotalexe[id]&&g_level[id]==g_Maxlevel)
+ g_levelexe[id]=floatround(get_pcvar_num(g_sfBasicExe)*g_Maxlevel*get_pcvar_float(g_sfBasicNum))
+ }
+ }
+ else if(g_showtrue[id])
+ {
+ g_showtrue[id]=false
+ }
+}
+
+public plugin_natives()
+{
+ register_native("skill_add_item","add_skillitem",1) //注册技能的基本信息并返回技能的ID值
+ register_native("skill_get_item_id","get_skillitem",1) //搜索技能返回技能ID的值
+ register_native("skill_reset_item","reset_skillitem",1) //删除升级菜单中指定技能
+ register_native("skill_set_item","set_skillitem",1) //修改升级菜单中技能的基本属性
+ register_native("skill_get_item_hasbuy","hasbuy",1) //技能是否被升级,是的话返回值1,否的话0,并保存在主插件
+ register_native("skill_reset_item_hasbuy","resethasbuy",1) //把技能升级的返回值设置为0
+ register_native("skill_get_item_cost","getmoney",1) //返回指定技能所需的技能点数
+ register_native("skill_get_item_team","getteam",1) //返回指定技能所代表的队伍
+ register_native("skill_is_item_alive","isalive",1) //返回指定技能是否需要活着才可以升级
+ register_native("skill_limit_item","limititem",1) //限制技能的每局升级次数
+ register_native("skill_limit_item_time","limittime",1) //限制技能的升级时间
+ register_native("skill_remove_item_limit","removetimeslimit",1) //移除指定技能的限制的次数
+ register_native("skill_remove_item_time","removetime",1) //移除指定技能的限制的时间
+ register_native("skill_reset_item_limit","limitreset",1) //把玩家当前限定的次数清零
+ register_native("skill_reset_item_time","timereset",1) //把玩家当前限制的时间清零
+ register_native("skill_get_item_time","gettime",1) //返回技能限制的时间的值
+ register_native("skill_get_item_limit","getlimit",1) //返回技能限制的次数的值
+ register_native("skill_give_item","giveiditem",1) //不用钱和验证直接给予指定玩家技能
+ register_native("skill_set_item_flag","limitlevel",1) //技能升级权限的限定
+ register_native("skill_get_item_flag","getlimitlevel",1) //返回指定技能升级所需的权限
+ register_native("skill_get_item_name","getitemidname",1) //技能名字的获取
+ register_native("skill_get_item_maxlevel","getitemidmaxlevel",1) //技能的最高等级的获取
+ register_native("skill_get_item_respawn","getitemidrespawn",1) //技能的重生所执行的模式的获取
+ register_native("skill_get_item_restart","getitemidrestart",1) //技能的重新开始所执行的模式的获取
+ register_native("skill_get_item_openmode","getitemidopenmode",1) //技能的升级菜单开放时所执行的模式的获取
+ register_native("skill_get_item_buymode","getitemidbuymode",1) //技能的升级技能时所执行的模式的获取
+ register_native("skill_set_item_mode","setmode",1) //设置技能的触发模式
+ register_native("skill_get_item_damagemode","getdamagemode",1) //获取技能的攻击触发模式
+ register_native("skill_set_level_exe","setlevelexe",1) //设置等级的经验值
+ register_native("skill_get_level_exe","getlevelexe",1) //获取该等级的经验值
+ register_native("skill_set_level","setlevel",1) //设置等级
+ register_native("skill_get_level","getlevel",1) //获取等级
+ register_native("skill_set_level_point","setlevelpoint",1) //设置技能点
+ register_native("skill_get_level_point","getlevelpoint",1) //获取技能点
+ register_native("skill_set_skill_level","setlevelskill",1) //设置技能的等级
+ register_native("skill_get_skill_level","getlevelskill",1) //获取技能的等级
+ register_native("skill_reset_skill_point","resetlevelskill",1) //重置技能点数
+ register_native("skill_get_skill_num","getlevelskillnum",1) //获取技能的数目
+
+}
+
+//native注册技能的基本信息并返回技能的ID值
+public add_skillitem(const itemname[],itemteam,itemcosts,itembuyalive,skillmaxlevel)
+{
+ param_convert(1)
+ ArrayPushString(AritemName,itemname)
+ ArrayGetString(AritemName,IteamNums,MenuItem[IteamNums],ITEMNUM-1)
+ ItemTeams[IteamNums]=itemteam
+ ItemCost[IteamNums]=itemcosts
+ ItemIfaLive[IteamNums]=itembuyalive
+ ItemMaxLevel[IteamNums]=skillmaxlevel
+ IteamNums+=1
+ return IteamNums-1
+}
+
+//native技能的重生所执行的forward的模式的获取
+public getitemidrespawn(itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ return ItemRespawn[itemid]
+}
+
+
+//native技能的重新开始所执行的forward的模式的获取
+public getitemidrestart(itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ return ItemRestart[itemid]
+}
+
+
+//native搜索技能返回技能ID的值
+public get_skillitem(const itemname[])
+{
+ param_convert(1)
+ static i, item_name[32]
+ for (i = 0; i < IteamNums; i++)
+ {
+ ArrayGetString(AritemName, i, item_name, charsmax(item_name))
+ if (equali(itemname, item_name))
+ return i;
+ }
+
+ return -1;
+}
+//native删除升级菜单中指定技能
+public reset_skillitem(itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+ new item[]={""}
+ format(MenuItem[itemid],ITEMNUM-1,"%s",item)
+ ItemTeams[itemid]=0
+ ItemCost[itemid]=0
+ ItemIfaLive[itemid]=0
+ ItemMaxLevel[itemid]=0
+ ItemRespawn[itemid]=0
+ ItemRestart[itemid]=0
+ ItemBuy[itemid]=0
+ ItemOpen[itemid]=0
+ ItemSkillDamage[itemid]=0
+ return 0
+}
+//native修改升级菜单中技能的基本属性
+public set_skillitem(itemid,const itemname[],itemteam,itemcosts,itembuyalive,skillmaxlevel)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ param_convert(2)
+ ArraySetString(AritemName,itemid,itemname)
+ ArrayGetString(AritemName,itemid,MenuItem[itemid],ITEMNUM-1)
+ ItemTeams[itemid]=itemteam
+ ItemCost[itemid]=itemcosts
+ return 0
+}
+//native技能是否被升级,是的话返回值1,否的话0,并保存在本插件
+public hasbuy(id,itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+ if(itemid+1==ApackPD[id])
+ return 1
+ return 0
+}
+//native把技能升级的返回值设置为0
+public resethasbuy(id)
+{
+ ApackPD[id]=0
+}
+//native返回指定技能所需的技能点数
+public getmoney(itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ return ItemCost[itemid]
+}
+//native返回指定技能所代表的队伍
+public getteam(itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ return ItemTeams[itemid]
+}
+//native返回指定技能是否需要活着才可以升级
+public isalive(itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ return ItemIfaLive[itemid]
+}
+//native限制技能的每局升级次数
+public limititem(itemid,times)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ TimesLimit[itemid]=times
+ return 0
+}
+//native限制技能的升级时间
+public limittime(itemid,Float:long)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ TimeLimit[itemid]=long
+ return 0
+}
+//native移除指定技能的限制的次数
+public removetimeslimit(itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ TimesLimit[itemid]=0
+ return 0
+}
+//native移除指定技能的限制的时间
+public removetime(itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ TimeLimit[itemid]=0.0
+ return 0
+}
+//native把玩家升级指定技能限定的次数清零
+public limitreset(id,itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+ Limit[itemid][id]=0
+ return 0
+}
+//native把玩家当前限制的时间清零
+public timereset(id,itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+ ITime[itemid][id]=0
+ return 0
+}
+//native返回技能限制的时间的值
+public Float:gettime(itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1.0
+
+ return TimeLimit[itemid]
+}
+//native返回技能限制的次数的值
+public getlimit(itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ return TimesLimit[itemid]
+}
+
+//native不用技能点数和验证直接升级指定玩家技能
+public giveiditem(id,itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+ new g_num
+ ApackPD[id]=itemid+1
+ ExecuteForward(g_ForwardID,g_num,id,itemid)
+
+ return 0
+}
+//native技能升级权限的限定
+public limitlevel(itemid,level)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ ItemLevel[itemid]=level
+
+ return 0
+}
+//native返回指定技能升级所需的权限
+public getlimitlevel(itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ return ItemLevel[itemid]
+}
+//native技能名字的获取
+public getitemidname(itemid,itemname[],len)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ format(itemname,len,"%s",MenuItem[itemid])
+
+ return 0
+}
+//native技能的最高等级的获取
+public getitemidmaxlevel(itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ return ItemMaxLevel[itemid]
+}
+//native设置技能的触发模式
+public setmode(itemid,Respawns,Restart,Buy,ShopOpen,Damage)
+{
+ if(itemid>ITEMNUM)
+ return -1
+ ItemRespawn[itemid]=Respawns
+ ItemRestart[itemid]=Restart
+ ItemBuy[itemid]=Buy
+ ItemOpen[itemid]=ShopOpen
+ ItemSkillDamage[itemid]=Damage
+
+ return 0
+}
+//native技能的升级菜单开放时所执行的模式的获取
+public getitemidopenmode(itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ return ItemOpen[itemid]
+}
+//native技能的升级技能时所执行的模式的获取
+public getitemidbuymode(itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ return ItemBuy[itemid]
+}
+//native获取技能的攻击触发模式
+public getdamagemode(itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ return ItemSkillDamage[itemid]
+}
+//native设置经验
+public setlevelexe(index,exe)
+{
+ new g_exe
+ if(g_level[index]>1)
+ {
+ for(new i=2;i<=g_level[index]-1;i++)
+ {
+ g_exe+=floatround(get_pcvar_num(g_sfBasicExe)*i*get_pcvar_float(g_sfBasicNum))
+ }
+ g_exe+=get_pcvar_num(g_sfBasicExe)
+ g_exe+=g_levelexe[index]
+ }
+ else g_exe=g_levelexe[index]
+ g_levelexe[index]+=exe-g_exe
+}
+//native得到经验
+public getlevelexe(index)
+{
+ new g_exe
+ if(g_level[index]>1)
+ {
+ for(new i=2;i<=g_level[index]-1;i++)
+ {
+ g_exe+=floatround(get_pcvar_num(g_sfBasicExe)*i*get_pcvar_float(g_sfBasicNum))
+ }
+ g_exe+=get_pcvar_num(g_sfBasicExe)
+ g_exe+=g_levelexe[index]
+ }
+ else g_exe=g_levelexe[index]
+ return g_exe
+}
+//native设置等级
+public setlevel(index,level)
+{
+ g_level[index]=level
+}
+//native获取等级
+public getlevel(index)
+{
+ return g_level[index]
+}
+
+//native设置技能点数
+public setlevelpoint(index,point)
+{
+ g_levelpoint[index]=point
+}
+//native获取技能点数
+public getlevelpoint(index)
+{
+ return g_levelpoint[index]
+}
+//native设置技能的等级
+public setlevelskill(id,itemid,level)
+{
+ if(itemid>ITEMNUM)
+ return -1
+ if(ItemMaxLevel[itemid]>=level)
+ {
+ g_skilllevel[id][itemid]=level
+ }
+ else return 1
+
+ return 0
+}
+//native获取技能的等级
+public getlevelskill(id,itemid)
+{
+ if(itemid>ITEMNUM)
+ return -1
+
+ return g_skilllevel[id][itemid]
+}
+//native重置技能点数
+public resetlevelskill(id)
+{
+ new g_num
+ g_levelpoint[id]=g_level[id]-1
+ for(new i=0;i<=IteamNums-1;i++)
+ g_skilllevel[id][i]=0
+ ExecuteForward(g_ForwardID7,g_num,id)
+
+ return 0
+}
+//native获取技能的数目
+public getlevelskillnum(mode)
+{
+ new g_num=0
+ if(mode!=3)
+ {
+ for(new i=0;i<=(IteamNums-1);i++)
+ {
+ if(mode==ItemTeams[i]||ItemTeams[i]==3)
+ {
+ g_num++
+ }
+ }
+ return g_num
+ }
+ else return (IteamNums-1)
+
+ return 0
+}
+
+
+
+public removelimits(id)
+{
+ ITime[Arid[id]][id]=0
+ Arid[id]=0
+}
+
+
+public Choose(id, menu, item)
+{
+ if(item==MENU_EXIT)
+ {
+ menu_destroy(menu)
+ return PLUGIN_HANDLED
+ }
+ new command[6], name[64], access, callback
+ menu_item_getinfo(menu, item, access, command, sizeof command - 1, name, sizeof name - 1, callback)
+ switch(item)
+ {
+ case 0..ITEMNUM:
+ {
+ if(g_ShopOpen)
+ {
+ new itemid=select_to_num(id,ItemTeams[0],ITEMNUM,item+1)
+ if(get_pcvar_num(g_sfrMode)!=0)
+ {
+ if(ItemSF[id]==item)
+ {
+ if((get_pcvar_num(g_sfrMode)==1)?getlevelexe(id)>=get_pcvar_num(g_sfrExe):zp_get_user_ammo_packs(id)>=get_pcvar_num(g_sfrPacks))
+ {
+ new g_num
+ g_levelpoint[id]=g_level[id]-1
+ for(new i=0;i<=IteamNums-1;i++)
+ g_skilllevel[id][i]=0
+ if(get_pcvar_num(g_sfrMode)==1)
+ g_levelexe[id]-=get_pcvar_num(g_sfrExe)
+
+ else zp_set_user_ammo_packs(id,zp_get_user_ammo_packs(id)-get_pcvar_num(g_sfrPacks))
+ ExecuteForward(g_ForwardID7,g_num,id)
+ client_color(id,"/y恭喜你!技能点重置成功...")
+ }
+ else
+ {
+ client_color(id,"/y对不起,您的/g%s/y不够,无法重置技能点数",(get_pcvar_num(g_sfrMode)==1)?"经验":"弹药袋")
+ }
+ return PLUGIN_CONTINUE;
+ }
+ }
+ if(get_user_flags(id)&ItemLevel[itemid]||ItemLevel[itemid]==0)
+ {
+ if(is_user_alive(id)&&ItemIfaLive[itemid]==1||!is_user_alive(id)&&ItemIfaLive[itemid]==2||ItemIfaLive[itemid]==3)
+ {
+ if(Limit[itemid][id]=ItemCost[itemid]&&item0)
+ Limit[itemid][id]+=1
+ if(TimeLimit[itemid]>0)
+ {
+ ITime[itemid][id]=1
+ Arid[id]=itemid
+ set_task(TimeLimit[itemid],"removelimits",id)
+ }
+ }
+ else if(item0)
+ Limit[itemid][id]+=1
+ if(TimeLimit[itemid]>0)
+ {
+ ITime[itemid][id]=1
+ Arid[id]=itemid
+ set_task(TimeLimit[itemid],"removelimits",id)
+ }
+ }
+
+ }
+ else client_color(id,"/ctr%s/y已经升到满级了,无法继续为您升级", MenuItem[itemid])
+ if(g_levelpoint[id]>0)
+ IMenuShow(id)
+ }
+ else
+ {
+ client_color(id,"/ctr%s/y被限制/g每%.1f秒/y升级,请/g等待/y后再升级", MenuItem[itemid],TimeLimit[itemid])
+ }
+ }
+ else
+ {
+ client_color(id,"/ctr%s/y被限制每局只能升级/g%d/y次,请/g下局/y再升级", MenuItem[itemid],TimesLimit[itemid])
+ }
+ }
+ else
+ {
+ client_color(id,"/y你现在处于/g%s/y的状态,不能升级 /ctr%s/y",AliveShow[ItemIfaLive[itemid]-1],MenuItem[itemid])
+ }
+ }
+ else
+ {
+ client_color(id,"/y你的/g权限/y不足以升级/ctr%s/y,请提升权限再行尝试",MenuItem[itemid])
+ }
+ }
+ else
+ {
+ client_color(id,"/ctr技能/y被限制开局后/g%d/y秒才可以升级,请/g等待.",get_pcvar_num(g_sfOpenTime))
+ }
+ }
+ }
+
+ menu_destroy(menu)
+
+ return PLUGIN_HANDLED
+}
+
+
+public IMenuShow(id)
+{
+ if(g_ShopOpen)
+ {
+ static opcion[64]
+ formatex(opcion, charsmax(opcion),"\w升级菜单\y||\w技能点数:\r%d",g_levelpoint[id])
+ new iMenu=menu_create(opcion,"Choose") //执行菜单命令的目标
+ new i,szTempid[10]
+ ItemSF[id]=0
+ for(i=0;i<=(IteamNums-1);i++)
+ {
+ if(((zp_get_user_zombie(id)?1:2)==ItemTeams[i]||ItemTeams[i]==3)&&get_user_team(id)!=3)
+ {
+ if(ItemCost[i]>0&&ItemIfaLive[i]!=0)
+ {
+ ItemSF[id]+=1
+ if(ItemLevel[i]==0)
+ {
+ if(g_skilllevel[id][i]!=ItemMaxLevel[i])
+ formatex(opcion, charsmax(opcion),"%s \y(\r%d/%d/%d\y) ", MenuItem[i],ItemCost[i],g_skilllevel[id][i],ItemMaxLevel[i])
+ else formatex(opcion, charsmax(opcion),"%s \rMAX!", MenuItem[i])
+ }
+ else{
+ if(g_skilllevel[id][i]!=ItemMaxLevel[i])
+ formatex(opcion, charsmax(opcion),"%s \rMAX! \yADMIN", MenuItem[i])
+ }
+ }
+ else if(ItemCost[i]==0&&ItemIfaLive[i]!=0)
+ {
+ ItemSF[id]+=1
+ if(ItemLevel[i]==0)
+ {
+ if(g_skilllevel[id][i]!=ItemMaxLevel[i])
+ formatex(opcion, charsmax(opcion),"%s \y(\r%d/%d\y)", MenuItem[i],g_skilllevel[id][i],ItemMaxLevel[i])
+ else formatex(opcion, charsmax(opcion),"%s \rMax!", MenuItem[i])
+ }
+ else{
+ if(g_skilllevel[id][i]!=ItemMaxLevel[i])
+ formatex(opcion, charsmax(opcion),"%s \y(\r%d/%d\y) \yADMIN", MenuItem[i],g_skilllevel[id][i],ItemMaxLevel[i])
+ else formatex(opcion, charsmax(opcion),"%s \rMax! \yADMIN", MenuItem[i])
+ }
+ }
+ menu_additem(iMenu, opcion, szTempid,0)
+ }
+ }
+ if(ItemSF[id]==0)
+ {
+ client_color(id,"/y该/ctr队伍/y的升级菜单/g无技能/y,/ctr无法打开/g升级菜单")
+ }
+ else if(get_pcvar_num(g_sfrMode)!=0)
+ {
+ formatex(opcion, charsmax(opcion),"\y重置技能点数\w(\r%d%s\w)",(get_pcvar_num(g_sfrMode)==1)?get_pcvar_num(g_sfrExe):get_pcvar_num(g_sfrPacks),(get_pcvar_num(g_sfrMode)==1)?"经验":"弹药袋")
+ menu_additem(iMenu, opcion, szTempid,0)
+ }
+ menu_setprop(iMenu, MPROP_EXIT, MEXIT_ALL)
+ formatex(opcion, charsmax(opcion),"\w返回") //返回菜单的名字
+ menu_setprop(iMenu, MPROP_BACKNAME, opcion)
+ formatex(opcion, charsmax(opcion),"\w下一页") //下一页菜单的名字
+ menu_setprop(iMenu, MPROP_NEXTNAME, opcion)
+ formatex(opcion, charsmax(opcion),"\w退出") //退出菜单的名字
+ menu_setprop(iMenu, MPROP_EXITNAME, opcion)
+ menu_setprop(iMenu, MPROP_NUMBER_COLOR, "\r") //菜单前面颜色的数字
+ menu_display(id, iMenu, 0)
+ }
+ else
+ {
+ client_color(id,"/ctr升级菜单/y被限制开局后/g%d/y秒才可以打开,请/g等待.",get_pcvar_num(g_sfOpenTime))
+ }
+
+ return PLUGIN_HANDLED
+}
+
+public client_disconnect(id)
+{
+ ApackPD[id]=0
+ ItemSF[id]=0
+ get_all(Limit,ITEMNUM-1,0,id)
+ get_all(ITime,ITEMNUM-1,0,id)
+ for(new i=0;i<=IteamNums-1;i++)
+ g_skilllevel[id][i]=0
+ remove_task(id)
+ remove_task(id+1000)
+ g_levelexe[id]=0
+ g_leveltotalexe[id]=get_pcvar_num(g_sfBasicExe)
+ g_level[id]=1
+ g_levelpoint[id]=0
+}
+
+
+
+/*============================华丽分割线===============================*/
+
+stock client_color(id, const input[], any:...)
+{
+ static iPlayersNum[32], iCount; iCount = 1
+ static szMsg[191]
+
+ vformat(szMsg, charsmax(szMsg), input, 3)
+
+ replace_all(szMsg, 190, "/g", "^4") // 绿色
+ replace_all(szMsg, 190, "/y", "^1") // 橙色
+ replace_all(szMsg, 190, "/ctr", "^3") // 队伍色
+ replace_all(szMsg, 190, "/w", "^0") // 黄色
+
+ if(id) iPlayersNum[0] = id
+ else get_players(iPlayersNum, iCount, "ch")
+
+ for (new i = 0; i < iCount; i++)
+ {
+ if (is_user_connected(iPlayersNum[i]))
+ {
+ message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("SayText"), _, iPlayersNum[i])
+ write_byte(iPlayersNum[i])
+ write_string(szMsg)
+ message_end()
+ }
+ }
+}
+
+//判断出当前选择的技能是否符合设置的队伍,符合的话返回该技能在队伍中所对应的位置
+stock select_to_num(index,numbers[],len,item)
+{
+ new empty=0
+ for(new i=0;i
- net9.0
+ net8.0
enable
enable
true
diff --git a/Source/Metahook.Plugin/Metahook.Plugin.csproj b/Source/Metahook.Plugin/Metahook.Plugin.csproj
index d081498..5911da2 100644
--- a/Source/Metahook.Plugin/Metahook.Plugin.csproj
+++ b/Source/Metahook.Plugin/Metahook.Plugin.csproj
@@ -1,7 +1,7 @@
- net9.0
+ net8.0
enable
enable
true
diff --git a/Source/SourceGenerators/AmxxModuleSourceGenerator/Amxmodx.SourceGenerator.csproj b/Source/SourceGenerators/AmxxModuleSourceGenerator/Amxmodx.SourceGenerator.csproj
index 6122a8b..61803fc 100644
--- a/Source/SourceGenerators/AmxxModuleSourceGenerator/Amxmodx.SourceGenerator.csproj
+++ b/Source/SourceGenerators/AmxxModuleSourceGenerator/Amxmodx.SourceGenerator.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/Template/Amxmodx.Module.Template/.template.config/template.json b/Template/Amxmodx.Module.Template/.template.config/template.json
index a5c20e6..98d1aac 100644
--- a/Template/Amxmodx.Module.Template/.template.config/template.json
+++ b/Template/Amxmodx.Module.Template/.template.config/template.json
@@ -10,6 +10,17 @@
"type": "project"
},
"sourceName": "Amxmodx.Module.Template",
- "preferNameDirectory": true
+ "preferNameDirectory": true,
+ "sources": [
+ {
+ "source": "./",
+ "target": "./",
+ "exclude": [".template.config/**/*"]
+ },
+ {
+ "source": "Bridge",
+ "target": "Bridge"
+ }
+ ]
}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Amxmodx.Module.Template.csproj b/Template/Amxmodx.Module.Template/Amxmodx.Module.Template.csproj
index 4616131..0a48e67 100644
--- a/Template/Amxmodx.Module.Template/Amxmodx.Module.Template.csproj
+++ b/Template/Amxmodx.Module.Template/Amxmodx.Module.Template.csproj
@@ -10,8 +10,17 @@
$(MSBuildProjectName.Replace(".", ""))_amxx
+
+
+
+
+
+
+
+
+
diff --git a/Template/Amxmodx.Module.Template/Amxmodx.Module.Template.sln b/Template/Amxmodx.Module.Template/Amxmodx.Module.Template.sln
new file mode 100644
index 0000000..7cfe4d7
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Amxmodx.Module.Template.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.8.34227.203
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Amxmodx.Module.Template", "Amxmodx.Module.Template.csproj", "{01F1C56E-754E-41F2-8503-A9379E328F27}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {01F1C56E-754E-41F2-8503-A9379E328F27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {01F1C56E-754E-41F2-8503-A9379E328F27}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {01F1C56E-754E-41F2-8503-A9379E328F27}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {01F1C56E-754E-41F2-8503-A9379E328F27}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {0ED03508-EFF5-4811-98DC-E6E0936B23BA}
+ EndGlobalSection
+EndGlobal
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Communication/AmxModx.Bridge.Event.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Communication/AmxModx.Bridge.Event.cs
new file mode 100644
index 0000000..4c8623b
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Communication/AmxModx.Bridge.Event.cs
@@ -0,0 +1,223 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace AmxModx.Bridge.Event
+{
+ ///
+ /// 事件标志枚举
+ ///
+ [Flags]
+ public enum EventFlags
+ {
+ ///
+ /// 无特殊标志
+ ///
+ None = 0,
+
+ ///
+ /// 包含世界事件
+ ///
+ IncludeWorld = 1,
+
+ ///
+ /// 包含客户端事件
+ ///
+ IncludeClient = 2,
+
+ ///
+ /// 只执行一次
+ ///
+ Once = 4,
+
+ ///
+ /// 只包含死亡玩家
+ ///
+ DeadOnly = 8,
+
+ ///
+ /// 只包含存活玩家
+ ///
+ AliveOnly = 16,
+
+ ///
+ /// 不包含机器人
+ ///
+ NoBots = 32,
+
+ ///
+ /// 不包含真实玩家
+ ///
+ NoPlayers = 64
+ }
+
+ ///
+ /// 事件回调委托
+ ///
+ /// 事件数据
+ public delegate void EventCallback(EventData eventData);
+
+ ///
+ /// 事件数据类
+ ///
+ public class EventData
+ {
+ ///
+ /// 事件名称
+ ///
+ public string EventName { get; set; }
+
+ ///
+ /// 触发事件的玩家ID
+ ///
+ public int PlayerId { get; set; }
+
+ ///
+ /// 事件参数
+ ///
+ public object[] Parameters { get; set; }
+ }
+
+ ///
+ /// 事件系统桥接接口
+ ///
+ public static class EventBridge
+ {
+ private const string DllName = "amxmodx_mm";
+
+ ///
+ /// 注册游戏事件
+ ///
+ /// 事件名称
+ /// 回调函数名
+ /// 事件标志
+ /// 事件条件数组
+ /// 条件数量
+ /// 事件句柄,失败返回0
+ [DllImport(DllName, EntryPoint = "AmxModx_Bridge_RegisterEvent", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int RegisterEvent([MarshalAs(UnmanagedType.LPStr)] string eventName,
+ [MarshalAs(UnmanagedType.LPStr)] string callbackFunc,
+ int flags,
+ [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[] conditions,
+ int conditionCount);
+
+ ///
+ /// 扩展注册游戏事件
+ ///
+ /// 事件名称
+ /// 回调函数名
+ /// 事件标志
+ /// 事件条件数组
+ /// 条件数量
+ /// 事件句柄,失败返回0
+ [DllImport(DllName, EntryPoint = "AmxModx_Bridge_RegisterEventEx", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int RegisterEventEx([MarshalAs(UnmanagedType.LPStr)] string eventName,
+ [MarshalAs(UnmanagedType.LPStr)] string callbackFunc,
+ int flags,
+ [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[] conditions,
+ int conditionCount);
+
+ ///
+ /// 启用事件
+ ///
+ /// 事件句柄
+ /// 成功返回1,失败返回0
+ [DllImport(DllName, EntryPoint = "AmxModx_Bridge_EnableEvent", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int EnableEvent(int eventHandle);
+
+ ///
+ /// 禁用事件
+ ///
+ /// 事件句柄
+ /// 成功返回1,失败返回0
+ [DllImport(DllName, EntryPoint = "AmxModx_Bridge_DisableEvent", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int DisableEvent(int eventHandle);
+
+ ///
+ /// 获取事件ID
+ ///
+ /// 事件名称
+ /// 事件ID,0表示无效事件
+ [DllImport(DllName, EntryPoint = "AmxModx_Bridge_GetEventId", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetEventId([MarshalAs(UnmanagedType.LPStr)] string eventName);
+
+ ///
+ /// 检查事件是否有效
+ ///
+ /// 事件句柄
+ /// 有效返回1,无效返回0
+ [DllImport(DllName, EntryPoint = "AmxModx_Bridge_IsEventValid", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int IsEventValid(int eventHandle);
+
+ ///
+ /// 注册事件并绑定回调
+ ///
+ /// 事件名称
+ /// 回调函数
+ /// 事件标志
+ /// 事件条件
+ /// 事件句柄
+ public static int RegisterEventWithCallback(string eventName, EventCallback callback, EventFlags flags = EventFlags.None, params string[] conditions)
+ {
+ // 注意:由于AMX Mod X的事件系统需要函数名,
+ // 这里需要实现一个映射机制来将C#委托映射到内部函数
+ // 简化实现:返回句柄,实际回调需要通过其他机制处理
+ return RegisterEvent(eventName, "EventCallbackProxy", (int)flags, conditions, conditions?.Length ?? 0);
+ }
+
+ ///
+ /// 注册常见游戏事件
+ ///
+ public static class GameEvents
+ {
+ ///
+ /// 玩家死亡事件
+ ///
+ public const string PlayerDeath = "DeathMsg";
+
+ ///
+ /// 玩家连接事件
+ ///
+ public const string PlayerConnect = "PlayerConnect";
+
+ ///
+ /// 玩家断开连接事件
+ ///
+ public const string PlayerDisconnect = "PlayerDisconnect";
+
+ ///
+ /// 玩家重生事件
+ ///
+ public const string PlayerSpawn = "Spawn";
+
+ ///
+ /// 回合开始事件
+ ///
+ public const string RoundStart = "RoundStart";
+
+ ///
+ /// 回合结束事件
+ ///
+ public const string RoundEnd = "RoundEnd";
+
+ ///
+ /// 炸弹安放事件
+ ///
+ public const string BombPlanted = "BombPlanted";
+
+ ///
+ /// 炸弹爆炸事件
+ ///
+ public const string BombExploded = "BombExploded";
+
+ ///
+ /// 炸弹拆除事件
+ ///
+ public const string BombDefused = "BombDefused";
+
+ ///
+ /// 人质救援事件
+ ///
+ public const string HostageRescued = "HostageRescued";
+ }
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Communication/AmxModx.Bridge.Forward.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Communication/AmxModx.Bridge.Forward.cs
new file mode 100644
index 0000000..6d5b00d
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Communication/AmxModx.Bridge.Forward.cs
@@ -0,0 +1,252 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace AmxModx.Bridge
+{
+ ///
+ /// 转发系统桥接接口
+ /// 提供AMX Mod X转发器的C#封装
+ ///
+ public static class Forward
+ {
+ ///
+ /// 参数类型枚举
+ ///
+ public enum ForwardParamType
+ {
+ /// 普通整数
+ Cell = 0,
+ /// 浮点数
+ Float = 1,
+ /// 字符串
+ String = 2,
+ /// 可更新字符串
+ StringEx = 3,
+ /// 数组
+ Array = 4,
+ /// 整数引用
+ CellByRef = 5,
+ /// 浮点数引用
+ FloatByRef = 6
+ }
+
+ ///
+ /// 执行类型枚举
+ ///
+ public enum ForwardExecType
+ {
+ /// 忽略返回值
+ Ignore = 0,
+ /// 遇到PLUGIN_HANDLED时停止
+ Stop = 1,
+ /// 遇到PLUGIN_HANDLED时停止,其他值继续
+ Stop2 = 2,
+ /// 继续执行,返回最大返回值
+ Continue = 3
+ }
+
+ ///
+ /// 创建多插件转发器
+ ///
+ /// 转发器名称
+ /// 执行类型
+ /// 参数类型数组
+ /// 转发器ID,失败返回-1
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_CreateMultiForward(
+ [MarshalAs(UnmanagedType.LPStr)] string funcName,
+ ForwardExecType execType,
+ int numParams,
+ [In, MarshalAs(UnmanagedType.LPArray)] int[] paramTypes
+ );
+
+ ///
+ /// 创建单插件转发器
+ ///
+ /// 插件ID
+ /// 函数名称
+ /// 参数类型数组
+ /// 转发器ID,失败返回-1
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_CreateOneForward(
+ int pluginId,
+ [MarshalAs(UnmanagedType.LPStr)] string funcName,
+ int numParams,
+ [In, MarshalAs(UnmanagedType.LPArray)] int[] paramTypes
+ );
+
+ ///
+ /// 销毁转发器
+ ///
+ /// 转发器ID
+ /// 成功返回1,失败返回0
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_DestroyForward(int forwardId);
+
+ ///
+ /// 执行转发器
+ ///
+ /// 转发器ID
+ /// 参数数组
+ /// 执行结果
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ExecuteForward(
+ int forwardId,
+ [In, MarshalAs(UnmanagedType.LPArray)] int[] parameters,
+ int numParams
+ );
+
+ ///
+ /// 准备数组参数
+ ///
+ /// 数组数据
+ /// 数组大小
+ /// 是否复制回数据
+ /// 数组句柄
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_PrepareArray(
+ [In, MarshalAs(UnmanagedType.LPArray)] int[] arrayData,
+ int size,
+ int copyBack
+ );
+
+ ///
+ /// 获取转发器参数数量
+ ///
+ /// 转发器ID
+ /// 参数数量,失败返回-1
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetForwardParamCount(int forwardId);
+
+ ///
+ /// 获取转发器参数类型
+ ///
+ /// 转发器ID
+ /// 参数索引
+ /// 参数类型,失败返回-1
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetForwardParamType(int forwardId, int paramIndex);
+
+ ///
+ /// 创建多插件转发器(简化版)
+ ///
+ /// 转发器名称
+ /// 执行类型
+ /// 参数类型数组
+ /// 转发器ID
+ public static int CreateMultiForward(string funcName, ForwardExecType execType, params ForwardParamType[] paramTypes)
+ {
+ int[] types = Array.ConvertAll(paramTypes, x => (int)x);
+ return AmxModx_Bridge_CreateMultiForward(funcName, execType, types.Length, types);
+ }
+
+ ///
+ /// 创建单插件转发器(简化版)
+ ///
+ /// 插件ID
+ /// 函数名称
+ /// 参数类型数组
+ /// 转发器ID
+ public static int CreateOneForward(int pluginId, string funcName, params ForwardParamType[] paramTypes)
+ {
+ int[] types = Array.ConvertAll(paramTypes, x => (int)x);
+ return AmxModx_Bridge_CreateOneForward(pluginId, funcName, types.Length, types);
+ }
+
+ ///
+ /// 执行转发器(简化版)
+ ///
+ /// 转发器ID
+ /// 参数数组
+ /// 执行结果
+ public static int ExecuteForward(int forwardId, params int[] parameters)
+ {
+ return AmxModx_Bridge_ExecuteForward(forwardId, parameters, parameters.Length);
+ }
+
+ ///
+ /// 准备数组参数(简化版)
+ ///
+ /// 数组数据
+ /// 是否复制回数据
+ /// 数组句柄
+ public static int PrepareArray(int[] arrayData, bool copyBack = false)
+ {
+ return AmxModx_Bridge_PrepareArray(arrayData, arrayData.Length, copyBack ? 1 : 0);
+ }
+
+ ///
+ /// 委托定义:转发回调函数
+ ///
+ /// 参数数组
+ /// 执行结果
+ public delegate int ForwardCallback(params int[] parameters);
+
+ ///
+ /// 事件管理器类
+ ///
+ public static class ForwardManager
+ {
+ ///
+ /// 已注册的转发器字典
+ ///
+ private static Dictionary forwards =
+ new Dictionary();
+
+ ///
+ /// 注册全局转发器
+ ///
+ /// 转发器名称
+ /// 执行类型
+ /// 参数类型
+ /// 转发器ID
+ public static int RegisterForward(string name, ForwardExecType execType, params ForwardParamType[] paramTypes)
+ {
+ if (forwards.ContainsKey(name))
+ return forwards[name];
+
+ int forwardId = CreateMultiForward(name, execType, paramTypes);
+ if (forwardId >= 0)
+ forwards[name] = forwardId;
+
+ return forwardId;
+ }
+
+ ///
+ /// 获取转发器ID
+ ///
+ /// 转发器名称
+ /// 转发器ID,不存在返回-1
+ public static int GetForward(string name)
+ {
+ return forwards.ContainsKey(name) ? forwards[name] : -1;
+ }
+
+ ///
+ /// 执行已注册的转发器
+ ///
+ /// 转发器名称
+ /// 参数
+ /// 执行结果
+ public static int ExecuteRegisteredForward(string name, params int[] parameters)
+ {
+ if (!forwards.ContainsKey(name))
+ return 0;
+
+ return ExecuteForward(forwards[name], parameters);
+ }
+
+ ///
+ /// 清理所有转发器
+ ///
+ public static void Clear()
+ {
+ foreach (var forwardId in forwards.Values)
+ {
+ AmxModx_Bridge_DestroyForward(forwardId);
+ }
+ forwards.Clear();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Communication/AmxModx.Bridge.Messages.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Communication/AmxModx.Bridge.Messages.cs
new file mode 100644
index 0000000..3acdc9d
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Communication/AmxModx.Bridge.Messages.cs
@@ -0,0 +1,319 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+namespace AmxModx.Bridge.Messages
+{
+ ///
+ /// 消息系统桥接接口
+ ///
+ public static class MessageBridge
+ {
+ private const string DllName = "amxmodx_mm";
+
+ ///
+ /// 消息目标类型
+ ///
+ public enum MessageDestination
+ {
+ BROADCAST = 0,
+ ONE = 1,
+ ALL = 2,
+ INIT = 3,
+ PVS = 4,
+ PAS = 5,
+ PVS_R = 6,
+ PAS_R = 7,
+ ONE_UNRELIABLE = 8,
+ SPEC = 32
+ }
+
+ ///
+ /// 消息参数类型
+ ///
+ public enum MessageArgType
+ {
+ BYTE = 1,
+ CHAR = 2,
+ SHORT = 3,
+ LONG = 4,
+ ANGLE = 5,
+ COORD = 6,
+ STRING = 7,
+ ENTITY = 8
+ }
+
+ ///
+ /// 开始发送消息
+ ///
+ /// 消息目标
+ /// 消息类型
+ /// 消息原点坐标
+ /// 实体索引
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_MessageBegin(
+ int msgDest,
+ int msgType,
+ [MarshalAs(UnmanagedType.LPArray, SizeConst = 3)] float[] origin,
+ int edict);
+
+ ///
+ /// 结束消息发送
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_MessageEnd();
+
+ ///
+ /// 写入字节数据到消息
+ ///
+ /// 字节值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_WriteByte(int value);
+
+ ///
+ /// 写入字符数据到消息
+ ///
+ /// 字符值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_WriteChar(int value);
+
+ ///
+ /// 写入短整型数据到消息
+ ///
+ /// 短整型值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_WriteShort(int value);
+
+ ///
+ /// 写入长整型数据到消息
+ ///
+ /// 长整型值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_WriteLong(int value);
+
+ ///
+ /// 写入实体数据到消息
+ ///
+ /// 实体索引
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_WriteEntity(int value);
+
+ ///
+ /// 写入角度数据到消息
+ ///
+ /// 角度值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_WriteAngle(float value);
+
+ ///
+ /// 写入坐标数据到消息
+ ///
+ /// 坐标值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_WriteCoord(float value);
+
+ ///
+ /// 写入字符串数据到消息
+ ///
+ /// 字符串值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_WriteString([MarshalAs(UnmanagedType.LPStr)] string str);
+
+ ///
+ /// 注册消息钩子
+ ///
+ /// 消息ID
+ /// 回调函数指针
+ /// 是否为后置钩子
+ /// 是否注册成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_RegisterMessage(int msgId, IntPtr callback, int post);
+
+ ///
+ /// 注销消息钩子
+ ///
+ /// 消息ID
+ /// 回调函数指针
+ /// 是否为后置钩子
+ /// 是否注销成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_UnregisterMessage(int msgId, IntPtr callback, int post);
+
+ ///
+ /// 设置消息阻塞
+ ///
+ /// 消息ID
+ /// 是否阻塞
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_SetMessageBlock(int msgId, int blocking);
+
+ ///
+ /// 获取消息阻塞状态
+ ///
+ /// 消息ID
+ /// 阻塞状态
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetMessageBlock(int msgId);
+
+ ///
+ /// 获取消息参数数量
+ ///
+ /// 参数数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetMessageArgs();
+
+ ///
+ /// 获取消息参数类型
+ ///
+ /// 参数索引
+ /// 参数类型
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetMessageArgType(int argIndex);
+
+ ///
+ /// 获取消息参数整数值
+ ///
+ /// 参数索引
+ /// 整数值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetMessageArgInt(int argIndex);
+
+ ///
+ /// 获取消息参数浮点数值
+ ///
+ /// 参数索引
+ /// 浮点数值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern float AmxModx_Bridge_GetMessageArgFloat(int argIndex);
+
+ ///
+ /// 获取消息参数字符串值
+ ///
+ /// 参数索引
+ /// 输出缓冲区
+ /// 缓冲区大小
+ /// 实际复制的字符数
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetMessageArgString(int argIndex, [MarshalAs(UnmanagedType.LPStr)] StringBuilder buffer, int bufferSize);
+
+ ///
+ /// 设置消息参数整数值
+ ///
+ /// 参数索引
+ /// 整数值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_SetMessageArgInt(int argIndex, int value);
+
+ ///
+ /// 设置消息参数浮点数值
+ ///
+ /// 参数索引
+ /// 浮点数值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_SetMessageArgFloat(int argIndex, float value);
+
+ ///
+ /// 设置消息参数字符串值
+ ///
+ /// 参数索引
+ /// 字符串值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_SetMessageArgString(int argIndex, [MarshalAs(UnmanagedType.LPStr)] string str);
+
+ ///
+ /// 消息管理器包装类
+ ///
+ public static class MessageManager
+ {
+ ///
+ /// 开始发送消息
+ ///
+ public static void BeginMessage(MessageDestination dest, int msgType, float[] origin = null, int entityIndex = 0)
+ {
+ float[] originArray = origin ?? new float[3];
+ AmxModx_Bridge_MessageBegin((int)dest, msgType, originArray, entityIndex);
+ }
+
+ ///
+ /// 结束消息发送
+ ///
+ public static void EndMessage()
+ {
+ AmxModx_Bridge_MessageEnd();
+ }
+
+ ///
+ /// 发送简单消息
+ ///
+ public static void SendMessage(MessageDestination dest, int msgType, Action writeAction)
+ {
+ BeginMessage(dest, msgType);
+ writeAction?.Invoke();
+ EndMessage();
+ }
+
+ ///
+ /// 写入字节数据
+ ///
+ public static void WriteByte(byte value)
+ {
+ AmxModx_Bridge_WriteByte(value);
+ }
+
+ ///
+ /// 写入字符数据
+ ///
+ public static void WriteChar(sbyte value)
+ {
+ AmxModx_Bridge_WriteChar(value);
+ }
+
+ ///
+ /// 写入短整型数据
+ ///
+ public static void WriteShort(short value)
+ {
+ AmxModx_Bridge_WriteShort(value);
+ }
+
+ ///
+ /// 写入长整型数据
+ ///
+ public static void WriteLong(int value)
+ {
+ AmxModx_Bridge_WriteLong(value);
+ }
+
+ ///
+ /// 写入实体数据
+ ///
+ public static void WriteEntity(int entityIndex)
+ {
+ AmxModx_Bridge_WriteEntity(entityIndex);
+ }
+
+ ///
+ /// 写入角度数据
+ ///
+ public static void WriteAngle(float angle)
+ {
+ AmxModx_Bridge_WriteAngle(angle);
+ }
+
+ ///
+ /// 写入坐标数据
+ ///
+ public static void WriteCoord(float coord)
+ {
+ AmxModx_Bridge_WriteCoord(coord);
+ }
+
+ ///
+ /// 写入字符串数据
+ ///
+ public static void WriteString(string text)
+ {
+ AmxModx_Bridge_WriteString(text);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.CVar.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.CVar.cs
new file mode 100644
index 0000000..44de2d7
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.CVar.cs
@@ -0,0 +1,188 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace AmxModx.Bridge.CVar
+{
+ ///
+ /// 控制台变量桥接接口,提供CVar操作功能
+ ///
+ public static class CVarBridge
+ {
+ private const string NativeLibrary = "amxmodx_mm";
+
+ #region CVar操作
+
+ ///
+ /// 创建控制台变量
+ ///
+ /// 变量名
+ /// 初始值
+ /// 变量标志
+ /// 创建的变量指针
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_CreateCVar([MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string value, int flags);
+
+ ///
+ /// 查找控制台变量
+ ///
+ /// 变量名
+ /// 找到的变量指针
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_FindCVar([MarshalAs(UnmanagedType.LPStr)] string name);
+
+ ///
+ /// 获取控制台变量字符串值
+ ///
+ /// 变量指针
+ /// 字符串值
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_GetCVarString(IntPtr cvar);
+
+ ///
+ /// 获取控制台变量浮点数值
+ ///
+ /// 变量指针
+ /// 浮点数值
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern float AmxModx_Bridge_GetCVarFloat(IntPtr cvar);
+
+ ///
+ /// 获取控制台变量整数值
+ ///
+ /// 变量指针
+ /// 整数值
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetCVarInt(IntPtr cvar);
+
+ ///
+ /// 设置控制台变量字符串值
+ ///
+ /// 变量指针
+ /// 要设置的字符串值
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_SetCVarString(IntPtr cvar, [MarshalAs(UnmanagedType.LPStr)] string value);
+
+ ///
+ /// 设置控制台变量浮点数值
+ ///
+ /// 变量指针
+ /// 要设置的浮点数值
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_SetCVarFloat(IntPtr cvar, float value);
+
+ ///
+ /// 设置控制台变量整数值
+ ///
+ /// 变量指针
+ /// 要设置的整数值
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_SetCVarInt(IntPtr cvar, int value);
+
+ #endregion
+
+ #region 便捷方法
+
+ ///
+ /// 获取CVar字符串值的安全封装
+ ///
+ /// 变量指针
+ /// 字符串值
+ public static string GetCVarStringSafe(IntPtr cvar)
+ {
+ if (cvar == IntPtr.Zero)
+ return string.Empty;
+
+ IntPtr ptr = AmxModx_Bridge_GetCVarString(cvar);
+ return ptr != IntPtr.Zero ? Marshal.PtrToStringAnsi(ptr) : string.Empty;
+ }
+
+ ///
+ /// 通过变量名获取字符串值
+ ///
+ /// 变量名
+ /// 字符串值
+ public static string GetCVarStringByName(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ return string.Empty;
+
+ IntPtr cvar = AmxModx_Bridge_FindCVar(name);
+ return GetCVarStringSafe(cvar);
+ }
+
+ ///
+ /// 通过变量名获取浮点数值
+ ///
+ /// 变量名
+ /// 浮点数值
+ public static float GetCVarFloatByName(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ return 0.0f;
+
+ IntPtr cvar = AmxModx_Bridge_FindCVar(name);
+ return cvar != IntPtr.Zero ? AmxModx_Bridge_GetCVarFloat(cvar) : 0.0f;
+ }
+
+ ///
+ /// 通过变量名获取整数值
+ ///
+ /// 变量名
+ /// 整数值
+ public static int GetCVarIntByName(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ return 0;
+
+ IntPtr cvar = AmxModx_Bridge_FindCVar(name);
+ return cvar != IntPtr.Zero ? AmxModx_Bridge_GetCVarInt(cvar) : 0;
+ }
+
+ ///
+ /// 通过变量名设置字符串值
+ ///
+ /// 变量名
+ /// 要设置的值
+ public static void SetCVarStringByName(string name, string value)
+ {
+ if (string.IsNullOrEmpty(name))
+ return;
+
+ IntPtr cvar = AmxModx_Bridge_FindCVar(name);
+ if (cvar != IntPtr.Zero)
+ AmxModx_Bridge_SetCVarString(cvar, value);
+ }
+
+ ///
+ /// 通过变量名设置浮点数值
+ ///
+ /// 变量名
+ /// 要设置的值
+ public static void SetCVarFloatByName(string name, float value)
+ {
+ if (string.IsNullOrEmpty(name))
+ return;
+
+ IntPtr cvar = AmxModx_Bridge_FindCVar(name);
+ if (cvar != IntPtr.Zero)
+ AmxModx_Bridge_SetCVarFloat(cvar, value);
+ }
+
+ ///
+ /// 通过变量名设置整数值
+ ///
+ /// 变量名
+ /// 要设置的值
+ public static void SetCVarIntByName(string name, int value)
+ {
+ if (string.IsNullOrEmpty(name))
+ return;
+
+ IntPtr cvar = AmxModx_Bridge_FindCVar(name);
+ if (cvar != IntPtr.Zero)
+ AmxModx_Bridge_SetCVarInt(cvar, value);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.Config.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.Config.cs
new file mode 100644
index 0000000..cb8cda2
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.Config.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace AmxModx.Bridge.Config
+{
+ ///
+ /// 配置文件桥接接口
+ /// 提供游戏配置文件处理功能
+ ///
+ public static class ConfigBridge
+ {
+ ///
+ /// 加载游戏配置文件
+ ///
+ /// 配置文件名称
+ /// 配置句柄
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_LoadGameConfig([MarshalAs(UnmanagedType.LPStr)] string configName);
+
+ ///
+ /// 获取配置值
+ ///
+ /// 配置句柄
+ /// 配置键
+ /// 输出缓冲区
+ /// 缓冲区大小
+ /// 实际长度
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetConfigValue(IntPtr configHandle, [MarshalAs(UnmanagedType.LPStr)] string key, [Out] byte[] buffer, int bufferSize);
+
+ ///
+ /// 安全的获取配置值方法
+ ///
+ /// 配置句柄
+ /// 配置键
+ /// 配置值
+ public static string GetConfigValueSafe(IntPtr configHandle, string key)
+ {
+ if (configHandle == IntPtr.Zero || string.IsNullOrEmpty(key))
+ return string.Empty;
+
+ byte[] buffer = new byte[256];
+ int length = AmxModx_Bridge_GetConfigValue(configHandle, key, buffer, buffer.Length);
+ if (length <= 0)
+ return string.Empty;
+
+ return Encoding.UTF8.GetString(buffer, 0, Math.Min(length, buffer.Length));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.DataPack.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.DataPack.cs
new file mode 100644
index 0000000..f65a0fd
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.DataPack.cs
@@ -0,0 +1,119 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace AmxModx.Bridge.DataPack
+{
+ ///
+ /// 数据包桥接接口,提供CDataPack操作功能
+ ///
+ public static class DataPackBridge
+ {
+ private const string NativeLibrary = "amxmodx_mm";
+
+ #region DataPack操作
+
+ ///
+ /// 创建新的数据包
+ ///
+ /// 新创建的数据包指针
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_CreateDataPack();
+
+ ///
+ /// 销毁数据包
+ ///
+ /// 要销毁的数据包指针
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_DestroyDataPack(IntPtr pack);
+
+ ///
+ /// 获取数据包当前位置
+ ///
+ /// 数据包指针
+ /// 当前位置
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetDataPackPosition(IntPtr pack);
+
+ ///
+ /// 设置数据包位置
+ ///
+ /// 数据包指针
+ /// 要设置的位置
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_SetDataPackPosition(IntPtr pack, int position);
+
+ ///
+ /// 向数据包写入整数
+ ///
+ /// 数据包指针
+ /// 要写入的值
+ /// 写入是否成功
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ public static extern bool AmxModx_Bridge_WriteDataPackCell(IntPtr pack, int value);
+
+ ///
+ /// 向数据包写入浮点数
+ ///
+ /// 数据包指针
+ /// 要写入的值
+ /// 写入是否成功
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ public static extern bool AmxModx_Bridge_WriteDataPackFloat(IntPtr pack, float value);
+
+ ///
+ /// 向数据包写入字符串
+ ///
+ /// 数据包指针
+ /// 要写入的字符串
+ /// 写入是否成功
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ public static extern bool AmxModx_Bridge_WriteDataPackString(IntPtr pack, [MarshalAs(UnmanagedType.LPStr)] string value);
+
+ ///
+ /// 从数据包读取整数
+ ///
+ /// 数据包指针
+ /// 读取的整数值
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ReadDataPackCell(IntPtr pack);
+
+ ///
+ /// 从数据包读取浮点数
+ ///
+ /// 数据包指针
+ /// 读取的浮点数值
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern float AmxModx_Bridge_ReadDataPackFloat(IntPtr pack);
+
+ ///
+ /// 从数据包读取字符串
+ ///
+ /// 数据包指针
+ /// 读取的字符串
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_ReadDataPackString(IntPtr pack);
+
+ #endregion
+
+ #region 便捷方法
+
+ ///
+ /// 从数据包读取字符串的安全封装
+ ///
+ /// 数据包指针
+ /// 读取的字符串
+ public static string ReadDataPackStringSafe(IntPtr pack)
+ {
+ if (pack == IntPtr.Zero)
+ return string.Empty;
+
+ IntPtr ptr = AmxModx_Bridge_ReadDataPackString(pack);
+ return ptr != IntPtr.Zero ? Marshal.PtrToStringAnsi(ptr) : string.Empty;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.DataStructs.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.DataStructs.cs
new file mode 100644
index 0000000..98e9917
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.DataStructs.cs
@@ -0,0 +1,188 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace AmxModx.Bridge.Data
+{
+ ///
+ /// 数据结构桥接接口
+ /// 提供动态数组和栈结构的C#访问
+ ///
+ public static class DataStructsBridge
+ {
+ private const string DllName = "amxmodx_mm";
+
+ ///
+ /// 创建动态数组
+ ///
+ /// 每个元素的大小(以cell为单位)
+ /// 初始预留容量
+ /// 数组句柄,失败返回0
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ArrayCreate(int cellsize, int reserved = 32);
+
+ ///
+ /// 销毁数组并释放内存
+ ///
+ /// 数组句柄(传引用,成功后会置0)
+ /// 是否成功销毁
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_ArrayDestroy(ref int handle);
+
+ ///
+ /// 获取数组当前元素数量
+ ///
+ /// 数组句柄
+ /// 元素数量,失败返回-1
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ArraySize(int handle);
+
+ ///
+ /// 调整数组大小
+ ///
+ /// 数组句柄
+ /// 新的元素数量
+ /// 是否成功调整
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_ArrayResize(int handle, int count);
+
+ ///
+ /// 获取数组元素(单元格值)
+ ///
+ /// 数组句柄
+ /// 元素索引
+ /// 数据块索引(默认为0)
+ /// 单元格值,失败返回0
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ArrayGetCell(int handle, int index, int block = 0);
+
+ ///
+ /// 设置数组元素(单元格值)
+ ///
+ /// 数组句柄
+ /// 元素索引
+ /// 要设置的值
+ /// 数据块索引(默认为0)
+ /// 是否成功设置
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_ArraySetCell(int handle, int index, int value, int block = 0);
+
+ ///
+ /// 向数组末尾添加单元格值
+ ///
+ /// 数组句柄
+ /// 要添加的值
+ /// 新元素的索引,失败返回-1
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ArrayPushCell(int handle, int value);
+
+ ///
+ /// 从数组获取字符串
+ ///
+ /// 数组句柄
+ /// 元素索引
+ /// 输出缓冲区
+ /// 缓冲区大小
+ /// 实际复制的字符数
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ArrayGetString(int handle, int index, [Out] StringBuilder buffer, int size);
+
+ ///
+ /// 向数组设置字符串
+ ///
+ /// 数组句柄
+ /// 元素索引
+ /// 要设置的字符串
+ /// 实际复制的字符数
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ArraySetString(int handle, int index, [MarshalAs(UnmanagedType.LPStr)] string str);
+
+ ///
+ /// 克隆数组
+ ///
+ /// 原数组句柄
+ /// 新数组句柄,失败返回0
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ArrayClone(int handle);
+
+ ///
+ /// 清空数组内容
+ ///
+ /// 数组句柄
+ /// 是否成功清空
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_ArrayClear(int handle);
+
+ ///
+ /// 删除指定索引的元素
+ ///
+ /// 数组句柄
+ /// 要删除的索引
+ /// 是否成功删除
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_ArrayDeleteItem(int handle, int index);
+
+ ///
+ /// 交换两个元素的位置
+ ///
+ /// 数组句柄
+ /// 第一个索引
+ /// 第二个索引
+ /// 是否成功交换
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_ArraySwap(int handle, int index1, int index2);
+
+ ///
+ /// 在数组中查找字符串
+ ///
+ /// 数组句柄
+ /// 要查找的字符串
+ /// 找到返回索引,未找到返回-1
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ArrayFindString(int handle, [MarshalAs(UnmanagedType.LPStr)] string str);
+
+ ///
+ /// 在数组中查找数值
+ ///
+ /// 数组句柄
+ /// 要查找的值
+ /// 找到返回索引,未找到返回-1
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ArrayFindValue(int handle, int value);
+
+ ///
+ /// 安全的获取数组字符串
+ ///
+ /// 数组句柄
+ /// 元素索引
+ /// 字符串值
+ public static string GetArrayStringSafe(int handle, int index)
+ {
+ StringBuilder buffer = new StringBuilder(256);
+ int length = AmxModx_Bridge_ArrayGetString(handle, index, buffer, buffer.Capacity);
+ return length > 0 ? buffer.ToString() : string.Empty;
+ }
+
+ ///
+ /// 安全的设置数组字符串
+ ///
+ /// 数组句柄
+ /// 元素索引
+ /// 字符串值
+ /// 是否成功设置
+ public static bool SetArrayStringSafe(int handle, int index, string value)
+ {
+ if (string.IsNullOrEmpty(value))
+ return false;
+
+ int result = AmxModx_Bridge_ArraySetString(handle, index, value);
+ return result > 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.File.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.File.cs
new file mode 100644
index 0000000..6cd271b
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.File.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace AmxModx.Bridge.File
+{
+ ///
+ /// 文件系统桥接接口,提供文件操作功能
+ ///
+ public static class FileBridge
+ {
+ private const string NativeLibrary = "amxmodx_mm";
+
+ #region 文件系统操作
+
+ ///
+ /// 读取文件内容到内存缓冲区
+ ///
+ /// 文件路径
+ /// 返回文件大小
+ /// 文件内容缓冲区指针,需要手动释放
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_ReadFile([MarshalAs(UnmanagedType.LPStr)] string filePath, out int size);
+
+ ///
+ /// 将数据写入文件
+ ///
+ /// 文件路径
+ /// 要写入的数据
+ /// 数据大小
+ /// 写入是否成功
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ public static extern bool AmxModx_Bridge_WriteFile([MarshalAs(UnmanagedType.LPStr)] string filePath, [MarshalAs(UnmanagedType.LPStr)] string data, int size);
+
+ ///
+ /// 释放由ReadFile分配的缓冲区
+ ///
+ /// 要释放的缓冲区指针
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_FreeBuffer(IntPtr buffer);
+
+ ///
+ /// 检查文件是否存在
+ ///
+ /// 文件名
+ /// 文件是否存在
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ public static extern bool AmxModx_Bridge_FileExists([MarshalAs(UnmanagedType.LPStr)] string fileName);
+
+ ///
+ /// 从文件读取字符串内容
+ ///
+ /// 文件名
+ /// 输出缓冲区
+ /// 缓冲区大小
+ /// 读取是否成功
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ public static extern bool AmxModx_Bridge_ReadFileString([MarshalAs(UnmanagedType.LPStr)] string fileName, [Out, MarshalAs(UnmanagedType.LPArray)] byte[] buffer, int bufferSize);
+
+ ///
+ /// 将字符串写入文件
+ ///
+ /// 文件名
+ /// 要写入的内容
+ /// 写入是否成功
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ public static extern bool AmxModx_Bridge_WriteFileString([MarshalAs(UnmanagedType.LPStr)] string fileName, [MarshalAs(UnmanagedType.LPStr)] string content);
+
+ ///
+ /// 删除文件
+ ///
+ /// 文件名
+ /// 删除是否成功
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ public static extern bool AmxModx_Bridge_DeleteFile([MarshalAs(UnmanagedType.LPStr)] string fileName);
+
+ #endregion
+
+ #region 便捷方法
+
+ ///
+ /// 安全读取文件内容
+ ///
+ /// 文件路径
+ /// 文件内容字符串,失败返回null
+ public static string ReadFileSafe(string filePath)
+ {
+ if (string.IsNullOrEmpty(filePath))
+ return null;
+
+ IntPtr buffer = IntPtr.Zero;
+ try
+ {
+ buffer = AmxModx_Bridge_ReadFile(filePath, out int size);
+ if (buffer == IntPtr.Zero || size <= 0)
+ return null;
+
+ byte[] data = new byte[size];
+ Marshal.Copy(buffer, data, 0, size);
+ return Encoding.UTF8.GetString(data).TrimEnd('\0');
+ }
+ finally
+ {
+ if (buffer != IntPtr.Zero)
+ AmxModx_Bridge_FreeBuffer(buffer);
+ }
+ }
+
+ ///
+ /// 安全写入文件内容
+ ///
+ /// 文件路径
+ /// 要写入的内容
+ /// 写入是否成功
+ public static bool WriteFileSafe(string filePath, string content)
+ {
+ if (string.IsNullOrEmpty(filePath) || content == null)
+ return false;
+
+ byte[] data = Encoding.UTF8.GetBytes(content);
+ return AmxModx_Bridge_WriteFile(filePath, content, data.Length);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.GameConfigs.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.GameConfigs.cs
new file mode 100644
index 0000000..8043c04
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.GameConfigs.cs
@@ -0,0 +1,203 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace AmxModx.Bridge.GameConfigs
+{
+ ///
+ /// 游戏配置系统桥接接口
+ ///
+ public static class GameConfigBridge
+ {
+ private const string DllName = "amxmodx_mm";
+
+ ///
+ /// 加载游戏配置文件
+ ///
+ /// 配置文件名
+ /// 错误信息缓冲区
+ /// 缓冲区大小
+ /// 游戏配置句柄,失败返回0
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_LoadGameConfigFile(
+ [MarshalAs(UnmanagedType.LPStr)] string fileName,
+ [MarshalAs(UnmanagedType.LPStr)] StringBuilder errorBuffer,
+ int errorBufferSize);
+
+ ///
+ /// 获取游戏配置偏移量
+ ///
+ /// 游戏配置句柄
+ /// 配置键名
+ /// 偏移量值,失败返回-1
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GameConfGetOffset(
+ int handle,
+ [MarshalAs(UnmanagedType.LPStr)] string key);
+
+ ///
+ /// 获取类配置偏移量
+ ///
+ /// 游戏配置句柄
+ /// 类名
+ /// 配置键名
+ /// 偏移量值,失败返回-1
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GameConfGetClassOffset(
+ int handle,
+ [MarshalAs(UnmanagedType.LPStr)] string className,
+ [MarshalAs(UnmanagedType.LPStr)] string key);
+
+ ///
+ /// 获取游戏配置键值
+ ///
+ /// 游戏配置句柄
+ /// 配置键名
+ /// 输出缓冲区
+ /// 缓冲区大小
+ /// 是否成功获取
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GameConfGetKeyValue(
+ int handle,
+ [MarshalAs(UnmanagedType.LPStr)] string key,
+ [MarshalAs(UnmanagedType.LPStr)] StringBuilder buffer,
+ int bufferSize);
+
+ ///
+ /// 获取游戏配置地址
+ ///
+ /// 游戏配置句柄
+ /// 地址名
+ /// 地址值,失败返回0
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern UIntPtr AmxModx_Bridge_GameConfGetAddress(
+ int handle,
+ [MarshalAs(UnmanagedType.LPStr)] string name);
+
+ ///
+ /// 关闭游戏配置文件
+ ///
+ /// 游戏配置句柄
+ /// 是否成功关闭
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_CloseGameConfigFile(ref int handle);
+
+ ///
+ /// 游戏配置管理器包装类
+ ///
+ public class GameConfigManager : IDisposable
+ {
+ private int _handle = -1;
+ private bool _disposed = false;
+
+ ///
+ /// 加载游戏配置文件
+ ///
+ /// 配置文件名
+ /// 是否加载成功
+ public bool LoadConfig(string fileName)
+ {
+ if (_handle != -1)
+ CloseConfig();
+
+ StringBuilder errorBuffer = new StringBuilder(256);
+ _handle = AmxModx_Bridge_LoadGameConfigFile(fileName, errorBuffer, errorBuffer.Capacity);
+
+ if (_handle == 0)
+ {
+ throw new InvalidOperationException($"Failed to load game config: {errorBuffer}");
+ }
+
+ return true;
+ }
+
+ ///
+ /// 获取配置偏移量
+ ///
+ public int GetOffset(string key)
+ {
+ if (_handle == -1)
+ throw new InvalidOperationException("No config loaded");
+
+ return AmxModx_Bridge_GameConfGetOffset(_handle, key);
+ }
+
+ ///
+ /// 获取类配置偏移量
+ ///
+ public int GetClassOffset(string className, string key)
+ {
+ if (_handle == -1)
+ throw new InvalidOperationException("No config loaded");
+
+ return AmxModx_Bridge_GameConfGetClassOffset(_handle, className, key);
+ }
+
+ ///
+ /// 获取配置键值
+ ///
+ public string GetKeyValue(string key)
+ {
+ if (_handle == -1)
+ throw new InvalidOperationException("No config loaded");
+
+ StringBuilder buffer = new StringBuilder(256);
+ if (AmxModx_Bridge_GameConfGetKeyValue(_handle, key, buffer, buffer.Capacity) == 1)
+ {
+ return buffer.ToString();
+ }
+ return null;
+ }
+
+ ///
+ /// 获取配置地址
+ ///
+ public IntPtr GetAddress(string name)
+ {
+ if (_handle == -1)
+ throw new InvalidOperationException("No config loaded");
+
+ UIntPtr address = AmxModx_Bridge_GameConfGetAddress(_handle, name);
+ return address == UIntPtr.Zero ? IntPtr.Zero : (IntPtr)address;
+ }
+
+ ///
+ /// 关闭配置文件
+ ///
+ public void CloseConfig()
+ {
+ if (_handle != -1)
+ {
+ AmxModx_Bridge_CloseGameConfigFile(ref _handle);
+ _handle = -1;
+ }
+ }
+
+ ///
+ /// 释放资源
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ CloseConfig();
+ }
+ _disposed = true;
+ }
+ }
+
+ ~GameConfigManager()
+ {
+ Dispose(false);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.Vault.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.Vault.cs
new file mode 100644
index 0000000..16b2a6c
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Data/AmxModx.Bridge.Vault.cs
@@ -0,0 +1,110 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace AmxModx.Bridge.Vault
+{
+ ///
+ /// Vault持久化存储桥接接口,提供键值存储功能
+ ///
+ public static class VaultBridge
+ {
+ private const string NativeLibrary = "amxmodx_mm";
+
+ #region Vault操作
+
+ ///
+ /// 获取全局Vault实例
+ ///
+ /// Vault实例指针
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_GetVault();
+
+ ///
+ /// 检查键是否存在
+ ///
+ /// Vault实例指针
+ /// 键名
+ /// 键是否存在
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ public static extern bool AmxModx_Bridge_VaultExists(IntPtr vault, [MarshalAs(UnmanagedType.LPStr)] string key);
+
+ ///
+ /// 存储键值对
+ ///
+ /// Vault实例指针
+ /// 键名
+ /// 值
+ /// 存储是否成功
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ public static extern bool AmxModx_Bridge_VaultPut(IntPtr vault, [MarshalAs(UnmanagedType.LPStr)] string key, [MarshalAs(UnmanagedType.LPStr)] string value);
+
+ ///
+ /// 移除键值对
+ ///
+ /// Vault实例指针
+ /// 键名
+ /// 移除是否成功
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ public static extern bool AmxModx_Bridge_VaultRemove(IntPtr vault, [MarshalAs(UnmanagedType.LPStr)] string key);
+
+ ///
+ /// 获取键对应的值
+ ///
+ /// 键名
+ /// 值字符串
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_VaultGet([MarshalAs(UnmanagedType.LPStr)] string key);
+
+ #endregion
+
+ #region 便捷方法
+
+ ///
+ /// 获取Vault值的安全封装
+ ///
+ /// 键名
+ /// 值字符串
+ public static string GetVaultValueSafe(string key)
+ {
+ if (string.IsNullOrEmpty(key))
+ return string.Empty;
+
+ IntPtr ptr = AmxModx_Bridge_VaultGet(key);
+ return ptr != IntPtr.Zero ? Marshal.PtrToStringAnsi(ptr) : string.Empty;
+ }
+
+ ///
+ /// 存储键值对的安全封装
+ ///
+ /// 键名
+ /// 值
+ /// 存储是否成功
+ public static bool SetVaultValueSafe(string key, string value)
+ {
+ if (string.IsNullOrEmpty(key) || value == null)
+ return false;
+
+ IntPtr vault = AmxModx_Bridge_GetVault();
+ return vault != IntPtr.Zero && AmxModx_Bridge_VaultPut(vault, key, value);
+ }
+
+ ///
+ /// 检查键是否存在
+ ///
+ /// 键名
+ /// 键是否存在
+ public static bool ExistsVaultKey(string key)
+ {
+ if (string.IsNullOrEmpty(key))
+ return false;
+
+ IntPtr vault = AmxModx_Bridge_GetVault();
+ return vault != IntPtr.Zero && AmxModx_Bridge_VaultExists(vault, key);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Engine/AmxModx.Bridge.Engine.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Engine/AmxModx.Bridge.Engine.cs
new file mode 100644
index 0000000..0ba2675
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Engine/AmxModx.Bridge.Engine.cs
@@ -0,0 +1,456 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace AmxModx.Bridge.Engine
+{
+ ///
+ /// Engine模块的C#桥接接口
+ /// 提供对AMX Mod X引擎功能的访问
+ ///
+ public static class EngineBridge
+ {
+ private const string EngineBridgeDll = "engine_amxx";
+
+ #region 基本类型定义
+
+ ///
+ /// 3D向量结构
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Vector3
+ {
+ public float X;
+ public float Y;
+ public float Z;
+
+ public Vector3(float x, float y, float z)
+ {
+ X = x;
+ Y = y;
+ Z = z;
+ }
+
+ public override string ToString() => $"({X}, {Y}, {Z})";
+
+ public static implicit operator Vector3(float[] array)
+ {
+ if (array == null || array.Length < 3)
+ return new Vector3(0, 0, 0);
+ return new Vector3(array[0], array[1], array[2]);
+ }
+
+ public static implicit operator float[](Vector3 vec)
+ {
+ return new float[] { vec.X, vec.Y, vec.Z };
+ }
+ }
+
+ ///
+ /// 追踪结果信息
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ public struct TraceResultInfo
+ {
+ public int AllSolid;
+ public int StartSolid;
+ public int InOpen;
+ public int InWater;
+ public float Fraction;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
+ public float[] EndPos;
+ public float PlaneDist;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
+ public float[] PlaneNormal;
+ public int HitEntity;
+ public int HitGroup;
+
+ public TraceResultInfo()
+ {
+ EndPos = new float[3];
+ PlaneNormal = new float[3];
+ }
+ }
+
+ ///
+ /// 用户命令信息
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ public struct UserCmdInfo
+ {
+ public float ForwardMove;
+ public float SideMove;
+ public float UpMove;
+ public float LerpMsec;
+ public float Msec;
+ public float LightLevel;
+ public int Buttons;
+ public int WeaponSelect;
+ public int ImpactIndex;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
+ public float[] ViewAngles;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
+ public float[] ImpactPosition;
+
+ public UserCmdInfo()
+ {
+ ViewAngles = new float[3];
+ ImpactPosition = new float[3];
+ }
+ }
+
+ #endregion
+
+ #region 委托定义
+
+ ///
+ /// 脉冲处理委托
+ ///
+ /// 客户端索引
+ /// 脉冲值
+ public delegate void ImpulseCallback(int client, int impulse);
+
+ ///
+ /// 触碰处理委托
+ ///
+ /// 被触碰实体
+ /// 触碰实体
+ public delegate void TouchCallback(int touched, int toucher);
+
+ ///
+ /// 思考处理委托
+ ///
+ /// 实体索引
+ public delegate void ThinkCallback(int entity);
+
+ #endregion
+
+ #region 时间相关
+
+ ///
+ /// 获取游戏时间
+ ///
+ /// 当前游戏时间(秒)
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern float Engine_GetGameTime();
+
+ #endregion
+
+ #region 实体操作
+
+ ///
+ /// 创建实体
+ ///
+ /// 实体类名
+ /// 实体ID,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_CreateEntity(string className);
+
+ ///
+ /// 删除实体
+ ///
+ /// 实体ID
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_RemoveEntity(int entityId);
+
+ ///
+ /// 检查实体是否有效
+ ///
+ /// 实体ID
+ /// 有效返回1,无效返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_IsValidEntity(int entityId);
+
+ ///
+ /// 获取当前实体数量
+ ///
+ /// 实体数量
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_GetEntityCount();
+
+ ///
+ /// 计算两个实体间的距离
+ ///
+ /// 实体A
+ /// 实体B
+ /// 距离值
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern float Engine_GetEntityDistance(int entityA, int entityB);
+
+ #endregion
+
+ #region 追踪系统
+
+ ///
+ /// 线条追踪
+ ///
+ /// 起始点
+ /// 结束点
+ /// 忽略的实体ID(0表示不忽略)
+ /// 追踪结果
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_TraceLine(Vector3 start, Vector3 end, int ignoreEntity, out TraceResultInfo result);
+
+ ///
+ /// 包围盒追踪
+ ///
+ /// 起始点
+ /// 结束点
+ /// 包围盒类型
+ /// 忽略的实体ID
+ /// 追踪结果
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_TraceHull(Vector3 start, Vector3 end, int hullType, int ignoreEntity, out TraceResultInfo result);
+
+ ///
+ /// 法线追踪
+ ///
+ /// 实体ID
+ /// 起始点
+ /// 结束点
+ /// 返回的法线向量
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_TraceNormal(int entity, Vector3 start, Vector3 end, out Vector3 normal);
+
+ ///
+ /// 前向追踪
+ ///
+ /// 起始点
+ /// 角度
+ /// 追踪距离
+ /// 忽略的实体ID
+ /// 追踪结果
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_TraceForward(Vector3 start, Vector3 angles, float give, int ignoreEntity, out TraceResultInfo result);
+
+ #endregion
+
+ #region 游戏事件
+
+ ///
+ /// 播放游戏事件
+ ///
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_PlaybackEvent(int flags, int invoker, ushort eventIndex, float delay,
+ Vector3 origin, Vector3 angles, float fparam1, float fparam2,
+ int iparam1, int iparam2, int bparam1, int bparam2);
+
+ #endregion
+
+ #region 范围伤害
+
+ ///
+ /// 范围伤害
+ ///
+ /// 伤害中心点
+ /// 伤害倍数
+ /// 半径倍数
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_RadiusDamage(Vector3 origin, int damageMultiplier, int radiusMultiplier);
+
+ #endregion
+
+ #region 点内容检查
+
+ ///
+ /// 检查点的内容类型
+ ///
+ /// 检查点
+ /// 内容类型值
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_PointContents(Vector3 point);
+
+ #endregion
+
+ #region 字符串和索引
+
+ ///
+ /// 获取贴花索引
+ ///
+ /// 贴花名称
+ /// 索引值,失败返回-1
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_GetDecalIndex(string decalName);
+
+ ///
+ /// 获取信息键缓冲区
+ ///
+ /// 实体ID(-1表示全局)
+ /// 接收缓冲区
+ /// 缓冲区大小
+ /// 实际字符串长度
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_GetInfoKeyBuffer(int entity, byte[] buffer, int bufferSize);
+
+ ///
+ /// 获取引擎字符串
+ ///
+ /// 字符串ID
+ /// 接收缓冲区
+ /// 缓冲区大小
+ /// 实际字符串长度
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_GetEngineString(int stringId, byte[] buffer, int bufferSize);
+
+ #endregion
+
+ #region 用户命令
+
+ ///
+ /// 获取用户命令
+ ///
+ /// 客户端索引
+ /// 命令类型
+ /// 命令结构
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_GetUserCmd(int client, int type, out UserCmdInfo cmd);
+
+ ///
+ /// 设置用户命令
+ ///
+ /// 客户端索引
+ /// 命令类型
+ /// 命令结构
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_SetUserCmd(int client, int type, ref UserCmdInfo cmd);
+
+ #endregion
+
+ #region 说话权限
+
+ ///
+ /// 设置说话权限
+ ///
+ /// 客户端索引
+ /// 说话标志
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_SetSpeak(int client, int speakFlags);
+
+ ///
+ /// 获取说话权限
+ ///
+ /// 客户端索引
+ /// 说话标志
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_GetSpeak(int client);
+
+ #endregion
+
+ #region 视角控制
+
+ ///
+ /// 设置玩家视角
+ ///
+ /// 客户端索引
+ /// 视角实体ID
+ /// 视角类型
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_SetView(int client, int viewEntity, int viewType);
+
+ ///
+ /// 附加视角到目标实体
+ ///
+ /// 客户端索引
+ /// 目标实体ID
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_AttachView(int client, int targetEntity);
+
+ #endregion
+
+ #region 光照
+
+ ///
+ /// 设置光照
+ ///
+ /// 光照字符串
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_SetLights(string lights);
+
+ #endregion
+
+ #region 地面放置
+
+ ///
+ /// 将实体放置到地面
+ ///
+ /// 实体ID
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_DropToFloor(int entity);
+
+ #endregion
+
+ #region 可见性检查
+
+ ///
+ /// 检查实体间是否可见
+ ///
+ /// 源实体
+ /// 目标实体
+ /// 可见返回1,不可见返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_IsVisible(int srcEntity, int destEntity);
+
+ ///
+ /// 检查点是否在视角锥内
+ ///
+ /// 实体
+ /// 目标点
+ /// 在锥内返回1,不在返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_IsInViewCone(int entity, Vector3 target);
+
+ #endregion
+
+ #region 事件注册
+
+ ///
+ /// 注册脉冲处理
+ ///
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_RegisterImpulse(int impulse, ImpulseCallback callback);
+
+ ///
+ /// 注册触碰处理
+ ///
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_RegisterTouch(string touchedClass, string toucherClass, TouchCallback callback);
+
+ ///
+ /// 注册思考处理
+ ///
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_RegisterThink(string className, ThinkCallback callback);
+
+ ///
+ /// 注销脉冲处理
+ ///
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_UnregisterImpulse(int registerId);
+
+ ///
+ /// 注销触碰处理
+ ///
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_UnregisterTouch(int registerId);
+
+ ///
+ /// 注销思考处理
+ ///
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_UnregisterThink(int registerId);
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Engine/AmxModx.Bridge.Entity.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Engine/AmxModx.Bridge.Entity.cs
new file mode 100644
index 0000000..af8c41a
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Engine/AmxModx.Bridge.Entity.cs
@@ -0,0 +1,407 @@
+// vim: set ts=4 sw=4 tw=99 noet:
+//
+// AMX Mod X Entity Bridge for C#
+// Copyright (C) The AMX Mod X Development Team.
+//
+// This software is licensed under the GNU General Public License, version 3 or higher.
+// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
+// https://alliedmods.net/amxmodx-license
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace AmxModx.Bridge.Entity
+{
+ ///
+ /// 实体管理桥接接口,提供对游戏实体和玩家的访问
+ ///
+ public static class EntityBridge
+ {
+ private const string DllName = "amxmodx_mm";
+
+ #region 实体管理接口
+
+ ///
+ /// 获取服务器最大客户端数量
+ ///
+ /// 最大客户端数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetMaxClients();
+
+ ///
+ /// 获取服务器最大实体数量
+ ///
+ /// 最大实体数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetMaxEntities();
+
+ ///
+ /// 获取当前在线玩家数量
+ ///
+ /// 在线玩家数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetPlayerCount();
+
+ ///
+ /// 检查玩家ID是否有效
+ ///
+ /// 玩家ID
+ /// 是否有效
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_IsPlayerValid(int playerId);
+
+ ///
+ /// 检查玩家是否在游戏中
+ ///
+ /// 玩家ID
+ /// 是否在游戏中
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_IsPlayerInGame(int playerId);
+
+ ///
+ /// 检查玩家是否存活
+ ///
+ /// 玩家ID
+ /// 是否存活
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_IsPlayerAlive(int playerId);
+
+ ///
+ /// 检查玩家是否为机器人
+ ///
+ /// 玩家ID
+ /// 是否为机器人
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_IsPlayerBot(int playerId);
+
+ #endregion
+
+ #region 实体属性访问
+
+ ///
+ /// 获取玩家名称
+ ///
+ /// 玩家ID
+ /// 玩家名称
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.LPStr)]
+ public static extern string AmxModx_Bridge_GetPlayerName(int playerId);
+
+ ///
+ /// 获取玩家IP地址
+ ///
+ /// 玩家ID
+ /// IP地址
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.LPStr)]
+ public static extern string AmxModx_Bridge_GetPlayerIPAddress(int playerId);
+
+ ///
+ /// 获取玩家Steam Auth ID
+ ///
+ /// 玩家ID
+ /// Steam Auth ID
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.LPStr)]
+ public static extern string AmxModx_Bridge_GetPlayerAuthID(int playerId);
+
+ ///
+ /// 获取玩家队伍
+ ///
+ /// 玩家ID
+ /// 队伍名称
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.LPStr)]
+ public static extern string AmxModx_Bridge_GetPlayerTeam(int playerId);
+
+ ///
+ /// 获取玩家UserID
+ ///
+ /// 玩家ID
+ /// UserID
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetPlayerUserID(int playerId);
+
+ ///
+ /// 获取玩家击杀数
+ ///
+ /// 玩家ID
+ /// 击杀数
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetPlayerFrags(int playerId);
+
+ ///
+ /// 获取玩家死亡数
+ ///
+ /// 玩家ID
+ /// 死亡数
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetPlayerDeaths(int playerId);
+
+ ///
+ /// 获取玩家生命值
+ ///
+ /// 玩家ID
+ /// 生命值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetPlayerHealth(int playerId);
+
+ ///
+ /// 获取玩家护甲值
+ ///
+ /// 玩家ID
+ /// 护甲值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetPlayerArmor(int playerId);
+
+ ///
+ /// 获取玩家延迟
+ ///
+ /// 玩家ID
+ /// 延迟值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetPlayerPing(int playerId);
+
+ #endregion
+
+ #region 实体位置相关
+
+ ///
+ /// 获取玩家位置
+ ///
+ /// 玩家ID
+ /// X坐标
+ /// Y坐标
+ /// Z坐标
+ /// 是否成功获取
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_GetPlayerOrigin(int playerId, out float x, out float y, out float z);
+
+ ///
+ /// 获取玩家速度
+ ///
+ /// 玩家ID
+ /// X速度
+ /// Y速度
+ /// Z速度
+ /// 是否成功获取
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_GetPlayerVelocity(int playerId, out float x, out float y, out float z);
+
+ ///
+ /// 设置玩家位置
+ ///
+ /// 玩家ID
+ /// X坐标
+ /// Y坐标
+ /// Z坐标
+ /// 是否成功设置
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_SetPlayerOrigin(int playerId, float x, float y, float z);
+
+ ///
+ /// 设置玩家速度
+ ///
+ /// 玩家ID
+ /// X速度
+ /// Y速度
+ /// Z速度
+ /// 是否成功设置
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_SetPlayerVelocity(int playerId, float x, float y, float z);
+
+ #endregion
+
+ #region 实体武器相关
+
+ ///
+ /// 获取玩家当前武器
+ ///
+ /// 玩家ID
+ /// 武器ID
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetPlayerCurrentWeapon(int playerId);
+
+ ///
+ /// 获取玩家弹药数量
+ ///
+ /// 玩家ID
+ /// 武器ID
+ /// 弹药数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetPlayerAmmo(int playerId, int weaponId);
+
+ ///
+ /// 检查玩家是否拥有武器
+ ///
+ /// 玩家ID
+ /// 武器ID
+ /// 是否拥有武器
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_PlayerHasWeapon(int playerId, int weaponId);
+
+ #endregion
+
+ #region 实体操作
+
+ ///
+ /// 击杀玩家
+ ///
+ /// 玩家ID
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_KillPlayer(int playerId);
+
+ ///
+ /// 拍打玩家
+ ///
+ /// 玩家ID
+ /// 伤害值
+ /// 是否随机速度
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_SlapPlayer(int playerId, int damage, [MarshalAs(UnmanagedType.Bool)] bool randomVelocity);
+
+ ///
+ /// 传送玩家
+ ///
+ /// 玩家ID
+ /// X坐标
+ /// Y坐标
+ /// Z坐标
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_TeleportPlayer(int playerId, float x, float y, float z);
+
+ ///
+ /// 重新生成玩家
+ ///
+ /// 玩家ID
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_RespawnPlayer(int playerId);
+
+ ///
+ /// 移除玩家所有武器
+ ///
+ /// 玩家ID
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_StripWeapons(int playerId);
+
+ ///
+ /// 给予玩家武器
+ ///
+ /// 玩家ID
+ /// 武器名称
+ /// 弹药数量
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_GiveWeapon(int playerId, [MarshalAs(UnmanagedType.LPStr)] string weaponName, int ammo);
+
+ ///
+ /// 设置玩家队伍
+ ///
+ /// 玩家ID
+ /// 队伍ID
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_SetPlayerTeam(int playerId, int teamId);
+
+ ///
+ /// 冻结/解冻玩家
+ ///
+ /// 玩家ID
+ /// 是否冻结
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_FreezePlayer(int playerId, [MarshalAs(UnmanagedType.Bool)] bool freeze);
+
+ ///
+ /// 设置玩家生命值
+ ///
+ /// 玩家ID
+ /// 生命值
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_SetPlayerHealth(int playerId, int health);
+
+ ///
+ /// 设置玩家护甲值
+ ///
+ /// 玩家ID
+ /// 护甲值
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_SetPlayerArmor(int playerId, int armor);
+
+ ///
+ /// 设置玩家击杀数
+ ///
+ /// 玩家ID
+ /// 击杀数
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_SetPlayerFrags(int playerId, int frags);
+
+ ///
+ /// 设置玩家死亡数
+ ///
+ /// 玩家ID
+ /// 死亡数
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_SetPlayerDeaths(int playerId, int deaths);
+
+ #endregion
+
+ #region 实体查找
+
+ ///
+ /// 通过UserID查找玩家
+ ///
+ /// UserID
+ /// 玩家ID
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_FindPlayerByUserID(int userId);
+
+ ///
+ /// 通过名称查找玩家
+ ///
+ /// 玩家名称
+ /// 玩家ID
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_FindPlayerByName([MarshalAs(UnmanagedType.LPStr)] string name);
+
+ ///
+ /// 通过IP地址查找玩家
+ ///
+ /// IP地址
+ /// 玩家ID
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_FindPlayerByIPAddress([MarshalAs(UnmanagedType.LPStr)] string ip);
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Engine/AmxModx.Bridge.Vector.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Engine/AmxModx.Bridge.Vector.cs
new file mode 100644
index 0000000..7d6ca18
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Engine/AmxModx.Bridge.Vector.cs
@@ -0,0 +1,173 @@
+// vim: set ts=4 sw=4 tw=99 noet:
+//
+// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
+// Copyright (C) The AMX Mod X Development Team.
+//
+// This software is licensed under the GNU General Public License, version 3 or higher.
+// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
+// https://alliedmods.net/amxmodx-license
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace AmxModx.Bridge
+{
+ ///
+ /// 向量运算桥接接口
+ ///
+ public static class Vector
+ {
+ private const string DllName = "amxmodx_mm";
+ ///
+ /// 将3D向量转换为角度
+ ///
+ /// 向量的X分量
+ /// 向量的Y分量
+ /// 向量的Z分量
+ /// 输出的X角度
+ /// 输出的Y角度
+ /// 输出的Z角度
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_VectorToAngle(float x, float y, float z, out float outX, out float outY, out float outZ);
+
+ ///
+ /// 将角度转换为3D向量
+ ///
+ /// 俯仰角
+ /// 偏航角
+ /// 翻滚角
+ /// 向量类型:1=前向,2=右向,3=上向
+ /// 输出的X分量
+ /// 输出的Y分量
+ /// 输出的Z分量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_AngleVector(float pitch, float yaw, float roll, int type, out float outX, out float outY, out float outZ);
+
+ ///
+ /// 计算3D向量的长度
+ ///
+ /// 向量的X分量
+ /// 向量的Y分量
+ /// 向量的Z分量
+ /// 向量的长度
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern float AmxModx_Bridge_VectorLength(float x, float y, float z);
+
+ ///
+ /// 计算两个3D向量之间的距离
+ ///
+ /// 第一个向量的X分量
+ /// 第一个向量的Y分量
+ /// 第一个向量的Z分量
+ /// 第二个向量的X分量
+ /// 第二个向量的Y分量
+ /// 第二个向量的Z分量
+ /// 两个向量之间的距离
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern float AmxModx_Bridge_VectorDistance(float x1, float y1, float z1, float x2, float y2, float z2);
+
+ ///
+ /// 通过实体的瞄准方向获取速度向量
+ ///
+ /// 实体索引
+ /// 速度大小
+ /// 输出的X分量
+ /// 输出的Y分量
+ /// 输出的Z分量
+ /// 操作是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_VelocityByAim(int entity, int velocity, out float outX, out float outY, out float outZ);
+ }
+
+ ///
+ /// 向量类型枚举
+ ///
+ public enum AngleVectorType
+ {
+ ///
+ /// 前向向量
+ ///
+ Forward = 1,
+
+ ///
+ /// 右向向量
+ ///
+ Right = 2,
+
+ ///
+ /// 上向向量
+ ///
+ Up = 3
+ }
+
+ ///
+ /// 3D向量结构
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Vector3
+ {
+ public float X;
+ public float Y;
+ public float Z;
+
+ public Vector3(float x, float y, float z)
+ {
+ X = x;
+ Y = y;
+ Z = z;
+ }
+
+ ///
+ /// 计算向量长度
+ ///
+ public float Length()
+ {
+ return Vector.AmxModx_Bridge_VectorLength(X, Y, Z);
+ }
+
+ ///
+ /// 计算与另一个向量的距离
+ ///
+ public float DistanceTo(Vector3 other)
+ {
+ return Vector.AmxModx_Bridge_VectorDistance(X, Y, Z, other.X, other.Y, other.Z);
+ }
+
+ ///
+ /// 转换为角度
+ ///
+ public Vector3 ToAngles()
+ {
+ Vector.AmxModx_Bridge_VectorToAngle(X, Y, Z, out float x, out float y, out float z);
+ return new Vector3(x, y, z);
+ }
+ }
+
+ ///
+ /// 3D角度结构
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Angle3
+ {
+ public float Pitch;
+ public float Yaw;
+ public float Roll;
+
+ public Angle3(float pitch, float yaw, float roll)
+ {
+ Pitch = pitch;
+ Yaw = yaw;
+ Roll = roll;
+ }
+
+ ///
+ /// 转换为向量
+ ///
+ public Vector3 ToVector(AngleVectorType type)
+ {
+ Vector.AmxModx_Bridge_AngleVector(Pitch, Yaw, Roll, (int)type, out float x, out float y, out float z);
+ return new Vector3(x, y, z);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Engine/EngineBridgeExtensions.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Engine/EngineBridgeExtensions.cs
new file mode 100644
index 0000000..024fae4
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Engine/EngineBridgeExtensions.cs
@@ -0,0 +1,375 @@
+using System;
+using System.Runtime.InteropServices;
+using AmxModx.Bridge.Engine;
+using System.Text;
+
+namespace AmxModx.Bridge.Engine
+{
+ ///
+ /// EngineBridge扩展类,提供额外的实体操作方法
+ ///
+ public static class EngineBridgeExtensions
+ {
+ private const string EngineBridgeDll = "engine_amxx";
+
+ #region 实体位置相关
+
+ ///
+ /// 获取实体位置
+ ///
+ /// 实体ID
+ /// 返回的位置
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_GetEntityOrigin(int entityId, [Out] float[] origin);
+
+ ///
+ /// 设置实体位置
+ ///
+ /// 实体ID
+ /// 新位置
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_SetEntityOrigin(int entityId, [In] float[] origin);
+
+ ///
+ /// 获取实体角度
+ ///
+ /// 实体ID
+ /// 返回的角度
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_GetEntityAngles(int entityId, [Out] float[] angles);
+
+ ///
+ /// 设置实体角度
+ ///
+ /// 实体ID
+ /// 新角度
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_SetEntityAngles(int entityId, [In] float[] angles);
+
+ ///
+ /// 获取实体速度
+ ///
+ /// 实体ID
+ /// 返回的速度
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_GetEntityVelocity(int entityId, [Out] float[] velocity);
+
+ ///
+ /// 设置实体速度
+ ///
+ /// 实体ID
+ /// 新速度
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_SetEntityVelocity(int entityId, [In] float[] velocity);
+
+ #endregion
+
+ #region 实体属性相关
+
+ ///
+ /// 获取实体类名
+ ///
+ /// 实体ID
+ /// 缓冲区
+ /// 缓冲区大小
+ /// 实际返回的字符串长度
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_GetEntityClassName(int entityId, [Out] byte[] buffer, int bufferSize);
+
+ ///
+ /// 获取实体模型名
+ ///
+ /// 实体ID
+ /// 缓冲区
+ /// 缓冲区大小
+ /// 实际返回的字符串长度
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_GetEntityModelName(int entityId, [Out] byte[] buffer, int bufferSize);
+
+ ///
+ /// 获取实体健康值
+ ///
+ /// 实体ID
+ /// 健康值
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_GetEntityHealth(int entityId);
+
+ ///
+ /// 设置实体健康值
+ ///
+ /// 实体ID
+ /// 健康值
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_SetEntityHealth(int entityId, int health);
+
+ ///
+ /// 获取实体护甲值
+ ///
+ /// 实体ID
+ /// 护甲值
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_GetEntityArmor(int entityId);
+
+ ///
+ /// 设置实体护甲值
+ ///
+ /// 实体ID
+ /// 护甲值
+ /// 成功返回1,失败返回0
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_SetEntityArmor(int entityId, int armor);
+
+ #endregion
+
+ #region 实体列表相关
+
+ ///
+ /// 获取所有实体
+ ///
+ /// 最大实体数量
+ /// 返回的实体ID数组
+ /// 实际获取的实体数量
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_GetAllEntities([Out] int[] entityIds, int maxCount);
+
+ ///
+ /// 按类名查找实体
+ ///
+ /// 类名
+ /// 最大返回数量
+ /// 返回的实体ID数组
+ /// 实际找到的实体数量
+ [DllImport(EngineBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_FindEntitiesByClass(string className, [Out] int[] entityIds, int maxCount);
+
+ #endregion
+
+ #region 便捷包装方法
+
+ ///
+ /// 获取实体位置(便捷包装)
+ ///
+ /// 实体ID
+ /// 返回的位置
+ /// 成功返回true,失败返回false
+ public static bool GetEntityOrigin(int entityId, out EngineBridge.Vector3 origin)
+ {
+ float[] originArray = new float[3];
+ bool result = Engine_GetEntityOrigin(entityId, originArray) != 0;
+ if (result)
+ {
+ origin = new EngineBridge.Vector3(originArray[0], originArray[1], originArray[2]);
+ }
+ else
+ {
+ origin = new EngineBridge.Vector3(0, 0, 0);
+ }
+ return result;
+ }
+
+ ///
+ /// 设置实体位置(便捷包装)
+ ///
+ /// 实体ID
+ /// 新位置
+ /// 成功返回true,失败返回false
+ public static bool SetEntityOrigin(int entityId, EngineBridge.Vector3 origin)
+ {
+ float[] originArray = { origin.X, origin.Y, origin.Z };
+ return Engine_SetEntityOrigin(entityId, originArray) != 0;
+ }
+
+ ///
+ /// 获取实体角度(便捷包装)
+ ///
+ /// 实体ID
+ /// 返回的角度
+ /// 成功返回true,失败返回false
+ public static bool GetEntityAngles(int entityId, out EngineBridge.Vector3 angles)
+ {
+ float[] anglesArray = new float[3];
+ bool result = Engine_GetEntityAngles(entityId, anglesArray) != 0;
+ if (result)
+ {
+ angles = new EngineBridge.Vector3(anglesArray[0], anglesArray[1], anglesArray[2]);
+ }
+ else
+ {
+ angles = new EngineBridge.Vector3(0, 0, 0);
+ }
+ return result;
+ }
+
+ ///
+ /// 设置实体角度(便捷包装)
+ ///
+ /// 实体ID
+ /// 新角度
+ /// 成功返回true,失败返回false
+ public static bool SetEntityAngles(int entityId, EngineBridge.Vector3 angles)
+ {
+ float[] anglesArray = { angles.X, angles.Y, angles.Z };
+ return Engine_SetEntityAngles(entityId, anglesArray) != 0;
+ }
+
+ ///
+ /// 获取实体速度(便捷包装)
+ ///
+ /// 实体ID
+ /// 返回的速度
+ /// 成功返回true,失败返回false
+ public static bool GetEntityVelocity(int entityId, out EngineBridge.Vector3 velocity)
+ {
+ float[] velocityArray = new float[3];
+ bool result = Engine_GetEntityVelocity(entityId, velocityArray) != 0;
+ if (result)
+ {
+ velocity = new EngineBridge.Vector3(velocityArray[0], velocityArray[1], velocityArray[2]);
+ }
+ else
+ {
+ velocity = new EngineBridge.Vector3(0, 0, 0);
+ }
+ return result;
+ }
+
+ ///
+ /// 设置实体速度(便捷包装)
+ ///
+ /// 实体ID
+ /// 新速度
+ /// 成功返回true,失败返回false
+ public static bool SetEntityVelocity(int entityId, EngineBridge.Vector3 velocity)
+ {
+ float[] velocityArray = { velocity.X, velocity.Y, velocity.Z };
+ return Engine_SetEntityVelocity(entityId, velocityArray) != 0;
+ }
+
+ ///
+ /// 获取实体类名(便捷包装)
+ ///
+ /// 实体ID
+ /// 实体类名
+ public static string GetEntityClassName(int entityId)
+ {
+ const int bufferSize = 256;
+ byte[] buffer = new byte[bufferSize];
+ int length = Engine_GetEntityClassName(entityId, buffer, bufferSize);
+ if (length <= 0) return string.Empty;
+
+ return Encoding.UTF8.GetString(buffer, 0, length);
+ }
+
+ ///
+ /// 获取实体模型名(便捷包装)
+ ///
+ /// 实体ID
+ /// 实体模型名
+ public static string GetEntityModelName(int entityId)
+ {
+ const int bufferSize = 256;
+ byte[] buffer = new byte[bufferSize];
+ int length = Engine_GetEntityModelName(entityId, buffer, bufferSize);
+ if (length <= 0) return string.Empty;
+
+ return Encoding.UTF8.GetString(buffer, 0, length);
+ }
+
+ ///
+ /// 获取实体健康值(便捷包装)
+ ///
+ /// 实体ID
+ /// 健康值
+ public static int GetEntityHealth(int entityId)
+ {
+ return Engine_GetEntityHealth(entityId);
+ }
+
+ ///
+ /// 设置实体健康值(便捷包装)
+ ///
+ /// 实体ID
+ /// 健康值
+ /// 成功返回true,失败返回false
+ public static bool SetEntityHealth(int entityId, int health)
+ {
+ return Engine_SetEntityHealth(entityId, health) != 0;
+ }
+
+ ///
+ /// 获取实体护甲值(便捷包装)
+ ///
+ /// 实体ID
+ /// 护甲值
+ public static int GetEntityArmor(int entityId)
+ {
+ return Engine_GetEntityArmor(entityId);
+ }
+
+ ///
+ /// 设置实体护甲值(便捷包装)
+ ///
+ /// 实体ID
+ /// 护甲值
+ /// 成功返回true,失败返回false
+ public static bool SetEntityArmor(int entityId, int armor)
+ {
+ return Engine_SetEntityArmor(entityId, armor) != 0;
+ }
+
+ ///
+ /// 获取所有实体(便捷包装)
+ ///
+ /// 最大实体数量
+ /// 实体ID数组
+ public static int[] GetAllEntities(int maxCount)
+ {
+ if (maxCount <= 0)
+ return new int[0];
+
+ int[] entityIds = new int[maxCount];
+ int actualCount = Engine_GetAllEntities(entityIds, maxCount);
+
+ if (actualCount <= 0)
+ return new int[0];
+
+ // 调整数组大小到实际数量
+ int[] result = new int[actualCount];
+ Array.Copy(entityIds, result, actualCount);
+ return result;
+ }
+
+ ///
+ /// 按类名查找实体(便捷包装)
+ ///
+ /// 类名
+ /// 实体ID数组
+ public static int[] FindEntitiesByClass(string className)
+ {
+ if (string.IsNullOrEmpty(className))
+ return new int[0];
+
+ // 假设最大返回1000个实体
+ const int maxCount = 1000;
+ int[] entityIds = new int[maxCount];
+ int actualCount = Engine_FindEntitiesByClass(className, entityIds, maxCount);
+
+ if (actualCount <= 0)
+ return new int[0];
+
+ // 调整数组大小到实际数量
+ int[] result = new int[actualCount];
+ Array.Copy(entityIds, result, actualCount);
+ return result;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Engine/EngineEffectsBridge.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Engine/EngineEffectsBridge.cs
new file mode 100644
index 0000000..bc1b6be
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Engine/EngineEffectsBridge.cs
@@ -0,0 +1,241 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace AmxModx.Bridge.Engine
+{
+ ///
+ /// 引擎高级特效桥接接口
+ /// 提供音效、光照、粒子系统的高级控制功能
+ ///
+ public static class EngineEffectsBridge
+ {
+ private const string EngineEffectsDll = "engine_effects_bridge";
+
+ #region 音效系统
+
+ ///
+ /// 将音效附加到实体播放
+ ///
+ /// 目标实体ID
+ /// 音效文件路径
+ /// 音效通道
+ /// 音量 (0.0-1.0)
+ /// 衰减系数
+ /// 音调
+ /// 音效标志
+ /// 成功返回true,失败返回false
+ [DllImport(EngineEffectsDll, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I4)]
+ public static extern int Engine_SoundPlayAttached(
+ int entity,
+ [MarshalAs(UnmanagedType.LPStr)] string sample,
+ int channel,
+ float volume,
+ float attenuation,
+ int pitch,
+ int flags);
+
+ ///
+ /// 设置实体音效音调
+ ///
+ /// 目标实体ID
+ /// 音效通道
+ /// 新的音调值
+ /// 成功返回true,失败返回false
+ [DllImport(EngineEffectsDll, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I4)]
+ public static extern int Engine_SoundSetPitch(
+ int entity,
+ int channel,
+ int pitch);
+
+ #endregion
+
+ #region 光照系统
+
+ ///
+ /// 创建动态光源
+ ///
+ /// 光源位置数组 [x, y, z]
+ /// 光源半径
+ /// 红色分量 (0-255)
+ /// 绿色分量 (0-255)
+ /// 蓝色分量 (0-255)
+ /// 光源持续时间 (秒)
+ /// 光源样式 (0=常亮, 1=闪烁等)
+ /// 光源效果ID,失败返回0
+ [DllImport(EngineEffectsDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_LightCreate(
+ [MarshalAs(UnmanagedType.LPArray, SizeConst = 3)] float[] origin,
+ float radius,
+ byte red,
+ byte green,
+ byte blue,
+ float life,
+ int style);
+
+ ///
+ /// 设置光源颜色
+ ///
+ /// 光源效果ID
+ /// 红色分量
+ /// 绿色分量
+ /// 蓝色分量
+ /// 成功返回true,失败返回false
+ [DllImport(EngineEffectsDll, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I4)]
+ public static extern int Engine_LightSetColor(
+ int lightId,
+ int red,
+ int green,
+ int blue);
+
+ ///
+ /// 创建闪烁光源效果
+ ///
+ /// 光源效果ID
+ /// 闪烁速度
+ /// 最小亮度
+ /// 成功返回true,失败返回false
+ [DllImport(EngineEffectsDll, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I4)]
+ public static extern int Engine_LightFlicker(
+ int lightId,
+ float flickerSpeed,
+ float minIntensity);
+
+ ///
+ /// 创建脉冲光源效果
+ ///
+ /// 光源效果ID
+ /// 脉冲速度
+ /// 最小亮度
+ /// 最大亮度
+ /// 成功返回true,失败返回false
+ [DllImport(EngineEffectsDll, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I4)]
+ public static extern int Engine_LightPulse(
+ int lightId,
+ float pulseSpeed,
+ float minIntensity,
+ float maxIntensity);
+
+ ///
+ /// 停止光源效果
+ ///
+ /// 光源效果ID
+ /// 成功返回true,失败返回false
+ [DllImport(EngineEffectsDll, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I4)]
+ public static extern int Engine_LightStop(int lightId);
+
+ #endregion
+
+ #region 粒子系统
+
+ ///
+ /// 创建粒子系统
+ ///
+ /// 粒子起始位置数组 [x, y, z]
+ /// 精灵文件路径
+ /// 最大粒子数量
+ /// 粒子效果ID,失败返回0
+ [DllImport(EngineEffectsDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_ParticleCreate(
+ [MarshalAs(UnmanagedType.LPArray, SizeConst = 3)] float[] origin,
+ [MarshalAs(UnmanagedType.LPStr)] string sprite,
+ int maxParticles);
+
+ ///
+ /// 设置粒子颜色
+ ///
+ /// 粒子效果ID
+ /// 红色分量
+ /// 绿色分量
+ /// 蓝色分量
+ /// 成功返回true,失败返回false
+ [DllImport(EngineEffectsDll, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I4)]
+ public static extern int Engine_ParticleSetColor(
+ int particleId,
+ int red,
+ int green,
+ int blue);
+
+ ///
+ /// 设置粒子规模
+ ///
+ /// 粒子效果ID
+ /// 粒子规模
+ /// 成功返回true,失败返回false
+ [DllImport(EngineEffectsDll, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I4)]
+ public static extern int Engine_ParticleSetScale(
+ int particleId,
+ float scale);
+
+ ///
+ /// 停止粒子效果
+ ///
+ /// 粒子效果ID
+ /// 成功返回true,失败返回false
+ [DllImport(EngineEffectsDll, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I4)]
+ public static extern int Engine_ParticleStop(int particleId);
+
+ #endregion
+
+ #region 辅助函数
+
+ ///
+ /// 获取精灵索引
+ ///
+ /// 精灵文件路径
+ /// 精灵索引,失败返回-1
+ [DllImport(EngineEffectsDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_GetSpriteIndex(
+ [MarshalAs(UnmanagedType.LPStr)] string spriteName);
+
+ ///
+ /// 预缓存模型
+ ///
+ /// 模型文件路径
+ /// 模型索引,失败返回-1
+ [DllImport(EngineEffectsDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Engine_PrecacheModel(
+ [MarshalAs(UnmanagedType.LPStr)] string modelName);
+
+ #endregion
+ }
+
+ ///
+ /// 引擎特效桥接扩展类
+ /// 提供C#友好的封装接口
+ ///
+ public static class EngineEffectsExtensions
+ {
+ ///
+ /// 将音效附加到实体播放(简化版)
+ ///
+ public static bool PlaySoundAttached(int entity, string sample, float volume = 1.0f, int pitch = 100)
+ {
+ return EngineEffectsBridge.Engine_SoundPlayAttached(entity, sample, 0, volume, 1.0f, pitch, 0) != 0;
+ }
+
+ ///
+ /// 创建动态光源(简化版)
+ ///
+ public static int CreateLight(float[] origin, float radius, int red, int green, int blue, float life = 5.0f)
+ {
+ return EngineEffectsBridge.Engine_LightCreate(origin, radius, (byte)red, (byte)green, (byte)blue, life, 0);
+ }
+
+ ///
+ /// 创建爆炸效果
+ ///
+ public static int CreateExplosion(float[] origin, string sprite, int particleCount = 50)
+ {
+ return EngineEffectsBridge.Engine_ParticleCreate(origin, sprite, particleCount);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Gameplay/AmxModx.Bridge.CStrike.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Gameplay/AmxModx.Bridge.CStrike.cs
new file mode 100644
index 0000000..2a2018c
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Gameplay/AmxModx.Bridge.CStrike.cs
@@ -0,0 +1,462 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace AmxModx.Bridge.CStrike
+{
+ ///
+ /// Counter-Strike游戏功能桥接类
+ /// 提供对CS1.6游戏引擎的直接访问
+ ///
+ public static class CStrikeBridge
+ {
+ private const string DllName = "cstrike_bridge";
+
+ #region Player API
+
+ ///
+ /// 获取玩家金钱
+ ///
+ /// 玩家索引(1-32)
+ /// 玩家当前金钱数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CsGetUserMoney(int playerIndex);
+
+ ///
+ /// 设置玩家金钱
+ ///
+ /// 玩家索引(1-32)
+ /// 要设置的金钱数量
+ /// 是否显示更新提示(默认1)
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsSetUserMoney(int playerIndex, int money, int flash = 1);
+
+ ///
+ /// 获取玩家护甲值
+ ///
+ /// 玩家索引(1-32)
+ /// 玩家当前护甲值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CsGetUserArmor(int playerIndex);
+
+ ///
+ /// 设置玩家护甲值
+ ///
+ /// 玩家索引(1-32)
+ /// 要设置的护甲值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsSetUserArmor(int playerIndex, int armor);
+
+ ///
+ /// 获取玩家队伍
+ ///
+ /// 玩家索引(1-32)
+ /// 队伍ID (1=T, 2=CT, 3=SPEC)
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CsGetUserTeam(int playerIndex);
+
+ ///
+ /// 设置玩家队伍
+ ///
+ /// 玩家索引(1-32)
+ /// 队伍ID (1=T, 2=CT, 3=SPEC)
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsSetUserTeam(int playerIndex, int team);
+
+ ///
+ /// 获取玩家VIP状态
+ ///
+ /// 玩家索引(1-32)
+ /// 是否为VIP
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CsGetUserVip(int playerIndex);
+
+ ///
+ /// 设置玩家VIP状态
+ ///
+ /// 玩家索引(1-32)
+ /// VIP状态
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsSetUserVip(int playerIndex, [MarshalAs(UnmanagedType.Bool)] bool vip);
+
+ ///
+ /// 获取玩家死亡次数
+ ///
+ /// 玩家索引(1-32)
+ /// 死亡次数
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CsGetUserDeaths(int playerIndex);
+
+ ///
+ /// 设置玩家死亡次数
+ ///
+ /// 玩家索引(1-32)
+ /// 死亡次数
+ /// 是否更新计分板
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsSetUserDeaths(int playerIndex, int deaths, [MarshalAs(UnmanagedType.Bool)] bool updateScoreboard = true);
+
+ #endregion
+
+ #region Weapon API
+
+ ///
+ /// 获取武器ID
+ ///
+ /// 武器实体索引
+ /// 武器ID
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CsGetWeaponId(int weaponEntity);
+
+ ///
+ /// 获取武器消音器状态
+ ///
+ /// 武器实体索引
+ /// 是否装备消音器
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CsGetWeaponSilenced(int weaponEntity);
+
+ ///
+ /// 设置武器消音器状态
+ ///
+ /// 武器实体索引
+ /// 消音器状态
+ /// 是否播放动画
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsSetWeaponSilenced(int weaponEntity, [MarshalAs(UnmanagedType.Bool)] bool silenced, int drawAnimation = 1);
+
+ ///
+ /// 获取武器连发模式
+ ///
+ /// 武器实体索引
+ /// 是否为连发模式
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CsGetWeaponBurstMode(int weaponEntity);
+
+ ///
+ /// 设置武器连发模式
+ ///
+ /// 武器实体索引
+ /// 连发模式
+ /// 是否播放动画
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsSetWeaponBurstMode(int weaponEntity, [MarshalAs(UnmanagedType.Bool)] bool burstMode, int drawAnimation = 1);
+
+ ///
+ /// 获取武器弹药数量
+ ///
+ /// 武器实体索引
+ /// 弹药数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CsGetWeaponAmmo(int weaponEntity);
+
+ ///
+ /// 设置武器弹药数量
+ ///
+ /// 武器实体索引
+ /// 弹药数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsSetWeaponAmmo(int weaponEntity, int ammo);
+
+ #endregion
+
+ #region Game State API
+
+ ///
+ /// 检查玩家是否在购物区域
+ ///
+ /// 玩家索引(1-32)
+ /// 是否在购物区域
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CsGetUserInsideBuyzone(int playerIndex);
+
+ ///
+ /// 获取玩家地图区域
+ ///
+ /// 玩家索引(1-32)
+ /// 地图区域标志
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CsGetUserMapzones(int playerIndex);
+
+ ///
+ /// 检查玩家是否有主武器
+ ///
+ /// 玩家索引(1-32)
+ /// 是否有主武器
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CsGetUserHasPrimary(int playerIndex);
+
+ ///
+ /// 检查玩家是否有拆弹器
+ ///
+ /// 玩家索引(1-32)
+ /// 是否有拆弹器
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CsGetUserDefusekit(int playerIndex);
+
+ ///
+ /// 设置玩家拆弹器状态
+ ///
+ /// 玩家索引(1-32)
+ /// 是否有拆弹器
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsSetUserDefusekit(int playerIndex, [MarshalAs(UnmanagedType.Bool)] bool hasKit);
+
+ ///
+ /// 检查玩家是否有夜视镜
+ ///
+ /// 玩家索引(1-32)
+ /// 是否有夜视镜
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CsGetUserNvg(int playerIndex);
+
+ ///
+ /// 设置玩家夜视镜状态
+ ///
+ /// 玩家索引(1-32)
+ /// 是否有夜视镜
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsSetUserNvg(int playerIndex, [MarshalAs(UnmanagedType.Bool)] bool hasNvg);
+
+ #endregion
+
+ #region Model API
+
+ ///
+ /// 获取玩家模型
+ ///
+ /// 玩家索引(1-32)
+ /// 模型名称缓冲区
+ /// 缓冲区大小
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsGetUserModel(int playerIndex, [Out] StringBuilder buffer, int bufferSize);
+
+ ///
+ /// 设置玩家模型
+ ///
+ /// 玩家索引(1-32)
+ /// 模型名称
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsSetUserModel(int playerIndex, [MarshalAs(UnmanagedType.LPStr)] string model);
+
+ ///
+ /// 重置玩家模型为默认
+ ///
+ /// 玩家索引(1-32)
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsResetUserModel(int playerIndex);
+
+ #endregion
+
+ #region Entity API
+
+ ///
+ /// 创建游戏实体
+ ///
+ /// 实体类名
+ /// 实体索引
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CsCreateEntity([MarshalAs(UnmanagedType.LPStr)] string className);
+
+ ///
+ /// 按类名查找实体
+ ///
+ /// 起始索引
+ /// 实体类名
+ /// 实体索引
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CsFindEntityByClass(int startIndex, [MarshalAs(UnmanagedType.LPStr)] string className);
+
+ ///
+ /// 按所有者查找实体
+ ///
+ /// 起始索引
+ /// 所有者玩家索引
+ /// 实体索引
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CsFindEntityByOwner(int startIndex, int ownerIndex);
+
+ ///
+ /// 设置实体类名
+ ///
+ /// 实体索引
+ /// 新的类名
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CsSetEntityClass(int entityIndex, [MarshalAs(UnmanagedType.LPStr)] string className);
+
+ #endregion
+
+ #region Item API
+
+ ///
+ /// 通过物品名称获取物品ID
+ ///
+ /// 物品名称
+ /// 物品ID
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CsGetItemId([MarshalAs(UnmanagedType.LPStr)] string itemName);
+
+ ///
+ /// 获取物品别名
+ ///
+ /// 物品ID
+ /// 别名缓冲区
+ /// 缓冲区大小
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CsGetItemAlias(int itemId, [Out] StringBuilder buffer, int bufferSize);
+
+ ///
+ /// 获取物品翻译后的别名
+ ///
+ /// 物品ID
+ /// 别名缓冲区
+ /// 缓冲区大小
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CsGetTranslatedItemAlias(int itemId, [Out] StringBuilder buffer, int bufferSize);
+
+ #endregion
+
+ #region Hostage API
+
+ ///
+ /// 获取人质ID
+ ///
+ /// 人质索引
+ /// 人质ID
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int CsGetHostageId(int hostageIndex);
+
+ ///
+ /// 获取人质跟随状态
+ ///
+ /// 人质索引
+ /// 是否跟随
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CsGetHostageFollow(int hostageIndex);
+
+ ///
+ /// 设置人质跟随状态
+ ///
+ /// 人质索引
+ /// 是否跟随
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsSetHostageFollow(int hostageIndex, [MarshalAs(UnmanagedType.Bool)] bool follow);
+
+ #endregion
+
+ #region Bomb API
+
+ ///
+ /// 获取C4爆炸时间
+ ///
+ /// 爆炸时间(秒)
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern float CsGetC4ExplodeTime();
+
+ ///
+ /// 设置C4爆炸时间
+ ///
+ /// 爆炸时间(秒)
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsSetC4ExplodeTime(float time);
+
+ ///
+ /// 获取C4拆弹状态
+ ///
+ /// 是否在拆弹
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CsGetC4Defusing();
+
+ ///
+ /// 设置C4拆弹状态
+ ///
+ /// 拆弹状态
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsSetC4Defusing([MarshalAs(UnmanagedType.Bool)] bool defusing);
+
+ #endregion
+
+ #region Event Callbacks
+
+ // 委托定义
+ public delegate void CsPlayerDeathDelegate(int victim, int killer, int weapon);
+ public delegate void CsBombEventDelegate(int eventType, int player);
+ public delegate void CsWeaponPickupDelegate(int player, int weaponId);
+
+ ///
+ /// 注册玩家死亡事件回调
+ ///
+ /// 回调函数
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsRegisterPlayerDeathCallback(CsPlayerDeathDelegate callback);
+
+ ///
+ /// 注册炸弹事件回调
+ ///
+ /// 回调函数
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsRegisterBombEventCallback(CsBombEventDelegate callback);
+
+ ///
+ /// 注册武器拾取事件回调
+ ///
+ /// 回调函数
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void CsRegisterWeaponPickupCallback(CsWeaponPickupDelegate callback);
+
+ #endregion
+
+ #region Helper Methods
+
+ ///
+ /// 获取玩家模型名称
+ ///
+ /// 玩家索引
+ /// 模型名称
+ public static string GetUserModel(int playerIndex)
+ {
+ var sb = new StringBuilder(256);
+ CsGetUserModel(playerIndex, sb, sb.Capacity);
+ return sb.ToString();
+ }
+
+ ///
+ /// 获取物品别名
+ ///
+ /// 物品ID
+ /// 物品别名
+ public static string GetItemAlias(int itemId)
+ {
+ var sb = new StringBuilder(64);
+ return CsGetItemAlias(itemId, sb, sb.Capacity) ? sb.ToString() : string.Empty;
+ }
+
+ ///
+ /// 获取物品翻译别名
+ ///
+ /// 物品ID
+ /// 翻译后的别名
+ public static string GetTranslatedItemAlias(int itemId)
+ {
+ var sb = new StringBuilder(64);
+ return CsGetTranslatedItemAlias(itemId, sb, sb.Capacity) ? sb.ToString() : string.Empty;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Gameplay/AmxModx.Bridge.Fakemeta.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Gameplay/AmxModx.Bridge.Fakemeta.cs
new file mode 100644
index 0000000..71e9974
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Gameplay/AmxModx.Bridge.Fakemeta.cs
@@ -0,0 +1,828 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+
+namespace AmxModx.Bridge.Fakemeta
+{
+ ///
+ /// Fakemeta模块事件类型枚举
+ ///
+ public enum ForwardType
+ {
+ PrecacheModel = 0,
+ PrecacheSound = 1,
+ SetModel = 2,
+ CreateEntity = 3,
+ RemoveEntity = 4,
+ Spawn = 5,
+ Think = 6,
+ Use = 7,
+ Touch = 8,
+ Blocked = 9,
+ ClientCommand = 10,
+ ClientUserInfoChanged = 11,
+ ServerActivate = 12,
+ ServerDeactivate = 13,
+ PlayerPreThink = 14,
+ PlayerPostThink = 15,
+ StartFrame = 16,
+ ClientConnect = 17,
+ ClientDisconnect = 18,
+ ClientPutInServer = 19,
+ ClientKill = 20,
+ ClientSpawn = 21,
+ TraceLine = 22,
+ TraceToss = 23,
+ TraceMonsterHull = 24,
+ TraceHull = 25,
+ TraceModel = 26,
+ TraceTexture = 27,
+ TraceSphere = 28,
+ GetAimVector = 29,
+ EmitSound = 30,
+ EmitAmbientSound = 31,
+ LightStyle = 32,
+ DecalIndex = 33,
+ PointContents = 34,
+ MessageBegin = 35,
+ MessageEnd = 36,
+ WriteByte = 37,
+ WriteChar = 38,
+ WriteShort = 39,
+ WriteLong = 40,
+ WriteAngle = 41,
+ WriteCoord = 42,
+ WriteString = 43,
+ WriteEntity = 44,
+ CVarGetFloat = 45,
+ CVarGetString = 46,
+ CVarSetFloat = 47,
+ CVarSetString = 48,
+ CVarRegister = 49,
+ AlertMessage = 50,
+ EngineFprintf = 51,
+ PvsFindEntity = 52,
+ PvsEntitiesInPvs = 53,
+ PvsCheckOrigin = 54,
+ PvsCheckEntity = 55,
+ PvsCheckBox = 56,
+ PvsCheckPoint = 57,
+ PvsCheckEverything = 58,
+ PvsCheckEverything2 = 59,
+ PvsCheckEverything3 = 60,
+ PvsCheckEverything4 = 61,
+ PvsCheckEverything5 = 62,
+ PvsCheckEverything6 = 63,
+ PvsCheckEverything7 = 64,
+ PvsCheckEverything8 = 65,
+ PvsCheckEverything9 = 66,
+ PvsCheckEverything10 = 67,
+ PvsCheckEverything11 = 68,
+ PvsCheckEverything12 = 69,
+ PvsCheckEverything13 = 70,
+ PvsCheckEverything14 = 71,
+ PvsCheckEverything15 = 72,
+ PvsCheckEverything16 = 73,
+ PvsCheckEverything17 = 74,
+ PvsCheckEverything18 = 75,
+ PvsCheckEverything19 = 76,
+ PvsCheckEverything20 = 77,
+ PvsCheckEverything21 = 78,
+ PvsCheckEverything22 = 79,
+ PvsCheckEverything23 = 80,
+ PvsCheckEverything24 = 81,
+ PvsCheckEverything25 = 82,
+ PvsCheckEverything26 = 83,
+ PvsCheckEverything27 = 84,
+ PvsCheckEverything28 = 85,
+ PvsCheckEverything29 = 86,
+ PvsCheckEverything30 = 87,
+ PvsCheckEverything31 = 88,
+ PvsCheckEverything32 = 89,
+ PvsCheckEverything33 = 90,
+ PvsCheckEverything34 = 91,
+ PvsCheckEverything35 = 92,
+ PvsCheckEverything36 = 93,
+ PvsCheckEverything37 = 94,
+ PvsCheckEverything38 = 95,
+ PvsCheckEverything39 = 96,
+ PvsCheckEverything40 = 97,
+ PvsCheckEverything41 = 98,
+ PvsCheckEverything42 = 99,
+ PvsCheckEverything43 = 100,
+ PvsCheckEverything44 = 101,
+ PvsCheckEverything45 = 102,
+ PvsCheckEverything46 = 103,
+ PvsCheckEverything47 = 104,
+ PvsCheckEverything48 = 105,
+ PvsCheckEverything49 = 106,
+ PvsCheckEverything50 = 107,
+ PvsCheckEverything51 = 108,
+ PvsCheckEverything52 = 109,
+ PvsCheckEverything53 = 110,
+ PvsCheckEverything54 = 111,
+ PvsCheckEverything55 = 112,
+ PvsCheckEverything56 = 113,
+ PvsCheckEverything57 = 114,
+ PvsCheckEverything58 = 115,
+ PvsCheckEverything59 = 116,
+ PvsCheckEverything60 = 117,
+ PvsCheckEverything61 = 118,
+ PvsCheckEverything62 = 119,
+ PvsCheckEverything63 = 120,
+ PvsCheckEverything64 = 121,
+ PvsCheckEverything65 = 122,
+ PvsCheckEverything66 = 123,
+ PvsCheckEverything67 = 124,
+ PvsCheckEverything68 = 125,
+ PvsCheckEverything69 = 126,
+ PvsCheckEverything70 = 127,
+ PvsCheckEverything71 = 128,
+ PvsCheckEverything72 = 129,
+ PvsCheckEverything73 = 130,
+ PvsCheckEverything74 = 131
+ }
+
+ ///
+ /// 事件执行时机
+ ///
+ public enum ForwardTiming
+ {
+ Pre = 0, // 前置钩子
+ Post = 1 // 后置钩子
+ }
+
+ ///
+ /// 事件返回值
+ ///
+ public enum ForwardResult
+ {
+ Ignored = 0, // 忽略,继续执行
+ Handled = 1, // 已处理,继续执行
+ Override = 2, // 覆盖,继续执行
+ Supercede = 3 // 取代,停止执行
+ }
+
+ ///
+ /// 事件参数结构体
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ public struct EventData
+ {
+ public int EntityIndex; // 实体索引
+ [MarshalAs(UnmanagedType.LPStr)]
+ public string StringValue; // 字符串值
+ public float FloatValue; // 浮点值
+ public int IntValue; // 整数值
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
+ public float[] VectorValue; // 向量值
+ public IntPtr CustomData; // 自定义数据
+ }
+
+ ///
+ /// 事件回调委托
+ ///
+ /// 事件数据
+ /// 用户数据
+ /// 事件处理结果
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate ForwardResult ForwardCallback(ref EventData data, IntPtr userData);
+
+ ///
+ /// 简化的回调委托,用于lambda表达式
+ ///
+ /// 实体索引
+ /// 字符串值
+ /// 浮点值
+ /// 整数值
+ /// 向量值
+ /// 事件处理结果
+ public delegate ForwardResult SimpleForwardCallback(int entityIndex, string stringValue, float floatValue, int intValue, float[] vectorValue);
+
+ ///
+ /// 实体事件回调委托
+ ///
+ /// 实体索引
+ /// 事件处理结果
+ public delegate ForwardResult EntityForwardCallback(int entity);
+
+ ///
+ /// 玩家事件回调委托
+ ///
+ /// 玩家索引
+ /// 命令字符串
+ /// 事件处理结果
+ public delegate ForwardResult PlayerForwardCallback(int playerIndex, string command = null);
+
+ ///
+ /// 无参数事件回调委托
+ ///
+ /// 事件处理结果
+ public delegate ForwardResult VoidForwardCallback();
+
+ internal static class NativeMethods
+ {
+ private const string DllName = "fakemeta_amxx";
+
+ ///
+ /// 初始化事件系统
+ ///
+ /// 成功返回1,失败返回0
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int FMB_InitializeForwardSystem();
+
+ ///
+ /// 清理事件系统
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void FMB_CleanupForwardSystem();
+
+ ///
+ /// 注册事件钩子
+ ///
+ /// 事件类型
+ /// 执行时机
+ /// 回调函数
+ /// 用户数据
+ /// 注册句柄,失败返回0
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int FMB_RegisterForward(ForwardType type, ForwardTiming timing, ForwardCallback callback, IntPtr userData);
+
+ ///
+ /// 注销事件钩子
+ ///
+ /// 事件类型
+ /// 执行时机
+ /// 注册句柄
+ /// 成功返回1,失败返回0
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int FMB_UnregisterForward(ForwardType type, ForwardTiming timing, int handle);
+
+ ///
+ /// 触发事件
+ ///
+ /// 事件类型
+ /// 执行时机
+ /// 事件数据
+ /// 事件处理结果
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern ForwardResult FMB_ExecuteForwards(ForwardType type, ForwardTiming timing, ref EventData data);
+
+ ///
+ /// 获取事件队列长度
+ ///
+ /// 事件类型
+ /// 执行时机
+ /// 事件数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int FMB_GetForwardCount(ForwardType type, ForwardTiming timing);
+
+ ///
+ /// 检查事件是否已注册
+ ///
+ /// 事件类型
+ /// 执行时机
+ /// 注册句柄
+ /// 已注册返回1,未注册返回0
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int FMB_IsForwardRegistered(ForwardType type, ForwardTiming timing, int handle);
+
+ ///
+ /// 获取事件类型名称
+ ///
+ /// 事件类型
+ /// 类型名称
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.LPStr)]
+ public static extern string FMB_GetForwardTypeName(ForwardType type);
+
+ ///
+ /// 获取事件时机名称
+ ///
+ /// 执行时机
+ /// 时机名称
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.LPStr)]
+ public static extern string FMB_GetForwardTimingName(ForwardTiming timing);
+
+ ///
+ /// 获取事件结果名称
+ ///
+ /// 处理结果
+ /// 结果名称
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.LPStr)]
+ public static extern string FMB_GetForwardResultName(ForwardResult result);
+ }
+
+ ///
+ /// 事件管理器 - 提供简化的回调注册接口
+ ///
+ public static class ForwardManager
+ {
+ private static readonly Dictionary callbacks = new Dictionary();
+ private static readonly Dictionary gcHandles = new Dictionary();
+ private static int nextHandle = 1;
+ private static bool isInitialized = false;
+
+ ///
+ /// 初始化事件系统
+ ///
+ public static void Initialize()
+ {
+ if (!isInitialized)
+ {
+ int result = NativeMethods.FMB_InitializeForwardSystem();
+ if (result == 1)
+ {
+ isInitialized = true;
+ }
+ else
+ {
+ throw new InvalidOperationException("Failed to initialize Fakemeta forward system");
+ }
+ }
+ }
+
+ ///
+ /// 清理事件系统
+ ///
+ public static void Cleanup()
+ {
+ if (isInitialized)
+ {
+ NativeMethods.FMB_CleanupForwardSystem();
+ isInitialized = false;
+ }
+
+ foreach (var handle in gcHandles.Values)
+ {
+ if (handle.IsAllocated)
+ handle.Free();
+ }
+
+ callbacks.Clear();
+ gcHandles.Clear();
+ }
+
+ ///
+ /// 注册事件回调
+ ///
+ /// 事件类型
+ /// 执行时机
+ /// 回调函数
+ /// 用户数据
+ /// 注册句柄
+ public static int RegisterForward(ForwardType type, ForwardTiming timing, ForwardCallback callback, object userData = null)
+ {
+ if (callback == null)
+ throw new ArgumentNullException(nameof(callback));
+ if (!isInitialized)
+ Initialize();
+
+ int handle = nextHandle++;
+ callbacks[handle] = callback;
+
+ IntPtr userDataPtr = IntPtr.Zero;
+ if (userData != null)
+ {
+ var gcHandle = GCHandle.Alloc(userData);
+ gcHandles[handle] = gcHandle;
+ userDataPtr = GCHandle.ToIntPtr(gcHandle);
+ }
+
+ int result = NativeMethods.FMB_RegisterForward(type, timing, callback, userDataPtr);
+ if (result == 0)
+ {
+ callbacks.Remove(handle);
+ if (userData != null && gcHandles.ContainsKey(handle))
+ {
+ gcHandles[handle].Free();
+ gcHandles.Remove(handle);
+ }
+ return 0;
+ }
+
+ return handle;
+ }
+
+ ///
+ /// 使用lambda表达式注册事件回调
+ ///
+ /// 事件类型
+ /// 执行时机
+ /// lambda回调
+ /// 注册句柄
+ public static int RegisterForward(ForwardType type, ForwardTiming timing, SimpleForwardCallback callback)
+ {
+ if (callback == null)
+ throw new ArgumentNullException(nameof(callback));
+
+ ForwardCallback nativeCallback = (ref EventData data, IntPtr userData) =>
+ {
+ return callback(data.EntityIndex, data.StringValue, data.FloatValue, data.IntValue, data.VectorValue);
+ };
+
+ return RegisterForward(type, timing, nativeCallback);
+ }
+
+ ///
+ /// 注册实体事件回调
+ ///
+ /// 事件类型
+ /// 执行时机
+ /// 实体回调
+ /// 注册句柄
+ public static int RegisterEntityForward(ForwardType type, ForwardTiming timing, EntityForwardCallback callback)
+ {
+ if (callback == null)
+ throw new ArgumentNullException(nameof(callback));
+
+ ForwardCallback nativeCallback = (ref EventData data, IntPtr userData) =>
+ {
+ return callback(data.EntityIndex);
+ };
+
+ return RegisterForward(type, timing, nativeCallback);
+ }
+
+ ///
+ /// 注册玩家事件回调
+ ///
+ /// 事件类型
+ /// 执行时机
+ /// 玩家回调
+ /// 注册句柄
+ public static int RegisterPlayerForward(ForwardType type, ForwardTiming timing, PlayerForwardCallback callback)
+ {
+ if (callback == null)
+ throw new ArgumentNullException(nameof(callback));
+
+ ForwardCallback nativeCallback = (ref EventData data, IntPtr userData) =>
+ {
+ return callback(data.EntityIndex, data.StringValue);
+ };
+
+ return RegisterForward(type, timing, nativeCallback);
+ }
+
+ ///
+ /// 注册无参数事件回调
+ ///
+ /// 事件类型
+ /// 执行时机
+ /// 无参数回调
+ /// 注册句柄
+ public static int RegisterVoidForward(ForwardType type, ForwardTiming timing, VoidForwardCallback callback)
+ {
+ if (callback == null)
+ throw new ArgumentNullException(nameof(callback));
+
+ ForwardCallback nativeCallback = (ref EventData data, IntPtr userData) =>
+ {
+ return callback();
+ };
+
+ return RegisterForward(type, timing, nativeCallback);
+ }
+
+ ///
+ /// 注销事件回调
+ ///
+ /// 事件类型
+ /// 执行时机
+ /// 注册句柄
+ /// 是否成功
+ public static bool UnregisterForward(ForwardType type, ForwardTiming timing, int handle)
+ {
+ if (!callbacks.ContainsKey(handle))
+ return false;
+ if (!isInitialized)
+ return false;
+
+ int result = NativeMethods.FMB_UnregisterForward(type, timing, handle);
+ if (result != 0)
+ {
+ callbacks.Remove(handle);
+ if (gcHandles.ContainsKey(handle))
+ {
+ gcHandles[handle].Free();
+ gcHandles.Remove(handle);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// 触发事件
+ ///
+ /// 事件类型
+ /// 执行时机
+ /// 事件数据
+ /// 事件处理结果
+ public static ForwardResult ExecuteForwards(ForwardType type, ForwardTiming timing, ref EventData data)
+ {
+ if (!isInitialized)
+ return ForwardResult.Ignored;
+
+ return NativeMethods.FMB_ExecuteForwards(type, timing, ref data);
+ }
+
+ ///
+ /// 获取事件数量
+ ///
+ /// 事件类型
+ /// 执行时机
+ /// 事件数量
+ public static int GetForwardCount(ForwardType type, ForwardTiming timing)
+ {
+ if (!isInitialized)
+ return 0;
+
+ return NativeMethods.FMB_GetForwardCount(type, timing);
+ }
+
+ ///
+ /// 检查事件是否已注册
+ ///
+ /// 事件类型
+ /// 执行时机
+ /// 注册句柄
+ /// 是否已注册
+ public static bool IsForwardRegistered(ForwardType type, ForwardTiming timing, int handle)
+ {
+ if (!isInitialized)
+ return false;
+
+ return NativeMethods.FMB_IsForwardRegistered(type, timing, handle) != 0;
+ }
+ }
+
+ ///
+ /// Fakemeta回调管理器 - 提供高级封装
+ ///
+ public static class FakemetaCallbacks
+ {
+ ///
+ /// 注册实体创建回调
+ ///
+ /// 创建回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnEntityCreate(EntityForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterEntityForward(ForwardType.CreateEntity, timing, callback);
+ }
+
+ ///
+ /// 注册实体销毁回调
+ ///
+ /// 销毁回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnEntityRemove(EntityForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterEntityForward(ForwardType.RemoveEntity, timing, callback);
+ }
+
+ ///
+ /// 注册实体生成回调
+ ///
+ /// 生成回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnEntitySpawn(EntityForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterEntityForward(ForwardType.Spawn, timing, callback);
+ }
+
+ ///
+ /// 注册实体思考回调
+ ///
+ /// 思考回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnEntityThink(EntityForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterEntityForward(ForwardType.Think, timing, callback);
+ }
+
+ ///
+ /// 注册实体使用回调
+ ///
+ /// 使用回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnEntityUse(EntityForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterEntityForward(ForwardType.Use, timing, callback);
+ }
+
+ ///
+ /// 注册实体触碰回调
+ ///
+ /// 触碰回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnEntityTouch(EntityForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterEntityForward(ForwardType.Touch, timing, callback);
+ }
+
+ ///
+ /// 注册实体阻挡回调
+ ///
+ /// 阻挡回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnEntityBlocked(EntityForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterEntityForward(ForwardType.Blocked, timing, callback);
+ }
+
+ ///
+ /// 注册玩家连接回调
+ ///
+ /// 连接回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnPlayerConnect(PlayerForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterPlayerForward(ForwardType.ClientConnect, timing, callback);
+ }
+
+ ///
+ /// 注册玩家断开连接回调
+ ///
+ /// 断开连接回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnPlayerDisconnect(PlayerForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterPlayerForward(ForwardType.ClientDisconnect, timing, callback);
+ }
+
+ ///
+ /// 注册玩家命令回调
+ ///
+ /// 命令回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnPlayerCommand(PlayerForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterPlayerForward(ForwardType.ClientCommand, timing, callback);
+ }
+
+ ///
+ /// 注册玩家生成回调
+ ///
+ /// 生成回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnPlayerSpawn(PlayerForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterPlayerForward(ForwardType.ClientSpawn, timing, callback);
+ }
+
+ ///
+ /// 注册玩家预思考回调
+ ///
+ /// 预思考回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnPlayerPreThink(PlayerForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterPlayerForward(ForwardType.PlayerPreThink, timing, callback);
+ }
+
+ ///
+ /// 注册玩家后思考回调
+ ///
+ /// 后思考回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnPlayerPostThink(PlayerForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterPlayerForward(ForwardType.PlayerPostThink, timing, callback);
+ }
+
+ ///
+ /// 注册服务器激活回调
+ ///
+ /// 激活回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnServerActivate(VoidForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterVoidForward(ForwardType.ServerActivate, timing, callback);
+ }
+
+ ///
+ /// 注册服务器停用回调
+ ///
+ /// 停用回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnServerDeactivate(VoidForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterVoidForward(ForwardType.ServerDeactivate, timing, callback);
+ }
+
+ ///
+ /// 注册每帧回调
+ ///
+ /// 每帧回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnStartFrame(VoidForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterVoidForward(ForwardType.StartFrame, timing, callback);
+ }
+
+ ///
+ /// 注册模型预缓存回调
+ ///
+ /// 预缓存回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnPrecacheModel(PlayerForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterPlayerForward(ForwardType.PrecacheModel, timing, callback);
+ }
+
+ ///
+ /// 注册声音预缓存回调
+ ///
+ /// 预缓存回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnPrecacheSound(PlayerForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterPlayerForward(ForwardType.PrecacheSound, timing, callback);
+ }
+
+ ///
+ /// 注册模型设置回调
+ ///
+ /// 模型设置回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnSetModel(PlayerForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterPlayerForward(ForwardType.SetModel, timing, callback);
+ }
+
+ ///
+ /// 注册追踪线回调
+ ///
+ /// 追踪线回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnTraceLine(PlayerForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return ForwardManager.RegisterPlayerForward(ForwardType.TraceLine, timing, callback);
+ }
+ }
+
+ ///
+ /// 事件扩展方法,提供lambda表达式支持
+ ///
+ public static class ForwardExtensions
+ {
+ ///
+ /// 使用lambda表达式注册实体创建事件
+ ///
+ /// lambda回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnEntityCreate(this EntityForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return FakemetaCallbacks.OnEntityCreate(callback, timing);
+ }
+
+ /////
+ ///// 使用lambda表达式注册玩家连接事件
+ /////
+ ///// lambda回调
+ ///// 执行时机
+ ///// 注册句柄
+ //public static int OnPlayerConnect(this EntityForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ //{
+ // return FakemetaCallbacks.OnPlayerConnect(callback, timing);
+ //}
+
+ ///
+ /// 使用lambda表达式注册每帧事件
+ ///
+ /// lambda回调
+ /// 执行时机
+ /// 注册句柄
+ public static int OnStartFrame(this VoidForwardCallback callback, ForwardTiming timing = ForwardTiming.Pre)
+ {
+ return FakemetaCallbacks.OnStartFrame(callback, timing);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Gameplay/AmxModx.Bridge.Fun.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Gameplay/AmxModx.Bridge.Fun.cs
new file mode 100644
index 0000000..69d322d
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Gameplay/AmxModx.Bridge.Fun.cs
@@ -0,0 +1,425 @@
+// vim: set ts=4 sw=4 tw=99 noet:
+//
+// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
+// Copyright (C) The AMX Mod X Development Team.
+//
+// This software is licensed under the GNU General Public License, version 3 or higher.
+// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
+// https://alliedmods.net/amxmodx-license
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace AmxModx.Bridge.Fun
+{
+ ///
+ /// Fun模块的C#桥接接口
+ /// 提供对CS1.6游戏功能的访问
+ ///
+ public static class FunBridge
+ {
+ private const string FunBridgeDll = "fun_bridge";
+
+ #region 客户端语音监听
+
+ ///
+ /// 获取客户端是否监听其他玩家的语音
+ ///
+ /// 接收者玩家索引
+ /// 发送者玩家索引
+ /// 1表示监听,0表示不监听
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetClientListening(int receiver, int sender);
+
+ ///
+ /// 设置客户端是否监听其他玩家的语音
+ ///
+ /// 接收者玩家索引
+ /// 发送者玩家索引
+ /// 1表示监听,0表示不监听
+ /// 操作是否成功
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SetClientListening(int receiver, int sender, int listen);
+
+ #endregion
+
+ #region 玩家无敌模式
+
+ ///
+ /// 设置玩家无敌模式
+ ///
+ /// 玩家索引
+ /// 1开启无敌,0关闭无敌
+ /// 操作是否成功
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SetUserGodmode(int user, int godmode);
+
+ ///
+ /// 获取玩家无敌模式状态
+ ///
+ /// 玩家索引
+ /// 1表示无敌,0表示非无敌
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetUserGodmode(int user);
+
+ #endregion
+
+ #region 玩家生命值
+
+ ///
+ /// 获取玩家生命值
+ ///
+ /// 玩家索引
+ /// 生命值
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern float GetUserHealth(int index);
+
+ ///
+ /// 设置玩家生命值
+ ///
+ /// 玩家索引
+ /// 生命值
+ /// 操作是否成功
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SetUserHealth(int index, float health);
+
+ #endregion
+
+ #region 物品和武器
+
+ ///
+ /// 给予玩家物品
+ ///
+ /// 玩家索引
+ /// 物品名称
+ /// 物品实体ID,失败返回0或-1
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GiveItem(int index, [MarshalAs(UnmanagedType.LPStr)] string item);
+
+ ///
+ /// 重新生成实体
+ ///
+ /// 实体索引
+ /// 操作是否成功
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SpawnEntity(int index);
+
+ #endregion
+
+ #region 玩家击杀和护甲
+
+ ///
+ /// 获取玩家击杀数
+ ///
+ /// 玩家索引
+ /// 击杀数
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetUserFrags(int index);
+
+ ///
+ /// 设置玩家击杀数
+ ///
+ /// 玩家索引
+ /// 击杀数
+ /// 操作是否成功
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SetUserFrags(int index, int frags);
+
+ ///
+ /// 获取玩家护甲值
+ ///
+ /// 玩家索引
+ /// 护甲值
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetUserArmor(int index);
+
+ ///
+ /// 设置玩家护甲值
+ ///
+ /// 玩家索引
+ /// 护甲值
+ /// 操作是否成功
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SetUserArmor(int index, int armor);
+
+ #endregion
+
+ #region 玩家位置和渲染
+
+ ///
+ /// 获取玩家位置
+ ///
+ /// 玩家索引
+ /// 位置坐标数组(x,y,z)
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void GetUserOrigin(int index, [Out, MarshalAs(UnmanagedType.LPArray, SizeConst = 3)] float[] origin);
+
+ ///
+ /// 设置玩家位置
+ ///
+ /// 玩家索引
+ /// 位置坐标数组(x,y,z)
+ /// 操作是否成功
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SetUserOrigin(int index, [In, MarshalAs(UnmanagedType.LPArray, SizeConst = 3)] float[] origin);
+
+ ///
+ /// 获取玩家渲染效果
+ ///
+ /// 玩家索引
+ /// 特效类型输出
+ /// 红色分量输出
+ /// 绿色分量输出
+ /// 蓝色分量输出
+ /// 渲染模式输出
+ /// 透明度输出
+ /// 操作是否成功
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetUserRendering(int index, out int fx, out int r, out int g, out int b, out int render, out float amount);
+
+ ///
+ /// 设置玩家渲染效果
+ ///
+ /// 玩家索引
+ /// 特效类型
+ /// 红色分量
+ /// 绿色分量
+ /// 蓝色分量
+ /// 渲染模式
+ /// 透明度
+ /// 操作是否成功
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SetUserRendering(int index, int fx, int r, int g, int b, int render, float amount);
+
+ #endregion
+
+ #region 玩家物理属性
+
+ ///
+ /// 获取玩家最大速度
+ ///
+ /// 玩家索引
+ /// 最大速度值
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern float GetUserMaxspeed(int index);
+
+ ///
+ /// 设置玩家最大速度
+ ///
+ /// 玩家索引
+ /// 最大速度
+ /// 操作是否成功
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SetUserMaxspeed(int index, float speed);
+
+ ///
+ /// 获取玩家重力
+ ///
+ /// 玩家索引
+ /// 重力值
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern float GetUserGravity(int index);
+
+ ///
+ /// 设置玩家重力
+ ///
+ /// 玩家索引
+ /// 重力值
+ /// 操作是否成功
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SetUserGravity(int index, float gravity);
+
+ #endregion
+
+ #region 命中区域
+
+ ///
+ /// 获取玩家命中区域设置
+ ///
+ /// 攻击者索引
+ /// 目标索引
+ /// 命中区域标志
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetUserHitzones(int attacker, int target);
+
+ ///
+ /// 设置玩家命中区域
+ ///
+ /// 攻击者索引,0表示所有玩家
+ /// 目标索引,0表示所有玩家
+ /// 命中区域标志
+ /// 操作是否成功
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SetUserHitzones(int attacker, int target, int hitzones);
+
+ #endregion
+
+ #region 穿墙模式
+
+ ///
+ /// 设置玩家穿墙模式
+ ///
+ /// 玩家索引
+ /// 1开启穿墙,0关闭穿墙
+ /// 操作是否成功
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SetUserNoclip(int index, int noclip);
+
+ ///
+ /// 获取玩家穿墙模式状态
+ ///
+ /// 玩家索引
+ /// 1表示穿墙模式,0表示正常模式
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetUserNoclip(int index);
+
+ #endregion
+
+ #region 脚步声
+
+ ///
+ /// 设置玩家脚步声
+ ///
+ /// 玩家索引
+ /// 1开启无声脚步,0关闭无声脚步
+ /// 操作是否成功
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SetUserFootsteps(int index, int footsteps);
+
+ ///
+ /// 获取玩家脚步声状态
+ ///
+ /// 玩家索引
+ /// 1表示无声脚步,0表示正常脚步
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetUserFootsteps(int index);
+
+ #endregion
+
+ #region 武器管理
+
+ ///
+ /// 移除玩家所有武器
+ ///
+ /// 玩家索引
+ /// 操作是否成功
+ [DllImport(FunBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int StripUserWeapons(int index);
+
+ #endregion
+
+ #region 辅助类和方法
+
+ ///
+ /// 玩家渲染模式枚举
+ ///
+ public enum RenderMode
+ {
+ Normal = 0,
+ Color = 1,
+ Texture = 2,
+ Glow = 3,
+ Solid = 4,
+ Additive = 5
+ }
+
+ ///
+ /// 玩家特效类型枚举
+ ///
+ public enum RenderFx
+ {
+ None = 0,
+ PulseSlow = 1,
+ PulseFast = 2,
+ PulseSlowWide = 3,
+ PulseFastWide = 4,
+ FadeSlow = 5,
+ FadeFast = 6,
+ SolidSlow = 7,
+ SolidFast = 8,
+ StrobeSlow = 9,
+ StrobeFast = 10,
+ StrobeFaster = 11,
+ FlickerSlow = 12,
+ FlickerFast = 13,
+ NoDissipation = 14,
+ Distort = 15,
+ Hologram = 16,
+ DeadPlayer = 17,
+ Explode = 18,
+ GlowShell = 19,
+ ClampMinScale = 20,
+ LightMultiplier = 21
+ }
+
+ ///
+ /// 命中区域枚举
+ ///
+ [Flags]
+ public enum HitZones
+ {
+ Generic = 1 << 0,
+ Head = 1 << 1,
+ Chest = 1 << 2,
+ Stomach = 1 << 3,
+ LeftArm = 1 << 4,
+ RightArm = 1 << 5,
+ LeftLeg = 1 << 6,
+ RightLeg = 1 << 7,
+ All = (1 << 8) - 1
+ }
+
+ ///
+ /// 获取玩家渲染信息的结构体
+ ///
+ public struct PlayerRendering
+ {
+ public RenderFx Fx;
+ public int Red;
+ public int Green;
+ public int Blue;
+ public RenderMode RenderMode;
+ public float Amount;
+ }
+
+ ///
+ /// 获取玩家渲染信息的便捷方法
+ ///
+ /// 玩家索引
+ /// 玩家渲染信息
+ public static PlayerRendering GetPlayerRendering(int index)
+ {
+ int fx, r, g, b, render;
+ float amount;
+
+ int result = GetUserRendering(index, out fx, out r, out g, out b, out render, out amount);
+ if (result == 0)
+ throw new InvalidOperationException("无法获取玩家渲染信息");
+
+ return new PlayerRendering
+ {
+ Fx = (RenderFx)fx,
+ Red = r,
+ Green = g,
+ Blue = b,
+ RenderMode = (RenderMode)render,
+ Amount = amount
+ };
+ }
+
+ ///
+ /// 设置玩家渲染信息的便捷方法
+ ///
+ /// 玩家索引
+ /// 渲染信息
+ public static void SetPlayerRendering(int index, PlayerRendering rendering)
+ {
+ int result = SetUserRendering(index, (int)rendering.Fx, rendering.Red, rendering.Green,
+ rendering.Blue, (int)rendering.RenderMode, rendering.Amount);
+ if (result == 0)
+ throw new InvalidOperationException("无法设置玩家渲染信息");
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Gameplay/AmxModx.Bridge.HamSandwich.Direct.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Gameplay/AmxModx.Bridge.HamSandwich.Direct.cs
new file mode 100644
index 0000000..fd0cfe6
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Gameplay/AmxModx.Bridge.HamSandwich.Direct.cs
@@ -0,0 +1,146 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace AmxModx.Bridge.HamSandwich.Direct
+{
+ ///
+ /// Ham Sandwich模块的直接桥接接口 - 不依赖AMXX函数
+ /// 直接操作底层内存和实体数据
+ ///
+ public static class NativeDirectBridge
+ {
+ private const string DllName = "hamsandwich_amxx";
+
+ // 实体验证
+ ///
+ /// 验证实体ID是否有效
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern bool IsValidEntity(int entityId);
+
+ ///
+ /// 验证偏移量是否有效
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern bool IsValidOffset(int offset);
+
+ // 直接数据访问
+ ///
+ /// 获取实体私有数据的整型值
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetEntityPrivateDataInt(int entityId, int offset);
+
+ ///
+ /// 获取实体私有数据的浮点值
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern float GetEntityPrivateDataFloat(int entityId, int offset);
+
+ ///
+ /// 获取实体私有数据的实体引用
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetEntityPrivateDataEntity(int entityId, int offset);
+
+ ///
+ /// 设置实体私有数据的整型值
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void SetEntityPrivateDataInt(int entityId, int offset, int value);
+
+ ///
+ /// 设置实体私有数据的浮点值
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void SetEntityPrivateDataFloat(int entityId, int offset, float value);
+
+ ///
+ /// 设置实体私有数据的实体引用
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void SetEntityPrivateDataEntity(int entityId, int offset, int targetEntity);
+
+ // 向量数据访问
+ ///
+ /// 获取实体私有数据的向量值
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void GetEntityPrivateDataVector(int entityId, int offset, [Out] float[] vec);
+
+ ///
+ /// 设置实体私有数据的向量值
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void SetEntityPrivateDataVector(int entityId, int offset, float[] vec);
+
+ // 实体变量访问
+ ///
+ /// 获取实体变量的整型值
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetEntityVarInt(int entityId, int offset);
+
+ ///
+ /// 获取实体变量的浮点值
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern float GetEntityVarFloat(int entityId, int offset);
+
+ ///
+ /// 获取实体变量的向量值
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void GetEntityVarVector(int entityId, int offset, [Out] float[] vec);
+
+ ///
+ /// 设置实体变量的整型值
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void SetEntityVarInt(int entityId, int offset, int value);
+
+ ///
+ /// 设置实体变量的浮点值
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void SetEntityVarFloat(int entityId, int offset, float value);
+
+ ///
+ /// 设置实体变量的向量值
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void SetEntityVarVector(int entityId, int offset, float[] vec);
+
+ // 内存工具
+ ///
+ /// 获取实体基础内存指针
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr GetEntityBasePointer(int entityId);
+
+ ///
+ /// 获取实体内存大小
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetEntityMemorySize(int entityId);
+
+ ///
+ /// 将实体指针转换为索引
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int EntityToIndex(IntPtr edict);
+
+ ///
+ /// 将索引转换为实体指针
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr IndexToEntity(int index);
+
+ ///
+ /// 获取私有数据指针
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr GetPrivateDataPtr(int entityId);
+ }
+
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/Gameplay/AmxModx.Bridge.NewMenus.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Gameplay/AmxModx.Bridge.NewMenus.cs
new file mode 100644
index 0000000..736b24b
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/Gameplay/AmxModx.Bridge.NewMenus.cs
@@ -0,0 +1,321 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace AmxModx.Bridge.NewMenus
+{
+ ///
+ /// 新菜单系统桥接接口
+ ///
+ public static class NewMenuBridge
+ {
+ private const string DllName = "amxmodx_mm";
+
+ ///
+ /// 菜单属性类型
+ ///
+ public enum MenuProperty
+ {
+ PER_PAGE = 0,
+ EXIT = 1,
+ BACK = 2,
+ NEXT = 3,
+ TITLE = 4,
+ EXITBUTTON = 5,
+ NOVOTE = 6,
+ NOMORE = 7,
+ TIME = 8,
+ KEYS = 9
+ }
+
+ ///
+ /// 菜单选项类型
+ ///
+ public enum MenuItemType
+ {
+ NORMAL = 0,
+ BLANK = 1,
+ TEXT = 2,
+ SPACER = 3
+ }
+
+ ///
+ /// 创建新菜单
+ ///
+ /// 菜单标题
+ /// 页面回调
+ /// 退出回调
+ /// 返回回调
+ /// 下一页回调
+ /// 菜单句柄
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_MenuCreate(
+ [MarshalAs(UnmanagedType.LPStr)] string title,
+ IntPtr pageCallback,
+ IntPtr exitCallback,
+ IntPtr backCallback,
+ IntPtr nextCallback);
+
+ ///
+ /// 销毁菜单
+ ///
+ /// 菜单句柄
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_MenuDestroy(int menu);
+
+ ///
+ /// 添加菜单项
+ ///
+ /// 菜单句柄
+ /// 菜单文本
+ /// 回调函数
+ /// 附加信息
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_MenuAddItem(
+ int menu,
+ [MarshalAs(UnmanagedType.LPStr)] string text,
+ IntPtr callback,
+ [MarshalAs(UnmanagedType.LPStr)] string info);
+
+ ///
+ /// 添加空白菜单项
+ ///
+ /// 菜单句柄
+ /// 回调函数
+ /// 附加信息
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_MenuAddBlank(
+ int menu,
+ IntPtr callback,
+ [MarshalAs(UnmanagedType.LPStr)] string info);
+
+ ///
+ /// 添加文本菜单项
+ ///
+ /// 菜单句柄
+ /// 菜单文本
+ /// 回调函数
+ /// 附加信息
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_MenuAddText(
+ int menu,
+ [MarshalAs(UnmanagedType.LPStr)] string text,
+ IntPtr callback,
+ [MarshalAs(UnmanagedType.LPStr)] string info);
+
+ ///
+ /// 显示菜单给玩家
+ ///
+ /// 菜单句柄
+ /// 玩家索引
+ /// 页码
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_MenuDisplay(int menu, int player, int page);
+
+ ///
+ /// 设置菜单属性
+ ///
+ /// 菜单句柄
+ /// 属性类型
+ /// 属性值
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_MenuSetProperty(
+ int menu,
+ int prop,
+ int value);
+
+ ///
+ /// 获取菜单属性
+ ///
+ /// 菜单句柄
+ /// 属性类型
+ /// 属性值
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_MenuGetProperty(int menu, int prop);
+
+ ///
+ /// 获取菜单项信息
+ ///
+ /// 菜单句柄
+ /// 菜单项索引
+ /// 输出缓冲区
+ /// 缓冲区大小
+ /// 附加信息缓冲区
+ /// 附加信息缓冲区大小
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_MenuGetItemInfo(
+ int menu,
+ int item,
+ [MarshalAs(UnmanagedType.LPStr)] StringBuilder buffer,
+ int bufferSize,
+ [MarshalAs(UnmanagedType.LPStr)] StringBuilder info,
+ int infoSize);
+
+ ///
+ /// 获取菜单项数量
+ ///
+ /// 菜单句柄
+ /// 菜单项数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_MenuGetItems(int menu);
+
+ ///
+ /// 获取菜单页数
+ ///
+ /// 菜单句柄
+ /// 页数
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_MenuGetPages(int menu);
+
+ ///
+ /// 获取当前页菜单项数量
+ ///
+ /// 菜单句柄
+ /// 页码
+ /// 当前页菜单项数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_MenuGetPageItems(int menu, int page);
+
+ ///
+ /// 关闭玩家菜单
+ ///
+ /// 玩家索引
+ /// 是否成功
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_MenuClose(int player);
+
+ ///
+ /// 获取玩家当前菜单
+ ///
+ /// 玩家索引
+ /// 菜单句柄
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetPlayerMenu(int player);
+
+ ///
+ /// 获取玩家菜单页
+ ///
+ /// 玩家索引
+ /// 当前页码
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetPlayerMenuPage(int player);
+
+ ///
+ /// 菜单管理器包装类
+ ///
+ public static class MenuManager
+ {
+ ///
+ /// 创建新菜单
+ ///
+ public static int CreateMenu(string title)
+ {
+ return AmxModx_Bridge_MenuCreate(title, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
+ }
+
+ ///
+ /// 创建带回调的菜单
+ ///
+ public static int CreateMenu(
+ string title,
+ IntPtr pageCallback = default,
+ IntPtr exitCallback = default,
+ IntPtr backCallback = default,
+ IntPtr nextCallback = default)
+ {
+ return AmxModx_Bridge_MenuCreate(title, pageCallback, exitCallback, backCallback, nextCallback);
+ }
+
+ ///
+ /// 添加菜单项
+ ///
+ public static bool AddMenuItem(int menu, string text, IntPtr callback = default, string info = "")
+ {
+ return AmxModx_Bridge_MenuAddItem(menu, text, callback, info) != 0;
+ }
+
+ ///
+ /// 添加空白菜单项
+ ///
+ public static bool AddBlankItem(int menu, IntPtr callback = default, string info = "")
+ {
+ return AmxModx_Bridge_MenuAddBlank(menu, callback, info) != 0;
+ }
+
+ ///
+ /// 添加文本菜单项
+ ///
+ public static bool AddTextItem(int menu, string text, IntPtr callback = default, string info = "")
+ {
+ return AmxModx_Bridge_MenuAddText(menu, text, callback, info) != 0;
+ }
+
+ ///
+ /// 显示菜单给玩家
+ ///
+ public static bool DisplayMenu(int menu, int player, int page = 0)
+ {
+ return AmxModx_Bridge_MenuDisplay(menu, player, page) != 0;
+ }
+
+ ///
+ /// 设置菜单每页显示数量
+ ///
+ public static bool SetItemsPerPage(int menu, int count)
+ {
+ return AmxModx_Bridge_MenuSetProperty(menu, (int)MenuProperty.PER_PAGE, count) != 0;
+ }
+
+ ///
+ /// 设置菜单标题
+ ///
+ public static bool SetMenuTitle(int menu, string title)
+ {
+ return AmxModx_Bridge_MenuSetProperty(menu, (int)MenuProperty.TITLE, 0) != 0;
+ }
+
+ ///
+ /// 获取菜单信息
+ ///
+ public static string GetMenuItemText(int menu, int item)
+ {
+ var buffer = new StringBuilder(256);
+ var info = new StringBuilder(256);
+ if (AmxModx_Bridge_MenuGetItemInfo(menu, item, buffer, buffer.Capacity, info, info.Capacity) != 0)
+ {
+ return buffer.ToString();
+ }
+ return string.Empty;
+ }
+
+ ///
+ /// 获取菜单项信息
+ ///
+ public static (string text, string info) GetMenuItemInfo(int menu, int item)
+ {
+ var buffer = new StringBuilder(256);
+ var info = new StringBuilder(256);
+ if (AmxModx_Bridge_MenuGetItemInfo(menu, item, buffer, buffer.Capacity, info, info.Capacity) != 0)
+ {
+ return (buffer.ToString(), info.ToString());
+ }
+ return (string.Empty, string.Empty);
+ }
+
+ ///
+ /// 销毁菜单
+ ///
+ public static bool DestroyMenu(int menu)
+ {
+ return AmxModx_Bridge_MenuDestroy(menu) != 0;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Command.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Command.cs
new file mode 100644
index 0000000..7de8d0c
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Command.cs
@@ -0,0 +1,193 @@
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace AmxModx.Bridge.Command
+{
+ ///
+ /// 命令类型枚举
+ ///
+ public enum CommandType
+ {
+ ///
+ /// 控制台命令
+ ///
+ Console = 0,
+
+ ///
+ /// 客户端命令
+ ///
+ Client = 1,
+
+ ///
+ /// 服务器命令
+ ///
+ Server = 2
+ }
+
+ ///
+ /// 命令标志位
+ ///
+ [Flags]
+ public enum CommandFlags
+ {
+ ///
+ /// 管理员命令
+ ///
+ Admin = 1,
+
+ ///
+ /// RCON命令
+ ///
+ Rcon = 2,
+
+ ///
+ /// 公共命令
+ ///
+ Public = 4,
+
+ ///
+ /// 隐藏命令
+ ///
+ Hidden = 8
+ }
+
+ ///
+ /// 命令信息结构
+ ///
+ public struct CommandInfo
+ {
+ ///
+ /// 命令名称
+ ///
+ public string Command;
+
+ ///
+ /// 命令描述
+ ///
+ public string Info;
+
+ ///
+ /// 命令标志位
+ ///
+ public CommandFlags Flags;
+ }
+
+ ///
+ /// 命令系统P/Invoke接口
+ ///
+ public static class CommandBridge
+ {
+ private const string DllName = "amxmodx_mm";
+
+ ///
+ /// 注册控制台命令
+ ///
+ /// 插件ID
+ /// 函数ID
+ /// 命令名称
+ /// 命令描述
+ /// 命令标志位
+ /// 是否可列出
+ /// 成功返回1,失败返回0
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_RegisterConsoleCommand(
+ int pluginId,
+ int funcId,
+ [MarshalAs(UnmanagedType.LPStr)] string cmd,
+ [MarshalAs(UnmanagedType.LPStr)] string info,
+ int flags,
+ [MarshalAs(UnmanagedType.Bool)] bool listable);
+
+ ///
+ /// 注册客户端命令
+ ///
+ /// 插件ID
+ /// 函数ID
+ /// 命令名称
+ /// 命令描述
+ /// 命令标志位
+ /// 是否可列出
+ /// 成功返回1,失败返回0
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_RegisterClientCommand(
+ int pluginId,
+ int funcId,
+ [MarshalAs(UnmanagedType.LPStr)] string cmd,
+ [MarshalAs(UnmanagedType.LPStr)] string info,
+ int flags,
+ [MarshalAs(UnmanagedType.Bool)] bool listable);
+
+ ///
+ /// 注册服务器命令
+ ///
+ /// 插件ID
+ /// 函数ID
+ /// 命令名称
+ /// 命令描述
+ /// 命令标志位
+ /// 是否可列出
+ /// 成功返回1,失败返回0
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_RegisterServerCommand(
+ int pluginId,
+ int funcId,
+ [MarshalAs(UnmanagedType.LPStr)] string cmd,
+ [MarshalAs(UnmanagedType.LPStr)] string info,
+ int flags,
+ [MarshalAs(UnmanagedType.Bool)] bool listable);
+
+ ///
+ /// 获取命令数量
+ ///
+ /// 命令类型
+ /// 访问级别
+ /// 命令数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetCommandCount(int type, int access);
+
+ ///
+ /// 执行控制台命令
+ ///
+ /// 命令字符串
+ /// 成功返回1,失败返回0
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ExecuteConsoleCommand([MarshalAs(UnmanagedType.LPStr)] string cmd);
+
+ ///
+ /// 执行客户端命令
+ ///
+ /// 玩家ID
+ /// 命令字符串
+ /// 成功返回1,失败返回0
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ExecuteClientCommand(int playerId, [MarshalAs(UnmanagedType.LPStr)] string cmd);
+
+ ///
+ /// 执行服务器命令
+ ///
+ /// 命令字符串
+ /// 成功返回1,失败返回0
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ExecuteServerCommand([MarshalAs(UnmanagedType.LPStr)] string cmd);
+
+ ///
+ /// 检查命令是否存在
+ ///
+ /// 命令类型
+ /// 命令名称
+ /// 存在返回true,否则返回false
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_CommandExists(int type, [MarshalAs(UnmanagedType.LPStr)] string cmd);
+
+ ///
+ /// 移除命令
+ ///
+ /// 插件ID
+ /// 命令名称
+ /// 移除的命令数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_RemoveCommands(int pluginId, [MarshalAs(UnmanagedType.LPStr)] string cmd);
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.CommandSystem.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.CommandSystem.cs
new file mode 100644
index 0000000..67e8ba3
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.CommandSystem.cs
@@ -0,0 +1,438 @@
+// vim: set ts=4 sw=4 tw=99 noet:
+//
+// AMX Mod X Command System Bridge for C#
+// Copyright (C) The AMX Mod X Development Team.
+//
+// This software is licensed under the GNU General Public License, version 3 or higher.
+// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
+// https://alliedmods.net/amxmodx-license
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+using System.Text;
+
+namespace AmxModx.Bridge.CommandSystem
+{
+ ///
+ /// 命令类型枚举
+ ///
+ public enum CommandType
+ {
+ Console = 0, // 控制台命令
+ Client = 1, // 客户端命令
+ Server = 2 // 服务器命令
+ }
+
+ ///
+ /// 命令标志位枚举
+ ///
+ [Flags]
+ public enum CommandFlags
+ {
+ None = 0, // 无标志
+ Admin = 1, // 管理员命令
+ Rcon = 2, // RCON命令
+ Public = 4, // 公共命令
+ Hidden = 8 // 隐藏命令
+ }
+
+ ///
+ /// 命令信息结构体
+ ///
+ public struct CommandInfo
+ {
+ public string Name;
+ public string Description;
+ public CommandType Type;
+ public CommandFlags Flags;
+ public bool IsListable;
+ }
+
+ ///
+ /// 命令回调委托
+ ///
+ /// 玩家ID(-1表示控制台/服务器)
+ /// 命令参数
+ public delegate void CommandHandler(int playerId, string[] args);
+
+ ///
+ /// 命令系统桥接接口
+ ///
+ public static class CommandBridge
+ {
+ private const string DllName = "amxmodx_mm";
+
+ #region P/Invoke接口定义
+
+ ///
+ /// 注册控制台命令
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_RegisterConsoleCommand(
+ int pluginId,
+ int funcId,
+ [MarshalAs(UnmanagedType.LPStr)] string cmd,
+ [MarshalAs(UnmanagedType.LPStr)] string info,
+ int flags,
+ [MarshalAs(UnmanagedType.Bool)] bool listable);
+
+ ///
+ /// 注册客户端命令
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_RegisterClientCommand(
+ int pluginId,
+ int funcId,
+ [MarshalAs(UnmanagedType.LPStr)] string cmd,
+ [MarshalAs(UnmanagedType.LPStr)] string info,
+ int flags,
+ [MarshalAs(UnmanagedType.Bool)] bool listable);
+
+ ///
+ /// 注册服务器命令
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_RegisterServerCommand(
+ int pluginId,
+ int funcId,
+ [MarshalAs(UnmanagedType.LPStr)] string cmd,
+ [MarshalAs(UnmanagedType.LPStr)] string info,
+ int flags,
+ [MarshalAs(UnmanagedType.Bool)] bool listable);
+
+ ///
+ /// 获取命令数量
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetCommandCount(int type, int access);
+
+ ///
+ /// 获取命令信息
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetCommandInfo(
+ int type,
+ int index,
+ int access,
+ [Out] byte[] cmd,
+ int cmdSize,
+ [Out] byte[] info,
+ int infoSize,
+ out int flags);
+
+ ///
+ /// 执行控制台命令
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ExecuteConsoleCommand([MarshalAs(UnmanagedType.LPStr)] string cmd);
+
+ ///
+ /// 执行客户端命令
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ExecuteClientCommand(
+ int playerId,
+ [MarshalAs(UnmanagedType.LPStr)] string cmd);
+
+ ///
+ /// 执行服务器命令
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ExecuteServerCommand([MarshalAs(UnmanagedType.LPStr)] string cmd);
+
+ ///
+ /// 检查命令是否存在
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_CommandExists(int type, [MarshalAs(UnmanagedType.LPStr)] string cmd);
+
+ ///
+ /// 移除命令
+ ///
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_RemoveCommands(int pluginId, [MarshalAs(UnmanagedType.LPStr)] string cmd);
+
+ #endregion
+ }
+
+ ///
+ /// 命令管理器,提供高级命令管理功能
+ ///
+ public static class CommandManager
+ {
+ private static readonly Dictionary _handlers = new Dictionary();
+ private static int _pluginId = 1; // 默认插件ID
+
+ #region 命令注册
+
+ ///
+ /// 设置插件ID
+ ///
+ public static void SetPluginId(int pluginId)
+ {
+ _pluginId = pluginId;
+ }
+
+ ///
+ /// 注册控制台命令
+ ///
+ /// 命令名称
+ /// 命令描述
+ /// 命令处理器
+ /// 命令标志
+ /// 是否可列出
+ public static bool RegisterConsoleCommand(
+ string command,
+ string description,
+ CommandHandler handler,
+ CommandFlags flags = CommandFlags.Public,
+ bool listable = true)
+ {
+ if (string.IsNullOrEmpty(command) || handler == null)
+ return false;
+
+ int funcId = _handlers.Count + 1;
+ int result = CommandBridge.AmxModx_Bridge_RegisterConsoleCommand(
+ _pluginId,
+ funcId,
+ command,
+ description,
+ (int)flags,
+ listable);
+
+ if (result != 0)
+ {
+ _handlers[command] = handler;
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// 注册客户端命令
+ ///
+ /// 命令名称
+ /// 命令描述
+ /// 命令处理器
+ /// 命令标志
+ /// 是否可列出
+ public static bool RegisterClientCommand(
+ string command,
+ string description,
+ CommandHandler handler,
+ CommandFlags flags = CommandFlags.Public,
+ bool listable = true)
+ {
+ if (string.IsNullOrEmpty(command) || handler == null)
+ return false;
+
+ int funcId = _handlers.Count + 1;
+ int result = CommandBridge.AmxModx_Bridge_RegisterClientCommand(
+ _pluginId,
+ funcId,
+ command,
+ description,
+ (int)flags,
+ listable);
+
+ if (result != 0)
+ {
+ _handlers[command] = handler;
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// 注册服务器命令
+ ///
+ /// 命令名称
+ /// 命令描述
+ /// 命令处理器
+ /// 命令标志
+ /// 是否可列出
+ public static bool RegisterServerCommand(
+ string command,
+ string description,
+ CommandHandler handler,
+ CommandFlags flags = CommandFlags.Public,
+ bool listable = true)
+ {
+ if (string.IsNullOrEmpty(command) || handler == null)
+ return false;
+
+ int funcId = _handlers.Count + 1;
+ int result = CommandBridge.AmxModx_Bridge_RegisterServerCommand(
+ _pluginId,
+ funcId,
+ command,
+ description,
+ (int)flags,
+ listable);
+
+ if (result != 0)
+ {
+ _handlers[command] = handler;
+ return true;
+ }
+ return false;
+ }
+
+ #endregion
+
+ #region 命令执行
+
+ ///
+ /// 执行控制台命令
+ ///
+ public static bool ExecuteConsoleCommand(string command)
+ {
+ if (string.IsNullOrEmpty(command))
+ return false;
+
+ return CommandBridge.AmxModx_Bridge_ExecuteConsoleCommand(command) != 0;
+ }
+
+ ///
+ /// 执行客户端命令
+ ///
+ public static bool ExecuteClientCommand(int playerId, string command)
+ {
+ if (string.IsNullOrEmpty(command) || playerId <= 0)
+ return false;
+
+ return CommandBridge.AmxModx_Bridge_ExecuteClientCommand(playerId, command) != 0;
+ }
+
+ ///
+ /// 执行服务器命令
+ ///
+ public static bool ExecuteServerCommand(string command)
+ {
+ if (string.IsNullOrEmpty(command))
+ return false;
+
+ return CommandBridge.AmxModx_Bridge_ExecuteServerCommand(command) != 0;
+ }
+
+ #endregion
+
+ #region 命令查询
+
+ ///
+ /// 获取命令数量
+ ///
+ public static int GetCommandCount(CommandType type, int access = 0)
+ {
+ return CommandBridge.AmxModx_Bridge_GetCommandCount((int)type, access);
+ }
+
+ ///
+ /// 获取所有命令信息
+ ///
+ public static List GetAllCommands(CommandType type, int access = 0)
+ {
+ var commands = new List();
+ int count = GetCommandCount(type, access);
+
+ for (int i = 0; i < count; i++)
+ {
+ var cmdBuffer = new byte[64];
+ var infoBuffer = new byte[256];
+ int flags;
+
+ if (CommandBridge.AmxModx_Bridge_GetCommandInfo(
+ (int)type, i, access, cmdBuffer, cmdBuffer.Length,
+ infoBuffer, infoBuffer.Length, out flags) != 0)
+ {
+ string cmdName = Encoding.UTF8.GetString(cmdBuffer).TrimEnd('\0');
+ string cmdInfo = Encoding.UTF8.GetString(infoBuffer).TrimEnd('\0');
+
+ commands.Add(new CommandInfo
+ {
+ Name = cmdName,
+ Description = cmdInfo,
+ Type = type,
+ Flags = (CommandFlags)flags
+ });
+ }
+ }
+
+ return commands;
+ }
+
+ ///
+ /// 检查命令是否存在
+ ///
+ public static bool CommandExists(CommandType type, string command)
+ {
+ if (string.IsNullOrEmpty(command))
+ return false;
+
+ return CommandBridge.AmxModx_Bridge_CommandExists((int)type, command);
+ }
+
+ #endregion
+
+ #region 命令移除
+
+ ///
+ /// 移除指定命令
+ ///
+ public static int RemoveCommands(string command)
+ {
+ if (string.IsNullOrEmpty(command))
+ return 0;
+
+ return CommandBridge.AmxModx_Bridge_RemoveCommands(_pluginId, command);
+ }
+
+ ///
+ /// 移除所有命令
+ ///
+ public static int RemoveAllCommands()
+ {
+ return CommandBridge.AmxModx_Bridge_RemoveCommands(_pluginId, null);
+ }
+
+ #endregion
+
+ #region 快捷方法
+
+ ///
+ /// 向所有玩家发送消息
+ ///
+ public static bool BroadcastMessage(string message)
+ {
+ return ExecuteServerCommand($"say {message}");
+ }
+
+ ///
+ /// 向指定玩家发送消息
+ ///
+ public static bool SendMessageToPlayer(int playerId, string message)
+ {
+ return ExecuteClientCommand(playerId, $"say {message}");
+ }
+
+ ///
+ /// 踢出玩家
+ ///
+ public static bool KickPlayer(int playerId, string reason = "")
+ {
+ return ExecuteServerCommand($"kick #{playerId} {reason}");
+ }
+
+ ///
+ /// 更改地图
+ ///
+ public static bool ChangeMap(string mapName)
+ {
+ return ExecuteServerCommand($"changelevel {mapName}");
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Core.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Core.cs
new file mode 100644
index 0000000..23c6a18
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Core.cs
@@ -0,0 +1,145 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace AmxModx.Bridge.Core
+{
+ ///
+ /// AMX Mod X核心桥接接口
+ /// 提供amxcore.cpp中核心功能的C#访问
+ ///
+ public static class CoreBridge
+ {
+ ///
+ /// 获取当前函数的参数数量
+ ///
+ /// 参数数量
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetNumArgs();
+
+ ///
+ /// 获取指定索引的参数值
+ ///
+ /// 参数索引(从0开始)
+ /// 数组偏移量(对于数组参数)
+ /// 参数值
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetArg(int index, int offset);
+
+ ///
+ /// 设置指定索引的参数值
+ ///
+ /// 参数索引(从0开始)
+ /// 数组偏移量(对于数组参数)
+ /// 要设置的值
+ /// 成功返回true,失败返回false
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_SetArg(int index, int offset, int value);
+
+ ///
+ /// 获取可用堆空间大小
+ ///
+ /// 堆空间字节数
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetHeapSpace();
+
+ ///
+ /// 根据函数名获取函数索引
+ ///
+ /// 函数名称
+ /// 函数索引,-1表示未找到
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetFunctionIndex([MarshalAs(UnmanagedType.LPStr)] string functionName);
+
+ ///
+ /// 交换32位整数的字节顺序
+ ///
+ /// 要交换的值
+ /// 交换后的值
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_SwapChars(int value);
+
+ ///
+ /// 获取属性值
+ ///
+ /// 属性ID
+ /// 属性名称
+ /// 属性值
+ /// 输出缓冲区
+ /// 缓冲区最大长度
+ /// 属性值
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetProperty(int id, [MarshalAs(UnmanagedType.LPStr)] string name, int value, [Out] StringBuilder buffer, int maxLen);
+
+ ///
+ /// 设置属性值
+ ///
+ /// 属性ID
+ /// 属性名称
+ /// 属性值
+ /// 新属性名称(可选)
+ /// 之前的属性值
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_SetProperty(int id, [MarshalAs(UnmanagedType.LPStr)] string name, int value, [MarshalAs(UnmanagedType.LPStr)] string newName);
+
+ ///
+ /// 删除属性
+ ///
+ /// 属性ID
+ /// 属性名称
+ /// 属性值
+ /// 被删除的属性值
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_DeleteProperty(int id, [MarshalAs(UnmanagedType.LPStr)] string name, int value);
+
+ ///
+ /// 检查属性是否存在
+ ///
+ /// 属性ID
+ /// 属性名称
+ /// 属性值
+ /// 存在返回true,不存在返回false
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_PropertyExists(int id, [MarshalAs(UnmanagedType.LPStr)] string name, int value);
+
+ ///
+ /// 安全的获取属性值方法
+ ///
+ /// 属性ID
+ /// 属性名称
+ /// 属性值
+ /// 属性值和名称
+ public static (int value, string name) GetPropertySafe(int id, string name, int value)
+ {
+ StringBuilder buffer = new StringBuilder(256);
+ int result = AmxModx_Bridge_GetProperty(id, name, value, buffer, buffer.Capacity);
+ return (result, buffer.ToString());
+ }
+
+ ///
+ /// 安全的设置属性值方法
+ ///
+ /// 属性ID
+ /// 属性名称
+ /// 属性值
+ /// 之前的属性值
+ public static int SetPropertySafe(int id, string name, int value)
+ {
+ return AmxModx_Bridge_SetProperty(id, name, value, null);
+ }
+
+ ///
+ /// 安全的删除属性方法
+ ///
+ /// 属性ID
+ /// 属性名称
+ /// 属性值
+ /// 被删除的属性值
+ public static int DeletePropertySafe(int id, string name, int value)
+ {
+ return AmxModx_Bridge_DeleteProperty(id, name, value);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Debugger.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Debugger.cs
new file mode 100644
index 0000000..6d7072f
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Debugger.cs
@@ -0,0 +1,139 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace AmxModx.Bridge.Debugger
+{
+ ///
+ /// 调试器桥接接口,提供调试相关功能
+ ///
+ public static class DebuggerBridge
+ {
+ private const string NativeLibrary = "amxmodx_mm";
+
+ #region 调试器操作
+
+ ///
+ /// 设置错误过滤器
+ ///
+ /// 过滤器类型 (0=全部, 1=警告, 2=错误)
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_SetErrorFilter(int filter);
+
+ ///
+ /// 记录调试信息
+ ///
+ /// 调试信息
+ /// 日志级别 (0=调试, 1=信息, 2=警告, 3=错误)
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_LogDebug([MarshalAs(UnmanagedType.LPStr)] string message, int level);
+
+ ///
+ /// 获取最后错误信息
+ ///
+ /// 错误信息字符串
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_GetLastError();
+
+ ///
+ /// 清除最后错误信息
+ ///
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_ClearLastError();
+
+ ///
+ /// 启用/禁用调试模式
+ ///
+ /// 是否启用
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_SetDebugMode([MarshalAs(UnmanagedType.I1)] bool enabled);
+
+ ///
+ /// 检查是否处于调试模式
+ ///
+ /// 是否处于调试模式
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ public static extern bool AmxModx_Bridge_IsDebugMode();
+
+ ///
+ /// 设置断点
+ ///
+ /// 文件名
+ /// 行号
+ /// 设置是否成功
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ public static extern bool AmxModx_Bridge_SetBreakpoint([MarshalAs(UnmanagedType.LPStr)] string file, int line);
+
+ ///
+ /// 移除断点
+ ///
+ /// 文件名
+ /// 行号
+ /// 移除是否成功
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ public static extern bool AmxModx_Bridge_RemoveBreakpoint([MarshalAs(UnmanagedType.LPStr)] string file, int line);
+
+ ///
+ /// 获取当前调用栈信息
+ ///
+ /// 输出缓冲区
+ /// 缓冲区大小
+ /// 调用栈信息长度
+ [DllImport(NativeLibrary, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetCallStack([Out, MarshalAs(UnmanagedType.LPArray)] byte[] buffer, int bufferSize);
+
+ #endregion
+
+ #region 便捷方法
+
+ ///
+ /// 获取最后错误信息的安全封装
+ ///
+ /// 错误信息字符串
+ public static string GetLastErrorSafe()
+ {
+ IntPtr ptr = AmxModx_Bridge_GetLastError();
+ return ptr != IntPtr.Zero ? Marshal.PtrToStringAnsi(ptr) : string.Empty;
+ }
+
+ ///
+ /// 获取当前调用栈信息的安全封装
+ ///
+ /// 调用栈信息字符串
+ public static string GetCallStackSafe()
+ {
+ byte[] buffer = new byte[1024];
+ int length = AmxModx_Bridge_GetCallStack(buffer, buffer.Length);
+ return length > 0 ? Encoding.ASCII.GetString(buffer, 0, length) : string.Empty;
+ }
+
+ ///
+ /// 记录调试信息
+ ///
+ /// 调试信息
+ /// 日志级别
+ public static void LogDebugSafe(string message, LogLevel level = LogLevel.Info)
+ {
+ if (!string.IsNullOrEmpty(message))
+ {
+ AmxModx_Bridge_LogDebug(message, (int)level);
+ }
+ }
+
+ #endregion
+ }
+
+ ///
+ /// 日志级别枚举
+ ///
+ public enum LogLevel
+ {
+ Debug = 0,
+ Info = 1,
+ Warning = 2,
+ Error = 3
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Logging.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Logging.cs
new file mode 100644
index 0000000..4fcb790
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Logging.cs
@@ -0,0 +1,252 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace AmxModx.Bridge.System
+{
+ ///
+ /// 日志级别枚举
+ ///
+ public enum LogLevel
+ {
+ /// 调试日志
+ Debug = 0,
+ /// 信息日志
+ Info = 1,
+ /// 警告日志
+ Warning = 2,
+ /// 错误日志
+ Error = 3,
+ /// 致命错误
+ Fatal = 4
+ }
+
+ ///
+ /// 日志目标枚举
+ ///
+ public enum LogTarget
+ {
+ /// 控制台
+ Console = 0,
+ /// 日志文件
+ File = 1,
+ /// 游戏聊天
+ Chat = 2,
+ /// 所有目标
+ All = 3
+ }
+
+ ///
+ /// 日志系统桥接接口
+ /// 提供AMX Mod X日志系统的C#访问
+ ///
+ public static class LoggingBridge
+ {
+ private const string DllName = "amxmodx_mm";
+
+ ///
+ /// 记录日志消息
+ ///
+ /// 日志级别
+ /// 日志消息
+ /// 是否成功记录
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_LogMessage(
+ LogLevel level,
+ [MarshalAs(UnmanagedType.LPStr)] string message);
+
+ ///
+ /// 记录格式化日志消息
+ ///
+ /// 日志级别
+ /// 格式化字符串
+ /// 参数数组
+ /// 是否成功记录
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_LogFormat(
+ LogLevel level,
+ [MarshalAs(UnmanagedType.LPStr)] string format,
+ [MarshalAs(UnmanagedType.LPArray)] object[] args,
+ int argCount);
+
+ ///
+ /// 记录日志到指定目标
+ ///
+ /// 日志级别
+ /// 日志目标
+ /// 日志消息
+ /// 是否成功记录
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_LogToTarget(
+ LogLevel level,
+ LogTarget target,
+ [MarshalAs(UnmanagedType.LPStr)] string message);
+
+ ///
+ /// 设置日志级别
+ ///
+ /// 日志级别
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_SetLogLevel(LogLevel level);
+
+ ///
+ /// 获取当前日志级别
+ ///
+ /// 当前日志级别
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern LogLevel AmxModx_Bridge_GetLogLevel();
+
+ ///
+ /// 启用/禁用日志目标
+ ///
+ /// 日志目标
+ /// 是否启用
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_SetLogTargetEnabled(
+ LogTarget target,
+ [MarshalAs(UnmanagedType.Bool)] bool enabled);
+
+ ///
+ /// 检查日志目标是否启用
+ ///
+ /// 日志目标
+ /// 是否启用
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_IsLogTargetEnabled(LogTarget target);
+
+ ///
+ /// 设置日志文件路径
+ ///
+ /// 日志文件路径
+ /// 是否成功设置
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_SetLogFilePath([MarshalAs(UnmanagedType.LPStr)] string filePath);
+
+ ///
+ /// 获取日志文件路径
+ ///
+ /// 路径缓冲区
+ /// 缓冲区大小
+ /// 实际路径长度
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetLogFilePath(
+ [Out] StringBuilder buffer,
+ int bufferSize);
+
+ ///
+ /// 清空日志文件
+ ///
+ /// 是否成功清空
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_ClearLogFile();
+
+ ///
+ /// 获取日志文件大小
+ ///
+ /// 文件大小(字节)
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern long AmxModx_Bridge_GetLogFileSize();
+
+ ///
+ /// 安全的记录日志消息
+ ///
+ /// 日志级别
+ /// 日志消息
+ /// 是否成功记录
+ public static bool LogMessageSafe(LogLevel level, string message)
+ {
+ if (string.IsNullOrEmpty(message))
+ return false;
+
+ return AmxModx_Bridge_LogMessage(level, message);
+ }
+
+ ///
+ /// 安全的记录格式化日志消息
+ ///
+ /// 日志级别
+ /// 格式化字符串
+ /// 参数数组
+ /// 是否成功记录
+ public static bool LogFormatSafe(LogLevel level, string format, params object[] args)
+ {
+ if (string.IsNullOrEmpty(format) || args == null)
+ return false;
+
+ return AmxModx_Bridge_LogFormat(level, format, args, args.Length);
+ }
+
+ ///
+ /// 获取日志文件路径
+ ///
+ /// 日志文件路径
+ public static string GetLogFilePathSafe()
+ {
+ StringBuilder pathBuilder = new StringBuilder(512);
+ int length = AmxModx_Bridge_GetLogFilePath(pathBuilder, pathBuilder.Capacity);
+
+ if (length > 0)
+ {
+ return pathBuilder.ToString();
+ }
+
+ return string.Empty;
+ }
+
+ ///
+ /// 记录调试日志
+ ///
+ /// 日志消息
+ /// 是否成功记录
+ public static bool LogDebug(string message)
+ {
+ return LogMessageSafe(LogLevel.Debug, message);
+ }
+
+ ///
+ /// 记录信息日志
+ ///
+ /// 日志消息
+ /// 是否成功记录
+ public static bool LogInfo(string message)
+ {
+ return LogMessageSafe(LogLevel.Info, message);
+ }
+
+ ///
+ /// 记录警告日志
+ ///
+ /// 日志消息
+ /// 是否成功记录
+ public static bool LogWarning(string message)
+ {
+ return LogMessageSafe(LogLevel.Warning, message);
+ }
+
+ ///
+ /// 记录错误日志
+ ///
+ /// 日志消息
+ /// 是否成功记录
+ public static bool LogError(string message)
+ {
+ return LogMessageSafe(LogLevel.Error, message);
+ }
+
+ ///
+ /// 记录致命错误日志
+ ///
+ /// 日志消息
+ /// 是否成功记录
+ public static bool LogFatal(string message)
+ {
+ return LogMessageSafe(LogLevel.Fatal, message);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Memory.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Memory.cs
new file mode 100644
index 0000000..f981403
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Memory.cs
@@ -0,0 +1,260 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace AmxModx.Bridge.System
+{
+ ///
+ /// 内存分配类型枚举
+ ///
+ public enum MemoryType
+ {
+ /// 临时内存
+ Temporary = 0,
+ /// 持久内存
+ Permanent = 1,
+ /// 插件内存
+ Plugin = 2,
+ /// 全局内存
+ Global = 3
+ }
+
+ ///
+ /// 内存保护类型枚举
+ ///
+ public enum MemoryProtection
+ {
+ /// 无保护
+ None = 0,
+ /// 只读
+ ReadOnly = 1,
+ /// 读写
+ ReadWrite = 2,
+ /// 执行
+ Execute = 4,
+ /// 读写执行
+ ReadWriteExecute = 6
+ }
+
+ ///
+ /// 内存系统桥接接口
+ /// 提供AMX Mod X内存管理的C#访问
+ ///
+ public static class MemoryBridge
+ {
+ private const string DllName = "amxmodx_mm";
+
+ ///
+ /// 分配内存
+ ///
+ /// 内存大小(字节)
+ /// 内存类型
+ /// 分配的内存指针
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_AllocateMemory(long size, MemoryType type);
+
+ ///
+ /// 释放内存
+ ///
+ /// 内存指针
+ /// 内存类型
+ /// 是否成功释放
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_FreeMemory(IntPtr ptr, MemoryType type);
+
+ ///
+ /// 重新分配内存
+ ///
+ /// 原内存指针
+ /// 新内存大小
+ /// 内存类型
+ /// 重新分配的内存指针
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_ReallocateMemory(IntPtr ptr, long newSize, MemoryType type);
+
+ ///
+ /// 获取内存大小
+ ///
+ /// 内存指针
+ /// 内存大小(字节)
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern long AmxModx_Bridge_GetMemorySize(IntPtr ptr);
+
+ ///
+ /// 设置内存保护
+ ///
+ /// 内存指针
+ /// 内存大小
+ /// 保护类型
+ /// 是否成功设置
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_SetMemoryProtection(
+ IntPtr ptr,
+ long size,
+ MemoryProtection protection);
+
+ ///
+ /// 获取内存保护类型
+ ///
+ /// 内存指针
+ /// 保护类型
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern MemoryProtection AmxModx_Bridge_GetMemoryProtection(IntPtr ptr);
+
+ ///
+ /// 复制内存
+ ///
+ /// 目标指针
+ /// 源指针
+ /// 复制大小
+ /// 是否成功复制
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_CopyMemory(IntPtr dest, IntPtr src, long size);
+
+ ///
+ /// 填充内存
+ ///
+ /// 内存指针
+ /// 填充值
+ /// 填充大小
+ /// 是否成功填充
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_FillMemory(IntPtr ptr, byte value, long size);
+
+ ///
+ /// 比较内存
+ ///
+ /// 第一个内存指针
+ /// 第二个内存指针
+ /// 比较大小
+ /// 比较结果(0表示相等)
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_CompareMemory(IntPtr ptr1, IntPtr ptr2, long size);
+
+ ///
+ /// 获取内存统计信息
+ ///
+ /// 总分配内存
+ /// 已使用内存
+ /// 空闲内存
+ /// 是否成功获取
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_GetMemoryStats(
+ out long totalAllocated,
+ out long totalUsed,
+ out long totalFree);
+
+ ///
+ /// 检查内存指针是否有效
+ ///
+ /// 内存指针
+ /// 是否有效
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_IsMemoryValid(IntPtr ptr);
+
+ ///
+ /// 获取内存类型
+ ///
+ /// 内存指针
+ /// 内存类型
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern MemoryType AmxModx_Bridge_GetMemoryType(IntPtr ptr);
+
+ ///
+ /// 安全的分配内存
+ ///
+ /// 内存大小(字节)
+ /// 内存类型
+ /// 分配的内存指针
+ public static IntPtr AllocateMemorySafe(long size, MemoryType type)
+ {
+ if (size <= 0)
+ return IntPtr.Zero;
+
+ return AmxModx_Bridge_AllocateMemory(size, type);
+ }
+
+ ///
+ /// 安全的释放内存
+ ///
+ /// 内存指针
+ /// 内存类型
+ /// 是否成功释放
+ public static bool FreeMemorySafe(IntPtr ptr, MemoryType type)
+ {
+ if (ptr == IntPtr.Zero)
+ return false;
+
+ return AmxModx_Bridge_FreeMemory(ptr, type);
+ }
+
+ ///
+ /// 安全的重新分配内存
+ ///
+ /// 原内存指针
+ /// 新内存大小
+ /// 内存类型
+ /// 重新分配的内存指针
+ public static IntPtr ReallocateMemorySafe(IntPtr ptr, long newSize, MemoryType type)
+ {
+ if (newSize <= 0)
+ return IntPtr.Zero;
+
+ return AmxModx_Bridge_ReallocateMemory(ptr, newSize, type);
+ }
+
+ ///
+ /// 获取内存统计信息
+ ///
+ /// 内存统计信息元组
+ public static (long totalAllocated, long totalUsed, long totalFree) GetMemoryStatsSafe()
+ {
+ bool success = AmxModx_Bridge_GetMemoryStats(
+ out long totalAllocated,
+ out long totalUsed,
+ out long totalFree);
+
+ if (success)
+ {
+ return (totalAllocated, totalUsed, totalFree);
+ }
+
+ return (0, 0, 0);
+ }
+
+ ///
+ /// 安全的复制内存
+ ///
+ /// 目标指针
+ /// 源指针
+ /// 复制大小
+ /// 是否成功复制
+ public static bool CopyMemorySafe(IntPtr dest, IntPtr src, long size)
+ {
+ if (dest == IntPtr.Zero || src == IntPtr.Zero || size <= 0)
+ return false;
+
+ return AmxModx_Bridge_CopyMemory(dest, src, size);
+ }
+
+ ///
+ /// 安全的填充内存
+ ///
+ /// 内存指针
+ /// 填充值
+ /// 填充大小
+ /// 是否成功填充
+ public static bool FillMemorySafe(IntPtr ptr, byte value, long size)
+ {
+ if (ptr == IntPtr.Zero || size <= 0)
+ return false;
+
+ return AmxModx_Bridge_FillMemory(ptr, value, size);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Natives.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Natives.cs
new file mode 100644
index 0000000..69f8548
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Natives.cs
@@ -0,0 +1,271 @@
+// vim: set ts=4 sw=4 tw=99 noet:
+using System;
+using System.Runtime.InteropServices;
+
+namespace AmxModx.Bridge.Natives
+{
+ ///
+ /// 原生函数样式枚举
+ ///
+ public enum NativeStyle
+ {
+ ///
+ /// 标准样式
+ ///
+ Default = 0,
+ ///
+ /// 引用参数
+ ///
+ ByRef = 1,
+ ///
+ /// 数组参数
+ ///
+ Array = 2,
+ ///
+ /// 可变参数
+ ///
+ VarArgs = 3
+ }
+
+ ///
+ /// 参数类型枚举
+ ///
+ public enum ParamType
+ {
+ ///
+ /// 单元格类型
+ ///
+ Cell = 1,
+ ///
+ /// 数组类型
+ ///
+ Array = 2,
+ ///
+ /// 引用类型
+ ///
+ ByRef = 3,
+ ///
+ /// 可变参数类型
+ ///
+ VarArg = 4
+ }
+
+ ///
+ /// 原生函数信息结构体
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ public struct NativeInfo
+ {
+ ///
+ /// 函数名称
+ ///
+ [MarshalAs(UnmanagedType.LPStr)]
+ public string Name;
+
+ ///
+ /// 函数指针
+ ///
+ public IntPtr Function;
+ }
+
+ ///
+ /// 原生函数委托
+ ///
+ /// AMX实例指针
+ /// 参数数组
+ /// 返回值
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate int NativeDelegate(IntPtr amx, IntPtr parameters);
+
+ ///
+ /// 原生函数桥接类
+ ///
+ public static class NativeBridge
+ {
+ ///
+ /// 注册原生函数
+ ///
+ /// AMX实例指针
+ /// 函数名称
+ /// 函数指针
+ /// 成功返回1,失败返回0
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_RegisterNative(IntPtr amx, [MarshalAs(UnmanagedType.LPStr)] string name, NativeDelegate func);
+
+ ///
+ /// 注销原生函数
+ ///
+ /// AMX实例指针
+ /// 函数名称
+ /// 成功返回1,失败返回0
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_UnregisterNative(IntPtr amx, [MarshalAs(UnmanagedType.LPStr)] string name);
+
+ ///
+ /// 注册库
+ ///
+ /// AMX实例指针
+ /// 库名称
+ /// 成功返回1,失败返回0
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_RegisterLibrary(IntPtr amx, [MarshalAs(UnmanagedType.LPStr)] string libname);
+
+ ///
+ /// 获取原生函数数量
+ ///
+ /// AMX实例指针
+ /// 函数数量
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetNativeCount(IntPtr amx);
+
+ ///
+ /// 获取原生函数名称
+ ///
+ /// AMX实例指针
+ /// 函数索引
+ /// 函数名称
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_GetNativeName(IntPtr amx, int index);
+
+ ///
+ /// 检查原生函数是否存在
+ ///
+ /// AMX实例指针
+ /// 函数名称
+ /// 存在返回true,不存在返回false
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_NativeExists(IntPtr amx, [MarshalAs(UnmanagedType.LPStr)] string name);
+
+ ///
+ /// 清除库
+ ///
+ /// AMX实例指针
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_ClearLibraries(IntPtr amx);
+
+ ///
+ /// 获取字符串参数
+ ///
+ /// AMX实例指针
+ /// 参数索引
+ /// 字符串长度输出
+ /// 字符串内容
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_GetString(IntPtr amx, int param, out int length);
+
+ ///
+ /// 设置字符串参数
+ ///
+ /// AMX实例指针
+ /// 参数索引
+ /// 字符串内容
+ /// 最大长度
+ /// 成功返回1,失败返回0
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_SetString(IntPtr amx, int param, [MarshalAs(UnmanagedType.LPStr)] string str, int maxlen);
+
+ ///
+ /// 获取参数值
+ ///
+ /// AMX实例指针
+ /// 参数索引
+ /// 参数值
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetParam(IntPtr amx, int index);
+
+ ///
+ /// 获取参数地址
+ ///
+ /// AMX实例指针
+ /// 参数索引
+ /// 参数地址
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_GetParamAddress(IntPtr amx, int index);
+
+ ///
+ /// 设置参数值
+ ///
+ /// AMX实例指针
+ /// 参数索引
+ /// 参数值
+ /// 成功返回1,失败返回0
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_SetParam(IntPtr amx, int index, int value);
+
+ ///
+ /// 获取浮点数参数
+ ///
+ /// AMX实例指针
+ /// 参数索引
+ /// 浮点数值
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern float AmxModx_Bridge_GetFloat(IntPtr amx, int index);
+
+ ///
+ /// 设置浮点数参数
+ ///
+ /// AMX实例指针
+ /// 参数索引
+ /// 浮点数值
+ /// 成功返回1,失败返回0
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_SetFloat(IntPtr amx, int index, float value);
+
+ ///
+ /// 获取数组参数
+ ///
+ /// AMX实例指针
+ /// 参数索引
+ /// 目标数组
+ /// 数组大小
+ /// 成功返回1,失败返回0
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetArray(IntPtr amx, int param, [Out] int[] dest, int size);
+
+ ///
+ /// 设置数组参数
+ ///
+ /// AMX实例指针
+ /// 参数索引
+ /// 源数组
+ /// 数组大小
+ /// 成功返回1,失败返回0
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_SetArray(IntPtr amx, int param, [In] int[] source, int size);
+
+ ///
+ /// 记录错误
+ ///
+ /// AMX实例指针
+ /// 错误代码
+ /// 错误消息
+ [DllImport("amxmodx_mm", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void AmxModx_Bridge_LogError(IntPtr amx, int err, [MarshalAs(UnmanagedType.LPStr)] string message);
+
+ ///
+ /// 安全获取原生函数名称
+ ///
+ /// AMX实例指针
+ /// 函数索引
+ /// 函数名称
+ public static string GetNativeNameSafe(IntPtr amx, int index)
+ {
+ IntPtr namePtr = AmxModx_Bridge_GetNativeName(amx, index);
+ return namePtr != IntPtr.Zero ? Marshal.PtrToStringAnsi(namePtr) : string.Empty;
+ }
+
+ ///
+ /// 安全获取字符串
+ ///
+ /// AMX实例指针
+ /// 参数索引
+ /// 字符串内容
+ public static string GetStringSafe(IntPtr amx, int param)
+ {
+ int length;
+ IntPtr strPtr = AmxModx_Bridge_GetString(amx, param, out length);
+ return strPtr != IntPtr.Zero ? Marshal.PtrToStringAnsi(strPtr, length) : string.Empty;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.String.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.String.cs
new file mode 100644
index 0000000..463d4a2
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.String.cs
@@ -0,0 +1,321 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace AmxModx.Bridge.System
+{
+ ///
+ /// 字符串编码枚举
+ ///
+ public enum StringEncoding
+ {
+ /// ASCII编码
+ Ascii = 0,
+ /// UTF-8编码
+ Utf8 = 1,
+ /// UTF-16编码
+ Utf16 = 2,
+ /// 本地编码
+ Local = 3
+ }
+
+ ///
+ /// 字符串系统桥接接口
+ /// 提供AMX Mod X字符串处理的C#访问
+ ///
+ public static class StringBridge
+ {
+ private const string DllName = "amxmodx_mm";
+
+ ///
+ /// 创建字符串
+ ///
+ /// 字符串内容
+ /// 编码类型
+ /// 字符串句柄
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_CreateString(
+ [MarshalAs(UnmanagedType.LPStr)] string text,
+ StringEncoding encoding);
+
+ ///
+ /// 销毁字符串
+ ///
+ /// 字符串句柄
+ /// 是否成功销毁
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_DestroyString(IntPtr handle);
+
+ ///
+ /// 获取字符串长度
+ ///
+ /// 字符串句柄
+ /// 字符串长度
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetStringLength(IntPtr handle);
+
+ ///
+ /// 获取字符串内容
+ ///
+ /// 字符串句柄
+ /// 内容缓冲区
+ /// 缓冲区大小
+ /// 编码类型
+ /// 实际内容长度
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetStringContent(
+ IntPtr handle,
+ [Out] StringBuilder buffer,
+ int bufferSize,
+ StringEncoding encoding);
+
+ ///
+ /// 设置字符串内容
+ ///
+ /// 字符串句柄
+ /// 新内容
+ /// 编码类型
+ /// 是否成功设置
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_SetStringContent(
+ IntPtr handle,
+ [MarshalAs(UnmanagedType.LPStr)] string text,
+ StringEncoding encoding);
+
+ ///
+ /// 字符串比较
+ ///
+ /// 第一个字符串句柄
+ /// 第二个字符串句柄
+ /// 是否区分大小写
+ /// 比较结果(0表示相等)
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_CompareStrings(
+ IntPtr handle1,
+ IntPtr handle2,
+ [MarshalAs(UnmanagedType.Bool)] bool caseSensitive);
+
+ ///
+ /// 字符串查找
+ ///
+ /// 字符串句柄
+ /// 子字符串
+ /// 起始位置
+ /// 是否区分大小写
+ /// 子字符串位置(-1表示未找到)
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_FindString(
+ IntPtr handle,
+ [MarshalAs(UnmanagedType.LPStr)] string subString,
+ int startIndex,
+ [MarshalAs(UnmanagedType.Bool)] bool caseSensitive);
+
+ ///
+ /// 字符串替换
+ ///
+ /// 字符串句柄
+ /// 要替换的内容
+ /// 替换为的内容
+ /// 是否区分大小写
+ /// 替换次数
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ReplaceString(
+ IntPtr handle,
+ [MarshalAs(UnmanagedType.LPStr)] string oldValue,
+ [MarshalAs(UnmanagedType.LPStr)] string newValue,
+ [MarshalAs(UnmanagedType.Bool)] bool caseSensitive);
+
+ ///
+ /// 字符串分割
+ ///
+ /// 字符串句柄
+ /// 分隔符
+ /// 分割结果数组
+ /// 最大分割数量
+ /// 实际分割数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_SplitString(
+ IntPtr handle,
+ [MarshalAs(UnmanagedType.LPStr)] string delimiter,
+ [Out] IntPtr[] parts,
+ int maxParts);
+
+ ///
+ /// 字符串格式化
+ ///
+ /// 格式化字符串
+ /// 参数数组
+ /// 参数数量
+ /// 格式化后的字符串句柄
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_FormatString(
+ [MarshalAs(UnmanagedType.LPStr)] string format,
+ [MarshalAs(UnmanagedType.LPArray)] object[] args,
+ int argCount);
+
+ ///
+ /// 字符串转大写
+ ///
+ /// 字符串句柄
+ /// 是否成功转换
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_ToUpperCase(IntPtr handle);
+
+ ///
+ /// 字符串转小写
+ ///
+ /// 字符串句柄
+ /// 是否成功转换
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_ToLowerCase(IntPtr handle);
+
+ ///
+ /// 去除字符串空白字符
+ ///
+ /// 字符串句柄
+ /// 是否成功去除
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_TrimString(IntPtr handle);
+
+ ///
+ /// 字符串子串提取
+ ///
+ /// 字符串句柄
+ /// 起始位置
+ /// 子串长度(-1表示到末尾)
+ /// 子字符串句柄
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_Substring(
+ IntPtr handle,
+ int startIndex,
+ int length);
+
+ ///
+ /// 字符串复制
+ ///
+ /// 字符串句柄
+ /// 复制的字符串句柄
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_CopyString(IntPtr handle);
+
+ ///
+ /// 字符串拼接
+ ///
+ /// 字符串句柄数组
+ /// 字符串数量
+ /// 拼接后的字符串句柄
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr AmxModx_Bridge_ConcatenateStrings(
+ [MarshalAs(UnmanagedType.LPArray)] IntPtr[] handles,
+ int count);
+
+ ///
+ /// 安全的创建字符串
+ ///
+ /// 字符串内容
+ /// 编码类型
+ /// 字符串句柄
+ public static IntPtr CreateStringSafe(string text, StringEncoding encoding = StringEncoding.Utf8)
+ {
+ if (string.IsNullOrEmpty(text))
+ return IntPtr.Zero;
+
+ return AmxModx_Bridge_CreateString(text, encoding);
+ }
+
+ ///
+ /// 安全的销毁字符串
+ ///
+ /// 字符串句柄
+ /// 是否成功销毁
+ public static bool DestroyStringSafe(IntPtr handle)
+ {
+ if (handle == IntPtr.Zero)
+ return false;
+
+ return AmxModx_Bridge_DestroyString(handle);
+ }
+
+ ///
+ /// 安全的获取字符串内容
+ ///
+ /// 字符串句柄
+ /// 编码类型
+ /// 字符串内容
+ public static string GetStringContentSafe(IntPtr handle, StringEncoding encoding = StringEncoding.Utf8)
+ {
+ if (handle == IntPtr.Zero)
+ return string.Empty;
+
+ StringBuilder buffer = new StringBuilder(1024);
+ int length = AmxModx_Bridge_GetStringContent(handle, buffer, buffer.Capacity, encoding);
+
+ if (length > 0)
+ {
+ return buffer.ToString();
+ }
+
+ return string.Empty;
+ }
+
+ ///
+ /// 安全的字符串格式化
+ ///
+ /// 格式化字符串
+ /// 参数数组
+ /// 格式化后的字符串句柄
+ public static IntPtr FormatStringSafe(string format, params object[] args)
+ {
+ if (string.IsNullOrEmpty(format))
+ return IntPtr.Zero;
+
+ return AmxModx_Bridge_FormatString(format, args, args?.Length ?? 0);
+ }
+
+ ///
+ /// 安全的字符串复制
+ ///
+ /// 字符串句柄
+ /// 复制的字符串句柄
+ public static IntPtr CopyStringSafe(IntPtr handle)
+ {
+ if (handle == IntPtr.Zero)
+ return IntPtr.Zero;
+
+ return AmxModx_Bridge_CopyString(handle);
+ }
+
+ ///
+ /// 安全的字符串拼接
+ ///
+ /// 字符串句柄数组
+ /// 拼接后的字符串句柄
+ public static IntPtr ConcatenateStringsSafe(params IntPtr[] handles)
+ {
+ if (handles == null || handles.Length == 0)
+ return IntPtr.Zero;
+
+ return AmxModx_Bridge_ConcatenateStrings(handles, handles.Length);
+ }
+
+ ///
+ /// 安全的子串提取
+ ///
+ /// 字符串句柄
+ /// 起始位置
+ /// 子串长度
+ /// 子字符串句柄
+ public static IntPtr SubstringSafe(IntPtr handle, int startIndex, int length = -1)
+ {
+ if (handle == IntPtr.Zero || startIndex < 0)
+ return IntPtr.Zero;
+
+ return AmxModx_Bridge_Substring(handle, startIndex, length);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Task.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Task.cs
new file mode 100644
index 0000000..e728c9a
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Task.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace AmxModx.Bridge.Task
+{
+ ///
+ /// 任务标志位枚举
+ ///
+ [Flags]
+ public enum TaskFlags
+ {
+ ///
+ /// 重复执行
+ ///
+ Repeat = 1,
+
+ ///
+ /// 循环执行
+ ///
+ Loop = 2,
+
+ ///
+ /// 在地图开始后执行
+ ///
+ AfterStart = 4,
+
+ ///
+ /// 在地图结束前执行
+ ///
+ BeforeEnd = 8
+ }
+
+ ///
+ /// 任务调度系统P/Invoke接口
+ ///
+ public static class TaskBridge
+ {
+ private const string DllName = "amxmodx_mm";
+
+ ///
+ /// 创建任务
+ ///
+ /// 插件ID
+ /// 函数ID
+ /// 任务标志
+ /// 任务ID
+ /// 执行间隔(秒)
+ /// 重复次数(-1为无限)
+ /// 参数数组
+ /// 参数数量
+ /// 成功返回1,失败返回0
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_CreateTask(
+ int pluginId,
+ int funcId,
+ int flags,
+ int taskId,
+ float interval,
+ int repeat,
+ [MarshalAs(UnmanagedType.LPArray)] int[] parameters,
+ int paramCount);
+
+ ///
+ /// 移除任务
+ ///
+ /// 插件ID
+ /// 任务ID
+ /// 移除的任务数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_RemoveTasks(int pluginId, int taskId);
+
+ ///
+ /// 修改任务间隔
+ ///
+ /// 插件ID
+ /// 任务ID
+ /// 新的间隔时间
+ /// 修改的任务数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_ChangeTaskInterval(
+ int pluginId,
+ int taskId,
+ float newInterval);
+
+ ///
+ /// 检查任务是否存在
+ ///
+ /// 插件ID
+ /// 任务ID
+ /// 存在返回true,否则返回false
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_TaskExists(int pluginId, int taskId);
+
+ ///
+ /// 获取当前活动任务数量
+ ///
+ /// 活动任务数量
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AmxModx_Bridge_GetActiveTaskCount();
+
+ ///
+ /// 获取任务信息
+ ///
+ /// 插件ID
+ /// 任务ID
+ /// 返回间隔时间
+ /// 返回重复次数
+ /// 返回任务标志
+ /// 成功返回true,失败返回false
+ [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AmxModx_Bridge_GetTaskInfo(
+ int pluginId,
+ int taskId,
+ out float interval,
+ out int repeat,
+ out int flags);
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Template.cs b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Template.cs
new file mode 100644
index 0000000..860ebc2
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/PInvoke/System/AmxModx.Bridge.Template.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace AmxModx.Bridge.Template
+{
+ ///
+ /// 模板模块桥接接口
+ /// 提供模板模块功能的C#访问
+ ///
+ public static class TemplateBridge
+ {
+ ///
+ /// 模板模块DLL名称常量
+ ///
+ private const string TemplateBridgeDll = "template_amxx";
+
+ ///
+ /// 示例函数 - 获取模板信息
+ ///
+ /// 模板信息缓冲区
+ /// 缓冲区最大长度
+ /// 实际长度
+ [DllImport(TemplateBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Template_GetInfo([Out] byte[] info, int maxLen);
+
+ ///
+ /// 示例函数 - 设置模板参数
+ ///
+ /// 参数名称
+ /// 参数值
+ /// 成功返回true,失败返回false
+ [DllImport(TemplateBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool Template_SetParam([MarshalAs(UnmanagedType.LPStr)] string paramName, int value);
+
+ ///
+ /// 示例函数 - 执行模板操作
+ ///
+ /// 操作类型
+ /// 操作数据
+ /// 操作结果
+ [DllImport(TemplateBridgeDll, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Template_Execute(int operation, IntPtr data);
+
+ ///
+ /// 安全的获取模板信息方法
+ ///
+ /// 模板信息字符串
+ public static string GetTemplateInfoSafe()
+ {
+ byte[] buffer = new byte[256];
+ int length = Template_GetInfo(buffer, buffer.Length);
+ if (length <= 0) return string.Empty;
+
+ return Encoding.UTF8.GetString(buffer, 0, Math.Min(length, buffer.Length));
+ }
+
+ ///
+ /// 安全的设置模板参数方法
+ ///
+ /// 参数名称
+ /// 参数值
+ /// 是否设置成功
+ public static bool SetTemplateParamSafe(string paramName, int value)
+ {
+ if (string.IsNullOrEmpty(paramName)) return false;
+ return Template_SetParam(paramName, value);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Bridge/README.md b/Template/Amxmodx.Module.Template/Bridge/README.md
new file mode 100644
index 0000000..ed699c7
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/Bridge/README.md
@@ -0,0 +1,181 @@
+# AMX Mod X .NET 高级封装层
+
+## 📋 概述
+
+本项目为AMX Mod X提供了完整的.NET高级封装层,将原始的P/Invoke接口转换为易于使用的面向对象API。
+
+## 🏗️ 项目结构
+
+```
+Bridge/
+├── PInvoke/ # P/Invoke接口声明层
+│ ├── Communication/ # 通信模块P/Invoke
+│ ├── Data/ # 数据模块P/Invoke
+│ ├── Engine/ # 引擎模块P/Invoke
+│ ├── Gameplay/ # 游戏模块P/Invoke
+│ └── System/ # 系统模块P/Invoke
+├── Wrappers/ # 高级封装层
+│ ├── Communication/ # 通信模块高级封装
+│ ├── Data/ # 数据模块高级封装
+│ ├── Engine/ # 引擎模块高级封装
+│ ├── Gameplay/ # 游戏模块高级封装
+│ └── System/ # 系统模块高级封装
+└── Examples/ # 使用示例
+```
+
+## 🚀 快速开始
+
+### 1. 初始化
+
+```csharp
+using AmxModx.Wrappers;
+
+// 初始化所有模块
+AmxModxManager.Initialize();
+```
+
+### 2. 使用示例
+
+#### 系统模块
+```csharp
+// 获取参数
+int paramCount = CoreManager.ParameterCount;
+string paramValue = CoreManager.GetStringParameter(0);
+
+// 设置属性
+var result = CoreManager.SetProperty(1, "test", 123);
+```
+
+#### 引擎模块
+```csharp
+// 实体操作
+if (EngineManager.IsValidEntity(entityId))
+{
+ var origin = EngineManager.GetEntityOrigin(entityId);
+ var distance = EngineManager.GetEntityDistance(entity1, entity2);
+}
+
+// 追踪
+var trace = EngineManager.TraceLine(startPos, endPos, ignoreEntity);
+```
+
+#### 数据模块
+```csharp
+// CVar操作
+var cvar = CVarManager.Create("my_var", "default_value");
+string value = CVarManager.GetString("hostname");
+CVarManager.SetFloat("sv_gravity", 800.0f);
+```
+
+#### 通信模块
+```csharp
+// 事件系统
+EventManager.RegisterEvent("player_death", OnPlayerDeath);
+EventManager.FireEvent("round_start", new Dictionary());
+
+// 转发系统
+ForwardManager.RegisterClientConnect(OnClientConnect);
+int result = ForwardManager.ExecuteForward("client_command", clientId, command);
+```
+
+## 📚 模块文档
+
+### System 模块
+- **CoreManager**: 核心功能封装
+- **NativeManager**: 本地函数封装
+- **CommandManager**: 命令系统封装
+- **TaskManager**: 任务系统封装
+
+### Engine 模块
+- **EngineManager**: 引擎功能封装
+- **TraceResult**: 追踪结果封装
+
+### Data 模块
+- **CVarManager**: 控制台变量封装
+- **CVar**: CVar实例封装
+
+### Communication 模块
+- **EventManager**: 事件系统封装
+- **ForwardManager**: 转发系统封装
+
+### Gameplay 模块
+- **HamSandwichManager**: HAM系统封装
+- **HamSandwichWrapper**: HAM包装器
+
+## 🔧 开发指南
+
+### 创建新的高级封装
+
+1. **分析P/Invoke接口**: 查看对应的P/Invoke文件
+2. **设计封装结构**: 确定类和方法的命名
+3. **实现封装**: 在对应模块目录下创建封装类
+4. **添加示例**: 在Examples目录下添加使用示例
+
+### 命名规范
+
+- **命名空间**: `AmxModx.Wrappers.[模块名]`
+- **类名**: `[功能]Manager` 或 `[功能]Wrapper`
+- **方法名**: 使用PascalCase,描述性命名
+
+### 错误处理
+
+所有高级封装都包含完整的错误处理:
+- 参数验证
+- 空值检查
+- 异常捕获
+- 错误日志
+
+## 📖 API 参考
+
+### 统一入口
+
+使用 `AmxModxManager` 作为统一入口:
+
+```csharp
+// 系统模块
+AmxModxManager.System.Core.GetParameter(0);
+AmxModxManager.System.Native.PtrToString(ptr);
+
+// 引擎模块
+AmxModxManager.Engine.Engine.IsValidEntity(entityId);
+
+// 数据模块
+AmxModxManager.Data.CVar.GetString("hostname");
+
+// 通信模块
+AmxModxManager.Communication.Event.RegisterEvent("death", callback);
+```
+
+## 🎯 特性
+
+- ✅ **类型安全**: 强类型API,避免指针操作
+- ✅ **面向对象**: 面向对象设计,易于使用
+- ✅ **错误处理**: 完整的错误处理和验证
+- ✅ **性能优化**: 最小化P/Invoke调用
+- ✅ **文档完整**: 详细的XML注释和示例
+- ✅ **扩展性**: 易于扩展和自定义
+
+## 🔍 调试
+
+### 日志记录
+
+所有模块都包含详细的日志记录:
+```csharp
+// 启用调试日志
+AmxModxManager.EnableDebugLogging = true;
+```
+
+### 性能监控
+
+```csharp
+// 获取性能统计
+var stats = AmxModxManager.GetPerformanceStats();
+```
+
+## 📞 支持
+
+如有问题或建议,请查看项目文档或提交Issue。
+
+## 📝 许可证
+
+本项目采用MIT许可证,详见LICENSE文件。
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/amxcore_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/amxcore_bridge.h
new file mode 100644
index 0000000..cf91e19
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/amxcore_bridge.h
@@ -0,0 +1,98 @@
+/*
+ * AMX Mod X Core Bridge Header
+ * 实现amxcore.cpp中核心接口的C#桥接
+ */
+#ifndef AMXCORE_BRIDGE_H
+#define AMXCORE_BRIDGE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief 获取当前函数的参数数量
+ * @return 参数数量
+ */
+int AmxModx_Bridge_GetNumArgs(void);
+
+/**
+ * @brief 获取指定索引的参数值
+ * @param index 参数索引(从0开始)
+ * @param offset 数组偏移量(对于数组参数)
+ * @return 参数值
+ */
+int AmxModx_Bridge_GetArg(int index, int offset);
+
+/**
+ * @brief 设置指定索引的参数值
+ * @param index 参数索引(从0开始)
+ * @param offset 数组偏移量(对于数组参数)
+ * @param value 要设置的值
+ * @return 成功返回1,失败返回0
+ */
+int AmxModx_Bridge_SetArg(int index, int offset, int value);
+
+/**
+ * @brief 获取可用堆空间大小
+ * @return 堆空间字节数
+ */
+int AmxModx_Bridge_GetHeapSpace(void);
+
+/**
+ * @brief 根据函数名获取函数索引
+ * @param functionName 函数名称
+ * @return 函数索引,-1表示未找到
+ */
+int AmxModx_Bridge_GetFunctionIndex(const char* functionName);
+
+/**
+ * @brief 交换32位整数的字节顺序
+ * @param value 要交换的值
+ * @return 交换后的值
+ */
+int AmxModx_Bridge_SwapChars(int value);
+
+/**
+ * @brief 获取属性值
+ * @param id 属性ID
+ * @param name 属性名称
+ * @param value 属性值
+ * @param buffer 输出缓冲区
+ * @param maxLen 缓冲区最大长度
+ * @return 属性值
+ */
+int AmxModx_Bridge_GetProperty(int id, const char* name, int value, char* buffer, int maxLen);
+
+/**
+ * @brief 设置属性值
+ * @param id 属性ID
+ * @param name 属性名称
+ * @param value 属性值
+ * @param newName 新属性名称(可选)
+ * @return 之前的属性值
+ */
+int AmxModx_Bridge_SetProperty(int id, const char* name, int value, const char* newName);
+
+/**
+ * @brief 删除属性
+ * @param id 属性ID
+ * @param name 属性名称
+ * @param value 属性值
+ * @return 被删除的属性值
+ */
+int AmxModx_Bridge_DeleteProperty(int id, const char* name, int value);
+
+/**
+ * @brief 检查属性是否存在
+ * @param id 属性ID
+ * @param name 属性名称
+ * @param value 属性值
+ * @return 存在返回1,不存在返回0
+ */
+int AmxModx_Bridge_PropertyExists(int id, const char* name, int value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // AMXCORE_BRIDGE_H
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/command_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/command_bridge.h
new file mode 100644
index 0000000..2212017
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/command_bridge.h
@@ -0,0 +1,164 @@
+// vim: set ts=4 sw=4 tw=99 noet:
+//
+// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
+// Copyright (C) The AMX Mod X Development Team.
+//
+// This software is licensed under the GNU General Public License, version 3 or higher.
+// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
+// https://alliedmods.net/amxmodx-license
+
+#ifndef COMMAND_BRIDGE_H
+#define COMMAND_BRIDGE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * 命令类型枚举
+ */
+enum CommandType
+{
+ CMD_TYPE_CONSOLE = 0, // 控制台命令
+ CMD_TYPE_CLIENT = 1, // 客户端命令
+ CMD_TYPE_SERVER = 2 // 服务器命令
+};
+
+/**
+ * 命令标志位
+ */
+enum CommandFlags
+{
+ CMD_FLAG_ADMIN = 1, // 管理员命令
+ CMD_FLAG_RCON = 2, // RCON命令
+ CMD_FLAG_PUBLIC = 4, // 公共命令
+ CMD_FLAG_HIDDEN = 8 // 隐藏命令
+};
+
+/**
+ * 注册控制台命令
+ * @param pluginId 插件ID
+ * @param funcId 函数ID
+ * @param cmd 命令名称
+ * @param info 命令描述
+ * @param flags 命令标志位
+ * @param listable 是否可列出
+ * @return 成功返回1,失败返回0
+ */
+int AmxModx_Bridge_RegisterConsoleCommand(
+ int pluginId,
+ int funcId,
+ const char* cmd,
+ const char* info,
+ int flags,
+ bool listable);
+
+/**
+ * 注册客户端命令
+ * @param pluginId 插件ID
+ * @param funcId 函数ID
+ * @param cmd 命令名称
+ * @param info 命令描述
+ * @param flags 命令标志位
+ * @param listable 是否可列出
+ * @return 成功返回1,失败返回0
+ */
+int AmxModx_Bridge_RegisterClientCommand(
+ int pluginId,
+ int funcId,
+ const char* cmd,
+ const char* info,
+ int flags,
+ bool listable);
+
+/**
+ * 注册服务器命令
+ * @param pluginId 插件ID
+ * @param funcId 函数ID
+ * @param cmd 命令名称
+ * @param info 命令描述
+ * @param flags 命令标志位
+ * @param listable 是否可列出
+ * @return 成功返回1,失败返回0
+ */
+int AmxModx_Bridge_RegisterServerCommand(
+ int pluginId,
+ int funcId,
+ const char* cmd,
+ const char* info,
+ int flags,
+ bool listable);
+
+/**
+ * 获取命令数量
+ * @param type 命令类型
+ * @param access 访问级别
+ * @return 命令数量
+ */
+int AmxModx_Bridge_GetCommandCount(int type, int access);
+
+/**
+ * 获取命令信息
+ * @param type 命令类型
+ * @param index 命令索引
+ * @param access 访问级别
+ * @param cmd 返回命令名称缓冲区
+ * @param cmdSize 命令名称缓冲区大小
+ * @param info 返回命令描述缓冲区
+ * @param infoSize 命令描述缓冲区大小
+ * @param flags 返回命令标志位
+ * @return 成功返回1,失败返回0
+ */
+int AmxModx_Bridge_GetCommandInfo(
+ int type,
+ int index,
+ int access,
+ char* cmd,
+ int cmdSize,
+ char* info,
+ int infoSize,
+ int* flags);
+
+/**
+ * 执行控制台命令
+ * @param cmd 命令字符串
+ * @return 成功返回1,失败返回0
+ */
+int AmxModx_Bridge_ExecuteConsoleCommand(const char* cmd);
+
+/**
+ * 执行客户端命令
+ * @param playerId 玩家ID
+ * @param cmd 命令字符串
+ * @return 成功返回1,失败返回0
+ */
+int AmxModx_Bridge_ExecuteClientCommand(int playerId, const char* cmd);
+
+/**
+ * 执行服务器命令
+ * @param cmd 命令字符串
+ * @return 成功返回1,失败返回0
+ */
+int AmxModx_Bridge_ExecuteServerCommand(const char* cmd);
+
+/**
+ * 检查命令是否存在
+ * @param type 命令类型
+ * @param cmd 命令名称
+ * @return 存在返回true,否则返回false
+ */
+bool AmxModx_Bridge_CommandExists(int type, const char* cmd);
+
+/**
+ * 移除命令
+ * @param pluginId 插件ID
+ * @param cmd 命令名称
+ * @return 移除的命令数量
+ */
+int AmxModx_Bridge_RemoveCommands(int pluginId, const char* cmd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COMMAND_BRIDGE_H
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/cstrike_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/cstrike_bridge.h
new file mode 100644
index 0000000..bf98b4b
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/cstrike_bridge.h
@@ -0,0 +1,90 @@
+// vim: set ts=4 sw=4 tw=99 noet:
+//
+// Counter-Strike Module C# Bridge
+// C++ side bridge header
+//
+
+#ifndef CSTRIKE_BRIDGE_H
+#define CSTRIKE_BRIDGE_H
+
+#ifdef WIN32
+#define BRIDGE_API __declspec(dllexport)
+#else
+#define BRIDGE_API __attribute__((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Player API
+BRIDGE_API int CsGetUserMoney(int playerIndex);
+BRIDGE_API void CsSetUserMoney(int playerIndex, int money, int flash = 1);
+BRIDGE_API int CsGetUserArmor(int playerIndex);
+BRIDGE_API void CsSetUserArmor(int playerIndex, int armor);
+BRIDGE_API int CsGetUserTeam(int playerIndex);
+BRIDGE_API void CsSetUserTeam(int playerIndex, int team);
+BRIDGE_API bool CsGetUserVip(int playerIndex);
+BRIDGE_API void CsSetUserVip(int playerIndex, bool vip);
+BRIDGE_API int CsGetUserDeaths(int playerIndex);
+BRIDGE_API void CsSetUserDeaths(int playerIndex, int deaths, bool updateScoreboard = true);
+
+// Weapon API
+BRIDGE_API int CsGetWeaponId(int weaponEntity);
+BRIDGE_API bool CsGetWeaponSilenced(int weaponEntity);
+BRIDGE_API void CsSetWeaponSilenced(int weaponEntity, bool silenced, int drawAnimation = 1);
+BRIDGE_API bool CsGetWeaponBurstMode(int weaponEntity);
+BRIDGE_API void CsSetWeaponBurstMode(int weaponEntity, bool burstMode, int drawAnimation = 1);
+BRIDGE_API int CsGetWeaponAmmo(int weaponEntity);
+BRIDGE_API void CsSetWeaponAmmo(int weaponEntity, int ammo);
+
+// Game State API
+BRIDGE_API bool CsGetUserInsideBuyzone(int playerIndex);
+BRIDGE_API int CsGetUserMapzones(int playerIndex);
+BRIDGE_API bool CsGetUserHasPrimary(int playerIndex);
+BRIDGE_API bool CsGetUserDefusekit(int playerIndex);
+BRIDGE_API void CsSetUserDefusekit(int playerIndex, bool hasKit);
+BRIDGE_API bool CsGetUserNvg(int playerIndex);
+BRIDGE_API void CsSetUserNvg(int playerIndex, bool hasNvg);
+
+// Model API
+BRIDGE_API void CsGetUserModel(int playerIndex, char* buffer, int bufferSize);
+BRIDGE_API void CsSetUserModel(int playerIndex, const char* model);
+BRIDGE_API void CsResetUserModel(int playerIndex);
+
+// Entity API
+BRIDGE_API int CsCreateEntity(const char* className);
+BRIDGE_API int CsFindEntityByClass(int startIndex, const char* className);
+BRIDGE_API int CsFindEntityByOwner(int startIndex, int ownerIndex);
+BRIDGE_API bool CsSetEntityClass(int entityIndex, const char* className);
+
+// Item API
+BRIDGE_API int CsGetItemId(const char* itemName);
+BRIDGE_API bool CsGetItemAlias(int itemId, char* buffer, int bufferSize);
+BRIDGE_API bool CsGetTranslatedItemAlias(int itemId, char* buffer, int bufferSize);
+
+// Hostage API
+BRIDGE_API int CsGetHostageId(int hostageIndex);
+BRIDGE_API bool CsGetHostageFollow(int hostageIndex);
+BRIDGE_API void CsSetHostageFollow(int hostageIndex, bool follow);
+
+// Bomb API
+BRIDGE_API float CsGetC4ExplodeTime();
+BRIDGE_API void CsSetC4ExplodeTime(float time);
+BRIDGE_API bool CsGetC4Defusing();
+BRIDGE_API void CsSetC4Defusing(bool defusing);
+
+// Event delegates
+typedef void (*CsPlayerDeathCallback)(int victim, int killer, int weapon);
+typedef void (*CsBombEventCallback)(int eventType, int player);
+typedef void (*CsWeaponPickupCallback)(int player, int weaponId);
+
+BRIDGE_API void CsRegisterPlayerDeathCallback(CsPlayerDeathCallback callback);
+BRIDGE_API void CsRegisterBombEventCallback(CsBombEventCallback callback);
+BRIDGE_API void CsRegisterWeaponPickupCallback(CsWeaponPickupCallback callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CSTRIKE_BRIDGE_H
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/datastructs_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/datastructs_bridge.h
new file mode 100644
index 0000000..8bd7d43
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/datastructs_bridge.h
@@ -0,0 +1,136 @@
+// datastructs_bridge.h
+// 数据结构桥接接口定义
+#pragma once
+
+#include "../amxmodx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * 创建动态数组
+ * @param cellsize 每个元素的大小(以cell为单位)
+ * @param reserved 初始预留容量
+ * @return 数组句柄,失败返回0
+ */
+int AmxModx_Bridge_ArrayCreate(int cellsize, int reserved = 32);
+
+/**
+ * 销毁数组并释放内存
+ * @param handle 数组句柄(传引用,成功后会置0)
+ * @return 是否成功销毁
+ */
+int AmxModx_Bridge_ArrayDestroy(int* handle);
+
+/**
+ * 获取数组当前元素数量
+ * @param handle 数组句柄
+ * @return 元素数量,失败返回-1
+ */
+int AmxModx_Bridge_ArraySize(int handle);
+
+/**
+ * 调整数组大小
+ * @param handle 数组句柄
+ * @param count 新的元素数量
+ * @return 是否成功调整
+ */
+int AmxModx_Bridge_ArrayResize(int handle, int count);
+
+/**
+ * 获取数组元素(单元格值)
+ * @param handle 数组句柄
+ * @param index 元素索引
+ * @param block 数据块索引(默认为0)
+ * @return 单元格值,失败返回0
+ */
+int AmxModx_Bridge_ArrayGetCell(int handle, int index, int block = 0);
+
+/**
+ * 设置数组元素(单元格值)
+ * @param handle 数组句柄
+ * @param index 元素索引
+ * @param value 要设置的值
+ * @param block 数据块索引(默认为0)
+ * @return 是否成功设置
+ */
+int AmxModx_Bridge_ArraySetCell(int handle, int index, int value, int block = 0);
+
+/**
+ * 向数组末尾添加单元格值
+ * @param handle 数组句柄
+ * @param value 要添加的值
+ * @return 新元素的索引,失败返回-1
+ */
+int AmxModx_Bridge_ArrayPushCell(int handle, int value);
+
+/**
+ * 从数组获取字符串
+ * @param handle 数组句柄
+ * @param index 元素索引
+ * @param buffer 输出缓冲区
+ * @param size 缓冲区大小
+ * @return 实际复制的字符数
+ */
+int AmxModx_Bridge_ArrayGetString(int handle, int index, char* buffer, int size);
+
+/**
+ * 向数组设置字符串
+ * @param handle 数组句柄
+ * @param index 元素索引
+ * @param str 要设置的字符串
+ * @return 实际复制的字符数
+ */
+int AmxModx_Bridge_ArraySetString(int handle, int index, const char* str);
+
+/**
+ * 克隆数组
+ * @param handle 原数组句柄
+ * @return 新数组句柄,失败返回0
+ */
+int AmxModx_Bridge_ArrayClone(int handle);
+
+/**
+ * 清空数组内容
+ * @param handle 数组句柄
+ * @return 是否成功清空
+ */
+int AmxModx_Bridge_ArrayClear(int handle);
+
+/**
+ * 删除指定索引的元素
+ * @param handle 数组句柄
+ * @param index 要删除的索引
+ * @return 是否成功删除
+ */
+int AmxModx_Bridge_ArrayDeleteItem(int handle, int index);
+
+/**
+ * 交换两个元素的位置
+ * @param handle 数组句柄
+ * @param index1 第一个索引
+ * @param index2 第二个索引
+ * @return 是否成功交换
+ */
+int AmxModx_Bridge_ArraySwap(int handle, int index1, int index2);
+
+/**
+ * 在数组中查找字符串
+ * @param handle 数组句柄
+ * @param str 要查找的字符串
+ * @return 找到返回索引,未找到返回-1
+ */
+int AmxModx_Bridge_ArrayFindString(int handle, const char* str);
+
+/**
+ * 在数组中查找数值
+ * @param handle 数组句柄
+ * @param value 要查找的值
+ * @return 找到返回索引,未找到返回-1
+ */
+int AmxModx_Bridge_ArrayFindValue(int handle, int value);
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/debugger_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/debugger_bridge.h
new file mode 100644
index 0000000..3d558e3
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/debugger_bridge.h
@@ -0,0 +1,84 @@
+//
+// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
+// Copyright (C) The AMX Mod X Development Team.
+//
+// This software is licensed under the GNU General Public License, version 3 or higher.
+// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
+// https://alliedmods.net/amxmodx-license
+//
+
+#ifndef DEBUGGER_BRIDGE_H
+#define DEBUGGER_BRIDGE_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// 调试器桥接接口
+/**
+ * 设置错误过滤器
+ * @param filter 过滤器类型 (0=全部, 1=警告, 2=错误)
+ */
+void AmxModx_Bridge_SetErrorFilter(int filter);
+
+/**
+ * 记录调试信息
+ * @param message 调试信息
+ * @param level 日志级别 (0=调试, 1=信息, 2=警告, 3=错误)
+ */
+void AmxModx_Bridge_LogDebug(const char* message, int level);
+
+/**
+ * 获取最后错误信息
+ * @return 错误信息字符串
+ */
+const char* AmxModx_Bridge_GetLastError();
+
+/**
+ * 清除最后错误信息
+ */
+void AmxModx_Bridge_ClearLastError();
+
+/**
+ * 启用/禁用调试模式
+ * @param enabled 是否启用
+ */
+void AmxModx_Bridge_SetDebugMode(bool enabled);
+
+/**
+ * 检查是否处于调试模式
+ * @return 是否处于调试模式
+ */
+bool AmxModx_Bridge_IsDebugMode();
+
+/**
+ * 设置断点
+ * @param file 文件名
+ * @param line 行号
+ * @return 设置是否成功
+ */
+bool AmxModx_Bridge_SetBreakpoint(const char* file, int line);
+
+/**
+ * 移除断点
+ * @param file 文件名
+ * @param line 行号
+ * @return 移除是否成功
+ */
+bool AmxModx_Bridge_RemoveBreakpoint(const char* file, int line);
+
+/**
+ * 获取当前调用栈信息
+ * @param buffer 输出缓冲区
+ * @param bufferSize 缓冲区大小
+ * @return 调用栈信息长度
+ */
+int AmxModx_Bridge_GetCallStack(char* buffer, int bufferSize);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // DEBUGGER_BRIDGE_H
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/engine_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/engine_bridge.h
new file mode 100644
index 0000000..5d14c3a
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/engine_bridge.h
@@ -0,0 +1,140 @@
+// Engine Bridge Header
+// AMX Mod X Engine Module C# Bridge
+
+
+#define ENGINE_BRIDGE_H
+
+#define WINDOWS_IGNORE_PACKING_MISMATCH
+#include
+
+#pragma once
+
+#ifdef ENGINE_BRIDGE_EXPORTS
+#define ENGINE_BRIDGE_API __declspec(dllexport)
+#else
+#define ENGINE_BRIDGE_API __declspec(dllimport)
+#endif
+
+// 基本类型定义
+typedef int EntityId;
+typedef float Vector3[3];
+typedef unsigned int TraceResultType;
+
+// 追踪结果结构
+struct TraceResultInfo
+{
+ int allSolid;
+ int startSolid;
+ int inOpen;
+ int inWater;
+ float fraction;
+ Vector3 endPos;
+ float planeDist;
+ Vector3 planeNormal;
+ int hitEntity;
+ int hitGroup;
+};
+
+// 用户命令结构
+struct UserCmdInfo
+{
+ float forwardmove; // 前后移动
+ float sidemove; // 左右移动
+ float upmove; // 上下移动
+ float lerp_msec; // 插值毫秒
+ float msec; // 毫秒
+ float lightlevel; // 光照等级
+ int buttons; // 按键
+ int weaponselect; // 武器选择
+ int impact_index; // 碰撞索引
+ float viewangles[3]; // 视角角度
+ float impact_position[3]; // 碰撞位置
+};
+
+// 引擎桥接接口声明
+extern "C" {
+ // 时间相关
+ ENGINE_BRIDGE_API float Engine_GetGameTime();
+
+ // 实体操作
+ ENGINE_BRIDGE_API int Engine_CreateEntity(const char* className);
+ ENGINE_BRIDGE_API int Engine_RemoveEntity(int entityId);
+ ENGINE_BRIDGE_API int Engine_IsValidEntity(int entityId);
+ ENGINE_BRIDGE_API int Engine_GetEntityCount();
+ ENGINE_BRIDGE_API float Engine_GetEntityDistance(int entityA, int entityB);
+
+ // 追踪系统
+ ENGINE_BRIDGE_API int Engine_TraceLine(const Vector3 start, const Vector3 end, int ignoreEntity, TraceResultInfo* result);
+ ENGINE_BRIDGE_API int Engine_TraceHull(const Vector3 start, const Vector3 end, int hullType, int ignoreEntity, TraceResultInfo* result);
+ ENGINE_BRIDGE_API int Engine_TraceNormal(int entity, const Vector3 start, const Vector3 end, Vector3 normal);
+ ENGINE_BRIDGE_API int Engine_TraceForward(const Vector3 start, const Vector3 angles, float give, int ignoreEntity, TraceResultInfo* result);
+
+ // 游戏事件
+ ENGINE_BRIDGE_API int Engine_PlaybackEvent(int flags, int invoker, unsigned short eventIndex, float delay,
+ const Vector3 origin, const Vector3 angles, float fparam1, float fparam2,
+ int iparam1, int iparam2, int bparam1, int bparam2);
+
+ // 范围伤害
+ ENGINE_BRIDGE_API int Engine_RadiusDamage(const Vector3 origin, int damageMultiplier, int radiusMultiplier);
+
+ // 点内容检查
+ ENGINE_BRIDGE_API int Engine_PointContents(const Vector3 point);
+
+ // 字符串和索引
+ ENGINE_BRIDGE_API int Engine_GetDecalIndex(const char* decalName);
+ ENGINE_BRIDGE_API int Engine_GetInfoKeyBuffer(int entity, char* buffer, int bufferSize);
+ ENGINE_BRIDGE_API int Engine_GetEngineString(int stringId, char* buffer, int bufferSize);
+
+ // 用户命令
+ ENGINE_BRIDGE_API int Engine_GetUserCmd(int client, int type, UserCmdInfo* cmd);
+ ENGINE_BRIDGE_API int Engine_SetUserCmd(int client, int type, const UserCmdInfo* cmd);
+
+ // 说话权限
+ ENGINE_BRIDGE_API int Engine_SetSpeak(int client, int speakFlags);
+ ENGINE_BRIDGE_API int Engine_GetSpeak(int client);
+
+ // 视角控制
+ ENGINE_BRIDGE_API int Engine_SetView(int client, int viewEntity, int viewType);
+ ENGINE_BRIDGE_API int Engine_AttachView(int client, int targetEntity);
+
+ // 光照
+ ENGINE_BRIDGE_API int Engine_SetLights(const char* lights);
+
+ // 地面放置
+ ENGINE_BRIDGE_API int Engine_DropToFloor(int entity);
+
+ // 可见性检查
+ ENGINE_BRIDGE_API int Engine_IsVisible(int srcEntity, int destEntity);
+ ENGINE_BRIDGE_API int Engine_IsInViewCone(int entity, const Vector3 target);
+
+ // 实体属性访问
+ENGINE_BRIDGE_API int Engine_GetEntityOrigin(int entityId, Vector3 origin);
+ENGINE_BRIDGE_API int Engine_SetEntityOrigin(int entityId, const Vector3 origin);
+ENGINE_BRIDGE_API int Engine_GetEntityAngles(int entityId, Vector3 angles);
+ENGINE_BRIDGE_API int Engine_SetEntityAngles(int entityId, const Vector3 angles);
+ENGINE_BRIDGE_API int Engine_GetEntityVelocity(int entityId, Vector3 velocity);
+ENGINE_BRIDGE_API int Engine_SetEntityVelocity(int entityId, const Vector3 velocity);
+ENGINE_BRIDGE_API int Engine_GetEntityClassName(int entityId, char* buffer, int bufferSize);
+ENGINE_BRIDGE_API int Engine_GetEntityModelName(int entityId, char* buffer, int bufferSize);
+ENGINE_BRIDGE_API int Engine_GetEntityHealth(int entityId);
+ENGINE_BRIDGE_API int Engine_SetEntityHealth(int entityId, int health);
+ENGINE_BRIDGE_API int Engine_GetEntityArmor(int entityId);
+ENGINE_BRIDGE_API int Engine_SetEntityArmor(int entityId, int armor);
+
+// 实体列表操作
+ENGINE_BRIDGE_API int Engine_GetAllEntities(int* entities, int maxCount);
+ENGINE_BRIDGE_API int Engine_FindEntitiesByClass(const char* className, int* entities, int maxCount);
+
+// 事件注册(回调机制)
+typedef void (*ImpulseCallback)(int client, int impulse);
+typedef void (*TouchCallback)(int touched, int toucher);
+typedef void (*ThinkCallback)(int entity);
+
+ENGINE_BRIDGE_API int Engine_RegisterImpulse(int impulse, ImpulseCallback callback);
+ENGINE_BRIDGE_API int Engine_RegisterTouch(const char* touchedClass, const char* toucherClass, TouchCallback callback);
+ENGINE_BRIDGE_API int Engine_RegisterThink(const char* className, ThinkCallback callback);
+
+ENGINE_BRIDGE_API int Engine_UnregisterImpulse(int registerId);
+ENGINE_BRIDGE_API int Engine_UnregisterTouch(int registerId);
+ENGINE_BRIDGE_API int Engine_UnregisterThink(int registerId);
+}
diff --git a/Template/Amxmodx.Module.Template/CppInterface/engine_effects_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/engine_effects_bridge.h
new file mode 100644
index 0000000..db3181e
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/engine_effects_bridge.h
@@ -0,0 +1,83 @@
+// Engine Effects Bridge Header
+// AMX Mod X Engine Module Advanced Effects C# Bridge
+
+#ifndef ENGINE_EFFECTS_BRIDGE_H
+#define ENGINE_EFFECTS_BRIDGE_H
+
+#pragma once
+
+#ifdef _WIN32
+ #ifdef ENGINE_EFFECTS_BRIDGE_EXPORTS
+ #define ENGINE_EFFECTS_BRIDGE_API __declspec(dllexport)
+ #else
+ #define ENGINE_EFFECTS_BRIDGE_API __declspec(dllimport)
+ #endif
+#else
+ #define ENGINE_EFFECTS_BRIDGE_API __attribute__((visibility("default")))
+#endif
+
+// 基本类型定义
+typedef int EntityId;
+typedef float Vector3[3];
+typedef unsigned int EffectId;
+
+// 粒子系统参数结构
+struct ParticleParams {
+ Vector3 origin;
+ Vector3 velocity;
+ Vector3 angles;
+ float scale;
+ int color;
+ float life;
+ float decay;
+ int spriteIndex;
+ int flags;
+};
+
+// 光照参数结构
+struct LightParams {
+ Vector3 origin;
+ float radius;
+ int color[3]; // RGB
+ float life;
+ float decay;
+ int style; // 闪烁模式
+ int flags;
+};
+
+// 音效参数结构
+struct SoundParams {
+ Vector3 origin;
+ const char* sample;
+ float volume;
+ float attenuation;
+ int channel;
+ int pitch;
+ int flags;
+ EntityId entity;
+};
+
+extern "C" {
+ // 音效系统接口
+ ENGINE_EFFECTS_BRIDGE_API int Engine_SoundPlayAttached(EntityId entity, const char* sample, int channel, float volume, float attenuation, int pitch, int flags);
+ ENGINE_EFFECTS_BRIDGE_API int Engine_SoundSetPitch(EntityId entity, int channel, int pitch);
+
+ // 光照系统接口
+ENGINE_EFFECTS_BRIDGE_API EffectId Engine_LightCreate(const float origin[3], float radius, int red, int green, int blue, float life, int style);
+ ENGINE_EFFECTS_BRIDGE_API int Engine_LightSetColor(EffectId lightId, int red, int green, int blue);
+ ENGINE_EFFECTS_BRIDGE_API int Engine_LightFlicker(EffectId lightId, float flickerSpeed, float minIntensity);
+ ENGINE_EFFECTS_BRIDGE_API int Engine_LightPulse(EffectId lightId, float pulseSpeed, float minIntensity, float maxIntensity);
+ ENGINE_EFFECTS_BRIDGE_API int Engine_LightStop(EffectId lightId);
+
+ // 粒子系统接口
+ENGINE_EFFECTS_BRIDGE_API EffectId Engine_ParticleCreate(const float origin[3], const char* sprite, int maxParticles);
+ ENGINE_EFFECTS_BRIDGE_API int Engine_ParticleSetColor(EffectId particleId, int red, int green, int blue);
+ ENGINE_EFFECTS_BRIDGE_API int Engine_ParticleSetScale(EffectId particleId, float scale);
+ ENGINE_EFFECTS_BRIDGE_API int Engine_ParticleStop(EffectId particleId);
+
+ // 辅助函数
+ ENGINE_EFFECTS_BRIDGE_API int Engine_GetSpriteIndex(const char* spriteName);
+ ENGINE_EFFECTS_BRIDGE_API int Engine_PrecacheModel(const char* modelName);
+}
+
+#endif // ENGINE_EFFECTS_BRIDGE_H
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/entity_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/entity_bridge.h
new file mode 100644
index 0000000..2c7664f
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/entity_bridge.h
@@ -0,0 +1,72 @@
+// vim: set ts=4 sw=4 tw=99 noet:
+//
+// AMX Mod X Entity Bridge Header
+// Copyright (C) The AMX Mod X Development Team.
+//
+// This software is licensed under the GNU General Public License, version 3 or higher.
+// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
+// https://alliedmods.net/amxmodx-license
+
+#ifndef _ENTITY_BRIDGE_H
+#define _ENTITY_BRIDGE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// 实体管理接口
+int AmxModx_Bridge_GetMaxClients(void);
+int AmxModx_Bridge_GetMaxEntities(void);
+int AmxModx_Bridge_GetPlayerCount(void);
+bool AmxModx_Bridge_IsPlayerValid(int playerId);
+bool AmxModx_Bridge_IsPlayerInGame(int playerId);
+bool AmxModx_Bridge_IsPlayerAlive(int playerId);
+bool AmxModx_Bridge_IsPlayerBot(int playerId);
+
+// 实体属性访问
+const char* AmxModx_Bridge_GetPlayerName(int playerId);
+const char* AmxModx_Bridge_GetPlayerIPAddress(int playerId);
+const char* AmxModx_Bridge_GetPlayerAuthID(int playerId);
+const char* AmxModx_Bridge_GetPlayerTeam(int playerId);
+int AmxModx_Bridge_GetPlayerUserID(int playerId);
+int AmxModx_Bridge_GetPlayerFrags(int playerId);
+int AmxModx_Bridge_GetPlayerDeaths(int playerId);
+int AmxModx_Bridge_GetPlayerHealth(int playerId);
+int AmxModx_Bridge_GetPlayerArmor(int playerId);
+int AmxModx_Bridge_GetPlayerPing(int playerId);
+
+// 实体位置相关
+bool AmxModx_Bridge_GetPlayerOrigin(int playerId, float* x, float* y, float* z);
+bool AmxModx_Bridge_GetPlayerVelocity(int playerId, float* x, float* y, float* z);
+bool AmxModx_Bridge_SetPlayerOrigin(int playerId, float x, float y, float z);
+bool AmxModx_Bridge_SetPlayerVelocity(int playerId, float x, float y, float z);
+
+// 实体武器相关
+int AmxModx_Bridge_GetPlayerCurrentWeapon(int playerId);
+int AmxModx_Bridge_GetPlayerAmmo(int playerId, int weaponId);
+bool AmxModx_Bridge_PlayerHasWeapon(int playerId, int weaponId);
+
+// 实体操作
+bool AmxModx_Bridge_KillPlayer(int playerId);
+bool AmxModx_Bridge_SlapPlayer(int playerId, int damage, bool randomVelocity);
+bool AmxModx_Bridge_TeleportPlayer(int playerId, float x, float y, float z);
+bool AmxModx_Bridge_RespawnPlayer(int playerId);
+bool AmxModx_Bridge_StripWeapons(int playerId);
+bool AmxModx_Bridge_GiveWeapon(int playerId, const char* weaponName, int ammo);
+bool AmxModx_Bridge_SetPlayerTeam(int playerId, int teamId);
+bool AmxModx_Bridge_FreezePlayer(int playerId, bool freeze);
+bool AmxModx_Bridge_SetPlayerHealth(int playerId, int health);
+bool AmxModx_Bridge_SetPlayerArmor(int playerId, int armor);
+bool AmxModx_Bridge_SetPlayerFrags(int playerId, int frags);
+bool AmxModx_Bridge_SetPlayerDeaths(int playerId, int deaths);
+
+// 实体查找
+int AmxModx_Bridge_FindPlayerByUserID(int userId);
+int AmxModx_Bridge_FindPlayerByName(const char* name);
+int AmxModx_Bridge_FindPlayerByIPAddress(const char* ip);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _ENTITY_BRIDGE_H
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/event_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/event_bridge.h
new file mode 100644
index 0000000..65a70e5
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/event_bridge.h
@@ -0,0 +1,102 @@
+// vim: set ts=4 sw=4 tw=99 noet:
+//
+// Event System Bridge - C++ Header
+// Copyright (C) The AMX Mod X Development Team
+//
+// This software is licensed under the GNU General Public License, version 3 or higher.
+
+#pragma once
+
+#include
+#include "CEvent.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief 注册游戏事件
+ * @param eventName 事件名称
+ * @param callbackFunc 回调函数名
+ * @param flags 事件标志
+ * @param conditions 事件条件数组
+ * @param conditionCount 条件数量
+ * @return 事件句柄,失败返回0
+ */
+int AmxModx_Bridge_RegisterEvent(const char* eventName, const char* callbackFunc, int flags, const char** conditions, int conditionCount);
+
+/**
+ * @brief 扩展注册游戏事件
+ * @param eventName 事件名称
+ * @param callbackFunc 回调函数名
+ * @param flags 事件标志
+ * @param conditions 事件条件数组
+ * @param conditionCount 条件数量
+ * @return 事件句柄,失败返回0
+ */
+int AmxModx_Bridge_RegisterEventEx(const char* eventName, const char* callbackFunc, int flags, const char** conditions, int conditionCount);
+
+/**
+ * @brief 启用事件
+ * @param eventHandle 事件句柄
+ * @return 成功返回1,失败返回0
+ */
+int AmxModx_Bridge_EnableEvent(int eventHandle);
+
+/**
+ * @brief 禁用事件
+ * @param eventHandle 事件句柄
+ * @return 成功返回1,失败返回0
+ */
+int AmxModx_Bridge_DisableEvent(int eventHandle);
+
+/**
+ * @brief 获取事件ID
+ * @param eventName 事件名称
+ * @return 事件ID,0表示无效事件
+ */
+int AmxModx_Bridge_GetEventId(const char* eventName);
+
+/**
+ * @brief 检查事件是否有效
+ * @param eventHandle 事件句柄
+ * @return 有效返回1,无效返回0
+ */
+int AmxModx_Bridge_IsEventValid(int eventHandle);
+
+/**
+ * @brief 获取事件名称列表
+ * @param buffer 存储事件名称的缓冲区
+ * @param bufferSize 缓冲区大小
+ * @return 事件数量
+ */
+int AmxModx_Bridge_GetEventList(char** buffer, int bufferSize);
+
+/**
+ * @brief 获取事件参数数量
+ * @param eventName 事件名称
+ * @return 参数数量,-1表示无效事件
+ */
+int AmxModx_Bridge_GetEventParamCount(const char* eventName);
+
+/**
+ * @brief 获取事件参数名称
+ * @param eventName 事件名称
+ * @param paramIndex 参数索引(从0开始)
+ * @param buffer 存储参数名称的缓冲区
+ * @param bufferSize 缓冲区大小
+ * @return 成功返回1,失败返回0
+ */
+int AmxModx_Bridge_GetEventParamName(const char* eventName, int paramIndex, char* buffer, int bufferSize);
+
+/**
+ * @brief 获取事件参数类型
+ * @param eventName 事件名称
+ * @param paramIndex 参数索引(从0开始)
+ * @return 参数类型字符串,NULL表示无效事件或索引
+ */
+const char* AmxModx_Bridge_GetEventParamType(const char* eventName, int paramIndex);
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/fakemeta_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/fakemeta_bridge.h
new file mode 100644
index 0000000..af6f8dc
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/fakemeta_bridge.h
@@ -0,0 +1,271 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+// C++版本的事件类型枚举,与C#保持一致
+enum class FMB_ForwardType
+{
+ PrecacheModel = 0,
+ PrecacheSound = 1,
+ SetModel = 2,
+ CreateEntity = 3,
+ RemoveEntity = 4,
+ Spawn = 5,
+ Think = 6,
+ Use = 7,
+ Touch = 8,
+ Blocked = 9,
+ ClientCommand = 10,
+ ClientUserInfoChanged = 11,
+ ServerActivate = 12,
+ ServerDeactivate = 13,
+ PlayerPreThink = 14,
+ PlayerPostThink = 15,
+ StartFrame = 16,
+ ClientConnect = 17,
+ ClientDisconnect = 18,
+ ClientPutInServer = 19,
+ ClientKill = 20,
+ ClientSpawn = 21,
+ TraceLine = 22,
+ TraceToss = 23,
+ TraceMonsterHull = 24,
+ TraceHull = 25,
+ TraceModel = 26,
+ TraceTexture = 27,
+ TraceSphere = 28,
+ GetAimVector = 29,
+ EmitSound = 30,
+ EmitAmbientSound = 31,
+ LightStyle = 32,
+ DecalIndex = 33,
+ PointContents = 34,
+ MessageBegin = 35,
+ MessageEnd = 36,
+ WriteByte = 37,
+ WriteChar = 38,
+ WriteShort = 39,
+ WriteLong = 40,
+ WriteAngle = 41,
+ WriteCoord = 42,
+ WriteString = 43,
+ WriteEntity = 44,
+ CVarGetFloat = 45,
+ CVarGetString = 46,
+ CVarSetFloat = 47,
+ CVarSetString = 48,
+ CVarRegister = 49,
+ AlertMessage = 50,
+ EngineFprintf = 51,
+ PvsFindEntity = 52,
+ PvsEntitiesInPvs = 53,
+ PvsCheckOrigin = 54,
+ PvsCheckEntity = 55,
+ PvsCheckBox = 56,
+ PvsCheckPoint = 57,
+ PvsCheckEverything = 58,
+ PvsCheckEverything2 = 59,
+ PvsCheckEverything3 = 60,
+ PvsCheckEverything4 = 61,
+ PvsCheckEverything5 = 62,
+ PvsCheckEverything6 = 63,
+ PvsCheckEverything7 = 64,
+ PvsCheckEverything8 = 65,
+ PvsCheckEverything9 = 66,
+ PvsCheckEverything10 = 67,
+ PvsCheckEverything11 = 68,
+ PvsCheckEverything12 = 69,
+ PvsCheckEverything13 = 70,
+ PvsCheckEverything14 = 71,
+ PvsCheckEverything15 = 72,
+ PvsCheckEverything16 = 73,
+ PvsCheckEverything17 = 74,
+ PvsCheckEverything18 = 75,
+ PvsCheckEverything19 = 76,
+ PvsCheckEverything20 = 77,
+ PvsCheckEverything21 = 78,
+ PvsCheckEverything22 = 79,
+ PvsCheckEverything23 = 80,
+ PvsCheckEverything24 = 81,
+ PvsCheckEverything25 = 82,
+ PvsCheckEverything26 = 83,
+ PvsCheckEverything27 = 84,
+ PvsCheckEverything28 = 85,
+ PvsCheckEverything29 = 86,
+ PvsCheckEverything30 = 87,
+ PvsCheckEverything31 = 88,
+ PvsCheckEverything32 = 89,
+ PvsCheckEverything33 = 90,
+ PvsCheckEverything34 = 91,
+ PvsCheckEverything35 = 92,
+ PvsCheckEverything36 = 93,
+ PvsCheckEverything37 = 94,
+ PvsCheckEverything38 = 95,
+ PvsCheckEverything39 = 96,
+ PvsCheckEverything40 = 97,
+ PvsCheckEverything41 = 98,
+ PvsCheckEverything42 = 99,
+ PvsCheckEverything43 = 100,
+ PvsCheckEverything44 = 101,
+ PvsCheckEverything45 = 102,
+ PvsCheckEverything46 = 103,
+ PvsCheckEverything47 = 104,
+ PvsCheckEverything48 = 105,
+ PvsCheckEverything49 = 106,
+ PvsCheckEverything50 = 107,
+ PvsCheckEverything51 = 108,
+ PvsCheckEverything52 = 109,
+ PvsCheckEverything53 = 110,
+ PvsCheckEverything54 = 111,
+ PvsCheckEverything55 = 112,
+ PvsCheckEverything56 = 113,
+ PvsCheckEverything57 = 114,
+ PvsCheckEverything58 = 115,
+ PvsCheckEverything59 = 116,
+ PvsCheckEverything60 = 117,
+ PvsCheckEverything61 = 118,
+ PvsCheckEverything62 = 119,
+ PvsCheckEverything63 = 120,
+ PvsCheckEverything64 = 121,
+ PvsCheckEverything65 = 122,
+ PvsCheckEverything66 = 123,
+ PvsCheckEverything67 = 124,
+ PvsCheckEverything68 = 125,
+ PvsCheckEverything69 = 126,
+ PvsCheckEverything70 = 127,
+ PvsCheckEverything71 = 128,
+ PvsCheckEverything72 = 129,
+ PvsCheckEverything73 = 130,
+ PvsCheckEverything74 = 131
+};
+
+// 事件执行时机
+enum class FMB_ForwardTiming
+{
+ Pre = 0, // 前置钩子
+ Post = 1 // 后置钩子
+};
+
+// 事件处理结果
+enum class FMB_ForwardResult
+{
+ Ignored = 0, // 忽略,继续执行
+ Handled = 1, // 已处理,继续执行
+ Override = 2, // 覆盖,继续执行
+ Supercede = 3 // 取代,停止执行
+};
+
+// 事件数据结构体,与C#保持二进制兼容
+struct FMB_EventData
+{
+ int entityIndex; // 实体索引
+ const char* stringValue; // 字符串值
+ float floatValue; // 浮点值
+ int intValue; // 整数值
+ float vectorValue[3]; // 向量值
+ void* customData; // 自定义数据
+};
+
+// 回调函数类型定义
+using FMB_ForwardCallback = FMB_ForwardResult(*)(FMB_EventData&, void*);
+
+// 回调信息结构体
+struct FMB_CallbackInfo
+{
+ FMB_ForwardCallback callback;
+ void* userData;
+ int handle;
+ int priority; // 优先级,数值越高优先级越高
+};
+
+// 事件系统管理类
+class FMB_ForwardSystem
+{
+public:
+ static FMB_ForwardSystem& Instance();
+
+ // 初始化事件系统
+ bool Initialize();
+
+ // 清理事件系统
+ void Cleanup();
+
+ // 注册事件钩子
+ int RegisterForward(FMB_ForwardType type, FMB_ForwardTiming timing, FMB_ForwardCallback callback, void* userData);
+
+ // 注销事件钩子
+ bool UnregisterForward(FMB_ForwardType type, FMB_ForwardTiming timing, int handle);
+
+ // 触发事件
+ FMB_ForwardResult ExecuteForwards(FMB_ForwardType type, FMB_ForwardTiming timing, FMB_EventData& data);
+
+ // 获取事件数量
+ int GetForwardCount(FMB_ForwardType type, FMB_ForwardTiming timing);
+
+ // 检查事件是否已注册
+ bool IsForwardRegistered(FMB_ForwardType type, FMB_ForwardTiming timing, int handle);
+
+ // 获取事件类型名称
+ const char* GetForwardTypeName(FMB_ForwardType type);
+
+ // 获取事件时机名称
+ const char* GetForwardTimingName(FMB_ForwardTiming timing);
+
+ // 获取事件结果名称
+ const char* GetForwardResultName(FMB_ForwardResult result);
+
+private:
+ FMB_ForwardSystem() = default;
+ ~FMB_ForwardSystem() = default;
+
+ // 禁用拷贝构造和赋值
+ FMB_ForwardSystem(const FMB_ForwardSystem&) = delete;
+ FMB_ForwardSystem& operator=(const FMB_ForwardSystem&) = delete;
+
+ // 内部方法
+ std::vector& GetCallbacks(FMB_ForwardType type, FMB_ForwardTiming timing);
+ void SortCallbacksByPriority(std::vector& callbacks);
+
+ // 数据结构
+ std::unordered_map> preCallbacks;
+ std::unordered_map> postCallbacks;
+ int nextHandle = 1;
+ bool isInitialized = false;
+};
+
+// C接口导出函数
+extern "C"
+{
+ // 初始化事件系统
+ __declspec(dllexport) int FMB_InitializeForwardSystem();
+
+ // 清理事件系统
+ __declspec(dllexport) void FMB_CleanupForwardSystem();
+
+ // 注册事件钩子
+ __declspec(dllexport) int FMB_RegisterForward(FMB_ForwardType type, FMB_ForwardTiming timing, FMB_ForwardCallback callback, void* userData);
+
+ // 注销事件钩子
+ __declspec(dllexport) int FMB_UnregisterForward(FMB_ForwardType type, FMB_ForwardTiming timing, int handle);
+
+ // 触发事件
+ __declspec(dllexport) FMB_ForwardResult FMB_ExecuteForwards(FMB_ForwardType type, FMB_ForwardTiming timing, FMB_EventData& data);
+
+ // 获取事件数量
+ __declspec(dllexport) int FMB_GetForwardCount(FMB_ForwardType type, FMB_ForwardTiming timing);
+
+ // 检查事件是否已注册
+ __declspec(dllexport) int FMB_IsForwardRegistered(FMB_ForwardType type, FMB_ForwardTiming timing, int handle);
+
+ // 获取事件类型名称
+ __declspec(dllexport) const char* FMB_GetForwardTypeName(FMB_ForwardType type);
+
+ // 获取事件时机名称
+ __declspec(dllexport) const char* FMB_GetForwardTimingName(FMB_ForwardTiming timing);
+
+ // 获取事件结果名称
+ __declspec(dllexport) const char* FMB_GetForwardResultName(FMB_ForwardResult result);
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/file_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/file_bridge.h
new file mode 100644
index 0000000..4c3d011
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/file_bridge.h
@@ -0,0 +1,277 @@
+//
+// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
+// Copyright (C) The AMX Mod X Development Team.
+//
+// This software is licensed under the GNU General Public License, version 3 or higher.
+// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
+// https://alliedmods.net/amxmodx-license
+//
+
+#ifndef FILE_BRIDGE_H
+#define FILE_BRIDGE_H
+
+#include
+
+// 前向声明
+class CDataPack;
+class IGameConfig;
+class Vault;
+struct cvar_s;
+typedef struct cvar_s cvar_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// 文件系统桥接接口
+/**
+ * 读取文件内容到内存缓冲区
+ * @param filePath 文件路径
+ * @param size 返回文件大小
+ * @return 文件内容缓冲区,需要手动释放
+ */
+char* AmxModx_Bridge_ReadFile(const char* filePath, int* size);
+
+/**
+ * 将数据写入文件
+ * @param filePath 文件路径
+ * @param data 要写入的数据
+ * @param size 数据大小
+ * @return 写入是否成功
+ */
+bool AmxModx_Bridge_WriteFile(const char* filePath, const char* data, int size);
+
+/**
+ * 释放由ReadFile分配的缓冲区
+ * @param buffer 要释放的缓冲区
+ */
+void AmxModx_Bridge_FreeBuffer(char* buffer);
+
+/**
+ * 检查文件是否存在
+ * @param fileName 文件名
+ * @return 文件是否存在
+ */
+bool AmxModx_Bridge_FileExists(const char* fileName);
+
+/**
+ * 从文件读取字符串内容
+ * @param fileName 文件名
+ * @param buffer 输出缓冲区
+ * @param bufferSize 缓冲区大小
+ * @return 读取是否成功
+ */
+bool AmxModx_Bridge_ReadFileString(const char* fileName, char* buffer, int bufferSize);
+
+/**
+ * 将字符串写入文件
+ * @param fileName 文件名
+ * @param content 要写入的内容
+ * @return 写入是否成功
+ */
+bool AmxModx_Bridge_WriteFileString(const char* fileName, const char* content);
+
+/**
+ * 删除文件
+ * @param fileName 文件名
+ * @return 删除是否成功
+ */
+bool AmxModx_Bridge_DeleteFile(const char* fileName);
+
+// CDataPack桥接接口
+/**
+ * 创建新的数据包
+ * @return 新创建的数据包指针
+ */
+CDataPack* AmxModx_Bridge_CreateDataPack();
+
+/**
+ * 销毁数据包
+ * @param pack 要销毁的数据包
+ */
+void AmxModx_Bridge_DestroyDataPack(CDataPack* pack);
+
+/**
+ * 获取数据包当前位置
+ * @param pack 数据包指针
+ * @return 当前位置
+ */
+int AmxModx_Bridge_GetDataPackPosition(CDataPack* pack);
+
+/**
+ * 设置数据包位置
+ * @param pack 数据包指针
+ * @param position 要设置的位置
+ */
+void AmxModx_Bridge_SetDataPackPosition(CDataPack* pack, int position);
+
+/**
+ * 向数据包写入整数
+ * @param pack 数据包指针
+ * @param value 要写入的值
+ * @return 写入是否成功
+ */
+bool AmxModx_Bridge_WriteDataPackCell(CDataPack* pack, int value);
+
+/**
+ * 向数据包写入浮点数
+ * @param pack 数据包指针
+ * @param value 要写入的值
+ * @return 写入是否成功
+ */
+bool AmxModx_Bridge_WriteDataPackFloat(CDataPack* pack, float value);
+
+/**
+ * 向数据包写入字符串
+ * @param pack 数据包指针
+ * @param value 要写入的字符串
+ * @return 写入是否成功
+ */
+bool AmxModx_Bridge_WriteDataPackString(CDataPack* pack, const char* value);
+
+/**
+ * 从数据包读取整数
+ * @param pack 数据包指针
+ * @return 读取的整数值
+ */
+int AmxModx_Bridge_ReadDataPackCell(CDataPack* pack);
+
+/**
+ * 从数据包读取浮点数
+ * @param pack 数据包指针
+ * @return 读取的浮点数值
+ */
+float AmxModx_Bridge_ReadDataPackFloat(CDataPack* pack);
+
+/**
+ * 从数据包读取字符串
+ * @param pack 数据包指针
+ * @return 读取的字符串(静态缓冲区)
+ */
+const char* AmxModx_Bridge_ReadDataPackString(CDataPack* pack);
+
+// 控制台变量桥接接口
+/**
+ * 创建控制台变量
+ * @param name 变量名
+ * @param value 初始值
+ * @param flags 变量标志
+ * @return 创建的变量指针
+ */
+cvar_t* AmxModx_Bridge_CreateCVar(const char* name, const char* value, int flags);
+
+/**
+ * 查找控制台变量
+ * @param name 变量名
+ * @return 找到的变量指针
+ */
+cvar_t* AmxModx_Bridge_FindCVar(const char* name);
+
+/**
+ * 获取控制台变量字符串值
+ * @param cvar 变量指针
+ * @return 字符串值
+ */
+const char* AmxModx_Bridge_GetCVarString(cvar_t* cvar);
+
+/**
+ * 获取控制台变量浮点数值
+ * @param cvar 变量指针
+ * @return 浮点数值
+ */
+float AmxModx_Bridge_GetCVarFloat(cvar_t* cvar);
+
+/**
+ * 获取控制台变量整数值
+ * @param cvar 变量指针
+ * @return 整数值
+ */
+int AmxModx_Bridge_GetCVarInt(cvar_t* cvar);
+
+/**
+ * 设置控制台变量字符串值
+ * @param cvar 变量指针
+ * @param value 要设置的字符串值
+ */
+void AmxModx_Bridge_SetCVarString(cvar_t* cvar, const char* value);
+
+/**
+ * 设置控制台变量浮点数值
+ * @param cvar 变量指针
+ * @param value 要设置的浮点数值
+ */
+void AmxModx_Bridge_SetCVarFloat(cvar_t* cvar, float value);
+
+/**
+ * 设置控制台变量整数值
+ * @param cvar 变量指针
+ * @param value 要设置的整数值
+ */
+void AmxModx_Bridge_SetCVarInt(cvar_t* cvar, int value);
+
+// 游戏配置桥接接口
+/**
+ * 加载游戏配置文件
+ * @param filePath 配置文件路径
+ * @return 加载的配置对象指针
+ */
+IGameConfig* AmxModx_Bridge_LoadGameConfig(const char* filePath);
+
+/**
+ * 卸载游戏配置文件
+ * @param config 配置对象指针
+ */
+void AmxModx_Bridge_UnloadGameConfig(IGameConfig* config);
+
+/**
+ * 获取配置值
+ * @param config 配置对象指针
+ * @param key 配置键名
+ * @return 配置值字符串
+ */
+const char* AmxModx_Bridge_GetConfigValue(IGameConfig* config, const char* key);
+
+// 持久化存储桥接接口
+/**
+ * 获取全局Vault实例
+ * @return Vault实例指针
+ */
+Vault* AmxModx_Bridge_GetVault();
+
+/**
+ * 检查键是否存在
+ * @param vault Vault实例指针
+ * @param key 键名
+ * @return 键是否存在
+ */
+bool AmxModx_Bridge_VaultExists(Vault* vault, const char* key);
+
+/**
+ * 存储键值对
+ * @param vault Vault实例指针
+ * @param key 键名
+ * @param value 值
+ * @return 存储是否成功
+ */
+bool AmxModx_Bridge_VaultPut(Vault* vault, const char* key, const char* value);
+
+/**
+ * 移除键值对
+ * @param vault Vault实例指针
+ * @param key 键名
+ * @return 移除是否成功
+ */
+bool AmxModx_Bridge_VaultRemove(Vault* vault, const char* key);
+
+/**
+ * 获取键对应的值
+ * @param key 键名
+ * @return 值字符串
+ */
+const char* AmxModx_Bridge_VaultGet(const char* key);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // FILE_BRIDGE_H
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/forward_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/forward_bridge.h
new file mode 100644
index 0000000..858955c
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/forward_bridge.h
@@ -0,0 +1,81 @@
+// vim: set ts=4 sw=4 tw=99 noet:
+//
+// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
+// Copyright (C) The AMX Mod X Development Team.
+//
+// This software is licensed under the GNU General Public License, version 3 or higher.
+// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
+// https://alliedmods.net/amxmodx-license
+
+#ifndef _FORWARD_BRIDGE_H_
+#define _FORWARD_BRIDGE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * 创建多插件转发器
+ * @param funcName 转发器名称
+ * @param execType 执行类型 (0=忽略, 1=停止, 2=停止2, 3=继续)
+ * @param numParams 参数数量
+ * @param paramTypes 参数类型数组
+ * @return 转发器ID,失败返回-1
+ */
+int AmxModx_Bridge_CreateMultiForward(const char* funcName, int execType, int numParams, int* paramTypes);
+
+/**
+ * 创建单插件转发器
+ * @param pluginId 插件ID
+ * @param funcName 函数名称
+ * @param numParams 参数数量
+ * @param paramTypes 参数类型数组
+ * @return 转发器ID,失败返回-1
+ */
+int AmxModx_Bridge_CreateOneForward(int pluginId, const char* funcName, int numParams, int* paramTypes);
+
+/**
+ * 销毁转发器
+ * @param forwardId 转发器ID
+ * @return 成功返回1,失败返回0
+ */
+int AmxModx_Bridge_DestroyForward(int forwardId);
+
+/**
+ * 执行转发器
+ * @param forwardId 转发器ID
+ * @param params 参数数组
+ * @param numParams 参数数量
+ * @return 执行结果
+ */
+int AmxModx_Bridge_ExecuteForward(int forwardId, int* params, int numParams);
+
+/**
+ * 准备数组参数
+ * @param arrayData 数组数据
+ * @param size 数组大小
+ * @param copyBack 是否复制回数据
+ * @return 数组句柄
+ */
+int AmxModx_Bridge_PrepareArray(int* arrayData, int size, int copyBack);
+
+/**
+ * 获取转发器参数数量
+ * @param forwardId 转发器ID
+ * @return 参数数量,失败返回-1
+ */
+int AmxModx_Bridge_GetForwardParamCount(int forwardId);
+
+/**
+ * 获取转发器参数类型
+ * @param forwardId 转发器ID
+ * @param paramIndex 参数索引
+ * @return 参数类型,失败返回-1
+ */
+int AmxModx_Bridge_GetForwardParamType(int forwardId, int paramIndex);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _FORWARD_BRIDGE_H_
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/fun_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/fun_bridge.h
new file mode 100644
index 0000000..3bc0cdb
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/fun_bridge.h
@@ -0,0 +1,54 @@
+// vim: set ts=4 sw=4 tw=99 noet:
+//
+// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
+// Copyright (C) The AMX Mod X Development Team.
+//
+// This software is licensed under the GNU General Public License, version 3 or higher.
+// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
+// https://alliedmods.net/amxmodx-license
+
+//
+// Fun Module Bridge
+//
+
+#pragma once
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// 玩家状态管理
+int GetClientListening(int receiver, int sender);
+int SetClientListening(int receiver, int sender, int listen);
+int SetUserGodmode(int index, int godmode);
+int GetUserGodmode(int index);
+int SetUserHealth(int index, float health);
+float GetUserHealth(int index);
+int GiveItem(int index, const char* item);
+int SpawnEntity(int index);
+int SetUserFrags(int index, int frags);
+int GetUserFrags(int index);
+int SetUserArmor(int index, int armor);
+int GetUserArmor(int index);
+int SetUserOrigin(int index, const float origin[3]);
+int GetUserOrigin(int index, float *origin);
+int SetUserRendering(int index, int renderMode, int renderAmount, int renderFx, const float *renderColor);
+int GetUserRendering(int index, int *renderMode, int *renderAmount, int *renderFx, float *renderColor);
+int SetUserMaxspeed(int index, float maxspeed);
+float GetUserMaxspeed(int index);
+int SetUserGravity(int index, float gravity);
+float GetUserGravity(int index);
+int SetUserHitzones(int index, int zones);
+int GetUserHitzones(int index);
+int SetUserNoclip(int index, int noclip);
+int GetUserNoclip(int index);
+int SetUserFootsteps(int index, int footsteps);
+int GetUserFootsteps(int index);
+int StripUserWeapons(int index);
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/gameconfigs_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/gameconfigs_bridge.h
new file mode 100644
index 0000000..a366e63
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/gameconfigs_bridge.h
@@ -0,0 +1,65 @@
+// gameconfigs_bridge.h
+// 游戏配置系统桥接接口定义
+#pragma once
+
+#include "../amxmodx.h"
+#include "../gameconfigs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * 加载游戏配置文件
+ * @param fileName 配置文件名
+ * @param errorBuffer 错误信息缓冲区
+ * @param errorBufferSize 缓冲区大小
+ * @return 游戏配置句柄,失败返回0
+ */
+int AmxModx_Bridge_LoadGameConfigFile(const char* fileName, char* errorBuffer, int errorBufferSize);
+
+/**
+ * 获取游戏配置偏移量
+ * @param handle 游戏配置句柄
+ * @param key 配置键名
+ * @return 偏移量值,失败返回-1
+ */
+int AmxModx_Bridge_GameConfGetOffset(int handle, const char* key);
+
+/**
+ * 获取类配置偏移量
+ * @param handle 游戏配置句柄
+ * @param className 类名
+ * @param key 配置键名
+ * @return 偏移量值,失败返回-1
+ */
+int AmxModx_Bridge_GameConfGetClassOffset(int handle, const char* className, const char* key);
+
+/**
+ * 获取游戏配置键值
+ * @param handle 游戏配置句柄
+ * @param key 配置键名
+ * @param buffer 输出缓冲区
+ * @param bufferSize 缓冲区大小
+ * @return 是否成功获取
+ */
+int AmxModx_Bridge_GameConfGetKeyValue(int handle, const char* key, char* buffer, int bufferSize);
+
+/**
+ * 获取游戏配置地址
+ * @param handle 游戏配置句柄
+ * @param name 地址名
+ * @return 地址值,失败返回0
+ */
+uintptr_t AmxModx_Bridge_GameConfGetAddress(int handle, const char* name);
+
+/**
+ * 关闭游戏配置文件
+ * @param handle 游戏配置句柄(传引用,成功后会置0)
+ * @return 是否成功关闭
+ */
+int AmxModx_Bridge_CloseGameConfigFile(int* handle);
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/hamsandwich_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/hamsandwich_bridge.h
new file mode 100644
index 0000000..015cdeb
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/hamsandwich_bridge.h
@@ -0,0 +1,53 @@
+// hamsandwich_bridge.h
+// HAM Sandwich桥接层头文件
+
+#ifndef HAMSANDWICH_BRIDGE_H
+#define HAMSANDWICH_BRIDGE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// 初始化/清理
+void InitializeHamSandwichBridge();
+void CleanupHamSandwichBridge();
+
+// 钩子管理
+int RegisterHamHook(int function, int entityIndex, void* preCallback, void* postCallback);
+bool EnableHamHook(int hookId);
+bool DisableHamHook(int hookId);
+bool RemoveHamHook(int hookId);
+
+// 返回值处理
+int GetReturnStatus();
+int GetReturnValueInt();
+float GetReturnValueFloat();
+int GetReturnValueEntity();
+void GetReturnValueVector(float vec[3]);
+
+void SetReturnValueInt(int value);
+void SetReturnValueFloat(float value);
+void SetReturnValueVector(const float vec[3]);
+void SetReturnValueEntity(int entity);
+
+// 参数处理
+int GetParameterInt(int paramIndex);
+float GetParameterFloat(int paramIndex);
+int GetParameterEntity(int paramIndex);
+void GetParameterVector(int paramIndex, float vec[3]);
+
+void SetParameterInt(int paramIndex, int value);
+void SetParameterFloat(int paramIndex, float value);
+void SetParameterVector(int paramIndex, const float vec[3]);
+void SetParameterEntity(int paramIndex, int entity);
+
+// 实用工具
+bool IsValidHamFunction(int function);
+const char* GetHamFunctionName(int function);
+int GetHamFunctionCount();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HAMSANDWICH_BRIDGE_H
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/hamsandwich_direct_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/hamsandwich_direct_bridge.h
new file mode 100644
index 0000000..804af77
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/hamsandwich_direct_bridge.h
@@ -0,0 +1,43 @@
+#pragma once
+
+// 前置声明,避免包含vector.h头文件
+struct edict_s;
+typedef struct edict_s edict_t;
+
+// 直接桥接接口 - 不依赖AMXX函数
+extern "C" {
+
+// 实体和偏移验证
+bool IsValidEntity(int entityId);
+bool IsValidOffset(int offset);
+
+// 直接数据访问
+int GetEntityPrivateDataInt(int entityId, int offset);
+float GetEntityPrivateDataFloat(int entityId, int offset);
+int GetEntityPrivateDataEntity(int entityId, int offset);
+void SetEntityPrivateDataInt(int entityId, int offset, int value);
+void SetEntityPrivateDataFloat(int entityId, int offset, float value);
+void SetEntityPrivateDataEntity(int entityId, int offset, int targetEntity);
+
+// 向量数据访问
+void GetEntityPrivateDataVector(int entityId, int offset, float vec[3]);
+void SetEntityPrivateDataVector(int entityId, int offset, const float vec[3]);
+
+// 实体变量访问
+int GetEntityVarInt(int entityId, int offset);
+float GetEntityVarFloat(int entityId, int offset);
+void GetEntityVarVector(int entityId, int offset, float vec[3]);
+void SetEntityVarInt(int entityId, int offset, int value);
+void SetEntityVarFloat(int entityId, int offset, float value);
+void SetEntityVarVector(int entityId, int offset, const float vec[3]);
+
+// 直接内存操作
+void* GetEntityBasePointer(int entityId);
+int GetEntityMemorySize(int entityId);
+
+// 工具函数
+int EntityToIndex(edict_t* edict);
+edict_t* IndexToEntity(int index);
+void* GetPrivateDataPtr(int entityId);
+
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/hamsandwich_game_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/hamsandwich_game_bridge.h
new file mode 100644
index 0000000..107ab1c
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/hamsandwich_game_bridge.h
@@ -0,0 +1,48 @@
+// hamsandwich_game_bridge.h
+// 游戏特定钩子的桥接头文件
+
+#ifndef HAMSANDWICH_GAME_BRIDGE_H
+#define HAMSANDWICH_GAME_BRIDGE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// 游戏特定钩子注册函数
+extern "C" {
+
+// Counter-Strike钩子
+int RegisterCsPlayerOnTouchingWeaponHook(const char* entityClass, void* preCallback, void* postCallback);
+int RegisterCsItemGetMaxSpeedHook(const char* entityClass, void* preCallback, void* postCallback);
+int RegisterCsItemCanDropHook(const char* entityClass, void* preCallback, void* postCallback);
+int RegisterCsRestartHook(void* preCallback, void* postCallback);
+int RegisterCsRoundRespawnHook(void* preCallback, void* postCallback);
+
+// Team Fortress Classic钩子
+int RegisterTfcEngineerUseHook(const char* entityClass, void* preCallback, void* postCallback);
+int RegisterTfcEmpExplodeHook(const char* entityClass, void* preCallback, void* postCallback);
+int RegisterTfcTakeEmpBlastHook(const char* entityClass, void* preCallback, void* postCallback);
+int RegisterTfcRadiusDamage2Hook(const char* entityClass, void* preCallback, void* postCallback);
+
+// Day of Defeat钩子
+int RegisterDodWeaponSpecialHook(const char* entityClass, void* preCallback, void* postCallback);
+int RegisterDodRoundRespawnHook(void* preCallback, void* postCallback);
+int RegisterDodItemCanDropHook(const char* entityClass, void* preCallback, void* postCallback);
+
+// The Specialists钩子
+int RegisterTsBreakableRespawnHook(const char* entityClass, void* preCallback, void* postCallback);
+int RegisterTsShouldCollideHook(const char* entityClass, void* preCallback, void* postCallback);
+int RegisterTsCanUsedThroughWallsHook(const char* entityClass, void* preCallback, void* postCallback);
+
+// Natural Selection钩子
+int RegisterNsUpdateOnRemoveHook(const char* entityClass, void* preCallback, void* postCallback);
+int RegisterNsGetPointValueHook(const char* entityClass, void* preCallback, void* postCallback);
+int RegisterNsAwardKillHook(void* preCallback, void* postCallback);
+
+// Earth's Special Forces钩子
+int RegisterEsfWeaponHolsterWhenMeleedHook(const char* entityClass, void* preCallback, void* postCallback);
+int RegisterEsfTakeDamage2Hook(const char* entityClass, void* preCallback, void* postCallback);
+}
+#endif
+
+#endif // HAMSANDWICH_GAME_BRIDGE_H
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/hamsandwich_hook_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/hamsandwich_hook_bridge.h
new file mode 100644
index 0000000..2a19067
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/hamsandwich_hook_bridge.h
@@ -0,0 +1,61 @@
+#pragma once
+
+// 前置声明
+struct edict_s;
+typedef struct edict_s edict_t;
+
+// 回调函数类型定义
+typedef void (*HamHookCallback)(int entity, int paramCount, void** parameters);
+typedef void (*HamHookCallbackPost)(int entity, int paramCount, void** parameters);
+
+// 注意:HAM函数枚举值已在ham_const.h中定义,这里直接使用
+
+// 钩子管理接口
+extern "C" {
+ // 注册钩子
+ int RegisterHamHook(int function, const char* entityClass,
+ HamHookCallback preCallback, HamHookCallbackPost postCallback);
+
+ int RegisterHamHookFromEntity(int function, int entityId,
+ HamHookCallback preCallback, HamHookCallbackPost postCallback);
+
+ int RegisterHamHookPlayer(int function,
+ HamHookCallback preCallback, HamHookCallbackPost postCallback);
+
+ // 钩子控制
+ void EnableHamHook(int hookId);
+ void DisableHamHook(int hookId);
+ int IsHamHookValid(int function);
+
+ // 初始化/清理
+ void InitializeHamSandwichBridge();
+ void CleanupHamSandwichBridge();
+}
+
+// 内部使用的前向声明
+namespace HamHooks {
+ struct HookData;
+ struct ForwardData;
+}
+
+// 参数访问辅助函数
+extern "C" {
+ // 返回值处理
+ int GetReturnStatus();
+ int GetReturnValueInt();
+ float GetReturnValueFloat();
+ void GetReturnValueVector(float vec[3]);
+ int GetReturnValueEntity();
+
+ // 设置返回值
+ void SetReturnValueInt(int value);
+ void SetReturnValueFloat(float value);
+ void SetReturnValueVector(const float vec[3]);
+ void SetReturnValueEntity(int entity);
+
+ // 参数处理
+ void SetParameterInt(int paramIndex, int value);
+ void SetParameterFloat(int paramIndex, float value);
+ void SetParameterVector(int paramIndex, const float vec[3]);
+ void SetParameterEntity(int paramIndex, int entity);
+}
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/hamsandwich_structs_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/hamsandwich_structs_bridge.h
new file mode 100644
index 0000000..de1d05d
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/hamsandwich_structs_bridge.h
@@ -0,0 +1,54 @@
+// hamsandwich_structs_bridge.h
+// 复杂结构体的桥接头文件
+
+#ifndef HAMSANDWICH_STRUCTS_BRIDGE_H
+#define HAMSANDWICH_STRUCTS_BRIDGE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// TraceResult结构体访问函数
+void GetTraceResultAllSolid(void* traceResult, int* allSolid);
+void GetTraceResultStartSolid(void* traceResult, int* startSolid);
+void GetTraceResultFraction(void* traceResult, float* fraction);
+void GetTraceResultEndPos(void* traceResult, float endPos[3]);
+void GetTraceResultPlaneNormal(void* traceResult, float normal[3]);
+void GetTraceResultHit(void* traceResult, int* hit);
+void GetTraceResultHitGroup(void* traceResult, int* hitGroup);
+
+// ItemInfo结构体访问函数
+void GetItemInfoName(void* itemInfo, char* name, int maxLen);
+void GetItemInfoMaxClip(void* itemInfo, int* maxClip);
+void GetItemInfoSlot(void* itemInfo, int* slot);
+void GetItemInfoPosition(void* itemInfo, int* position);
+void GetItemInfoId(void* itemInfo, int* id);
+void GetItemInfoFlags(void* itemInfo, int* flags);
+
+void SetItemInfoMaxClip(void* itemInfo, int maxClip);
+void SetItemInfoSlot(void* itemInfo, int slot);
+void SetItemInfoPosition(void* itemInfo, int position);
+void SetItemInfoFlags(void* itemInfo, int flags);
+
+// 向量操作辅助函数
+void VectorNormalize(float vec[3]);
+float VectorLength(const float vec[3]);
+void VectorAdd(const float a[3], const float b[3], float result[3]);
+void VectorSubtract(const float a[3], const float b[3], float result[3]);
+void VectorScale(const float vec[3], float scale, float result[3]);
+
+// 实体变换矩阵访问
+void GetEntityOrigin(int entity, float origin[3]);
+void GetEntityAngles(int entity, float angles[3]);
+void SetEntityOrigin(int entity, const float origin[3]);
+void SetEntityAngles(int entity, const float angles[3]);
+
+// 距离和可见性检查
+float GetDistanceBetweenEntities(int entity1, int entity2);
+bool IsEntityVisible(int entity, int target);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HAMSANDWICH_STRUCTS_BRIDGE_H
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/messages_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/messages_bridge.h
new file mode 100644
index 0000000..05c25e2
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/messages_bridge.h
@@ -0,0 +1,165 @@
+// messages_bridge.h
+// 消息系统桥接接口定义
+#pragma once
+
+#include "../amxmodx.h"
+#include "../messages.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * 开始发送消息
+ * @param msg_dest 消息目标
+ * @param msg_type 消息类型
+ * @param origin 消息原点坐标
+ * @param edict 实体指针
+ */
+void AmxModx_Bridge_MessageBegin(int msg_dest, int msg_type, const float* origin, int edict);
+
+/**
+ * 结束消息发送
+ */
+void AmxModx_Bridge_MessageEnd(void);
+
+/**
+ * 写入字节数据到消息
+ * @param value 字节值
+ */
+void AmxModx_Bridge_WriteByte(int value);
+
+/**
+ * 写入字符数据到消息
+ * @param value 字符值
+ */
+void AmxModx_Bridge_WriteChar(int value);
+
+/**
+ * 写入短整型数据到消息
+ * @param value 短整型值
+ */
+void AmxModx_Bridge_WriteShort(int value);
+
+/**
+ * 写入长整型数据到消息
+ * @param value 长整型值
+ */
+void AmxModx_Bridge_WriteLong(int value);
+
+/**
+ * 写入实体数据到消息
+ * @param value 实体索引
+ */
+void AmxModx_Bridge_WriteEntity(int value);
+
+/**
+ * 写入角度数据到消息
+ * @param value 角度值
+ */
+void AmxModx_Bridge_WriteAngle(float value);
+
+/**
+ * 写入坐标数据到消息
+ * @param value 坐标值
+ */
+void AmxModx_Bridge_WriteCoord(float value);
+
+/**
+ * 写入字符串数据到消息
+ * @param str 字符串值
+ */
+void AmxModx_Bridge_WriteString(const char* str);
+
+/**
+ * 注册消息钩子
+ * @param msgId 消息ID
+ * @param callback 回调函数指针
+ * @param post 是否为后置钩子
+ * @return 是否注册成功
+ */
+int AmxModx_Bridge_RegisterMessage(int msgId, void* callback, int post);
+
+/**
+ * 注销消息钩子
+ * @param msgId 消息ID
+ * @param callback 回调函数指针
+ * @param post 是否为后置钩子
+ * @return 是否注销成功
+ */
+int AmxModx_Bridge_UnregisterMessage(int msgId, void* callback, int post);
+
+/**
+ * 设置消息阻塞
+ * @param msgId 消息ID
+ * @param blocking 是否阻塞
+ */
+void AmxModx_Bridge_SetMessageBlock(int msgId, int blocking);
+
+/**
+ * 获取消息阻塞状态
+ * @param msgId 消息ID
+ * @return 阻塞状态
+ */
+int AmxModx_Bridge_GetMessageBlock(int msgId);
+
+/**
+ * 获取消息参数数量
+ * @return 参数数量
+ */
+int AmxModx_Bridge_GetMessageArgs(void);
+
+/**
+ * 获取消息参数类型
+ * @param argIndex 参数索引
+ * @return 参数类型
+ */
+int AmxModx_Bridge_GetMessageArgType(int argIndex);
+
+/**
+ * 获取消息参数整数值
+ * @param argIndex 参数索引
+ * @return 整数值
+ */
+int AmxModx_Bridge_GetMessageArgInt(int argIndex);
+
+/**
+ * 获取消息参数浮点数值
+ * @param argIndex 参数索引
+ * @return 浮点数值
+ */
+float AmxModx_Bridge_GetMessageArgFloat(int argIndex);
+
+/**
+ * 获取消息参数字符串值
+ * @param argIndex 参数索引
+ * @param buffer 输出缓冲区
+ * @param bufferSize 缓冲区大小
+ * @return 实际复制的字符数
+ */
+int AmxModx_Bridge_GetMessageArgString(int argIndex, char* buffer, int bufferSize);
+
+/**
+ * 设置消息参数整数值
+ * @param argIndex 参数索引
+ * @param value 整数值
+ */
+void AmxModx_Bridge_SetMessageArgInt(int argIndex, int value);
+
+/**
+ * 设置消息参数浮点数值
+ * @param argIndex 参数索引
+ * @param value 浮点数值
+ */
+void AmxModx_Bridge_SetMessageArgFloat(int argIndex, float value);
+
+/**
+ * 设置消息参数字符串值
+ * @param argIndex 参数索引
+ * @param str 字符串值
+ */
+void AmxModx_Bridge_SetMessageArgString(int argIndex, const char* str);
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/natives_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/natives_bridge.h
new file mode 100644
index 0000000..bac4d8d
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/natives_bridge.h
@@ -0,0 +1,45 @@
+// vim: set ts=4 sw=4 tw=99 noet:
+#ifndef _INCLUDE_NATIVES_BRIDGE_H
+#define _INCLUDE_NATIVES_BRIDGE_H
+
+#include
+
+// 前向声明AMX结构体
+#include "amx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// 原生函数注册管理
+int AmxModx_Bridge_RegisterNative(AMX *amx, const char *name, AMX_NATIVE func);
+int AmxModx_Bridge_UnregisterNative(AMX *amx, const char *name);
+int AmxModx_Bridge_RegisterLibrary(AMX *amx, const char *libname);
+int AmxModx_Bridge_GetNativeCount(AMX *amx);
+const char *AmxModx_Bridge_GetNativeName(AMX *amx, int index);
+bool AmxModx_Bridge_NativeExists(AMX *amx, const char *name);
+void AmxModx_Bridge_ClearLibraries(AMX *amx);
+
+// 参数处理
+const char *AmxModx_Bridge_GetString(AMX *amx, cell param, int *length);
+int AmxModx_Bridge_SetString(AMX *amx, cell param, const char *string, int maxlen);
+cell AmxModx_Bridge_GetParam(AMX *amx, int index);
+cell *AmxModx_Bridge_GetParamAddress(AMX *amx, int index);
+int AmxModx_Bridge_SetParam(AMX *amx, int index, cell value);
+
+// 浮点数处理
+float AmxModx_Bridge_GetFloat(AMX *amx, int index);
+int AmxModx_Bridge_SetFloat(AMX *amx, int index, float value);
+
+// 数组处理
+int AmxModx_Bridge_GetArray(AMX *amx, cell param, cell *dest, int size);
+int AmxModx_Bridge_SetArray(AMX *amx, cell param, const cell *source, int size);
+
+// 错误处理
+void AmxModx_Bridge_LogError(AMX *amx, int err, const char *message);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _INCLUDE_NATIVES_BRIDGE_H
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/newmenus_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/newmenus_bridge.h
new file mode 100644
index 0000000..5a18632
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/newmenus_bridge.h
@@ -0,0 +1,147 @@
+// newmenus_bridge.h
+// 新菜单系统桥接接口定义
+#pragma once
+
+#include "../amxmodx.h"
+#include "../CMenu.h"
+#include "../newmenus.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * 创建新菜单
+ * @param title 菜单标题
+ * @param handler 菜单处理函数
+ * @param useMultiLanguage 是否使用多语言
+ * @return 菜单句柄,失败返回-1
+ */
+int AmxModx_Bridge_MenuCreate(const char* title, void* handler, int useMultiLanguage);
+
+/**
+ * 销毁菜单
+ * @param menuHandle 菜单句柄(传引用,成功后会置-1)
+ * @return 是否成功销毁
+ */
+int AmxModx_Bridge_MenuDestroy(int* menuHandle);
+
+/**
+ * 添加菜单项
+ * @param menuHandle 菜单句柄
+ * @param text 菜单项文本
+ * @param command 菜单项命令
+ * @param access 访问权限
+ * @return 菜单项索引,失败返回-1
+ */
+int AmxModx_Bridge_MenuAddItem(int menuHandle, const char* text, const char* command, int access);
+
+/**
+ * 添加空白菜单项
+ * @param menuHandle 菜单句柄
+ * @param slots 占用的槽位数
+ * @return 是否成功添加
+ */
+int AmxModx_Bridge_MenuAddBlank(int menuHandle, int slots);
+
+/**
+ * 添加文本菜单项
+ * @param menuHandle 菜单句柄
+ * @param text 菜单项文本
+ * @param slots 占用的槽位数
+ * @return 是否成功添加
+ */
+int AmxModx_Bridge_MenuAddText(int menuHandle, const char* text, int slots);
+
+/**
+ * 显示菜单给玩家
+ * @param menuHandle 菜单句柄
+ * @param playerIndex 玩家索引
+ * @param page 起始页码
+ * @return 是否成功显示
+ */
+int AmxModx_Bridge_MenuDisplay(int menuHandle, int playerIndex, int page);
+
+/**
+ * 取消玩家菜单
+ * @param playerIndex 玩家索引
+ * @return 是否成功取消
+ */
+int AmxModx_Bridge_MenuCancel(int playerIndex);
+
+/**
+ * 设置菜单属性
+ * @param menuHandle 菜单句柄
+ * @param prop 属性类型
+ * @param value 属性值
+ * @return 是否成功设置
+ */
+int AmxModx_Bridge_MenuSetProperty(int menuHandle, int prop, int value);
+
+/**
+ * 获取菜单项信息
+ * @param menuHandle 菜单句柄
+ * @param itemIndex 菜单项索引
+ * @param textBuffer 文本输出缓冲区
+ * @param textBufferSize 文本缓冲区大小
+ * @param commandBuffer 命令输出缓冲区
+ * @param commandBufferSize 命令缓冲区大小
+ * @param access 访问权限输出
+ * @return 是否成功获取
+ */
+int AmxModx_Bridge_MenuGetItemInfo(int menuHandle, int itemIndex,
+ char* textBuffer, int textBufferSize,
+ char* commandBuffer, int commandBufferSize,
+ int* access);
+
+/**
+ * 设置菜单项名称
+ * @param menuHandle 菜单句柄
+ * @param itemIndex 菜单项索引
+ * @param newName 新名称
+ * @return 是否成功设置
+ */
+int AmxModx_Bridge_MenuSetItemName(int menuHandle, int itemIndex, const char* newName);
+
+/**
+ * 设置菜单项命令
+ * @param menuHandle 菜单句柄
+ * @param itemIndex 菜单项索引
+ * @param newCommand 新命令
+ * @return 是否成功设置
+ */
+int AmxModx_Bridge_MenuSetItemCommand(int menuHandle, int itemIndex, const char* newCommand);
+
+/**
+ * 获取菜单页数
+ * @param menuHandle 菜单句柄
+ * @return 页数,失败返回-1
+ */
+int AmxModx_Bridge_MenuGetPages(int menuHandle);
+
+/**
+ * 获取菜单项数
+ * @param menuHandle 菜单句柄
+ * @return 项数,失败返回-1
+ */
+int AmxModx_Bridge_MenuGetItems(int menuHandle);
+
+/**
+ * 查找菜单ID
+ * @param menuName 菜单名称
+ * @return 菜单ID,失败返回-1
+ */
+int AmxModx_Bridge_MenuFindId(const char* menuName);
+
+/**
+ * 获取玩家菜单信息
+ * @param playerIndex 玩家索引
+ * @param menuHandle 菜单句柄输出
+ * @param item 选择项输出
+ * @return 是否成功获取
+ */
+int AmxModx_Bridge_PlayerMenuInfo(int playerIndex, int* menuHandle, int* item);
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/stackstructs_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/stackstructs_bridge.h
new file mode 100644
index 0000000..af195bd
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/stackstructs_bridge.h
@@ -0,0 +1,47 @@
+// stackstructs_bridge.h
+// 栈管理接口
+
+#ifndef STACKSTRUCTS_BRIDGE_H
+#define STACKSTRUCTS_BRIDGE_H
+
+#include "../amxmodx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// 创建栈
+int AmxModx_Bridge_CreateStack();
+
+// 销毁栈
+int AmxModx_Bridge_DestroyStack(int* handle);
+
+// 压入单元格值
+int AmxModx_Bridge_PushStackCell(int handle, int value);
+
+// 压入字符串
+int AmxModx_Bridge_PushStackString(int handle, const char* str);
+
+// 压入数组
+int AmxModx_Bridge_PushStackArray(int handle, int arrayHandle);
+
+// 弹出单元格值
+int AmxModx_Bridge_PopStackCell(int handle, int* value);
+
+// 弹出字符串
+int AmxModx_Bridge_PopStackString(int handle, char* buffer, int size);
+
+// 弹出数组
+int AmxModx_Bridge_PopStackArray(int handle, int* arrayHandle);
+
+// 获取栈深度
+int AmxModx_Bridge_GetStackDepth(int handle);
+
+// 清空栈
+int AmxModx_Bridge_ClearStack(int handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/task_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/task_bridge.h
new file mode 100644
index 0000000..3dfeef1
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/task_bridge.h
@@ -0,0 +1,42 @@
+// vim: set ts=4 sw=4 tw=99 noet:
+//
+// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
+// Copyright (C) The AMX Mod X Development Team.
+//
+// This software is licensed under the GNU General Public License, version 3 or higher.
+// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
+// https://alliedmods.net/amxmodx-license
+
+#ifndef TASK_BRIDGE_H
+#define TASK_BRIDGE_H
+
+#include "amxmodx.h"
+
+// 任务标志位定义
+#define TASK_FLAG_REPEAT 1
+#define TASK_FLAG_LOOP 2
+#define TASK_FLAG_AFTER_START 4
+#define TASK_FLAG_BEFORE_END 8
+
+// 任务调度系统桥接接口
+extern "C" {
+ // 创建任务
+ int AmxModx_Bridge_CreateTask(int pluginId, int funcId, int flags, int taskId, float interval, int repeat, cell* params, int paramCount);
+
+ // 移除任务
+ int AmxModx_Bridge_RemoveTasks(int pluginId, int taskId);
+
+ // 修改任务间隔
+ int AmxModx_Bridge_ChangeTaskInterval(int pluginId, int taskId, float newInterval);
+
+ // 检查任务是否存在
+ bool AmxModx_Bridge_TaskExists(int pluginId, int taskId);
+
+ // 获取当前活动任务数量
+ int AmxModx_Bridge_GetActiveTaskCount();
+
+ // 获取任务信息
+ bool AmxModx_Bridge_GetTaskInfo(int pluginId, int taskId, float* interval, int* repeat, int* flags);
+}
+
+#endif // TASK_BRIDGE_H
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/CppInterface/vector_bridge.h b/Template/Amxmodx.Module.Template/CppInterface/vector_bridge.h
new file mode 100644
index 0000000..bc667f5
--- /dev/null
+++ b/Template/Amxmodx.Module.Template/CppInterface/vector_bridge.h
@@ -0,0 +1,38 @@
+// vim: set ts=4 sw=4 tw=99 noet:
+//
+// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
+// Copyright (C) The AMX Mod X Development Team.
+//
+// This software is licensed under the GNU General Public License, version 3 or higher.
+// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
+// https://alliedmods.net/amxmodx-license
+
+#ifndef _VECTOR_BRIDGE_H_
+#define _VECTOR_BRIDGE_H_
+
+#include "amxmodx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// 向量转角度
+void AmxModx_Bridge_VectorToAngle(float x, float y, float z, float* outX, float* outY, float* outZ);
+
+// 角度转向量
+void AmxModx_Bridge_AngleVector(float pitch, float yaw, float roll, int type, float* outX, float* outY, float* outZ);
+
+// 向量长度
+float AmxModx_Bridge_VectorLength(float x, float y, float z);
+
+// 向量距离
+float AmxModx_Bridge_VectorDistance(float x1, float y1, float z1, float x2, float y2, float z2);
+
+// 通过实体瞄准方向获取速度
+bool AmxModx_Bridge_VelocityByAim(int entity, int velocity, float* outX, float* outY, float* outZ);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _VECTOR_BRIDGE_H_
\ No newline at end of file
diff --git a/Template/Amxmodx.Module.Template/Module.cs b/Template/Amxmodx.Module.Template/Module.cs
index bf1c429..9b1017c 100644
--- a/Template/Amxmodx.Module.Template/Module.cs
+++ b/Template/Amxmodx.Module.Template/Module.cs
@@ -1,4 +1,4 @@
-using GoldSrc.Amxmodx;
+using GoldSrc.Amxmodx;
using GoldSrc.Amxmodx.Native;
using GoldSrc.HLSDK;
using GoldSrc.HLSDK.Native;
diff --git a/Template/Amxmodx.Module.Template/Plugin.cs b/Template/Amxmodx.Module.Template/Plugin.cs
index a810207..11e83d0 100644
--- a/Template/Amxmodx.Module.Template/Plugin.cs
+++ b/Template/Amxmodx.Module.Template/Plugin.cs
@@ -1,4 +1,4 @@
-using GoldSrc.Amxmodx.Native;
+using GoldSrc.Amxmodx.Native;
using GoldSrc.HLSDK;
using GoldSrc.HLSDK.Native;
using System.Runtime.CompilerServices;
| | | | |