Skip to content

Commit daefc6c

Browse files
committed
refactor: use Memory::Patch for all patches
1 parent 5ea8a2c commit daefc6c

File tree

5 files changed

+69
-41
lines changed

5 files changed

+69
-41
lines changed

src/Modules/MaterialSystem.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ DETOUR_T(IMaterial *, MaterialSystem::CreateMaterial, const char *pMaterialName,
8181
return MaterialSystem::CreateMaterial(thisptr, pMaterialName, pVMTKeyValues);
8282
}
8383

84+
Memory::Patch *g_renderContextPatch;
85+
8486
bool MaterialSystem::Init() {
8587
this->materials = Interface::Create(this->Name(), "VMaterialSystem080");
8688
if (this->materials) {
@@ -97,11 +99,11 @@ bool MaterialSystem::Init() {
9799
this->renderContextSize = Memory::Scan<uint32_t *>(this->Name(), Offsets::RenderContextSize, Offsets::RenderContextSizeOff);
98100
this->RenderContextShutdown = Memory::Scan<_RenderContextShutdown>(this->Name(), Offsets::RenderContextShutdown);
99101
this->RenderContextInit = Memory::Scan<_RenderContextInit>(this->Name(), Offsets::RenderContextInit);
102+
g_renderContextPatch = new Memory::Patch();
100103
if (this->renderContextSize && this->RenderContextShutdown && this->RenderContextInit) {
101104
if (*this->renderContextSize != RENDERCONTEXT_ALLOC_SIZE) {
102-
Memory::UnProtect((void *)this->renderContextSize, sizeof(uint32_t));
103-
this->origRenderContextSize = *this->renderContextSize;
104-
*this->renderContextSize = RENDERCONTEXT_ALLOC_SIZE;
105+
auto byte = RENDERCONTEXT_ALLOC_SIZE;
106+
g_renderContextPatch->Execute((uintptr_t)this->renderContextSize, (unsigned char *)&byte, sizeof(uint32_t));
105107
this->RenderContextShutdown();
106108
this->RenderContextInit();
107109
}
@@ -112,8 +114,8 @@ bool MaterialSystem::Init() {
112114
void MaterialSystem::Shutdown() {
113115
Interface::Delete(this->materials);
114116

115-
if (origRenderContextSize) {
116-
*renderContextSize = origRenderContextSize;
117+
if (g_renderContextPatch->IsPatched()) {
118+
g_renderContextPatch->Restore();
117119
RenderContextShutdown();
118120
RenderContextInit();
119121
}

src/Modules/Server.cpp

Lines changed: 59 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -517,33 +517,33 @@ DETOUR_B(Server::AirMove) {
517517

518518
return Server::AirMove(thisptr);
519519
}
520+
521+
Memory::Patch *g_aircontrolPatch;
522+
520523
static void setAircontrol(int val) {
521-
if (!server->aircontrol_fling_speed_addr) return;
524+
if (!g_aircontrolPatch->IsInit()) return;
522525
switch (val) {
523526
case 0:
524-
*server->aircontrol_fling_speed_addr = 300.0f * 300.0f;
527+
g_aircontrolPatch->Restore();
525528
break;
526529
default:
527-
*server->aircontrol_fling_speed_addr = INFINITY;
530+
g_aircontrolPatch->Execute();
528531
break;
529532
}
530533
}
534+
535+
Memory::Patch *g_portalsThruPortalsPatch;
536+
531537
static void setPortalsThruPortals(bool val) {
532-
uintptr_t tfp = (uintptr_t)server->TraceFirePortal;
533-
if (!server->TraceFirePortal) return;
534-
#ifdef _WIN32
535-
*(uint8_t *)(tfp + Offsets::portalsThruPortals) = val ? 0x00 : 0x0A;
536-
#else
537-
if (sar.game->Is(SourceGame_EIPRelPIC)) {
538-
*(uint8_t *)(tfp + Offsets::portalsThruPortals) = val ? 0x82 : 0x85;
539-
} else if (sar.game->Is(SourceGame_PortalReloaded) || sar.game->Is(SourceGame_PortalStoriesMel)) {
540-
*(uint8_t *)(tfp + Offsets::portalsThruPortals) = val ? 0xEB : 0x74;
538+
if (!g_portalsThruPortalsPatch->IsInit()) return;
539+
if (val) {
540+
g_portalsThruPortalsPatch->Execute();
541541
} else {
542-
*(uint8_t *)(tfp + Offsets::portalsThruPortals) = val ? 0x85 : 0x84;
542+
g_portalsThruPortalsPatch->Restore();
543543
}
544-
#endif
545544
}
546545
Variable sar_portals_thru_portals("sar_portals_thru_portals", "0", "Allow firing portals through portals.\n");
546+
547547
// cvar callbacks dont want to fucking work so we'll just do this bs
548548
ON_EVENT(PRE_TICK) {
549549
setAircontrol(server->AllowsMovementChanges() ? sar_aircontrol.GetInt() : 0);
@@ -817,8 +817,9 @@ float hostTimeWrap() {
817817
return engine->GetHostTime();
818818
}
819819

820-
static char g_orig_check_stuck_code[6];
821-
static void *g_check_stuck_code;
820+
Memory::Patch *g_chatPatch;
821+
Memory::Patch *g_unblockChatPatch;
822+
Memory::Patch *g_checkStuckPatch;
822823

823824
bool Server::Init() {
824825
this->g_GameMovement = Interface::Create(this->Name(), "GameMovement001");
@@ -844,9 +845,13 @@ bool Server::Init() {
844845
Memory::Deref<_CheckJumpButton>(baseOffset + Offsets::CheckJumpButton * sizeof(uintptr_t *), &Server::CheckJumpButtonBase);
845846

846847
auto aircontrol_fling_speed_addr = Memory::Scan(this->Name(), Offsets::aircontrol_fling_speedSig, Offsets::aircontrol_fling_speedOff);
848+
g_aircontrolPatch = new Memory::Patch();
847849
if (aircontrol_fling_speed_addr) {
848-
this->aircontrol_fling_speed_addr = Memory::Deref<float *>(aircontrol_fling_speed_addr);
849-
Memory::UnProtect(this->aircontrol_fling_speed_addr, 4);
850+
unsigned char bytes[4];
851+
float infinityValue = INFINITY;
852+
std::memcpy(bytes, &infinityValue, sizeof(bytes));
853+
g_aircontrolPatch->Execute(Memory::Deref<uintptr_t>(aircontrol_fling_speed_addr), bytes, 4);
854+
g_aircontrolPatch->Restore();
850855
}
851856
}
852857

@@ -889,40 +894,47 @@ bool Server::Init() {
889894

890895
// Remove the limit on how quickly you can use 'say', and also hook it
891896
Command::Hook("say", Server::say_callback_hook, Server::say_callback);
897+
g_chatPatch = new Memory::Patch();
892898
if (say_callback) {
893899
auto insn_addr = (uintptr_t)say_callback + Offsets::say_callback_insn;
894900
// This is the location of an ADDSD instruction which adds 0.66
895901
// to the current time. If we instead *subtract* 0.66, we'll
896902
// always be able to chat again! We can just do this by changing
897903
// the third byte from 0x58 to 0x5C, hence making the full
898904
// opcode start with F2 0F 5C.
899-
Memory::UnProtect((void *)(insn_addr + 2), 1);
900905
if (*(char *)(insn_addr + 2) == 0x58) {
901-
*(char *)(insn_addr + 2) = 0x5C;
906+
unsigned char patchByte = 0x5C;
907+
g_chatPatch->Execute((uintptr_t)(insn_addr + 2), &patchByte, 1);
902908
} else {
903-
console->DevMsg("Failed to uncap chat time. insn was %02X\n", *(char *)(insn_addr + 2));
909+
console->Warning("Failed to uncap chat time. insn was %02X\n", *(char *)(insn_addr + 2));
904910
}
905911
}
906912
auto Host_Say = Memory::Scan(this->Name(), Offsets::Host_Say);
913+
g_unblockChatPatch = new Memory::Patch();
907914
if (Host_Say) {
908915
auto insn_addr = Host_Say + Offsets::Host_Say_insn;
909916
// FIXME: This also disables the "ignoremsg" client command
910917
// functionality.
911918
// This is the location of a JZ instruction which jumps if the
912919
// chat sender is dead but recipient is alive, blocking
913920
// messages. We just change it to a JO, which will never jump.
914-
Memory::UnProtect((void *)insn_addr, 1);
915921
if (*(char *)insn_addr == 0x74) {
916-
*(char *)insn_addr = 0x70;
922+
unsigned char patchByte = 0x70;
923+
g_unblockChatPatch->Execute((uintptr_t)insn_addr, &patchByte, 1);
917924
} else {
918-
console->DevMsg("Failed to unblock chat when dead. insn was %02X\n", *(char *)insn_addr);
925+
console->Warning("Failed to unblock chat. insn was %02X\n", *(char *)insn_addr);
919926
}
920927
}
921928

922929
// find the TraceFirePortal function
923930
TraceFirePortal = (_TraceFirePortal)Memory::Scan(this->Name(), Offsets::TraceFirePortal);
931+
g_portalsThruPortalsPatch = new Memory::Patch();
932+
if (TraceFirePortal && Offsets::portalsThruPortals) {
933+
unsigned char portalsThruPortalsValOn = Offsets::portalsThruPortalsValOn;
934+
g_portalsThruPortalsPatch->Execute((uintptr_t)TraceFirePortal + Offsets::portalsThruPortals, &portalsThruPortalsValOn, 1);
935+
g_portalsThruPortalsPatch->Restore();
936+
}
924937
FindPortal = (_FindPortal)Memory::Scan(this->Name(), Offsets::FindPortal);
925-
if (TraceFirePortal) Memory::UnProtect((void *)((uintptr_t)TraceFirePortal + Offsets::portalsThruPortals), 1); // see setPortalsThruPortals
926938

927939
ViewPunch = (decltype(ViewPunch))Memory::Scan(this->Name(), Offsets::ViewPunch);
928940

@@ -939,17 +951,19 @@ bool Server::Init() {
939951

940952
// a call to Plat_FloatTime in CGameMovement::CheckStuck
941953
auto code = Memory::Scan(this->Name(), Offsets::CheckStuck_FloatTime);
954+
g_checkStuckPatch = new Memory::Patch();
942955
if (code) {
943-
Memory::UnProtect((void *)code, sizeof g_orig_check_stuck_code);
944-
memcpy(g_orig_check_stuck_code, (void *)code, sizeof g_orig_check_stuck_code);
945-
946-
*(uint8_t *)code = 0xE8;
947-
*(uint32_t *)(code + 1) = (uint32_t)&hostTimeWrap - (code + 5);
948956
#ifdef _WIN32
949-
*(uint8_t *)(code + 5) = 0x90; // nop
957+
unsigned char checkStuckBytes[6];
958+
#else
959+
unsigned char checkStuckBytes[5];
950960
#endif
951-
952-
g_check_stuck_code = (void *)code;
961+
checkStuckBytes[0] = 0xE8; // call
962+
*(uint32_t *)(checkStuckBytes + 1) = (uint32_t)&hostTimeWrap - (code + 5);
963+
#ifdef _WIN32
964+
checkStuckBytes[5] = 0x90; // nop
965+
#endif
966+
g_checkStuckPatch->Execute((uintptr_t)code, checkStuckBytes, sizeof checkStuckBytes);
953967
}
954968

955969
if (sar.game->Is(SourceGame_Portal2 | SourceGame_Portal2_2011)) {
@@ -1028,9 +1042,18 @@ DETOUR_COMMAND(Server::say) {
10281042
}
10291043
void Server::Shutdown() {
10301044
Command::Unhook("say", Server::say_callback);
1031-
setAircontrol(0);
1032-
setPortalsThruPortals(false);
1033-
if (g_check_stuck_code) memcpy(g_check_stuck_code, g_orig_check_stuck_code, sizeof g_orig_check_stuck_code);
1045+
1046+
g_aircontrolPatch->Restore();
1047+
SAFE_DELETE(g_aircontrolPatch);
1048+
g_portalsThruPortalsPatch->Restore();
1049+
SAFE_DELETE(g_portalsThruPortalsPatch);
1050+
g_chatPatch->Restore();
1051+
SAFE_DELETE(g_chatPatch);
1052+
g_unblockChatPatch->Restore();
1053+
SAFE_DELETE(g_unblockChatPatch);
1054+
g_checkStuckPatch->Restore();
1055+
SAFE_DELETE(g_checkStuckPatch);
1056+
10341057
Interface::Delete(this->gEntList);
10351058
Interface::Delete(this->g_GameMovement);
10361059
Interface::Delete(this->g_ServerGameDLL);

src/Offsets/Portal 2 7054.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ OFFSET_LINUX(gamerules, 7)
1212
OFFSET_LINUX(say_callback_insn, 57)
1313
OFFSET_LINUX(Host_Say_insn, 0x346)
1414
OFFSET_LINUX(portalsThruPortals, 409)
15+
OFFSET_LINUX(portalsThruPortalsValOn, 0x85)
1516

1617
// Renderer
1718
SIGSCAN_LINUX(SND_RecordBuffer, "55 89 E5 57 56 53 83 EC 2C E8 ? ? ? ? 84 C0 75 0E 8D 65 F4 5B 5E 5F 5D C3")

src/Offsets/Portal 2 8151.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ OFFSET_LINUX(host_frametime, 70)
4545
OFFSET_LINUX(say_callback_insn, 88)
4646
OFFSET_LINUX(Host_Say_insn, 0x37A)
4747
OFFSET_LINUX(portalsThruPortals, 462)
48+
OFFSET_LINUX(portalsThruPortalsValOn, 0xEB)
4849

4950
// clang-format off
5051

src/Offsets/Portal 2 9568.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ OFFSET_DEFAULT(host_frametime, 92, 81)
382382
OFFSET_DEFAULT(say_callback_insn, 52, 55)
383383
OFFSET_DEFAULT(Host_Say_insn, 0x335, 0x36C)
384384
OFFSET_DEFAULT(portalsThruPortals, 391, 388)
385+
OFFSET_DEFAULT(portalsThruPortalsValOn, 0x00, 0x82)
385386

386387
// clang-format off
387388

0 commit comments

Comments
 (0)