From db0af63704a6fbc57e80a9db01bbc01b79339d9f Mon Sep 17 00:00:00 2001 From: Emma Miler <27428383+emma-miler@users.noreply.github.com> Date: Mon, 7 Feb 2022 00:43:01 +0100 Subject: Added code for chathooks This may not seem like much to a passing observer, but this commit took me 30 hours of blood, sweat, tears, IDA debugging, server crashes, and insanity. --- NorthstarDedicatedTest/serverauthentication.cpp | 91 +++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 5 deletions(-) diff --git a/NorthstarDedicatedTest/serverauthentication.cpp b/NorthstarDedicatedTest/serverauthentication.cpp index 112db2a4..e0d4207e 100644 --- a/NorthstarDedicatedTest/serverauthentication.cpp +++ b/NorthstarDedicatedTest/serverauthentication.cpp @@ -13,6 +13,7 @@ #include #include #include "configurables.h" +#include "squirrel.h" const char* AUTHSERVER_VERIFY_STRING = "I am a northstar server!"; @@ -50,6 +51,7 @@ CServerGameDLL__OnRecievedSayTextMessageType CServerGameDLL__OnRecievedSayTextMe typedef void (*ConCommand__DispatchType)(ConCommand* command, const CCommand& args, void* a3); ConCommand__DispatchType ConCommand__Dispatch; + // global vars ServerAuthenticationManager* g_ServerAuthenticationManager; @@ -516,7 +518,32 @@ bool ProcessConnectionlessPacketHook(void* a1, netpacket_t* packet) return ProcessConnectionlessPacket(a1, packet); } -void CServerGameDLL__OnRecievedSayTextMessageHook(void* self, unsigned int senderClientIndex, const char* message, char unknown) +void ReplaceStringInPlace(std::string& subject, const std::string& search, const std::string& replace) +{ + size_t pos = 0; + while ((pos = subject.find(search, pos)) != std::string::npos) + { + subject.replace(pos, search.length(), replace); + pos += replace.length(); + } +} + +std::string currentMessage; +int currentPlayerId; +int currentChannelId; +bool shouldBlock; +bool isProcessed = true; + +SQRESULT setMessage(void* sqvm) +{ + currentMessage = ServerSq_getstring(sqvm, 1); + currentPlayerId = ServerSq_getinteger(sqvm, 2); + currentChannelId = ServerSq_getinteger(sqvm, 3); + shouldBlock = ServerSq_getbool(sqvm, 4); + return SQRESULT_NOTNULL; +} + +void CServerGameDLL__OnRecievedSayTextMessageHook(void* self, unsigned int senderClientIndex, const char* message, int channelId) { void* sender = GetPlayerByIndex(senderClientIndex - 1); // senderClientIndex starts at 1 @@ -532,10 +559,26 @@ void CServerGameDLL__OnRecievedSayTextMessageHook(void* self, unsigned int sende g_ServerAuthenticationManager->m_additionalPlayerData[sender].sayTextLimitCount++; - // todo: could censor messages here if we have a banned word list, we do not currently have one of these - // could possibly make this call a script codecallback, or smth + bool shouldDoChathooks = strstr(GetCommandLineA(), "-enableChatHooks"); + if (shouldDoChathooks) + { + + currentMessage = message; + currentPlayerId = senderClientIndex - 1; // Stupid fix cause of index offsets + currentChannelId = channelId; + shouldBlock = false; + isProcessed = false; - CServerGameDLL__OnRecievedSayTextMessage(self, senderClientIndex, message, unknown); + g_ServerSquirrelManager->ExecuteCode("CServerGameDLL_ProcessMessageStartThread()"); + if (!shouldBlock && currentPlayerId + 1 == senderClientIndex) // stop player id spoofing from server + { + CServerGameDLL__OnRecievedSayTextMessage(self, currentPlayerId + 1, currentMessage.c_str(), currentChannelId); + } + } + else + { + CServerGameDLL__OnRecievedSayTextMessage(self, senderClientIndex, message, channelId); + } } void ResetPdataCommand(const CCommand& args) @@ -642,10 +685,48 @@ void InitialiseServerAuthentication(HMODULE baseAddress) } } +SQRESULT getMessageServer(void* sqvm) +{ + ServerSq_pushstring(sqvm, currentMessage.c_str(), -1); + return SQRESULT_NOTNULL; +} +SQRESULT getPlayerServer(void* sqvm) +{ + ServerSq_pushinteger(sqvm, currentPlayerId); + return SQRESULT_NOTNULL; +} +SQRESULT getChannelServer(void* sqvm) +{ + ServerSq_pushinteger(sqvm, currentChannelId); + return SQRESULT_NOTNULL; +} +SQRESULT getShouldProcessMessage(void* sqvm) +{ + ServerSq_pushbool(sqvm, !isProcessed); + return SQRESULT_NOTNULL; +} +SQRESULT pushMessage(void* sqvm) +{ + currentMessage = ServerSq_getstring(sqvm, 1); + currentPlayerId = ServerSq_getinteger(sqvm, 2); + currentChannelId = ServerSq_getinteger(sqvm, 3); + shouldBlock = ServerSq_getbool(sqvm, 4); + isProcessed = true; + return SQRESULT_NOTNULL; +} + void InitialiseServerAuthenticationServerDLL(HMODULE baseAddress) { HookEnabler hook; ENABLER_CREATEHOOK( hook, (char*)baseAddress + 0x1595C0, &CServerGameDLL__OnRecievedSayTextMessageHook, reinterpret_cast(&CServerGameDLL__OnRecievedSayTextMessage)); -} \ No newline at end of file + + g_ServerSquirrelManager->AddFuncRegistration("void", "NSSetMessage", "string message, int playerId, int channelId, bool shouldBlock", "", setMessage); + + g_ServerSquirrelManager->AddFuncRegistration("string", "NSChatGetCurrentMessage", "", "", getMessageServer); + g_ServerSquirrelManager->AddFuncRegistration("int", "NSChatGetCurrentPlayer", "", "", getPlayerServer); + g_ServerSquirrelManager->AddFuncRegistration("int", "NSChatGetCurrentChannel", "", "", getChannelServer); + g_ServerSquirrelManager->AddFuncRegistration("bool", "NSShouldProcessMessage", "", "", getShouldProcessMessage); + g_ServerSquirrelManager->AddFuncRegistration("void", "NSPushMessage", "string message, int playerId, int channelId, bool shouldBlock", "", pushMessage); +} -- cgit v1.2.3