Change the behaviour of shavit_misc_resettargetname (#1123)

* Redo shavit_misc_resettargetname

Also changes the way event abuses are fixed

* Obsolete shavit_misc_resettargetname/classname cvars

Also few minor optimisations to the code

* Revert the deletion of shavit_misc_resettargetname/classname

* Move targetname/classname resets to OnStartPre() forward

* Rename shavit_misc_resettargetname cvar

* Move event reset code to shavit-zones

Also replaces PhysicsCheckForEntityUntouch() function call with PhysicsRemoveTouchedList()

* don't hook teleport on bots & some random code-style changes

* remove added whitespace

Co-authored-by: rtldg <55846624+rtldg@users.noreply.github.com>
This commit is contained in:
GAMMACASE 2022-03-18 05:17:19 +03:00 committed by GitHub
parent d58d3ee1d5
commit 0fee1862c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 180 additions and 114 deletions

View File

@ -1,124 +1,44 @@
"Map fixes"
{
"bhop_apathy"
{
"shavit_misc_forcetargetnamereset" "1"
"shavit_misc_resettargetname_main" "apathy"
}
"bhop_appaisaniceman3"
{
"shavit_misc_resetclassname_main" "main"
"shavit_misc_resetclassname_bonus" "bonus_filter"
}
"bhop_amaranthglow"
{
"shavit_zones_prebuilt_visual_offset" "16"
}
"bhop_blackshit"
{
"shavit_misc_resettargetname_main" "fil_fw"
}
"bhop_crash_egypt"
{
"shavit_misc_forcetargetnamereset" "1"
"shavit_misc_resettargetname_main" "player"
}
"bhop_decbble"
{
"shavit_misc_resettargetname_main" "p1"
}
"bhop_downtown"
{
"shavit_misc_resettargetname_main" "fil_fw"
}
"bhop_drop"
{
"shavit_misc_forcetargetnamereset" "1"
"shavit_misc_resettargetname_main" "activator_boost"
}
"bhop_futile"
{
"shavit_misc_resettargetname" "0"
}
"bhop_futile_fix"
{
"shavit_misc_resettargetname" "0"
}
"bhop_horseshit_5"
{
"shavit_misc_resettargetname_main" "last"
}
"bhop_interloper"
{
"shavit_misc_resettargetname_main" "l"
}
"bhop_japan"
{
"shavit_misc_forcetargetnamereset" "1"
"shavit_misc_resetclassname_main" "beginner"
}
"bhop_kirous"
{
"shavit_misc_resettargetname_main" "state0"
}
"bhop_lowg"
{
"shavit_misc_resettargetname" "0"
}
"bhop_microwave"
{
"shavit_misc_resettargetname" "0"
}
"bhop_overthinker"
{
"shavit_misc_resettargetname_main" "noobinside"
"shavit_misc_resettargetname_bonus" "filter_bonus"
"shavit_misc_resetclassname_main" "cp1"
"shavit_misc_resetclassname_bonus" "cp1"
}
"bhop_overthinker_go"
{
"shavit_misc_resettargetname_main" "noobinside"
"shavit_misc_resettargetname_bonus" "filter_bonus"
"shavit_misc_resetclassname_main" "cp1"
"shavit_misc_resetclassname_bonus" "cp1"
}
"bhop_shutdown"
{
"shavit_misc_forcetargetnamereset" "1"
"shavit_misc_resettargetname_main" "asdf"
}
"bhop_space"
{
"shavit_misc_resettargetname" "0"
}
"bhop_strafecontrol"
{
"shavit_zones_extra_spawn_height" "1.0"
}
"bhop_symbiotic"
{
"shavit_misc_resettargetname_main" "filter_main"
"shavit_misc_resettargetname_bonus" "filter_bonus"
}
"bhop_tranquility"
{
"shavit_zones_prebuilt_visual_offset" "16"
}
"kz_bhop_izanami"
"bhop_solitude"
{
"shavit_misc_resettargetname" "0"
"shavit_misc_forcetargetnamereset" "1"
}
"kz_bhop_kairo"
{
"shavit_misc_resettargetname" "0"
}
"kz_bhop_sanctum"
{
"shavit_misc_resetclassname_main" "A1"
}
"kz_bhop_strafe_comjump2"
{
"shavit_misc_resettargetname_main" "pass1"
}
"kz_bhop_strafe_comjump2_v2"
{
"shavit_misc_resettargetname_main" "pass1"
}
}
}

View File

@ -101,6 +101,13 @@
"windows" "\x55\x8B\xEC\x83\xEC\x08\x56\x8B\xF1\x8B\x86\xD0\x00\x00\x00"
"linux" "\x55\x89\xE5\x57\x56\x53\x83\xEC\x2C\x8B\x5D\x08\xC7\x44\x24\x04\x01\x00\x00\x00\x89\x1C\x24"
}
// search string: "remove 0x%p: %s-%s (%d-%d) [%d in play, %d max]\n".
// function with one argument is PhysicsRemoveTouchedList
"PhysicsRemoveTouchedList"
{
"windows" "\x55\x8B\xEC\x83\xEC\x0C\x57\x8B\xF9\x8B\x87\x2A\x2A\x2A\x2A\xD1\xE8\xA8\x01\x0F\x84"
"linux" "\x55\x89\xE5\x57\x56\x53\x83\xEC\x5C\x8B\x55\x08\xC7\x44\x24\x2A\x2A\x2A\x2A\x2A\x89\x14\x24\xE8"
}
}
}
@ -177,6 +184,13 @@
"windows" "\x55\x8B\xEC\x56\x8B\xF1\xE8\x2A\x2A\x2A\x2A\x8B\x45\x2A\x83\xE8\x02"
"linux" "@_ZN12CCSGameRules8TeamFullEi"
}
// search string: "remove 0x%p: %s-%s (%d-%d) [%d in play, %d max]\n".
// function with one argument is PhysicsRemoveTouchedList
"PhysicsRemoveTouchedList"
{
"windows" "\x55\x8B\xEC\x83\xEC\x08\x57\x8B\x7D\x08\x8B\x87\x2A\x2A\x2A\x2A\xD1\xE8\xA8\x01\x0F\x84"
"linux" "@_ZN11CBaseEntity24PhysicsRemoveTouchedListEPS_"
}
}
}
@ -232,6 +246,13 @@
"windows" "\x55\x8B\xEC\x56\x8B\x75\x2A\x85\xF6\x75\x2A\x33\xC0\x5E\x5D\xC3\x8B\x56"
"linux" "@_ZN12CTFGameRules15CalcPlayerScoreEP12RoundStats_tP9CTFPlayer"
}
// search string: "remove 0x%p: %s-%s (%d-%d) [%d in play, %d max]\n".
// function with one argument is PhysicsRemoveTouchedList
"PhysicsRemoveTouchedList"
{
"windows" "\x55\x8B\xEC\x83\xEC\x08\x57\x8B\x7D\x08\x8B\x87\x2A\x2A\x2A\x2A\xD1\xE8\xA8\x01\x0F\x84"
"linux" "@_ZN11CBaseEntity24PhysicsRemoveTouchedListEPS_"
}
}
}
}

View File

@ -43,7 +43,6 @@
#include <shavit/zones>
#include <eventqueuefix>
#include <shavit/physicsuntouch>
#include <shavit/weapon-stocks>
#pragma newdecls required
@ -102,7 +101,7 @@ Convar gCV_AdvertisementInterval = null;
Convar gCV_RemoveRagdolls = null;
Convar gCV_ClanTag = null;
Convar gCV_DropAll = null;
Convar gCV_ResetTargetname = null;
Convar gCV_ForceTargetnameReset = null;
Convar gCV_ResetTargetnameMain = null;
Convar gCV_ResetTargetnameBonus = null;
Convar gCV_ResetClassnameMain = null;
@ -277,7 +276,7 @@ public void OnPluginStart()
gCV_RemoveRagdolls = new Convar("shavit_misc_removeragdolls", "1", "Remove ragdolls after death?\n0 - Disabled\n1 - Only remove replay bot ragdolls.\n2 - Remove all ragdolls.", 0, true, 0.0, true, 2.0);
gCV_ClanTag = new Convar("shavit_misc_clantag", "{tr}{styletag} :: {time}", "Custom clantag for players.\n0 - Disabled\n{styletag} - style tag.\n{style} - style name.\n{time} - formatted time.\n{tr} - first letter of track.\n{rank} - player rank.\n{cr} - player's chatrank from shavit-chat, trimmed, with no colors", 0);
gCV_DropAll = new Convar("shavit_misc_dropall", "1", "Allow all weapons to be dropped?\n0 - Disabled\n1 - Enabled", 0, true, 0.0, true, 1.0);
gCV_ResetTargetname = new Convar("shavit_misc_resettargetname", "1", "Reset the player's targetname and eventqueue upon timer start?\n0 - Disabled\n1 - Enabled", 0, true, 0.0, true, 1.0);
gCV_ForceTargetnameReset = new Convar("shavit_misc_forcetargetnamereset", "0", "Reset the player's targetname upon timer start?\nRecommended to leave disabled. Enable via per-map configs when necessary.\n0 - Disabled\n1 - Enabled", 0, true, 0.0, true, 1.0);
gCV_ResetTargetnameMain = new Convar("shavit_misc_resettargetname_main", "", "What targetname to use when resetting the player. You don't need to touch this");
gCV_ResetTargetnameBonus = new Convar("shavit_misc_resettargetname_bonus", "", "What targetname to use when resetting the player (on bonus tracks). You don't need to touch this");
gCV_ResetClassnameMain = new Convar("shavit_misc_resetclassname_main", "", "What classname to use when resetting the player. You don't need to touch this");
@ -370,8 +369,6 @@ void LoadDHooks()
SetFailState("Couldn't get the offset for \"CGameRules::IsSpawnPointValid\" - make sure your gamedata is updated!");
}
LoadPhysicsUntouch(hGameData);
delete hGameData;
}
@ -2130,16 +2127,6 @@ public Action Command_Specs(int client, int args)
return Plugin_Handled;
}
void ClearClientEventsFrame(int serial)
{
int client = GetClientFromSerial(serial);
if (client > 0 && gB_Eventqueuefix)
{
ClearClientEvents(client);
}
}
public Action Shavit_OnStartPre(int client)
{
if (Shavit_GetStyleSettingInt(gI_Style[client], "prespeed") == 0 && GetEntityMoveType(client) == MOVETYPE_NOCLIP)
@ -2157,11 +2144,11 @@ public Action Shavit_OnStart(int client)
SetClientEventsPaused(client, false);
}
if(gCV_ResetTargetname.BoolValue)
if(gCV_ForceTargetnameReset.BoolValue)
{
char targetname[64];
char classname[64];
if (Shavit_GetClientTrack(client) == Track_Main)
{
gCV_ResetTargetnameMain.GetString(targetname, sizeof(targetname));
@ -2181,14 +2168,6 @@ public Action Shavit_OnStart(int client)
}
SetEntPropString(client, Prop_Data, "m_iClassname", classname);
// Used to clear some (mainly basevelocity) events that can be used to boost out of the start zone.
if(gB_Eventqueuefix)
{
ClearClientEvents(client); // maybe unneeded?
// The RequestFrame is the on that's actually needed though...
RequestFrame(ClearClientEventsFrame, GetClientSerial(client));
}
}
return Plugin_Continue;

View File

@ -27,6 +27,7 @@
#include <shavit/core>
#include <shavit/zones>
#include <shavit/physicsuntouch>
#undef REQUIRE_PLUGIN
#include <adminmenu>
@ -35,6 +36,7 @@
#undef REQUIRE_EXTENSIONS
#include <cstrike>
#include <tf2>
#include <eventqueuefix>
#pragma semicolon 1
#pragma newdecls required
@ -91,6 +93,8 @@ int gI_GridSnap[MAXPLAYERS+1];
bool gB_SnapToWall[MAXPLAYERS+1];
bool gB_CursorTracing[MAXPLAYERS+1];
int gI_LatestTeleportTick[MAXPLAYERS+1];
// player zone status
bool gB_InsideZone[MAXPLAYERS+1][ZONETYPES_SIZE][TRACKS_SIZE];
bool gB_InsideZoneID[MAXPLAYERS+1][MAX_ZONES];
@ -153,6 +157,12 @@ Handle gH_Forwards_EnterZone = null;
Handle gH_Forwards_LeaveZone = null;
Handle gH_Forwards_StageMessage = null;
// sdkcalls
Handle gH_PhysicsRemoveTouchedList = null;
// dhooks
DynamicHook gH_TeleportDhook = null;
// kz support
float gF_ClimbButtonCache[MAXPLAYERS+1][TRACKS_SIZE][2][3]; // 0 - location, 1 - angles
@ -162,6 +172,8 @@ bool gB_StartAnglesOnly[MAXPLAYERS+1][TRACKS_SIZE];
float gF_StartPos[MAXPLAYERS+1][TRACKS_SIZE][3];
float gF_StartAng[MAXPLAYERS+1][TRACKS_SIZE][3];
// modules
bool gB_Eventqueuefix = false;
bool gB_ReplayRecorder = false;
// custom zone stuff
@ -308,7 +320,9 @@ public void OnPluginStart()
gCV_BoxOffset.AddChangeHook(OnConVarChanged);
Convar.AutoExecConfig();
LoadDHooks();
// misc cvars
sv_gravity = FindConVar("sv_gravity");
@ -332,6 +346,7 @@ public void OnPluginStart()
}
gB_ReplayRecorder = LibraryExists("shavit-replay-recorder");
gB_Eventqueuefix = LibraryExists("eventqueuefix");
if (gB_Late)
{
@ -343,6 +358,7 @@ public void OnPluginStart()
if (IsValidClient(i))
{
OnClientConnected(i);
OnClientPutInServer(i);
if (AreClientCookiesCached(i) && !IsFakeClient(i))
{
@ -358,6 +374,70 @@ public void OnPluginEnd()
UnloadZones(0);
}
void LoadDHooks()
{
Handle hGameData = LoadGameConfigFile("shavit.games");
if (hGameData == null)
{
SetFailState("Failed to load shavit gamedata");
}
LoadPhysicsUntouch(hGameData);
if (gEV_Type == Engine_CSGO)
{
StartPrepSDKCall(SDKCall_Entity);
}
else
{
StartPrepSDKCall(SDKCall_Static);
}
if (!PrepSDKCall_SetFromConf(hGameData, SDKConf_Signature, "PhysicsRemoveTouchedList"))
{
SetFailState("Failed to find \"PhysicsRemoveTouchedList\" signature!");
}
if (gEV_Type != Engine_CSGO)
{
PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer);
}
gH_PhysicsRemoveTouchedList = EndPrepSDKCall();
if (!gH_PhysicsRemoveTouchedList)
{
SetFailState("Failed to create sdkcall to \"PhysicsRemoveTouchedList\"!");
}
delete hGameData;
hGameData = LoadGameConfigFile("sdktools.games");
if (hGameData == null)
{
SetFailState("Failed to load sdktools gamedata");
}
int iOffset = GameConfGetOffset(hGameData, "Teleport");
if (iOffset == -1)
{
SetFailState("Couldn't get the offset for \"Teleport\"!");
}
gH_TeleportDhook = new DynamicHook(iOffset, HookType_Entity, ReturnType_Void, ThisPointer_CBaseEntity);
gH_TeleportDhook.AddParam(HookParamType_VectorPtr);
gH_TeleportDhook.AddParam(HookParamType_VectorPtr);
gH_TeleportDhook.AddParam(HookParamType_VectorPtr);
if (GetEngineVersion() == Engine_CSGO)
{
gH_TeleportDhook.AddParam(HookParamType_Bool);
}
delete hGameData;
}
public void OnAllPluginsLoaded()
{
// admin menu
@ -380,6 +460,10 @@ public void OnLibraryAdded(const char[] name)
{
gB_ReplayRecorder = true;
}
else if (StrEqual(name, "eventqueuefix"))
{
gB_Eventqueuefix = true;
}
}
public void OnLibraryRemoved(const char[] name)
@ -393,6 +477,10 @@ public void OnLibraryRemoved(const char[] name)
{
gB_ReplayRecorder = false;
}
else if (StrEqual(name, "eventqueuefix"))
{
gB_Eventqueuefix = false;
}
}
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
@ -913,6 +1001,16 @@ public void OnMapEnd()
delete gH_DrawAllZones;
}
public void OnClientPutInServer(int client)
{
gI_LatestTeleportTick[client] = 0;
if (!IsFakeClient(client) && gH_TeleportDhook != null)
{
gH_TeleportDhook.HookEntity(Hook_Pre, client, DHooks_OnTeleport);
}
}
public void OnEntityCreated(int entity, const char[] classname)
{
if(StrEqual(classname, "func_button", false))
@ -4192,6 +4290,26 @@ public void CreateZoneEntities(bool only_create_dead_entities)
gB_ZoneCreationQueued = false;
}
public MRESReturn DHooks_OnTeleport(int pThis, DHookParam hParams)
{
if (!IsValidEntity(pThis) || !IsClientInGame(pThis))
{
return MRES_Ignored;
}
if (!hParams.IsNull(1))
{
gI_LatestTeleportTick[pThis] = GetGameTickCount();
}
return MRES_Ignored;
}
void PhysicsRemoveTouchedList(int client)
{
SDKCall(gH_PhysicsRemoveTouchedList, client);
}
public void StartTouchPost(int entity, int other)
{
if(other < 1 || other > MaxClients || gI_EntityZone[entity] == -1 || !gA_ZoneCache[gI_EntityZone[entity]].bZoneInitialized || IsFakeClient(other) ||
@ -4324,6 +4442,34 @@ public void TouchPost(int entity, int other)
{
case Zone_Start:
{
if (gB_Eventqueuefix)
{
static int tick_served[MAXPLAYERS + 1];
int curr_tick = GetGameTickCount();
// GAMMACASE: This prevents further abuses related to external events being ran after you teleport from the trigger, with events setup, outside the start zone into the start zone.
// This accounts for the io events that might be set inside the start zone trigger in OnStartTouch and wont reset them!
// Logic behind this code is that all events in this chain are not instantly fired, so checking if there were teleport from the outside of a start zone in last couple of ticks
// and doing PhysicsRemoveTouchedList() now to trigger all OnEndTouch that should happen at the same tick but later and removing them allows further events from OnStartTouch be separated
// and be fired after which is the expected and desired effect.
// This also kills all ongoing events that were active on the client prior to the teleportation to start and also resets targetname and classname
// before the OnStartTouch from triggers in start zone are run, thus preventing the maps to be abusable if they don't have any reset triggers in place
if (curr_tick != tick_served[other])
{
if (gI_LatestTeleportTick[other] <= curr_tick <= gI_LatestTeleportTick[other] + 4)
{
PhysicsRemoveTouchedList(other);
ClearClientEvents(other);
tick_served[other] = curr_tick;
return;
}
tick_served[other] = 0;
}
}
if (GetEntPropEnt(other, Prop_Send, "m_hGroundEntity") == -1 && !Shavit_GetStyleSettingBool(Shavit_GetBhopStyle(other), "startinair"))
{
return;