diff options
Diffstat (limited to 'NorthstarDedicatedTest')
-rw-r--r-- | NorthstarDedicatedTest/ExploitFixes.cpp | 41 | ||||
-rw-r--r-- | NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters | 6 | ||||
-rw-r--r-- | NorthstarDedicatedTest/dllmain.cpp | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/emit_blocker.cpp | 26 | ||||
-rw-r--r-- | NorthstarDedicatedTest/emit_blocker.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/latencyflex.cpp | 50 | ||||
-rw-r--r-- | NorthstarDedicatedTest/masterserver.cpp | 42 | ||||
-rw-r--r-- | NorthstarDedicatedTest/masterserver.h | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/miscserverfixes.cpp | 106 | ||||
-rw-r--r-- | NorthstarDedicatedTest/miscserverfixes.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/miscserverscript.cpp | 10 | ||||
-rw-r--r-- | NorthstarDedicatedTest/scriptserverbrowser.cpp | 9 | ||||
-rw-r--r-- | NorthstarDedicatedTest/serverauthentication.cpp | 4 |
14 files changed, 253 insertions, 54 deletions
diff --git a/NorthstarDedicatedTest/ExploitFixes.cpp b/NorthstarDedicatedTest/ExploitFixes.cpp index db754ad5..af7d48ac 100644 --- a/NorthstarDedicatedTest/ExploitFixes.cpp +++ b/NorthstarDedicatedTest/ExploitFixes.cpp @@ -5,6 +5,9 @@ #include "NSMem.h" #include "cvar.h" +typedef char(__fastcall* function_containing_emit_t)(uint64_t a1, uint64_t a2); +function_containing_emit_t function_containing_emit; +ConVar* sv_cheats; ConVar* ns_exploitfixes_log; #define SHOULD_LOG (ns_exploitfixes_log->m_Value.m_nValue > 0) #define BLOCKED_INFO(s) \ @@ -347,6 +350,21 @@ KHOOK( return oCrashFunc_ParseUTF8(a1, a2, strData); } +// GetEntByIndex (called by ScriptGetEntByIndex) doesn't check for the index being out of bounds when it's +// above the max entity count. This allows it to be used to crash servers. +typedef void*(__fastcall* GetEntByIndexType)(int idx); +GetEntByIndexType GetEntByIndex; + +static void* GetEntByIndexHook(int idx) +{ + if (idx >= 0x4000) + { + spdlog::info("GetEntByIndex {} is out of bounds", idx); + return nullptr; + } + return GetEntByIndex(idx); +} + ////////////////////////////////////////////////// void DoBytePatches() @@ -394,7 +412,19 @@ void DoBytePatches() } } -void ExploitFixes::LoadCallback(HMODULE unused) +char function_containing_emit_hook(uint64_t unknown_value, uint64_t command_ptr) +{ + char* command_string = *(char**)(command_ptr + 1040); // From decompile + + if (!sv_cheats->m_Value.m_nValue && !_strnicmp(command_string, "emit", 5)) + { + spdlog::info("Blocking command \"emit\" because sv_cheats was 0"); + return 1; + } + return function_containing_emit(unknown_value, command_ptr); +} + +void ExploitFixes::LoadCallback(HMODULE baseAddress) { spdlog::info("ExploitFixes::LoadCallback ..."); @@ -416,4 +446,11 @@ void ExploitFixes::LoadCallback(HMODULE unused) ns_exploitfixes_log = new ConVar("ns_exploitfixes_log", "1", FCVAR_GAMEDLL, "Whether to log whenever ExploitFixes.cpp blocks/corrects something"); -}
\ No newline at end of file + + HookEnabler hook; + + sv_cheats = g_pCVar->FindVar("sv_cheats"); + ENABLER_CREATEHOOK( + hook, (char*)baseAddress + 0x5889A0, &function_containing_emit_hook, reinterpret_cast<LPVOID*>(&function_containing_emit)); + ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x2a8a50, &GetEntByIndexHook, reinterpret_cast<LPVOID*>(&GetEntByIndex)); +} diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj index 3fe2da06..4151a7e5 100644 --- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj +++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj @@ -121,7 +121,6 @@ <ClInclude Include="debugoverlay.h" /> <ClInclude Include="clientruihooks.h" /> <ClInclude Include="clientvideooverrides.h" /> - <ClInclude Include="emit_blocker.h" /> <ClInclude Include="localchatwriter.h" /> <ClInclude Include="ns_version.h" /> <ClInclude Include="plugins.h" /> @@ -603,7 +602,6 @@ <ClCompile Include="dedicated.cpp" /> <ClCompile Include="dedicatedmaterialsystem.cpp" /> <ClCompile Include="dllmain.cpp" /> - <ClCompile Include="emit_blocker.cpp" /> <ClCompile Include="filesystem.cpp" /> <ClCompile Include="gameutils.cpp" /> <ClCompile Include="hooks.cpp" /> diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters index 1845c3ea..b3387eab 100644 --- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters +++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters @@ -1548,9 +1548,6 @@ <ClInclude Include="NSMem.h"> <Filter>Header Files\Shared\ExploitFixes</Filter> </ClInclude> - <ClInclude Include="emit_blocker.h"> - <Filter>Header Files\Shared\ExploitFixes</Filter> - </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="dllmain.cpp"> @@ -1748,9 +1745,6 @@ <ClCompile Include="clientruihooks.cpp"> <Filter>Source Files\Client</Filter> </ClCompile> - <ClCompile Include="emit_blocker.cpp"> - <Filter>Source Files\Shared\Exploit Fixes</Filter> - </ClCompile> </ItemGroup> <ItemGroup> <MASM Include="audio_asm.asm"> diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp index 77dd4957..266bf10f 100644 --- a/NorthstarDedicatedTest/dllmain.cpp +++ b/NorthstarDedicatedTest/dllmain.cpp @@ -49,7 +49,6 @@ #include "rapidjson/writer.h" #include "rapidjson/error/en.h" #include "ExploitFixes.h" -#include "emit_blocker.h" typedef void (*initPluginFuncPtr)(void* getPluginObject); @@ -265,6 +264,7 @@ bool InitialiseNorthstar() AddDllLoadCallback("engine.dll", InitialiseSharedMasterServer); AddDllLoadCallback("server.dll", InitialiseMiscServerScriptCommand); AddDllLoadCallback("server.dll", InitialiseMiscServerFixes); + AddDllLoadCallback("engine.dll", InitialiseMiscEngineServerFixes); AddDllLoadCallback("server.dll", InitialiseBuildAINFileHooks); AddDllLoadCallback("engine.dll", InitializeCHostStateHooks); @@ -289,7 +289,6 @@ bool InitialiseNorthstar() // activate exploit fixes AddDllLoadCallback("server.dll", ExploitFixes::LoadCallback); - AddDllLoadCallback("server.dll", InitialiseServerEmit_Blocker); // run callbacks for any libraries that are already loaded by now CallAllPendingDLLLoadCallbacks(); diff --git a/NorthstarDedicatedTest/emit_blocker.cpp b/NorthstarDedicatedTest/emit_blocker.cpp deleted file mode 100644 index 3f996c69..00000000 --- a/NorthstarDedicatedTest/emit_blocker.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "pch.h" -#include "cvar.h" - -ConVar* sv_cheats; - -typedef char(__fastcall* function_containing_emit_t)(uint64_t a1, uint64_t a2); -function_containing_emit_t function_containing_emit; - -char function_containing_emit_hook(uint64_t unknown_value, uint64_t command_ptr) -{ - char* command_string = *(char**)(command_ptr + 1040); // From decompile - if (!sv_cheats->m_Value.m_nValue && !strncmp(command_string, "emit", 5)) - { - spdlog::info("Blocking command \"emit\" because sv_cheats was 0"); - return 1; - } - return function_containing_emit(unknown_value, command_ptr); -} - -void InitialiseServerEmit_Blocker(HMODULE baseAddress) -{ - HookEnabler hook; - sv_cheats = g_pCVar->FindVar("sv_cheats"); - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x5889A0, &function_containing_emit_hook, reinterpret_cast<LPVOID*>(&function_containing_emit)); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/emit_blocker.h b/NorthstarDedicatedTest/emit_blocker.h deleted file mode 100644 index 43991927..00000000 --- a/NorthstarDedicatedTest/emit_blocker.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void InitialiseServerEmit_Blocker(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/latencyflex.cpp b/NorthstarDedicatedTest/latencyflex.cpp index 4ac1c760..3e2cecd7 100644 --- a/NorthstarDedicatedTest/latencyflex.cpp +++ b/NorthstarDedicatedTest/latencyflex.cpp @@ -9,13 +9,19 @@ OnRenderStartType OnRenderStart; ConVar* Cvar_r_latencyflex; HMODULE m_lfxModule {}; -typedef void (*PFN_winelfx_WaitAndBeginFrame)(); -PFN_winelfx_WaitAndBeginFrame m_winelfx_WaitAndBeginFrame {}; +typedef void (*PFN_lfx_WaitAndBeginFrame)(); +PFN_lfx_WaitAndBeginFrame m_lfx_WaitAndBeginFrame {}; void OnRenderStartHook() { + // Sleep before next frame as needed to reduce latency. if (Cvar_r_latencyflex->GetInt()) - m_winelfx_WaitAndBeginFrame(); + { + if (m_lfx_WaitAndBeginFrame) + { + m_lfx_WaitAndBeginFrame(); + } + } OnRenderStart(); } @@ -25,17 +31,43 @@ void InitialiseLatencyFleX(HMODULE baseAddress) // Connect to the LatencyFleX service // LatencyFleX is an open source vendor agnostic replacement for Nvidia Reflex input latency reduction technology. // https://ishitatsuyuki.github.io/post/latencyflex/ - m_lfxModule = LoadLibraryA("latencyflex_wine.dll"); + const auto lfxModuleName = "latencyflex_layer.dll"; + const auto lfxModuleNameFallback = "latencyflex_wine.dll"; + auto useFallbackEntrypoints = false; + + // Load LatencyFleX library. + m_lfxModule = ::LoadLibraryA(lfxModuleName); + if (m_lfxModule == nullptr && ::GetLastError() == ERROR_MOD_NOT_FOUND) + { + spdlog::info("LFX: Primary LatencyFleX library not found, trying fallback."); - if (m_lfxModule == nullptr) + m_lfxModule = ::LoadLibraryA(lfxModuleNameFallback); + if (m_lfxModule == nullptr) + { + if (::GetLastError() == ERROR_MOD_NOT_FOUND) + { + spdlog::info("LFX: Fallback LatencyFleX library not found."); + } + else + { + spdlog::info("LFX: Error loading fallback LatencyFleX library - Code: {}", ::GetLastError()); + } + + return; + } + + useFallbackEntrypoints = true; + } + else if (m_lfxModule == nullptr) { - spdlog::info("Unable to load LatencyFleX library, LatencyFleX disabled."); + spdlog::info("LFX: Error loading primary LatencyFleX library - Code: {}", ::GetLastError()); return; } - m_winelfx_WaitAndBeginFrame = - reinterpret_cast<PFN_winelfx_WaitAndBeginFrame>(reinterpret_cast<void*>(GetProcAddress(m_lfxModule, "winelfx_WaitAndBeginFrame"))); - spdlog::info("LatencyFleX initialized."); + m_lfx_WaitAndBeginFrame = reinterpret_cast<PFN_lfx_WaitAndBeginFrame>(reinterpret_cast<void*>( + GetProcAddress(m_lfxModule, !useFallbackEntrypoints ? "lfx_WaitAndBeginFrame" : "winelfx_WaitAndBeginFrame"))); + + spdlog::info("LFX: Initialized."); Cvar_r_latencyflex = new ConVar("r_latencyflex", "1", FCVAR_ARCHIVE, "Whether or not to use LatencyFleX input latency reduction."); diff --git a/NorthstarDedicatedTest/masterserver.cpp b/NorthstarDedicatedTest/masterserver.cpp index d351fc13..28d11d4f 100644 --- a/NorthstarDedicatedTest/masterserver.cpp +++ b/NorthstarDedicatedTest/masterserver.cpp @@ -12,6 +12,7 @@ #include "modmanager.h" #include "misccommands.h" #include "host_state.h" +#include "version.h" // NOTE for anyone reading this: we used to use httplib for requests here, but it had issues, so we're moving to curl now for masterserver // requests so httplib is used exclusively for server stuff now @@ -488,6 +489,10 @@ void MasterServerManager::RequestMainMenuPromos() { spdlog::error("Failed reading masterserver response: got fastify error response"); spdlog::error(readBuffer); + if (mainMenuPromoJson["error"].HasMember("enum")) + s_authfail_reason = std::string(mainMenuPromoJson["error"]["enum"].GetString()); + else + s_authfail_reason = std::string("No error message provided"); goto REQUEST_END_CLEANUP; } @@ -608,6 +613,10 @@ void MasterServerManager::AuthenticateWithOwnServer(char* uid, char* playerToken { spdlog::error("Failed reading masterserver response: got fastify error response"); spdlog::error(readBuffer); + if (authInfoJson["error"].HasMember("enum")) + s_authfail_reason = std::string(authInfoJson["error"]["enum"].GetString()); + else + s_authfail_reason = std::string("No error message provided"); goto REQUEST_END_CLEANUP; } @@ -755,6 +764,10 @@ void MasterServerManager::AuthenticateWithServer(char* uid, char* playerToken, c { spdlog::error("Failed reading masterserver response: got fastify error response"); spdlog::error(readBuffer); + if (connectionInfoJson["error"].HasMember("enum")) + s_authfail_reason = std::string(connectionInfoJson["error"]["enum"].GetString()); + else + s_authfail_reason = std::string("No error message provided"); goto REQUEST_END_CLEANUP; } @@ -822,6 +835,10 @@ void MasterServerManager::AddSelfToServerList( std::thread requestThread( [this, port, authPort, strName, strDescription, strMap, strPlaylist, maxPlayers, strPassword] { + // Keep track of attempted connects in case of DUPLICATE_SERVER response + int retry_counter = 0; + + START_REQUEST: m_ownServerId[0] = 0; m_ownServerAuthToken[0] = 0; @@ -901,6 +918,29 @@ void MasterServerManager::AddSelfToServerList( { spdlog::error("Failed reading masterserver response: got fastify error response"); spdlog::error(readBuffer); + + // Check for enum member in JSON + if (serverAddedJson["error"].HasMember("enum")) + { + // Check for DUPLICATE_SERVER error response, stop if we tried 10 times + if (strncmp(serverAddedJson["error"]["enum"].GetString(), "DUPLICATE_SERVER", 17) == 0 && retry_counter < 10) + { + + spdlog::info("Retrying request in 10 seconds."); + // Incremement retry counter + retry_counter++; + + // Sleep for 10 seconds + std::this_thread::sleep_for(std::chrono::seconds(10)); + + // curl cleanup to retry request + curl_easy_cleanup(curl); + curl_mime_free(mime); + + // go to beginning and retry + goto START_REQUEST; + } + } goto REQUEST_END_CLEANUP; } @@ -923,6 +963,8 @@ void MasterServerManager::AddSelfToServerList( strncpy(m_ownServerAuthToken, serverAddedJson["serverAuthToken"].GetString(), sizeof(m_ownServerAuthToken)); m_ownServerAuthToken[sizeof(m_ownServerAuthToken) - 1] = 0; + spdlog::info("Succesfully added server to the master server."); + // heartbeat thread // ideally this should actually be done in main thread, rather than on it's own thread, so it'd stop if server freezes std::thread heartbeatThread( diff --git a/NorthstarDedicatedTest/masterserver.h b/NorthstarDedicatedTest/masterserver.h index 10f91356..8dd42d77 100644 --- a/NorthstarDedicatedTest/masterserver.h +++ b/NorthstarDedicatedTest/masterserver.h @@ -98,6 +98,8 @@ class MasterServerManager bool m_scriptAuthenticatingWithGameServer = false; bool m_successfullyAuthenticatedWithGameServer = false; + std::string s_authfail_reason {}; + bool m_hasPendingConnectionInfo = false; RemoteServerConnectionInfo m_pendingConnectionInfo; diff --git a/NorthstarDedicatedTest/miscserverfixes.cpp b/NorthstarDedicatedTest/miscserverfixes.cpp index 30cd5777..ddbfcfbb 100644 --- a/NorthstarDedicatedTest/miscserverfixes.cpp +++ b/NorthstarDedicatedTest/miscserverfixes.cpp @@ -25,4 +25,108 @@ void InitialiseMiscServerFixes(HMODULE baseAddress) } } -void InitialiseMiscEngineServerFixes(HMODULE baseAddress) {}
\ No newline at end of file +typedef unsigned int(__fastcall* CLZSS__SafeUncompressType)( + void* self, const unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize); +CLZSS__SafeUncompressType CLZSS__SafeUncompress; + +struct lzss_header_t +{ + unsigned int id; + unsigned int actualSize; +}; + +static constexpr int LZSS_LOOKSHIFT = 4; + +// 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. +static unsigned int CLZSS__SafeUncompressHook(void* self, const unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize) +{ + unsigned int totalBytes = 0; + int getCmdByte = 0; + int cmdByte = 0; + + lzss_header_t header = *(lzss_header_t*)pInput; + + if (pInput == NULL) + { + return 0; + } + if (header.id != 0x53535a4c) + { + return 0; + } + if (header.actualSize == 0) + { + return 0; + } + if (header.actualSize > unBufSize) + { + return 0; + } + + pInput += sizeof(lzss_header_t); + + for (;;) + { + if (!getCmdByte) + { + cmdByte = *pInput++; + } + getCmdByte = (getCmdByte + 1) & 0x07; + + if (cmdByte & 0x01) + { + int position = *pInput++ << LZSS_LOOKSHIFT; + position |= (*pInput >> LZSS_LOOKSHIFT); + position += 1; + int count = (*pInput++ & 0x0F) + 1; + if (count == 1) + { + break; + } + + // Ensure reference chunk exists entirely within our buffer + if (position > totalBytes) + { + return 0; + } + + totalBytes += count; + if (totalBytes > unBufSize) + { + return 0; + } + + unsigned char* pSource = pOutput - position; + for (int i = 0; i < count; i++) + { + *pOutput++ = *pSource++; + } + } + else + { + totalBytes++; + if (totalBytes > unBufSize) + { + return 0; + } + *pOutput++ = *pInput++; + } + cmdByte = cmdByte >> 1; + } + + if (totalBytes != header.actualSize) + { + return 0; + } + + return totalBytes; + + return 0; +} + +void InitialiseMiscEngineServerFixes(HMODULE baseAddress) +{ + HookEnabler hook; + ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x432a10, &CLZSS__SafeUncompressHook, reinterpret_cast<LPVOID*>(&CLZSS__SafeUncompress)); +} diff --git a/NorthstarDedicatedTest/miscserverfixes.h b/NorthstarDedicatedTest/miscserverfixes.h index d1c05a6b..3fdf56a8 100644 --- a/NorthstarDedicatedTest/miscserverfixes.h +++ b/NorthstarDedicatedTest/miscserverfixes.h @@ -1 +1,2 @@ -void InitialiseMiscServerFixes(HMODULE baseAddress);
\ No newline at end of file +void InitialiseMiscServerFixes(HMODULE baseAddress); +void InitialiseMiscEngineServerFixes(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/miscserverscript.cpp b/NorthstarDedicatedTest/miscserverscript.cpp index b2bf52ec..3b06ca10 100644 --- a/NorthstarDedicatedTest/miscserverscript.cpp +++ b/NorthstarDedicatedTest/miscserverscript.cpp @@ -4,6 +4,7 @@ #include "masterserver.h" #include "serverauthentication.h" #include "gameutils.h" +#include "dedicated.h" // annoying helper function because i can't figure out getting players or entities from sqvm rn // wish i didn't have to do it like this, but here we are @@ -57,10 +58,19 @@ SQRESULT SQ_IsPlayerIndexLocalPlayer(void* sqvm) return SQRESULT_NOTNULL; } +// bool function NSIsDedicated() + +SQRESULT SQ_IsDedicated(void* sqvm) +{ + ServerSq_pushbool(sqvm, IsDedicated()); + return SQRESULT_NOTNULL; +} + void InitialiseMiscServerScriptCommand(HMODULE baseAddress) { g_ServerSquirrelManager->AddFuncRegistration( "void", "NSEarlyWritePlayerIndexPersistenceForLeave", "int playerIndex", "", SQ_EarlyWritePlayerIndexPersistenceForLeave); g_ServerSquirrelManager->AddFuncRegistration("bool", "NSIsWritingPlayerPersistence", "", "", SQ_IsWritingPlayerPersistence); g_ServerSquirrelManager->AddFuncRegistration("bool", "NSIsPlayerIndexLocalPlayer", "int playerIndex", "", SQ_IsPlayerIndexLocalPlayer); + g_ServerSquirrelManager->AddFuncRegistration("bool", "NSIsDedicated", "", "", SQ_IsDedicated); }
\ No newline at end of file diff --git a/NorthstarDedicatedTest/scriptserverbrowser.cpp b/NorthstarDedicatedTest/scriptserverbrowser.cpp index aec47c3b..b0e19fc1 100644 --- a/NorthstarDedicatedTest/scriptserverbrowser.cpp +++ b/NorthstarDedicatedTest/scriptserverbrowser.cpp @@ -355,6 +355,13 @@ SQRESULT SQ_WasAuthSuccessful(void* sqvm) return SQRESULT_NOTNULL; } +// bool function NSWasAuthSuccessful() +SQRESULT SQ_GetAuthFailReason(void* sqvm) +{ + ClientSq_pushstring(sqvm, g_MasterServerManager->s_authfail_reason.c_str(), -1); + return SQRESULT_NOTNULL; +} + // void function NSConnectToAuthedServer() SQRESULT SQ_ConnectToAuthedServer(void* sqvm) { @@ -438,4 +445,6 @@ void InitialiseScriptServerBrowser(HMODULE baseAddress) g_UISquirrelManager->AddFuncRegistration("void", "NSTryAuthWithLocalServer", "", "", SQ_TryAuthWithLocalServer); g_UISquirrelManager->AddFuncRegistration("void", "NSCompleteAuthWithLocalServer", "", "", SQ_CompleteAuthWithLocalServer); + + g_UISquirrelManager->AddFuncRegistration("string", "NSGetAuthFailReason", "", "", SQ_GetAuthFailReason); }
\ No newline at end of file diff --git a/NorthstarDedicatedTest/serverauthentication.cpp b/NorthstarDedicatedTest/serverauthentication.cpp index 730c601d..8d7c063b 100644 --- a/NorthstarDedicatedTest/serverauthentication.cpp +++ b/NorthstarDedicatedTest/serverauthentication.cpp @@ -257,7 +257,7 @@ bool ServerAuthenticationManager::AuthenticatePlayer(void* player, int64_t uid, std::fstream pdataStream(pdataPath, std::ios_base::in); if (pdataStream.fail()) // file doesn't exist, use placeholder - pdataStream = std::fstream(GetNorthstarPrefix() + "/placeholder_playerdata.pdata"); + pdataStream = std::fstream(GetNorthstarPrefix() + "/placeholder_playerdata.pdata", std::ios_base::in); // get file length pdataStream.seekg(0, pdataStream.end); @@ -666,7 +666,7 @@ void InitialiseServerAuthentication(HMODULE baseAddress) new ConVar("net_chan_limit_mode", "0", FCVAR_GAMEDLL, "The mode for netchan processing limits: 0 = log, 1 = kick"); Cvar_net_chan_limit_msec_per_sec = new ConVar( "net_chan_limit_msec_per_sec", - "0", + "100", FCVAR_GAMEDLL, "Netchannel processing is limited to so many milliseconds, abort connection if exceeding budget"); Cvar_ns_player_auth_port = new ConVar("ns_player_auth_port", "8081", FCVAR_GAMEDLL, ""); |