From aef0d1c1268ab7d4bc18996c9c6b4da16a40aadc Mon Sep 17 00:00:00 2001 From: navewindre Date: Mon, 4 Dec 2023 18:06:10 +0100 Subject: bbbbbbbbwaaaaaaaaaaa --- sourcemod/scripting/gokz-tpanglefix.sp | 277 +++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 sourcemod/scripting/gokz-tpanglefix.sp (limited to 'sourcemod/scripting/gokz-tpanglefix.sp') diff --git a/sourcemod/scripting/gokz-tpanglefix.sp b/sourcemod/scripting/gokz-tpanglefix.sp new file mode 100644 index 0000000..6297795 --- /dev/null +++ b/sourcemod/scripting/gokz-tpanglefix.sp @@ -0,0 +1,277 @@ +#include + +#include + +#include +#include + +#include + +#undef REQUIRE_EXTENSIONS +#undef REQUIRE_PLUGIN +#include + +#pragma newdecls required +#pragma semicolon 1 + + + +public Plugin myinfo = +{ + name = "GOKZ Teleport Angle Fix", + author = "zer0.k", + description = "Fix teleporting not modifying player's view angles due to packet loss", + version = GOKZ_VERSION, + url = "https://github.com/KZGlobalTeam/gokz" +}; + +#define UPDATER_URL GOKZ_UPDATER_BASE_URL..."gokz-tpanglefix.txt" + +TopMenu gTM_Options; +TopMenuObject gTMO_CatGeneral; +TopMenuObject gTMO_ItemTPAngleFix; +Address gA_ViewAnglePatchAddress; +bool gB_EnableFix[MAXPLAYERS + 1]; +DynamicDetour gH_WriteViewAngleUpdate; +int gI_ClientOffset; + +// =====[ PLUGIN EVENTS ]===== + +public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) +{ + RegPluginLibrary("gokz-tpanglefix"); + return APLRes_Success; +} + +public void OnPluginStart() +{ + LoadTranslations("gokz-common.phrases"); + LoadTranslations("gokz-tpanglefix.phrases"); + + SetupPatch(); + HookEvents(); + RegisterCommands(); +} + +void SetupPatch() +{ + GameData gamedataConf = LoadGameConfigFile("gokz-tpanglefix.games"); + if (gamedataConf == null) + { + SetFailState("Failed to load gokz-tpanglefix gamedata"); + } + // Get the patching address + Address addr = GameConfGetAddress(gamedataConf, "WriteViewAngleUpdate"); + if(addr == Address_Null) + { + SetFailState("Can't find WriteViewAngleUpdate address."); + } + + // Get the offset from the start of the signature to the start of our patch area. + int offset = GameConfGetOffset(gamedataConf, "WriteViewAngleUpdateReliableOffset"); + if(offset == -1) + { + SetFailState("Can't find WriteViewAngleUpdateReliableOffset in gamedata."); + } + gA_ViewAnglePatchAddress = view_as
(addr + view_as
(offset)); +} + +void HookEvents() +{ + GameData gamedataConf = LoadGameConfigFile("gokz-tpanglefix.games"); + if (gamedataConf == null) + { + SetFailState("Failed to load gokz-tpanglefix gamedata"); + } + gH_WriteViewAngleUpdate = DynamicDetour.FromConf(gamedataConf, "CGameClient::WriteViewAngleUpdate"); + + if (gH_WriteViewAngleUpdate == INVALID_HANDLE) + { + SetFailState("Failed to find CGameClient::WriteViewAngleUpdate function signature"); + } + + if (!gH_WriteViewAngleUpdate.Enable(Hook_Pre, DHooks_OnWriteViewAngleUpdate_Pre)) + { + SetFailState("Failed to enable detour on CGameClient::WriteViewAngleUpdate"); + } + // Prevent the server from crashing. + FindConVar("sv_parallel_sendsnapshot").SetBool(false); + FindConVar("sv_parallel_sendsnapshot").AddChangeHook(OnParallelSendSnapshotCvarChanged); + + gI_ClientOffset = gamedataConf.GetOffset("ClientIndexOffset"); + if (gI_ClientOffset == -1) + { + SetFailState("Failed to get ClientIndexOffset offset."); + } +} + +void OnParallelSendSnapshotCvarChanged(ConVar convar, const char[] oldValue, const char[] newValue) +{ + if (convar.BoolValue) + { + convar.BoolValue = false; + } +} + +public MRESReturn DHooks_OnWriteViewAngleUpdate_Pre(Address pThis) +{ + int client = LoadFromAddress(pThis + view_as
(gI_ClientOffset), NumberType_Int32); + if (gB_EnableFix[client]) + { + PatchAngleFix(); + } + else + { + RestoreAngleFix(); + } + return MRES_Ignored; +} + +void PatchAngleFix() +{ + if (LoadFromAddress(gA_ViewAnglePatchAddress, NumberType_Int8) == 0) + { + StoreToAddress(gA_ViewAnglePatchAddress, 1, NumberType_Int8); + } +} + +void RestoreAngleFix() +{ + if (LoadFromAddress(gA_ViewAnglePatchAddress, NumberType_Int8) == 1) + { + StoreToAddress(gA_ViewAnglePatchAddress, 0, NumberType_Int8); + } +} + +bool ToggleAngleFix(int client) +{ + gB_EnableFix[client] = !gB_EnableFix[client]; + return gB_EnableFix[client]; +} + +public void OnAllPluginsLoaded() +{ + if (LibraryExists("updater")) + { + Updater_AddPlugin(UPDATER_URL); + } + + TopMenu topMenu; + if (LibraryExists("gokz-core") && ((topMenu = GOKZ_GetOptionsTopMenu()) != null)) + { + GOKZ_OnOptionsMenuReady(topMenu); + } +} + +public void OnLibraryAdded(const char[] name) +{ + if (StrEqual(name, "updater")) + { + Updater_AddPlugin(UPDATER_URL); + } + +} + +// =====[ CLIENT EVENTS ]===== + +public void GOKZ_OnOptionChanged(int client, const char[] option, any newValue) +{ + OnOptionChanged_Options(client, option, newValue); +} + +// =====[ OTHER EVENTS ]===== + +public void GOKZ_OnOptionsMenuReady(TopMenu topMenu) +{ + OnOptionsMenuReady_Options(); + OnOptionsMenuReady_OptionsMenu(topMenu); +} + + +// =====[ OPTIONS ]===== + +void OnOptionsMenuReady_Options() +{ + RegisterOption(); +} + +void RegisterOption() +{ + GOKZ_RegisterOption(TPANGLEFIX_OPTION_NAME, TPANGLEFIX_OPTION_DESCRIPTION, + OptionType_Int, TPAngleFix_Disabled, 0, TPANGLEFIX_COUNT - 1); +} + +void OnOptionChanged_Options(int client, const char[] option, any newValue) +{ + if (StrEqual(option, TPANGLEFIX_OPTION_NAME)) + { + gB_EnableFix[client] = newValue; + switch (newValue) + { + case TPAngleFix_Disabled: + { + GOKZ_PrintToChat(client, true, "%t", "Option - TP Angle Fix - Disable"); + } + case TPAngleFix_Enabled: + { + GOKZ_PrintToChat(client, true, "%t", "Option - TP Angle Fix - Enable"); + } + } + } +} + +// =====[ OPTIONS MENU ]===== + +void OnOptionsMenuReady_OptionsMenu(TopMenu topMenu) +{ + if (gTM_Options == topMenu) + { + return; + } + + gTM_Options = topMenu; + gTMO_CatGeneral = gTM_Options.FindCategory(GENERAL_OPTION_CATEGORY); + gTMO_ItemTPAngleFix = gTM_Options.AddItem(TPANGLEFIX_OPTION_NAME, TopMenuHandler_TPAngleFix, gTMO_CatGeneral); +} + +public void TopMenuHandler_TPAngleFix(TopMenu topmenu, TopMenuAction action, TopMenuObject topobj_id, int param, char[] buffer, int maxlength) +{ + if (topobj_id != gTMO_ItemTPAngleFix) + { + return; + } + + if (action == TopMenuAction_DisplayOption) + { + if (GOKZ_GetOption(param, TPANGLEFIX_OPTION_NAME) == TPAngleFix_Disabled) + { + FormatEx(buffer, maxlength, "%T - %T", + "Options Menu - TP Angle Fix", param, + "Options Menu - Disabled", param); + } + else + { + FormatEx(buffer, maxlength, "%T - %T", + "Options Menu - TP Angle Fix", param, + "Options Menu - Enabled", param); + } + } + else if (action == TopMenuAction_SelectOption) + { + GOKZ_CycleOption(param, TPANGLEFIX_OPTION_NAME); + gTM_Options.Display(param, TopMenuPosition_LastCategory); + } +} + +// =====[ COMMANDS ]===== + +void RegisterCommands() +{ + RegConsoleCmd("sm_tpafix", CommandTPAFix, "[KZ] Toggle teleport angle fix."); +} + +public Action CommandTPAFix(int client, int args) +{ + GOKZ_SetOption(client, TPANGLEFIX_OPTION_NAME, ToggleAngleFix(client)); + return Plugin_Handled; +} \ No newline at end of file -- cgit v1.2.3