Skip to content

Commit 0d8c707

Browse files
committed
Added more debug logs and moved some hooks to be PS:Mel only
1 parent 1921c5f commit 0d8c707

1 file changed

Lines changed: 53 additions & 21 deletions

File tree

p2mm.cpp

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -357,11 +357,15 @@ bool CP2MMServerPlugin::Load(CreateInterfaceFn interfaceFactory, const CreateInt
357357

358358
// Make sure -allowspectators is there so we get our 33 max players.
359359
if (!CommandLine()->FindParm("-allowspectators"))
360+
{
361+
Log(INFO, true, R"(Missing "-allowspectators" launch parameter, adding!)");
360362
CommandLine()->AppendParm("-allowspectators", "");
363+
}
361364

362365
// big ol' try catch because game has a TerminateProcess handler for exceptions...
363366
// why this wasn't here is mystifying, - 10/2024 NULLderef
364-
try {
367+
try
368+
{
365369
// Byte patches
366370

367371
// "Steam not running." error fix for dedicated servers. This only works for dedicated servrs when the plugin file is named "ghostinj" and server is run with -usegh.
@@ -373,10 +377,12 @@ bool CP2MMServerPlugin::Load(CreateInterfaceFn interfaceFactory, const CreateInt
373377
Memory::ReplacePattern("server", "0F B6 87 04 05 00 00 8B 16", "EB 14 87 04 05 00 00 8B 16");
374378

375379
// Partner disconnects.
380+
Log(INFO, true, "Patching partner disconnect event...");
376381
Memory::ReplacePattern("server", "51 50 FF D2 83 C4 10 E8", "51 50 90 90 83 C4 10 E8");
377382
Memory::ReplacePattern("server", "74 28 3B 75 FC", "EB 28 3B 75 FC");
378383

379384
// Max players -> 33
385+
Log(INFO, true, "Patching patching max players...");
380386
Memory::ReplacePattern("server", "83 C0 02 89 01", "83 C0 20 89 01");
381387
Memory::ReplacePattern("engine", "85 C0 78 13 8B 17", "31 C0 04 21 8B 17");
382388
uintptr_t svPtr = *static_cast<uintptr_t*>(Memory::Scanner::Scan<void*>(ENGINEDLL, "74 0A B9 ?? ?? ?? ?? E8 ?? ?? ?? ?? 8B E5", 3));
@@ -386,41 +392,37 @@ bool CP2MMServerPlugin::Load(CreateInterfaceFn interfaceFactory, const CreateInt
386392
this->sv = reinterpret_cast<CBaseServer*>(svPtr);
387393

388394
// Prevent disconnect by "STEAM validation rejected".
395+
Log(INFO, true, R"(Patching "STEAM validation rejected" disconnection...)");
389396
Memory::ReplacePattern("engine", "01 74 7D 8B", "01 EB 7D 8B");
390397

391-
// Fix sv_password.
398+
// Fix sv_password so passwords can be used on servers.
399+
Log(INFO, true, "Fixing sv_password...");
392400
Memory::ReplacePattern("engine", "0F 95 C1 51 8D 4D E8", "03 C9 90 51 8D 4D E8");
393401

394-
// runtime max 0.03 -> 0.05
402+
// Increase runtime max form 0.03 to 0.05.
403+
// Helps add some more leeway to some things we do in VScript without the engine complaining and shutting down the rest of the script.
404+
Log(INFO, true, "Patching max runtime for VScript...");
395405
Memory::ReplacePattern("vscript", "00 00 00 E0 51 B8 9E 3F", "9a 99 99 99 99 99 a9 3f");
396406

397-
// MinHook initialization and hooking
407+
// MinHook initialization and hooking.
398408
Log(INFO, true, "Initializing MinHook and hooking functions...");
399409
MH_Initialize();
400410

401411
// NoSteamLogon disconnect hook patch.
412+
Log(INFO, true, "Hooking CSteam3Server::OnGSClientDenyHelper...");
402413
MH_CreateHook(
403414
(LPVOID)Memory::Scanner::Scan<void*>(ENGINEDLL, "55 8B EC 83 EC 08 53 56 57 8B F1 E8 ?? ?? ?? ?? 8B"),
404415
&CSteam3Server__OnGSClientDenyHelper_hook, reinterpret_cast<void**>(&CSteam3Server__OnGSClientDenyHelper_orig)
405416
);
406417

407-
// Hook onto the function which defines what Atlas's and PBody's models are.
408-
MH_CreateHook(
409-
Memory::Rel32(Memory::Scanner::Scan(SERVERDLL, "E8 ?? ?? ?? ?? 83 C4 40 50", 1)),
410-
&GetBallBotModel_hook, reinterpret_cast<void**>(&GetBallBotModel_orig)
411-
);
412-
MH_CreateHook(
413-
Memory::Rel32(Memory::Scanner::Scan(SERVERDLL, "E8 ?? ?? ?? ?? 83 C4 04 50 8B 45 10 8B 10", 1)),
414-
&GetEggBotModel_hook, reinterpret_cast<void**>(&GetEggBotModel_orig)
415-
);
416-
417418
// For p2mm_instantrespawn.
418419
MH_CreateHook(
419420
Memory::Scanner::Scan(SERVERDLL, "53 8B DC 83 EC 08 83 E4 F0 83 C4 04 55 8B 6B ?? 89 6C 24 ?? 8B EC A1 ?? ?? ?? ?? F3 0F 10 40 ?? F3 0F 58 05 ?? ?? ?? ?? 83 EC 28 56 57 6A 00 51 8B F1 F3 0F 11 04 24 E8 ?? ?? ?? ?? 6A 03"),
420421
&CPortal_Player__PlayerDeathThink_hook, reinterpret_cast<void**>(&CPortal_Player__PlayerDeathThink_orig)
421422
);
422423

423424
// "respawn" function hook for getting a VScript "game event" call out of it.
425+
Log(INFO, true, "Hooking respawn function call...");
424426
MH_CreateHook(
425427
Memory::Scanner::Scan(SERVERDLL, "55 8B EC A1 ?? ?? ?? ?? 80 78 ?? ?? 75 ?? 80 78"),
426428
&respawn_hook, reinterpret_cast<void**>(&respawn_orig)
@@ -436,15 +438,34 @@ bool CP2MMServerPlugin::Load(CreateInterfaceFn interfaceFactory, const CreateInt
436438
switch (g_P2MMServerPlugin.m_iCurGameIndex)
437439
{
438440
case PORTAL_STORIES_MEL:
441+
// Valve's compiler for P2 inlined the GetBallBotModel and GetEggBotModel functions here,
442+
// so this also needs to be forced to return a different string.
443+
Log(INFO, true, "Hooking CPortal_Player::GetPlayerModelName...");
439444
MH_CreateHook(
440445
Memory::Scanner::Scan(SERVERDLL, "55 8B EC 81 EC 10 01 00 00 53 8B 1D"),
441446
&CPortal_Player__GetPlayerModelName_hook, reinterpret_cast<void**>(&CPortal_Player__GetPlayerModelName_orig)
442447
);
448+
449+
// Hook onto the function which defines what Atlas's and PBody's models are.
450+
Log(INFO, true, "Hooking GetBallBotModel...");
451+
MH_CreateHook(
452+
Memory::Rel32(Memory::Scanner::Scan(SERVERDLL, "E8 ?? ?? ?? ?? 83 C4 40 50", 1)),
453+
&GetBallBotModel_hook, reinterpret_cast<void**>(&GetBallBotModel_orig)
454+
);
455+
Log(INFO, true, "Hooking GetEggBotModel...");
456+
MH_CreateHook(
457+
Memory::Rel32(Memory::Scanner::Scan(SERVERDLL, "E8 ?? ?? ?? ?? 83 C4 04 50 8B 45 10 8B 10", 1)),
458+
&GetEggBotModel_hook, reinterpret_cast<void**>(&GetEggBotModel_orig)
459+
);
460+
break;
443461
}
444-
462+
463+
Log(INFO, true, "Enabling hooks...");
445464
MH_EnableHook(MH_ALL_HOOKS);
446-
} catch (const std::exception& ex) {
447-
Log(INFO, false, "Failed to load plugin! :( Exception: \"%s\"", ex.what());
465+
} catch (const std::exception& ex)
466+
{
467+
assert(0 && "Failed to implement patch or hook!");
468+
Log(INFO, false, R"(Failed to load plugin! :( Exception: "%s")", ex.what());
448469
this->m_bNoUnload = true;
449470
return false;
450471
}
@@ -465,7 +486,7 @@ void CP2MMServerPlugin::Unload(void)
465486
if (m_bNoUnload)
466487
{
467488
m_bNoUnload = false;
468-
MessageBox(this->m_hWnd, "P2:MM ran into a error when starting! Please check the console for more info!", "P2:MM Startup Error", MB_OK | MB_ICONERROR);
489+
MessageBox(this->m_hWnd, "P2:MM ran into a error when starting!\nPlease check the console for more info!", "P2:MM Startup Error", MB_OK | MB_ICONERROR);
469490
return;
470491
}
471492

@@ -480,16 +501,20 @@ void CP2MMServerPlugin::Unload(void)
480501
Log(INFO, true, "Unblocking console commands...");
481502
for (const char* conCommand : forbiddenConCommands)
482503
{
483-
ConCommandBase* commandBase = g_pCVar->FindCommandBase(conCommand);
484-
if (commandBase)
504+
if (ConCommandBase* commandBase = g_pCVar->FindCommandBase(conCommand))
485505
commandBase->AddFlags(FCVAR_GAMEDLL);
486506
}
487507

488508
// Remove -allowspectators so max player count is indeed back to 2 and not 3.
489509
if (CommandLine()->FindParm("-allowspectators"))
510+
{
511+
Log(INFO, true, R"(Removing "-allowspectators" launch parameter"...)");
490512
CommandLine()->RemoveParm("-allowspectators");
513+
}
491514

515+
Log(INFO, true, "Unregistering ConVars...");
492516
ConVar_Unregister();
517+
493518
Log(INFO, true, "Disconnecting tier libraries...");
494519
DisconnectTier2Libraries();
495520
DisconnectTier1Libraries();
@@ -507,21 +532,26 @@ void CP2MMServerPlugin::Unload(void)
507532
Memory::ReplacePattern("server", "EB 14 87 04 05 00 00 8B 16", "0F B6 87 04 05 00 00 8B 16");
508533

509534
// Partner disconnects
535+
Log(INFO, true, "Un-patching partner disconnect event...");
510536
Memory::ReplacePattern("server", "51 50 90 90 83 C4 10 E8", "51 50 FF D2 83 C4 10 E8");
511537
Memory::ReplacePattern("server", "EB 28 3B 75 FC", "74 28 3B 75 FC");
512538

513539
// Max players -> 2
540+
Log(INFO, true, "Un-patching max players...");
514541
Memory::ReplacePattern("server", "83 C0 20 89 01", "83 C0 02 89 01");
515542
Memory::ReplacePattern("engine", "31 C0 04 21 8B 17", "85 C0 78 13 8B 17");
516543
*reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(this->sv) + 0x228) = 2;
517544

518545
// Disconnect by "STEAM validation rejected"
546+
Log(INFO, true, R"(Un-patching "STEAM validation rejected" disconnection...)");
519547
Memory::ReplacePattern("engine", "01 EB 7D 8B", "01 74 7D 8B");
520548

521549
// sv_password
550+
Log(INFO, true, "Unfixing sv_password...");
522551
Memory::ReplacePattern("engine", "03 C9 90 51 8D 4D E8", "0F 95 C1 51 8D 4D E8");
523552

524553
// runtime max 0.05 -> 0.03
554+
Log(INFO, true, "Un-patching max runtime for VScript...");
525555
Memory::ReplacePattern("vscript", "00 00 00 00 00 00 E0 3F", "00 00 00 E0 51 B8 9E 3F");
526556

527557
Log(INFO, true, "Disconnecting hooked functions and initializing MinHook...");
@@ -530,7 +560,9 @@ void CP2MMServerPlugin::Unload(void)
530560
}
531561
catch (const std::exception& ex)
532562
{
533-
Log(INFO, false, "Encountered error when unload plugin! Skipping other patches... :( Exception: \"%s\"", ex.what());
563+
assert(0 && "Failed to fully unload!");
564+
Log(INFO, false, R"(Encountered error when unload plugin! :( Exception: "%s")", ex.what());
565+
Log(ERRORR, false, "P2:MM failed to unload!\nGame has to be shutdown as possibly some other patches/hooks are still connected which can cause issues!");
534566
}
535567

536568
if (p2mm_discord_rpc.GetBool() && CDiscordIntegration::DiscordRPCRunning())

0 commit comments

Comments
 (0)