diff options
Diffstat (limited to 'NorthstarDedicatedTest')
-rw-r--r-- | NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/dedicated.cpp | 19 | ||||
-rw-r--r-- | NorthstarDedicatedTest/hooks.cpp | 4 | ||||
-rw-r--r-- | NorthstarDedicatedTest/languagehooks.cpp | 8 | ||||
-rw-r--r-- | NorthstarDedicatedTest/masterserver.cpp | 60 | ||||
-rw-r--r-- | NorthstarDedicatedTest/masterserver.h | 8 |
6 files changed, 86 insertions, 16 deletions
diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj index 93b35e5c..8aa300c8 100644 --- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj +++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj @@ -627,9 +627,6 @@ <ItemGroup> <MASM Include="audio_asm.asm" /> </ItemGroup> - <ItemGroup> - <None Include="..\Northstar-Legal.txt" CopyToOutputDirectory="PreserveNewest" /> - </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" /> diff --git a/NorthstarDedicatedTest/dedicated.cpp b/NorthstarDedicatedTest/dedicated.cpp index e6115415..e140281a 100644 --- a/NorthstarDedicatedTest/dedicated.cpp +++ b/NorthstarDedicatedTest/dedicated.cpp @@ -3,7 +3,7 @@ #include "hookutils.h" #include "gameutils.h" #include "serverauthentication.h" - +#include "masterserver.h" bool IsDedicated() { //return CommandLine()->CheckParm("-dedicated"); @@ -58,17 +58,24 @@ void RunServer(CDedicatedExports* dedicated) // note: we no longer manually set map and hoststate to start server in g_pHostState, we just use +map which seems to initialise stuff better // main loop + double frameTitle = 0; while (g_pEngine->m_nQuitting == EngineQuitState::QUIT_NOTQUITTING) { double frameStart = Plat_FloatTime(); g_pEngine->Frame(); - // this way of getting playercount/maxplayers honestly really sucks, but not got any other methods of doing it rn - const char* maxPlayers = GetCurrentPlaylistVar("max_players", false); - if (!maxPlayers) - maxPlayers = "6"; + // only update the title after at least 500ms since the last update + if ((frameStart - frameTitle) > 0.5) { + frameTitle = frameStart; + + // this way of getting playercount/maxplayers honestly really sucks, but not got any other methods of doing it rn + const char* maxPlayers = GetCurrentPlaylistVar("max_players", false); + if (!maxPlayers) + maxPlayers = "6"; + + SetConsoleTitleA(fmt::format("{} - {} {}/{} players ({})", g_MasterServerManager->ns_auth_srvName, g_pHostState->m_levelName, g_ServerAuthenticationManager->m_additionalPlayerData.size(), maxPlayers, GetCurrentPlaylistName()).c_str()); + } - SetConsoleTitleA(fmt::format("Titanfall 2 dedicated server - {} {}/{} players ({})", g_pHostState->m_levelName, g_ServerAuthenticationManager->m_additionalPlayerData.size(), maxPlayers, GetCurrentPlaylistName()).c_str()); std::this_thread::sleep_for(std::chrono::duration<double, std::ratio<1>>(Cvar_base_tickinterval_mp->m_fValue - fmin(Plat_FloatTime() - frameStart, 0.25))); } } diff --git a/NorthstarDedicatedTest/hooks.cpp b/NorthstarDedicatedTest/hooks.cpp index ce4d75ad..cdb5fef9 100644 --- a/NorthstarDedicatedTest/hooks.cpp +++ b/NorthstarDedicatedTest/hooks.cpp @@ -73,6 +73,10 @@ LPSTR GetCommandLineAHook() argBuffer << cmdlineArgFile.rdbuf(); cmdlineArgFile.close(); + // if some other command line option includes "-northstar" in the future then you have to refactor this check to check with both either space after or ending with + if (!isDedi && argBuffer.str().find("-northstar") != std::string::npos) + MessageBoxA(NULL, "The \"-northstar\" command line option is NOT supposed to go into ns_startup_args.txt file!\n\nThis option is supposed to go into Origin/Steam game launch options, and then you are supposed to launch the original Titanfall2.exe rather than NorthstarLauncher.exe to make use of it.", "Northstar Warning", MB_ICONWARNING); + args.append(argBuffer.str()); } diff --git a/NorthstarDedicatedTest/languagehooks.cpp b/NorthstarDedicatedTest/languagehooks.cpp index 0929b73d..3a69df9d 100644 --- a/NorthstarDedicatedTest/languagehooks.cpp +++ b/NorthstarDedicatedTest/languagehooks.cpp @@ -26,6 +26,9 @@ std::vector<std::string> file_list(fs::path dir, std::regex ext_pattern) { std::vector<std::string> result; + if (!fs::exists(dir) || !fs::is_directory(dir)) + return result; + using iterator = fs::directory_iterator; const iterator end; @@ -77,7 +80,8 @@ char* GetGameLanguageHook() auto lang = GetGameLanguageOriginal(); if (!CheckLangAudioExists(lang)) { - spdlog::info("Origin detected language \"{}\", but we do not have audio for it installed, falling back to the next option", lang); + if (strcmp(lang, "russian") != 0) // don't log for "russian" since it's the default and that means Origin detection just didn't change it most likely + spdlog::info("Origin detected language \"{}\", but we do not have audio for it installed, falling back to the next option", lang); } else @@ -95,7 +99,7 @@ char* GetGameLanguageHook() { spdlog::warn("Caution, audio for this language does NOT exist. You might want to override your game language with -language command line option."); auto lang = GetAnyInstalledAudioLanguage(); - spdlog::warn("Falling back to first installed audio language: {}", lang.c_str()); + spdlog::warn("Falling back to the first installed audio language: {}", lang.c_str()); strncpy(ingameLang1, lang.c_str(), 256); return ingameLang1; } diff --git a/NorthstarDedicatedTest/masterserver.cpp b/NorthstarDedicatedTest/masterserver.cpp index c040a239..c61c69e5 100644 --- a/NorthstarDedicatedTest/masterserver.cpp +++ b/NorthstarDedicatedTest/masterserver.cpp @@ -11,7 +11,8 @@ #include "rapidjson/error/en.h" #include "modmanager.h" #include "misccommands.h" - +#include <cstring> +#include <regex> // 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 @@ -40,6 +41,57 @@ CHostState__State_ChangeLevelSPType CHostState__State_ChangeLevelSP; typedef void(*CHostState__State_GameShutdownType)(CHostState* hostState); CHostState__State_GameShutdownType CHostState__State_GameShutdown; +// Convert a hex digit char to integer. +inline int hctod(char c) { + if (c >= 'A' && c <= 'F') { + return c - 'A' + 10; + } + else if (c >= 'a' && c <= 'f') { + return c - 'a' + 10; + } + else { + return c - '0'; + } +} + +// This function interprets all 4-hexadecimal-digit unicode codepoint characters like \u4E2D to UTF-8 encoding. +std::string unescape_unicode(const std::string &str) { + std::string result; + std::regex r("\\\\u([a-f\\d]{4})", std::regex::icase); + auto matches_begin = std::sregex_iterator(str.begin(), str.end(), r); + auto matches_end = std::sregex_iterator(); + std::smatch last_match; + for (std::sregex_iterator i = matches_begin; i != matches_end; ++i) { + last_match = *i; + result.append(last_match.prefix()); + unsigned int cp = 0; + for (int i = 2; i <= 5; ++i) { + cp *= 16; + cp += hctod(last_match.str()[i]); + } + if (cp <= 0x7F) { + result.push_back(cp); + } + else if (cp <= 0x7FF) { + result.push_back((cp >> 6) | 0b11000000 & (~(1 << 5))); + result.push_back(cp & ((1 << 6) - 1) | 0b10000000 & (~(1 << 6))); + } + else if (cp <= 0xFFFF) { + result.push_back((cp >> 12) | 0b11100000 & (~(1 << 4))); + result.push_back((cp >> 6) & ((1 << 6) - 1) | 0b10000000 & (~(1 << 6))); + result.push_back(cp & ((1 << 6) - 1) | 0b10000000 & (~(1 << 6))); + } + } + result.append(last_match.suffix()); + return result; +} + +void UpdateServerInfoFromUnicodeToUTF8() +{ + g_MasterServerManager->ns_auth_srvName = unescape_unicode(Cvar_ns_server_name->m_pszString); + g_MasterServerManager->ns_auth_srvDesc = unescape_unicode(Cvar_ns_server_desc->m_pszString); +} + const char* HttplibErrorToString(httplib::Error error) { switch (error) @@ -786,8 +838,8 @@ void MasterServerManager::AddSelfToServerList(int port, int authPort, char* name // send all registration info so we have all necessary info to reregister our server if masterserver goes down, without a restart // this isn't threadsafe :terror: { - char* escapedNameNew = curl_easy_escape(curl, Cvar_ns_server_name->m_pszString, NULL); - char* escapedDescNew = curl_easy_escape(curl, Cvar_ns_server_desc->m_pszString, NULL); + char* escapedNameNew = curl_easy_escape(curl, g_MasterServerManager->ns_auth_srvName.c_str(), NULL); + char* escapedDescNew = curl_easy_escape(curl, g_MasterServerManager->ns_auth_srvDesc.c_str(), NULL); char* escapedMapNew = curl_easy_escape(curl, g_pHostState->m_levelName, NULL); char* escapedPlaylistNew = curl_easy_escape(curl, GetCurrentPlaylistName(), NULL); char* escapedPasswordNew = curl_easy_escape(curl, Cvar_ns_server_password->m_pszString, NULL); @@ -1044,6 +1096,8 @@ void CHostState__State_NewGameHook(CHostState* hostState) // Copy new server name cvar to source Cvar_hostname->m_pszString = Cvar_ns_server_name->m_pszString; Cvar_hostname->m_StringLength = Cvar_ns_server_name->m_StringLength; + // This calls the function that converts unicode strings from servername and serverdesc to UTF-8 + UpdateServerInfoFromUnicodeToUTF8(); g_MasterServerManager->AddSelfToServerList(Cvar_hostport->m_nValue, Cvar_ns_player_auth_port->m_nValue, Cvar_ns_server_name->m_pszString, Cvar_ns_server_desc->m_pszString, hostState->m_levelName, (char*)GetCurrentPlaylistName(), maxPlayers, Cvar_ns_server_password->m_pszString); g_ServerAuthenticationManager->StartPlayerAuthServer(); diff --git a/NorthstarDedicatedTest/masterserver.h b/NorthstarDedicatedTest/masterserver.h index d7071b6c..2e7468b4 100644 --- a/NorthstarDedicatedTest/masterserver.h +++ b/NorthstarDedicatedTest/masterserver.h @@ -1,7 +1,8 @@ #pragma once #include "convar.h" #include <WinSock2.h> - +#include <string> +#include <cstring> struct RemoteModInfo { public: @@ -73,6 +74,8 @@ public: char m_ownClientAuthToken[33]; std::string m_ownModInfoJson; + std::string ns_auth_srvName; // Unicode unescaped version of Cvar_ns_auth_servername for support in cjk characters + std::string ns_auth_srvDesc; // Unicode unescaped version of Cvar_ns_auth_serverdesc for support in cjk characters bool m_bOriginAuthWithMasterServerDone = false; bool m_bOriginAuthWithMasterServerInProgress = false; @@ -112,7 +115,8 @@ public: void WritePlayerPersistentData(char* playerId, char* pdata, size_t pdataSize); void RemoveSelfFromServerList(); }; - +std::string unescape_unicode(const std::string &str); +void UpdateServerInfoFromUnicodeToUTF8(); void InitialiseSharedMasterServer(HMODULE baseAddress); extern MasterServerManager* g_MasterServerManager; |