aboutsummaryrefslogtreecommitdiff
path: root/NorthstarDedicatedTest
diff options
context:
space:
mode:
Diffstat (limited to 'NorthstarDedicatedTest')
-rw-r--r--NorthstarDedicatedTest/ExploitFixes.cpp41
-rw-r--r--NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj2
-rw-r--r--NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters6
-rw-r--r--NorthstarDedicatedTest/dllmain.cpp3
-rw-r--r--NorthstarDedicatedTest/emit_blocker.cpp26
-rw-r--r--NorthstarDedicatedTest/emit_blocker.h3
-rw-r--r--NorthstarDedicatedTest/latencyflex.cpp50
-rw-r--r--NorthstarDedicatedTest/masterserver.cpp42
-rw-r--r--NorthstarDedicatedTest/masterserver.h2
-rw-r--r--NorthstarDedicatedTest/miscserverfixes.cpp106
-rw-r--r--NorthstarDedicatedTest/miscserverfixes.h3
-rw-r--r--NorthstarDedicatedTest/miscserverscript.cpp10
-rw-r--r--NorthstarDedicatedTest/scriptserverbrowser.cpp9
-rw-r--r--NorthstarDedicatedTest/serverauthentication.cpp4
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, "");