diff options
author | BobTheBob9 <for.oliver.kirkham@gmail.com> | 2022-09-15 00:20:56 +0100 |
---|---|---|
committer | BobTheBob9 <for.oliver.kirkham@gmail.com> | 2022-09-15 00:20:56 +0100 |
commit | ba26be9bea801f219fa6340178fd6b13f02d574e (patch) | |
tree | f50e67e06f7174daca0c97cf95659c7cbcef8151 | |
parent | d2907aa522d56a4baacec1c17426f7d6f1fae3a2 (diff) | |
download | NorthstarLauncher-ba26be9bea801f219fa6340178fd6b13f02d574e.tar.gz NorthstarLauncher-ba26be9bea801f219fa6340178fd6b13f02d574e.zip |
clang format, fix issues with server registration and rpak loading
58 files changed, 720 insertions, 412 deletions
diff --git a/NorthstarDLL/NorthstarDLL.vcxproj b/NorthstarDLL/NorthstarDLL.vcxproj index 7b2ece51..b6f3ea37 100644 --- a/NorthstarDLL/NorthstarDLL.vcxproj +++ b/NorthstarDLL/NorthstarDLL.vcxproj @@ -553,7 +553,6 @@ <ClInclude Include="scriptsrson.h" />
<ClInclude Include="serverauthentication.h" />
<ClInclude Include="serverpresence.h" />
- <ClInclude Include="sigscanning.h" />
<ClInclude Include="sourceconsole.h" />
<ClInclude Include="sourceinterface.h" />
<ClInclude Include="squirrel.h" />
diff --git a/NorthstarDLL/NorthstarDLL.vcxproj.filters b/NorthstarDLL/NorthstarDLL.vcxproj.filters index 66fe25ca..9b5837d2 100644 --- a/NorthstarDLL/NorthstarDLL.vcxproj.filters +++ b/NorthstarDLL/NorthstarDLL.vcxproj.filters @@ -1470,9 +1470,6 @@ <ClInclude Include="tier0.h">
<Filter>Header Files\Game Functions</Filter>
</ClInclude>
- <ClInclude Include="sigscanning.h">
- <Filter>Header Files\Hooks</Filter>
- </ClInclude>
<ClInclude Include="rpakfilesystem.h">
<Filter>Header Files\Filesystem</Filter>
</ClInclude>
diff --git a/NorthstarDLL/audio.cpp b/NorthstarDLL/audio.cpp index c298687a..268175bf 100644 --- a/NorthstarDLL/audio.cpp +++ b/NorthstarDLL/audio.cpp @@ -372,8 +372,10 @@ bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal( // DO NOT TOUCH THIS FUNCTION // The actual logic of it in a separate function (forcefully not inlined) to preserve the r12 register, which holds the event pointer. +// clang-format off AUTOHOOK(LoadSampleMetadata, mileswin64.dll + 0xF110, bool, __fastcall, (void* sample, void* audioBuffer, unsigned int audioBufferLength, int audioType)) +// clang-format on { uintptr_t parentEvent = (uintptr_t)Audio_GetParentEvent(); @@ -488,8 +490,10 @@ bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal( return res; } +// clang-format off AUTOHOOK(MilesLog, client.dll + 0x57DAD0, void, __fastcall, (int level, const char* string)) +// clang-format on { spdlog::info("[MSS] {} - {}", level, string); } diff --git a/NorthstarDLL/buildainfile.cpp b/NorthstarDLL/buildainfile.cpp index c61484c7..8190adba 100644 --- a/NorthstarDLL/buildainfile.cpp +++ b/NorthstarDLL/buildainfile.cpp @@ -361,16 +361,20 @@ void DumpAINInfo(CAI_Network* aiNetwork) writeStream.close(); } +// clang-format off AUTOHOOK(CAI_NetworkBuilder__Build, server.dll + 0x385E20, -void,, (void* builder, CAI_Network* aiNetwork, void* unknown)) +void, __fastcall, (void* builder, CAI_Network* aiNetwork, void* unknown)) +// clang-format on { CAI_NetworkBuilder__Build(builder, aiNetwork, unknown); DumpAINInfo(aiNetwork); } +// clang-format off AUTOHOOK(LoadAINFile, server.dll + 0x3933A0, -void,, (void* aimanager, void* buf, const char* filename)) +void, __fastcall, (void* aimanager, void* buf, const char* filename)) +// clang-format on { LoadAINFile(aimanager, buf, filename); diff --git a/NorthstarDLL/chatcommand.cpp b/NorthstarDLL/chatcommand.cpp index 05404363..37c438f3 100644 --- a/NorthstarDLL/chatcommand.cpp +++ b/NorthstarDLL/chatcommand.cpp @@ -5,8 +5,7 @@ // note: isIngameChat is an int64 because the whole register the arg is stored in needs to be 0'd out to work // if isIngameChat is false, we use network chat instead -typedef void(__fastcall* ClientSayTextType)(void* a1, const char* message, uint64_t isIngameChat, bool isTeamChat); -ClientSayTextType ClientSayText; +void(__fastcall* ClientSayText)(void* a1, const char* message, uint64_t isIngameChat, bool isTeamChat); void ConCommand_say(const CCommand& args) { @@ -30,7 +29,7 @@ void ConCommand_log(const CCommand& args) ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", ClientChatCommand, ConCommand, (CModule module)) { - ClientSayText = module.Offset(0x54780).As<ClientSayTextType>(); + ClientSayText = module.Offset(0x54780).As<void(__fastcall*)(void* a1, const char* message, uint64_t isIngameChat, bool isTeamChat)>(); RegisterConCommand("say", ConCommand_say, "Enters a message in public chat", FCVAR_CLIENTDLL); RegisterConCommand("say_team", ConCommand_say_team, "Enters a message in team chat", FCVAR_CLIENTDLL); RegisterConCommand("log", ConCommand_log, "Log a message to the local chat window", FCVAR_CLIENTDLL); diff --git a/NorthstarDLL/clientauthhooks.cpp b/NorthstarDLL/clientauthhooks.cpp index 3f3ace8e..ccd7432e 100644 --- a/NorthstarDLL/clientauthhooks.cpp +++ b/NorthstarDLL/clientauthhooks.cpp @@ -12,8 +12,10 @@ const int NOT_DECIDED_TO_SEND_TOKEN = 0; const int AGREED_TO_SEND_TOKEN = 1; const int DISAGREED_TO_SEND_TOKEN = 2; +// clang-format off AUTOHOOK(AuthWithStryder, engine.dll + 0x1843A0, -void,, (void* a1)) +void, __fastcall, (void* a1)) +// clang-format on { // game will call this forever, until it gets a valid auth key // so, we need to manually invalidate our key until we're authed with northstar, then we'll allow game to auth with stryder diff --git a/NorthstarDLL/clientchathooks.cpp b/NorthstarDLL/clientchathooks.cpp index 647e67f1..a7a42689 100644 --- a/NorthstarDLL/clientchathooks.cpp +++ b/NorthstarDLL/clientchathooks.cpp @@ -7,8 +7,10 @@ AUTOHOOK_INIT() -AUTOHOOK(CHudChat__AddGameLine, client.dll + 0x22E580, -void,, (void* self, const char* message, int inboxId, bool isTeam, bool isDead)) +// clang-format off +AUTOHOOK(CHudChat__AddGameLine, client.dll + 0x22E580, +void, __fastcall, (void* self, const char* message, int inboxId, bool isTeam, bool isDead)) +// clang-format on { // This hook is called for each HUD, but we only want our logic to run once. if (self != *CHudChat::allHuds) diff --git a/NorthstarDLL/clientruihooks.cpp b/NorthstarDLL/clientruihooks.cpp index 9d6562d2..3cb08368 100644 --- a/NorthstarDLL/clientruihooks.cpp +++ b/NorthstarDLL/clientruihooks.cpp @@ -5,8 +5,10 @@ AUTOHOOK_INIT() ConVar* Cvar_rui_drawEnable; +// clang-format off AUTOHOOK(DrawRUIFunc, engine.dll + 0xFC500, -bool,, (void* a1, float* a2)) +bool, __fastcall, (void* a1, float* a2)) +// clang-format on { if (!Cvar_rui_drawEnable->GetBool()) return 0; diff --git a/NorthstarDLL/clientvideooverrides.cpp b/NorthstarDLL/clientvideooverrides.cpp index 6d5c9053..b9954bf2 100644 --- a/NorthstarDLL/clientvideooverrides.cpp +++ b/NorthstarDLL/clientvideooverrides.cpp @@ -3,8 +3,10 @@ AUTOHOOK_INIT() +// clang-format off AUTOHOOK_PROCADDRESS(BinkOpen, bink2w64.dll, BinkOpen, -void*,, (const char* path, uint32_t flags)) +void*, __fastcall, (const char* path, uint32_t flags)) +// clang-format on { std::string filename(fs::path(path).filename().string()); spdlog::info("BinkOpen {}", filename); diff --git a/NorthstarDLL/concommand.h b/NorthstarDLL/concommand.h index a02604f2..89363bc7 100644 --- a/NorthstarDLL/concommand.h +++ b/NorthstarDLL/concommand.h @@ -83,7 +83,8 @@ typedef void (*FnCommandCallback_t)(const CCommand& command); //----------------------------------------------------------------------------- // Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings //----------------------------------------------------------------------------- -typedef int (*__fastcall FnCommandCompletionCallback)(const char* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]); +typedef int (*__fastcall FnCommandCompletionCallback)( + const char* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]); // From r5reloaded class ConCommandBase diff --git a/NorthstarDLL/convar.h b/NorthstarDLL/convar.h index 5a9aa4eb..176d0d72 100644 --- a/NorthstarDLL/convar.h +++ b/NorthstarDLL/convar.h @@ -59,9 +59,9 @@ #define FCVAR_SERVER_CANNOT_QUERY \ (1 << 29) // If this is set, then the server is not allowed to query this cvar's value (via IServerPluginHelpers::StartQueryCvarValue). -// !!!NOTE!!! : this is likely incorrect, there are multiple concommands that the vanilla game registers with this flag that 100% should not be remotely executable -// i.e. multiple commands that only exist on client (screenshot, joystick_initialize) -// we now use FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS in all places this flag was previously used +// !!!NOTE!!! : this is likely incorrect, there are multiple concommands that the vanilla game registers with this flag that 100% should not +// be remotely executable i.e. multiple commands that only exist on client (screenshot, joystick_initialize) we now use +// FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS in all places this flag was previously used #define FCVAR_CLIENTCMD_CAN_EXECUTE \ (1 << 30) // IVEngineClient::ClientCmd is allowed to execute this command. // Note: IVEngineClient::ClientCmd_Unrestricted can run any client command. @@ -108,8 +108,7 @@ const std::multimap<int, const char*> g_PrintCommandFlags = { {FCVAR_SERVER_CAN_EXECUTE, "SERVER_CAN_EXECUTE"}, {FCVAR_SERVER_CANNOT_QUERY, "SERVER_CANNOT_QUERY"}, {FCVAR_CLIENTCMD_CAN_EXECUTE, "UNKNOWN"}, - {FCVAR_ACCESSIBLE_FROM_THREADS, "ACCESSIBLE_FROM_THREADS"} -}; + {FCVAR_ACCESSIBLE_FROM_THREADS, "ACCESSIBLE_FROM_THREADS"}}; //----------------------------------------------------------------------------- // Forward declarations diff --git a/NorthstarDLL/debugoverlay.cpp b/NorthstarDLL/debugoverlay.cpp index 2d2d03e0..ef456867 100644 --- a/NorthstarDLL/debugoverlay.cpp +++ b/NorthstarDLL/debugoverlay.cpp @@ -76,8 +76,10 @@ typedef void (*RenderBoxType)(Vector3 vOrigin, QAngle angles, Vector3 vMins, Vec static RenderBoxType RenderBox; static RenderBoxType RenderWireframeBox; +// clang-format off AUTOHOOK(DrawOverlay, engine.dll + 0xABCB0, void, __fastcall, (OverlayBase_t * pOverlay)) +// clang-format on { EnterCriticalSection((LPCRITICAL_SECTION)((char*)sEngineModule + 0x10DB0A38)); // s_OverlayMutex diff --git a/NorthstarDLL/dedicated.cpp b/NorthstarDLL/dedicated.cpp index 42af9456..251e2437 100644 --- a/NorthstarDLL/dedicated.cpp +++ b/NorthstarDLL/dedicated.cpp @@ -114,7 +114,10 @@ DWORD WINAPI ConsoleInputThread(PVOID pThreadParameter) return 0; } -AUTOHOOK(IsGameActiveWindow, engine.dll + 0x1CDC80, bool, , ()) +// clang-format off +AUTOHOOK(IsGameActiveWindow, engine.dll + 0x1CDC80, +bool,, ()) +// clang-format on { return true; } @@ -130,7 +133,8 @@ ON_DLL_LOAD_DEDI_RELIESON("engine.dll", DedicatedServer, ServerPresence, (CModul module.Offset(0x156799).NOP(5); // Host_Init - // don't call Key_Init to avoid loading some extra rsons from rpak (will be necessary to boot if we ever wanna disable rpaks entirely on dedi) + // don't call Key_Init to avoid loading some extra rsons from rpak (will be necessary to boot if we ever wanna disable rpaks entirely on + // dedi) module.Offset(0x1565B0).NOP(5); { @@ -262,8 +266,10 @@ ON_DLL_LOAD_DEDI("tier0.dll", DedicatedServerOrigin, (CModule module)) module.GetExport("Tier0_InitOrigin").Patch("C3"); } +// clang-format off AUTOHOOK(PrintSquirrelError, server.dll + 0x794D0, -void, , (void* sqvm)) +void, __fastcall, (void* sqvm)) +// clang-format on { PrintSquirrelError(sqvm); diff --git a/NorthstarDLL/dedicatedmaterialsystem.cpp b/NorthstarDLL/dedicatedmaterialsystem.cpp index 5dfa19ec..28ee9b76 100644 --- a/NorthstarDLL/dedicatedmaterialsystem.cpp +++ b/NorthstarDLL/dedicatedmaterialsystem.cpp @@ -4,6 +4,7 @@ AUTOHOOK_INIT() +// clang-format off AUTOHOOK(D3D11CreateDevice, materialsystem_dx11.dll + 0xD9A0E, HRESULT, __stdcall, ( void* pAdapter, @@ -16,6 +17,7 @@ HRESULT, __stdcall, ( void** ppDevice, int* pFeatureLevel, void** ppImmediateContext)) +// clang-format on { // note: this is super duper temp pretty much just messing around with it // does run surprisingly well on dedi for a software driver tho if you ignore the +1gb ram usage at times, seems like dedi doesn't diff --git a/NorthstarDLL/exploitfixes.cpp b/NorthstarDLL/exploitfixes.cpp index 419fc448..de60a854 100644 --- a/NorthstarDLL/exploitfixes.cpp +++ b/NorthstarDLL/exploitfixes.cpp @@ -18,7 +18,7 @@ ConVar* Cvar_sv_cheats; ( \ [=]() -> bool \ { \ - if (Cvar_ns_exploitfixes_log->GetBool()) \ + if (Cvar_ns_exploitfixes_log->GetBool()) \ { \ std::stringstream stream; \ stream << "ExploitFixes.cpp: " << BLOCK_PREFIX << s; \ @@ -29,27 +29,35 @@ ConVar* Cvar_sv_cheats; // block bad netmessages // Servers can literally request a screenshot from any client, yeah no +// clang-format off AUTOHOOK(CLC_Screenshot_WriteToBuffer, engine.dll + 0x22AF20, bool, __fastcall, (void* thisptr, void* buffer)) // 48 89 5C 24 ? 57 48 83 EC 20 8B 42 10 +// clang-format on { return false; } +// clang-format off AUTOHOOK(CLC_Screenshot_ReadFromBuffer, engine.dll + 0x221F00, bool, __fastcall, (void* thisptr, void* buffer)) // 48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 48 8B DA 48 8B 52 38 +// clang-format on { return false; } // This is unused ingame and a big client=>server=>client exploit vector +// clang-format off AUTOHOOK(Base_CmdKeyValues_ReadFromBuffer, engine.dll + 0x220040, bool, __fastcall, (void* thisptr, void* buffer)) // 40 55 48 81 EC ? ? ? ? 48 8D 6C 24 ? 48 89 5D 70 +// clang-format on { return false; } +// clang-format off AUTOHOOK(CClient_ProcessSetConVar, engine.dll + 0x75CF0, bool, __fastcall, (void* pMsg)) // 48 8B D1 48 8B 49 18 48 8B 01 48 FF 60 10 +// clang-format on { constexpr int ENTRY_STR_LEN = 260; @@ -74,7 +82,8 @@ bool, __fastcall, (void* pMsg)) // 48 8B D1 48 8B 49 18 48 8B 01 48 FF 60 10 auto msg = (NET_SetConVar*)pMsg; bool bIsServerFrame = Tier0::ThreadInServerFrameThread(); - std::string BLOCK_PREFIX = std::string {"NET_SetConVar ("} + (bIsServerFrame ? "server" : "client") + "): Blocked dangerous/invalid msg: "; + std::string BLOCK_PREFIX = + std::string {"NET_SetConVar ("} + (bIsServerFrame ? "server" : "client") + "): Blocked dangerous/invalid msg: "; if (bIsServerFrame) { @@ -147,8 +156,10 @@ bool, __fastcall, (void* pMsg)) // 48 8B D1 48 8B 49 18 48 8B 01 48 FF 60 10 } // prevent invalid user CMDs +// clang-format off AUTOHOOK(CClient_ProcessUsercmds, engine.dll + 0x1040F0, bool, __fastcall, (void* thisptr, void* pMsg)) // 40 55 56 48 83 EC 58 +// clang-format on { struct CLC_Move { @@ -181,8 +192,10 @@ bool, __fastcall, (void* thisptr, void* pMsg)) // 40 55 56 48 83 EC 58 return CClient_ProcessUsercmds(thisptr, pMsg); } +// clang-format off AUTOHOOK(ReadUsercmd, server.dll + 0x2603F0, void, __fastcall, (void* buf, void* pCmd_move, void* pCmd_from)) // 4C 89 44 24 ? 53 55 56 57 +// clang-format on { // Let normal usercmd read happen first, it's safe ReadUsercmd(buf, pCmd_move, pCmd_from); @@ -256,22 +269,26 @@ INVALID_CMD: // ensure that GetLocalBaseClient().m_bRestrictServerCommands is set correctly, which the return value of this function controls // this is IsValveMod in source, but we're making it IsRespawnMod now since valve didn't make this one +// clang-format off AUTOHOOK(IsRespawnMod, engine.dll + 0x1C6360, bool, __fastcall, (const char* pModName)) // 48 83 EC 28 48 8B 0D ? ? ? ? 48 8D 15 ? ? ? ? E8 ? ? ? ? 85 C0 74 63 +// clang-format on { // somewhat temp, store the modname here, since we don't have a proper ptr in engine to it rn int iSize = strlen(pModName); R2::g_pModName = new char[iSize + 1]; strcpy(R2::g_pModName, pModName); - return (!strcmp("r2", pModName) || !strcmp("r1", pModName)) - && !Tier0::CommandLine()->CheckParm("-norestrictservercommands"); + return (!strcmp("r2", pModName) || !strcmp("r1", pModName)) && !Tier0::CommandLine()->CheckParm("-norestrictservercommands"); } // ratelimit stringcmds, and prevent remote clients from calling commands that they shouldn't bool (*CCommand__Tokenize)(CCommand& self, const char* pCommandString, R2::cmd_source_t commandSource); -AUTOHOOK(CGameClient__ExecuteStringCommand, -engine.dll + 0x1022E0, bool, , (R2::CBaseClient* self, uint32_t unknown, const char* pCommandString)) + +// clang-format off +AUTOHOOK(CGameClient__ExecuteStringCommand, engine.dll + 0x1022E0, +bool, __fastcall, (R2::CBaseClient* self, uint32_t unknown, const char* pCommandString)) +// clang-format on { if (Cvar_ns_should_log_all_clientcommands->GetBool()) spdlog::info("player {} (UID: {}) sent command: \"{}\"", self->m_Name, self->m_UID, pCommandString); @@ -341,8 +358,11 @@ engine.dll + 0x1022E0, bool, , (R2::CBaseClient* self, uint32_t unknown, const c // prevent clients from crashing servers through overflowing CNetworkStringTableContainer::WriteBaselines bool bWasWritingStringTableSuccessful; -AUTOHOOK(CBaseClient__SendServerInfo, -engine.dll + 0x104FB0, void, , (void* self)) + +// clang-format off +AUTOHOOK(CBaseClient__SendServerInfo, engine.dll + 0x104FB0, +void, __fastcall, (void* self)) +// clang-format on { bWasWritingStringTableSuccessful = true; CBaseClient__SendServerInfo(self); @@ -353,8 +373,10 @@ engine.dll + 0x104FB0, void, , (void* self)) // return null when GetEntByIndex is passed an index >= 0x4000 // this is called from exactly 1 script clientcommand that can be given an arbitrary index, and going above 0x4000 crashes -AUTOHOOK(GetEntByIndex, engine.dll + 0x2A8A50, -void*,, (int i)) +// clang-format off +AUTOHOOK(GetEntByIndex, server.dll + 0x2A8A50, +void*, __fastcall, (int i)) +// clang-format on { const int MAX_ENT_IDX = 0x4000; diff --git a/NorthstarDLL/exploitfixes_lzss.cpp b/NorthstarDLL/exploitfixes_lzss.cpp index 87d2868d..4205133a 100644 --- a/NorthstarDLL/exploitfixes_lzss.cpp +++ b/NorthstarDLL/exploitfixes_lzss.cpp @@ -12,8 +12,10 @@ struct lzss_header_t // Rewrite of CLZSS::SafeUncompress to fix a vulnerability where malicious compressed payloads could cause the decompressor to try to read // out of the bounds of the output buffer. +// clang-format off AUTOHOOK(CLZSS__SafeDecompress, engine.dll + 0x432A10, -unsigned int,, (void* self, const unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize)) +unsigned int, __fastcall, (void* self, const unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize)) +// clang-format on { unsigned int totalBytes = 0; int getCmdByte = 0; diff --git a/NorthstarDLL/exploitfixes_utf8parser.cpp b/NorthstarDLL/exploitfixes_utf8parser.cpp index 581596a7..e2510765 100644 --- a/NorthstarDLL/exploitfixes_utf8parser.cpp +++ b/NorthstarDLL/exploitfixes_utf8parser.cpp @@ -169,20 +169,24 @@ LABEL_48: return true; } -// prevent utf8 parser from crashing when provided bad data, which can be sent through user-controlled openinvites +// prevent utf8 parser from crashing when provided bad data, which can be sent through user-controlled openinvites +// clang-format off AUTOHOOK(Rson_ParseUTF8, engine.dll + 0xEF670, bool, __fastcall, (INT64* a1, DWORD* a2, char* strData)) // 48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 41 54 41 55 41 56 41 57 48 83 EC 20 8B 1A +// clang-format on { static void* targetRetAddr = CModule("engine.dll").FindPattern("84 C0 75 2C 49 8B 16"); // only call if we're parsing utf8 data from the network (i.e. communities), otherwise we get perf issues - if ( + void* pReturnAddress = #ifdef _MSC_VER _ReturnAddress() #else __builtin_return_address(0) #endif - == targetRetAddr && !CheckUTF8Valid(a1, a2, strData)) + ; + + if (pReturnAddress == targetRetAddr && !CheckUTF8Valid(a1, a2, strData)) return false; return Rson_ParseUTF8(a1, a2, strData); diff --git a/NorthstarDLL/filesystem.cpp b/NorthstarDLL/filesystem.cpp index 9fba160f..e6c6f49a 100644 --- a/NorthstarDLL/filesystem.cpp +++ b/NorthstarDLL/filesystem.cpp @@ -51,8 +51,10 @@ namespace R2 } } // namespace R2 +// clang-format off HOOK(AddSearchPathHook, AddSearchPath, -void,, (IFileSystem* fileSystem, const char* pPath, const char* pathID, SearchPathAdd_t addType)) +void, __fastcall, (IFileSystem * fileSystem, const char* pPath, const char* pathID, SearchPathAdd_t addType)) +// clang-format on { AddSearchPath(fileSystem, pPath, pathID, addType); @@ -104,8 +106,10 @@ bool TryReplaceFile(const char* pPath, bool shouldCompile) } // force modded files to be read from mods, not cache +// clang-format off HOOK(ReadFromCacheHook, ReadFromCache, -bool,, (IFileSystem* filesystem, char* pPath, void* result)) +bool, __fastcall, (IFileSystem * filesystem, char* pPath, void* result)) +// clang-format off { if (TryReplaceFile(pPath, true)) return false; @@ -114,8 +118,10 @@ bool,, (IFileSystem* filesystem, char* pPath, void* result)) } // force modded files to be read from mods, not vpk +// clang-format off AUTOHOOK(ReadFileFromVPK, filesystem_stdio.dll + 0x5CBA0, -FileHandle_t,, (VPKData* vpkInfo, uint64_t* b, char* filename)) +FileHandle_t, __fastcall, (VPKData* vpkInfo, uint64_t* b, char* filename)) +// clang-format on { // don't compile here because this is only ever called from OpenEx, which already compiles if (TryReplaceFile(filename, false)) @@ -127,15 +133,16 @@ FileHandle_t,, (VPKData* vpkInfo, uint64_t* b, char* filename)) return ReadFileFromVPK(vpkInfo, b, filename); } +// clang-format off AUTOHOOK(CBaseFileSystem__OpenEx, filesystem_stdio.dll + 0x15F50, -FileHandle_t,, (IFileSystem* filesystem, const char* pPath, const char* pOptions, uint32_t flags, const char* pPathID, char **ppszResolvedFilename)) +FileHandle_t, __fastcall, (IFileSystem* filesystem, const char* pPath, const char* pOptions, uint32_t flags, const char* pPathID, char **ppszResolvedFilename)) +// clang-format on { TryReplaceFile(pPath, true); return CBaseFileSystem__OpenEx(filesystem, pPath, pOptions, flags, pPathID, ppszResolvedFilename); } -HOOK(MountVPKHook, MountVPK, -VPKData*,, (IFileSystem* fileSystem, const char* pVpkPath)) +HOOK(MountVPKHook, MountVPK, VPKData*, , (IFileSystem * fileSystem, const char* pVpkPath)) { spdlog::info("MountVPK {}", pVpkPath); VPKData* ret = MountVPK(fileSystem, pVpkPath); diff --git a/NorthstarDLL/hooks.cpp b/NorthstarDLL/hooks.cpp index f0ea74e9..4c068fe8 100644 --- a/NorthstarDLL/hooks.cpp +++ b/NorthstarDLL/hooks.cpp @@ -44,23 +44,23 @@ __dllLoadCallback::__dllLoadCallback( switch (side) { - case eDllLoadCallbackSide::UNSIDED: - { - AddDllLoadCallback(dllName, callback, uniqueStr, reliesOnArray); - break; - } + case eDllLoadCallbackSide::UNSIDED: + { + AddDllLoadCallback(dllName, callback, uniqueStr, reliesOnArray); + break; + } - case eDllLoadCallbackSide::CLIENT: - { - AddDllLoadCallbackForClient(dllName, callback, uniqueStr, reliesOnArray); - break; - } + case eDllLoadCallbackSide::CLIENT: + { + AddDllLoadCallbackForClient(dllName, callback, uniqueStr, reliesOnArray); + break; + } - case eDllLoadCallbackSide::DEDICATED_SERVER: - { - AddDllLoadCallbackForDedicatedServer(dllName, callback, uniqueStr, reliesOnArray); - break; - } + case eDllLoadCallbackSide::DEDICATED_SERVER: + { + AddDllLoadCallbackForDedicatedServer(dllName, callback, uniqueStr, reliesOnArray); + break; + } } } @@ -80,16 +80,14 @@ void __fileAutohook::DispatchForModule(const char* pModuleName) hook->Dispatch(); } -ManualHook::ManualHook(const char* funcName, LPVOID func) - : pHookFunc(func), ppOrigFunc(nullptr) +ManualHook::ManualHook(const char* funcName, LPVOID func) : pHookFunc(func), ppOrigFunc(nullptr) { const int iFuncNameStrlen = strlen(funcName); pFuncName = new char[iFuncNameStrlen]; memcpy(pFuncName, funcName, iFuncNameStrlen); } -ManualHook::ManualHook(const char* funcName, LPVOID* orig, LPVOID func) - : pHookFunc(func), ppOrigFunc(orig) +ManualHook::ManualHook(const char* funcName, LPVOID* orig, LPVOID func) : pHookFunc(func), ppOrigFunc(orig) { const int iFuncNameStrlen = strlen(funcName); pFuncName = new char[iFuncNameStrlen]; @@ -182,8 +180,7 @@ void MakeHook(LPVOID pTarget, LPVOID pDetour, void* ppOriginal, const char* pFun spdlog::error("MH_CreateHook failed for function {}", pStrippedFuncName); } -AUTOHOOK_ABSOLUTEADDR(_GetCommandLineA, GetCommandLineA, -LPSTR, WINAPI, ()) +AUTOHOOK_ABSOLUTEADDR(_GetCommandLineA, GetCommandLineA, LPSTR, WINAPI, ()) { static char* cmdlineModified; static char* cmdlineOrg; @@ -352,9 +349,8 @@ void CallAllPendingDLLLoadCallbacks() } } -AUTOHOOK_ABSOLUTEADDR(_LoadLibraryExA, LoadLibraryExA, -HMODULE, WINAPI, (LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)) - { +AUTOHOOK_ABSOLUTEADDR(_LoadLibraryExA, LoadLibraryExA, HMODULE, WINAPI, (LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)) +{ HMODULE moduleAddress = _LoadLibraryExA(lpLibFileName, hFile, dwFlags); if (moduleAddress) @@ -363,9 +359,7 @@ HMODULE, WINAPI, (LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)) return moduleAddress; } - -AUTOHOOK_ABSOLUTEADDR(_LoadLibraryA, LoadLibraryA, -HMODULE, WINAPI, (LPCSTR lpLibFileName)) +AUTOHOOK_ABSOLUTEADDR(_LoadLibraryA, LoadLibraryA, HMODULE, WINAPI, (LPCSTR lpLibFileName)) { HMODULE moduleAddress = _LoadLibraryA(lpLibFileName); @@ -375,8 +369,7 @@ HMODULE, WINAPI, (LPCSTR lpLibFileName)) return moduleAddress; } -AUTOHOOK_ABSOLUTEADDR(_LoadLibraryExW, LoadLibraryExW, -HMODULE, WINAPI, (LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)) +AUTOHOOK_ABSOLUTEADDR(_LoadLibraryExW, LoadLibraryExW, HMODULE, WINAPI, (LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)) { HMODULE moduleAddress = _LoadLibraryExW(lpLibFileName, hFile, dwFlags); @@ -386,8 +379,7 @@ HMODULE, WINAPI, (LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)) return moduleAddress; } -AUTOHOOK_ABSOLUTEADDR(_LoadLibraryW, LoadLibraryW, -HMODULE, WINAPI, (LPCWSTR lpLibFileName)) +AUTOHOOK_ABSOLUTEADDR(_LoadLibraryW, LoadLibraryW, HMODULE, WINAPI, (LPCWSTR lpLibFileName)) { HMODULE moduleAddress = _LoadLibraryW(lpLibFileName); diff --git a/NorthstarDLL/hooks.h b/NorthstarDLL/hooks.h index feda40c7..f47791fb 100644 --- a/NorthstarDLL/hooks.h +++ b/NorthstarDLL/hooks.h @@ -42,17 +42,24 @@ class __dllLoadCallback #define __STR(s) #s // adds a callback to be called when a given dll is loaded, for creating hooks and such -#define __ON_DLL_LOAD(dllName, side, uniquestr, reliesOn, args) \ -void CONCAT2(__dllLoadCallback, uniquestr) args; \ -namespace { __dllLoadCallback CONCAT2(__dllLoadCallbackInstance, __LINE__)(side, dllName, CONCAT2(__dllLoadCallback, uniquestr), __STR(uniquestr), reliesOn); } \ -void CONCAT2(__dllLoadCallback, uniquestr) args \ +#define __ON_DLL_LOAD(dllName, side, uniquestr, reliesOn, args) \ + void CONCAT2(__dllLoadCallback, uniquestr) args; \ + namespace \ + { \ + __dllLoadCallback CONCAT2(__dllLoadCallbackInstance, __LINE__)( \ + side, dllName, CONCAT2(__dllLoadCallback, uniquestr), __STR(uniquestr), reliesOn); \ + } \ + void CONCAT2(__dllLoadCallback, uniquestr) args #define ON_DLL_LOAD(dllName, uniquestr, args) __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::UNSIDED, uniquestr, "", args) -#define ON_DLL_LOAD_RELIESON(dllName, uniquestr, reliesOn, args) __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::UNSIDED, uniquestr, __STR(reliesOn), args) +#define ON_DLL_LOAD_RELIESON(dllName, uniquestr, reliesOn, args) \ + __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::UNSIDED, uniquestr, __STR(reliesOn), args) #define ON_DLL_LOAD_CLIENT(dllName, uniquestr, args) __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::CLIENT, uniquestr, "", args) -#define ON_DLL_LOAD_CLIENT_RELIESON(dllName, uniquestr, reliesOn, args) __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::CLIENT, uniquestr, __STR(reliesOn), args) +#define ON_DLL_LOAD_CLIENT_RELIESON(dllName, uniquestr, reliesOn, args) \ + __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::CLIENT, uniquestr, __STR(reliesOn), args) #define ON_DLL_LOAD_DEDI(dllName, uniquestr, args) __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::DEDICATED_SERVER, uniquestr, "", args) -#define ON_DLL_LOAD_DEDI_RELIESON(dllName, uniquestr, reliesOn, args) __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::DEDICATED_SERVER, uniquestr, __STR(reliesOn), args) +#define ON_DLL_LOAD_DEDI_RELIESON(dllName, uniquestr, reliesOn, args) \ + __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::DEDICATED_SERVER, uniquestr, __STR(reliesOn), args) // new macro hook stuff class __autohook; @@ -67,15 +74,16 @@ class __fileAutohook }; // initialise autohooks for this file -#define AUTOHOOK_INIT() \ -namespace { __fileAutohook __FILEAUTOHOOK; } \ +#define AUTOHOOK_INIT() \ + namespace \ + { \ + __fileAutohook __FILEAUTOHOOK; \ + } // dispatch all autohooks in this file -#define AUTOHOOK_DISPATCH() \ -__FILEAUTOHOOK.Dispatch(); \ +#define AUTOHOOK_DISPATCH() __FILEAUTOHOOK.Dispatch(); -#define AUTOHOOK_DISPATCH_MODULE(moduleName) \ -__FILEAUTOHOOK.DispatchForModule(__STR(moduleName)); \ +#define AUTOHOOK_DISPATCH_MODULE(moduleName) __FILEAUTOHOOK.DispatchForModule(__STR(moduleName)); class __autohook { @@ -99,7 +107,7 @@ class __autohook char* pModuleName; // for PROCADDRESS char* pProcName; // for PROCADDRESS - public: + public: __autohook() = delete; __autohook(__fileAutohook* autohook, const char* funcName, LPVOID absoluteAddress, LPVOID* orig, LPVOID func) @@ -164,7 +172,7 @@ class __autohook delete[] pProcName; } - void Dispatch() + void Dispatch() { LPVOID targetAddr = nullptr; @@ -181,7 +189,8 @@ class __autohook { // in the format server.dll + 0xDEADBEEF int iDllNameEnd = 0; - for (; !isspace(pAddrString[iDllNameEnd]) && pAddrString[iDllNameEnd] != '+'; iDllNameEnd++); + for (; !isspace(pAddrString[iDllNameEnd]) && pAddrString[iDllNameEnd] != '+'; iDllNameEnd++) + ; char* pModuleName = new char[iDllNameEnd + 1]; memcpy(pModuleName, pAddrString, iDllNameEnd); @@ -200,9 +209,11 @@ class __autohook int iOffsetEnd = strlen(pAddrString); // seek until we hit the start of the number offset - for (; !(pAddrString[iOffsetBegin] >= '0' && pAddrString[iOffsetBegin] <= '9') && pAddrString[iOffsetBegin]; iOffsetBegin++); + for (; !(pAddrString[iOffsetBegin] >= '0' && pAddrString[iOffsetBegin] <= '9') && pAddrString[iOffsetBegin]; iOffsetBegin++) + ; - bool bIsHex = pAddrString[iOffsetBegin] == '0' && (pAddrString[iOffsetBegin + 1] == 'X' || pAddrString[iOffsetBegin + 1] == 'x'); + bool bIsHex = + pAddrString[iOffsetBegin] == '0' && (pAddrString[iOffsetBegin + 1] == 'X' || pAddrString[iOffsetBegin + 1] == 'x'); if (bIsHex) iOffset = std::stoi(pAddrString + iOffsetBegin + 2, 0, 16); else @@ -232,31 +243,38 @@ class __autohook }; // hook a function at a given offset from a dll to be dispatched with AUTOHOOK_DISPATCH() -#define AUTOHOOK(name, addrString, type, callingConvention, args) \ -type callingConvention CONCAT2(__autohookfunc, name) args; \ -namespace { \ -type(*callingConvention name) args; \ -__autohook CONCAT2(__autohook, __LINE__)(&__FILEAUTOHOOK, __STR(name), __STR(addrString), (LPVOID*)&name, (LPVOID)CONCAT2(__autohookfunc, name)); \ -} \ -type callingConvention CONCAT2(__autohookfunc, name) args \ +#define AUTOHOOK(name, addrString, type, callingConvention, args) \ + type callingConvention CONCAT2(__autohookfunc, name) args; \ + namespace \ + { \ + type(*callingConvention name) args; \ + __autohook CONCAT2(__autohook, __LINE__)( \ + &__FILEAUTOHOOK, __STR(name), __STR(addrString), (LPVOID*)&name, (LPVOID)CONCAT2(__autohookfunc, name)); \ + } \ + type callingConvention CONCAT2(__autohookfunc, name) args // hook a function at a given absolute constant address to be dispatched with AUTOHOOK_DISPATCH() -#define AUTOHOOK_ABSOLUTEADDR(name, addr, type, callingConvention, args) \ -type callingConvention CONCAT2(__autohookfunc, name) args; \ -namespace { \ -type(*callingConvention name) args; \ -__autohook CONCAT2(__autohook, __LINE__)(&__FILEAUTOHOOK, __STR(name), addr, (LPVOID*)&name, (LPVOID)CONCAT2(__autohookfunc, name)); \ -} \ -type callingConvention CONCAT2(__autohookfunc, name) args \ +#define AUTOHOOK_ABSOLUTEADDR(name, addr, type, callingConvention, args) \ + type callingConvention CONCAT2(__autohookfunc, name) args; \ + namespace \ + { \ + type(*callingConvention name) args; \ + __autohook \ + CONCAT2(__autohook, __LINE__)(&__FILEAUTOHOOK, __STR(name), addr, (LPVOID*)&name, (LPVOID)CONCAT2(__autohookfunc, name)); \ + } \ + type callingConvention CONCAT2(__autohookfunc, name) args // hook a function at a given module and exported function to be dispatched with AUTOHOOK_DISPATCH() -#define AUTOHOOK_PROCADDRESS(name, moduleName, procName, type, callingConvention, args) \ -type callingConvention CONCAT2(__autohookfunc, name) args; \ -namespace { \ -type(*callingConvention name) args; \ -__autohook CONCAT2(__autohook, __LINE__)(&__FILEAUTOHOOK, __STR(name), __STR(moduleName), __STR(procName), (LPVOID*)&name, (LPVOID)CONCAT2(__autohookfunc, name)); \ -} \ -type callingConvention CONCAT2(__autohookfunc, name) args \ +#define AUTOHOOK_PROCADDRESS(name, moduleName, procName, type, callingConvention, args) \ + type callingConvention CONCAT2(__autohookfunc, name) args; \ + namespace \ + { \ + type(*callingConvention name) args; \ + __autohook CONCAT2(__autohook, __LINE__)( \ + &__FILEAUTOHOOK, __STR(name), __STR(moduleName), __STR(procName), (LPVOID*)&name, (LPVOID)CONCAT2(__autohookfunc, name)); \ + } \ + type callingConvention CONCAT2(__autohookfunc, name) \ + args class ManualHook { @@ -274,16 +292,20 @@ class ManualHook }; // hook a function to be dispatched manually later -#define HOOK(varName, originalFunc, type, callingConvention, args) \ -namespace { type(*callingConvention originalFunc) args; } \ -type callingConvention CONCAT2(__manualhookfunc, varName) args; \ -ManualHook varName = ManualHook(__STR(varName), (LPVOID*)&originalFunc, (LPVOID)CONCAT2(__manualhookfunc, varName)); \ -type callingConvention CONCAT2(__manualhookfunc, varName) args \ - -#define HOOK_NOORIG(varName, type, callingConvention, args) \ -type callingConvention CONCAT2(__manualhookfunc, varName) args; \ -ManualHook varName = ManualHook(__STR(varName), (LPVOID)CONCAT2(__manualhookfunc, varName)); \ -type callingConvention CONCAT2(__manualhookfunc, varName) args \ +#define HOOK(varName, originalFunc, type, callingConvention, args) \ + namespace \ + { \ + type(*callingConvention originalFunc) args; \ + } \ + type callingConvention CONCAT2(__manualhookfunc, varName) args; \ + ManualHook varName = ManualHook(__STR(varName), (LPVOID*)&originalFunc, (LPVOID)CONCAT2(__manualhookfunc, varName)); \ + type callingConvention CONCAT2(__manualhookfunc, varName) args + +#define HOOK_NOORIG(varName, type, callingConvention, args) \ + type callingConvention CONCAT2(__manualhookfunc, varName) args; \ + ManualHook varName = ManualHook(__STR(varName), (LPVOID)CONCAT2(__manualhookfunc, varName)); \ + type callingConvention CONCAT2(__manualhookfunc, varName) \ + args void MakeHook(LPVOID pTarget, LPVOID pDetour, void* ppOriginal, const char* pFuncName = ""); #define MAKEHOOK(pTarget, pDetour, ppOriginal) MakeHook(pTarget, pDetour, ppOriginal, __STR(pDetour)) diff --git a/NorthstarDLL/host.cpp b/NorthstarDLL/host.cpp index 74dad785..e8cb9bdc 100644 --- a/NorthstarDLL/host.cpp +++ b/NorthstarDLL/host.cpp @@ -7,8 +7,10 @@ AUTOHOOK_INIT() +// clang-format off AUTOHOOK(Host_Init, engine.dll + 0x155EA0, -void,, (bool bDedicated)) +void, __fastcall, (bool bDedicated)) +// clang-format on { spdlog::info("Host_Init()"); Host_Init(bDedicated); diff --git a/NorthstarDLL/hoststate.cpp b/NorthstarDLL/hoststate.cpp index 875d671d..adbcde3b 100644 --- a/NorthstarDLL/hoststate.cpp +++ b/NorthstarDLL/hoststate.cpp @@ -6,6 +6,7 @@ #include "playlist.h" #include "tier0.h" #include "r2engine.h" +#include "limits.h" AUTOHOOK_INIT() @@ -27,8 +28,10 @@ void ServerStartingOrChangingMap() g_pCVar->FindVar("net_data_block_enabled")->SetValue(true); } +// clang-format off AUTOHOOK(CHostState__State_NewGame, engine.dll + 0x16E7D0, -void,, (CHostState* self)) +void, __fastcall, (CHostState* self)) +// clang-format on { spdlog::info("HostState: NewGame"); @@ -58,8 +61,10 @@ void,, (CHostState* self)) g_pServerAuthentication->m_bNeedLocalAuthForNewgame = false; } +// clang-format off AUTOHOOK(CHostState__State_ChangeLevelMP, engine.dll + 0x16E520, -void,, (CHostState* self)) +void, __fastcall, (CHostState* self)) +// clang-format on { spdlog::info("HostState: ChangeLevelMP"); @@ -72,8 +77,10 @@ void,, (CHostState* self)) g_pServerPresence->SetMap(g_pHostState->m_levelName); } +// clang-format off AUTOHOOK(CHostState__State_GameShutdown, engine.dll + 0x16E640, -void,, (CHostState* self)) +void, __fastcall, (CHostState* self)) +// clang-format on { spdlog::info("HostState: GameShutdown"); @@ -83,8 +90,10 @@ void,, (CHostState* self)) CHostState__State_GameShutdown(self); } +// clang-format off AUTOHOOK(CHostState__FrameUpdate, engine.dll + 0x16DB00, void, __fastcall, (CHostState* self, double flCurrentTime, float flFrameTime)) +// clang-format on { CHostState__FrameUpdate(self, flCurrentTime, flFrameTime); @@ -92,6 +101,9 @@ void, __fastcall, (CHostState* self, double flCurrentTime, float flFrameTime)) { // update server presence g_pServerPresence->RunFrame(flCurrentTime); + + // update limits for frame + g_pServerLimits->RunFrame(flCurrentTime, flFrameTime); } } diff --git a/NorthstarDLL/keyvalues.cpp b/NorthstarDLL/keyvalues.cpp index 69965e89..98a9ce66 100644 --- a/NorthstarDLL/keyvalues.cpp +++ b/NorthstarDLL/keyvalues.cpp @@ -106,8 +106,10 @@ void ModManager::TryBuildKeyValues(const char* filename) m_ModFiles[normalisedPath] = overrideFile; } +// clang-format off AUTOHOOK(KeyValues__LoadFromBuffer, engine.dll + 0x426C30, -char,, (void* self, const char* resourceName, const char* pBuffer, void* pFileSystem, void* a5, void* a6, int a7)) +char, __fastcall, (void* self, const char* resourceName, const char* pBuffer, void* pFileSystem, void* a5, void* a6, int a7)) +// clang-format on { static void* pSavedFilesystemPtr = nullptr; diff --git a/NorthstarDLL/languagehooks.cpp b/NorthstarDLL/languagehooks.cpp index 9e5dda86..d00beb68 100644 --- a/NorthstarDLL/languagehooks.cpp +++ b/NorthstarDLL/languagehooks.cpp @@ -47,8 +47,10 @@ std::string GetAnyInstalledAudioLanguage() return "NO LANGUAGE DETECTED"; } +// clang-format off AUTOHOOK(GetGameLanguage, tier0.dll + 0xF560, -char*,, ()) +char*, __fastcall, ()) +// clang-format on { auto tier0Handle = GetModuleHandleA("tier0.dll"); auto Tier0_DetectDefaultLanguageType = GetProcAddress(tier0Handle, "Tier0_DetectDefaultLanguage"); diff --git a/NorthstarDLL/latencyflex.cpp b/NorthstarDLL/latencyflex.cpp index 7b5a8ebf..620e031a 100644 --- a/NorthstarDLL/latencyflex.cpp +++ b/NorthstarDLL/latencyflex.cpp @@ -7,8 +7,10 @@ ConVar* Cvar_r_latencyflex; void (*m_winelfx_WaitAndBeginFrame)(); +// clang-format off AUTOHOOK(OnRenderStart, client.dll + 0x1952C0, -void,, ()) +void, __fastcall, ()) +// clang-format on { if (Cvar_r_latencyflex->GetBool() && m_winelfx_WaitAndBeginFrame) m_winelfx_WaitAndBeginFrame(); @@ -24,11 +26,11 @@ ON_DLL_LOAD_CLIENT_RELIESON("client.dll", LatencyFlex, ConVar, (CModule module)) HMODULE pLfxModule; if (pLfxModule = LoadLibraryA("latencyflex_layer.dll")) - m_winelfx_WaitAndBeginFrame = reinterpret_cast<void (*)()>( - reinterpret_cast<void*>(GetProcAddress(pLfxModule, "lfx_WaitAndBeginFrame"))); + m_winelfx_WaitAndBeginFrame = + reinterpret_cast<void (*)()>(reinterpret_cast<void*>(GetProcAddress(pLfxModule, "lfx_WaitAndBeginFrame"))); else if (pLfxModule = LoadLibraryA("latencyflex_wine.dll")) - m_winelfx_WaitAndBeginFrame = reinterpret_cast<void (*)()>( - reinterpret_cast<void*>(GetProcAddress(pLfxModule, "winelfx_WaitAndBeginFrame"))); + m_winelfx_WaitAndBeginFrame = + reinterpret_cast<void (*)()>(reinterpret_cast<void*>(GetProcAddress(pLfxModule, "winelfx_WaitAndBeginFrame"))); else { spdlog::info("Unable to load LatencyFleX library, LatencyFleX disabled."); diff --git a/NorthstarDLL/limits.cpp b/NorthstarDLL/limits.cpp index f1dc23bd..fd635136 100644 --- a/NorthstarDLL/limits.cpp +++ b/NorthstarDLL/limits.cpp @@ -3,7 +3,10 @@ #include "hoststate.h" #include "r2client.h" #include "r2engine.h" +#include "r2server.h" +#include "maxplayers.h" #include "tier0.h" +#include "vector.h" #include "serverauthentication.h" AUTOHOOK_INIT() @@ -12,12 +15,41 @@ ServerLimitsManager* g_pServerLimits; ConVar* Cvar_net_datablock_enabled; +// todo: make this work on higher timescales, also possibly disable when sv_cheats is set +void ServerLimitsManager::RunFrame(double flCurrentTime, float flFrameTime) +{ + if (Cvar_sv_antispeedhack_enable->GetBool()) + { + // for each player, set their usercmd processing budget for the frame to the last frametime for the server + for (int i = 0; i < R2::GetMaxPlayers(); i++) + { + R2::CBaseClient* player = &R2::g_pClientArray[i]; + + if (m_PlayerLimitData.find(player) != m_PlayerLimitData.end()) + { + PlayerLimitData* pLimitData = &g_pServerLimits->m_PlayerLimitData[player]; + if (pLimitData->flFrameUserCmdBudget < 0.016666667 * Cvar_sv_antispeedhack_maxtickbudget->GetFloat()) + pLimitData->flFrameUserCmdBudget += + fmax(flFrameTime, 0.016666667) * g_pServerLimits->Cvar_sv_antispeedhack_budgetincreasemultiplier->GetFloat(); + } + } + } +} + void ServerLimitsManager::AddPlayer(R2::CBaseClient* player) { PlayerLimitData limitData; + limitData.flFrameUserCmdBudget = 0.016666667 * Cvar_sv_antispeedhack_maxtickbudget->GetFloat(); + m_PlayerLimitData.insert(std::make_pair(player, limitData)); } +void ServerLimitsManager::RemovePlayer(R2::CBaseClient* player) +{ + if (m_PlayerLimitData.find(player) != m_PlayerLimitData.end()) + m_PlayerLimitData.erase(player); +} + bool ServerLimitsManager::CheckStringCommandLimits(R2::CBaseClient* player) { if (CVar_sv_quota_stringcmdspersecond->GetInt() != -1) @@ -31,8 +63,7 @@ bool ServerLimitsManager::CheckStringCommandLimits(R2::CBaseClient* player) } m_PlayerLimitData[player].numClientCommandsInQuota++; - if (m_PlayerLimitData[player].numClientCommandsInQuota > - CVar_sv_quota_stringcmdspersecond->GetInt()) + if (m_PlayerLimitData[player].numClientCommandsInQuota > CVar_sv_quota_stringcmdspersecond->GetInt()) { // too many stringcmds, dc player return false; @@ -57,8 +88,10 @@ bool ServerLimitsManager::CheckChatLimits(R2::CBaseClient* player) return true; } +// clang-format off AUTOHOOK(CNetChan__ProcessMessages, engine.dll + 0x2140A0, char, __fastcall, (void* self, void* buf)) +// clang-format on { enum eNetChanLimitMode { @@ -87,8 +120,7 @@ char, __fastcall, (void* self, void* buf)) g_pServerLimits->m_PlayerLimitData[sender].lastNetChanProcessingLimitStart = startTime; g_pServerLimits->m_PlayerLimitData[sender].netChanProcessingLimitTime = 0.0; } - g_pServerLimits->m_PlayerLimitData[sender].netChanProcessingLimitTime += - (Tier0::Plat_FloatTime() * 1000) - (startTime * 1000); + g_pServerLimits->m_PlayerLimitData[sender].netChanProcessingLimitTime += (Tier0::Plat_FloatTime() * 1000) - (startTime * 1000); if (g_pServerLimits->m_PlayerLimitData[sender].netChanProcessingLimitTime >= g_pServerLimits->Cvar_net_chan_limit_msec_per_sec->GetInt()) @@ -100,8 +132,7 @@ char, __fastcall, (void* self, void* buf)) g_pServerLimits->Cvar_net_chan_limit_msec_per_sec->GetInt()); // never kick local player - if (g_pServerLimits->Cvar_net_chan_limit_mode->GetInt() != NETCHANLIMIT_WARN && - strcmp(R2::g_pLocalPlayerUserID, sender->m_UID)) + if (g_pServerLimits->Cvar_net_chan_limit_mode->GetInt() != NETCHANLIMIT_WARN && strcmp(R2::g_pLocalPlayerUserID, sender->m_UID)) { R2::CBaseClient__Disconnect(sender, 1, "Exceeded net channel processing limit"); return false; @@ -112,8 +143,10 @@ char, __fastcall, (void* self, void* buf)) return ret; } +// clang-format off AUTOHOOK(ProcessConnectionlessPacket, engine.dll + 0x117800, bool, , (void* a1, R2::netpacket_t* packet)) +// clang-format on { if (packet->adr.type == R2::NA_IP && (!(packet->data[4] == 'N' && Cvar_net_datablock_enabled->GetBool()) || !Cvar_net_datablock_enabled->GetBool())) @@ -162,9 +195,71 @@ bool, , (void* a1, R2::netpacket_t* packet)) return ProcessConnectionlessPacket(a1, packet); } +// this is weird and i'm not sure if it's correct, so not using for now +/*AUTOHOOK(CBasePlayer__PhysicsSimulate, server.dll + 0x5A6E50, bool, __fastcall, (void* self, int a2, char a3)) +{ + spdlog::info("CBasePlayer::PhysicsSimulate"); + return CBasePlayer__PhysicsSimulate(self, a2, a3); +}*/ + +struct alignas(4) SV_CUserCmd +{ + DWORD command_number; + DWORD tick_count; + float command_time; + Vector3 worldViewAngles; + BYTE gap18[4]; + Vector3 localViewAngles; + Vector3 attackangles; + Vector3 move; + DWORD buttons; + BYTE impulse; + short weaponselect; + DWORD meleetarget; + BYTE gap4C[24]; + char headoffset; + BYTE gap65[11]; + Vector3 cameraPos; + Vector3 cameraAngles; + BYTE gap88[4]; + int tickSomething; + DWORD dword90; + DWORD predictedServerEventAck; + DWORD dword98; + float frameTime; +}; + +// clang-format off +AUTOHOOK(CPlayerMove__RunCommand, server.dll + 0x5B8100, +void, __fastcall, (void* self, R2::CBasePlayer* player, SV_CUserCmd* pUserCmd, uint64_t a4)) +// clang-format on +{ + if (g_pServerLimits->Cvar_sv_antispeedhack_enable->GetBool()) + { + R2::CBaseClient* pClient = &R2::g_pClientArray[player->m_nPlayerIndex - 1]; + + if (g_pServerLimits->m_PlayerLimitData.find(pClient) != g_pServerLimits->m_PlayerLimitData.end()) + { + PlayerLimitData* pLimitData = &g_pServerLimits->m_PlayerLimitData[pClient]; + + pLimitData->flFrameUserCmdBudget = fmax(0.0, pLimitData->flFrameUserCmdBudget - pUserCmd->frameTime); + + if (pLimitData->flFrameUserCmdBudget <= 0.0) + { + spdlog::warn("player {} went over usercmd budget ({})", pClient->m_Name, pLimitData->flFrameUserCmdBudget); + return; + } + // else + // spdlog::info("{}: {}", pClient->m_Name, pLimitData->flFrameUserCmdBudget); + } + } + + CPlayerMove__RunCommand(self, player, pUserCmd, a4); +} + ON_DLL_LOAD_RELIESON("engine.dll", ServerLimits, ConVar, (CModule module)) { - AUTOHOOK_DISPATCH() + AUTOHOOK_DISPATCH_MODULE(engine.dll) g_pServerLimits = new ServerLimitsManager; @@ -182,6 +277,23 @@ ON_DLL_LOAD_RELIESON("engine.dll", ServerLimits, ConVar, (CModule module)) "Netchannel processing is limited to so many milliseconds, abort connection if exceeding budget"); g_pServerLimits->Cvar_sv_querylimit_per_sec = new ConVar("sv_querylimit_per_sec", "15", FCVAR_GAMEDLL, ""); g_pServerLimits->Cvar_sv_max_chat_messages_per_sec = new ConVar("sv_max_chat_messages_per_sec", "5", FCVAR_GAMEDLL, ""); + g_pServerLimits->Cvar_sv_antispeedhack_enable = + new ConVar("sv_antispeedhack_enable", "0", FCVAR_NONE, "whether to enable antispeedhack protections"); + g_pServerLimits->Cvar_sv_antispeedhack_maxtickbudget = new ConVar( + "sv_antispeedhack_maxtickbudget", + "64", + FCVAR_GAMEDLL, + "Maximum number of client-issued usercmd ticks that can be replayed in packet loss conditions, 0 to allow no restrictions"); + g_pServerLimits->Cvar_sv_antispeedhack_budgetincreasemultiplier = new ConVar( + "sv_antispeedhack_budgetincreasemultiplier", + "1.2", + FCVAR_GAMEDLL, + "Increase usercmd processing budget by tickinterval * value per tick"); Cvar_net_datablock_enabled = R2::g_pCVar->FindVar("net_datablock_enabled"); } + +ON_DLL_LOAD("server.dll", ServerLimitsServer, (CModule module)) +{ + AUTOHOOK_DISPATCH_MODULE(server.dll) +} diff --git a/NorthstarDLL/limits.h b/NorthstarDLL/limits.h index 943e07b6..068f91c9 100644 --- a/NorthstarDLL/limits.h +++ b/NorthstarDLL/limits.h @@ -13,6 +13,8 @@ struct PlayerLimitData double lastSayTextLimitStart = -1.0; int sayTextLimitCount = 0; + + float flFrameUserCmdBudget = 0.0; }; struct UnconnectedPlayerLimitData @@ -31,12 +33,17 @@ class ServerLimitsManager ConVar* Cvar_net_chan_limit_msec_per_sec; ConVar* Cvar_sv_querylimit_per_sec; ConVar* Cvar_sv_max_chat_messages_per_sec; + ConVar* Cvar_sv_antispeedhack_enable; + ConVar* Cvar_sv_antispeedhack_maxtickbudget; + ConVar* Cvar_sv_antispeedhack_budgetincreasemultiplier; std::unordered_map<R2::CBaseClient*, PlayerLimitData> m_PlayerLimitData; std::vector<UnconnectedPlayerLimitData> m_UnconnectedPlayerLimitData; public: + void RunFrame(double flCurrentTime, float flFrameTime); void AddPlayer(R2::CBaseClient* player); + void RemovePlayer(R2::CBaseClient* player); bool CheckStringCommandLimits(R2::CBaseClient* player); bool CheckChatLimits(R2::CBaseClient* player); }; diff --git a/NorthstarDLL/localchatwriter.cpp b/NorthstarDLL/localchatwriter.cpp index 2c661feb..efa7eeee 100644 --- a/NorthstarDLL/localchatwriter.cpp +++ b/NorthstarDLL/localchatwriter.cpp @@ -218,8 +218,7 @@ class AnsiEscapeParser unsigned char blue = code % 6; unsigned char green = ((code - blue) / 6) % 6; unsigned char red = (code - blue - (green * 6)) / 36; - m_writer->InsertColorChange( - Color {(unsigned char)(red * 51), (unsigned char)(green * 51), (unsigned char)(blue * 51), 255}); + m_writer->InsertColorChange(Color {(unsigned char)(red * 51), (unsigned char)(green * 51), (unsigned char)(blue * 51), 255}); } else if (val < UCHAR_MAX) { diff --git a/NorthstarDLL/logging.cpp b/NorthstarDLL/logging.cpp index 5bd5ae40..7c6d50a6 100644 --- a/NorthstarDLL/logging.cpp +++ b/NorthstarDLL/logging.cpp @@ -31,11 +31,12 @@ const std::unordered_map<SpewType_t, const char*> PrintSpewTypes = { {SpewType_t::SPEW_WARNING, "SPEW_WARNING"}, {SpewType_t::SPEW_ASSERT, "SPEW_ASSERT"}, {SpewType_t::SPEW_ERROR, "SPEW_ERROR"}, - {SpewType_t::SPEW_LOG, "SPEW_LOG"} -}; + {SpewType_t::SPEW_LOG, "SPEW_LOG"}}; +// clang-format off AUTOHOOK(EngineSpewFunc, engine.dll + 0x11CA80, -void,, (void* pEngineServer, SpewType_t type, const char* format, va_list args)) +void, __fastcall, (void* pEngineServer, SpewType_t type, const char* format, va_list args)) +// clang-format on { if (!Cvar_spewlog_enable->GetBool()) return; @@ -109,8 +110,10 @@ void,, (void* pEngineServer, SpewType_t type, const char* format, va_list args)) } // used for printing the output of status +// clang-format off AUTOHOOK(Status_ConMsg, engine.dll + 0x15ABD0, void,, (const char* text, ...)) +// clang-format on { char formatted[2048]; va_list list; @@ -126,8 +129,10 @@ void,, (const char* text, ...)) spdlog::info(formatted); } +// clang-format off AUTOHOOK(CClientState_ProcessPrint, engine.dll + 0x1A1530, bool,, (void* thisptr, uintptr_t msg)) +// clang-format on { char* text = *(char**)(msg + 0x20); @@ -163,8 +168,10 @@ enum class TextMsgPrintType_t HUD_PRINTCENTER }; +// clang-format off AUTOHOOK(TextMsg, client.dll + 0x198710, void,, (BFRead* msg)) +// clang-format on { TextMsgPrintType_t msg_dest = (TextMsgPrintType_t)msg->ReadByte(); @@ -194,8 +201,10 @@ void,, (BFRead* msg)) } } +// clang-format off AUTOHOOK(ConCommand_echo, engine.dll + 0x123680, void,, (const CCommand& arg)) +// clang-format on { if (arg.ArgC() >= 2) spdlog::info("[echo] {}", arg.ArgS()); @@ -231,7 +240,7 @@ void InitialiseLogging() // work regardless of these two lines // freopen("CONOUT$", "w", stdout); // freopen("CONOUT$", "w", stderr); - spdlog::default_logger()->set_pattern("[%H:%M:%S] [%^%l%$] %v"); + spdlog::default_logger()->set_pattern("[%H:%M:%S] [%l] %v"); } ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", EngineSpewFuncHooks, ConVar, (CModule module)) diff --git a/NorthstarDLL/masterserver.cpp b/NorthstarDLL/masterserver.cpp index a1fb839a..b8e00bdc 100644 --- a/NorthstarDLL/masterserver.cpp +++ b/NorthstarDLL/masterserver.cpp @@ -129,7 +129,8 @@ void MasterServerManager::AuthenticateOriginWithMasterServer(const char* uid, co { strncpy_s( m_sOwnClientAuthToken, - sizeof(m_sOwnClientAuthToken), originAuthInfo["token"].GetString(), + sizeof(m_sOwnClientAuthToken), + originAuthInfo["token"].GetString(), sizeof(m_sOwnClientAuthToken) - 1); spdlog::info("Northstar origin authentication completed successfully!"); } @@ -531,7 +532,8 @@ void MasterServerManager::AuthenticateWithOwnServer(const char* uid, const char* std::lock_guard<std::mutex> guard(g_pServerAuthentication->m_AuthDataMutex); g_pServerAuthentication->m_RemoteAuthenticationData.clear(); - g_pServerAuthentication->m_RemoteAuthenticationData.insert(std::make_pair(authInfoJson["authToken"].GetString(), newAuthData)); + g_pServerAuthentication->m_RemoteAuthenticationData.insert( + std::make_pair(authInfoJson["authToken"].GetString(), newAuthData)); m_bSuccessfullyAuthenticatedWithGameServer = true; } @@ -752,159 +754,168 @@ class MasterServerPresenceReporter : public ServerPresenceReporter { const int MAX_REGISTRATION_ATTEMPTS = 5; - double m_bShouldTryRegisterServer; + bool m_bShouldTryRegisterServer; + bool m_bHasAddServerRequest; int m_nNumRegistrationAttempts; void CreatePresence(const ServerPresence* pServerPresence) override { m_bShouldTryRegisterServer = true; + m_bHasAddServerRequest = false; m_nNumRegistrationAttempts = 0; } void ReportPresence(const ServerPresence* pServerPresence) override { // make a copy of presence for multithreading purposes - ServerPresence threadedPresence(pServerPresence); - if (!*g_pMasterServerManager->m_sOwnServerId || m_bShouldTryRegisterServer) + if (!*g_pMasterServerManager->m_sOwnServerId) { - // add server - std::thread addServerThread( - [this, threadedPresence] - { - g_pMasterServerManager->m_sOwnServerId[0] = 0; - g_pMasterServerManager->m_sOwnServerAuthToken[0] = 0; + if (m_bShouldTryRegisterServer && !m_bHasAddServerRequest) + { + // add server + std::thread addServerThread( + [this, threadedPresence] + { + g_pMasterServerManager->m_sOwnServerId[0] = 0; + g_pMasterServerManager->m_sOwnServerAuthToken[0] = 0; - CURL* curl = curl_easy_init(); - SetCommonHttpClientOptions(curl); + CURL* curl = curl_easy_init(); + SetCommonHttpClientOptions(curl); - std::string readBuffer; - curl_easy_setopt(curl, CURLOPT_POST, 1L); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); + std::string readBuffer; + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - curl_mime* mime = curl_mime_init(curl); - curl_mimepart* part = curl_mime_addpart(mime); + curl_mime* mime = curl_mime_init(curl); + curl_mimepart* part = curl_mime_addpart(mime); - curl_mime_data( - part, g_pMasterServerManager->m_sOwnModInfoJson.c_str(), g_pMasterServerManager->m_sOwnModInfoJson.size()); - curl_mime_name(part, "modinfo"); - curl_mime_filename(part, "modinfo.json"); - curl_mime_type(part, "application/json"); + curl_mime_data( + part, g_pMasterServerManager->m_sOwnModInfoJson.c_str(), g_pMasterServerManager->m_sOwnModInfoJson.size()); + curl_mime_name(part, "modinfo"); + curl_mime_filename(part, "modinfo.json"); + curl_mime_type(part, "application/json"); - curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); + curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); - // format every paramter because computers hate me - { - char* nameEscaped = curl_easy_escape(curl, threadedPresence.m_sServerName.c_str(), NULL); - char* descEscaped = curl_easy_escape(curl, threadedPresence.m_sServerDesc.c_str(), NULL); - char* mapEscaped = curl_easy_escape(curl, threadedPresence.m_MapName, NULL); - char* playlistEscaped = curl_easy_escape(curl, threadedPresence.m_PlaylistName, NULL); - char* passwordEscaped = curl_easy_escape(curl, threadedPresence.m_Password, NULL); + // format every paramter because computers hate me + { + char* nameEscaped = curl_easy_escape(curl, threadedPresence.m_sServerName.c_str(), NULL); + char* descEscaped = curl_easy_escape(curl, threadedPresence.m_sServerDesc.c_str(), NULL); + char* mapEscaped = curl_easy_escape(curl, threadedPresence.m_MapName, NULL); + char* playlistEscaped = curl_easy_escape(curl, threadedPresence.m_PlaylistName, NULL); + char* passwordEscaped = curl_easy_escape(curl, threadedPresence.m_Password, NULL); + + curl_easy_setopt( + curl, + CURLOPT_URL, + fmt::format( + "{}/server/" + "add_server?port={}&authPort={}&name={}&description={}&map={}&playlist={}&maxPlayers={}&password={}", + Cvar_ns_masterserver_hostname->GetString(), + threadedPresence.m_iPort, + threadedPresence.m_iAuthPort, + nameEscaped, + descEscaped, + mapEscaped, + playlistEscaped, + threadedPresence.m_iMaxPlayers, + passwordEscaped) + .c_str()); + + curl_free(nameEscaped); + curl_free(descEscaped); + curl_free(mapEscaped); + curl_free(playlistEscaped); + curl_free(passwordEscaped); + } - curl_easy_setopt( - curl, - CURLOPT_URL, - fmt::format( - "{}/server/" - "add_server?port={}&authPort={}&name={}&description={}&map={}&playlist={}&maxPlayers={}&password={}", - Cvar_ns_masterserver_hostname->GetString(), - threadedPresence.m_iPort, - threadedPresence.m_iAuthPort, - nameEscaped, - descEscaped, - mapEscaped, - playlistEscaped, - threadedPresence.m_iMaxPlayers, - passwordEscaped) - .c_str()); + CURLcode result = curl_easy_perform(curl); - curl_free(nameEscaped); - curl_free(descEscaped); - curl_free(mapEscaped); - curl_free(playlistEscaped); - curl_free(passwordEscaped); - } + if (result == CURLcode::CURLE_OK) + { + g_pMasterServerManager->m_bSuccessfullyConnected = true; - CURLcode result = curl_easy_perform(curl); + rapidjson_document serverAddedJson; + serverAddedJson.Parse(readBuffer.c_str()); - if (result == CURLcode::CURLE_OK) - { - g_pMasterServerManager->m_bSuccessfullyConnected = true; + if (serverAddedJson.HasParseError()) + { + spdlog::error( + "Failed reading masterserver authentication response: encountered parse error \"{}\"", + rapidjson::GetParseError_En(serverAddedJson.GetParseError())); + goto REQUEST_END_CLEANUP; + } - rapidjson_document serverAddedJson; - serverAddedJson.Parse(readBuffer.c_str()); + if (!serverAddedJson.IsObject()) + { + spdlog::error("Failed reading masterserver authentication response: root object is not an object"); + goto REQUEST_END_CLEANUP; + } - if (serverAddedJson.HasParseError()) - { - spdlog::error( - "Failed reading masterserver authentication response: encountered parse error \"{}\"", - rapidjson::GetParseError_En(serverAddedJson.GetParseError())); - goto REQUEST_END_CLEANUP; - } + if (serverAddedJson.HasMember("error")) + { + spdlog::error("Failed reading masterserver response: got fastify error response"); + spdlog::error(readBuffer); - if (!serverAddedJson.IsObject()) - { - spdlog::error("Failed reading masterserver authentication response: root object is not an object"); - goto REQUEST_END_CLEANUP; - } + if (serverAddedJson["error"].HasMember("enum") && + !strcmp(serverAddedJson["error"]["enum"].GetString(), "DUPLICATE_SERVER")) + { + if (++m_nNumRegistrationAttempts == MAX_REGISTRATION_ATTEMPTS) + m_bShouldTryRegisterServer = false; - if (serverAddedJson.HasMember("error")) - { - spdlog::error("Failed reading masterserver response: got fastify error response"); - spdlog::error(readBuffer); + goto REQUEST_END_CLEANUP_RETRY; + } + + goto REQUEST_END_CLEANUP; + } - if (serverAddedJson["error"].HasMember("enum") && !strcmp(serverAddedJson["error"]["enum"].GetString(), "DUPLICATE_SERVER")) + if (!serverAddedJson["success"].IsTrue()) { - if (++m_nNumRegistrationAttempts == MAX_REGISTRATION_ATTEMPTS) - m_bShouldTryRegisterServer = false; + spdlog::error("Adding server to masterserver failed: \"success\" is not true"); + goto REQUEST_END_CLEANUP; + } - goto REQUEST_END_CLEANUP_RETRY; + if (!serverAddedJson.HasMember("id") || !serverAddedJson["id"].IsString() || + !serverAddedJson.HasMember("serverAuthToken") || !serverAddedJson["serverAuthToken"].IsString()) + { + spdlog::error("Failed reading masterserver response: malformed json object"); + goto REQUEST_END_CLEANUP; } - goto REQUEST_END_CLEANUP; + strncpy_s( + g_pMasterServerManager->m_sOwnServerId, + sizeof(g_pMasterServerManager->m_sOwnServerId), + serverAddedJson["id"].GetString(), + sizeof(g_pMasterServerManager->m_sOwnServerId) - 1); + + strncpy_s( + g_pMasterServerManager->m_sOwnServerAuthToken, + sizeof(g_pMasterServerManager->m_sOwnServerAuthToken), + serverAddedJson["serverAuthToken"].GetString(), + sizeof(g_pMasterServerManager->m_sOwnServerAuthToken) - 1); } - - if (!serverAddedJson["success"].IsTrue()) + else { - spdlog::error("Adding server to masterserver failed: \"success\" is not true"); - goto REQUEST_END_CLEANUP; + spdlog::error("Failed adding self to server list: error {}", curl_easy_strerror(result)); + g_pMasterServerManager->m_bSuccessfullyConnected = false; } - if (!serverAddedJson.HasMember("id") || !serverAddedJson["id"].IsString() || - !serverAddedJson.HasMember("serverAuthToken") || !serverAddedJson["serverAuthToken"].IsString()) - { - spdlog::error("Failed reading masterserver response: malformed json object"); - goto REQUEST_END_CLEANUP; - } + REQUEST_END_CLEANUP: + m_bShouldTryRegisterServer = false; - strncpy_s( - g_pMasterServerManager->m_sOwnServerId, - sizeof(g_pMasterServerManager->m_sOwnServerId), - serverAddedJson["id"].GetString(), - sizeof(g_pMasterServerManager->m_sOwnServerId) - 1); - - strncpy_s( - g_pMasterServerManager->m_sOwnServerAuthToken, - sizeof(g_pMasterServerManager->m_sOwnServerAuthToken), - serverAddedJson["serverAuthToken"].GetString(), - sizeof(g_pMasterServerManager->m_sOwnServerAuthToken) - 1); - } - else - { - spdlog::error("Failed adding self to server list: error {}", curl_easy_strerror(result)); - g_pMasterServerManager->m_bSuccessfullyConnected = false; - } + REQUEST_END_CLEANUP_RETRY: + m_bHasAddServerRequest = false; - REQUEST_END_CLEANUP: - m_bShouldTryRegisterServer = false; + curl_easy_cleanup(curl); + curl_mime_free(mime); + }); - REQUEST_END_CLEANUP_RETRY: - curl_easy_cleanup(curl); - curl_mime_free(mime); - }); - addServerThread.detach(); + m_bHasAddServerRequest = true; + addServerThread.detach(); + } } else { diff --git a/NorthstarDLL/maxplayers.cpp b/NorthstarDLL/maxplayers.cpp index bc7fce32..ece8d14b 100644 --- a/NorthstarDLL/maxplayers.cpp +++ b/NorthstarDLL/maxplayers.cpp @@ -70,8 +70,10 @@ template <class T> void ChangeOffset(MemoryAddress addr, unsigned int offset) addr.Patch((BYTE*)&offset, sizeof(T)); } +// clang-format off AUTOHOOK(StringTables_CreateStringTable, engine.dll + 0x22E220, void*,, (void* thisptr, const char* name, int maxentries, int userdatafixedsize, int userdatanetworkbits, int flags)) +// clang-format on { // Change the amount of entries to account for a bigger player amount if (!strcmp(name, "userinfo")) @@ -135,8 +137,10 @@ HMODULE serverBase = 0; auto RandomIntZeroMax = (__int64(__fastcall*)())0; // lazy rebuild +// clang-format off AUTOHOOK(RunUserCmds, server.dll + 0x483D10, void,, (bool a1, float a2)) +// clang-format on { unsigned char v3; // bl int v5; // er14 @@ -277,8 +281,10 @@ void,, (bool a1, float a2)) } } +// clang-format off AUTOHOOK(SendPropArray2, server.dll + 0x12B130, __int64, __fastcall, (__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn, unsigned char unk1)) +// clang-format on { // Change the amount of elements to account for a bigger player amount if (!strcmp(name, "\"player_array\"")) @@ -446,8 +452,10 @@ ON_DLL_LOAD("server.dll", MaxPlayersOverride_Server, (CModule module)) DT_Team_Construct(); } +// clang-format off AUTOHOOK(RecvPropArray2, client.dll + 0x1CEDA0, __int64, __fastcall, (__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn)) +// clang-format on { // Change the amount of elements to account for a bigger player amount if (!strcmp(name, "\"player_array\"")) diff --git a/NorthstarDLL/memory.cpp b/NorthstarDLL/memory.cpp index 8b7694bd..2e994fb2 100644 --- a/NorthstarDLL/memory.cpp +++ b/NorthstarDLL/memory.cpp @@ -279,7 +279,7 @@ MemoryAddress CModule::FindPattern(const uint8_t* pPattern, const char* pMask) } } - CONTINUE:; + CONTINUE:; } return MemoryAddress(); diff --git a/NorthstarDLL/modlocalisation.cpp b/NorthstarDLL/modlocalisation.cpp index 14379bb3..b12f0a40 100644 --- a/NorthstarDLL/modlocalisation.cpp +++ b/NorthstarDLL/modlocalisation.cpp @@ -3,8 +3,10 @@ AUTOHOOK_INIT() +// clang-format off AUTOHOOK(AddLocalisationFile, localize.dll + 0x6D80, -bool,, (void* pVguiLocalize, const char* path, const char* pathId, char unknown)) +bool, __fastcall, (void* pVguiLocalize, const char* path, const char* pathId, char unknown)) +// clang-format on { static bool bLoadModLocalisationFiles = true; bool ret = AddLocalisationFile(pVguiLocalize, path, pathId, unknown); diff --git a/NorthstarDLL/modmanager.cpp b/NorthstarDLL/modmanager.cpp index c9dfcdbb..05060902 100644 --- a/NorthstarDLL/modmanager.cpp +++ b/NorthstarDLL/modmanager.cpp @@ -401,13 +401,12 @@ void ModManager::LoadMods() std::string formattedPath = file.path().filename().string(); // this really fucking sucks but it'll work - std::string vpkName = - (file.path().parent_path() / formattedPath.substr(strlen("english"), formattedPath.find(".bsp") - 3)).string(); + std::string vpkName = formattedPath.substr(strlen("english"), formattedPath.find(".bsp") - 3); ModVPKEntry& modVpk = mod.Vpks.emplace_back(); modVpk.m_bAutoLoad = !bUseVPKJson || (dVpkJson.HasMember("Preload") && dVpkJson["Preload"].IsObject() && dVpkJson["Preload"].HasMember(vpkName) && dVpkJson["Preload"][vpkName].IsTrue()); - modVpk.m_sVpkPath = vpkName; + modVpk.m_sVpkPath = (file.path().parent_path() / vpkName).string(); if (m_bHasLoadedMods && modVpk.m_bAutoLoad) (*R2::g_pFilesystem)->m_vtable->MountVPK(*R2::g_pFilesystem, vpkName.c_str()); @@ -484,7 +483,8 @@ void ModManager::LoadMods() { if (fs::is_regular_file(file)) { - std::string kvStr = g_pModManager->NormaliseModFilePath(file.path().lexically_relative(mod.m_ModDirectory / "keyvalues")); + std::string kvStr = + g_pModManager->NormaliseModFilePath(file.path().lexically_relative(mod.m_ModDirectory / "keyvalues")); mod.KeyValues.emplace(STR_HASH(kvStr), kvStr); } } diff --git a/NorthstarDLL/playlist.cpp b/NorthstarDLL/playlist.cpp index 7cf9e41e..4f34dbb1 100644 --- a/NorthstarDLL/playlist.cpp +++ b/NorthstarDLL/playlist.cpp @@ -19,18 +19,23 @@ namespace R2 ConVar* Cvar_ns_use_clc_SetPlaylistVarOverride; +// clang-format off AUTOHOOK(clc_SetPlaylistVarOverride__Process, engine.dll + 0x222180, -char,, (void* a1, void* a2)) +char, __fastcall, (void* a1, void* a2)) +// clang-format on { // the private_match playlist on mp_lobby is the only situation where there should be any legitimate sending of this netmessage - if (!Cvar_ns_use_clc_SetPlaylistVarOverride->GetBool() || strcmp(R2::GetCurrentPlaylistName(), "private_match") || strcmp(R2::g_pHostState->m_levelName, "mp_lobby")) + if (!Cvar_ns_use_clc_SetPlaylistVarOverride->GetBool() || strcmp(R2::GetCurrentPlaylistName(), "private_match") || + strcmp(R2::g_pHostState->m_levelName, "mp_lobby")) return 1; return clc_SetPlaylistVarOverride__Process(a1, a2); } +// clang-format off AUTOHOOK(SetCurrentPlaylist, engine.dll + 0x18EB20, bool, __fastcall, (const char* pPlaylistName)) +// clang-format on { bool bSuccess = SetCurrentPlaylist(pPlaylistName); @@ -43,8 +48,10 @@ bool, __fastcall, (const char* pPlaylistName)) return bSuccess; } +// clang-format off AUTOHOOK(SetPlaylistVarOverride, engine.dll + 0x18ED00, -void,, (const char* pVarName, const char* pValue)) +void, __fastcall, (const char* pVarName, const char* pValue)) +// clang-format on { if (strlen(pValue) >= 64) return; @@ -52,8 +59,10 @@ void,, (const char* pVarName, const char* pValue)) SetPlaylistVarOverride(pVarName, pValue); } +// clang-format off AUTOHOOK(GetCurrentPlaylistVar, engine.dll + 0x18C680, -const char*,, (const char* pVarName, bool bUseOverrides)) +const char*, __fastcall, (const char* pVarName, bool bUseOverrides)) +// clang-format on { if (!bUseOverrides && !strcmp(pVarName, "max_players")) bUseOverrides = true; @@ -61,8 +70,10 @@ const char*,, (const char* pVarName, bool bUseOverrides)) return GetCurrentPlaylistVar(pVarName, bUseOverrides); } +// clang-format off AUTOHOOK(GetCurrentGamemodeMaxPlayers, engine.dll + 0x18C430, -int,, ()) +int, __fastcall, ()) +// clang-format on { const char* pMaxPlayers = R2::GetCurrentPlaylistVar("max_players", 0); if (!pMaxPlayers) diff --git a/NorthstarDLL/printmaps.cpp b/NorthstarDLL/printmaps.cpp index 82ba8d5e..c378daad 100644 --- a/NorthstarDLL/printmaps.cpp +++ b/NorthstarDLL/printmaps.cpp @@ -19,10 +19,7 @@ enum class MapSource_t }; const std::unordered_map<MapSource_t, const char*> PrintMapSource = { - {MapSource_t::VPK, "VPK"}, - {MapSource_t::MOD, "MOD"}, - {MapSource_t::GAMEDIR, "R2"} -}; + {MapSource_t::VPK, "VPK"}, {MapSource_t::MOD, "MOD"}, {MapSource_t::GAMEDIR, "R2"}}; struct MapVPKInfo { @@ -110,8 +107,10 @@ void RefreshMapList() } } +// clang-format off AUTOHOOK(_Host_Map_f_CompletionFunc, engine.dll + 0x161AE0, int, __fastcall, (const char const* cmdname, const char const* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH])) +// clang-format on { // don't update our map list often from this func, only refresh every 10 seconds so we avoid constantly reading fs static double flLastAutocompleteRefresh = -999; diff --git a/NorthstarDLL/r2engine.cpp b/NorthstarDLL/r2engine.cpp index 4807a174..11233a2d 100644 --- a/NorthstarDLL/r2engine.cpp +++ b/NorthstarDLL/r2engine.cpp @@ -17,7 +17,8 @@ namespace R2 server_state_t* g_pServerState; - char* g_pModName = nullptr; // we cant set this up here atm since we dont have an offset to it in engine, instead we store it in IsRespawnMod + char* g_pModName = + nullptr; // we cant set this up here atm since we dont have an offset to it in engine, instead we store it in IsRespawnMod } // namespace R2 ON_DLL_LOAD("engine.dll", R2Engine, (CModule module)) @@ -26,7 +27,7 @@ ON_DLL_LOAD("engine.dll", R2Engine, (CModule module)) Cbuf_AddText = module.Offset(0x1203B0).As<Cbuf_AddTextType>(); Cbuf_Execute = module.Offset(0x1204B0).As<Cbuf_ExecuteType>(); - g_pEngine = module.Offset(0x7D70C8).Deref().As<CEngine*>(); // new + g_pEngine = module.Offset(0x7D70C8).Deref().As<CEngine*>(); CBaseClient__Disconnect = module.Offset(0x1012C0).As<void (*)(void*, uint32_t, const char*, ...)>(); g_pClientArray = module.Offset(0x12A53F90).As<CBaseClient*>(); diff --git a/NorthstarDLL/r2engine.h b/NorthstarDLL/r2engine.h index e5755c54..5566f339 100644 --- a/NorthstarDLL/r2engine.h +++ b/NorthstarDLL/r2engine.h @@ -102,7 +102,7 @@ namespace R2 extern void (*CBaseClient__Disconnect)(void* self, uint32_t unknownButAlways1, const char* reason, ...); - #pragma once +#pragma once typedef enum { NA_NULL = 0, @@ -110,7 +110,7 @@ namespace R2 NA_IP, } netadrtype_t; - #pragma pack(push, 1) +#pragma pack(push, 1) typedef struct netadr_s { netadrtype_t type; @@ -119,9 +119,9 @@ namespace R2 // 00 00 00 00 00 00 00 00 00 00 FF FF 7F 00 00 01 unsigned short port; } netadr_t; - #pragma pack(pop) +#pragma pack(pop) - #pragma pack(push, 1) +#pragma pack(push, 1) typedef struct netpacket_s { netadr_t adr; // sender address @@ -139,7 +139,7 @@ namespace R2 // bool stream; // was send as stream // struct netpacket_s* pNext; // for internal use, should be NULL in public } netpacket_t; - #pragma pack(pop) +#pragma pack(pop) const int PERSISTENCE_MAX_SIZE = 0xD000; @@ -153,7 +153,7 @@ namespace R2 READY_REMOTE }; - #pragma pack(push, 1) +#pragma pack(push, 1) struct CBaseClient // 0x2D728 bytes { char pad0[0x16]; @@ -181,7 +181,7 @@ namespace R2 char pad4[0x1E208]; }; - #pragma pack(pop) +#pragma pack(pop) extern CBaseClient* g_pClientArray; diff --git a/NorthstarDLL/r2server.h b/NorthstarDLL/r2server.h index fdfae156..58b39a05 100644 --- a/NorthstarDLL/r2server.h +++ b/NorthstarDLL/r2server.h @@ -7,6 +7,13 @@ namespace R2 class CBaseEntity; extern CBaseEntity* (*Server_GetEntityByIndex)(int index); - class CBasePlayer; +#pragma pack(push, 1) + struct CBasePlayer + { + char pad[88]; + int m_nPlayerIndex; + }; +#pragma pack(pop) + extern CBasePlayer*(__fastcall* UTIL_PlayerByIndex)(int playerIndex); } // namespace R2 diff --git a/NorthstarDLL/rpakfilesystem.cpp b/NorthstarDLL/rpakfilesystem.cpp index d5cff26c..b1363589 100644 --- a/NorthstarDLL/rpakfilesystem.cpp +++ b/NorthstarDLL/rpakfilesystem.cpp @@ -29,7 +29,9 @@ int PakLoadManager::LoadPakAsync(const char* pPath, const ePakLoadSource nLoadSo int nHandle = g_pakLoadApi->LoadPakAsync(pPath, *pUnknownPakLoadSingleton, 2, nullptr, nullptr); // set the load source of the pak we just loaded - GetPakInfo(nHandle)->m_nLoadSource = nLoadSource; + if (nHandle != -1) + GetPakInfo(nHandle)->m_nLoadSource = nLoadSource; + return nHandle; } @@ -173,7 +175,10 @@ void LoadCustomMapPaks(char** pakName, bool* bNeedToFreePakName) } } -HOOK(LoadPakAsyncHook, LoadPakAsync, int, , (char* pPath, void* unknownSingleton, int flags, void* pCallback0, void* pCallback1)) +// clang-format off +HOOK(LoadPakAsyncHook, LoadPakAsync, +int, __fastcall, (char* pPath, void* unknownSingleton, int flags, void* pCallback0, void* pCallback1)) +// clang-format on { HandlePakAliases(&pPath); @@ -187,7 +192,8 @@ HOOK(LoadPakAsyncHook, LoadPakAsync, int, , (char* pPath, void* unknownSingleton static bool bShouldLoadPaks = true; if (bShouldLoadPaks) { - // make a copy of the path for comparing to determine whether we should load this pak on dedi, before it could get overwritten by LoadCustomMapPaks + // make a copy of the path for comparing to determine whether we should load this pak on dedi, before it could get overwritten by + // LoadCustomMapPaks std::string originalPath(pPath); // disable preloading while we're doing this @@ -200,7 +206,8 @@ HOOK(LoadPakAsyncHook, LoadPakAsync, int, , (char* pPath, void* unknownSingleton // do this after custom paks load and in bShouldLoadPaks so we only ever call this on the root pakload call // todo: could probably add some way to flag custom paks to not be loaded on dedicated servers in rpak.json - if (IsDedicatedServer() && (Tier0::CommandLine()->CheckParm("-nopakdedi") || strncmp(&originalPath[0], "common", 6))) // dedicated only needs common and common_mp + if (IsDedicatedServer() && (Tier0::CommandLine()->CheckParm("-nopakdedi") || + strncmp(&originalPath[0], "common", 6))) // dedicated only needs common and common_mp { if (bNeedToFreePakName) delete[] pPath; @@ -223,8 +230,10 @@ HOOK(LoadPakAsyncHook, LoadPakAsync, int, , (char* pPath, void* unknownSingleton return iPakHandle; } +// clang-format off HOOK(UnloadPakHook, UnloadPak, -void*,, (int nPakHandle, void* pCallback)) +void*, __fastcall, (int nPakHandle, void* pCallback)) +// clang-format on { // stop tracking the pak g_pPakLoadManager->RemoveLoadedPak(nPakHandle); @@ -242,8 +251,11 @@ void*,, (int nPakHandle, void* pCallback)) } // we hook this exclusively for resolving stbsp paths, but seemingly it's also used for other stuff like vpk, rpak, mprj and starpak loads +// tbh this actually might be for memory mapped files or something, would make sense i think +// clang-format off HOOK(ReadFileAsyncHook, ReadFileAsync, -void*, , (const char* pPath, void* pCallback)) +void*, __fastcall, (const char* pPath, void* pCallback)) +// clang-format on { fs::path path(pPath); char* allocatedNewPath = nullptr; diff --git a/NorthstarDLL/runframe.cpp b/NorthstarDLL/runframe.cpp index 0698e430..eb401f51 100644 --- a/NorthstarDLL/runframe.cpp +++ b/NorthstarDLL/runframe.cpp @@ -6,8 +6,10 @@ AUTOHOOK_INIT() +// clang-format off AUTOHOOK(CEngine__Frame, engine.dll + 0x1C8650, void, __fastcall, (R2::CEngine* self)) +// clang-format on { CEngine__Frame(self); } diff --git a/NorthstarDLL/scriptbrowserhooks.cpp b/NorthstarDLL/scriptbrowserhooks.cpp index 7e0144b7..df4014de 100644 --- a/NorthstarDLL/scriptbrowserhooks.cpp +++ b/NorthstarDLL/scriptbrowserhooks.cpp @@ -4,11 +4,13 @@ AUTOHOOK_INIT() bool* bIsOriginOverlayEnabled; +// clang-format off AUTOHOOK(OpenExternalWebBrowser, engine.dll + 0x184E40, -void,, (char* pUrl, char flags)) +void, __fastcall, (char* pUrl, char flags)) +// clang-format on { bool bIsOriginOverlayEnabledOriginal = *bIsOriginOverlayEnabled; - if (flags & 2 && !strncmp(pUrl, "http", 4)) // custom force external browser flag + if (flags & 2 && !strncmp(pUrl, "http", 4)) // custom force external browser flag *bIsOriginOverlayEnabled = false; // if this bool is false, game will use an external browser rather than the origin overlay one OpenExternalWebBrowser(pUrl, flags); diff --git a/NorthstarDLL/scriptdatatables.cpp b/NorthstarDLL/scriptdatatables.cpp index 2861b964..fc2be943 100644 --- a/NorthstarDLL/scriptdatatables.cpp +++ b/NorthstarDLL/scriptdatatables.cpp @@ -19,7 +19,7 @@ const uint64_t USERDATA_TYPE_DATATABLE_CUSTOM = 0xFFFCFFFC12345678; enum class DatatableType : int { BOOL = 0, - INT, + INT, FLOAT, VECTOR, STRING, @@ -123,7 +123,7 @@ template <ScriptContext context> SQRESULT SQ_GetDatatable(HSquirrelVM* sqvm) return SQRESULT_NOTNULL; } - + // check files on disk // we don't use .rpak as the extension for on-disk datatables, so we need to replace .rpak with .csv in the filename we're reading fs::path diskAssetPath("scripts"); @@ -154,9 +154,9 @@ template <ScriptContext context> SQRESULT SQ_GetDatatable(HSquirrelVM* sqvm) memcpy(csv.m_pDataBuf, &sTableCSV[0], csv.m_nDataBufSize); // parse the csv - // csvs are essentially comma and newline-deliniated sets of strings for parsing, only thing we need to worry about is quoted entries - // when we parse an element of the csv, rather than allocating an entry for it, we just convert that element to a null-terminated string - // i.e., store the ptr to the first char of it, then make the comma that delinates it a nullchar + // csvs are essentially comma and newline-deliniated sets of strings for parsing, only thing we need to worry about is quoted + // entries when we parse an element of the csv, rather than allocating an entry for it, we just convert that element to a + // null-terminated string i.e., store the ptr to the first char of it, then make the comma that delinates it a nullchar bool bHasColumns = false; bool bInQuotes = false; @@ -172,7 +172,7 @@ template <ScriptContext context> SQRESULT SQ_GetDatatable(HSquirrelVM* sqvm) if (!pElemEnd) pElemEnd = csv.m_pDataBuf + i; - continue; // next iteration can handle the \n + continue; // next iteration can handle the \n } // newline, end of a row @@ -184,7 +184,7 @@ template <ScriptContext context> SQRESULT SQ_GetDatatable(HSquirrelVM* sqvm) g_pSquirrel<context>->raiseerror(sqvm, "Unexpected \\n in string"); return SQRESULT_ERROR; } - + // push last entry to current row if (pElemEnd) *pElemEnd = '\0'; @@ -283,7 +283,7 @@ template <ScriptContext context> SQRESULT SQ_GetDataTableColumnByName(HSquirrelV CSVData* csv = *pData; const char* pColumnName = g_pSquirrel<context>->getstring(sqvm, 2); - + for (int i = 0; i < csv->columns.size(); i++) { if (!strcmp(csv->columns[i], pColumnName)) @@ -464,7 +464,10 @@ template <ScriptContext context> SQRESULT SQ_GetDataTableVector(HSquirrelVM* sqv if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size()) { g_pSquirrel<context>->raiseerror( - sqvm, fmt::format("row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()).c_str()); + sqvm, + fmt::format( + "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) + .c_str()); return SQRESULT_ERROR; } @@ -621,10 +624,10 @@ template <ScriptContext context> SQRESULT SQ_GetDataTableRowGreaterThanOrEqualTo { if (nIntVal >= std::stoi(csv->dataPointers[i][nCol])) { - spdlog::info("datatable not loaded"); - g_pSquirrel<context>->pushinteger(sqvm, 1); - return SQRESULT_NOTNULL; - } + spdlog::info("datatable not loaded"); + g_pSquirrel<context>->pushinteger(sqvm, 1); + return SQRESULT_NOTNULL; + } } g_pSquirrel<context>->pushinteger(sqvm, -1); @@ -883,7 +886,7 @@ void ConCommand_dump_datatables(const CCommand& args) DumpDatatable(datatable); } -template <ScriptContext context> void RegisterDataTableFunctions() +template <ScriptContext context> void RegisterDataTableFunctions() { g_pSquirrel<context>->AddFuncOverride("GetDataTable", SQ_GetDatatable<context>); g_pSquirrel<context>->AddFuncOverride("GetDataTableColumnByName", SQ_GetDataTableColumnByName<context>); @@ -920,11 +923,11 @@ ON_DLL_LOAD_RELIESON("client.dll", ClientScriptDatatables, ClientSquirrel, (CMod RegisterDataTableFunctions<ScriptContext::CLIENT>(); RegisterDataTableFunctions<ScriptContext::UI>(); - SQ_GetDatatableInternal<ScriptContext::CLIENT> = module.Offset(0x1C9070).As<Datatable*(*)(HSquirrelVM*)>(); + SQ_GetDatatableInternal<ScriptContext::CLIENT> = module.Offset(0x1C9070).As<Datatable* (*)(HSquirrelVM*)>(); SQ_GetDatatableInternal<ScriptContext::UI> = SQ_GetDatatableInternal<ScriptContext::CLIENT>; } -ON_DLL_LOAD_RELIESON("engine.dll", SharedScriptDataTables, ConVar, (CModule module)) +ON_DLL_LOAD_RELIESON("engine.dll", SharedScriptDataTables, ConVar, (CModule module)) { Cvar_ns_prefer_datatable_from_disk = new ConVar( "ns_prefer_datatable_from_disk", diff --git a/NorthstarDLL/scriptjson.cpp b/NorthstarDLL/scriptjson.cpp index 62074587..a9767615 100644 --- a/NorthstarDLL/scriptjson.cpp +++ b/NorthstarDLL/scriptjson.cpp @@ -97,8 +97,10 @@ DecodeJsonTable(HSquirrelVM* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char> } } -template <ScriptContext context> -void EncodeJSONTable(SQTable* table, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj, rapidjson::MemoryPoolAllocator<SourceAllocator>& allocator) +template <ScriptContext context> void EncodeJSONTable( + SQTable* table, + rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj, + rapidjson::MemoryPoolAllocator<SourceAllocator>& allocator) { for (int i = 0; i < table->_numOfNodes; i++) { @@ -257,7 +259,11 @@ template <ScriptContext context> SQRESULT SQ_EncodeJSON(HSquirrelVM* sqvm) ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ClientScriptJSON, ClientSquirrel, (CModule module)) { g_pSquirrel<ScriptContext::CLIENT>->AddFuncRegistration( - "table", "DecodeJSON", "string json, bool fatalParseErrors = false", "converts a json string to a squirrel table", SQ_DecodeJSON<ScriptContext::CLIENT>); + "table", + "DecodeJSON", + "string json, bool fatalParseErrors = false", + "converts a json string to a squirrel table", + SQ_DecodeJSON<ScriptContext::CLIENT>); g_pSquirrel<ScriptContext::CLIENT>->AddFuncRegistration( "string", "EncodeJSON", "table data", "converts a squirrel table to a json string", SQ_EncodeJSON<ScriptContext::CLIENT>); @@ -273,4 +279,4 @@ ON_DLL_LOAD_RELIESON("server.dll", ServerScriptJSON, ServerSquirrel, (CModule mo "table", "DecodeJSON", "string json", "converts a json string to a squirrel table", SQ_DecodeJSON<ScriptContext::SERVER>); g_pSquirrel<ScriptContext::SERVER>->AddFuncRegistration( "string", "EncodeJSON", "table data", "converts a squirrel table to a json string", SQ_EncodeJSON<ScriptContext::SERVER>); -}
\ No newline at end of file +} diff --git a/NorthstarDLL/scriptmainmenupromos.cpp b/NorthstarDLL/scriptmainmenupromos.cpp index f88cd3e9..a1277235 100644 --- a/NorthstarDLL/scriptmainmenupromos.cpp +++ b/NorthstarDLL/scriptmainmenupromos.cpp @@ -131,5 +131,6 @@ ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ScriptMainMenuPromos, ClientSquirrel, { g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("void", "NSRequestCustomMainMenuPromos", "", "", SQ_RequestCustomMainMenuPromos); g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("bool", "NSHasCustomMainMenuPromoData", "", "", SQ_HasCustomMainMenuPromoData); - g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("var", "NSGetCustomMainMenuPromoData", "int promoDataKey", "", SQ_GetCustomMainMenuPromoData); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "var", "NSGetCustomMainMenuPromoData", "int promoDataKey", "", SQ_GetCustomMainMenuPromoData); } diff --git a/NorthstarDLL/scriptserverbrowser.cpp b/NorthstarDLL/scriptserverbrowser.cpp index ba5b17e2..a361aeb8 100644 --- a/NorthstarDLL/scriptserverbrowser.cpp +++ b/NorthstarDLL/scriptserverbrowser.cpp @@ -261,7 +261,8 @@ SQRESULT SQ_GetServerRequiredModName(HSquirrelVM* sqvm) return SQRESULT_ERROR; } - g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods[modIndex].Name.c_str()); + g_pSquirrel<ScriptContext::UI>->pushstring( + sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods[modIndex].Name.c_str()); return SQRESULT_NOTNULL; } @@ -295,7 +296,8 @@ SQRESULT SQ_GetServerRequiredModVersion(HSquirrelVM* sqvm) return SQRESULT_ERROR; } - g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods[modIndex].Version.c_str()); + g_pSquirrel<ScriptContext::UI>->pushstring( + sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods[modIndex].Version.c_str()); return SQRESULT_NOTNULL; } @@ -421,7 +423,8 @@ ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ScriptServerBrowser, ClientSquirrel, ( g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("bool", "NSIsMasterServerAuthenticated", "", "", SQ_IsMasterServerAuthenticated); g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("void", "NSRequestServerList", "", "", SQ_RequestServerList); g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("bool", "NSIsRequestingServerList", "", "", SQ_IsRequestingServerList); - g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("bool", "NSMasterServerConnectionSuccessful", "", "", SQ_MasterServerConnectionSuccessful); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "bool", "NSMasterServerConnectionSuccessful", "", "", SQ_MasterServerConnectionSuccessful); g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("int", "NSGetServerCount", "", "", SQ_GetServerCount); g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("void", "NSClearRecievedServerList", "", "", SQ_ClearRecievedServerList); @@ -430,10 +433,13 @@ ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ScriptServerBrowser, ClientSquirrel, ( g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("string", "NSGetServerMap", "int serverIndex", "", SQ_GetServerMap); g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("string", "NSGetServerPlaylist", "int serverIndex", "", SQ_GetServerPlaylist); g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("int", "NSGetServerPlayerCount", "int serverIndex", "", SQ_GetServerPlayerCount); - g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("int", "NSGetServerMaxPlayerCount", "int serverIndex", "", SQ_GetServerMaxPlayerCount); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "int", "NSGetServerMaxPlayerCount", "int serverIndex", "", SQ_GetServerMaxPlayerCount); g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("string", "NSGetServerID", "int serverIndex", "", SQ_GetServerID); - g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("bool", "NSServerRequiresPassword", "int serverIndex", "", SQ_ServerRequiresPassword); - g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("int", "NSGetServerRequiredModsCount", "int serverIndex", "", SQ_GetServerRequiredModsCount); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "bool", "NSServerRequiresPassword", "int serverIndex", "", SQ_ServerRequiresPassword); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "int", "NSGetServerRequiredModsCount", "int serverIndex", "", SQ_GetServerRequiredModsCount); g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( "string", "NSGetServerRequiredModName", "int serverIndex, int modIndex", "", SQ_GetServerRequiredModName); g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( diff --git a/NorthstarDLL/scriptservertoclientstringcommand.cpp b/NorthstarDLL/scriptservertoclientstringcommand.cpp index b3a405fc..5c116973 100644 --- a/NorthstarDLL/scriptservertoclientstringcommand.cpp +++ b/NorthstarDLL/scriptservertoclientstringcommand.cpp @@ -9,7 +9,9 @@ void ConCommand_ns_script_servertoclientstringcommand(const CCommand& arg) g_pSquirrel<ScriptContext::CLIENT>->setupfunc("NSClientCodeCallback_RecievedServerToClientStringCommand") != SQRESULT_ERROR) { g_pSquirrel<ScriptContext::CLIENT>->pushstring(g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM->sqvm, arg.ArgS()); - g_pSquirrel<ScriptContext::CLIENT>->call(g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM->sqvm, 1); // todo: doesn't throw or log errors from within this, probably not great behaviour + g_pSquirrel<ScriptContext::CLIENT>->call( + g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM->sqvm, + 1); // todo: doesn't throw or log errors from within this, probably not great behaviour } } diff --git a/NorthstarDLL/serverauthentication.cpp b/NorthstarDLL/serverauthentication.cpp index 366a391a..98054dd7 100644 --- a/NorthstarDLL/serverauthentication.cpp +++ b/NorthstarDLL/serverauthentication.cpp @@ -57,10 +57,7 @@ void ServerAuthenticationManager::StartPlayerAuthServer() { if (!request.has_param("id") || !request.has_param("authToken") || request.body.size() >= R2::PERSISTENCE_MAX_SIZE || !request.has_param("serverAuthToken") || - strcmp( - g_pMasterServerManager->m_sOwnServerAuthToken, - request.get_param_value("serverAuthToken") - .c_str())) + strcmp(g_pMasterServerManager->m_sOwnServerAuthToken, request.get_param_value("serverAuthToken").c_str())) { response.set_content("{\"success\":false}", "application/json"); return; @@ -70,7 +67,8 @@ void ServerAuthenticationManager::StartPlayerAuthServer() strncpy_s(newAuthData.uid, sizeof(newAuthData.uid), request.get_param_value("id").c_str(), sizeof(newAuthData.uid) - 1); strncpy_s( newAuthData.username, - sizeof(newAuthData.username), request.get_param_value("username").c_str(), + sizeof(newAuthData.username), + request.get_param_value("username").c_str(), sizeof(newAuthData.username) - 1); newAuthData.pdataSize = request.body.size(); @@ -101,7 +99,7 @@ void ServerAuthenticationManager::StopPlayerAuthServer() m_PlayerAuthServer.stop(); } -void ServerAuthenticationManager::AddPlayerData(R2::CBaseClient* player, const char* pToken) +void ServerAuthenticationManager::AddPlayer(R2::CBaseClient* player, const char* pToken) { PlayerAuthenticationData additionalData; additionalData.pdataSize = m_RemoteAuthenticationData[pToken].pdataSize; @@ -110,6 +108,12 @@ void ServerAuthenticationManager::AddPlayerData(R2::CBaseClient* player, const c m_PlayerAuthenticationData.insert(std::make_pair(player, additionalData)); } +void ServerAuthenticationManager::RemovePlayer(R2::CBaseClient* player) +{ + if (m_PlayerAuthenticationData.count(player)) + m_PlayerAuthenticationData.erase(player); +} + void ServerAuthenticationManager::VerifyPlayerName(R2::CBaseClient* player, char* authToken, char* name) { std::lock_guard<std::mutex> guard(m_AuthDataMutex); @@ -237,6 +241,7 @@ void ServerAuthenticationManager::WritePersistentData(R2::CBaseClient* player) char* pNextPlayerToken; uint64_t iNextPlayerUid; +// clang-format off AUTOHOOK(CBaseServer__ConnectClient, engine.dll + 0x114430, void*,, ( void* server, @@ -256,6 +261,7 @@ void*,, ( int64_t uid, uint32_t a16, uint32_t a17)) +// clang-format on { // auth tokens are sent with serverfilter, can't be accessed from player struct to my knowledge, so have to do this here pNextPlayerToken = serverFilter; @@ -264,8 +270,10 @@ void*,, ( return CBaseServer__ConnectClient(server, a2, a3, a4, a5, a6, a7, a8, serverFilter, a10, a11, a12, a13, a14, uid, a16, a17); } +// clang-format off AUTOHOOK(CBaseClient__Connect, engine.dll + 0x101740, bool,, (R2::CBaseClient* self, char* name, void* netchan_ptr_arg, char b_fake_player_arg, void* a5, char* Buffer, void* a7)) +// clang-format on { // try changing name before all else g_pServerAuthentication->VerifyPlayerName(self, pNextPlayerToken, name); @@ -284,18 +292,21 @@ bool,, (R2::CBaseClient* self, char* name, void* netchan_ptr_arg, char b_fake_pl if (strlen(name) >= 64) // fix for name overflow bug R2::CBaseClient__Disconnect(self, 1, "Invalid name"); - else if (!g_pServerAuthentication->AuthenticatePlayer(self, iNextPlayerUid, pNextPlayerToken) && + else if ( + !g_pServerAuthentication->AuthenticatePlayer(self, iNextPlayerUid, pNextPlayerToken) && g_pServerAuthentication->m_bRequireClientAuth) R2::CBaseClient__Disconnect(self, 1, "Authentication Failed"); - g_pServerAuthentication->AddPlayerData(self, pNextPlayerToken); + g_pServerAuthentication->AddPlayer(self, pNextPlayerToken); g_pServerLimits->AddPlayer(self); return ret; } +// clang-format off AUTOHOOK(CBaseClient__ActivatePlayer, engine.dll + 0x100F80, void,, (R2::CBaseClient* self)) +// clang-format on { // if we're authed, write our persistent data // RemovePlayerAuthData returns true if it removed successfully, i.e. on first call only, and we only want to write on >= second call @@ -310,8 +321,10 @@ void,, (R2::CBaseClient* self)) CBaseClient__ActivatePlayer(self); } +// clang-format off AUTOHOOK(_CBaseClient__Disconnect, engine.dll + 0x1012C0, void,, (R2::CBaseClient* self, uint32_t unknownButAlways1, const char* pReason, ...)) +// clang-format on { // have to manually format message because can't pass varargs to original func char buf[1024]; @@ -332,11 +345,10 @@ void,, (R2::CBaseClient* self, uint32_t unknownButAlways1, const char* pReason, g_pServerAuthentication->RemovePlayerAuthData(self); // won't do anything 99% of the time, but just in case } - if (g_pServerAuthentication->m_PlayerAuthenticationData.count(self)) - { - g_pServerAuthentication->m_PlayerAuthenticationData.erase(self); - g_pServerPresence->SetPlayerCount(g_pServerAuthentication->m_PlayerAuthenticationData.size()); - } + g_pServerAuthentication->RemovePlayer(self); + g_pServerLimits->RemovePlayer(self); + + g_pServerPresence->SetPlayerCount(g_pServerAuthentication->m_PlayerAuthenticationData.size()); _CBaseClient__Disconnect(self, unknownButAlways1, buf); } diff --git a/NorthstarDLL/serverauthentication.h b/NorthstarDLL/serverauthentication.h index b010e6b1..08854ac0 100644 --- a/NorthstarDLL/serverauthentication.h +++ b/NorthstarDLL/serverauthentication.h @@ -45,7 +45,8 @@ class ServerAuthenticationManager public: void StartPlayerAuthServer(); void StopPlayerAuthServer(); - void AddPlayerData(R2::CBaseClient* player, const char* pToken); + void AddPlayer(R2::CBaseClient* player, const char* pToken); + void RemovePlayer(R2::CBaseClient* player); bool CheckDuplicateAccounts(R2::CBaseClient* player); bool AuthenticatePlayer(R2::CBaseClient* player, uint64_t uid, char* authToken); void VerifyPlayerName(R2::CBaseClient* player, char* authToken, char* name); diff --git a/NorthstarDLL/serverchathooks.cpp b/NorthstarDLL/serverchathooks.cpp index bc9098dc..1dd05830 100644 --- a/NorthstarDLL/serverchathooks.cpp +++ b/NorthstarDLL/serverchathooks.cpp @@ -35,9 +35,10 @@ void(__fastcall* MessageWriteString)(const char* sz); void(__fastcall* MessageWriteBool)(bool bValue); bool bShouldCallSayTextHook = false; - +// clang-format off AUTOHOOK(_CServerGameDLL__OnReceivedSayTextMessage, server.dll + 0x1595C0, -void,, (CServerGameDLL* self, unsigned int senderPlayerId, const char* text, bool isTeam)) +void, __fastcall, (CServerGameDLL* self, unsigned int senderPlayerId, const char* text, bool isTeam)) +// clang-format on { // MiniHook doesn't allow calling the base function outside of anywhere but the hook function. // To allow bypassing the hook, isSkippingHook can be set. @@ -63,7 +64,7 @@ void,, (CServerGameDLL* self, unsigned int senderPlayerId, const char* text, boo _CServerGameDLL__OnReceivedSayTextMessage(self, senderPlayerId, text, isTeam); } -void ChatSendMessage(unsigned int playerIndex, const char* text, bool isteam) +void ChatSendMessage(unsigned int playerIndex, const char* text, bool isTeam) { bShouldCallSayTextHook = true; CServerGameDLL__OnReceivedSayTextMessage( @@ -71,7 +72,7 @@ void ChatSendMessage(unsigned int playerIndex, const char* text, bool isteam) // Ensure the first bit isn't set, since this indicates a custom message (playerIndex + 1) & CUSTOM_MESSAGE_INDEX_MASK, text, - isteam); + isTeam); } void ChatBroadcastMessage(int fromPlayerIndex, int toPlayerIndex, const char* text, bool isTeam, bool isDead, CustomMessageType messageType) @@ -156,7 +157,8 @@ ON_DLL_LOAD_RELIESON("server.dll", ServerChatHooks, ServerSquirrel, (CModule mod { AUTOHOOK_DISPATCH_MODULE(server.dll) - CServerGameDLL__OnReceivedSayTextMessage = module.Offset(0x1595C0).As<void(__fastcall*)(CServerGameDLL*, unsigned int, const char*, int)>(); + CServerGameDLL__OnReceivedSayTextMessage = + module.Offset(0x1595C0).As<void(__fastcall*)(CServerGameDLL*, unsigned int, const char*, int)>(); CRecipientFilter__Construct = module.Offset(0x1E9440).As<void(__fastcall*)(CRecipientFilter*)>(); CRecipientFilter__Destruct = module.Offset(0x1E9700).As<void(__fastcall*)(CRecipientFilter*)>(); CRecipientFilter__AddAllPlayers = module.Offset(0x1E9940).As<void(__fastcall*)(CRecipientFilter*)>(); @@ -170,7 +172,8 @@ ON_DLL_LOAD_RELIESON("server.dll", ServerChatHooks, ServerSquirrel, (CModule mod MessageWriteBool = module.Offset(0x158A00).As<void(__fastcall*)(bool)>(); // Chat sending functions - g_pSquirrel<ScriptContext::SERVER>->AddFuncRegistration("void", "NSSendMessage", "int playerIndex, string text, bool isTeam", "", SQ_SendMessage); + g_pSquirrel<ScriptContext::SERVER>->AddFuncRegistration( + "void", "NSSendMessage", "int playerIndex, string text, bool isTeam", "", SQ_SendMessage); g_pSquirrel<ScriptContext::SERVER>->AddFuncRegistration( "void", "NSBroadcastMessage", diff --git a/NorthstarDLL/serverpresence.cpp b/NorthstarDLL/serverpresence.cpp index 9338cd9c..9b7b0f1a 100644 --- a/NorthstarDLL/serverpresence.cpp +++ b/NorthstarDLL/serverpresence.cpp @@ -74,6 +74,7 @@ std::string UnescapeUnicode(const std::string& str) ServerPresenceManager::ServerPresenceManager() { + // clang-format off // register convars Cvar_ns_server_presence_update_rate = new ConVar( "ns_server_presence_update_rate", "5000", FCVAR_GAMEDLL, "How often we update our server's presence on server lists in ms"); @@ -95,6 +96,7 @@ ServerPresenceManager::ServerPresenceManager() Cvar_ns_report_server_to_masterserver = new ConVar("ns_report_server_to_masterserver", "1", FCVAR_GAMEDLL, "Whether we should report this server to the masterserver"); Cvar_ns_report_sp_server_to_masterserver = new ConVar("ns_report_sp_server_to_masterserver", "0", FCVAR_GAMEDLL, "Whether we should report this server to the masterserver, when started in singleplayer"); + // clang-format on } void ServerPresenceManager::AddPresenceReporter(ServerPresenceReporter* reporter) @@ -132,7 +134,7 @@ void ServerPresenceManager::DestroyPresence() void ServerPresenceManager::RunFrame(double flCurrentTime) { - if (!m_bHasPresence && Cvar_ns_report_server_to_masterserver->GetBool()) // don't run until we actually have server presence + if (!m_bHasPresence || !Cvar_ns_report_server_to_masterserver->GetBool()) // don't run until we actually have server presence return; // don't run if we're sp and don't want to report sp @@ -202,7 +204,11 @@ void ServerPresenceManager::SetMap(const char* pMapName, bool isInitialising) void ServerPresenceManager::SetPlaylist(const char* pPlaylistName) { // update playlist - strncpy_s(m_ServerPresence.m_PlaylistName, sizeof(m_ServerPresence.m_PlaylistName), pPlaylistName, sizeof(m_ServerPresence.m_PlaylistName) - 1); + strncpy_s( + m_ServerPresence.m_PlaylistName, + sizeof(m_ServerPresence.m_PlaylistName), + pPlaylistName, + sizeof(m_ServerPresence.m_PlaylistName) - 1); // update maxplayers const char* pMaxPlayers = R2::GetCurrentPlaylistVar("max_players", true); diff --git a/NorthstarDLL/sigscanning.h b/NorthstarDLL/sigscanning.h deleted file mode 100644 index 5d255152..00000000 --- a/NorthstarDLL/sigscanning.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include <string> - -// note: sigscanning is only really intended to be used for resolving stuff like shared function definitions -// we mostly use raw function addresses for stuff - -void* FindSignature(std::string dllName, const char* sig, const char* mask); diff --git a/NorthstarDLL/sourceconsole.cpp b/NorthstarDLL/sourceconsole.cpp index 718b6c3c..ad31e09d 100644 --- a/NorthstarDLL/sourceconsole.cpp +++ b/NorthstarDLL/sourceconsole.cpp @@ -32,14 +32,15 @@ void SourceConsoleSink::sink_it_(const spdlog::details::log_msg& msg) spdlog::memory_buf_t formatted; spdlog::sinks::base_sink<std::mutex>::formatter_->format(msg, formatted); - (*g_pSourceGameConsole) - ->m_pConsole->m_pConsolePanel->ColorPrint(m_LogColours[msg.level], fmt::to_string(formatted).c_str()); + (*g_pSourceGameConsole)->m_pConsole->m_pConsolePanel->ColorPrint(m_LogColours[msg.level], fmt::to_string(formatted).c_str()); } void SourceConsoleSink::flush_() {} +// clang-format off HOOK(OnCommandSubmittedHook, OnCommandSubmitted, -void,, (CConsoleDialog* consoleDialog, const char* pCommand)) +void, __fastcall, (CConsoleDialog* consoleDialog, const char* pCommand)) +// clang-format on { consoleDialog->m_pConsolePanel->Print("] "); consoleDialog->m_pConsolePanel->Print(pCommand); diff --git a/NorthstarDLL/sourceinterface.cpp b/NorthstarDLL/sourceinterface.cpp index 2f1df4ba..157ce614 100644 --- a/NorthstarDLL/sourceinterface.cpp +++ b/NorthstarDLL/sourceinterface.cpp @@ -6,8 +6,10 @@ AUTOHOOK_INIT() // really wanted to do a modular callback system here but honestly couldn't be bothered so hardcoding stuff for now: todo later +// clang-format off AUTOHOOK_PROCADDRESS(ClientCreateInterface, client.dll, CreateInterface, -void*,, (const char* pName, const int* pReturnCode)) +void*, __fastcall, (const char* pName, const int* pReturnCode)) +// clang-format on { void* ret = ClientCreateInterface(pName, pReturnCode); spdlog::info("CreateInterface CLIENT {}", pName); @@ -18,35 +20,28 @@ void*,, (const char* pName, const int* pReturnCode)) return ret; } +// clang-format off AUTOHOOK_PROCADDRESS(ServerCreateInterface, server.dll, CreateInterface, -void*,, (const char* pName, const int* pReturnCode)) +void*, __fastcall, (const char* pName, const int* pReturnCode)) +// clang-format on { void* ret = ServerCreateInterface(pName, pReturnCode); - spdlog::info("CreateInterface SERVER {}", pName); + spdlog::info("CreateInterface SERVER {}", pName); return ret; } +// clang-format off AUTOHOOK_PROCADDRESS(EngineCreateInterface, engine.dll, CreateInterface, -void*,, (const char* pName, const int* pReturnCode)) +void*, __fastcall, (const char* pName, const int* pReturnCode)) +// clang-format on { void* ret = EngineCreateInterface(pName, pReturnCode); - spdlog::info("CreateInterface ENGINE {}", pName); + spdlog::info("CreateInterface ENGINE {}", pName); return ret; } -ON_DLL_LOAD("client.dll", ClientInterface, (CModule module)) -{ - AUTOHOOK_DISPATCH_MODULE(client.dll) -} - -ON_DLL_LOAD("server.dll", ServerInterface, (CModule module)) -{ - AUTOHOOK_DISPATCH_MODULE(server.dll) -} - -ON_DLL_LOAD("engine.dll", EngineInterface, (CModule module)) -{ - AUTOHOOK_DISPATCH_MODULE(engine.dll) -} +ON_DLL_LOAD("client.dll", ClientInterface, (CModule module)) {AUTOHOOK_DISPATCH_MODULE(client.dll)} +ON_DLL_LOAD("server.dll", ServerInterface, (CModule module)) {AUTOHOOK_DISPATCH_MODULE(server.dll)} +ON_DLL_LOAD("engine.dll", EngineInterface, (CModule module)) {AUTOHOOK_DISPATCH_MODULE(engine.dll)} diff --git a/NorthstarDLL/squirrel.cpp b/NorthstarDLL/squirrel.cpp index cf5cb49e..5c2d8b1b 100644 --- a/NorthstarDLL/squirrel.cpp +++ b/NorthstarDLL/squirrel.cpp @@ -101,7 +101,7 @@ template class SquirrelManager<ScriptContext::UI>; template <ScriptContext context> void SquirrelManager<context>::VMCreated(CSquirrelVM* newSqvm) { - m_pSQVM = newSqvm; + m_pSQVM = newSqvm; for (SQFuncRegistration* funcReg : m_funcRegistrations) { @@ -205,8 +205,8 @@ bool IsUIVM(ScriptContext context, HSquirrelVM* pSqvm) g_pSquirrel<ScriptContext::UI>->m_pSQVM->sqvm == pSqvm; } -template <ScriptContext context> void* (*sq_compiler_create)(HSquirrelVM* sqvm, void* a2, void* a3, SQBool bShouldThrowError); -template <ScriptContext context> void* sq_compiler_createHook(HSquirrelVM* sqvm, void* a2, void* a3, SQBool bShouldThrowError) +template <ScriptContext context> void* (*__fastcall sq_compiler_create)(HSquirrelVM* sqvm, void* a2, void* a3, SQBool bShouldThrowError); +template <ScriptContext context> void* __fastcall sq_compiler_createHook(HSquirrelVM* sqvm, void* a2, void* a3, SQBool bShouldThrowError) { // store whether errors generated from this compile should be fatal if (IsUIVM(context, sqvm)) @@ -238,8 +238,8 @@ template <ScriptContext context> SQInteger SQPrintHook(HSquirrelVM* sqvm, const return 0; } -template <ScriptContext context> CSquirrelVM* (*CreateNewVM)(void* a1, ScriptContext realContext); -template <ScriptContext context> CSquirrelVM* CreateNewVMHook(void* a1, ScriptContext realContext) +template <ScriptContext context> CSquirrelVM* (*__fastcall CreateNewVM)(void* a1, ScriptContext realContext); +template <ScriptContext context> CSquirrelVM* __fastcall CreateNewVMHook(void* a1, ScriptContext realContext) { CSquirrelVM* sqvm = CreateNewVM<context>(a1, realContext); if (realContext == ScriptContext::UI) @@ -251,8 +251,8 @@ template <ScriptContext context> CSquirrelVM* CreateNewVMHook(void* a1, ScriptCo return sqvm; } -template <ScriptContext context> void (*DestroyVM)(void* a1, HSquirrelVM* sqvm); -template <ScriptContext context> void DestroyVMHook(void* a1, HSquirrelVM* sqvm) +template <ScriptContext context> void (*__fastcall DestroyVM)(void* a1, HSquirrelVM* sqvm); +template <ScriptContext context> void __fastcall DestroyVMHook(void* a1, HSquirrelVM* sqvm) { ScriptContext realContext = context; // ui and client use the same function so we use this for prints if (IsUIVM(context, sqvm)) @@ -266,8 +266,10 @@ template <ScriptContext context> void DestroyVMHook(void* a1, HSquirrelVM* sqvm) spdlog::info("DestroyVM {} {}", GetContextName(realContext), (void*)sqvm); } -template <ScriptContext context> void (*SQCompileError)(HSquirrelVM* sqvm, const char* error, const char* file, int line, int column); -template <ScriptContext context> void ScriptCompileErrorHook(HSquirrelVM* sqvm, const char* error, const char* file, int line, int column) +template <ScriptContext context> +void (*__fastcall SQCompileError)(HSquirrelVM* sqvm, const char* error, const char* file, int line, int column); +template <ScriptContext context> +void __fastcall ScriptCompileErrorHook(HSquirrelVM* sqvm, const char* error, const char* file, int line, int column) { bool bIsFatalError = g_pSquirrel<context>->m_bFatalCompilationErrors; ScriptContext realContext = context; // ui and client use the same function so we use this for prints @@ -306,8 +308,10 @@ template <ScriptContext context> void ScriptCompileErrorHook(HSquirrelVM* sqvm, // dont call the original function since it kills game lol } -template <ScriptContext context> int64_t(*RegisterSquirrelFunction)(CSquirrelVM* sqvm, SQFuncRegistration* funcReg, char unknown); -template <ScriptContext context> int64_t RegisterSquirrelFunctionHook(CSquirrelVM* sqvm, SQFuncRegistration* funcReg, char unknown) +template <ScriptContext context> +int64_t (*__fastcall RegisterSquirrelFunction)(CSquirrelVM* sqvm, SQFuncRegistration* funcReg, char unknown); +template <ScriptContext context> +int64_t __fastcall RegisterSquirrelFunctionHook(CSquirrelVM* sqvm, SQFuncRegistration* funcReg, char unknown) { if (IsUIVM(context, sqvm->sqvm)) { @@ -331,8 +335,8 @@ template <ScriptContext context> int64_t RegisterSquirrelFunctionHook(CSquirrelV return g_pSquirrel<context>->RegisterSquirrelFunc(sqvm, funcReg, unknown); } -template <ScriptContext context> bool (*CallScriptInitCallback)(void* sqvm, const char* callback); -template <ScriptContext context> bool CallScriptInitCallbackHook(void* sqvm, const char* callback) +template <ScriptContext context> bool (*__fastcall CallScriptInitCallback)(void* sqvm, const char* callback); +template <ScriptContext context> bool __fastcall CallScriptInitCallbackHook(void* sqvm, const char* callback) { ScriptContext realContext = context; bool bShouldCallCustomCallbacks = true; @@ -439,7 +443,7 @@ ON_DLL_LOAD_RELIESON("client.dll", ClientSquirrel, ConCommand, (CModule module)) g_pSquirrel<ScriptContext::CLIENT> = new SquirrelManager<ScriptContext::CLIENT>; g_pSquirrel<ScriptContext::UI> = new SquirrelManager<ScriptContext::UI>; - + g_pSquirrel<ScriptContext::CLIENT>->__sq_defconst = module.Offset(0x12120).As<sq_defconstType>(); g_pSquirrel<ScriptContext::UI>->__sq_defconst = g_pSquirrel<ScriptContext::CLIENT>->__sq_defconst; @@ -516,10 +520,7 @@ ON_DLL_LOAD_RELIESON("client.dll", ClientSquirrel, ConCommand, (CModule module)) MAKEHOOK(module.Offset(0x26E70), &DestroyVMHook<ScriptContext::CLIENT>, &DestroyVM<ScriptContext::CLIENT>); MAKEHOOK(module.Offset(0x79A50), &ScriptCompileErrorHook<ScriptContext::CLIENT>, &SQCompileError<ScriptContext::CLIENT>); - MAKEHOOK( - module.Offset(0x10190), - &CallScriptInitCallbackHook<ScriptContext::CLIENT>, - &CallScriptInitCallback<ScriptContext::CLIENT>); + MAKEHOOK(module.Offset(0x10190), &CallScriptInitCallbackHook<ScriptContext::CLIENT>, &CallScriptInitCallback<ScriptContext::CLIENT>); RegisterConCommand("script_client", ConCommand_script<ScriptContext::CLIENT>, "Executes script code on the client vm", FCVAR_CLIENTDLL); RegisterConCommand("script_ui", ConCommand_script<ScriptContext::UI>, "Executes script code on the ui vm", FCVAR_CLIENTDLL); diff --git a/NorthstarDLL/squirrel.h b/NorthstarDLL/squirrel.h index 2fa50ba6..4f644703 100644 --- a/NorthstarDLL/squirrel.h +++ b/NorthstarDLL/squirrel.h @@ -34,10 +34,7 @@ enum class eSQReturnType }; const std::map<SQRESULT, const char*> PrintSQRESULT = { - {SQRESULT_ERROR, "SQRESULT_ERROR"}, - {SQRESULT_NULL, "SQRESULT_NULL"}, - {SQRESULT_NOTNULL, "SQRESULT_NOTNULL"} -}; + {SQRESULT_ERROR, "SQRESULT_ERROR"}, {SQRESULT_NULL, "SQRESULT_NULL"}, {SQRESULT_NOTNULL, "SQRESULT_NOTNULL"}}; struct CompileBufferState { @@ -53,7 +50,6 @@ struct CompileBufferState } }; - struct SQFuncRegistration { const char* squirrelFuncName; @@ -94,7 +90,8 @@ const char* SQTypeNameFromID(const int iTypeId); typedef int64_t (*RegisterSquirrelFuncType)(CSquirrelVM* sqvm, SQFuncRegistration* funcReg, char unknown); typedef void (*sq_defconstType)(CSquirrelVM* sqvm, const SQChar* name, int value); -typedef SQRESULT (*sq_compilebufferType)(HSquirrelVM* sqvm, CompileBufferState* compileBuffer, const char* file, int a1, SQBool bShouldThrowError); +typedef SQRESULT (*sq_compilebufferType)( + HSquirrelVM* sqvm, CompileBufferState* compileBuffer, const char* file, int a1, SQBool bShouldThrowError); typedef SQRESULT (*sq_callType)(HSquirrelVM* sqvm, SQInteger iArgs, SQBool bShouldReturn, SQBool bThrowError); typedef SQInteger (*sq_raiseerrorType)(HSquirrelVM* sqvm, const SQChar* pError); @@ -115,7 +112,6 @@ typedef void (*sq_pushboolType)(HSquirrelVM* sqvm, SQBool b); typedef void (*sq_pushassetType)(HSquirrelVM* sqvm, const SQChar* str, SQInteger iLength); typedef void (*sq_pushvectorType)(HSquirrelVM* sqvm, const SQFloat* pVec); - // sq stack get funcs typedef const SQChar* (*sq_getstringType)(HSquirrelVM* sqvm, SQInteger iStackpos); typedef SQInteger (*sq_getintegerType)(HSquirrelVM* sqvm, SQInteger iStackpos); @@ -142,7 +138,7 @@ template <ScriptContext context> class SquirrelManager bool m_bFatalCompilationErrors = false; - #pragma region SQVM funcs +#pragma region SQVM funcs RegisterSquirrelFuncType RegisterSquirrelFunc; sq_defconstType __sq_defconst; @@ -187,7 +183,7 @@ template <ScriptContext context> class SquirrelManager SQRESULT setupfunc(const SQChar* funcname); void AddFuncOverride(std::string name, SQFunction func); - #pragma region SQVM func wrappers +#pragma region SQVM func wrappers inline void defconst(CSquirrelVM* sqvm, const SQChar* pName, int nValue) { __sq_defconst(sqvm, pName, nValue); @@ -259,7 +255,7 @@ template <ScriptContext context> class SquirrelManager __sq_pushasset(sqvm, sVal, length); } - inline void pushvector(HSquirrelVM* sqvm, const Vector3 pVal) + inline void pushvector(HSquirrelVM* sqvm, const Vector3 pVal) { __sq_pushvector(sqvm, *(float**)&pVal); } diff --git a/NorthstarDLL/vector.h b/NorthstarDLL/vector.h index 122fd211..c06e0bba 100644 --- a/NorthstarDLL/vector.h +++ b/NorthstarDLL/vector.h @@ -26,7 +26,7 @@ union Vector3 }
// todo: more operators maybe
- bool operator==(const Vector3& other)
+ bool operator==(const Vector3& other)
{
return x == other.x && y == other.y && z == other.z;
}
diff --git a/loader_wsock32_proxy/loader.cpp b/loader_wsock32_proxy/loader.cpp index 34a4b546..4af4daa1 100644 --- a/loader_wsock32_proxy/loader.cpp +++ b/loader_wsock32_proxy/loader.cpp @@ -14,7 +14,11 @@ void LibraryLoadError(DWORD dwMessageId, const wchar_t* libName, const wchar_t* sprintf_s(text, "Failed to load the %ls at \"%ls\" (%lu):\n\n%hs", libName, location, dwMessageId, message.c_str()); if (dwMessageId == 126 && std::filesystem::exists(location)) { - sprintf_s(text, "%s\n\nThe file at the specified location DOES exist, so this error indicates that one of its *dependencies* failed to be found.", text); + sprintf_s( + text, + "%s\n\nThe file at the specified location DOES exist, so this error indicates that one of its *dependencies* failed to be " + "found.", + text); } MessageBoxA(GetForegroundWindow(), text, "Northstar Wsock32 Proxy Error", 0); } @@ -44,7 +48,8 @@ bool LoadNorthstar() { swprintf_s(buffer1, L"%s\\Northstar.dll", exePath); auto hHookModule = LoadLibraryExW(buffer1, 0, LOAD_WITH_ALTERED_SEARCH_PATH); - if (hHookModule) Hook_Init = GetProcAddress(hHookModule, "InitialiseNorthstar"); + if (hHookModule) + Hook_Init = GetProcAddress(hHookModule, "InitialiseNorthstar"); if (!hHookModule || Hook_Init == nullptr) { LibraryLoadError(GetLastError(), L"Northstar.dll", buffer1); @@ -52,11 +57,11 @@ bool LoadNorthstar() } } - ((bool (*)()) Hook_Init)(); + ((bool (*)())Hook_Init)(); return true; } -typedef int(*LauncherMainType)(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow); +typedef int (*LauncherMainType)(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow); LauncherMainType LauncherMainOriginal; int LauncherMainHook(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) @@ -73,21 +78,26 @@ bool ProvisionNorthstar() if (MH_Initialize() != MH_OK) { - MessageBoxA(GetForegroundWindow(), "MH_Initialize failed\nThe game cannot continue and has to exit.", "Northstar Wsock32 Proxy Error", 0); + MessageBoxA( + GetForegroundWindow(), "MH_Initialize failed\nThe game cannot continue and has to exit.", "Northstar Wsock32 Proxy Error", 0); return false; } auto launcherHandle = GetModuleHandleA("launcher.dll"); if (!launcherHandle) { - MessageBoxA(GetForegroundWindow(), "Launcher isn't loaded yet.\nThe game cannot continue and has to exit.", "Northstar Wsock32 Proxy Error", 0); + MessageBoxA( + GetForegroundWindow(), + "Launcher isn't loaded yet.\nThe game cannot continue and has to exit.", + "Northstar Wsock32 Proxy Error", + 0); return false; } LPVOID pTarget = GetProcAddress(launcherHandle, "LauncherMain"); - if (MH_CreateHook(pTarget, &LauncherMainHook, reinterpret_cast<LPVOID*>(&LauncherMainOriginal)) != MH_OK || MH_EnableHook(pTarget) != MH_OK) - MessageBoxA( - GetForegroundWindow(), "Hook creation failed for function LauncherMain.", "Northstar Wsock32 Proxy Error", 0); + if (MH_CreateHook(pTarget, &LauncherMainHook, reinterpret_cast<LPVOID*>(&LauncherMainOriginal)) != MH_OK || + MH_EnableHook(pTarget) != MH_OK) + MessageBoxA(GetForegroundWindow(), "Hook creation failed for function LauncherMain.", "Northstar Wsock32 Proxy Error", 0); return true; } |