diff options
-rw-r--r-- | NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters | 6 | ||||
-rw-r--r-- | NorthstarDedicatedTest/clientauthhooks.cpp | 42 | ||||
-rw-r--r-- | NorthstarDedicatedTest/clientauthhooks.h | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/dllmain.cpp | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/gameutils.cpp | 4 | ||||
-rw-r--r-- | NorthstarDedicatedTest/gameutils.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/masterserver.cpp | 56 | ||||
-rw-r--r-- | NorthstarDedicatedTest/masterserver.h | 4 |
9 files changed, 119 insertions, 2 deletions
diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj index fc3d0fbe..fa617e4d 100644 --- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj +++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj @@ -171,6 +171,7 @@ </ItemDefinitionGroup> <ItemGroup> <ClInclude Include="chatcommand.h" /> + <ClInclude Include="clientauthhooks.h" /> <ClInclude Include="concommand.h" /> <ClInclude Include="context.h" /> <ClInclude Include="convar.h" /> @@ -331,6 +332,7 @@ </ItemGroup> <ItemGroup> <ClCompile Include="chatcommand.cpp" /> + <ClCompile Include="clientauthhooks.cpp" /> <ClCompile Include="concommand.cpp" /> <ClCompile Include="context.cpp" /> <ClCompile Include="convar.cpp" /> diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters index 59a5cb19..7572deb6 100644 --- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters +++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters @@ -582,6 +582,9 @@ <ClInclude Include="pdef.h"> <Filter>Header Files\Shared\Mods\Compiled</Filter> </ClInclude> + <ClInclude Include="clientauthhooks.h"> + <Filter>Header Files\Client</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="dllmain.cpp"> @@ -677,6 +680,9 @@ <ClCompile Include="pdef.cpp"> <Filter>Source Files\Shared\Mods\Compiled</Filter> </ClCompile> + <ClCompile Include="clientauthhooks.cpp"> + <Filter>Source Files\Client</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <None Include="include\spdlog\fmt\bundled\LICENSE.rst"> diff --git a/NorthstarDedicatedTest/clientauthhooks.cpp b/NorthstarDedicatedTest/clientauthhooks.cpp new file mode 100644 index 00000000..ff7e42f6 --- /dev/null +++ b/NorthstarDedicatedTest/clientauthhooks.cpp @@ -0,0 +1,42 @@ +#include "pch.h" +#include "clientauthhooks.h" +#include "hookutils.h" +#include "dedicated.h" +#include "gameutils.h" +#include "masterserver.h" +#include "convar.h" + +typedef void(*AuthWithStryderType)(void* a1); +AuthWithStryderType AuthWithStryder; + +ConVar* Cvar_ns_has_agreed_to_send_token; + +void AuthWithStryderHook(void* a1) +{ + // 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 + + if (!g_MasterServerManager->m_bOriginAuthWithMasterServerDone) + { + // if player has agreed to send token and we aren't already authing, try to auth + if (Cvar_ns_has_agreed_to_send_token->m_nValue && !g_MasterServerManager->m_bOriginAuthWithMasterServerInProgress) + g_MasterServerManager->AuthenticateOriginWithMasterServer(g_LocalPlayerUserID, g_LocalPlayerOriginToken); + + // invalidate key so auth will fail + *g_LocalPlayerOriginToken = 0; + } + + AuthWithStryder(a1); +} + +void InitialiseClientAuthHooks(HMODULE baseAddress) +{ + if (IsDedicated()) + return; + + // this cvar will save to cfg once initially agreed with + Cvar_ns_has_agreed_to_send_token = RegisterConVar("ns_has_agreed_to_send_token", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE, "whether the user has agreed to send their origin token to the northstar masterserver"); + + HookEnabler hook; + ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1843A0, &AuthWithStryderHook, reinterpret_cast<LPVOID*>(&AuthWithStryder)); +}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/clientauthhooks.h b/NorthstarDedicatedTest/clientauthhooks.h new file mode 100644 index 00000000..e40a68a5 --- /dev/null +++ b/NorthstarDedicatedTest/clientauthhooks.h @@ -0,0 +1,2 @@ +#pragma once +void InitialiseClientAuthHooks(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp index 2ecaf3db..dc1489e3 100644 --- a/NorthstarDedicatedTest/dllmain.cpp +++ b/NorthstarDedicatedTest/dllmain.cpp @@ -21,6 +21,7 @@ #include "playlist.h" #include "securitypatches.h" #include "miscserverscript.h" +#include "clientauthhooks.h" bool initialised = false; @@ -90,6 +91,7 @@ void InitialiseNorthstar() AddDllLoadCallback("client.dll", InitialiseScriptModMenu); AddDllLoadCallback("client.dll", InitialiseScriptServerBrowser); AddDllLoadCallback("localize.dll", InitialiseModLocalisation); + AddDllLoadCallback("engine.dll", InitialiseClientAuthHooks); } AddDllLoadCallback("server.dll", InitialiseServerSquirrel); diff --git a/NorthstarDedicatedTest/gameutils.cpp b/NorthstarDedicatedTest/gameutils.cpp index 984bc28a..adf13be7 100644 --- a/NorthstarDedicatedTest/gameutils.cpp +++ b/NorthstarDedicatedTest/gameutils.cpp @@ -26,8 +26,9 @@ GetCurrentPlaylistVarType GetCurrentPlaylistVar; // server entity stuff Server_GetEntityByIndexType Server_GetEntityByIndex; -// uid +// auth char* g_LocalPlayerUserID; +char* g_LocalPlayerOriginToken; void InitialiseEngineGameUtilFunctions(HMODULE baseAddress) { @@ -46,6 +47,7 @@ void InitialiseEngineGameUtilFunctions(HMODULE baseAddress) GetCurrentPlaylistVar = (GetCurrentPlaylistVarType)((char*)baseAddress + 0x18C680); g_LocalPlayerUserID = (char*)baseAddress + 0x13F8E688; + g_LocalPlayerOriginToken = (char*)baseAddress + 0x13979C80; } void InitialiseServerGameUtilFunctions(HMODULE baseAddress) diff --git a/NorthstarDedicatedTest/gameutils.h b/NorthstarDedicatedTest/gameutils.h index c861eb22..3970bfdb 100644 --- a/NorthstarDedicatedTest/gameutils.h +++ b/NorthstarDedicatedTest/gameutils.h @@ -185,8 +185,9 @@ extern GetCurrentPlaylistVarType GetCurrentPlaylistVar; typedef void*(*Server_GetEntityByIndexType)(int index); extern Server_GetEntityByIndexType Server_GetEntityByIndex; -// uid +// auth extern char* g_LocalPlayerUserID; +extern char* g_LocalPlayerOriginToken; void InitialiseEngineGameUtilFunctions(HMODULE baseAddress); void InitialiseServerGameUtilFunctions(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/masterserver.cpp b/NorthstarDedicatedTest/masterserver.cpp index 80d606eb..9ac88667 100644 --- a/NorthstarDedicatedTest/masterserver.cpp +++ b/NorthstarDedicatedTest/masterserver.cpp @@ -67,6 +67,62 @@ void MasterServerManager::ClearServerList() m_requestingServerList = false; } +void MasterServerManager::AuthenticateOriginWithMasterServer(char* uid, char* originToken) +{ + if (m_bOriginAuthWithMasterServerInProgress) + return; + + // do this here so it's instantly set + m_bOriginAuthWithMasterServerInProgress = true; + std::string uidStr(uid); + std::string tokenStr(originToken); + + std::thread requestThread([this, uidStr, tokenStr]() + { + httplib::Client http(Cvar_ns_masterserver_hostname->m_pszString, Cvar_ns_masterserver_port->m_nValue); + http.set_connection_timeout(10); + + spdlog::info("Trying to authenticate with northstar masterserver for user {} {}", uidStr, tokenStr); + + if (auto result = http.Get(fmt::format("/client/origin_auth?uid={}&token={}", uidStr, tokenStr).c_str())) + { + m_successfullyConnected = true; + + rapidjson::Document originAuthInfo; + originAuthInfo.Parse(result->body.c_str()); + + if (originAuthInfo.HasParseError()) + { + spdlog::error("Failed reading origin auth info response: encountered parse error \{}\"", rapidjson::GetParseError_En(originAuthInfo.GetParseError())); + goto REQUEST_END_CLEANUP; + } + + if (!originAuthInfo.IsObject() || !originAuthInfo.HasMember("success")) + { + spdlog::error("Failed reading origin auth info response: malformed response object {}", result->body); + goto REQUEST_END_CLEANUP; + } + + if (originAuthInfo["success"].IsTrue()) + spdlog::info("Northstar origin authentication completed successfully!"); + else + spdlog::error("Northstar origin authentication failed"); + } + else + { + spdlog::error("Failed performing northstar origin auth: error {}", result.error()); + m_successfullyConnected = false; + } + + // we goto this instead of returning so we always hit this + REQUEST_END_CLEANUP: + m_bOriginAuthWithMasterServerInProgress = false; + m_bOriginAuthWithMasterServerDone = true; + }); + + requestThread.detach(); +} + void MasterServerManager::RequestServerList() { // do this here so it's instantly set on call for scripts diff --git a/NorthstarDedicatedTest/masterserver.h b/NorthstarDedicatedTest/masterserver.h index d1033336..911555d1 100644 --- a/NorthstarDedicatedTest/masterserver.h +++ b/NorthstarDedicatedTest/masterserver.h @@ -49,6 +49,9 @@ private: public: char m_ownServerId[33]; + bool m_bOriginAuthWithMasterServerDone = false; + bool m_bOriginAuthWithMasterServerInProgress = false; + bool m_bRequireClientAuth = false; bool m_savingPersistentData = false; @@ -67,6 +70,7 @@ public: public: void ClearServerList(); void RequestServerList(); + void AuthenticateOriginWithMasterServer(char* uid, char* originToken); void AuthenticateWithOwnServer(char* uid, char* playerToken); void AuthenticateWithServer(char* uid, char* playerToken, char* serverId, char* password); void AddSelfToServerList(int port, int authPort, char* name, char* description, char* map, char* playlist, int maxPlayers, char* password); |