aboutsummaryrefslogtreecommitdiff
path: root/NorthstarDedicatedTest
diff options
context:
space:
mode:
Diffstat (limited to 'NorthstarDedicatedTest')
-rw-r--r--NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj3
-rw-r--r--NorthstarDedicatedTest/dedicated.cpp19
-rw-r--r--NorthstarDedicatedTest/hooks.cpp4
-rw-r--r--NorthstarDedicatedTest/languagehooks.cpp8
-rw-r--r--NorthstarDedicatedTest/masterserver.cpp60
-rw-r--r--NorthstarDedicatedTest/masterserver.h8
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;