diff --git a/set_tickrate_nextmap/gamedata/force_change_level.games.txt b/set_tickrate_nextmap/gamedata/force_change_level.games.txt new file mode 100644 index 0000000..500e36c --- /dev/null +++ b/set_tickrate_nextmap/gamedata/force_change_level.games.txt @@ -0,0 +1,14 @@ +"Games" +{ + "cstrike" + { + "Signatures" + { + "Host_Changelevel" + { + "library" "engine" + "linux" "@_Z16Host_ChangelevelbPKcS0_" + } + } + } +} diff --git a/set_tickrate_nextmap/scripting/set_tickrate_for_nextmap.sp b/set_tickrate_nextmap/scripting/set_tickrate_for_nextmap.sp index 3d62b42..adda893 100644 --- a/set_tickrate_nextmap/scripting/set_tickrate_for_nextmap.sp +++ b/set_tickrate_nextmap/scripting/set_tickrate_for_nextmap.sp @@ -3,7 +3,7 @@ #define PLUGIN_VERSION "1.0" #include -#include +#include //https://github.com/Mikusch/SM-TickrateChanger/tree/main @@ -16,11 +16,59 @@ public Plugin myinfo = url = "www.unloze.com" }; +Handle hChangeLevel; +char map_intended_switch[256]; + //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- +public void OnPluginStart() +{ + Handle conf = LoadGameConfigFile("force_change_level.games"); + if (conf == INVALID_HANDLE) + SetFailState("Failed to load gamedata force_change_level.games"); -public void OnMapVoteEnd(const char[] map) + //thanks Irineu + hChangeLevel = DHookCreateDetour(Address_Null, CallConv_CDECL, ReturnType_Bool, ThisPointer_Ignore); + if (!hChangeLevel) + SetFailState("Failed to setup detour "); + + + if (!DHookSetFromConf(hChangeLevel, conf, SDKConf_Signature, "Host_Changelevel")) + SetFailState("Failed to load signature from gamedata"); + + DHookAddParam(hChangeLevel, HookParamType_Bool); + DHookAddParam(hChangeLevel, HookParamType_CharPtr); + DHookAddParam(hChangeLevel, HookParamType_CharPtr); + + if (!DHookEnableDetour(hChangeLevel, false, ChangeLevel)) + SetFailState("Failed to detour "); + + delete conf; +} + +//thanks Irineu +public MRESReturn ChangeLevel(DHookReturn hReturn, DHookParam hParams) +{ + char cmd[256]; + Address addr_map_name = DHookGetParamAddress(hParams, 2); + + for (int i = 0; i < sizeof(cmd) - 1; i++) + { + int iByte = LoadFromAddress(addr_map_name + view_as
(i), NumberType_Int8); + if (iByte < 32 || iByte > 126) //ascii range of legal characters we are interested in + { + break; + } + cmd[i] = iByte; + } + + //LogMessage("cmd: %s", cmd); + check_map(cmd); + return MRES_Ignored; +} + +public void check_map(const char []map) { new Handle:fileHandle = OpenFile("maps_66_tick.txt", "r" ); char lineBuffer[256]; @@ -35,12 +83,31 @@ public void OnMapVoteEnd(const char[] map) } } CloseHandle(fileHandle); + float interveral_per_tick_pre = GetConVarFloat(FindConVar("sm_interval_per_tick")); + bool double_map_change = false; + if (changeTick) { ServerCommand("sm_tickrate 66"); + //are we at 100 tick and change to 66 right now? do a quick change map restart. + double_map_change = interveral_per_tick_pre < 0.014; } else { ServerCommand("sm_tickrate 100"); + //are we at 66 tick and change to 100 right now? do a quick change map restart. + double_map_change = interveral_per_tick_pre > 0.011; + } + + if (double_map_change) + { + Format(map_intended_switch, sizeof(map_intended_switch), map); + CreateTimer(10.0, restart_map); } } + +public Action restart_map(Handle timer, any data) +{ + ForceChangeLevel(map_intended_switch, "switching tickrate, applied double map change which was needed to fix entities."); + return Plugin_Continue; +}