aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNorthstar <northstar@northstar.tf>2022-02-03 22:09:08 -0300
committerBarichello <artur@barichello.me>2022-02-03 22:09:08 -0300
commit75bf194b2fca06de805a7bc025c6dd8379250fa5 (patch)
treec9327ac7921ae80bb2d91381bb7db11b47ca2403
parente9f93ba2e8b9df280aed20131a1606d731d2dbbe (diff)
downloadNorthstarLauncher-75bf194b2fca06de805a7bc025c6dd8379250fa5.tar.gz
NorthstarLauncher-75bf194b2fca06de805a7bc025c6dd8379250fa5.zip
Format project
-rw-r--r--LauncherInjector/main.cpp430
-rw-r--r--LauncherInjector/resource1.h12
-rw-r--r--NorthstarDedicatedTest/audio.cpp102
-rw-r--r--NorthstarDedicatedTest/audio.h9
-rw-r--r--NorthstarDedicatedTest/bansystem.cpp7
-rw-r--r--NorthstarDedicatedTest/bansystem.h4
-rw-r--r--NorthstarDedicatedTest/bitbuf.h2017
-rw-r--r--NorthstarDedicatedTest/buildainfile.cpp55
-rw-r--r--NorthstarDedicatedTest/chatcommand.cpp2
-rw-r--r--NorthstarDedicatedTest/clientauthhooks.cpp9
-rw-r--r--NorthstarDedicatedTest/concommand.cpp10
-rw-r--r--NorthstarDedicatedTest/concommand.h111
-rw-r--r--NorthstarDedicatedTest/configurables.cpp55
-rw-r--r--NorthstarDedicatedTest/context.cpp2
-rw-r--r--NorthstarDedicatedTest/convar.cpp12
-rw-r--r--NorthstarDedicatedTest/convar.h140
-rw-r--r--NorthstarDedicatedTest/dedicated.cpp59
-rw-r--r--NorthstarDedicatedTest/dedicatedmaterialsystem.cpp28
-rw-r--r--NorthstarDedicatedTest/dllmain.cpp213
-rw-r--r--NorthstarDedicatedTest/filesystem.cpp23
-rw-r--r--NorthstarDedicatedTest/filesystem.h77
-rw-r--r--NorthstarDedicatedTest/gameutils.h93
-rw-r--r--NorthstarDedicatedTest/hooks.cpp29
-rw-r--r--NorthstarDedicatedTest/hooks.h2
-rw-r--r--NorthstarDedicatedTest/hookutils.cpp81
-rw-r--r--NorthstarDedicatedTest/hookutils.h32
-rw-r--r--NorthstarDedicatedTest/keyvalues.cpp22
-rw-r--r--NorthstarDedicatedTest/languagehooks.cpp26
-rw-r--r--NorthstarDedicatedTest/latencyflex.cpp5
-rw-r--r--NorthstarDedicatedTest/logging.cpp189
-rw-r--r--NorthstarDedicatedTest/masterserver.cpp397
-rw-r--r--NorthstarDedicatedTest/masterserver.h27
-rw-r--r--NorthstarDedicatedTest/maxplayers.cpp102
-rw-r--r--NorthstarDedicatedTest/memalloc.cpp11
-rw-r--r--NorthstarDedicatedTest/memalloc.h52
-rw-r--r--NorthstarDedicatedTest/miscclientfixes.cpp15
-rw-r--r--NorthstarDedicatedTest/misccommands.cpp16
-rw-r--r--NorthstarDedicatedTest/miscserverfixes.cpp2
-rw-r--r--NorthstarDedicatedTest/miscserverscript.cpp5
-rw-r--r--NorthstarDedicatedTest/modlocalisation.cpp2
-rw-r--r--NorthstarDedicatedTest/modmanager.cpp69
-rw-r--r--NorthstarDedicatedTest/modmanager.h20
-rw-r--r--NorthstarDedicatedTest/pch.h4
-rw-r--r--NorthstarDedicatedTest/pdef.cpp5
-rw-r--r--NorthstarDedicatedTest/playlist.cpp32
-rw-r--r--NorthstarDedicatedTest/rpakfilesystem.cpp11
-rw-r--r--NorthstarDedicatedTest/scriptbrowserhooks.cpp5
-rw-r--r--NorthstarDedicatedTest/scriptmainmenupromos.cpp160
-rw-r--r--NorthstarDedicatedTest/scriptmodmenu.cpp27
-rw-r--r--NorthstarDedicatedTest/scriptserverbrowser.cpp114
-rw-r--r--NorthstarDedicatedTest/scriptsrson.cpp4
-rw-r--r--NorthstarDedicatedTest/securitypatches.cpp6
-rw-r--r--NorthstarDedicatedTest/serverauthentication.cpp166
-rw-r--r--NorthstarDedicatedTest/serverauthentication.h42
-rw-r--r--NorthstarDedicatedTest/sourceconsole.cpp10
-rw-r--r--NorthstarDedicatedTest/sourceconsole.h117
-rw-r--r--NorthstarDedicatedTest/sourceinterface.cpp16
-rw-r--r--NorthstarDedicatedTest/sourceinterface.h36
-rw-r--r--NorthstarDedicatedTest/squirrel.cpp109
-rw-r--r--NorthstarDedicatedTest/squirrel.h50
60 files changed, 2934 insertions, 2554 deletions
diff --git a/LauncherInjector/main.cpp b/LauncherInjector/main.cpp
index a5d70f76..a52b71fe 100644
--- a/LauncherInjector/main.cpp
+++ b/LauncherInjector/main.cpp
@@ -8,9 +8,10 @@
namespace fs = std::filesystem;
-extern "C" {
- __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
- __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
+extern "C"
+{
+ __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
+ __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}
HMODULE hLauncherModule;
@@ -22,231 +23,272 @@ wchar_t buffer[8192];
DWORD GetProcessByName(std::wstring processName)
{
- HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- PROCESSENTRY32 processSnapshotEntry = { 0 };
- processSnapshotEntry.dwSize = sizeof(PROCESSENTRY32);
+ PROCESSENTRY32 processSnapshotEntry = {0};
+ processSnapshotEntry.dwSize = sizeof(PROCESSENTRY32);
- if (snapshot == INVALID_HANDLE_VALUE)
- return 0;
+ if (snapshot == INVALID_HANDLE_VALUE)
+ return 0;
- if (!Process32First(snapshot, &processSnapshotEntry))
- return 0;
+ if (!Process32First(snapshot, &processSnapshotEntry))
+ return 0;
- while (Process32Next(snapshot, &processSnapshotEntry))
- {
- if (!wcscmp(processSnapshotEntry.szExeFile, processName.c_str()))
- {
- CloseHandle(snapshot);
- return processSnapshotEntry.th32ProcessID;
- }
- }
+ while (Process32Next(snapshot, &processSnapshotEntry))
+ {
+ if (!wcscmp(processSnapshotEntry.szExeFile, processName.c_str()))
+ {
+ CloseHandle(snapshot);
+ return processSnapshotEntry.th32ProcessID;
+ }
+ }
- CloseHandle(snapshot);
- return 0;
+ CloseHandle(snapshot);
+ return 0;
}
bool GetExePathWide(wchar_t* dest, DWORD destSize)
{
- if (!dest) return NULL;
- if (destSize < MAX_PATH) return NULL;
+ if (!dest)
+ return NULL;
+ if (destSize < MAX_PATH)
+ return NULL;
- DWORD length = GetModuleFileNameW(NULL, dest, destSize);
- return length && PathRemoveFileSpecW(dest);
+ DWORD length = GetModuleFileNameW(NULL, dest, destSize);
+ return length && PathRemoveFileSpecW(dest);
}
FARPROC GetLauncherMain()
{
- static FARPROC Launcher_LauncherMain;
- if (!Launcher_LauncherMain)
- Launcher_LauncherMain = GetProcAddress(hLauncherModule, "LauncherMain");
- return Launcher_LauncherMain;
+ static FARPROC Launcher_LauncherMain;
+ if (!Launcher_LauncherMain)
+ Launcher_LauncherMain = GetProcAddress(hLauncherModule, "LauncherMain");
+ return Launcher_LauncherMain;
}
void LibraryLoadError(DWORD dwMessageId, const wchar_t* libName, const wchar_t* location)
{
- char text[8192];
- std::string message = std::system_category().message(dwMessageId);
-
- sprintf_s(text, "Failed to load the %ls at \"%ls\" (%lu):\n\n%hs\n\nMake sure you followed the Northstar installation instructions carefully before reaching out for help.", libName, location, dwMessageId, message.c_str());
-
- if (dwMessageId == 126 && std::filesystem::exists(location))
- {
- sprintf_s(text, "%s\n\nThe file at the specified location DOES exist, so this error indicates that one of its *dependencies* failed to be found.\n\nTry the following steps:\n1. Install Visual C++ 2022 Redistributable: https://aka.ms/vs/17/release/vc_redist.x64.exe\n2. Repair game files", text);
- }
- else if (!fs::exists("Titanfall2.exe") && (fs::exists("..\\Titanfall2.exe") || fs::exists("..\\..\\Titanfall2.exe")))
- {
- auto curDir = std::filesystem::current_path().filename().string();
- auto aboveDir = std::filesystem::current_path().parent_path().filename().string();
- sprintf_s(text, "%s\n\nWe detected that in your case you have extracted the files into a *subdirectory* of your Titanfall 2 installation.\nPlease move all the files and folders from current folder (\"%s\") into the Titanfall 2 installation directory just above (\"%s\").\n\nPlease try out the above steps by yourself before reaching out to the community for support.", text, curDir.c_str(), aboveDir.c_str());
- }
- else if (!fs::exists("Titanfall2.exe"))
- {
- sprintf_s(text, "%s\n\nRemember: you need to unpack the contents of this archive into your Titanfall 2 game installation directory, not just to any random folder.", text);
- }
- else if (fs::exists("Titanfall2.exe"))
- {
- sprintf_s(text, "%s\n\nTitanfall2.exe has been found in the current directory: is the game installation corrupted or did you not unpack all Northstar files here?", text);
- }
-
- MessageBoxA(GetForegroundWindow(), text, "Northstar Launcher Error", 0);
+ char text[8192];
+ std::string message = std::system_category().message(dwMessageId);
+
+ sprintf_s(
+ text,
+ "Failed to load the %ls at \"%ls\" (%lu):\n\n%hs\n\nMake sure you followed the Northstar installation instructions carefully "
+ "before reaching out for help.",
+ libName, location, dwMessageId, message.c_str());
+
+ if (dwMessageId == 126 && std::filesystem::exists(location))
+ {
+ sprintf_s(
+ text,
+ "%s\n\nThe file at the specified location DOES exist, so this error indicates that one of its *dependencies* failed to be "
+ "found.\n\nTry the following steps:\n1. Install Visual C++ 2022 Redistributable: "
+ "https://aka.ms/vs/17/release/vc_redist.x64.exe\n2. Repair game files",
+ text);
+ }
+ else if (!fs::exists("Titanfall2.exe") && (fs::exists("..\\Titanfall2.exe") || fs::exists("..\\..\\Titanfall2.exe")))
+ {
+ auto curDir = std::filesystem::current_path().filename().string();
+ auto aboveDir = std::filesystem::current_path().parent_path().filename().string();
+ sprintf_s(
+ text,
+ "%s\n\nWe detected that in your case you have extracted the files into a *subdirectory* of your Titanfall 2 "
+ "installation.\nPlease move all the files and folders from current folder (\"%s\") into the Titanfall 2 installation directory "
+ "just above (\"%s\").\n\nPlease try out the above steps by yourself before reaching out to the community for support.",
+ text, curDir.c_str(), aboveDir.c_str());
+ }
+ else if (!fs::exists("Titanfall2.exe"))
+ {
+ sprintf_s(
+ text,
+ "%s\n\nRemember: you need to unpack the contents of this archive into your Titanfall 2 game installation directory, not just "
+ "to any random folder.",
+ text);
+ }
+ else if (fs::exists("Titanfall2.exe"))
+ {
+ sprintf_s(
+ text,
+ "%s\n\nTitanfall2.exe has been found in the current directory: is the game installation corrupted or did you not unpack all "
+ "Northstar files here?",
+ text);
+ }
+
+ MessageBoxA(GetForegroundWindow(), text, "Northstar Launcher Error", 0);
}
void EnsureOriginStarted()
{
- if (GetProcessByName(L"Origin.exe") || GetProcessByName(L"EADesktop.exe"))
- return; // already started
-
- // unpacked exe will crash if origin isn't open on launch, so launch it
- // get origin path from registry, code here is reversed from OriginSDK.dll
- HKEY key;
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\WOW6432Node\\Origin", 0, KEY_READ, &key) != ERROR_SUCCESS)
- {
- MessageBoxA(0, "Error: failed reading Origin path!", "Northstar Launcher Error", MB_OK);
- return;
- }
-
- char originPath[520];
- DWORD originPathLength = 520;
- if (RegQueryValueExA(key, "ClientPath", 0, 0, (LPBYTE)&originPath, &originPathLength) != ERROR_SUCCESS)
- {
- MessageBoxA(0, "Error: failed reading Origin path!", "Northstar Launcher Error", MB_OK);
- return;
- }
-
- PROCESS_INFORMATION pi;
- memset(&pi, 0, sizeof(pi));
- STARTUPINFO si;
- memset(&si, 0, sizeof(si));
- CreateProcessA(originPath, (char*)"", NULL, NULL, false, CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_PROCESS_GROUP, NULL, NULL, (LPSTARTUPINFOA)&si, &pi);
-
- printf("[*] Waiting for Origin...\n");
-
- // wait for origin to be ready, this process is created when origin is ready enough to launch game without any errors
- while (!GetProcessByName(L"OriginClientService.exe") && !GetProcessByName(L"EADesktop.exe"))
- Sleep(200);
-
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ if (GetProcessByName(L"Origin.exe") || GetProcessByName(L"EADesktop.exe"))
+ return; // already started
+
+ // unpacked exe will crash if origin isn't open on launch, so launch it
+ // get origin path from registry, code here is reversed from OriginSDK.dll
+ HKEY key;
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\WOW6432Node\\Origin", 0, KEY_READ, &key) != ERROR_SUCCESS)
+ {
+ MessageBoxA(0, "Error: failed reading Origin path!", "Northstar Launcher Error", MB_OK);
+ return;
+ }
+
+ char originPath[520];
+ DWORD originPathLength = 520;
+ if (RegQueryValueExA(key, "ClientPath", 0, 0, (LPBYTE)&originPath, &originPathLength) != ERROR_SUCCESS)
+ {
+ MessageBoxA(0, "Error: failed reading Origin path!", "Northstar Launcher Error", MB_OK);
+ return;
+ }
+
+ PROCESS_INFORMATION pi;
+ memset(&pi, 0, sizeof(pi));
+ STARTUPINFO si;
+ memset(&si, 0, sizeof(si));
+ CreateProcessA(
+ originPath, (char*)"", NULL, NULL, false, CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_PROCESS_GROUP, NULL, NULL, (LPSTARTUPINFOA)&si,
+ &pi);
+
+ printf("[*] Waiting for Origin...\n");
+
+ // wait for origin to be ready, this process is created when origin is ready enough to launch game without any errors
+ while (!GetProcessByName(L"OriginClientService.exe") && !GetProcessByName(L"EADesktop.exe"))
+ Sleep(200);
+
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
}
void PrependPath()
{
- wchar_t* pPath;
- size_t len;
- errno_t err = _wdupenv_s(&pPath, &len, L"PATH");
- if (!err)
- {
- swprintf_s(buffer, L"PATH=%s\\bin\\x64_retail\\;%s", exePath, pPath);
- auto result = _wputenv(buffer);
- if (result == -1)
- {
- MessageBoxW(GetForegroundWindow(), L"Warning: could not prepend the current directory to app's PATH environment variable. Something may break because of that.", L"Northstar Launcher Warning", 0);
- }
- free(pPath);
- }
- else
- {
- MessageBoxW(GetForegroundWindow(), L"Warning: could not get current PATH environment variable in order to prepend the current directory to it. Something may break because of that.", L"Northstar Launcher Warning", 0);
- }
+ wchar_t* pPath;
+ size_t len;
+ errno_t err = _wdupenv_s(&pPath, &len, L"PATH");
+ if (!err)
+ {
+ swprintf_s(buffer, L"PATH=%s\\bin\\x64_retail\\;%s", exePath, pPath);
+ auto result = _wputenv(buffer);
+ if (result == -1)
+ {
+ MessageBoxW(
+ GetForegroundWindow(),
+ L"Warning: could not prepend the current directory to app's PATH environment variable. Something may break because of "
+ L"that.",
+ L"Northstar Launcher Warning", 0);
+ }
+ free(pPath);
+ }
+ else
+ {
+ MessageBoxW(
+ GetForegroundWindow(),
+ L"Warning: could not get current PATH environment variable in order to prepend the current directory to it. Something may "
+ L"break because of that.",
+ L"Northstar Launcher Warning", 0);
+ }
}
bool ShouldLoadNorthstar(int argc, char* argv[])
{
- bool loadNorthstar = true;
- for (int i = 0; i < argc; i++)
- if (!strcmp(argv[i], "-vanilla"))
- loadNorthstar = false;
-
- if (!loadNorthstar)
- return loadNorthstar;
-
- auto runNorthstarFile = std::ifstream("run_northstar.txt");
- if (runNorthstarFile)
- {
- std::stringstream runNorthstarFileBuffer;
- runNorthstarFileBuffer << runNorthstarFile.rdbuf();
- runNorthstarFile.close();
- if (runNorthstarFileBuffer.str()._Starts_with("0"))
- loadNorthstar = false;
- }
- return loadNorthstar;
+ bool loadNorthstar = true;
+ for (int i = 0; i < argc; i++)
+ if (!strcmp(argv[i], "-vanilla"))
+ loadNorthstar = false;
+
+ if (!loadNorthstar)
+ return loadNorthstar;
+
+ auto runNorthstarFile = std::ifstream("run_northstar.txt");
+ if (runNorthstarFile)
+ {
+ std::stringstream runNorthstarFileBuffer;
+ runNorthstarFileBuffer << runNorthstarFile.rdbuf();
+ runNorthstarFile.close();
+ if (runNorthstarFileBuffer.str()._Starts_with("0"))
+ loadNorthstar = false;
+ }
+ return loadNorthstar;
}
bool LoadNorthstar()
{
- FARPROC Hook_Init = nullptr;
- {
- swprintf_s(buffer, L"%s\\Northstar.dll", exePath);
- hHookModule = LoadLibraryExW(buffer, 0i64, 8u);
- if (hHookModule) Hook_Init = GetProcAddress(hHookModule, "InitialiseNorthstar");
- if (!hHookModule || Hook_Init == nullptr)
- {
- LibraryLoadError(GetLastError(), L"Northstar.dll", buffer);
- return false;
- }
- }
-
- ((bool (*)()) Hook_Init)();
- return true;
+ FARPROC Hook_Init = nullptr;
+ {
+ swprintf_s(buffer, L"%s\\Northstar.dll", exePath);
+ hHookModule = LoadLibraryExW(buffer, 0i64, 8u);
+ if (hHookModule)
+ Hook_Init = GetProcAddress(hHookModule, "InitialiseNorthstar");
+ if (!hHookModule || Hook_Init == nullptr)
+ {
+ LibraryLoadError(GetLastError(), L"Northstar.dll", buffer);
+ return false;
+ }
+ }
+
+ ((bool (*)())Hook_Init)();
+ return true;
}
-int main(int argc, char* argv[]) {
-
- // checked to avoid starting origin, Northstar.dll will check for -dedicated as well on its own
- bool noOriginStartup = false;
- for (int i = 0; i < argc; i++)
- if (!strcmp(argv[i], "-noOriginStartup") || !strcmp(argv[i], "-dedicated"))
- noOriginStartup = true;
-
- if (!noOriginStartup)
- {
- EnsureOriginStarted();
- }
-
- {
- if (!GetExePathWide(exePath, sizeof(exePath)))
- {
- MessageBoxA(GetForegroundWindow(), "Failed getting game directory.\nThe game cannot continue and has to exit.", "Northstar Launcher Error", 0);
- return 1;
- }
-
- PrependPath();
-
- printf("[*] Loading tier0.dll\n");
- swprintf_s(buffer, L"%s\\bin\\x64_retail\\tier0.dll", exePath);
- hTier0Module = LoadLibraryExW(buffer, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
- if (!hTier0Module)
- {
- LibraryLoadError(GetLastError(), L"tier0.dll", buffer);
- return 1;
- }
-
- bool loadNorthstar = ShouldLoadNorthstar(argc, argv);
- if (loadNorthstar)
- {
- printf("[*] Loading Northstar\n");
- if (!LoadNorthstar())
- return 1;
- }
- else
- printf("[*] Going to load the vanilla game\n");
-
- printf("[*] Loading launcher.dll\n");
- swprintf_s(buffer, L"%s\\bin\\x64_retail\\launcher.dll", exePath);
- hLauncherModule = LoadLibraryExW(buffer, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
- if (!hLauncherModule)
- {
- LibraryLoadError(GetLastError(), L"launcher.dll", buffer);
- return 1;
- }
- }
-
- printf("[*] Launching the game...\n");
- auto LauncherMain = GetLauncherMain();
- if (!LauncherMain)
- MessageBoxA(GetForegroundWindow(), "Failed loading launcher.dll.\nThe game cannot continue and has to exit.", "Northstar Launcher Error", 0);
- //auto result = ((__int64(__fastcall*)())LauncherMain)();
- //auto result = ((signed __int64(__fastcall*)(__int64))LauncherMain)(0i64);
- return ((int(/*__fastcall*/*)(HINSTANCE, HINSTANCE, LPSTR, int))LauncherMain)(NULL, NULL, NULL, 0); // the parameters aren't really used anyways
+int main(int argc, char* argv[])
+{
+
+ // checked to avoid starting origin, Northstar.dll will check for -dedicated as well on its own
+ bool noOriginStartup = false;
+ for (int i = 0; i < argc; i++)
+ if (!strcmp(argv[i], "-noOriginStartup") || !strcmp(argv[i], "-dedicated"))
+ noOriginStartup = true;
+
+ if (!noOriginStartup)
+ {
+ EnsureOriginStarted();
+ }
+
+ {
+ if (!GetExePathWide(exePath, sizeof(exePath)))
+ {
+ MessageBoxA(
+ GetForegroundWindow(), "Failed getting game directory.\nThe game cannot continue and has to exit.",
+ "Northstar Launcher Error", 0);
+ return 1;
+ }
+
+ PrependPath();
+
+ printf("[*] Loading tier0.dll\n");
+ swprintf_s(buffer, L"%s\\bin\\x64_retail\\tier0.dll", exePath);
+ hTier0Module = LoadLibraryExW(buffer, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
+ if (!hTier0Module)
+ {
+ LibraryLoadError(GetLastError(), L"tier0.dll", buffer);
+ return 1;
+ }
+
+ bool loadNorthstar = ShouldLoadNorthstar(argc, argv);
+ if (loadNorthstar)
+ {
+ printf("[*] Loading Northstar\n");
+ if (!LoadNorthstar())
+ return 1;
+ }
+ else
+ printf("[*] Going to load the vanilla game\n");
+
+ printf("[*] Loading launcher.dll\n");
+ swprintf_s(buffer, L"%s\\bin\\x64_retail\\launcher.dll", exePath);
+ hLauncherModule = LoadLibraryExW(buffer, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
+ if (!hLauncherModule)
+ {
+ LibraryLoadError(GetLastError(), L"launcher.dll", buffer);
+ return 1;
+ }
+ }
+
+ printf("[*] Launching the game...\n");
+ auto LauncherMain = GetLauncherMain();
+ if (!LauncherMain)
+ MessageBoxA(
+ GetForegroundWindow(), "Failed loading launcher.dll.\nThe game cannot continue and has to exit.", "Northstar Launcher Error",
+ 0);
+ // auto result = ((__int64(__fastcall*)())LauncherMain)();
+ // auto result = ((signed __int64(__fastcall*)(__int64))LauncherMain)(0i64);
+ return ((int(/*__fastcall*/*)(HINSTANCE, HINSTANCE, LPSTR, int))LauncherMain)(
+ NULL, NULL, NULL, 0); // the parameters aren't really used anyways
} \ No newline at end of file
diff --git a/LauncherInjector/resource1.h b/LauncherInjector/resource1.h
index 60157c4b..bb584502 100644
--- a/LauncherInjector/resource1.h
+++ b/LauncherInjector/resource1.h
@@ -2,15 +2,15 @@
// Microsoft Visual C++ generated include file.
// Used by resources.rc
//
-#define IDI_ICON1 101
+#define IDI_ICON1 101
// Next default values for new objects
-//
+//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 102
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1001
-#define _APS_NEXT_SYMED_VALUE 101
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
diff --git a/NorthstarDedicatedTest/audio.cpp b/NorthstarDedicatedTest/audio.cpp
index f5767386..d6f70255 100644
--- a/NorthstarDedicatedTest/audio.cpp
+++ b/NorthstarDedicatedTest/audio.cpp
@@ -9,7 +9,8 @@
#include <random>
#include "convar.h"
-extern "C" {
+extern "C"
+{
// should be called only in LoadSampleMetadata_Hook
extern void* __fastcall Audio_GetParentEvent();
}
@@ -37,7 +38,10 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa
if (!fs::exists(samplesFolder))
{
- spdlog::error("Failed reading audio override file {}: samples folder doesn't exist; should be named the same as the definition file without JSON extension.", path.string());
+ spdlog::error(
+ "Failed reading audio override file {}: samples folder doesn't exist; should be named the same as the definition file without "
+ "JSON extension.",
+ path.string());
return;
}
@@ -47,7 +51,9 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa
// fail if parse error
if (dataJson.HasParseError())
{
- spdlog::error("Failed reading audio override file {}: encountered parse error \"{}\" at offset {}", path.string(), GetParseError_En(dataJson.GetParseError()), dataJson.GetErrorOffset());
+ spdlog::error(
+ "Failed reading audio override file {}: encountered parse error \"{}\" at offset {}", path.string(),
+ GetParseError_En(dataJson.GetParseError()), dataJson.GetErrorOffset());
return;
}
@@ -72,7 +78,8 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa
{
if (!eventId.IsString())
{
- spdlog::error("Failed reading audio override file {}: EventId array has a value of invalid type, all must be strings", path.string());
+ spdlog::error(
+ "Failed reading audio override file {}: EventId array has a value of invalid type, all must be strings", path.string());
return;
}
@@ -87,7 +94,9 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa
// incorrect type
else
{
- spdlog::error("Failed reading audio override file {}: EventId property is of invalid type (must be a string or an array of strings)", path.string());
+ spdlog::error(
+ "Failed reading audio override file {}: EventId property is of invalid type (must be a string or an array of strings)",
+ path.string());
return;
}
@@ -100,15 +109,20 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa
{
if (!eventId.IsString())
{
- spdlog::error("Failed reading audio override file {}: EventIdRegex array has a value of invalid type, all must be strings", path.string());
+ spdlog::error(
+ "Failed reading audio override file {}: EventIdRegex array has a value of invalid type, all must be strings",
+ path.string());
return;
}
const std::string& regex = eventId.GetString();
- try {
- EventIdsRegex.push_back({ regex, std::regex(regex) });
- } catch (...) {
+ try
+ {
+ EventIdsRegex.push_back({regex, std::regex(regex)});
+ }
+ catch (...)
+ {
spdlog::error("Malformed regex \"{}\" in audio override file {}", regex, path.string());
return;
}
@@ -118,10 +132,12 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa
else if (dataJson["EventIdRegex"].IsString())
{
const std::string& regex = dataJson["EventIdRegex"].GetString();
- try {
- EventIdsRegex.push_back({ regex, std::regex(regex) });
+ try
+ {
+ EventIdsRegex.push_back({regex, std::regex(regex)});
}
- catch (...) {
+ catch (...)
+ {
spdlog::error("Malformed regex \"{}\" in audio override file {}", regex, path.string());
return;
}
@@ -129,7 +145,9 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa
// incorrect type
else
{
- spdlog::error("Failed reading audio override file {}: EventIdRegex property is of invalid type (must be a string or an array of strings)", path.string());
+ spdlog::error(
+ "Failed reading audio override file {}: EventIdRegex property is of invalid type (must be a string or an array of strings)",
+ path.string());
return;
}
}
@@ -154,7 +172,9 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa
}
else
{
- spdlog::error("Failed reading audio override file {}: AudioSelectionStrategy string must be either \"sequential\" or \"random\"", path.string());
+ spdlog::error(
+ "Failed reading audio override file {}: AudioSelectionStrategy string must be either \"sequential\" or \"random\"",
+ path.string());
return;
}
}
@@ -180,11 +200,11 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa
// Allocate enough memory for the file.
uint8_t* data = new uint8_t[fileSize];
-
+
// Read the file.
wavStream.read(data, fileSize);
- Samples.push_back({ fileSize, std::unique_ptr<uint8_t[]>(data) });
+ Samples.push_back({fileSize, std::unique_ptr<uint8_t[]>(data)});
// Close the file.
wavStream.close();
@@ -196,8 +216,8 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa
{
if (!dataJson["EnableOnLoopedSounds"].IsBool())
{
- spdlog::error("Failed reading audio override file {}: EnableOnLoopedSounds property is of invalid type (must be a bool)", path.string());
- return;
+ spdlog::error("Failed reading audio override file {}: EnableOnLoopedSounds property is of invalid type (must be a bool)",
+ path.string()); return;
}
EnableOnLoopedSounds = dataJson["EnableOnLoopedSounds"].GetBool();
@@ -240,13 +260,13 @@ bool CustomAudioManager::TryLoadAudioOverride(const fs::path& defPath)
for (const std::string& eventId : data->EventIds)
{
spdlog::info("Registering sound event {}", eventId);
- m_loadedAudioOverrides.insert({ eventId, data });
+ m_loadedAudioOverrides.insert({eventId, data});
}
for (const auto& eventIdRegexData : data->EventIdsRegex)
{
spdlog::info("Registering sound event regex {}", eventIdRegexData.first);
- m_loadedAudioOverridesRegex.insert({ eventIdRegexData.first, data });
+ m_loadedAudioOverridesRegex.insert({eventIdRegexData.first, data});
}
return true;
@@ -278,22 +298,19 @@ typedef bool (*LoadSampleMetadata_Type)(void* sample, void* audioBuffer, unsigne
LoadSampleMetadata_Type LoadSampleMetadata_Original;
// Empty stereo 48000 WAVE file
-unsigned char EMPTY_WAVE[45] = {
- 0x52, 0x49, 0x46, 0x46, 0x25, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45,
- 0x66, 0x6D, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
- 0x44, 0xAC, 0x00, 0x00, 0x88, 0x58, 0x01, 0x00, 0x02, 0x00, 0x10, 0x00,
- 0x64, 0x61, 0x74, 0x61, 0x74, 0x00, 0x00, 0x00, 0x00
-};
-
-template<typename Iter, typename RandomGenerator>
-Iter select_randomly(Iter start, Iter end, RandomGenerator& g) {
+unsigned char EMPTY_WAVE[45] = {0x52, 0x49, 0x46, 0x46, 0x25, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x44, 0xAC, 0x00, 0x00, 0x88, 0x58,
+ 0x01, 0x00, 0x02, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x74, 0x00, 0x00, 0x00, 0x00};
+
+template <typename Iter, typename RandomGenerator> Iter select_randomly(Iter start, Iter end, RandomGenerator& g)
+{
std::uniform_int_distribution<> dis(0, std::distance(start, end) - 1);
std::advance(start, dis(g));
return start;
}
-template<typename Iter>
-Iter select_randomly(Iter start, Iter end) {
+template <typename Iter> Iter select_randomly(Iter start, Iter end)
+{
static std::random_device rd;
static std::mt19937 gen(rd());
return select_randomly(start, end, gen);
@@ -323,7 +340,8 @@ bool ShouldPlayAudioEvent(const char* eventName, const std::shared_ptr<EventOver
// DO NOT INLINE THIS FUNCTION
// See comment below.
-bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal(uintptr_t parentEvent, void* sample, void* audioBuffer, unsigned int audioBufferLength, int audioType)
+bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal(
+ uintptr_t parentEvent, void* sample, void* audioBuffer, unsigned int audioBufferLength, int audioType)
{
char* eventName = (char*)parentEvent + 0x110;
@@ -357,9 +375,11 @@ bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal(uintptr_t paren
g_CustomAudioManager.m_loadedAudioOverrides[eventName] = overrideData;
}
}
- else overrideData = iter->second;
- }
- else overrideData = iter->second;
+ else
+ overrideData = iter->second;
+ }
+ else
+ overrideData = iter->second;
if (!ShouldPlayAudioEvent(eventName, overrideData))
return LoadSampleMetadata_Original(sample, audioBuffer, audioBufferLength, audioType);
@@ -370,7 +390,7 @@ bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal(uintptr_t paren
if (overrideData->Samples.size() == 0)
{
// 0 samples, turn off this particular event.
-
+
// using a dummy empty wave file
data = EMPTY_WAVE;
dataLength = sizeof(EMPTY_WAVE);
@@ -438,10 +458,7 @@ bool __fastcall LoadSampleMetadata_Hook(void* sample, void* audioBuffer, unsigne
typedef bool (*MilesLog_Type)(int level, const char* string);
MilesLog_Type MilesLog_Original;
-void __fastcall MilesLog_Hook(int level, const char* string)
-{
- spdlog::info("[MSS] {} - {}", level, string);
-}
+void __fastcall MilesLog_Hook(int level, const char* string) { spdlog::info("[MSS] {} - {}", level, string); }
void InitialiseMilesAudioHooks(HMODULE baseAddress)
{
@@ -456,8 +473,9 @@ void InitialiseMilesAudioHooks(HMODULE baseAddress)
return spdlog::error("miles audio not found :terror:");
HookEnabler hook;
-
- ENABLER_CREATEHOOK(hook, (char*)milesAudioBase + 0xF110, &LoadSampleMetadata_Hook, reinterpret_cast<LPVOID*>(&LoadSampleMetadata_Original));
+
+ ENABLER_CREATEHOOK(
+ hook, (char*)milesAudioBase + 0xF110, &LoadSampleMetadata_Hook, reinterpret_cast<LPVOID*>(&LoadSampleMetadata_Original));
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x57DAD0, &MilesLog_Hook, reinterpret_cast<LPVOID*>(&MilesLog_Original));
MilesStopAll = (MilesStopAll_Type)((char*)baseAddress + 0x580850);
diff --git a/NorthstarDedicatedTest/audio.h b/NorthstarDedicatedTest/audio.h
index d53f5317..3220d804 100644
--- a/NorthstarDedicatedTest/audio.h
+++ b/NorthstarDedicatedTest/audio.h
@@ -15,17 +15,18 @@ enum class AudioSelectionStrategy
class EventOverrideData
{
-public:
+ public:
EventOverrideData(const std::string&, const fs::path&);
EventOverrideData();
-public:
+
+ public:
bool LoadedSuccessfully = false;
std::vector<std::string> EventIds = {};
std::vector<std::pair<std::string, std::regex>> EventIdsRegex = {};
std::vector<std::pair<size_t, std::unique_ptr<uint8_t[]>>> Samples = {};
-
+
AudioSelectionStrategy Strategy = AudioSelectionStrategy::SEQUENTIAL;
size_t CurrentIndex = 0;
@@ -34,7 +35,7 @@ public:
class CustomAudioManager
{
-public:
+ public:
bool TryLoadAudioOverride(const fs::path&);
void ClearAudioOverrides();
diff --git a/NorthstarDedicatedTest/bansystem.cpp b/NorthstarDedicatedTest/bansystem.cpp
index b9e3fd33..0a4e9124 100644
--- a/NorthstarDedicatedTest/bansystem.cpp
+++ b/NorthstarDedicatedTest/bansystem.cpp
@@ -23,7 +23,7 @@ void ServerBanSystem::OpenBanlist()
m_vBannedUids.push_back(strtoll(line.c_str(), nullptr, 10));
enabledModsStream.close();
- }
+ }
// open write stream for banlist
m_sBanlistStream.open(GetNorthstarPrefix() + "/banlist.txt", std::ofstream::out | std::ofstream::binary | std::ofstream::app);
@@ -90,10 +90,7 @@ void UnbanPlayerCommand(const CCommand& args)
g_ServerBanSystem->UnbanUID(strtoll(args.Arg(1), nullptr, 10));
}
-void ClearBanlistCommand(const CCommand& args)
-{
- g_ServerBanSystem->ClearBanlist();
-}
+void ClearBanlistCommand(const CCommand& args) { g_ServerBanSystem->ClearBanlist(); }
void InitialiseBanSystem(HMODULE baseAddress)
{
diff --git a/NorthstarDedicatedTest/bansystem.h b/NorthstarDedicatedTest/bansystem.h
index 8ce05308..0f618843 100644
--- a/NorthstarDedicatedTest/bansystem.h
+++ b/NorthstarDedicatedTest/bansystem.h
@@ -3,11 +3,11 @@
class ServerBanSystem
{
-private:
+ private:
std::ofstream m_sBanlistStream;
std::vector<uint64_t> m_vBannedUids;
-public:
+ public:
void OpenBanlist();
void ClearBanlist();
void BanUID(uint64_t uid);
diff --git a/NorthstarDedicatedTest/bitbuf.h b/NorthstarDedicatedTest/bitbuf.h
index 7ee0df2a..902a9976 100644
--- a/NorthstarDedicatedTest/bitbuf.h
+++ b/NorthstarDedicatedTest/bitbuf.h
@@ -4,44 +4,15 @@
#define BITS_PER_INT 32
-INLINE int GetBitForBitnum(int bitNum) {
- static int bitsForBitnum[] =
- {
- (1 << 0),
- (1 << 1),
- (1 << 2),
- (1 << 3),
- (1 << 4),
- (1 << 5),
- (1 << 6),
- (1 << 7),
- (1 << 8),
- (1 << 9),
- (1 << 10),
- (1 << 11),
- (1 << 12),
- (1 << 13),
- (1 << 14),
- (1 << 15),
- (1 << 16),
- (1 << 17),
- (1 << 18),
- (1 << 19),
- (1 << 20),
- (1 << 21),
- (1 << 22),
- (1 << 23),
- (1 << 24),
- (1 << 25),
- (1 << 26),
- (1 << 27),
- (1 << 28),
- (1 << 29),
- (1 << 30),
- (1 << 31),
- };
-
- return bitsForBitnum[(bitNum) & (BITS_PER_INT - 1)];
+INLINE int GetBitForBitnum(int bitNum)
+{
+ static int bitsForBitnum[] = {
+ (1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4), (1 << 5), (1 << 6), (1 << 7), (1 << 8), (1 << 9), (1 << 10),
+ (1 << 11), (1 << 12), (1 << 13), (1 << 14), (1 << 15), (1 << 16), (1 << 17), (1 << 18), (1 << 19), (1 << 20), (1 << 21),
+ (1 << 22), (1 << 23), (1 << 24), (1 << 25), (1 << 26), (1 << 27), (1 << 28), (1 << 29), (1 << 30), (1 << 31),
+ };
+
+ return bitsForBitnum[(bitNum) & (BITS_PER_INT - 1)];
}
#undef BITS_PER_INT
@@ -61,994 +32,1042 @@ using iptr = intptr_t;
// Endianess, don't use on PPC64 nor ARM64BE
#define LittleDWord(val) (val)
-static INLINE void StoreLittleDWord(u32* base, size_t dwordIndex, u32 dword) {
- base[dwordIndex] = LittleDWord(dword);
-}
+static INLINE void StoreLittleDWord(u32* base, size_t dwordIndex, u32 dword) { base[dwordIndex] = LittleDWord(dword); }
-static INLINE u32 LoadLittleDWord(u32* base, size_t dwordIndex) {
- return LittleDWord(base[dwordIndex]);
-}
+static INLINE u32 LoadLittleDWord(u32* base, size_t dwordIndex) { return LittleDWord(base[dwordIndex]); }
#include <algorithm>
static inline const u32 s_nMaskTable[33] = {
- 0,
- (1 << 1) - 1,
- (1 << 2) - 1,
- (1 << 3) - 1,
- (1 << 4) - 1,
- (1 << 5) - 1,
- (1 << 6) - 1,
- (1 << 7) - 1,
- (1 << 8) - 1,
- (1 << 9) - 1,
- (1 << 10) - 1,
- (1 << 11) - 1,
- (1 << 12) - 1,
- (1 << 13) - 1,
- (1 << 14) - 1,
- (1 << 15) - 1,
- (1 << 16) - 1,
- (1 << 17) - 1,
- (1 << 18) - 1,
- (1 << 19) - 1,
- (1 << 20) - 1,
- (1 << 21) - 1,
- (1 << 22) - 1,
- (1 << 23) - 1,
- (1 << 24) - 1,
- (1 << 25) - 1,
- (1 << 26) - 1,
- (1 << 27) - 1,
- (1 << 28) - 1,
- (1 << 29) - 1,
- (1 << 30) - 1,
- 0x7fffffff,
- 0xffffffff,
+ 0,
+ (1 << 1) - 1,
+ (1 << 2) - 1,
+ (1 << 3) - 1,
+ (1 << 4) - 1,
+ (1 << 5) - 1,
+ (1 << 6) - 1,
+ (1 << 7) - 1,
+ (1 << 8) - 1,
+ (1 << 9) - 1,
+ (1 << 10) - 1,
+ (1 << 11) - 1,
+ (1 << 12) - 1,
+ (1 << 13) - 1,
+ (1 << 14) - 1,
+ (1 << 15) - 1,
+ (1 << 16) - 1,
+ (1 << 17) - 1,
+ (1 << 18) - 1,
+ (1 << 19) - 1,
+ (1 << 20) - 1,
+ (1 << 21) - 1,
+ (1 << 22) - 1,
+ (1 << 23) - 1,
+ (1 << 24) - 1,
+ (1 << 25) - 1,
+ (1 << 26) - 1,
+ (1 << 27) - 1,
+ (1 << 28) - 1,
+ (1 << 29) - 1,
+ (1 << 30) - 1,
+ 0x7fffffff,
+ 0xffffffff,
};
-enum EBitCoordType {
- kCW_None,
- kCW_LowPrecision,
- kCW_Integral
+enum EBitCoordType
+{
+ kCW_None,
+ kCW_LowPrecision,
+ kCW_Integral
};
-class BitBufferBase {
-protected:
- INLINE void SetName(const char* name) { m_BufferName = name; }
+class BitBufferBase
+{
+ protected:
+ INLINE void SetName(const char* name) { m_BufferName = name; }
-public:
- INLINE bool IsOverflowed() { return m_Overflow; }
- INLINE void SetOverflowed() { m_Overflow = true; }
+ public:
+ INLINE bool IsOverflowed() { return m_Overflow; }
+ INLINE void SetOverflowed() { m_Overflow = true; }
- INLINE const char* GetName() { return m_BufferName; }
+ INLINE const char* GetName() { return m_BufferName; }
-private:
- const char* m_BufferName = "";
+ private:
+ const char* m_BufferName = "";
-protected:
- u8 m_Overflow = false;
+ protected:
+ u8 m_Overflow = false;
};
-class BFRead : public BitBufferBase {
-public:
- BFRead() = default;
-
- INLINE BFRead(uptr data, size_t byteLength, size_t startPos = 0, const char* bufferName = 0) {
- StartReading(data, byteLength, startPos);
-
- if (bufferName)
- SetName(bufferName);
- }
-
-public:
- INLINE void StartReading(uptr data, size_t byteLength, size_t startPos = 0) {
- m_Data = reinterpret_cast<u32 const*>(data);
- m_DataIn = m_Data;
-
- m_DataBytes = byteLength;
- m_DataBits = byteLength << 3;
-
- m_DataEnd = reinterpret_cast<u32 const*>(reinterpret_cast<u8 const*>(m_Data) + m_DataBytes);
-
- Seek(startPos);
- }
-
- INLINE void GrabNextDWord(bool overflow = false) {
- if (m_Data == m_DataEnd) {
- m_CachedBitsLeft = 1;
- m_CachedBufWord = 0;
-
- m_DataIn++;
-
- if (overflow)
- SetOverflowed();
- }
- else {
- if (m_DataIn > m_DataEnd) {
- SetOverflowed();
- m_CachedBufWord = 0;
- }
- else {
- m_CachedBufWord = LittleDWord(*(m_DataIn++));
- }
- }
- }
-
- INLINE void FetchNext() {
- m_CachedBitsLeft = 32;
- GrabNextDWord(false);
- }
-
- INLINE i32 ReadOneBit() {
- i32 ret = m_CachedBufWord & 1;
-
- if (--m_CachedBitsLeft == 0)
- FetchNext();
- else
- m_CachedBufWord >>= 1;
-
- return ret;
- }
-
- INLINE u32 ReadUBitLong(i32 numBits) {
- if (m_CachedBitsLeft >= numBits) {
- u32 ret = m_CachedBufWord & s_nMaskTable[numBits];
-
- m_CachedBitsLeft -= numBits;
-
- if (m_CachedBitsLeft)
- m_CachedBufWord >>= numBits;
- else
- FetchNext();
-
- return ret;
- }
- else {
- // need to merge words
- u32 ret = m_CachedBufWord;
- numBits -= m_CachedBitsLeft;
-
- GrabNextDWord(true);
-
- if (IsOverflowed())
- return 0;
-
- ret |= ((m_CachedBufWord & s_nMaskTable[numBits]) << m_CachedBitsLeft);
-
- m_CachedBitsLeft = 32 - numBits;
- m_CachedBufWord >>= numBits;
-
- return ret;
- }
- }
-
- INLINE i32 ReadSBitLong(int numBits) {
- i32 ret = ReadUBitLong(numBits);
- return (ret << (32 - numBits)) >> (32 - numBits);
- }
-
- INLINE u32 ReadUBitVar() {
- u32 ret = ReadUBitLong(6);
-
- switch (ret & (16 | 32)) {
- case 16:
- ret = (ret & 15) | (ReadUBitLong(4) << 4);
- // Assert(ret >= 16);
- break;
- case 32:
- ret = (ret & 15) | (ReadUBitLong(8) << 4);
- // Assert(ret >= 256);
- break;
- case 48:
- ret = (ret & 15) | (ReadUBitLong(32 - 4) << 4);
- // Assert(ret >= 4096);
- break;
- }
-
- return ret;
- }
-
- INLINE u32 PeekUBitLong(i32 numBits) {
- i32 nSaveBA = m_CachedBitsLeft;
- i32 nSaveW = m_CachedBufWord;
- u32 const* pSaveP = m_DataIn;
- u32 nRet = ReadUBitLong(numBits);
-
- m_CachedBitsLeft = nSaveBA;
- m_CachedBufWord = nSaveW;
- m_DataIn = pSaveP;
-
- return nRet;
- }
-
- INLINE float ReadBitFloat() {
- u32 value = ReadUBitLong(32);
- return *reinterpret_cast<float*>(&value);
- }
-
- /*INLINE float ReadBitCoord() {
- i32 intval = 0, fractval = 0, signbit = 0;
- float value = 0.0;
-
- // Read the required integer and fraction flags
- intval = ReadOneBit();
- fractval = ReadOneBit();
-
- // If we got either parse them, otherwise it's a zero.
- if (intval || fractval) {
- // Read the sign bit
- signbit = ReadOneBit();
-
- // If there's an integer, read it in
- if (intval) {
- // Adjust the integers from [0..MAX_COORD_VALUE-1] to [1..MAX_COORD_VALUE]
- intval = ReadUBitLong(COORD_INTEGER_BITS) + 1;
- }
-
- // If there's a fraction, read it in
- if (fractval) {
- fractval = ReadUBitLong(COORD_FRACTIONAL_BITS);
- }
-
- // Calculate the correct floating point value
- value = intval + ((float)fractval * COORD_RESOLUTION);
-
- // Fixup the sign if negative.
- if (signbit)
- value = -value;
- }
-
- return value;
- }
-
- INLINE float ReadBitCoordMP() {
- i32 intval = 0, fractval = 0, signbit = 0;
- float value = 0.0;
-
- bool inBounds = ReadOneBit() ? true : false;
-
- // Read the required integer and fraction flags
- intval = ReadOneBit();
-
- // If we got either parse them, otherwise it's a zero.
- if (intval) {
- // Read the sign bit
- signbit = ReadOneBit();
-
- // If there's an integer, read it in
- // Adjust the integers from [0..MAX_COORD_VALUE-1] to [1..MAX_COORD_VALUE]
- if (inBounds)
- value = ReadUBitLong(COORD_INTEGER_BITS_MP) + 1;
- else
- value = ReadUBitLong(COORD_INTEGER_BITS) + 1;
- }
-
- // Fixup the sign if negative.
- if (signbit)
- value = -value;
-
- return value;
- }
-
- INLINE float ReadBitCellCoord(int bits, EBitCoordType coordType) {
- bool bIntegral = (coordType == kCW_Integral);
- bool bLowPrecision = (coordType == kCW_LowPrecision);
-
- int intval = 0, fractval = 0;
- float value = 0.0;
-
- if (bIntegral)
- value = ReadUBitLong(bits);
- else {
- intval = ReadUBitLong(bits);
-
- // If there's a fraction, read it in
- fractval = ReadUBitLong(bLowPrecision ? COORD_FRACTIONAL_BITS_MP_LOWPRECISION : COORD_FRACTIONAL_BITS);
-
- // Calculate the correct floating point value
- value = intval + ((float)fractval * (bLowPrecision ? COORD_RESOLUTION_LOWPRECISION : COORD_RESOLUTION));
- }
-
- return value;
- }
-
- INLINE float ReadBitNormal() {
- // Read the sign bit
- i32 signbit = ReadOneBit();
-
- // Read the fractional part
- u32 fractval = ReadUBitLong(NORMAL_FRACTIONAL_BITS);
-
- // Calculate the correct floating point value
- float value = (float)fractval * NORMAL_RESOLUTION;
-
- // Fixup the sign if negative.
- if (signbit)
- value = -value;
-
- return value;
- }
-
- INLINE void ReadBitVec3Coord(Vector& fa) {
- i32 xflag, yflag, zflag;
-
- // This vector must be initialized! Otherwise, If any of the flags aren't set,
- // the corresponding component will not be read and will be stack garbage.
- fa.Init(0, 0, 0);
-
- xflag = ReadOneBit();
- yflag = ReadOneBit();
- zflag = ReadOneBit();
-
- if (xflag)
- fa[0] = ReadBitCoord();
- if (yflag)
- fa[1] = ReadBitCoord();
- if (zflag)
- fa[2] = ReadBitCoord();
- }
-
- INLINE void ReadBitVec3Normal(Vector& fa) {
- i32 xflag = ReadOneBit();
- i32 yflag = ReadOneBit();
-
- if (xflag)
- fa[0] = ReadBitNormal();
- else
- fa[0] = 0.0f;
-
- if (yflag)
- fa[1] = ReadBitNormal();
- else
- fa[1] = 0.0f;
-
- // The first two imply the third (but not its sign)
- i32 znegative = ReadOneBit();
-
- float fafafbfb = fa[0] * fa[0] + fa[1] * fa[1];
- if (fafafbfb < 1.0f)
- fa[2] = sqrt(1.0f - fafafbfb);
- else
- fa[2] = 0.0f;
-
- if (znegative)
- fa[2] = -fa[2];
- }
-
- INLINE void ReadBitAngles(QAngle& fa) {
- Vector tmp;
- ReadBitVec3Coord(tmp);
- fa.Init(tmp.x, tmp.y, tmp.z);
- }*/
-
- INLINE float ReadBitAngle(int numBits) {
- float shift = (float)(GetBitForBitnum(numBits));
-
- i32 i = ReadUBitLong(numBits);
- float fReturn = (float)i * (360.0 / shift);
-
- return fReturn;
- }
-
- INLINE i32 ReadChar() { return ReadSBitLong(sizeof(char) << 3); }
- INLINE u32 ReadByte() { return ReadUBitLong(sizeof(unsigned char) << 3); }
-
- INLINE i32 ReadShort() { return ReadSBitLong(sizeof(short) << 3); }
- INLINE u32 ReadWord() { return ReadUBitLong(sizeof(unsigned short) << 3); }
-
- INLINE i32 ReadLong() { return (i32)(ReadUBitLong(sizeof(i32) << 3)); }
- INLINE float ReadFloat() {
- u32 temp = ReadUBitLong(sizeof(float) << 3);
- return *reinterpret_cast<float*>(&temp);
- }
-
- INLINE u32 ReadVarInt32() {
- constexpr int kMaxVarint32Bytes = 5;
-
- u32 result = 0;
- int count = 0;
- u32 b;
-
- do {
- if (count == kMaxVarint32Bytes)
- return result;
-
- b = ReadUBitLong(8);
- result |= (b & 0x7F) << (7 * count);
- ++count;
- } while (b & 0x80);
-
- return result;
- }
-
- INLINE u64 ReadVarInt64() {
- constexpr int kMaxVarintBytes = 10;
-
- u64 result = 0;
- int count = 0;
- u64 b;
-
- do {
- if (count == kMaxVarintBytes)
- return result;
-
- b = ReadUBitLong(8);
- result |= static_cast<u64>(b & 0x7F) << (7 * count);
- ++count;
- } while (b & 0x80);
-
- return result;
- }
-
- INLINE void ReadBits(uptr outData, u32 bitLength) {
- u8* out = reinterpret_cast<u8*>(outData);
- int bitsLeft = bitLength;
-
- // align output to dword boundary
- while (((uptr)out & 3) != 0 && bitsLeft >= 8) {
- *out = (unsigned char)ReadUBitLong(8);
- ++out;
- bitsLeft -= 8;
- }
-
- // read dwords
- while (bitsLeft >= 32) {
- *((u32*)out) = ReadUBitLong(32);
- out += sizeof(u32);
- bitsLeft -= 32;
- }
-
- // read remaining bytes
- while (bitsLeft >= 8) {
- *out = ReadUBitLong(8);
- ++out;
- bitsLeft -= 8;
- }
-
- // read remaining bits
- if (bitsLeft)
- *out = ReadUBitLong(bitsLeft);
- }
-
- INLINE bool ReadBytes(uptr outData, u32 byteLength) {
- ReadBits(outData, byteLength << 3);
- return !IsOverflowed();
- }
-
- INLINE bool ReadString(char* str, i32 maxLength, bool stopAtLineTermination = false, i32* outNumChars = 0) {
- bool tooSmall = false;
- int iChar = 0;
-
- while (1) {
- char val = ReadChar();
-
- if (val == 0)
- break;
- else if (stopAtLineTermination && val == '\n')
- break;
-
- if (iChar < (maxLength - 1)) {
- str[iChar] = val;
- ++iChar;
- }
- else {
- tooSmall = true;
- }
- }
-
- // Make sure it's null-terminated.
- // Assert(iChar < maxLength);
- str[iChar] = 0;
-
- if (outNumChars)
- *outNumChars = iChar;
-
- return !IsOverflowed() && !tooSmall;
- }
-
- INLINE char* ReadAndAllocateString(bool* hasOverflowed = 0) {
- char str[2048];
-
- int chars = 0;
- bool overflowed = !ReadString(str, sizeof(str), false, &chars);
-
- if (hasOverflowed)
- *hasOverflowed = overflowed;
-
- // Now copy into the output and return it;
- char* ret = new char[chars + 1];
- for (u32 i = 0; i <= chars; i++)
- ret[i] = str[i];
-
- return ret;
- }
-
- INLINE i64 ReadLongLong() {
- i64 retval;
- u32* longs = (u32*)&retval;
-
- // Read the two DWORDs according to network endian
- const short endianIndex = 0x0100;
- u8* idx = (u8*)&endianIndex;
-
- longs[*idx++] = ReadUBitLong(sizeof(i32) << 3);
- longs[*idx] = ReadUBitLong(sizeof(i32) << 3);
-
- return retval;
- }
-
- INLINE bool Seek(size_t startPos) {
- bool bSucc = true;
-
- if (startPos < 0 || startPos > m_DataBits) {
- SetOverflowed();
- bSucc = false;
- startPos = m_DataBits;
- }
-
- // non-multiple-of-4 bytes at head of buffer. We put the "round off"
- // at the head to make reading and detecting the end efficient.
- int nHead = m_DataBytes & 3;
-
- int posBytes = startPos / 8;
- if ((m_DataBytes < 4) || (nHead && (posBytes < nHead))) {
- // partial first dword
- u8 const* partial = (u8 const*)m_Data;
-
- if (m_Data) {
- m_CachedBufWord = *(partial++);
- if (nHead > 1)
- m_CachedBufWord |= (*partial++) << 8;
- if (nHead > 2)
- m_CachedBufWord |= (*partial++) << 16;
- }
-
- m_DataIn = (u32 const*)partial;
-
- m_CachedBufWord >>= (startPos & 31);
- m_CachedBitsLeft = (nHead << 3) - (startPos & 31);
- }
- else {
- int adjustedPos = startPos - (nHead << 3);
-
- m_DataIn = reinterpret_cast<u32 const*>(
- reinterpret_cast<u8 const*>(m_Data) + ((adjustedPos / 32) << 2) + nHead);
-
- if (m_Data) {
- m_CachedBitsLeft = 32;
- GrabNextDWord();
- }
- else {
- m_CachedBufWord = 0;
- m_CachedBitsLeft = 1;
- }
-
- m_CachedBufWord >>= (adjustedPos & 31);
- m_CachedBitsLeft = std::min(m_CachedBitsLeft, u32(32 - (adjustedPos & 31))); // in case grabnextdword overflowed
- }
-
- return bSucc;
- }
-
- INLINE size_t GetNumBitsRead() {
- if (!m_Data)
- return 0;
-
- size_t nCurOfs = size_t(((iptr(m_DataIn) - iptr(m_Data)) / 4) - 1);
- nCurOfs *= 32;
- nCurOfs += (32 - m_CachedBitsLeft);
-
- size_t nAdjust = 8 * (m_DataBytes & 3);
- return std::min(nCurOfs + nAdjust, m_DataBits);
- }
-
- INLINE bool SeekRelative(size_t offset) {
- return Seek(GetNumBitsRead() + offset);
- }
-
- INLINE size_t TotalBytesAvailable() { return m_DataBytes; }
-
- INLINE size_t GetNumBitsLeft() { return m_DataBits - GetNumBitsRead(); }
- INLINE size_t GetNumBytesLeft() { return GetNumBitsLeft() >> 3; }
-
-private:
- size_t m_DataBits; //0x0010
- size_t m_DataBytes; //0x0018
-
- u32 m_CachedBufWord; //0x0020
- u32 m_CachedBitsLeft; //0x0024
-
- const u32* m_DataIn; //0x0028
- const u32* m_DataEnd; //0x0030
- const u32* m_Data; //0x0038
+class BFRead : public BitBufferBase
+{
+ public:
+ BFRead() = default;
+
+ INLINE BFRead(uptr data, size_t byteLength, size_t startPos = 0, const char* bufferName = 0)
+ {
+ StartReading(data, byteLength, startPos);
+
+ if (bufferName)
+ SetName(bufferName);
+ }
+
+ public:
+ INLINE void StartReading(uptr data, size_t byteLength, size_t startPos = 0)
+ {
+ m_Data = reinterpret_cast<u32 const*>(data);
+ m_DataIn = m_Data;
+
+ m_DataBytes = byteLength;
+ m_DataBits = byteLength << 3;
+
+ m_DataEnd = reinterpret_cast<u32 const*>(reinterpret_cast<u8 const*>(m_Data) + m_DataBytes);
+
+ Seek(startPos);
+ }
+
+ INLINE void GrabNextDWord(bool overflow = false)
+ {
+ if (m_Data == m_DataEnd)
+ {
+ m_CachedBitsLeft = 1;
+ m_CachedBufWord = 0;
+
+ m_DataIn++;
+
+ if (overflow)
+ SetOverflowed();
+ }
+ else
+ {
+ if (m_DataIn > m_DataEnd)
+ {
+ SetOverflowed();
+ m_CachedBufWord = 0;
+ }
+ else
+ {
+ m_CachedBufWord = LittleDWord(*(m_DataIn++));
+ }
+ }
+ }
+
+ INLINE void FetchNext()
+ {
+ m_CachedBitsLeft = 32;
+ GrabNextDWord(false);
+ }
+
+ INLINE i32 ReadOneBit()
+ {
+ i32 ret = m_CachedBufWord & 1;
+
+ if (--m_CachedBitsLeft == 0)
+ FetchNext();
+ else
+ m_CachedBufWord >>= 1;
+
+ return ret;
+ }
+
+ INLINE u32 ReadUBitLong(i32 numBits)
+ {
+ if (m_CachedBitsLeft >= numBits)
+ {
+ u32 ret = m_CachedBufWord & s_nMaskTable[numBits];
+
+ m_CachedBitsLeft -= numBits;
+
+ if (m_CachedBitsLeft)
+ m_CachedBufWord >>= numBits;
+ else
+ FetchNext();
+
+ return ret;
+ }
+ else
+ {
+ // need to merge words
+ u32 ret = m_CachedBufWord;
+ numBits -= m_CachedBitsLeft;
+
+ GrabNextDWord(true);
+
+ if (IsOverflowed())
+ return 0;
+
+ ret |= ((m_CachedBufWord & s_nMaskTable[numBits]) << m_CachedBitsLeft);
+
+ m_CachedBitsLeft = 32 - numBits;
+ m_CachedBufWord >>= numBits;
+
+ return ret;
+ }
+ }
+
+ INLINE i32 ReadSBitLong(int numBits)
+ {
+ i32 ret = ReadUBitLong(numBits);
+ return (ret << (32 - numBits)) >> (32 - numBits);
+ }
+
+ INLINE u32 ReadUBitVar()
+ {
+ u32 ret = ReadUBitLong(6);
+
+ switch (ret & (16 | 32))
+ {
+ case 16:
+ ret = (ret & 15) | (ReadUBitLong(4) << 4);
+ // Assert(ret >= 16);
+ break;
+ case 32:
+ ret = (ret & 15) | (ReadUBitLong(8) << 4);
+ // Assert(ret >= 256);
+ break;
+ case 48:
+ ret = (ret & 15) | (ReadUBitLong(32 - 4) << 4);
+ // Assert(ret >= 4096);
+ break;
+ }
+
+ return ret;
+ }
+
+ INLINE u32 PeekUBitLong(i32 numBits)
+ {
+ i32 nSaveBA = m_CachedBitsLeft;
+ i32 nSaveW = m_CachedBufWord;
+ u32 const* pSaveP = m_DataIn;
+ u32 nRet = ReadUBitLong(numBits);
+
+ m_CachedBitsLeft = nSaveBA;
+ m_CachedBufWord = nSaveW;
+ m_DataIn = pSaveP;
+
+ return nRet;
+ }
+
+ INLINE float ReadBitFloat()
+ {
+ u32 value = ReadUBitLong(32);
+ return *reinterpret_cast<float*>(&value);
+ }
+
+ /*INLINE float ReadBitCoord() {
+ i32 intval = 0, fractval = 0, signbit = 0;
+ float value = 0.0;
+
+ // Read the required integer and fraction flags
+ intval = ReadOneBit();
+ fractval = ReadOneBit();
+
+ // If we got either parse them, otherwise it's a zero.
+ if (intval || fractval) {
+ // Read the sign bit
+ signbit = ReadOneBit();
+
+ // If there's an integer, read it in
+ if (intval) {
+ // Adjust the integers from [0..MAX_COORD_VALUE-1] to [1..MAX_COORD_VALUE]
+ intval = ReadUBitLong(COORD_INTEGER_BITS) + 1;
+ }
+
+ // If there's a fraction, read it in
+ if (fractval) {
+ fractval = ReadUBitLong(COORD_FRACTIONAL_BITS);
+ }
+
+ // Calculate the correct floating point value
+ value = intval + ((float)fractval * COORD_RESOLUTION);
+
+ // Fixup the sign if negative.
+ if (signbit)
+ value = -value;
+ }
+
+ return value;
+ }
+
+ INLINE float ReadBitCoordMP() {
+ i32 intval = 0, fractval = 0, signbit = 0;
+ float value = 0.0;
+
+ bool inBounds = ReadOneBit() ? true : false;
+
+ // Read the required integer and fraction flags
+ intval = ReadOneBit();
+
+ // If we got either parse them, otherwise it's a zero.
+ if (intval) {
+ // Read the sign bit
+ signbit = ReadOneBit();
+
+ // If there's an integer, read it in
+ // Adjust the integers from [0..MAX_COORD_VALUE-1] to [1..MAX_COORD_VALUE]
+ if (inBounds)
+ value = ReadUBitLong(COORD_INTEGER_BITS_MP) + 1;
+ else
+ value = ReadUBitLong(COORD_INTEGER_BITS) + 1;
+ }
+
+ // Fixup the sign if negative.
+ if (signbit)
+ value = -value;
+
+ return value;
+ }
+
+ INLINE float ReadBitCellCoord(int bits, EBitCoordType coordType) {
+ bool bIntegral = (coordType == kCW_Integral);
+ bool bLowPrecision = (coordType == kCW_LowPrecision);
+
+ int intval = 0, fractval = 0;
+ float value = 0.0;
+
+ if (bIntegral)
+ value = ReadUBitLong(bits);
+ else {
+ intval = ReadUBitLong(bits);
+
+ // If there's a fraction, read it in
+ fractval = ReadUBitLong(bLowPrecision ? COORD_FRACTIONAL_BITS_MP_LOWPRECISION : COORD_FRACTIONAL_BITS);
+
+ // Calculate the correct floating point value
+ value = intval + ((float)fractval * (bLowPrecision ? COORD_RESOLUTION_LOWPRECISION : COORD_RESOLUTION));
+ }
+
+ return value;
+ }
+
+ INLINE float ReadBitNormal() {
+ // Read the sign bit
+ i32 signbit = ReadOneBit();
+
+ // Read the fractional part
+ u32 fractval = ReadUBitLong(NORMAL_FRACTIONAL_BITS);
+
+ // Calculate the correct floating point value
+ float value = (float)fractval * NORMAL_RESOLUTION;
+
+ // Fixup the sign if negative.
+ if (signbit)
+ value = -value;
+
+ return value;
+ }
+
+ INLINE void ReadBitVec3Coord(Vector& fa) {
+ i32 xflag, yflag, zflag;
+
+ // This vector must be initialized! Otherwise, If any of the flags aren't set,
+ // the corresponding component will not be read and will be stack garbage.
+ fa.Init(0, 0, 0);
+
+ xflag = ReadOneBit();
+ yflag = ReadOneBit();
+ zflag = ReadOneBit();
+
+ if (xflag)
+ fa[0] = ReadBitCoord();
+ if (yflag)
+ fa[1] = ReadBitCoord();
+ if (zflag)
+ fa[2] = ReadBitCoord();
+ }
+
+ INLINE void ReadBitVec3Normal(Vector& fa) {
+ i32 xflag = ReadOneBit();
+ i32 yflag = ReadOneBit();
+
+ if (xflag)
+ fa[0] = ReadBitNormal();
+ else
+ fa[0] = 0.0f;
+
+ if (yflag)
+ fa[1] = ReadBitNormal();
+ else
+ fa[1] = 0.0f;
+
+ // The first two imply the third (but not its sign)
+ i32 znegative = ReadOneBit();
+
+ float fafafbfb = fa[0] * fa[0] + fa[1] * fa[1];
+ if (fafafbfb < 1.0f)
+ fa[2] = sqrt(1.0f - fafafbfb);
+ else
+ fa[2] = 0.0f;
+
+ if (znegative)
+ fa[2] = -fa[2];
+ }
+
+ INLINE void ReadBitAngles(QAngle& fa) {
+ Vector tmp;
+ ReadBitVec3Coord(tmp);
+ fa.Init(tmp.x, tmp.y, tmp.z);
+ }*/
+
+ INLINE float ReadBitAngle(int numBits)
+ {
+ float shift = (float)(GetBitForBitnum(numBits));
+
+ i32 i = ReadUBitLong(numBits);
+ float fReturn = (float)i * (360.0 / shift);
+
+ return fReturn;
+ }
+
+ INLINE i32 ReadChar() { return ReadSBitLong(sizeof(char) << 3); }
+ INLINE u32 ReadByte() { return ReadUBitLong(sizeof(unsigned char) << 3); }
+
+ INLINE i32 ReadShort() { return ReadSBitLong(sizeof(short) << 3); }
+ INLINE u32 ReadWord() { return ReadUBitLong(sizeof(unsigned short) << 3); }
+
+ INLINE i32 ReadLong() { return (i32)(ReadUBitLong(sizeof(i32) << 3)); }
+ INLINE float ReadFloat()
+ {
+ u32 temp = ReadUBitLong(sizeof(float) << 3);
+ return *reinterpret_cast<float*>(&temp);
+ }
+
+ INLINE u32 ReadVarInt32()
+ {
+ constexpr int kMaxVarint32Bytes = 5;
+
+ u32 result = 0;
+ int count = 0;
+ u32 b;
+
+ do
+ {
+ if (count == kMaxVarint32Bytes)
+ return result;
+
+ b = ReadUBitLong(8);
+ result |= (b & 0x7F) << (7 * count);
+ ++count;
+ } while (b & 0x80);
+
+ return result;
+ }
+
+ INLINE u64 ReadVarInt64()
+ {
+ constexpr int kMaxVarintBytes = 10;
+
+ u64 result = 0;
+ int count = 0;
+ u64 b;
+
+ do
+ {
+ if (count == kMaxVarintBytes)
+ return result;
+
+ b = ReadUBitLong(8);
+ result |= static_cast<u64>(b & 0x7F) << (7 * count);
+ ++count;
+ } while (b & 0x80);
+
+ return result;
+ }
+
+ INLINE void ReadBits(uptr outData, u32 bitLength)
+ {
+ u8* out = reinterpret_cast<u8*>(outData);
+ int bitsLeft = bitLength;
+
+ // align output to dword boundary
+ while (((uptr)out & 3) != 0 && bitsLeft >= 8)
+ {
+ *out = (unsigned char)ReadUBitLong(8);
+ ++out;
+ bitsLeft -= 8;
+ }
+
+ // read dwords
+ while (bitsLeft >= 32)
+ {
+ *((u32*)out) = ReadUBitLong(32);
+ out += sizeof(u32);
+ bitsLeft -= 32;
+ }
+
+ // read remaining bytes
+ while (bitsLeft >= 8)
+ {
+ *out = ReadUBitLong(8);
+ ++out;
+ bitsLeft -= 8;
+ }
+
+ // read remaining bits
+ if (bitsLeft)
+ *out = ReadUBitLong(bitsLeft);
+ }
+
+ INLINE bool ReadBytes(uptr outData, u32 byteLength)
+ {
+ ReadBits(outData, byteLength << 3);
+ return !IsOverflowed();
+ }
+
+ INLINE bool ReadString(char* str, i32 maxLength, bool stopAtLineTermination = false, i32* outNumChars = 0)
+ {
+ bool tooSmall = false;
+ int iChar = 0;
+
+ while (1)
+ {
+ char val = ReadChar();
+
+ if (val == 0)
+ break;
+ else if (stopAtLineTermination && val == '\n')
+ break;
+
+ if (iChar < (maxLength - 1))
+ {
+ str[iChar] = val;
+ ++iChar;
+ }
+ else
+ {
+ tooSmall = true;
+ }
+ }
+
+ // Make sure it's null-terminated.
+ // Assert(iChar < maxLength);
+ str[iChar] = 0;
+
+ if (outNumChars)
+ *outNumChars = iChar;
+
+ return !IsOverflowed() && !tooSmall;
+ }
+
+ INLINE char* ReadAndAllocateString(bool* hasOverflowed = 0)
+ {
+ char str[2048];
+
+ int chars = 0;
+ bool overflowed = !ReadString(str, sizeof(str), false, &chars);
+
+ if (hasOverflowed)
+ *hasOverflowed = overflowed;
+
+ // Now copy into the output and return it;
+ char* ret = new char[chars + 1];
+ for (u32 i = 0; i <= chars; i++)
+ ret[i] = str[i];
+
+ return ret;
+ }
+
+ INLINE i64 ReadLongLong()
+ {
+ i64 retval;
+ u32* longs = (u32*)&retval;
+
+ // Read the two DWORDs according to network endian
+ const short endianIndex = 0x0100;
+ u8* idx = (u8*)&endianIndex;
+
+ longs[*idx++] = ReadUBitLong(sizeof(i32) << 3);
+ longs[*idx] = ReadUBitLong(sizeof(i32) << 3);
+
+ return retval;
+ }
+
+ INLINE bool Seek(size_t startPos)
+ {
+ bool bSucc = true;
+
+ if (startPos < 0 || startPos > m_DataBits)
+ {
+ SetOverflowed();
+ bSucc = false;
+ startPos = m_DataBits;
+ }
+
+ // non-multiple-of-4 bytes at head of buffer. We put the "round off"
+ // at the head to make reading and detecting the end efficient.
+ int nHead = m_DataBytes & 3;
+
+ int posBytes = startPos / 8;
+ if ((m_DataBytes < 4) || (nHead && (posBytes < nHead)))
+ {
+ // partial first dword
+ u8 const* partial = (u8 const*)m_Data;
+
+ if (m_Data)
+ {
+ m_CachedBufWord = *(partial++);
+ if (nHead > 1)
+ m_CachedBufWord |= (*partial++) << 8;
+ if (nHead > 2)
+ m_CachedBufWord |= (*partial++) << 16;
+ }
+
+ m_DataIn = (u32 const*)partial;
+
+ m_CachedBufWord >>= (startPos & 31);
+ m_CachedBitsLeft = (nHead << 3) - (startPos & 31);
+ }
+ else
+ {
+ int adjustedPos = startPos - (nHead << 3);
+
+ m_DataIn = reinterpret_cast<u32 const*>(reinterpret_cast<u8 const*>(m_Data) + ((adjustedPos / 32) << 2) + nHead);
+
+ if (m_Data)
+ {
+ m_CachedBitsLeft = 32;
+ GrabNextDWord();
+ }
+ else
+ {
+ m_CachedBufWord = 0;
+ m_CachedBitsLeft = 1;
+ }
+
+ m_CachedBufWord >>= (adjustedPos & 31);
+ m_CachedBitsLeft = std::min(m_CachedBitsLeft, u32(32 - (adjustedPos & 31))); // in case grabnextdword overflowed
+ }
+
+ return bSucc;
+ }
+
+ INLINE size_t GetNumBitsRead()
+ {
+ if (!m_Data)
+ return 0;
+
+ size_t nCurOfs = size_t(((iptr(m_DataIn) - iptr(m_Data)) / 4) - 1);
+ nCurOfs *= 32;
+ nCurOfs += (32 - m_CachedBitsLeft);
+
+ size_t nAdjust = 8 * (m_DataBytes & 3);
+ return std::min(nCurOfs + nAdjust, m_DataBits);
+ }
+
+ INLINE bool SeekRelative(size_t offset) { return Seek(GetNumBitsRead() + offset); }
+
+ INLINE size_t TotalBytesAvailable() { return m_DataBytes; }
+
+ INLINE size_t GetNumBitsLeft() { return m_DataBits - GetNumBitsRead(); }
+ INLINE size_t GetNumBytesLeft() { return GetNumBitsLeft() >> 3; }
+
+ private:
+ size_t m_DataBits; // 0x0010
+ size_t m_DataBytes; // 0x0018
+
+ u32 m_CachedBufWord; // 0x0020
+ u32 m_CachedBitsLeft; // 0x0024
+
+ const u32* m_DataIn; // 0x0028
+ const u32* m_DataEnd; // 0x0030
+ const u32* m_Data; // 0x0038
};
-class BFWrite : public BitBufferBase {
-public:
- BFWrite() = default;
-
- INLINE BFWrite(uptr data, size_t byteLength, const char* bufferName = 0) {
- StartWriting(data, byteLength);
-
- if (bufferName)
- SetName(bufferName);
- }
-
-public:
- INLINE void StartWriting(uptr data, size_t byteLength) {
- m_Data = reinterpret_cast<u32*>(data);
- m_DataOut = m_Data;
-
- m_DataBytes = byteLength;
- m_DataBits = byteLength << 3;
-
- m_DataEnd = reinterpret_cast<u32*>(reinterpret_cast<u8*>(m_Data) + m_DataBytes);
- }
-
- INLINE int GetNumBitsLeft() {
- return m_OutBitsLeft + (32 * (m_DataEnd - m_DataOut - 1));
- }
-
- INLINE void Reset() {
- m_Overflow = false;
- m_OutBufWord = 0;
- m_OutBitsLeft = 32;
- m_DataOut = m_Data;
- }
-
- INLINE void TempFlush() {
- if (m_OutBitsLeft != 32) {
- if (m_DataOut == m_DataEnd)
- SetOverflowed();
- else
- StoreLittleDWord(m_DataOut, 0, LoadLittleDWord(m_DataOut, 0) & ~s_nMaskTable[32 - m_OutBitsLeft] | m_OutBufWord);
- }
-
- m_Flushed = true;
- }
-
- INLINE u8* GetBasePointer() {
- TempFlush();
- return reinterpret_cast<u8*>(m_Data);
- }
-
- INLINE u8* GetData() {
- return GetBasePointer();
- }
-
- INLINE void Finish() {
- if (m_OutBitsLeft != 32) {
- if (m_DataOut == m_DataEnd)
- SetOverflowed();
-
- StoreLittleDWord(m_DataOut, 0, m_OutBufWord);
- }
- }
-
- INLINE void FlushNoCheck() {
- StoreLittleDWord(m_DataOut++, 0, m_OutBufWord);
-
- m_OutBitsLeft = 32;
- m_OutBufWord = 0;
- }
-
- INLINE void Flush() {
- if (m_DataOut == m_DataEnd)
- SetOverflowed();
- else
- StoreLittleDWord(m_DataOut++, 0, m_OutBufWord);
-
- m_OutBitsLeft = 32;
- m_OutBufWord = 0;
- }
-
- INLINE void WriteOneBitNoCheck(i32 value) {
- m_OutBufWord |= (value & 1) << (32 - m_OutBitsLeft);
-
- if (--m_OutBitsLeft == 0)
- FlushNoCheck();
- }
-
- INLINE void WriteOneBit(i32 value) {
- m_OutBufWord |= (value & 1) << (32 - m_OutBitsLeft);
-
- if (--m_OutBitsLeft == 0)
- Flush();
- }
-
- INLINE void WriteUBitLong(u32 data, i32 numBits, bool checkRange = true) {
- if (numBits <= m_OutBitsLeft) {
- if (checkRange)
- m_OutBufWord |= (data) << (32 - m_OutBitsLeft);
- else
- m_OutBufWord |= (data & s_nMaskTable[numBits]) << (32 - m_OutBitsLeft);
-
- m_OutBitsLeft -= numBits;
-
- if (m_OutBitsLeft == 0)
- Flush();
- }
- else {
- // split dwords case
- i32 overflowBits = (numBits - m_OutBitsLeft);
- m_OutBufWord |= (data & s_nMaskTable[m_OutBitsLeft]) << (32 - m_OutBitsLeft);
- Flush();
- m_OutBufWord = (data >> (numBits - overflowBits));
- m_OutBitsLeft = 32 - overflowBits;
- }
- }
-
- INLINE void WriteSBitLong(i32 data, i32 numBits) {
- WriteUBitLong((u32)data, numBits, false);
- }
-
- INLINE void WriteUBitVar(u32 n) {
- if (n < 16)
- WriteUBitLong(n, 6);
- else if (n < 256)
- WriteUBitLong((n & 15) | 16 | ((n & (128 | 64 | 32 | 16)) << 2), 10);
- else if (n < 4096)
- WriteUBitLong((n & 15) | 32 | ((n & (2048 | 1024 | 512 | 256 | 128 | 64 | 32 | 16)) << 2), 14);
- else {
- WriteUBitLong((n & 15) | 48, 6);
- WriteUBitLong((n >> 4), 32 - 4);
- }
- }
-
- INLINE void WriteBitFloat(float value) {
- auto temp = &value;
- WriteUBitLong(*reinterpret_cast<u32*>(temp), 32);
- }
-
- INLINE void WriteFloat(float value) {
- auto temp = &value;
- WriteUBitLong(*reinterpret_cast<u32*>(temp), 32);
- }
-
- INLINE bool WriteBits(const uptr data, i32 numBits) {
- u8* out = (u8*)data;
- i32 numBitsLeft = numBits;
-
- // Bounds checking..
- if ((GetNumBitsWritten() + numBits) > m_DataBits) {
- SetOverflowed();
- return false;
- }
-
- // !! speed!! need fast paths
- // write remaining bytes
- while (numBitsLeft >= 8) {
- WriteUBitLong(*out, 8, false);
- ++out;
- numBitsLeft -= 8;
- }
-
- // write remaining bits
- if (numBitsLeft)
- WriteUBitLong(*out, numBitsLeft, false);
-
- return !IsOverflowed();
- }
-
- INLINE bool WriteBytes(const uptr data, i32 numBytes) {
- return WriteBits(data, numBytes << 3);
- }
-
- INLINE i32 GetNumBitsWritten() {
- return (32 - m_OutBitsLeft) + (32 * (m_DataOut - m_Data));
- }
-
- INLINE i32 GetNumBytesWritten() {
- return (GetNumBitsWritten() + 7) >> 3;
- }
-
- INLINE void WriteChar(i32 val) {
- WriteSBitLong(val, sizeof(char) << 3);
- }
-
- INLINE void WriteByte(i32 val) {
- WriteUBitLong(val, sizeof(unsigned char) << 3, false);
- }
-
- INLINE void WriteShort(i32 val) {
- WriteSBitLong(val, sizeof(short) << 3);
- }
-
- INLINE void WriteWord(i32 val) {
- WriteUBitLong(val, sizeof(unsigned short) << 3);
- }
-
- INLINE bool WriteString(const char* str) {
- if (str)
- while (*str)
- WriteChar(*(str++));
-
- WriteChar(0);
-
- return !IsOverflowed();
- }
-
- INLINE void WriteLongLong(i64 val) {
- u32* pLongs = (u32*)&val;
-
- // Insert the two DWORDS according to network endian
- const short endianIndex = 0x0100;
- u8* idx = (u8*)&endianIndex;
-
- WriteUBitLong(pLongs[*idx++], sizeof(i32) << 3);
- WriteUBitLong(pLongs[*idx], sizeof(i32) << 3);
- }
-
- /*INLINE void WriteBitCoord(const float f) {
- i32 signbit = (f <= -COORD_RESOLUTION);
- i32 intval = (i32)abs(f);
- i32 fractval = abs((i32)(f * COORD_DENOMINATOR)) & (COORD_DENOMINATOR - 1);
-
- // Send the bit flags that indicate whether we have an integer part and/or a fraction part.
- WriteOneBit(intval);
- WriteOneBit(fractval);
-
- if (intval || fractval) {
- // Send the sign bit
- WriteOneBit(signbit);
-
- // Send the integer if we have one.
- if (intval) {
- // Adjust the integers from [1..MAX_COORD_VALUE] to [0..MAX_COORD_VALUE-1]
- intval--;
- WriteUBitLong((u32)intval, COORD_INTEGER_BITS);
- }
-
- // Send the fraction if we have one
- if (fractval) {
- WriteUBitLong((u32)fractval, COORD_FRACTIONAL_BITS);
- }
- }
- }
-
- INLINE void WriteBitCoordMP(const float f) {
- i32 signbit = (f <= -COORD_RESOLUTION);
- i32 intval = (i32)abs(f);
- i32 fractval = (abs((i32)(f * COORD_DENOMINATOR)) & (COORD_DENOMINATOR - 1));
-
- bool bInBounds = intval < (1 << COORD_INTEGER_BITS_MP);
-
- WriteOneBit(bInBounds);
-
- // Send the sign bit
- WriteOneBit(intval);
-
- if (intval) {
- WriteOneBit(signbit);
-
- // Send the integer if we have one.
- // Adjust the integers from [1..MAX_COORD_VALUE] to [0..MAX_COORD_VALUE-1]
- intval--;
-
- if (bInBounds)
- WriteUBitLong((u32)intval, COORD_INTEGER_BITS_MP);
- else
- WriteUBitLong((u32)intval, COORD_INTEGER_BITS);
- }
- }
-
- INLINE void WriteBitCellCoord(const float f, int bits, EBitCoordType coordType) {
- bool bIntegral = (coordType == kCW_Integral);
- bool bLowPrecision = (coordType == kCW_LowPrecision);
-
- i32 intval = (i32)abs(f);
- i32 fractval = bLowPrecision ? (abs((i32)(f * COORD_DENOMINATOR_LOWPRECISION)) & (COORD_DENOMINATOR_LOWPRECISION - 1)) : (abs((i32)(f * COORD_DENOMINATOR)) & (COORD_DENOMINATOR - 1));
-
- if (bIntegral)
- WriteUBitLong((u32)intval, bits);
- else {
- WriteUBitLong((u32)intval, bits);
- WriteUBitLong((u32)fractval, bLowPrecision ? COORD_FRACTIONAL_BITS_MP_LOWPRECISION : COORD_FRACTIONAL_BITS);
- }
- }*/
-
- INLINE void SeekToBit(int bit) {
- TempFlush();
+class BFWrite : public BitBufferBase
+{
+ public:
+ BFWrite() = default;
+
+ INLINE BFWrite(uptr data, size_t byteLength, const char* bufferName = 0)
+ {
+ StartWriting(data, byteLength);
+
+ if (bufferName)
+ SetName(bufferName);
+ }
+
+ public:
+ INLINE void StartWriting(uptr data, size_t byteLength)
+ {
+ m_Data = reinterpret_cast<u32*>(data);
+ m_DataOut = m_Data;
+
+ m_DataBytes = byteLength;
+ m_DataBits = byteLength << 3;
+
+ m_DataEnd = reinterpret_cast<u32*>(reinterpret_cast<u8*>(m_Data) + m_DataBytes);
+ }
+
+ INLINE int GetNumBitsLeft() { return m_OutBitsLeft + (32 * (m_DataEnd - m_DataOut - 1)); }
+
+ INLINE void Reset()
+ {
+ m_Overflow = false;
+ m_OutBufWord = 0;
+ m_OutBitsLeft = 32;
+ m_DataOut = m_Data;
+ }
+
+ INLINE void TempFlush()
+ {
+ if (m_OutBitsLeft != 32)
+ {
+ if (m_DataOut == m_DataEnd)
+ SetOverflowed();
+ else
+ StoreLittleDWord(m_DataOut, 0, LoadLittleDWord(m_DataOut, 0) & ~s_nMaskTable[32 - m_OutBitsLeft] | m_OutBufWord);
+ }
+
+ m_Flushed = true;
+ }
+
+ INLINE u8* GetBasePointer()
+ {
+ TempFlush();
+ return reinterpret_cast<u8*>(m_Data);
+ }
+
+ INLINE u8* GetData() { return GetBasePointer(); }
+
+ INLINE void Finish()
+ {
+ if (m_OutBitsLeft != 32)
+ {
+ if (m_DataOut == m_DataEnd)
+ SetOverflowed();
+
+ StoreLittleDWord(m_DataOut, 0, m_OutBufWord);
+ }
+ }
+
+ INLINE void FlushNoCheck()
+ {
+ StoreLittleDWord(m_DataOut++, 0, m_OutBufWord);
+
+ m_OutBitsLeft = 32;
+ m_OutBufWord = 0;
+ }
+
+ INLINE void Flush()
+ {
+ if (m_DataOut == m_DataEnd)
+ SetOverflowed();
+ else
+ StoreLittleDWord(m_DataOut++, 0, m_OutBufWord);
+
+ m_OutBitsLeft = 32;
+ m_OutBufWord = 0;
+ }
+
+ INLINE void WriteOneBitNoCheck(i32 value)
+ {
+ m_OutBufWord |= (value & 1) << (32 - m_OutBitsLeft);
+
+ if (--m_OutBitsLeft == 0)
+ FlushNoCheck();
+ }
+
+ INLINE void WriteOneBit(i32 value)
+ {
+ m_OutBufWord |= (value & 1) << (32 - m_OutBitsLeft);
+
+ if (--m_OutBitsLeft == 0)
+ Flush();
+ }
+
+ INLINE void WriteUBitLong(u32 data, i32 numBits, bool checkRange = true)
+ {
+ if (numBits <= m_OutBitsLeft)
+ {
+ if (checkRange)
+ m_OutBufWord |= (data) << (32 - m_OutBitsLeft);
+ else
+ m_OutBufWord |= (data & s_nMaskTable[numBits]) << (32 - m_OutBitsLeft);
+
+ m_OutBitsLeft -= numBits;
+
+ if (m_OutBitsLeft == 0)
+ Flush();
+ }
+ else
+ {
+ // split dwords case
+ i32 overflowBits = (numBits - m_OutBitsLeft);
+ m_OutBufWord |= (data & s_nMaskTable[m_OutBitsLeft]) << (32 - m_OutBitsLeft);
+ Flush();
+ m_OutBufWord = (data >> (numBits - overflowBits));
+ m_OutBitsLeft = 32 - overflowBits;
+ }
+ }
+
+ INLINE void WriteSBitLong(i32 data, i32 numBits) { WriteUBitLong((u32)data, numBits, false); }
+
+ INLINE void WriteUBitVar(u32 n)
+ {
+ if (n < 16)
+ WriteUBitLong(n, 6);
+ else if (n < 256)
+ WriteUBitLong((n & 15) | 16 | ((n & (128 | 64 | 32 | 16)) << 2), 10);
+ else if (n < 4096)
+ WriteUBitLong((n & 15) | 32 | ((n & (2048 | 1024 | 512 | 256 | 128 | 64 | 32 | 16)) << 2), 14);
+ else
+ {
+ WriteUBitLong((n & 15) | 48, 6);
+ WriteUBitLong((n >> 4), 32 - 4);
+ }
+ }
+
+ INLINE void WriteBitFloat(float value)
+ {
+ auto temp = &value;
+ WriteUBitLong(*reinterpret_cast<u32*>(temp), 32);
+ }
+
+ INLINE void WriteFloat(float value)
+ {
+ auto temp = &value;
+ WriteUBitLong(*reinterpret_cast<u32*>(temp), 32);
+ }
+
+ INLINE bool WriteBits(const uptr data, i32 numBits)
+ {
+ u8* out = (u8*)data;
+ i32 numBitsLeft = numBits;
+
+ // Bounds checking..
+ if ((GetNumBitsWritten() + numBits) > m_DataBits)
+ {
+ SetOverflowed();
+ return false;
+ }
+
+ // !! speed!! need fast paths
+ // write remaining bytes
+ while (numBitsLeft >= 8)
+ {
+ WriteUBitLong(*out, 8, false);
+ ++out;
+ numBitsLeft -= 8;
+ }
+
+ // write remaining bits
+ if (numBitsLeft)
+ WriteUBitLong(*out, numBitsLeft, false);
+
+ return !IsOverflowed();
+ }
+
+ INLINE bool WriteBytes(const uptr data, i32 numBytes) { return WriteBits(data, numBytes << 3); }
+
+ INLINE i32 GetNumBitsWritten() { return (32 - m_OutBitsLeft) + (32 * (m_DataOut - m_Data)); }
+
+ INLINE i32 GetNumBytesWritten() { return (GetNumBitsWritten() + 7) >> 3; }
+
+ INLINE void WriteChar(i32 val) { WriteSBitLong(val, sizeof(char) << 3); }
+
+ INLINE void WriteByte(i32 val) { WriteUBitLong(val, sizeof(unsigned char) << 3, false); }
+
+ INLINE void WriteShort(i32 val) { WriteSBitLong(val, sizeof(short) << 3); }
+
+ INLINE void WriteWord(i32 val) { WriteUBitLong(val, sizeof(unsigned short) << 3); }
+
+ INLINE bool WriteString(const char* str)
+ {
+ if (str)
+ while (*str)
+ WriteChar(*(str++));
+
+ WriteChar(0);
+
+ return !IsOverflowed();
+ }
+
+ INLINE void WriteLongLong(i64 val)
+ {
+ u32* pLongs = (u32*)&val;
+
+ // Insert the two DWORDS according to network endian
+ const short endianIndex = 0x0100;
+ u8* idx = (u8*)&endianIndex;
+
+ WriteUBitLong(pLongs[*idx++], sizeof(i32) << 3);
+ WriteUBitLong(pLongs[*idx], sizeof(i32) << 3);
+ }
+
+ /*INLINE void WriteBitCoord(const float f) {
+ i32 signbit = (f <= -COORD_RESOLUTION);
+ i32 intval = (i32)abs(f);
+ i32 fractval = abs((i32)(f * COORD_DENOMINATOR)) & (COORD_DENOMINATOR - 1);
+
+ // Send the bit flags that indicate whether we have an integer part and/or a fraction part.
+ WriteOneBit(intval);
+ WriteOneBit(fractval);
+
+ if (intval || fractval) {
+ // Send the sign bit
+ WriteOneBit(signbit);
+
+ // Send the integer if we have one.
+ if (intval) {
+ // Adjust the integers from [1..MAX_COORD_VALUE] to [0..MAX_COORD_VALUE-1]
+ intval--;
+ WriteUBitLong((u32)intval, COORD_INTEGER_BITS);
+ }
+
+ // Send the fraction if we have one
+ if (fractval) {
+ WriteUBitLong((u32)fractval, COORD_FRACTIONAL_BITS);
+ }
+ }
+ }
+
+ INLINE void WriteBitCoordMP(const float f) {
+ i32 signbit = (f <= -COORD_RESOLUTION);
+ i32 intval = (i32)abs(f);
+ i32 fractval = (abs((i32)(f * COORD_DENOMINATOR)) & (COORD_DENOMINATOR - 1));
+
+ bool bInBounds = intval < (1 << COORD_INTEGER_BITS_MP);
- m_DataOut = m_Data + (bit / 32);
- m_OutBufWord = LoadLittleDWord(m_DataOut, 0);
- m_OutBitsLeft = 32 - (bit & 31);
- }
-
- /*INLINE void WriteBitVec3Coord(const Vector& fa) {
- i32 xflag, yflag, zflag;
+ WriteOneBit(bInBounds);
+
+ // Send the sign bit
+ WriteOneBit(intval);
- xflag = (fa[0] >= COORD_RESOLUTION) || (fa[0] <= -COORD_RESOLUTION);
- yflag = (fa[1] >= COORD_RESOLUTION) || (fa[1] <= -COORD_RESOLUTION);
- zflag = (fa[2] >= COORD_RESOLUTION) || (fa[2] <= -COORD_RESOLUTION);
+ if (intval) {
+ WriteOneBit(signbit);
- WriteOneBit(xflag);
- WriteOneBit(yflag);
- WriteOneBit(zflag);
-
- if (xflag)
- WriteBitCoord(fa[0]);
- if (yflag)
- WriteBitCoord(fa[1]);
- if (zflag)
- WriteBitCoord(fa[2]);
- }
-
- INLINE void WriteBitNormal(float f) {
- i32 signbit = (f <= -NORMAL_RESOLUTION);
-
- // NOTE: Since +/-1 are valid values for a normal, I'm going to encode that as all ones
- u32 fractval = abs((i32)(f * NORMAL_DENOMINATOR));
-
- // clamp..
- if (fractval > NORMAL_DENOMINATOR)
- fractval = NORMAL_DENOMINATOR;
-
- // Send the sign bit
- WriteOneBit(signbit);
-
- // Send the fractional component
- WriteUBitLong(fractval, NORMAL_FRACTIONAL_BITS);
- }
-
- INLINE void WriteBitVec3Normal(const Vector& fa) {
- i32 xflag, yflag;
-
- xflag = (fa[0] >= NORMAL_RESOLUTION) || (fa[0] <= -NORMAL_RESOLUTION);
- yflag = (fa[1] >= NORMAL_RESOLUTION) || (fa[1] <= -NORMAL_RESOLUTION);
-
- WriteOneBit(xflag);
- WriteOneBit(yflag);
-
- if (xflag)
- WriteBitNormal(fa[0]);
- if (yflag)
- WriteBitNormal(fa[1]);
+ // Send the integer if we have one.
+ // Adjust the integers from [1..MAX_COORD_VALUE] to [0..MAX_COORD_VALUE-1]
+ intval--;
- // Write z sign bit
- i32 signbit = (fa[2] <= -NORMAL_RESOLUTION);
- WriteOneBit(signbit);
- }*/
+ if (bInBounds)
+ WriteUBitLong((u32)intval, COORD_INTEGER_BITS_MP);
+ else
+ WriteUBitLong((u32)intval, COORD_INTEGER_BITS);
+ }
+ }
- INLINE void WriteBitAngle(float angle, int numBits) {
- u32 shift = GetBitForBitnum(numBits);
- u32 mask = shift - 1;
+ INLINE void WriteBitCellCoord(const float f, int bits, EBitCoordType coordType) {
+ bool bIntegral = (coordType == kCW_Integral);
+ bool bLowPrecision = (coordType == kCW_LowPrecision);
- i32 d = (i32)((angle / 360.0) * shift);
- d &= mask;
-
- WriteUBitLong((u32)d, numBits);
- }
-
- INLINE bool WriteBitsFromBuffer(BFRead* in, int numBits) {
- while (numBits > 32) {
- WriteUBitLong(in->ReadUBitLong(32), 32);
- numBits -= 32;
- }
-
- WriteUBitLong(in->ReadUBitLong(numBits), numBits);
- return !IsOverflowed() && !in->IsOverflowed();
- }
+ i32 intval = (i32)abs(f);
+ i32 fractval = bLowPrecision ? (abs((i32)(f * COORD_DENOMINATOR_LOWPRECISION)) & (COORD_DENOMINATOR_LOWPRECISION - 1)) :
+ (abs((i32)(f * COORD_DENOMINATOR)) & (COORD_DENOMINATOR - 1));
- /*INLINE void WriteBitAngles(const QAngle& fa) {
- // FIXME:
- Vector tmp(fa.x, fa.y, fa.z);
- WriteBitVec3Coord(tmp);
- }*/
+ if (bIntegral)
+ WriteUBitLong((u32)intval, bits);
+ else {
+ WriteUBitLong((u32)intval, bits);
+ WriteUBitLong((u32)fractval, bLowPrecision ? COORD_FRACTIONAL_BITS_MP_LOWPRECISION : COORD_FRACTIONAL_BITS);
+ }
+ }*/
-private:
- size_t m_DataBits = 0;
- size_t m_DataBytes = 0;
-
- u32 m_OutBufWord = 0;
- u32 m_OutBitsLeft = 32;
+ INLINE void SeekToBit(int bit)
+ {
+ TempFlush();
+
+ m_DataOut = m_Data + (bit / 32);
+ m_OutBufWord = LoadLittleDWord(m_DataOut, 0);
+ m_OutBitsLeft = 32 - (bit & 31);
+ }
+
+ /*INLINE void WriteBitVec3Coord(const Vector& fa) {
+ i32 xflag, yflag, zflag;
+
+ xflag = (fa[0] >= COORD_RESOLUTION) || (fa[0] <= -COORD_RESOLUTION);
+ yflag = (fa[1] >= COORD_RESOLUTION) || (fa[1] <= -COORD_RESOLUTION);
+ zflag = (fa[2] >= COORD_RESOLUTION) || (fa[2] <= -COORD_RESOLUTION);
+
+ WriteOneBit(xflag);
+ WriteOneBit(yflag);
+ WriteOneBit(zflag);
+
+ if (xflag)
+ WriteBitCoord(fa[0]);
+ if (yflag)
+ WriteBitCoord(fa[1]);
+ if (zflag)
+ WriteBitCoord(fa[2]);
+ }
+
+ INLINE void WriteBitNormal(float f) {
+ i32 signbit = (f <= -NORMAL_RESOLUTION);
+
+ // NOTE: Since +/-1 are valid values for a normal, I'm going to encode that as all ones
+ u32 fractval = abs((i32)(f * NORMAL_DENOMINATOR));
+
+ // clamp..
+ if (fractval > NORMAL_DENOMINATOR)
+ fractval = NORMAL_DENOMINATOR;
+
+ // Send the sign bit
+ WriteOneBit(signbit);
+
+ // Send the fractional component
+ WriteUBitLong(fractval, NORMAL_FRACTIONAL_BITS);
+ }
+
+ INLINE void WriteBitVec3Normal(const Vector& fa) {
+ i32 xflag, yflag;
+
+ xflag = (fa[0] >= NORMAL_RESOLUTION) || (fa[0] <= -NORMAL_RESOLUTION);
+ yflag = (fa[1] >= NORMAL_RESOLUTION) || (fa[1] <= -NORMAL_RESOLUTION);
+
+ WriteOneBit(xflag);
+ WriteOneBit(yflag);
+
+ if (xflag)
+ WriteBitNormal(fa[0]);
+ if (yflag)
+ WriteBitNormal(fa[1]);
+
+ // Write z sign bit
+ i32 signbit = (fa[2] <= -NORMAL_RESOLUTION);
+ WriteOneBit(signbit);
+ }*/
+
+ INLINE void WriteBitAngle(float angle, int numBits)
+ {
+ u32 shift = GetBitForBitnum(numBits);
+ u32 mask = shift - 1;
+
+ i32 d = (i32)((angle / 360.0) * shift);
+ d &= mask;
+
+ WriteUBitLong((u32)d, numBits);
+ }
+
+ INLINE bool WriteBitsFromBuffer(BFRead* in, int numBits)
+ {
+ while (numBits > 32)
+ {
+ WriteUBitLong(in->ReadUBitLong(32), 32);
+ numBits -= 32;
+ }
+
+ WriteUBitLong(in->ReadUBitLong(numBits), numBits);
+ return !IsOverflowed() && !in->IsOverflowed();
+ }
+
+ /*INLINE void WriteBitAngles(const QAngle& fa) {
+ // FIXME:
+ Vector tmp(fa.x, fa.y, fa.z);
+ WriteBitVec3Coord(tmp);
+ }*/
+
+ private:
+ size_t m_DataBits = 0;
+ size_t m_DataBytes = 0;
+
+ u32 m_OutBufWord = 0;
+ u32 m_OutBitsLeft = 32;
- u32* m_DataOut = nullptr;
- u32* m_DataEnd = nullptr;
- u32* m_Data = nullptr;
+ u32* m_DataOut = nullptr;
+ u32* m_DataEnd = nullptr;
+ u32* m_Data = nullptr;
- bool m_Flushed = false; // :flushed:
+ bool m_Flushed = false; // :flushed:
};
#undef INLINE \ No newline at end of file
diff --git a/NorthstarDedicatedTest/buildainfile.cpp b/NorthstarDedicatedTest/buildainfile.cpp
index 25c3254f..1eccd294 100644
--- a/NorthstarDedicatedTest/buildainfile.cpp
+++ b/NorthstarDedicatedTest/buildainfile.cpp
@@ -13,20 +13,20 @@ struct CAI_Node
float yaw;
float hulls[MAX_HULLS];
- int unk0; // always 2 in buildainfile, maps directly to unk0 in disk struct
- int unk1; // maps directly to unk1 in disk struct
+ int unk0; // always 2 in buildainfile, maps directly to unk0 in disk struct
+ int unk1; // maps directly to unk1 in disk struct
int unk2[MAX_HULLS]; // maps directly to unk2 in disk struct, despite being ints rather than shorts
// view server.dll+393672 for context and death wish
- char unk3[MAX_HULLS]; // hell on earth, should map to unk3 on disk
- char pad[3]; // aligns next bytes
+ char unk3[MAX_HULLS]; // hell on earth, should map to unk3 on disk
+ char pad[3]; // aligns next bytes
float unk4[MAX_HULLS]; // i have no fucking clue, calculated using some kind of demon hell function float magic
char unk5[32]; // padding until next bits i know
- short unk6; // should match up to unk4 on disk
+ short unk6; // should match up to unk4 on disk
char unk7[16]; // padding until next bit
- short unk8; // should match up to unk5 on disk
- char unk9[8]; // padding until next bit
+ short unk8; // should match up to unk5 on disk
+ char unk9[8]; // padding until next bit
char unk10[8]; // should match up to unk6 on disk
};
@@ -55,7 +55,7 @@ struct CAI_Network
CAI_Node** nodes;
};
-typedef void(*CAI_NetworkBuilder__BuildType)(void* builder, CAI_Network* aiNetwork, void* unknown);
+typedef void (*CAI_NetworkBuilder__BuildType)(void* builder, CAI_Network* aiNetwork, void* unknown);
CAI_NetworkBuilder__BuildType CAI_NetworkBuilder__Build;
void CAI_NetworkBuilder__BuildHook(void* builder, CAI_Network* aiNetwork, void* unknown)
@@ -74,18 +74,22 @@ void CAI_NetworkBuilder__BuildHook(void* builder, CAI_Network* aiNetwork, void*
spdlog::info("nodecount: {}", aiNetwork->nodecount);
for (int i = 0; i < aiNetwork->nodecount; i++)
{
- //spdlog::info("x = {}", aiNetwork->nodes[i]->x);
- //spdlog::info("y = {}", aiNetwork->nodes[i]->y);
- //spdlog::info("z = {}", aiNetwork->nodes[i]->z);
- //spdlog::info("yaw = {}", aiNetwork->nodes[i]->yaw);
- //spdlog::info("hulls = {} {} {} {} {}", aiNetwork->nodes[i]->hulls[0], aiNetwork->nodes[i]->hulls[1], aiNetwork->nodes[i]->hulls[2], aiNetwork->nodes[i]->hulls[3], aiNetwork->nodes[i]->hulls[4]);
+ // spdlog::info("x = {}", aiNetwork->nodes[i]->x);
+ // spdlog::info("y = {}", aiNetwork->nodes[i]->y);
+ // spdlog::info("z = {}", aiNetwork->nodes[i]->z);
+ // spdlog::info("yaw = {}", aiNetwork->nodes[i]->yaw);
+ // spdlog::info("hulls = {} {} {} {} {}", aiNetwork->nodes[i]->hulls[0], aiNetwork->nodes[i]->hulls[1],
+ // aiNetwork->nodes[i]->hulls[2], aiNetwork->nodes[i]->hulls[3], aiNetwork->nodes[i]->hulls[4]);
//
- //spdlog::info("unk0 = {} (should always be 2)", aiNetwork->nodes[i]->unk0);
- //spdlog::info("unk1 = {}", aiNetwork->nodes[i]->unk1);
- //spdlog::info("unk2 = {} {} {} {} {}", aiNetwork->nodes[i]->unk2[0], aiNetwork->nodes[i]->unk2[1], aiNetwork->nodes[i]->unk2[2], aiNetwork->nodes[i]->unk2[3], aiNetwork->nodes[i]->unk2[4]);
+ // spdlog::info("unk0 = {} (should always be 2)", aiNetwork->nodes[i]->unk0);
+ // spdlog::info("unk1 = {}", aiNetwork->nodes[i]->unk1);
+ // spdlog::info("unk2 = {} {} {} {} {}", aiNetwork->nodes[i]->unk2[0], aiNetwork->nodes[i]->unk2[1], aiNetwork->nodes[i]->unk2[2],
+ // aiNetwork->nodes[i]->unk2[3], aiNetwork->nodes[i]->unk2[4]);
//
- //spdlog::info("unk3 = {} {} {} {} {}", (int)aiNetwork->nodes[i]->unk3[0], (int)aiNetwork->nodes[i]->unk3[1], (int)aiNetwork->nodes[i]->unk3[2], (int)aiNetwork->nodes[i]->unk3[3], (int)aiNetwork->nodes[i]->unk3[4]);
- //spdlog::info("unk4 = {} {} {} {} {}", aiNetwork->nodes[i]->unk4[0], aiNetwork->nodes[i]->unk4[1], aiNetwork->nodes[i]->unk4[2], aiNetwork->nodes[i]->unk4[3], aiNetwork->nodes[i]->unk4[4]);
+ // spdlog::info("unk3 = {} {} {} {} {}", (int)aiNetwork->nodes[i]->unk3[0], (int)aiNetwork->nodes[i]->unk3[1],
+ // (int)aiNetwork->nodes[i]->unk3[2], (int)aiNetwork->nodes[i]->unk3[3], (int)aiNetwork->nodes[i]->unk3[4]); spdlog::info("unk4 = {}
+ // {} {} {} {}", aiNetwork->nodes[i]->unk4[0], aiNetwork->nodes[i]->unk4[1], aiNetwork->nodes[i]->unk4[2],
+ // aiNetwork->nodes[i]->unk4[3], aiNetwork->nodes[i]->unk4[4]);
// construct on-disk node struct
CAI_NodeDisk diskNode;
@@ -109,22 +113,27 @@ void CAI_NetworkBuilder__BuildHook(void* builder, CAI_Network* aiNetwork, void*
spdlog::info("y = {}", diskNode.y);
spdlog::info("z = {}", diskNode.z);
spdlog::info("yaw = {}", diskNode.yaw);
- spdlog::info("hulls = {} {} {} {} {}", diskNode.hulls[0], diskNode.hulls[1], diskNode.hulls[2], diskNode.hulls[3], diskNode.hulls[4]);
+ spdlog::info(
+ "hulls = {} {} {} {} {}", diskNode.hulls[0], diskNode.hulls[1], diskNode.hulls[2], diskNode.hulls[3], diskNode.hulls[4]);
spdlog::info("unk0 = {}", (int)diskNode.unk0);
spdlog::info("unk1 = {}", diskNode.unk1);
spdlog::info("unk2 = {} {} {} {} {}", diskNode.unk2[0], diskNode.unk2[1], diskNode.unk2[2], diskNode.unk2[3], diskNode.unk2[4]);
- spdlog::info("unk3 = {} {} {} {} {}", (int)diskNode.unk3[0], (int)diskNode.unk3[1], (int)diskNode.unk3[2], (int)diskNode.unk3[3], (int)diskNode.unk3[4]);
+ spdlog::info(
+ "unk3 = {} {} {} {} {}", (int)diskNode.unk3[0], (int)diskNode.unk3[1], (int)diskNode.unk3[2], (int)diskNode.unk3[3],
+ (int)diskNode.unk3[4]);
spdlog::info("unk4 = {}", diskNode.unk4);
spdlog::info("unk5 = {}", diskNode.unk5);
- spdlog::info("unk6 = {} {} {} {} {} {} {} {}", (int)diskNode.unk6[0], (int)diskNode.unk6[1], (int)diskNode.unk6[2], (int)diskNode.unk6[3], (int)diskNode.unk6[4], (int)diskNode.unk6[5], (int)diskNode.unk6[6], (int)diskNode.unk6[7]);
-
+ spdlog::info(
+ "unk6 = {} {} {} {} {} {} {} {}", (int)diskNode.unk6[0], (int)diskNode.unk6[1], (int)diskNode.unk6[2], (int)diskNode.unk6[3],
+ (int)diskNode.unk6[4], (int)diskNode.unk6[5], (int)diskNode.unk6[6], (int)diskNode.unk6[7]);
}
}
void InitialiseBuildAINFileHooks(HMODULE baseAddress)
{
HookEnabler hook;
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x385E20, &CAI_NetworkBuilder__BuildHook, reinterpret_cast<LPVOID*>(&CAI_NetworkBuilder__Build));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x385E20, &CAI_NetworkBuilder__BuildHook, reinterpret_cast<LPVOID*>(&CAI_NetworkBuilder__Build));
// remove a check that prevents a logging function in link generation from working
// due to the sheer amount of logging this is a massive perf hit to generation, but spewlog_enable 0 exists so whatever
diff --git a/NorthstarDedicatedTest/chatcommand.cpp b/NorthstarDedicatedTest/chatcommand.cpp
index c0f91e66..0540a9a0 100644
--- a/NorthstarDedicatedTest/chatcommand.cpp
+++ b/NorthstarDedicatedTest/chatcommand.cpp
@@ -5,7 +5,7 @@
// note: isIngameChat is an int64 because the whole register the arg is stored in needs to be 0'd out to work
// if isIngameChat is false, we use network chat instead
-typedef void(__fastcall *ClientSayTextType)(void* a1, const char* message, __int64 isIngameChat, bool isTeamChat);
+typedef void(__fastcall* ClientSayTextType)(void* a1, const char* message, __int64 isIngameChat, bool isTeamChat);
ClientSayTextType ClientSayText;
void ConCommand_say(const CCommand& args)
diff --git a/NorthstarDedicatedTest/clientauthhooks.cpp b/NorthstarDedicatedTest/clientauthhooks.cpp
index a139504d..41f0fd32 100644
--- a/NorthstarDedicatedTest/clientauthhooks.cpp
+++ b/NorthstarDedicatedTest/clientauthhooks.cpp
@@ -6,7 +6,7 @@
#include "masterserver.h"
#include "convar.h"
-typedef void(*AuthWithStryderType)(void* a1);
+typedef void (*AuthWithStryderType)(void* a1);
AuthWithStryderType AuthWithStryder;
ConVar* Cvar_ns_has_agreed_to_send_token;
@@ -23,7 +23,8 @@ void AuthWithStryderHook(void* a1)
if (!g_MasterServerManager->m_bOriginAuthWithMasterServerDone && Cvar_ns_has_agreed_to_send_token->m_nValue != DISAGREED_TO_SEND_TOKEN)
{
// 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 == AGREED_TO_SEND_TOKEN && !g_MasterServerManager->m_bOriginAuthWithMasterServerInProgress)
+ if (Cvar_ns_has_agreed_to_send_token->m_nValue == AGREED_TO_SEND_TOKEN &&
+ !g_MasterServerManager->m_bOriginAuthWithMasterServerInProgress)
g_MasterServerManager->AuthenticateOriginWithMasterServer(g_LocalPlayerUserID, g_LocalPlayerOriginToken);
// invalidate key so auth will fail
@@ -39,7 +40,9 @@ void InitialiseClientAuthHooks(HMODULE baseAddress)
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_ARCHIVE_PLAYERPROFILE, "whether the user has agreed to send their origin token to the northstar masterserver");
+ Cvar_ns_has_agreed_to_send_token = RegisterConVar(
+ "ns_has_agreed_to_send_token", "0", FCVAR_ARCHIVE_PLAYERPROFILE,
+ "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));
diff --git a/NorthstarDedicatedTest/concommand.cpp b/NorthstarDedicatedTest/concommand.cpp
index 2952e7e7..b876a05c 100644
--- a/NorthstarDedicatedTest/concommand.cpp
+++ b/NorthstarDedicatedTest/concommand.cpp
@@ -4,10 +4,11 @@
#include "misccommands.h"
#include <iostream>
-typedef void(*ConCommandConstructorType)(ConCommand* newCommand, const char* name, void(*callback)(const CCommand&), const char* helpString, int flags, void* parent);
+typedef void (*ConCommandConstructorType)(
+ ConCommand* newCommand, const char* name, void (*callback)(const CCommand&), const char* helpString, int flags, void* parent);
ConCommandConstructorType conCommandConstructor;
-void RegisterConCommand(const char* name, void(*callback)(const CCommand&), const char* helpString, int flags)
+void RegisterConCommand(const char* name, void (*callback)(const CCommand&), const char* helpString, int flags)
{
spdlog::info("Registering ConCommand {}", name);
@@ -18,8 +19,9 @@ void RegisterConCommand(const char* name, void(*callback)(const CCommand&), cons
ConCommand* FindConCommand(const char* name)
{
- ICvar* icvar = *g_pCvar; // hellish call because i couldn't get icvar vtable stuff in convar.h to get the right offset for whatever reason
- typedef ConCommand* (*FindCommandBaseType)(ICvar* self, const char* varName);
+ ICvar* icvar =
+ *g_pCvar; // hellish call because i couldn't get icvar vtable stuff in convar.h to get the right offset for whatever reason
+ typedef ConCommand* (*FindCommandBaseType)(ICvar * self, const char* varName);
FindCommandBaseType FindCommandBase = *(FindCommandBaseType*)((*(char**)icvar) + 112);
return FindCommandBase(icvar, name);
}
diff --git a/NorthstarDedicatedTest/concommand.h b/NorthstarDedicatedTest/concommand.h
index 7e610f91..c7458794 100644
--- a/NorthstarDedicatedTest/concommand.h
+++ b/NorthstarDedicatedTest/concommand.h
@@ -4,90 +4,73 @@
// taken from ttf2sdk
class ConCommand
{
- unsigned char unknown[0x68];
-public:
- virtual void EngineDestructor(void) {}
- virtual bool IsCommand(void) const { return false; }
- virtual bool IsFlagSet(int flag) { return false; }
- virtual void AddFlags(int flags) {}
- virtual void RemoveFlags(int flags) {}
- virtual int GetFlags() const { return 0; }
- virtual const char* GetName(void) const { return nullptr; }
- virtual const char* GetHelpText(void) const { return nullptr; }
- virtual bool IsRegistered(void) const { return false; }
- // NOTE: there are more virtual methods here
- // NOTE: Not using the engine's destructor here because it doesn't do anything useful for us
+ unsigned char unknown[0x68];
+
+ public:
+ virtual void EngineDestructor(void) {}
+ virtual bool IsCommand(void) const { return false; }
+ virtual bool IsFlagSet(int flag) { return false; }
+ virtual void AddFlags(int flags) {}
+ virtual void RemoveFlags(int flags) {}
+ virtual int GetFlags() const { return 0; }
+ virtual const char* GetName(void) const { return nullptr; }
+ virtual const char* GetHelpText(void) const { return nullptr; }
+ virtual bool IsRegistered(void) const { return false; }
+ // NOTE: there are more virtual methods here
+ // NOTE: Not using the engine's destructor here because it doesn't do anything useful for us
};
// From Source SDK
class CCommand
{
-public:
- CCommand() = delete;
+ public:
+ CCommand() = delete;
- int64_t ArgC() const;
- const char** ArgV() const;
- const char* ArgS() const; // All args that occur after the 0th arg, in string form
- const char* GetCommandString() const; // The entire command in string form, including the 0th arg
- const char* operator[](int nIndex) const; // Gets at arguments
- const char* Arg(int nIndex) const; // Gets at arguments
+ int64_t ArgC() const;
+ const char** ArgV() const;
+ const char* ArgS() const; // All args that occur after the 0th arg, in string form
+ const char* GetCommandString() const; // The entire command in string form, including the 0th arg
+ const char* operator[](int nIndex) const; // Gets at arguments
+ const char* Arg(int nIndex) const; // Gets at arguments
- static int MaxCommandLength();
+ static int MaxCommandLength();
-private:
- enum
- {
- COMMAND_MAX_ARGC = 64,
- COMMAND_MAX_LENGTH = 512,
- };
+ private:
+ enum
+ {
+ COMMAND_MAX_ARGC = 64,
+ COMMAND_MAX_LENGTH = 512,
+ };
- int64_t m_nArgc;
- int64_t m_nArgv0Size;
- char m_pArgSBuffer[COMMAND_MAX_LENGTH];
- char m_pArgvBuffer[COMMAND_MAX_LENGTH];
- const char* m_ppArgv[COMMAND_MAX_ARGC];
+ int64_t m_nArgc;
+ int64_t m_nArgv0Size;
+ char m_pArgSBuffer[COMMAND_MAX_LENGTH];
+ char m_pArgvBuffer[COMMAND_MAX_LENGTH];
+ const char* m_ppArgv[COMMAND_MAX_ARGC];
};
-inline int CCommand::MaxCommandLength()
-{
- return COMMAND_MAX_LENGTH - 1;
-}
+inline int CCommand::MaxCommandLength() { return COMMAND_MAX_LENGTH - 1; }
-inline int64_t CCommand::ArgC() const
-{
- return m_nArgc;
-}
+inline int64_t CCommand::ArgC() const { return m_nArgc; }
-inline const char** CCommand::ArgV() const
-{
- return m_nArgc ? (const char**)m_ppArgv : NULL;
-}
+inline const char** CCommand::ArgV() const { return m_nArgc ? (const char**)m_ppArgv : NULL; }
-inline const char* CCommand::ArgS() const
-{
- return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : "";
-}
+inline const char* CCommand::ArgS() const { return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : ""; }
-inline const char* CCommand::GetCommandString() const
-{
- return m_nArgc ? m_pArgSBuffer : "";
-}
+inline const char* CCommand::GetCommandString() const { return m_nArgc ? m_pArgSBuffer : ""; }
inline const char* CCommand::Arg(int nIndex) const
{
- // FIXME: Many command handlers appear to not be particularly careful
- // about checking for valid argc range. For now, we're going to
- // do the extra check and return an empty string if it's out of range
- if (nIndex < 0 || nIndex >= m_nArgc)
- return "";
- return m_ppArgv[nIndex];
+ // FIXME: Many command handlers appear to not be particularly careful
+ // about checking for valid argc range. For now, we're going to
+ // do the extra check and return an empty string if it's out of range
+ if (nIndex < 0 || nIndex >= m_nArgc)
+ return "";
+ return m_ppArgv[nIndex];
}
-inline const char* CCommand::operator[](int nIndex) const
-{
- return Arg(nIndex);
-}
+inline const char* CCommand::operator[](int nIndex) const { return Arg(nIndex); }
-void RegisterConCommand(const char* name, void(*callback)(const CCommand&), const char* helpString, int flags);
+void RegisterConCommand(const char* name, void (*callback)(const CCommand&), const char* helpString, int flags);
ConCommand* FindConCommand(const char* name);
void InitialiseConCommands(HMODULE baseAddress); \ No newline at end of file
diff --git a/NorthstarDedicatedTest/configurables.cpp b/NorthstarDedicatedTest/configurables.cpp
index 7096b2e9..e7dad8ca 100644
--- a/NorthstarDedicatedTest/configurables.cpp
+++ b/NorthstarDedicatedTest/configurables.cpp
@@ -2,31 +2,34 @@
#include "pch.h"
#include "configurables.h"
-std::string GetNorthstarPrefix() {
- return NORTHSTAR_FOLDER_PREFIX;
-}
+std::string GetNorthstarPrefix() { return NORTHSTAR_FOLDER_PREFIX; }
-void parseConfigurables() {
- char* clachar = strstr(GetCommandLineA(), "-profile=");
- if (clachar) {
- std::string cla = std::string(clachar);
- if (strncmp(cla.substr(9, 1).c_str(), "\"", 1)) {
- int space = cla.find(" ");
- std::string dirname = cla.substr(9, space - 9);
- spdlog::info("Found profile in command line arguments: " + dirname);
- NORTHSTAR_FOLDER_PREFIX = dirname;
- }
- else {
- std::string quote = "\"";
- int quote1 = cla.find(quote);
- int quote2 = (cla.substr(quote1 + 1)).find(quote);
- std::string dirname = cla.substr(quote1 + 1, quote2);
- spdlog::info("Found profile in command line arguments: " + dirname);
- NORTHSTAR_FOLDER_PREFIX = dirname;
- }
- }
- else {
- spdlog::info("Didnt' find profile in command line arguments. Using default: R2Northstar");
- NORTHSTAR_FOLDER_PREFIX = "R2Northstar";
- }
+void parseConfigurables()
+{
+ char* clachar = strstr(GetCommandLineA(), "-profile=");
+ if (clachar)
+ {
+ std::string cla = std::string(clachar);
+ if (strncmp(cla.substr(9, 1).c_str(), "\"", 1))
+ {
+ int space = cla.find(" ");
+ std::string dirname = cla.substr(9, space - 9);
+ spdlog::info("Found profile in command line arguments: " + dirname);
+ NORTHSTAR_FOLDER_PREFIX = dirname;
+ }
+ else
+ {
+ std::string quote = "\"";
+ int quote1 = cla.find(quote);
+ int quote2 = (cla.substr(quote1 + 1)).find(quote);
+ std::string dirname = cla.substr(quote1 + 1, quote2);
+ spdlog::info("Found profile in command line arguments: " + dirname);
+ NORTHSTAR_FOLDER_PREFIX = dirname;
+ }
+ }
+ else
+ {
+ spdlog::info("Didnt' find profile in command line arguments. Using default: R2Northstar");
+ NORTHSTAR_FOLDER_PREFIX = "R2Northstar";
+ }
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/context.cpp b/NorthstarDedicatedTest/context.cpp
index 17de66b3..7478faa3 100644
--- a/NorthstarDedicatedTest/context.cpp
+++ b/NorthstarDedicatedTest/context.cpp
@@ -9,6 +9,6 @@ const char* GetContextName(ScriptContext context)
return "SERVER";
else if (context == ScriptContext::UI)
return "UI";
-
+
return "";
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/convar.cpp b/NorthstarDedicatedTest/convar.cpp
index 324779b4..4157b42f 100644
--- a/NorthstarDedicatedTest/convar.cpp
+++ b/NorthstarDedicatedTest/convar.cpp
@@ -6,12 +6,13 @@
#include <set>
// should this be in modmanager?
-std::unordered_map<std::string, ConVar*> g_CustomConvars; // this is used in modloading code to determine whether we've registered a mod convar already
+std::unordered_map<std::string, ConVar*>
+ g_CustomConvars; // this is used in modloading code to determine whether we've registered a mod convar already
SourceInterface<ICvar>* g_pCvar;
-typedef void(*ConVarConstructorType)(ConVar* newVar, const char* name, const char* defaultValue, int flags, const char* helpString);
+typedef void (*ConVarConstructorType)(ConVar* newVar, const char* name, const char* defaultValue, int flags, const char* helpString);
ConVarConstructorType conVarConstructor;
-typedef bool(*CvarIsFlagSetType)(ConVar* self, int flags);
+typedef bool (*CvarIsFlagSetType)(ConVar* self, int flags);
CvarIsFlagSetType CvarIsFlagSet;
ConVar* RegisterConVar(const char* name, const char* defaultValue, int flags, const char* helpString)
@@ -29,8 +30,9 @@ ConVar* RegisterConVar(const char* name, const char* defaultValue, int flags, co
ConVar* FindConVar(const char* name)
{
- ICvar* icvar = *g_pCvar; // hellish call because i couldn't get icvar vtable stuff in convar.h to get the right offset for whatever reason
- typedef ConVar* (*FindConVarType)(ICvar* self, const char* varName);
+ ICvar* icvar =
+ *g_pCvar; // hellish call because i couldn't get icvar vtable stuff in convar.h to get the right offset for whatever reason
+ typedef ConVar* (*FindConVarType)(ICvar * self, const char* varName);
FindConVarType FindConVarInternal = *(FindConVarType*)((*(char**)icvar) + 128);
return FindConVarInternal(icvar, name);
}
diff --git a/NorthstarDedicatedTest/convar.h b/NorthstarDedicatedTest/convar.h
index df51edb7..30ab702b 100644
--- a/NorthstarDedicatedTest/convar.h
+++ b/NorthstarDedicatedTest/convar.h
@@ -4,57 +4,64 @@
// taken directly from iconvar.h
// The default, no flags at all
-#define FCVAR_NONE 0
+#define FCVAR_NONE 0
// Command to ConVars and ConCommands
// ConVar Systems
-#define FCVAR_UNREGISTERED (1<<0) // If this is set, don't add to linked list, etc.
-#define FCVAR_DEVELOPMENTONLY (1<<1) // Hidden in released products. Flag is removed automatically if ALLOW_DEVELOPMENT_CVARS is defined.
-#define FCVAR_GAMEDLL (1<<2) // defined by the game DLL
-#define FCVAR_CLIENTDLL (1<<3) // defined by the client DLL
-#define FCVAR_HIDDEN (1<<4) // Hidden. Doesn't appear in find or auto complete. Like DEVELOPMENTONLY, but can't be compiled out.
+#define FCVAR_UNREGISTERED (1 << 0) // If this is set, don't add to linked list, etc.
+#define FCVAR_DEVELOPMENTONLY (1 << 1) // Hidden in released products. Flag is removed automatically if ALLOW_DEVELOPMENT_CVARS is defined.
+#define FCVAR_GAMEDLL (1 << 2) // defined by the game DLL
+#define FCVAR_CLIENTDLL (1 << 3) // defined by the client DLL
+#define FCVAR_HIDDEN (1 << 4) // Hidden. Doesn't appear in find or auto complete. Like DEVELOPMENTONLY, but can't be compiled out.
// ConVar only
-#define FCVAR_PROTECTED (1<<5) // It's a server cvar, but we don't send the data since it's a password, etc. Sends 1 if it's not bland/zero, 0 otherwise as value
-#define FCVAR_SPONLY (1<<6) // This cvar cannot be changed by clients connected to a multiplayer server.
-#define FCVAR_ARCHIVE (1<<7) // set to cause it to be saved to vars.rc
-#define FCVAR_NOTIFY (1<<8) // notifies players when changed
-#define FCVAR_USERINFO (1<<9) // changes the client's info string
+#define FCVAR_PROTECTED \
+ (1 << 5) // It's a server cvar, but we don't send the data since it's a password, etc. Sends 1 if it's not bland/zero, 0 otherwise as
+ // value
+#define FCVAR_SPONLY (1 << 6) // This cvar cannot be changed by clients connected to a multiplayer server.
+#define FCVAR_ARCHIVE (1 << 7) // set to cause it to be saved to vars.rc
+#define FCVAR_NOTIFY (1 << 8) // notifies players when changed
+#define FCVAR_USERINFO (1 << 9) // changes the client's info string
-#define FCVAR_PRINTABLEONLY (1<<10) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ).
+#define FCVAR_PRINTABLEONLY (1 << 10) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ).
-#define FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS (1<<10) // When on concommands this allows remote clients to execute this cmd on the server.
- // We are changing the default behavior of concommands to disallow execution by remote clients without
- // this flag due to the number existing concommands that can lag or crash the server when clients abuse them.
+#define FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS \
+ (1 << 10) // When on concommands this allows remote clients to execute this cmd on the server.
+ // We are changing the default behavior of concommands to disallow execution by remote clients without
+ // this flag due to the number existing concommands that can lag or crash the server when clients abuse them.
-#define FCVAR_UNLOGGED (1<<11) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log
-#define FCVAR_NEVER_AS_STRING (1<<12) // never try to print that cvar
+#define FCVAR_UNLOGGED (1 << 11) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log
+#define FCVAR_NEVER_AS_STRING (1 << 12) // never try to print that cvar
// It's a ConVar that's shared between the client and the server.
// At signon, the values of all such ConVars are sent from the server to the client (skipped for local
// client, of course )
// If a change is requested it must come from the console (i.e., no remote client changes)
// If a value is changed while a server is active, it's replicated to all connected clients
-#define FCVAR_REPLICATED (1<<13) // server setting enforced on clients, TODO rename to FCAR_SERVER at some time
-#define FCVAR_CHEAT (1<<14) // Only useable in singleplayer / debug / multiplayer & sv_cheats
-#define FCVAR_SS (1<<15) // causes varnameN where N == 2 through max splitscreen slots for mod to be autogenerated
-#define FCVAR_DEMO (1<<16) // record this cvar when starting a demo file
-#define FCVAR_DONTRECORD (1<<17) // don't record these command in demofiles
-#define FCVAR_SS_ADDED (1<<18) // This is one of the "added" FCVAR_SS variables for the splitscreen players
-#define FCVAR_RELEASE (1<<19) // Cvars tagged with this are the only cvars avaliable to customers
-#define FCVAR_RELOAD_MATERIALS (1<<20) // If this cvar changes, it forces a material reload
-#define FCVAR_RELOAD_TEXTURES (1<<21) // If this cvar changes, if forces a texture reload
-
-#define FCVAR_NOT_CONNECTED (1<<22) // cvar cannot be changed by a client that is connected to a server
-#define FCVAR_MATERIAL_SYSTEM_THREAD (1<<23) // Indicates this cvar is read from the material system thread
-#define FCVAR_ARCHIVE_PLAYERPROFILE (1<<24) // respawn-defined flag, same as FCVAR_ARCHIVE but writes to profile.cfg
-
-#define FCVAR_SERVER_CAN_EXECUTE (1<<28)// the server is allowed to execute this command on clients via ClientCommand/NET_StringCmd/CBaseClientState::ProcessStringCmd.
-#define FCVAR_SERVER_CANNOT_QUERY (1<<29)// If this is set, then the server is not allowed to query this cvar's value (via IServerPluginHelpers::StartQueryCvarValue).
-#define FCVAR_CLIENTCMD_CAN_EXECUTE (1<<30) // IVEngineClient::ClientCmd is allowed to execute this command.
- // Note: IVEngineClient::ClientCmd_Unrestricted can run any client command.
-
-#define FCVAR_ACCESSIBLE_FROM_THREADS (1<<25) // used as a debugging tool necessary to check material system thread convars
+#define FCVAR_REPLICATED (1 << 13) // server setting enforced on clients, TODO rename to FCAR_SERVER at some time
+#define FCVAR_CHEAT (1 << 14) // Only useable in singleplayer / debug / multiplayer & sv_cheats
+#define FCVAR_SS (1 << 15) // causes varnameN where N == 2 through max splitscreen slots for mod to be autogenerated
+#define FCVAR_DEMO (1 << 16) // record this cvar when starting a demo file
+#define FCVAR_DONTRECORD (1 << 17) // don't record these command in demofiles
+#define FCVAR_SS_ADDED (1 << 18) // This is one of the "added" FCVAR_SS variables for the splitscreen players
+#define FCVAR_RELEASE (1 << 19) // Cvars tagged with this are the only cvars avaliable to customers
+#define FCVAR_RELOAD_MATERIALS (1 << 20) // If this cvar changes, it forces a material reload
+#define FCVAR_RELOAD_TEXTURES (1 << 21) // If this cvar changes, if forces a texture reload
+
+#define FCVAR_NOT_CONNECTED (1 << 22) // cvar cannot be changed by a client that is connected to a server
+#define FCVAR_MATERIAL_SYSTEM_THREAD (1 << 23) // Indicates this cvar is read from the material system thread
+#define FCVAR_ARCHIVE_PLAYERPROFILE (1 << 24) // respawn-defined flag, same as FCVAR_ARCHIVE but writes to profile.cfg
+
+#define FCVAR_SERVER_CAN_EXECUTE \
+ (1 << 28) // the server is allowed to execute this command on clients via
+ // ClientCommand/NET_StringCmd/CBaseClientState::ProcessStringCmd.
+#define FCVAR_SERVER_CANNOT_QUERY \
+ (1 << 29) // If this is set, then the server is not allowed to query this cvar's value (via IServerPluginHelpers::StartQueryCvarValue).
+#define FCVAR_CLIENTCMD_CAN_EXECUTE \
+ (1 << 30) // IVEngineClient::ClientCmd is allowed to execute this command.
+ // Note: IVEngineClient::ClientCmd_Unrestricted can run any client command.
+
+#define FCVAR_ACCESSIBLE_FROM_THREADS (1 << 25) // used as a debugging tool necessary to check material system thread convars
// #define FCVAR_AVAILABLE (1<<26)
// #define FCVAR_AVAILABLE (1<<27)
// #define FCVAR_AVAILABLE (1<<31)
@@ -65,44 +72,43 @@ class ConCommand;
// also i sure do hope this size is right because there's a fairly decent chance it isn't
class ConVar
{
-public:
+ public:
// if there are ever crashes caused by modifying custom cvars, check this
unsigned char unknown[0x40];
- char* m_pszString;
- size_t m_StringLength;
- float m_fValue;
- int32_t m_nValue;
- unsigned char unknown2[0x28];
-
-public:
- virtual void EngineDestructor(void) {}
- virtual bool IsCommand(void) const { return false; }
- virtual bool IsFlagSet(int flag) { return false; }
- virtual void AddFlags(int flags) {}
- virtual void RemoveFlags(int flags) {}
- virtual int GetFlags() const { return 0; }
- virtual const char* GetName(void) const { return nullptr; }
- virtual const char* GetHelpText(void) const { return nullptr; }
- virtual bool IsRegistered(void) const { return false; }
+ char* m_pszString;
+ size_t m_StringLength;
+ float m_fValue;
+ int32_t m_nValue;
+ unsigned char unknown2[0x28];
+
+ public:
+ virtual void EngineDestructor(void) {}
+ virtual bool IsCommand(void) const { return false; }
+ virtual bool IsFlagSet(int flag) { return false; }
+ virtual void AddFlags(int flags) {}
+ virtual void RemoveFlags(int flags) {}
+ virtual int GetFlags() const { return 0; }
+ virtual const char* GetName(void) const { return nullptr; }
+ virtual const char* GetHelpText(void) const { return nullptr; }
+ virtual bool IsRegistered(void) const { return false; }
};
class ICvar
{
-public:
- struct VTable
- {
- //void* unknown[10];
- //void(*UnregisterConCommand) (ICvar* cvar, ConCommand* pCommandBase);
- //void* unknown2[28];
- //ConVar*(*FindVar)(const char* var_name); // offset for this is currently very wrong
- char* unknown[112];
- ConCommand*(*FindCommandBase)(ICvar* self, const char* varName); // this offset is also wrong for some reason
- };
-
- VTable* m_vtable;
+ public:
+ struct VTable
+ {
+ // void* unknown[10];
+ // void(*UnregisterConCommand) (ICvar* cvar, ConCommand* pCommandBase);
+ // void* unknown2[28];
+ // ConVar*(*FindVar)(const char* var_name); // offset for this is currently very wrong
+ char* unknown[112];
+ ConCommand* (*FindCommandBase)(ICvar* self, const char* varName); // this offset is also wrong for some reason
+ };
+
+ VTable* m_vtable;
};
-
ConVar* RegisterConVar(const char* name, const char* defaultValue, int flags, const char* helpString);
ConVar* FindConVar(const char* name);
void InitialiseConVars(HMODULE baseAddress);
diff --git a/NorthstarDedicatedTest/dedicated.cpp b/NorthstarDedicatedTest/dedicated.cpp
index e140281a..39f683e6 100644
--- a/NorthstarDedicatedTest/dedicated.cpp
+++ b/NorthstarDedicatedTest/dedicated.cpp
@@ -6,7 +6,7 @@
#include "masterserver.h"
bool IsDedicated()
{
- //return CommandLine()->CheckParm("-dedicated");
+ // return CommandLine()->CheckParm("-dedicated");
return strstr(GetCommandLineA(), "-dedicated");
}
@@ -27,12 +27,9 @@ struct CDedicatedExports
DedicatedRunServerType RunServer;
};
-void Sys_Printf(CDedicatedExports* dedicated, const char* msg)
-{
- spdlog::info("[DEDICATED PRINT] {}", msg);
-}
+void Sys_Printf(CDedicatedExports* dedicated, const char* msg) { spdlog::info("[DEDICATED PRINT] {}", msg); }
-typedef void(*CHostState__InitType)(CHostState* self);
+typedef void (*CHostState__InitType)(CHostState* self);
void RunServer(CDedicatedExports* dedicated)
{
@@ -54,8 +51,9 @@ void RunServer(CDedicatedExports* dedicated)
// ensure playlist initialises right, if we've not explicitly called setplaylist
SetCurrentPlaylist(GetCurrentPlaylistName());
-
- // 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
+
+ // 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;
@@ -65,7 +63,8 @@ void RunServer(CDedicatedExports* dedicated)
g_pEngine->Frame();
// only update the title after at least 500ms since the last update
- if ((frameStart - frameTitle) > 0.5) {
+ 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
@@ -73,19 +72,20 @@ void RunServer(CDedicatedExports* dedicated)
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(
+ "{} - {} {}/{} players ({})", g_MasterServerManager->ns_auth_srvName, 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)));
+ std::this_thread::sleep_for(
+ std::chrono::duration<double, std::ratio<1>>(Cvar_base_tickinterval_mp->m_fValue - fmin(Plat_FloatTime() - frameStart, 0.25)));
}
}
-typedef bool(*IsGameActiveWindowType)();
+typedef bool (*IsGameActiveWindowType)();
IsGameActiveWindowType IsGameActiveWindow;
-bool IsGameActiveWindowHook()
-{
- return true;
-}
+bool IsGameActiveWindowHook() { return true; }
HANDLE consoleInputThreadHandle = NULL;
@@ -212,7 +212,7 @@ void InitialiseDedicated(HMODULE engineAddress)
//*(ptr + 13) = (char)0x90;
//*(ptr + 14) = (char)0x90;
- * (ptr + 15) = (char)0x90;
+ *(ptr + 15) = (char)0x90;
*(ptr + 16) = (char)0x90;
*(ptr + 17) = (char)0x90;
*(ptr + 18) = (char)0x90;
@@ -258,7 +258,7 @@ void InitialiseDedicated(HMODULE engineAddress)
// // CEngineAPI::Connect
// char* ptr = (char*)engineAddress + 0x1C4E07;
// TempReadWrite rw(ptr);
- //
+ //
// // remove calls to register ui rpak asset types
// *ptr = 0x90;
// *(ptr + 1) = (char)0x90;
@@ -375,8 +375,8 @@ void InitialiseDedicated(HMODULE engineAddress)
*(ptr + 15) = (char)0x90;
}
- // note: previously had DisableDedicatedWindowCreation patches here, but removing those rn since they're all shit and unstable and bad and such
- // check commit history if any are needed for reimplementation
+ // note: previously had DisableDedicatedWindowCreation patches here, but removing those rn since they're all shit and unstable and bad
+ // and such check commit history if any are needed for reimplementation
{
// IVideoMode::CreateGameWindow
char* ptr = (char*)engineAddress + 0x1CD146;
@@ -423,8 +423,10 @@ void InitialiseDedicated(HMODULE engineAddress)
HANDLE stdIn = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode = 0;
- if (GetConsoleMode(stdIn, &mode)) {
- if (mode & ENABLE_QUICK_EDIT_MODE) {
+ if (GetConsoleMode(stdIn, &mode))
+ {
+ if (mode & ENABLE_QUICK_EDIT_MODE)
+ {
mode &= ~ENABLE_QUICK_EDIT_MODE;
mode &= ~ENABLE_MOUSE_INPUT;
@@ -433,19 +435,22 @@ void InitialiseDedicated(HMODULE engineAddress)
SetConsoleMode(stdIn, mode);
}
}
- } else spdlog::info("Quick Edit enabled by user request");
+ }
+ else
+ spdlog::info("Quick Edit enabled by user request");
// create console input thread
if (!CommandLine()->CheckParm("-noconsoleinput"))
consoleInputThreadHandle = CreateThread(0, 0, ConsoleInputThread, 0, 0, NULL);
- else spdlog::info("Console input disabled by user request");
+ else
+ spdlog::info("Console input disabled by user request");
}
void InitialiseDedicatedOrigin(HMODULE baseAddress)
{
// disable origin on dedicated
- // for any big ea lawyers, this can't be used to play the game without origin, game will throw a fit if you try to do anything without an origin id as a client
- // for dedi it's fine though, game doesn't care if origin is disabled as long as there's only a server
+ // for any big ea lawyers, this can't be used to play the game without origin, game will throw a fit if you try to do anything without
+ // an origin id as a client for dedi it's fine though, game doesn't care if origin is disabled as long as there's only a server
if (!IsDedicated())
return;
@@ -455,7 +460,7 @@ void InitialiseDedicatedOrigin(HMODULE baseAddress)
*ptr = (char)0xC3; // ret
}
-typedef void(*PrintFatalSquirrelErrorType)(void* sqvm);
+typedef void (*PrintFatalSquirrelErrorType)(void* sqvm);
PrintFatalSquirrelErrorType PrintFatalSquirrelError;
void PrintFatalSquirrelErrorHook(void* sqvm)
{
diff --git a/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp b/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp
index 1d0e13b6..5db3d629 100644
--- a/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp
+++ b/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp
@@ -5,20 +5,26 @@
#include "hookutils.h"
#include "gameutils.h"
-typedef HRESULT(*__stdcall D3D11CreateDeviceType)(void* pAdapter, int DriverType, HMODULE Software, UINT Flags, int* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, void** ppDevice, int* pFeatureLevel, void** ppImmediateContext);
+typedef HRESULT (*__stdcall D3D11CreateDeviceType)(
+ void* pAdapter, int DriverType, HMODULE Software, UINT Flags, int* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, void** ppDevice,
+ int* pFeatureLevel, void** ppImmediateContext);
D3D11CreateDeviceType D3D11CreateDevice;
-HRESULT __stdcall D3D11CreateDeviceHook(void* pAdapter, int DriverType, HMODULE Software, UINT Flags, int* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, void** ppDevice, int* pFeatureLevel, void** ppImmediateContext)
+HRESULT __stdcall D3D11CreateDeviceHook(
+ void* pAdapter, int DriverType, HMODULE Software, UINT Flags, int* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, void** ppDevice,
+ int* pFeatureLevel, void** ppImmediateContext)
{
// note: this is super duper temp pretty much just messing around with it
- // does run surprisingly well on dedi for a software driver tho if you ignore the +1gb ram usage at times, seems like dedi doesn't really call gpu much even with renderthread still being a thing
- // will be using this hook for actual d3d stubbing and stuff later
+ // does run surprisingly well on dedi for a software driver tho if you ignore the +1gb ram usage at times, seems like dedi doesn't
+ // really call gpu much even with renderthread still being a thing will be using this hook for actual d3d stubbing and stuff later
- // atm, i think the play might be to run d3d in software, and then just stub out any calls that allocate memory/use alot of resources (e.g. createtexture and that sorta thing)
+ // atm, i think the play might be to run d3d in software, and then just stub out any calls that allocate memory/use alot of resources
+ // (e.g. createtexture and that sorta thing)
if (CommandLine()->CheckParm("-softwared3d11"))
DriverType = 5; // D3D_DRIVER_TYPE_WARP
- return D3D11CreateDevice(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext);
+ return D3D11CreateDevice(
+ pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext);
}
void InitialiseDedicatedMaterialSystem(HMODULE baseAddress)
@@ -69,17 +75,17 @@ void InitialiseDedicatedMaterialSystem(HMODULE baseAddress)
// check commit history if needed
}
-typedef void*(*PakLoadAPI__LoadRpakType)(char* filename, void* unknown, int flags);
+typedef void* (*PakLoadAPI__LoadRpakType)(char* filename, void* unknown, int flags);
PakLoadAPI__LoadRpakType PakLoadAPI__LoadRpak;
void* PakLoadAPI__LoadRpakHook(char* filename, void* unknown, int flags)
{
spdlog::info("PakLoadAPI__LoadRpakHook {}", filename);
-
+
// on dedi, don't load any paks that aren't required
if (strncmp(filename, "common", 6))
return 0;
-
+
return PakLoadAPI__LoadRpak(filename, unknown, flags);
}
@@ -106,6 +112,6 @@ void InitialiseDedicatedRtechGame(HMODULE baseAddress)
HookEnabler hook;
// unfortunately this is unstable, seems to freeze when changing maps
- //ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0xB0F0, &PakLoadAPI__LoadRpakHook, reinterpret_cast<LPVOID*>(&PakLoadAPI__LoadRpak));
- //ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0xB170, &PakLoadAPI__LoadRpak2Hook, reinterpret_cast<LPVOID*>(&PakLoadAPI__LoadRpak2));
+ // ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0xB0F0, &PakLoadAPI__LoadRpakHook, reinterpret_cast<LPVOID*>(&PakLoadAPI__LoadRpak));
+ // ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0xB170, &PakLoadAPI__LoadRpak2Hook, reinterpret_cast<LPVOID*>(&PakLoadAPI__LoadRpak2));
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp
index 0ada0531..4cc0a84d 100644
--- a/NorthstarDedicatedTest/dllmain.cpp
+++ b/NorthstarDedicatedTest/dllmain.cpp
@@ -37,123 +37,120 @@
#include <string.h>
#include "pch.h"
-
bool initialised = false;
-BOOL APIENTRY DllMain( HMODULE hModule,
- DWORD ul_reason_for_call,
- LPVOID lpReserved
- )
+BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
- switch (ul_reason_for_call)
- {
- case DLL_PROCESS_ATTACH:
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- case DLL_PROCESS_DETACH:
- break;
- }
-
- return TRUE;
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+
+ return TRUE;
}
void WaitForDebugger(HMODULE baseAddress)
{
- // earlier waitfordebugger call than is in vanilla, just so we can debug stuff a little easier
- if (CommandLine()->CheckParm("-waitfordebugger"))
- {
- spdlog::info("waiting for debugger...");
-
- while (!IsDebuggerPresent())
- Sleep(100);
- }
+ // earlier waitfordebugger call than is in vanilla, just so we can debug stuff a little easier
+ if (CommandLine()->CheckParm("-waitfordebugger"))
+ {
+ spdlog::info("waiting for debugger...");
+
+ while (!IsDebuggerPresent())
+ Sleep(100);
+ }
}
bool InitialiseNorthstar()
{
- if (initialised)
- {
- //spdlog::warn("Called InitialiseNorthstar more than once!"); // it's actually 100% fine for that to happen
- return false;
- }
-
- initialised = true;
-
- parseConfigurables();
-
- SetEnvironmentVariableA("OPENSSL_ia32cap", "~0x200000200000000");
- curl_global_init_mem(CURL_GLOBAL_DEFAULT, _malloc_base, _free_base, _realloc_base, _strdup_base, _calloc_base);
-
- InitialiseLogging();
- InstallInitialHooks();
- CreateLogFiles();
- InitialiseInterfaceCreationHooks();
-
- AddDllLoadCallback("tier0.dll", InitialiseTier0GameUtilFunctions);
- AddDllLoadCallback("engine.dll", WaitForDebugger);
- AddDllLoadCallback("engine.dll", InitialiseEngineGameUtilFunctions);
- AddDllLoadCallback("server.dll", InitialiseServerGameUtilFunctions);
-
- // dedi patches
- {
- AddDllLoadCallback("tier0.dll", InitialiseDedicatedOrigin);
- AddDllLoadCallback("engine.dll", InitialiseDedicated);
- AddDllLoadCallback("server.dll", InitialiseDedicatedServerGameDLL);
- AddDllLoadCallback("materialsystem_dx11.dll", InitialiseDedicatedMaterialSystem);
- // this fucking sucks, but seemingly we somehow load after rtech_game???? unsure how, but because of this we have to apply patches here, not on rtech_game load
- AddDllLoadCallback("engine.dll", InitialiseDedicatedRtechGame);
- }
-
- AddDllLoadCallback("engine.dll", InitialiseConVars);
- AddDllLoadCallback("engine.dll", InitialiseConCommands);
-
- // client-exclusive patches
- {
- AddDllLoadCallback("tier0.dll", InitialiseTier0LanguageHooks);
- AddDllLoadCallback("engine.dll", InitialiseClientEngineSecurityPatches);
- AddDllLoadCallback("client.dll", InitialiseClientSquirrel);
- AddDllLoadCallback("client.dll", InitialiseSourceConsole);
- AddDllLoadCallback("engine.dll", InitialiseChatCommands);
- AddDllLoadCallback("client.dll", InitialiseScriptModMenu);
- AddDllLoadCallback("client.dll", InitialiseScriptServerBrowser);
- AddDllLoadCallback("localize.dll", InitialiseModLocalisation);
- AddDllLoadCallback("engine.dll", InitialiseClientAuthHooks);
- AddDllLoadCallback("client.dll", InitialiseLatencyFleX);
- AddDllLoadCallback("engine.dll", InitialiseScriptExternalBrowserHooks);
- AddDllLoadCallback("client.dll", InitialiseScriptMainMenuPromos);
- AddDllLoadCallback("client.dll", InitialiseMiscClientFixes);
- AddDllLoadCallback("client.dll", InitialiseClientPrintHooks);
- }
-
- AddDllLoadCallback("engine.dll", InitialiseEngineSpewFuncHooks);
- AddDllLoadCallback("server.dll", InitialiseServerSquirrel);
- AddDllLoadCallback("engine.dll", InitialiseBanSystem);
- AddDllLoadCallback("engine.dll", InitialiseServerAuthentication);
- AddDllLoadCallback("server.dll", InitialiseServerAuthenticationServerDLL);
- AddDllLoadCallback("engine.dll", InitialiseSharedMasterServer);
- AddDllLoadCallback("server.dll", InitialiseMiscServerScriptCommand);
- AddDllLoadCallback("server.dll", InitialiseMiscServerFixes);
- AddDllLoadCallback("server.dll", InitialiseBuildAINFileHooks);
-
- AddDllLoadCallback("engine.dll", InitialisePlaylistHooks);
-
- AddDllLoadCallback("filesystem_stdio.dll", InitialiseFilesystem);
- AddDllLoadCallback("engine.dll", InitialiseEngineRpakFilesystem);
- AddDllLoadCallback("engine.dll", InitialiseKeyValues);
-
- // maxplayers increase
- AddDllLoadCallback("engine.dll", InitialiseMaxPlayersOverride_Engine);
- AddDllLoadCallback("client.dll", InitialiseMaxPlayersOverride_Client);
- AddDllLoadCallback("server.dll", InitialiseMaxPlayersOverride_Server);
-
- // audio hooks
- AddDllLoadCallback("client.dll", InitialiseMilesAudioHooks);
-
- // mod manager after everything else
- AddDllLoadCallback("engine.dll", InitialiseModManager);
-
- // run callbacks for any libraries that are already loaded by now
- CallAllPendingDLLLoadCallbacks();
-
- return true;
+ if (initialised)
+ {
+ // spdlog::warn("Called InitialiseNorthstar more than once!"); // it's actually 100% fine for that to happen
+ return false;
+ }
+
+ initialised = true;
+
+ parseConfigurables();
+
+ SetEnvironmentVariableA("OPENSSL_ia32cap", "~0x200000200000000");
+ curl_global_init_mem(CURL_GLOBAL_DEFAULT, _malloc_base, _free_base, _realloc_base, _strdup_base, _calloc_base);
+
+ InitialiseLogging();
+ InstallInitialHooks();
+ CreateLogFiles();
+ InitialiseInterfaceCreationHooks();
+
+ AddDllLoadCallback("tier0.dll", InitialiseTier0GameUtilFunctions);
+ AddDllLoadCallback("engine.dll", WaitForDebugger);
+ AddDllLoadCallback("engine.dll", InitialiseEngineGameUtilFunctions);
+ AddDllLoadCallback("server.dll", InitialiseServerGameUtilFunctions);
+
+ // dedi patches
+ {
+ AddDllLoadCallback("tier0.dll", InitialiseDedicatedOrigin);
+ AddDllLoadCallback("engine.dll", InitialiseDedicated);
+ AddDllLoadCallback("server.dll", InitialiseDedicatedServerGameDLL);
+ AddDllLoadCallback("materialsystem_dx11.dll", InitialiseDedicatedMaterialSystem);
+ // this fucking sucks, but seemingly we somehow load after rtech_game???? unsure how, but because of this we have to apply patches
+ // here, not on rtech_game load
+ AddDllLoadCallback("engine.dll", InitialiseDedicatedRtechGame);
+ }
+
+ AddDllLoadCallback("engine.dll", InitialiseConVars);
+ AddDllLoadCallback("engine.dll", InitialiseConCommands);
+
+ // client-exclusive patches
+ {
+ AddDllLoadCallback("tier0.dll", InitialiseTier0LanguageHooks);
+ AddDllLoadCallback("engine.dll", InitialiseClientEngineSecurityPatches);
+ AddDllLoadCallback("client.dll", InitialiseClientSquirrel);
+ AddDllLoadCallback("client.dll", InitialiseSourceConsole);
+ AddDllLoadCallback("engine.dll", InitialiseChatCommands);
+ AddDllLoadCallback("client.dll", InitialiseScriptModMenu);
+ AddDllLoadCallback("client.dll", InitialiseScriptServerBrowser);
+ AddDllLoadCallback("localize.dll", InitialiseModLocalisation);
+ AddDllLoadCallback("engine.dll", InitialiseClientAuthHooks);
+ AddDllLoadCallback("client.dll", InitialiseLatencyFleX);
+ AddDllLoadCallback("engine.dll", InitialiseScriptExternalBrowserHooks);
+ AddDllLoadCallback("client.dll", InitialiseScriptMainMenuPromos);
+ AddDllLoadCallback("client.dll", InitialiseMiscClientFixes);
+ AddDllLoadCallback("client.dll", InitialiseClientPrintHooks);
+ }
+
+ AddDllLoadCallback("engine.dll", InitialiseEngineSpewFuncHooks);
+ AddDllLoadCallback("server.dll", InitialiseServerSquirrel);
+ AddDllLoadCallback("engine.dll", InitialiseBanSystem);
+ AddDllLoadCallback("engine.dll", InitialiseServerAuthentication);
+ AddDllLoadCallback("server.dll", InitialiseServerAuthenticationServerDLL);
+ AddDllLoadCallback("engine.dll", InitialiseSharedMasterServer);
+ AddDllLoadCallback("server.dll", InitialiseMiscServerScriptCommand);
+ AddDllLoadCallback("server.dll", InitialiseMiscServerFixes);
+ AddDllLoadCallback("server.dll", InitialiseBuildAINFileHooks);
+
+ AddDllLoadCallback("engine.dll", InitialisePlaylistHooks);
+
+ AddDllLoadCallback("filesystem_stdio.dll", InitialiseFilesystem);
+ AddDllLoadCallback("engine.dll", InitialiseEngineRpakFilesystem);
+ AddDllLoadCallback("engine.dll", InitialiseKeyValues);
+
+ // maxplayers increase
+ AddDllLoadCallback("engine.dll", InitialiseMaxPlayersOverride_Engine);
+ AddDllLoadCallback("client.dll", InitialiseMaxPlayersOverride_Client);
+ AddDllLoadCallback("server.dll", InitialiseMaxPlayersOverride_Server);
+
+ // audio hooks
+ AddDllLoadCallback("client.dll", InitialiseMilesAudioHooks);
+
+ // mod manager after everything else
+ AddDllLoadCallback("engine.dll", InitialiseModManager);
+
+ // run callbacks for any libraries that are already loaded by now
+ CallAllPendingDLLLoadCallbacks();
+
+ return true;
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/filesystem.cpp b/NorthstarDedicatedTest/filesystem.cpp
index a8382db3..951198af 100644
--- a/NorthstarDedicatedTest/filesystem.cpp
+++ b/NorthstarDedicatedTest/filesystem.cpp
@@ -9,19 +9,20 @@
#include <sstream>
// hook forward declares
-typedef FileHandle_t(*ReadFileFromVPKType)(VPKData* vpkInfo, __int64* b, char* filename);
+typedef FileHandle_t (*ReadFileFromVPKType)(VPKData* vpkInfo, __int64* b, char* filename);
ReadFileFromVPKType readFileFromVPK;
FileHandle_t ReadFileFromVPKHook(VPKData* vpkInfo, __int64* b, char* filename);
-typedef bool(*ReadFromCacheType)(IFileSystem* filesystem, char* path, void* result);
+typedef bool (*ReadFromCacheType)(IFileSystem* filesystem, char* path, void* result);
ReadFromCacheType readFromCache;
bool ReadFromCacheHook(IFileSystem* filesystem, char* path, void* result);
-typedef void(*AddSearchPathType)(IFileSystem* fileSystem, const char* pPath, const char* pathID, SearchPathAdd_t addType);
+typedef void (*AddSearchPathType)(IFileSystem* fileSystem, const char* pPath, const char* pathID, SearchPathAdd_t addType);
AddSearchPathType addSearchPathOriginal;
void AddSearchPathHook(IFileSystem* fileSystem, const char* pPath, const char* pathID, SearchPathAdd_t addType);
-typedef FileHandle_t(*ReadFileFromFilesystemType)(IFileSystem* filesystem, const char* pPath, const char* pOptions, int64_t a4, uint32_t a5);
+typedef FileHandle_t (*ReadFileFromFilesystemType)(
+ IFileSystem* filesystem, const char* pPath, const char* pOptions, int64_t a4, uint32_t a5);
ReadFileFromFilesystemType readFileFromFilesystem;
FileHandle_t ReadFileFromFilesystemHook(IFileSystem* filesystem, const char* pPath, const char* pOptions, int64_t a4, uint32_t a5);
@@ -42,7 +43,8 @@ void InitialiseFilesystem(HMODULE baseAddress)
HookEnabler hook;
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x5CBA0, &ReadFileFromVPKHook, reinterpret_cast<LPVOID*>(&readFileFromVPK));
ENABLER_CREATEHOOK(hook, (*g_Filesystem)->m_vtable->ReadFromCache, &ReadFromCacheHook, reinterpret_cast<LPVOID*>(&readFromCache));
- ENABLER_CREATEHOOK(hook, (*g_Filesystem)->m_vtable->AddSearchPath, &AddSearchPathHook, reinterpret_cast<LPVOID*>(&addSearchPathOriginal));
+ ENABLER_CREATEHOOK(
+ hook, (*g_Filesystem)->m_vtable->AddSearchPath, &AddSearchPathHook, reinterpret_cast<LPVOID*>(&addSearchPathOriginal));
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x15F20, &ReadFileFromFilesystemHook, reinterpret_cast<LPVOID*>(&readFileFromFilesystem));
ENABLER_CREATEHOOK(hook, (*g_Filesystem)->m_vtable->MountVPK, &MountVPKHook, reinterpret_cast<LPVOID*>(&mountVPK));
}
@@ -85,13 +87,13 @@ void SetNewModSearchPaths(Mod* mod)
{
spdlog::info("changing mod search path from {} to {}", currentModPath, mod->ModDirectory.string());
- addSearchPathOriginal(&*(*g_Filesystem), (fs::absolute(mod->ModDirectory) / MOD_OVERRIDE_DIR).string().c_str(), "GAME", PATH_ADD_TO_HEAD);
+ addSearchPathOriginal(
+ &*(*g_Filesystem), (fs::absolute(mod->ModDirectory) / MOD_OVERRIDE_DIR).string().c_str(), "GAME", PATH_ADD_TO_HEAD);
currentModPath = (fs::absolute(mod->ModDirectory) / MOD_OVERRIDE_DIR).string();
}
}
else // push compiled to head
addSearchPathOriginal(&*(*g_Filesystem), fs::absolute(GetCompiledAssetsPath()).string().c_str(), "GAME", PATH_ADD_TO_HEAD);
-
}
bool TryReplaceFile(char* path, bool shouldCompile)
@@ -117,9 +119,10 @@ bool TryReplaceFile(char* path, bool shouldCompile)
FileHandle_t ReadFileFromVPKHook(VPKData* vpkInfo, __int64* b, char* filename)
{
// move this to a convar at some point when we can read them in native
- //spdlog::info("ReadFileFromVPKHook {} {}", filename, vpkInfo->path);
+ // spdlog::info("ReadFileFromVPKHook {} {}", filename, vpkInfo->path);
- // there is literally never any reason to compile here, since we'll always compile in ReadFileFromFilesystemHook in the same codepath this is called
+ // there is literally never any reason to compile here, since we'll always compile in ReadFileFromFilesystemHook in the same codepath
+ // this is called
if (TryReplaceFile(filename, false))
{
*b = -1;
@@ -132,7 +135,7 @@ FileHandle_t ReadFileFromVPKHook(VPKData* vpkInfo, __int64* b, char* filename)
bool ReadFromCacheHook(IFileSystem* filesystem, char* path, void* result)
{
// move this to a convar at some point when we can read them in native
- //spdlog::info("ReadFromCacheHook {}", path);
+ // spdlog::info("ReadFromCacheHook {}", path);
if (TryReplaceFile(path, true))
return false;
diff --git a/NorthstarDedicatedTest/filesystem.h b/NorthstarDedicatedTest/filesystem.h
index cf93df8d..960c2836 100644
--- a/NorthstarDedicatedTest/filesystem.h
+++ b/NorthstarDedicatedTest/filesystem.h
@@ -4,66 +4,67 @@
// taken from ttf2sdk
typedef void* FileHandle_t;
-#pragma pack(push,1)
+#pragma pack(push, 1)
struct VPKFileEntry
{
- char* directory;
- char* filename;
- char* extension;
- unsigned char unknown[0x38];
+ char* directory;
+ char* filename;
+ char* extension;
+ unsigned char unknown[0x38];
};
#pragma pack(pop)
-#pragma pack(push,1)
+#pragma pack(push, 1)
struct VPKData
{
- unsigned char unknown[5];
- char path[255];
- unsigned char unknown2[0x134];
- int32_t numEntries;
- unsigned char unknown3[12];
- VPKFileEntry* entries;
+ unsigned char unknown[5];
+ char path[255];
+ unsigned char unknown2[0x134];
+ int32_t numEntries;
+ unsigned char unknown3[12];
+ VPKFileEntry* entries;
};
#pragma pack(pop)
enum SearchPathAdd_t
{
- PATH_ADD_TO_HEAD, // First path searched
- PATH_ADD_TO_TAIL, // Last path searched
+ PATH_ADD_TO_HEAD, // First path searched
+ PATH_ADD_TO_TAIL, // Last path searched
};
class CSearchPath
{
-public:
- unsigned char unknown[0x18];
- const char* debugPath;
+ public:
+ unsigned char unknown[0x18];
+ const char* debugPath;
};
class IFileSystem
{
-public:
- struct VTable
- {
- void* unknown[10];
- void(*AddSearchPath) (IFileSystem* fileSystem, const char* pPath, const char* pathID, SearchPathAdd_t addType);
- void* unknown2[84];
- bool(*ReadFromCache) (IFileSystem* fileSystem, const char* path, void* result);
- void* unknown3[15];
- VPKData* (*MountVPK) (IFileSystem* fileSystem, const char* vpkPath);
- };
+ public:
+ struct VTable
+ {
+ void* unknown[10];
+ void (*AddSearchPath)(IFileSystem* fileSystem, const char* pPath, const char* pathID, SearchPathAdd_t addType);
+ void* unknown2[84];
+ bool (*ReadFromCache)(IFileSystem* fileSystem, const char* path, void* result);
+ void* unknown3[15];
+ VPKData* (*MountVPK)(IFileSystem* fileSystem, const char* vpkPath);
+ };
- struct VTable2
- {
- int(*Read) (IFileSystem::VTable2** fileSystem, void* pOutput, int size, FileHandle_t file);
- void* unknown[1];
- FileHandle_t(*Open) (IFileSystem::VTable2** fileSystem, const char* pFileName, const char* pOptions, const char* pathID, int64_t unknown);
- void(*Close) (IFileSystem* fileSystem, FileHandle_t file);
- void* unknown2[6];
- bool(*FileExists)(IFileSystem::VTable2** fileSystem, const char* pFileName, const char* pPathID);
- };
+ struct VTable2
+ {
+ int (*Read)(IFileSystem::VTable2** fileSystem, void* pOutput, int size, FileHandle_t file);
+ void* unknown[1];
+ FileHandle_t (*Open)(
+ IFileSystem::VTable2** fileSystem, const char* pFileName, const char* pOptions, const char* pathID, int64_t unknown);
+ void (*Close)(IFileSystem* fileSystem, FileHandle_t file);
+ void* unknown2[6];
+ bool (*FileExists)(IFileSystem::VTable2** fileSystem, const char* pFileName, const char* pPathID);
+ };
- VTable* m_vtable;
- VTable2* m_vtable2;
+ VTable* m_vtable;
+ VTable2* m_vtable2;
};
std::string ReadVPKFile(const char* path);
diff --git a/NorthstarDedicatedTest/gameutils.h b/NorthstarDedicatedTest/gameutils.h
index 48ad75e4..f382d6c0 100644
--- a/NorthstarDedicatedTest/gameutils.h
+++ b/NorthstarDedicatedTest/gameutils.h
@@ -4,36 +4,36 @@
// memory
class IMemAlloc
{
-public:
+ public:
struct VTable
{
void* unknown[1]; // alloc debug
- void* (*Alloc) (IMemAlloc* memAlloc, size_t nSize);
+ void* (*Alloc)(IMemAlloc* memAlloc, size_t nSize);
void* unknown2[1]; // realloc debug
void* (*Realloc)(IMemAlloc* memAlloc, void* pMem, size_t nSize);
void* unknown3[1]; // free #1
- void (*Free) (IMemAlloc* memAlloc, void* pMem);
+ void (*Free)(IMemAlloc* memAlloc, void* pMem);
void* unknown4[2]; // nullsubs, maybe CrtSetDbgFlag
- size_t(*GetSize) (IMemAlloc* memAlloc, void* pMem);
+ size_t (*GetSize)(IMemAlloc* memAlloc, void* pMem);
void* unknown5[9]; // they all do literally nothing
- void (*DumpStats) (IMemAlloc* memAlloc);
- void (*DumpStatsFileBase) (IMemAlloc* memAlloc, const char* pchFileBase);
+ void (*DumpStats)(IMemAlloc* memAlloc);
+ void (*DumpStatsFileBase)(IMemAlloc* memAlloc, const char* pchFileBase);
void* unknown6[4];
- int (*heapchk) (IMemAlloc* memAlloc);
+ int (*heapchk)(IMemAlloc* memAlloc);
};
VTable* m_vtable;
};
extern IMemAlloc* g_pMemAllocSingleton;
-typedef IMemAlloc*(*CreateGlobalMemAllocType)();
+typedef IMemAlloc* (*CreateGlobalMemAllocType)();
extern CreateGlobalMemAllocType CreateGlobalMemAlloc;
// cmd.h
enum class ECommandTarget_t
{
CBUF_FIRST_PLAYER = 0,
- CBUF_LAST_PLAYER = 1, // MAX_SPLITSCREEN_CLIENTS - 1, MAX_SPLITSCREEN_CLIENTS = 2
+ CBUF_LAST_PLAYER = 1, // MAX_SPLITSCREEN_CLIENTS - 1, MAX_SPLITSCREEN_CLIENTS = 2
CBUF_SERVER = CBUF_LAST_PLAYER + 1,
CBUF_COUNT,
@@ -75,20 +75,20 @@ enum class cmd_source_t
kCommandSrcInvalid = -1
};
-typedef ECommandTarget_t(*Cbuf_GetCurrentPlayerType)();
+typedef ECommandTarget_t (*Cbuf_GetCurrentPlayerType)();
extern Cbuf_GetCurrentPlayerType Cbuf_GetCurrentPlayer;
// compared to the defs i've seen, this is missing an arg, it could be nTickInterval or source, not sure, guessing it's source
-typedef void(*Cbuf_AddTextType)(ECommandTarget_t eTarget, const char* text, cmd_source_t source);
+typedef void (*Cbuf_AddTextType)(ECommandTarget_t eTarget, const char* text, cmd_source_t source);
extern Cbuf_AddTextType Cbuf_AddText;
-typedef void(*Cbuf_ExecuteType)();
+typedef void (*Cbuf_ExecuteType)();
extern Cbuf_ExecuteType Cbuf_Execute;
// commandline stuff
class CCommandLine
{
-public:
+ public:
// based on the defs in the 2013 source sdk, but for some reason has an extra function (may be another CreateCmdLine overload?)
// these seem to line up with what they should be though
virtual void CreateCmdLine(const char* commandline) {}
@@ -109,7 +109,7 @@ public:
virtual const char* GetParm(int nIndex) const {}
virtual void SetParm(int nIndex, char const* pParm) {}
- //virtual const char** GetParms() const {}
+ // virtual const char** GetParms() const {}
};
// hoststate stuff
@@ -127,7 +127,7 @@ enum HostState_t
struct CHostState
{
-public:
+ public:
HostState_t m_iCurrentState;
HostState_t m_iNextState;
@@ -138,16 +138,17 @@ public:
char m_mapGroupName[32];
char m_landmarkName[32];
char m_saveName[32];
- float m_flShortFrameTime; // run a few one-tick frames to avoid large timesteps while loading assets
-
- bool m_activeGame;
- bool m_bRememberLocation;
- bool m_bBackgroundLevel;
- bool m_bWaitingForConnection;
- bool m_bLetToolsOverrideLoadGameEnts; // During a load game, this tells Foundry to override ents that are selected in Hammer.
- bool m_bSplitScreenConnect;
- bool m_bGameHasShutDownAndFlushedMemory; // This is false once we load a map into memory, and set to true once the map is unloaded and all memory flushed
- bool m_bWorkshopMapDownloadPending;
+ float m_flShortFrameTime; // run a few one-tick frames to avoid large timesteps while loading assets
+
+ bool m_activeGame;
+ bool m_bRememberLocation;
+ bool m_bBackgroundLevel;
+ bool m_bWaitingForConnection;
+ bool m_bLetToolsOverrideLoadGameEnts; // During a load game, this tells Foundry to override ents that are selected in Hammer.
+ bool m_bSplitScreenConnect;
+ bool m_bGameHasShutDownAndFlushedMemory; // This is false once we load a map into memory, and set to true once the map is unloaded and
+ // all memory flushed
+ bool m_bWorkshopMapDownloadPending;
};
extern CHostState* g_pHostState;
@@ -162,17 +163,17 @@ enum EngineQuitState
enum EngineState_t
{
- DLL_INACTIVE = 0, // no dll
- DLL_ACTIVE, // engine is focused
- DLL_CLOSE, // closing down dll
- DLL_RESTART, // engine is shutting down but will restart right away
- DLL_PAUSED, // engine is paused, can become active from this state
+ DLL_INACTIVE = 0, // no dll
+ DLL_ACTIVE, // engine is focused
+ DLL_CLOSE, // closing down dll
+ DLL_RESTART, // engine is shutting down but will restart right away
+ DLL_PAUSED, // engine is paused, can become active from this state
};
class CEngine
{
-public:
- virtual void unknown() {} // unsure if this is where
+ public:
+ virtual void unknown() {} // unsure if this is where
virtual bool Load(bool dedicated, const char* baseDir) {}
virtual void Unload() {}
virtual void SetNextState(EngineState_t iNextState) {}
@@ -195,10 +196,10 @@ extern CEngine* g_pEngine;
enum server_state_t
{
- ss_dead = 0, // Dead
- ss_loading, // Spawning
- ss_active, // Running
- ss_paused, // Running, but paused
+ ss_dead = 0, // Dead
+ ss_loading, // Spawning
+ ss_active, // Running
+ ss_paused, // Running, but paused
};
extern server_state_t* sv_m_State;
@@ -208,20 +209,20 @@ extern ConVar* Cvar_hostport;
extern ConVar* Cvar_net_datablock_enabled;
// playlist stuff
-typedef const char*(*GetCurrentPlaylistType)();
+typedef const char* (*GetCurrentPlaylistType)();
extern GetCurrentPlaylistType GetCurrentPlaylistName;
-typedef void(*SetCurrentPlaylistType)(const char* playlistName);
+typedef void (*SetCurrentPlaylistType)(const char* playlistName);
extern SetCurrentPlaylistType SetCurrentPlaylist;
-typedef void(*SetPlaylistVarOverrideType)(const char* varName, const char* value);
+typedef void (*SetPlaylistVarOverrideType)(const char* varName, const char* value);
extern SetPlaylistVarOverrideType SetPlaylistVarOverride;
-typedef char*(*GetCurrentPlaylistVarType)(const char* varName, bool useOverrides);
+typedef char* (*GetCurrentPlaylistVarType)(const char* varName, bool useOverrides);
extern GetCurrentPlaylistVarType GetCurrentPlaylistVar;
// server entity stuff
-typedef void*(*Server_GetEntityByIndexType)(int index);
+typedef void* (*Server_GetEntityByIndexType)(int index);
extern Server_GetEntityByIndexType Server_GetEntityByIndex;
// server tickrate stuff
@@ -236,19 +237,19 @@ extern char* g_LocalPlayerOriginToken;
extern ConVar* Cvar_match_defaultMap;
extern ConVar* Cvar_communities_hostname;
-typedef void(*ErrorType)(const char* fmt, ...);
+typedef void (*ErrorType)(const char* fmt, ...);
extern ErrorType Error;
-typedef CCommandLine*(*CommandLineType)();
+typedef CCommandLine* (*CommandLineType)();
extern CommandLineType CommandLine;
-typedef double(*Plat_FloatTimeType)();
+typedef double (*Plat_FloatTimeType)();
extern Plat_FloatTimeType Plat_FloatTime;
-typedef bool(*ThreadInServerFrameThreadType)();
+typedef bool (*ThreadInServerFrameThreadType)();
extern ThreadInServerFrameThreadType ThreadInServerFrameThread;
-typedef void*(*GetBaseLocalClientType)();
+typedef void* (*GetBaseLocalClientType)();
extern GetBaseLocalClientType GetBaseLocalClient;
void InitialiseEngineGameUtilFunctions(HMODULE baseAddress);
diff --git a/NorthstarDedicatedTest/hooks.cpp b/NorthstarDedicatedTest/hooks.cpp
index cdb5fef9..7d7f39fb 100644
--- a/NorthstarDedicatedTest/hooks.cpp
+++ b/NorthstarDedicatedTest/hooks.cpp
@@ -11,19 +11,19 @@
#include <filesystem>
#include <Psapi.h>
-typedef LPSTR(*GetCommandLineAType)();
+typedef LPSTR (*GetCommandLineAType)();
LPSTR GetCommandLineAHook();
-typedef HMODULE(*LoadLibraryExAType)(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
+typedef HMODULE (*LoadLibraryExAType)(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
HMODULE LoadLibraryExAHook(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
-typedef HMODULE(*LoadLibraryAType)(LPCSTR lpLibFileName);
+typedef HMODULE (*LoadLibraryAType)(LPCSTR lpLibFileName);
HMODULE LoadLibraryAHook(LPCSTR lpLibFileName);
-typedef HMODULE(*LoadLibraryExWType)(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
+typedef HMODULE (*LoadLibraryExWType)(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
HMODULE LoadLibraryExWHook(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
-typedef HMODULE(*LoadLibraryWType)(LPCWSTR lpLibFileName);
+typedef HMODULE (*LoadLibraryWType)(LPCWSTR lpLibFileName);
HMODULE LoadLibraryWHook(LPCWSTR lpLibFileName);
GetCommandLineAType GetCommandLineAOriginal;
@@ -36,7 +36,7 @@ void InstallInitialHooks()
{
if (MH_Initialize() != MH_OK)
spdlog::error("MH_Initialize failed");
-
+
HookEnabler hook;
ENABLER_CREATEHOOK(hook, &GetCommandLineA, &GetCommandLineAHook, reinterpret_cast<LPVOID*>(&GetCommandLineAOriginal));
ENABLER_CREATEHOOK(hook, &LoadLibraryExA, &LoadLibraryExAHook, reinterpret_cast<LPVOID*>(&LoadLibraryExAOriginal));
@@ -73,9 +73,15 @@ 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 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);
+ 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());
}
@@ -88,7 +94,7 @@ LPSTR GetCommandLineAHook()
return cmdlineOrg;
}
memcpy(cmdlineModified, args.c_str(), len + 1);
-
+
spdlog::info("Command line: {}", cmdlineModified);
}
@@ -120,7 +126,8 @@ void CallLoadLibraryACallbacks(LPCSTR lpLibFileName, HMODULE moduleAddress)
{
for (auto& callbackStruct : dllLoadCallbacks)
{
- if (!callbackStruct->called && strstr(lpLibFileName + (strlen(lpLibFileName) - callbackStruct->dll.length()), callbackStruct->dll.c_str()) != nullptr)
+ if (!callbackStruct->called &&
+ strstr(lpLibFileName + (strlen(lpLibFileName) - callbackStruct->dll.length()), callbackStruct->dll.c_str()) != nullptr)
{
callbackStruct->callback(moduleAddress);
callbackStruct->called = true;
@@ -168,7 +175,7 @@ void CallAllPendingDLLLoadCallbacks()
HMODULE LoadLibraryExAHook(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
{
HMODULE moduleAddress = LoadLibraryExAOriginal(lpLibFileName, hFile, dwFlags);
-
+
if (moduleAddress)
{
CallLoadLibraryACallbacks(lpLibFileName, moduleAddress);
diff --git a/NorthstarDedicatedTest/hooks.h b/NorthstarDedicatedTest/hooks.h
index 10e4d4ba..45695990 100644
--- a/NorthstarDedicatedTest/hooks.h
+++ b/NorthstarDedicatedTest/hooks.h
@@ -3,7 +3,7 @@
void InstallInitialHooks();
-typedef void(*DllLoadCallbackFuncType)(HMODULE moduleAddress);
+typedef void (*DllLoadCallbackFuncType)(HMODULE moduleAddress);
void AddDllLoadCallback(std::string dll, DllLoadCallbackFuncType callback);
void CallAllPendingDLLLoadCallbacks(); \ No newline at end of file
diff --git a/NorthstarDedicatedTest/hookutils.cpp b/NorthstarDedicatedTest/hookutils.cpp
index 8ab24a3b..b7d82724 100644
--- a/NorthstarDedicatedTest/hookutils.cpp
+++ b/NorthstarDedicatedTest/hookutils.cpp
@@ -5,57 +5,56 @@
TempReadWrite::TempReadWrite(void* ptr)
{
- m_ptr = ptr;
- MEMORY_BASIC_INFORMATION mbi;
- VirtualQuery(m_ptr, &mbi, sizeof(mbi));
- VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &mbi.Protect);
- m_origProtection = mbi.Protect;
+ m_ptr = ptr;
+ MEMORY_BASIC_INFORMATION mbi;
+ VirtualQuery(m_ptr, &mbi, sizeof(mbi));
+ VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &mbi.Protect);
+ m_origProtection = mbi.Protect;
}
TempReadWrite::~TempReadWrite()
{
- MEMORY_BASIC_INFORMATION mbi;
- VirtualQuery(m_ptr, &mbi, sizeof(mbi));
- VirtualProtect(mbi.BaseAddress, mbi.RegionSize, m_origProtection, &mbi.Protect);
+ MEMORY_BASIC_INFORMATION mbi;
+ VirtualQuery(m_ptr, &mbi, sizeof(mbi));
+ VirtualProtect(mbi.BaseAddress, mbi.RegionSize, m_origProtection, &mbi.Protect);
}
-
void HookEnabler::CreateHook(LPVOID ppTarget, LPVOID ppDetour, LPVOID* ppOriginal, const char* targetName)
{
- // the macro for this uses ppTarget's name as targetName, and this typically starts with &
- // targetname is used for debug stuff and debug output is nicer if we don't have this
- if (*targetName == '&')
- targetName++;
-
- if (MH_CreateHook(ppTarget, ppDetour, ppOriginal) == MH_OK)
- {
- HookTarget *target = new HookTarget;
- target->targetAddress = ppTarget;
- target->targetName = (char*)targetName;
-
- m_hookTargets.push_back(target);
- }
- else
- {
- if (targetName != nullptr)
- spdlog::error("MH_CreateHook failed for function {}", targetName);
- else
- spdlog::error("MH_CreateHook failed for unknown function");
- }
+ // the macro for this uses ppTarget's name as targetName, and this typically starts with &
+ // targetname is used for debug stuff and debug output is nicer if we don't have this
+ if (*targetName == '&')
+ targetName++;
+
+ if (MH_CreateHook(ppTarget, ppDetour, ppOriginal) == MH_OK)
+ {
+ HookTarget* target = new HookTarget;
+ target->targetAddress = ppTarget;
+ target->targetName = (char*)targetName;
+
+ m_hookTargets.push_back(target);
+ }
+ else
+ {
+ if (targetName != nullptr)
+ spdlog::error("MH_CreateHook failed for function {}", targetName);
+ else
+ spdlog::error("MH_CreateHook failed for unknown function");
+ }
}
HookEnabler::~HookEnabler()
{
- for (auto& hook : m_hookTargets)
- {
- if (MH_EnableHook(hook->targetAddress) != MH_OK)
- {
- if (hook->targetName != nullptr)
- spdlog::error("MH_EnableHook failed for function {}", hook->targetName);
- else
- spdlog::error("MH_EnableHook failed for unknown function");
- }
- else
- spdlog::info("Enabling hook {}", hook->targetName);
- }
+ for (auto& hook : m_hookTargets)
+ {
+ if (MH_EnableHook(hook->targetAddress) != MH_OK)
+ {
+ if (hook->targetName != nullptr)
+ spdlog::error("MH_EnableHook failed for function {}", hook->targetName);
+ else
+ spdlog::error("MH_EnableHook failed for unknown function");
+ }
+ else
+ spdlog::info("Enabling hook {}", hook->targetName);
+ }
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/hookutils.h b/NorthstarDedicatedTest/hookutils.h
index dd3b15b1..006bc16d 100644
--- a/NorthstarDedicatedTest/hookutils.h
+++ b/NorthstarDedicatedTest/hookutils.h
@@ -4,30 +4,30 @@
// Sets an area of memory as writeable until the TempReadWrite object goes out of scope
class TempReadWrite
{
-private:
- DWORD m_origProtection;
- void* m_ptr;
+ private:
+ DWORD m_origProtection;
+ void* m_ptr;
-public:
- TempReadWrite(void* ptr);
- ~TempReadWrite();
+ public:
+ TempReadWrite(void* ptr);
+ ~TempReadWrite();
};
// Enables all hooks created with the HookEnabler object when it goes out of scope and handles hook errors
class HookEnabler
{
-private:
- struct HookTarget
- {
- char* targetName;
- LPVOID targetAddress;
- };
+ private:
+ struct HookTarget
+ {
+ char* targetName;
+ LPVOID targetAddress;
+ };
- std::vector<HookTarget*> m_hookTargets;
+ std::vector<HookTarget*> m_hookTargets;
-public:
- void CreateHook(LPVOID ppTarget, LPVOID ppDetour, LPVOID* ppOriginal, const char* targetName = nullptr);
- ~HookEnabler();
+ public:
+ void CreateHook(LPVOID ppTarget, LPVOID ppDetour, LPVOID* ppOriginal, const char* targetName = nullptr);
+ ~HookEnabler();
};
// macro to call HookEnabler::CreateHook with the hook's name
diff --git a/NorthstarDedicatedTest/keyvalues.cpp b/NorthstarDedicatedTest/keyvalues.cpp
index c1fefdd7..08c85dc1 100644
--- a/NorthstarDedicatedTest/keyvalues.cpp
+++ b/NorthstarDedicatedTest/keyvalues.cpp
@@ -7,22 +7,26 @@
#include <fstream>
// hook forward defs
-typedef char(*KeyValues__LoadFromBufferType)(void* self, const char* resourceName, const char* pBuffer, void* pFileSystem, void* a5, void* a6, int a7);
+typedef char (*KeyValues__LoadFromBufferType)(
+ void* self, const char* resourceName, const char* pBuffer, void* pFileSystem, void* a5, void* a6, int a7);
KeyValues__LoadFromBufferType KeyValues__LoadFromBuffer;
-char KeyValues__LoadFromBufferHook(void* self, const char* resourceName, const char* pBuffer, void* pFileSystem, void* a5, void* a6, int a7);
+char KeyValues__LoadFromBufferHook(
+ void* self, const char* resourceName, const char* pBuffer, void* pFileSystem, void* a5, void* a6, int a7);
void InitialiseKeyValues(HMODULE baseAddress)
{
HookEnabler hook;
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x426C30, &KeyValues__LoadFromBufferHook, reinterpret_cast<LPVOID*>(&KeyValues__LoadFromBuffer));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x426C30, &KeyValues__LoadFromBufferHook, reinterpret_cast<LPVOID*>(&KeyValues__LoadFromBuffer));
}
void* savedFilesystemPtr;
char KeyValues__LoadFromBufferHook(void* self, const char* resourceName, const char* pBuffer, void* pFileSystem, void* a5, void* a6, int a7)
{
- // this is just to allow playlists to get a valid pFileSystem ptr for kv building, other functions that call this particular overload of LoadFromBuffer seem to get called on network stuff exclusively
- // not exactly sure what the address wanted here is, so just taking it from a function call that always happens before playlists is loaded
+ // this is just to allow playlists to get a valid pFileSystem ptr for kv building, other functions that call this particular overload of
+ // LoadFromBuffer seem to get called on network stuff exclusively not exactly sure what the address wanted here is, so just taking it
+ // from a function call that always happens before playlists is loaded
if (pFileSystem != nullptr)
savedFilesystemPtr = pFileSystem;
if (!pFileSystem && !strcmp(resourceName, "playlists"))
@@ -76,7 +80,7 @@ void ModManager::TryBuildKeyValues(const char* filename)
}
}
- // add original #base last, #bases don't override preexisting keys, including the ones we've just done
+ // add original #base last, #bases don't override preexisting keys, including the ones we've just done
newKvs += "#base \"";
newKvs += ogFilePath;
newKvs += "\"\n";
@@ -102,14 +106,14 @@ void ModManager::TryBuildKeyValues(const char* filename)
if (originalFile[i] == '/' || originalFile[i] == '#')
while (originalFile[i] != '\n')
i++;
-
+
i++;
}
-
+
int j = 0;
for (int j = 0; originalFile[i] >= 65 && originalFile[i] <= 122; j++)
rootName[j] = originalFile[i++];
-
+
// empty kv, all the other stuff gets #base'd
newKvs += rootName;
newKvs += "\n{\n}\n";
diff --git a/NorthstarDedicatedTest/languagehooks.cpp b/NorthstarDedicatedTest/languagehooks.cpp
index 3a69df9d..43547e82 100644
--- a/NorthstarDedicatedTest/languagehooks.cpp
+++ b/NorthstarDedicatedTest/languagehooks.cpp
@@ -10,13 +10,13 @@ namespace fs = std::filesystem;
typedef char* (*GetGameLanguageType)();
char* GetGameLanguage();
-typedef LANGID(*Tier0_DetectDefaultLanguageType)();
+typedef LANGID (*Tier0_DetectDefaultLanguageType)();
GetGameLanguageType GetGameLanguageOriginal;
bool CheckLangAudioExists(char* lang)
{
- std::string path{ "r2\\sound\\general_" };
+ std::string path{"r2\\sound\\general_"};
path += lang;
path += ".mstr";
return fs::exists(path);
@@ -32,7 +32,7 @@ std::vector<std::string> file_list(fs::path dir, std::regex ext_pattern)
using iterator = fs::directory_iterator;
const iterator end;
- for (iterator iter{ dir }; iter != end; ++iter)
+ for (iterator iter{dir}; iter != end; ++iter)
{
const std::string filename = iter->path().filename().string();
std::smatch matches;
@@ -65,7 +65,10 @@ char* GetGameLanguageHook()
{
if (!CheckLangAudioExists((char*)forcedLanguage))
{
- spdlog::info("User tried to force the language (-language) to \"{}\", but audio for this language doesn't exist and the game is bound to error, falling back to next option...", forcedLanguage);
+ spdlog::info(
+ "User tried to force the language (-language) to \"{}\", but audio for this language doesn't exist and the game is bound "
+ "to error, falling back to next option...",
+ forcedLanguage);
}
else
{
@@ -80,9 +83,10 @@ char* GetGameLanguageHook()
auto lang = GetGameLanguageOriginal();
if (!CheckLangAudioExists(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);
-
+ 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
{
@@ -91,13 +95,15 @@ char* GetGameLanguageHook()
}
}
- Tier0_DetectDefaultLanguageType(); // force the global in tier0 to be populated with language inferred from user's system rather than defaulting to Russian
- canOriginDictateLang = false; // Origin has no say anymore, we will fallback to user's system setup language
+ Tier0_DetectDefaultLanguageType(); // force the global in tier0 to be populated with language inferred from user's system rather than
+ // defaulting to Russian
+ canOriginDictateLang = false; // Origin has no say anymore, we will fallback to user's system setup language
auto lang = GetGameLanguageOriginal();
spdlog::info("Detected system language: {}", lang);
if (!CheckLangAudioExists(lang))
{
- spdlog::warn("Caution, audio for this language does NOT exist. You might want to override your game language with -language command line option.");
+ 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 the first installed audio language: {}", lang.c_str());
strncpy(ingameLang1, lang.c_str(), 256);
diff --git a/NorthstarDedicatedTest/latencyflex.cpp b/NorthstarDedicatedTest/latencyflex.cpp
index 84b79d33..4772b78a 100644
--- a/NorthstarDedicatedTest/latencyflex.cpp
+++ b/NorthstarDedicatedTest/latencyflex.cpp
@@ -4,7 +4,7 @@
#include "dedicated.h"
#include "convar.h"
-typedef void(*OnRenderStartType)();
+typedef void (*OnRenderStartType)();
OnRenderStartType OnRenderStart;
ConVar* Cvar_r_latencyflex;
@@ -37,7 +37,8 @@ void InitialiseLatencyFleX(HMODULE baseAddress)
return;
}
- m_winelfx_WaitAndBeginFrame = reinterpret_cast<PFN_winelfx_WaitAndBeginFrame>(reinterpret_cast<void*>(GetProcAddress(m_lfxModule,"winelfx_WaitAndBeginFrame")));
+ m_winelfx_WaitAndBeginFrame =
+ reinterpret_cast<PFN_winelfx_WaitAndBeginFrame>(reinterpret_cast<void*>(GetProcAddress(m_lfxModule, "winelfx_WaitAndBeginFrame")));
spdlog::info("LatencyFleX initialized.");
Cvar_r_latencyflex = RegisterConVar("r_latencyflex", "1", FCVAR_ARCHIVE, "Whether or not to use LatencyFleX input latency reduction.");
diff --git a/NorthstarDedicatedTest/logging.cpp b/NorthstarDedicatedTest/logging.cpp
index 136fdf9b..ec46bedc 100644
--- a/NorthstarDedicatedTest/logging.cpp
+++ b/NorthstarDedicatedTest/logging.cpp
@@ -11,7 +11,6 @@
#include <minidumpapiset.h>
#include "configurables.h"
-
// This needs to be called after hooks are loaded so we can access the command line args
void CreateLogFiles()
{
@@ -68,7 +67,8 @@ long __stdcall ExceptionFilter(EXCEPTION_POINTERS* exceptionInfo)
else if (exceptionInfo0 == 1)
exceptionCause << "Attempted to write to: 0x" << std::setw(8) << std::setfill('0') << std::hex << exceptionInfo1;
else if (exceptionInfo0 == 8)
- exceptionCause << "Data Execution Prevention (DEP) at: 0x" << std::setw(8) << std::setfill('0') << std::hex << exceptionInfo1;
+ exceptionCause << "Data Execution Prevention (DEP) at: 0x" << std::setw(8) << std::setfill('0') << std::hex
+ << exceptionInfo1;
else
exceptionCause << "Unknown access violation at: 0x" << std::setw(8) << std::setfill('0') << std::hex << exceptionInfo1;
@@ -186,21 +186,23 @@ long __stdcall ExceptionFilter(EXCEPTION_POINTERS* exceptionInfo)
dumpExceptionInfo.ExceptionPointers = exceptionInfo;
dumpExceptionInfo.ClientPointers = false;
- MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hMinidumpFile, MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory), &dumpExceptionInfo, nullptr, nullptr);
+ MiniDumpWriteDump(
+ GetCurrentProcess(), GetCurrentProcessId(), hMinidumpFile,
+ MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory), &dumpExceptionInfo, nullptr, nullptr);
CloseHandle(hMinidumpFile);
}
else
spdlog::error("Failed to write minidump file {}!", stream.str());
if (!IsDedicated())
- MessageBoxA(0, "Northstar has crashed! Crash info can be found in R2Northstar/logs", "Northstar has crashed!", MB_ICONERROR | MB_OK);
+ MessageBoxA(
+ 0, "Northstar has crashed! Crash info can be found in R2Northstar/logs", "Northstar has crashed!", MB_ICONERROR | MB_OK);
}
logged = true;
return EXCEPTION_EXECUTE_HANDLER;
}
-
void InitialiseLogging()
{
AddVectoredExceptionHandler(TRUE, ExceptionFilter);
@@ -223,7 +225,7 @@ enum SpewType_t
SPEW_TYPE_COUNT
};
-typedef void(*EngineSpewFuncType)();
+typedef void (*EngineSpewFuncType)();
EngineSpewFuncType EngineSpewFunc;
void EngineSpewFuncHook(void* engineServer, SpewType_t type, const char* format, va_list args)
@@ -234,44 +236,44 @@ void EngineSpewFuncHook(void* engineServer, SpewType_t type, const char* format,
const char* typeStr;
switch (type)
{
- case SPEW_MESSAGE:
- {
- typeStr = "SPEW_MESSAGE";
- break;
- }
+ case SPEW_MESSAGE:
+ {
+ typeStr = "SPEW_MESSAGE";
+ break;
+ }
- case SPEW_WARNING:
- {
- typeStr = "SPEW_WARNING";
- break;
- }
+ case SPEW_WARNING:
+ {
+ typeStr = "SPEW_WARNING";
+ break;
+ }
- case SPEW_ASSERT:
- {
- typeStr = "SPEW_ASSERT";
- break;
- }
+ case SPEW_ASSERT:
+ {
+ typeStr = "SPEW_ASSERT";
+ break;
+ }
- case SPEW_ERROR:
- {
- typeStr = "SPEW_ERROR";
- break;
- }
+ case SPEW_ERROR:
+ {
+ typeStr = "SPEW_ERROR";
+ break;
+ }
- case SPEW_LOG:
- {
- typeStr = "SPEW_LOG";
- break;
- }
+ case SPEW_LOG:
+ {
+ typeStr = "SPEW_LOG";
+ break;
+ }
- default:
- {
- typeStr = "SPEW_UNKNOWN";
- break;
- }
+ default:
+ {
+ typeStr = "SPEW_UNKNOWN";
+ break;
+ }
}
- char formatted[2048] = { 0 };
+ char formatted[2048] = {0};
bool shouldFormat = true;
// because titanfall 2 is quite possibly the worst thing to yet exist, it sometimes gives invalid specifiers which will crash
@@ -283,45 +285,45 @@ void EngineSpewFuncHook(void* engineServer, SpewType_t type, const char* format,
{
switch (format[i + 1])
{
- // this is fucking awful lol
- case 'd':
- case 'i':
- case 'u':
- case 'x':
- case 'X':
- case 'f':
- case 'F':
- case 'g':
- case 'G':
- case 'a':
- case 'A':
- case 'c':
- case 's':
- case 'p':
- case 'n':
- case '%':
- case '-':
- case '+':
- case ' ':
- case '#':
- case '*':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- break;
-
- default:
- {
- shouldFormat = false;
- break;
- }
+ // this is fucking awful lol
+ case 'd':
+ case 'i':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ case 'a':
+ case 'A':
+ case 'c':
+ case 's':
+ case 'p':
+ case 'n':
+ case '%':
+ case '-':
+ case '+':
+ case ' ':
+ case '#':
+ case '*':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ break;
+
+ default:
+ {
+ shouldFormat = false;
+ break;
+ }
}
}
}
@@ -340,8 +342,7 @@ void EngineSpewFuncHook(void* engineServer, SpewType_t type, const char* format,
spdlog::info("[SERVER {}] {}", typeStr, formatted);
}
-
-typedef void(*Status_ConMsg_Type)(const char* text, ...);
+typedef void (*Status_ConMsg_Type)(const char* text, ...);
Status_ConMsg_Type Status_ConMsg_Original;
void Status_ConMsg_Hook(const char* text, ...)
@@ -360,13 +361,13 @@ void Status_ConMsg_Hook(const char* text, ...)
spdlog::info(formatted);
}
-typedef bool(*CClientState_ProcessPrint_Type)(__int64 thisptr, __int64 msg);
+typedef bool (*CClientState_ProcessPrint_Type)(__int64 thisptr, __int64 msg);
CClientState_ProcessPrint_Type CClientState_ProcessPrint_Original;
bool CClientState_ProcessPrint_Hook(__int64 thisptr, __int64 msg)
{
char* text = *(char**)(msg + 0x20);
-
+
auto endpos = strlen(text);
if (text[endpos - 1] == '\n')
text[endpos - 1] = '\0'; // cut off repeated newline
@@ -385,28 +386,31 @@ void InitialiseEngineSpewFuncHooks(HMODULE baseAddress)
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x15ABD0, Status_ConMsg_Hook, reinterpret_cast<LPVOID*>(&Status_ConMsg_Original));
// Hook CClientState::ProcessPrint
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1A1530, CClientState_ProcessPrint_Hook, reinterpret_cast<LPVOID*>(&CClientState_ProcessPrint_Original));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x1A1530, CClientState_ProcessPrint_Hook,
+ reinterpret_cast<LPVOID*>(&CClientState_ProcessPrint_Original));
- Cvar_spewlog_enable = RegisterConVar("spewlog_enable", "1", FCVAR_NONE, "Enables/disables whether the engine spewfunc should be logged");
+ Cvar_spewlog_enable =
+ RegisterConVar("spewlog_enable", "1", FCVAR_NONE, "Enables/disables whether the engine spewfunc should be logged");
}
#include "bitbuf.h"
ConVar* Cvar_cl_showtextmsg;
-typedef void(*TextMsg_Type)(__int64);
+typedef void (*TextMsg_Type)(__int64);
TextMsg_Type TextMsg_Original;
class ICenterPrint
{
-public:
- virtual void ctor() = 0;
- virtual void Clear(void) = 0;
- virtual void ColorPrint(int r, int g, int b, int a, wchar_t* text) = 0;
- virtual void ColorPrint(int r, int g, int b, int a, char* text) = 0;
- virtual void Print(wchar_t* text) = 0;
- virtual void Print(char* text) = 0;
- virtual void SetTextColor(int r, int g, int b, int a) = 0;
+ public:
+ virtual void ctor() = 0;
+ virtual void Clear(void) = 0;
+ virtual void ColorPrint(int r, int g, int b, int a, wchar_t* text) = 0;
+ virtual void ColorPrint(int r, int g, int b, int a, char* text) = 0;
+ virtual void Print(wchar_t* text) = 0;
+ virtual void Print(char* text) = 0;
+ virtual void SetTextColor(int r, int g, int b, int a) = 0;
};
ICenterPrint* internalCenterPrint = NULL;
@@ -421,7 +425,8 @@ void TextMsgHook(BFRead* msg)
if (!Cvar_cl_showtextmsg->m_nValue)
return;
- switch (msg_dest) {
+ switch (msg_dest)
+ {
case 4: // HUD_PRINTCENTER
internalCenterPrint->Print(text);
break;
diff --git a/NorthstarDedicatedTest/masterserver.cpp b/NorthstarDedicatedTest/masterserver.cpp
index c61c69e5..9d50eda5 100644
--- a/NorthstarDedicatedTest/masterserver.cpp
+++ b/NorthstarDedicatedTest/masterserver.cpp
@@ -13,8 +13,8 @@
#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
+// 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
ConVar* Cvar_ns_masterserver_hostname;
ConVar* Cvar_ns_report_server_to_masterserver;
@@ -29,54 +29,64 @@ ConVar* Cvar_hostname;
MasterServerManager* g_MasterServerManager;
-typedef void(*CHostState__State_NewGameType)(CHostState* hostState);
+typedef void (*CHostState__State_NewGameType)(CHostState* hostState);
CHostState__State_NewGameType CHostState__State_NewGame;
-typedef void(*CHostState__State_ChangeLevelMPType)(CHostState* hostState);
+typedef void (*CHostState__State_ChangeLevelMPType)(CHostState* hostState);
CHostState__State_ChangeLevelMPType CHostState__State_ChangeLevelMP;
-typedef void(*CHostState__State_ChangeLevelSPType)(CHostState* hostState);
+typedef void (*CHostState__State_ChangeLevelSPType)(CHostState* hostState);
CHostState__State_ChangeLevelSPType CHostState__State_ChangeLevelSP;
-typedef void(*CHostState__State_GameShutdownType)(CHostState* hostState);
+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') {
+inline int hctod(char c)
+{
+ if (c >= 'A' && c <= 'F')
+ {
return c - 'A' + 10;
}
- else if (c >= 'a' && c <= 'f') {
+ else if (c >= 'a' && c <= 'f')
+ {
return c - 'a' + 10;
}
- else {
+ 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 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) {
+ 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) {
+ for (int i = 2; i <= 5; ++i)
+ {
cp *= 16;
cp += hctod(last_match.str()[i]);
}
- if (cp <= 0x7F) {
+ if (cp <= 0x7F)
+ {
result.push_back(cp);
}
- else if (cp <= 0x7FF) {
+ 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) {
+ 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)));
@@ -125,7 +135,9 @@ const char* HttplibErrorToString(httplib::Error error)
return "";
}
-RemoteServerInfo::RemoteServerInfo(const char* newId, const char* newName, const char* newDescription, const char* newMap, const char* newPlaylist, int newPlayerCount, int newMaxPlayers, bool newRequiresPassword)
+RemoteServerInfo::RemoteServerInfo(
+ const char* newId, const char* newName, const char* newDescription, const char* newMap, const char* newPlaylist, int newPlayerCount,
+ int newMaxPlayers, bool newRequiresPassword)
{
// passworded servers don't have public ips
requiresPassword = newRequiresPassword;
@@ -150,7 +162,7 @@ void MasterServerManager::SetCommonHttpClientOptions(CURL* curl)
{
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
- //curl_easy_setopt(curl, CURLOPT_STDERR, stdout);
+ // curl_easy_setopt(curl, CURLOPT_STDERR, stdout);
if (CommandLine()->FindParm("-msinsecure")) // TODO: this check doesn't seem to work
{
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
@@ -184,7 +196,8 @@ void MasterServerManager::AuthenticateOriginWithMasterServer(char* uid, char* or
std::string uidStr(uid);
std::string tokenStr(originToken);
- std::thread requestThread([this, uidStr, tokenStr]()
+ std::thread requestThread(
+ [this, uidStr, tokenStr]()
{
spdlog::info("Trying to authenticate with northstar masterserver for user {}", uidStr);
@@ -192,7 +205,9 @@ void MasterServerManager::AuthenticateOriginWithMasterServer(char* uid, char* or
SetCommonHttpClientOptions(curl);
std::string readBuffer;
- curl_easy_setopt(curl, CURLOPT_URL, fmt::format("{}/client/origin_auth?id={}&token={}", Cvar_ns_masterserver_hostname->m_pszString, uidStr, tokenStr).c_str());
+ curl_easy_setopt(
+ curl, CURLOPT_URL,
+ fmt::format("{}/client/origin_auth?id={}&token={}", Cvar_ns_masterserver_hostname->m_pszString, uidStr, tokenStr).c_str());
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
@@ -208,7 +223,9 @@ void MasterServerManager::AuthenticateOriginWithMasterServer(char* uid, char* or
if (originAuthInfo.HasParseError())
{
- spdlog::error("Failed reading origin auth info response: encountered parse error \"{}\"", rapidjson::GetParseError_En(originAuthInfo.GetParseError()));
+ spdlog::error(
+ "Failed reading origin auth info response: encountered parse error \"{}\"",
+ rapidjson::GetParseError_En(originAuthInfo.GetParseError()));
goto REQUEST_END_CLEANUP;
}
@@ -248,7 +265,8 @@ void MasterServerManager::RequestServerList()
// do this here so it's instantly set on call for scripts
m_scriptRequestingServerList = true;
- std::thread requestThread([this]()
+ std::thread requestThread(
+ [this]()
{
// make sure we never have 2 threads writing at once
// i sure do hope this is actually threadsafe
@@ -280,7 +298,9 @@ void MasterServerManager::RequestServerList()
if (serverInfoJson.HasParseError())
{
- spdlog::error("Failed reading masterserver response: encountered parse error \"{}\"", rapidjson::GetParseError_En(serverInfoJson.GetParseError()));
+ spdlog::error(
+ "Failed reading masterserver response: encountered parse error \"{}\"",
+ rapidjson::GetParseError_En(serverInfoJson.GetParseError()));
goto REQUEST_END_CLEANUP;
}
@@ -310,15 +330,13 @@ void MasterServerManager::RequestServerList()
}
// todo: verify json props are fine before adding to m_remoteServers
- if (!serverObj.HasMember("id") || !serverObj["id"].IsString()
- || !serverObj.HasMember("name") || !serverObj["name"].IsString()
- || !serverObj.HasMember("description") || !serverObj["description"].IsString()
- || !serverObj.HasMember("map") || !serverObj["map"].IsString()
- || !serverObj.HasMember("playlist") || !serverObj["playlist"].IsString()
- || !serverObj.HasMember("playerCount") || !serverObj["playerCount"].IsNumber()
- || !serverObj.HasMember("maxPlayers") || !serverObj["maxPlayers"].IsNumber()
- || !serverObj.HasMember("hasPassword") || !serverObj["hasPassword"].IsBool()
- || !serverObj.HasMember("modInfo") || !serverObj["modInfo"].HasMember("Mods") || !serverObj["modInfo"]["Mods"].IsArray())
+ if (!serverObj.HasMember("id") || !serverObj["id"].IsString() || !serverObj.HasMember("name") ||
+ !serverObj["name"].IsString() || !serverObj.HasMember("description") || !serverObj["description"].IsString() ||
+ !serverObj.HasMember("map") || !serverObj["map"].IsString() || !serverObj.HasMember("playlist") ||
+ !serverObj["playlist"].IsString() || !serverObj.HasMember("playerCount") || !serverObj["playerCount"].IsNumber() ||
+ !serverObj.HasMember("maxPlayers") || !serverObj["maxPlayers"].IsNumber() || !serverObj.HasMember("hasPassword") ||
+ !serverObj["hasPassword"].IsBool() || !serverObj.HasMember("modInfo") || !serverObj["modInfo"].HasMember("Mods") ||
+ !serverObj["modInfo"]["Mods"].IsArray())
{
spdlog::error("Failed reading masterserver response: malformed server object");
continue;
@@ -334,7 +352,10 @@ void MasterServerManager::RequestServerList()
// if server already exists, update info rather than adding to it
if (!strncmp((const char*)server.id, id, 32))
{
- server = RemoteServerInfo(id, serverObj["name"].GetString(), serverObj["description"].GetString(), serverObj["map"].GetString(), serverObj["playlist"].GetString(), serverObj["playerCount"].GetInt(), serverObj["maxPlayers"].GetInt(), serverObj["hasPassword"].IsTrue());
+ server = RemoteServerInfo(
+ id, serverObj["name"].GetString(), serverObj["description"].GetString(), serverObj["map"].GetString(),
+ serverObj["playlist"].GetString(), serverObj["playerCount"].GetInt(), serverObj["maxPlayers"].GetInt(),
+ serverObj["hasPassword"].IsTrue());
newServer = &server;
createNewServerInfo = false;
break;
@@ -343,7 +364,10 @@ void MasterServerManager::RequestServerList()
// server didn't exist
if (createNewServerInfo)
- newServer = &m_remoteServers.emplace_back(id, serverObj["name"].GetString(), serverObj["description"].GetString(), serverObj["map"].GetString(), serverObj["playlist"].GetString(), serverObj["playerCount"].GetInt(), serverObj["maxPlayers"].GetInt(), serverObj["hasPassword"].IsTrue());
+ newServer = &m_remoteServers.emplace_back(
+ id, serverObj["name"].GetString(), serverObj["description"].GetString(), serverObj["map"].GetString(),
+ serverObj["playlist"].GetString(), serverObj["playerCount"].GetInt(), serverObj["maxPlayers"].GetInt(),
+ serverObj["hasPassword"].IsTrue());
newServer->requiredMods.clear();
for (auto& requiredMod : serverObj["modInfo"]["Mods"].GetArray())
@@ -364,13 +388,15 @@ void MasterServerManager::RequestServerList()
newServer->requiredMods.push_back(modInfo);
}
- spdlog::info("Server {} on map {} with playlist {} has {}/{} players", serverObj["name"].GetString(), serverObj["map"].GetString(), serverObj["playlist"].GetString(), serverObj["playerCount"].GetInt(), serverObj["maxPlayers"].GetInt());
+ spdlog::info(
+ "Server {} on map {} with playlist {} has {}/{} players", serverObj["name"].GetString(),
+ serverObj["map"].GetString(), serverObj["playlist"].GetString(), serverObj["playerCount"].GetInt(),
+ serverObj["maxPlayers"].GetInt());
}
- std::sort(m_remoteServers.begin(), m_remoteServers.end(), [](RemoteServerInfo& a, RemoteServerInfo& b)
- {
- return a.playerCount > b.playerCount;
- });
+ std::sort(
+ m_remoteServers.begin(), m_remoteServers.end(),
+ [](RemoteServerInfo& a, RemoteServerInfo& b) { return a.playerCount > b.playerCount; });
}
else
{
@@ -392,7 +418,8 @@ void MasterServerManager::RequestMainMenuPromos()
{
m_bHasMainMenuPromoData = false;
- std::thread requestThread([this]()
+ std::thread requestThread(
+ [this]()
{
while (m_bOriginAuthWithMasterServerInProgress || !m_bOriginAuthWithMasterServerDone)
Sleep(500);
@@ -401,7 +428,8 @@ void MasterServerManager::RequestMainMenuPromos()
SetCommonHttpClientOptions(curl);
std::string readBuffer;
- curl_easy_setopt(curl, CURLOPT_URL, fmt::format("{}/client/mainmenupromos", Cvar_ns_masterserver_hostname->m_pszString).c_str());
+ curl_easy_setopt(
+ curl, CURLOPT_URL, fmt::format("{}/client/mainmenupromos", Cvar_ns_masterserver_hostname->m_pszString).c_str());
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
@@ -417,7 +445,9 @@ void MasterServerManager::RequestMainMenuPromos()
if (mainMenuPromoJson.HasParseError())
{
- spdlog::error("Failed reading masterserver main menu promos response: encountered parse error \"{}\"", rapidjson::GetParseError_En(mainMenuPromoJson.GetParseError()));
+ spdlog::error(
+ "Failed reading masterserver main menu promos response: encountered parse error \"{}\"",
+ rapidjson::GetParseError_En(mainMenuPromoJson.GetParseError()));
goto REQUEST_END_CLEANUP;
}
@@ -443,17 +473,20 @@ void MasterServerManager::RequestMainMenuPromos()
!mainMenuPromoJson["largeButton"].HasMember("Title") || !mainMenuPromoJson["largeButton"]["Title"].IsString() ||
!mainMenuPromoJson["largeButton"].HasMember("Text") || !mainMenuPromoJson["largeButton"]["Text"].IsString() ||
!mainMenuPromoJson["largeButton"].HasMember("Url") || !mainMenuPromoJson["largeButton"]["Url"].IsString() ||
- !mainMenuPromoJson["largeButton"].HasMember("ImageIndex") || !mainMenuPromoJson["largeButton"]["ImageIndex"].IsNumber() ||
+ !mainMenuPromoJson["largeButton"].HasMember("ImageIndex") ||
+ !mainMenuPromoJson["largeButton"]["ImageIndex"].IsNumber() ||
!mainMenuPromoJson.HasMember("smallButton1") || !mainMenuPromoJson["smallButton1"].IsObject() ||
!mainMenuPromoJson["smallButton1"].HasMember("Title") || !mainMenuPromoJson["smallButton1"]["Title"].IsString() ||
!mainMenuPromoJson["smallButton1"].HasMember("Url") || !mainMenuPromoJson["smallButton1"]["Url"].IsString() ||
- !mainMenuPromoJson["smallButton1"].HasMember("ImageIndex") || !mainMenuPromoJson["smallButton1"]["ImageIndex"].IsNumber() ||
+ !mainMenuPromoJson["smallButton1"].HasMember("ImageIndex") ||
+ !mainMenuPromoJson["smallButton1"]["ImageIndex"].IsNumber() ||
!mainMenuPromoJson.HasMember("smallButton2") || !mainMenuPromoJson["smallButton2"].IsObject() ||
!mainMenuPromoJson["smallButton2"].HasMember("Title") || !mainMenuPromoJson["smallButton2"]["Title"].IsString() ||
!mainMenuPromoJson["smallButton2"].HasMember("Url") || !mainMenuPromoJson["smallButton2"]["Url"].IsString() ||
- !mainMenuPromoJson["smallButton2"].HasMember("ImageIndex") || !mainMenuPromoJson["smallButton2"]["ImageIndex"].IsNumber())
+ !mainMenuPromoJson["smallButton2"].HasMember("ImageIndex") ||
+ !mainMenuPromoJson["smallButton2"]["ImageIndex"].IsNumber())
{
spdlog::error("Failed reading masterserver main menu promos response: malformed json object");
goto REQUEST_END_CLEANUP;
@@ -501,17 +534,21 @@ void MasterServerManager::AuthenticateWithOwnServer(char* uid, char* playerToken
m_authenticatingWithGameServer = true;
m_scriptAuthenticatingWithGameServer = true;
m_successfullyAuthenticatedWithGameServer = false;
-
+
std::string uidStr(uid);
std::string tokenStr(playerToken);
- std::thread requestThread([this, uidStr, tokenStr]()
+ std::thread requestThread(
+ [this, uidStr, tokenStr]()
{
CURL* curl = curl_easy_init();
SetCommonHttpClientOptions(curl);
std::string readBuffer;
- curl_easy_setopt(curl, CURLOPT_URL, fmt::format("{}/client/auth_with_self?id={}&playerToken={}", Cvar_ns_masterserver_hostname->m_pszString, uidStr, tokenStr).c_str());
+ curl_easy_setopt(
+ curl, CURLOPT_URL,
+ fmt::format("{}/client/auth_with_self?id={}&playerToken={}", Cvar_ns_masterserver_hostname->m_pszString, uidStr, tokenStr)
+ .c_str());
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
@@ -527,7 +564,9 @@ void MasterServerManager::AuthenticateWithOwnServer(char* uid, char* playerToken
if (authInfoJson.HasParseError())
{
- spdlog::error("Failed reading masterserver authentication response: encountered parse error \"{}\"", rapidjson::GetParseError_En(authInfoJson.GetParseError()));
+ spdlog::error(
+ "Failed reading masterserver authentication response: encountered parse error \"{}\"",
+ rapidjson::GetParseError_En(authInfoJson.GetParseError()));
goto REQUEST_END_CLEANUP;
}
@@ -550,7 +589,9 @@ void MasterServerManager::AuthenticateWithOwnServer(char* uid, char* playerToken
goto REQUEST_END_CLEANUP;
}
- if (!authInfoJson.HasMember("success") || !authInfoJson.HasMember("id") || !authInfoJson["id"].IsString() || !authInfoJson.HasMember("authToken") || !authInfoJson["authToken"].IsString() || !authInfoJson.HasMember("persistentData") || !authInfoJson["persistentData"].IsArray())
+ if (!authInfoJson.HasMember("success") || !authInfoJson.HasMember("id") || !authInfoJson["id"].IsString() ||
+ !authInfoJson.HasMember("authToken") || !authInfoJson["authToken"].IsString() ||
+ !authInfoJson.HasMember("persistentData") || !authInfoJson["persistentData"].IsArray())
{
spdlog::error("Failed reading masterserver authentication response: malformed json object");
goto REQUEST_END_CLEANUP;
@@ -562,11 +603,11 @@ void MasterServerManager::AuthenticateWithOwnServer(char* uid, char* playerToken
newAuthData.pdataSize = authInfoJson["persistentData"].GetArray().Size();
newAuthData.pdata = new char[newAuthData.pdataSize];
- //memcpy(newAuthData.pdata, authInfoJson["persistentData"].GetString(), newAuthData.pdataSize);
+ // memcpy(newAuthData.pdata, authInfoJson["persistentData"].GetString(), newAuthData.pdataSize);
int i = 0;
- // note: persistentData is a uint8array because i had problems getting strings to behave, it sucks but it's just how it be unfortunately
- // potentially refactor later
+ // note: persistentData is a uint8array because i had problems getting strings to behave, it sucks but it's just how it be
+ // unfortunately potentially refactor later
for (auto& byte : authInfoJson["persistentData"].GetArray())
{
if (!byte.IsUint() || byte.GetUint() > 255)
@@ -624,7 +665,8 @@ void MasterServerManager::AuthenticateWithServer(char* uid, char* playerToken, c
std::string serverIdStr(serverId);
std::string passwordStr(password);
- std::thread requestThread([this, uidStr, tokenStr, serverIdStr, passwordStr]()
+ std::thread requestThread(
+ [this, uidStr, tokenStr, serverIdStr, passwordStr]()
{
// esnure that any persistence saving is done, so we know masterserver has newest
while (m_savingPersistentData)
@@ -643,8 +685,13 @@ void MasterServerManager::AuthenticateWithServer(char* uid, char* playerToken, c
{
char* escapedPassword = curl_easy_escape(curl, passwordStr.c_str(), passwordStr.length());
- curl_easy_setopt(curl, CURLOPT_URL, fmt::format("{}/client/auth_with_server?id={}&playerToken={}&server={}&password={}", Cvar_ns_masterserver_hostname->m_pszString, uidStr, tokenStr, serverIdStr, escapedPassword).c_str());
-
+ curl_easy_setopt(
+ curl, CURLOPT_URL,
+ fmt::format(
+ "{}/client/auth_with_server?id={}&playerToken={}&server={}&password={}", Cvar_ns_masterserver_hostname->m_pszString,
+ uidStr, tokenStr, serverIdStr, escapedPassword)
+ .c_str());
+
curl_free(escapedPassword);
}
@@ -659,7 +706,9 @@ void MasterServerManager::AuthenticateWithServer(char* uid, char* playerToken, c
if (connectionInfoJson.HasParseError())
{
- spdlog::error("Failed reading masterserver authentication response: encountered parse error \"{}\"", rapidjson::GetParseError_En(connectionInfoJson.GetParseError()));
+ spdlog::error(
+ "Failed reading masterserver authentication response: encountered parse error \"{}\"",
+ rapidjson::GetParseError_En(connectionInfoJson.GetParseError()));
goto REQUEST_END_CLEANUP;
}
@@ -682,7 +731,10 @@ void MasterServerManager::AuthenticateWithServer(char* uid, char* playerToken, c
goto REQUEST_END_CLEANUP;
}
- if (!connectionInfoJson.HasMember("success") || !connectionInfoJson.HasMember("ip") || !connectionInfoJson["ip"].IsString() || !connectionInfoJson.HasMember("port") || !connectionInfoJson["port"].IsNumber() || !connectionInfoJson.HasMember("authToken") || !connectionInfoJson["authToken"].IsString())
+ if (!connectionInfoJson.HasMember("success") || !connectionInfoJson.HasMember("ip") ||
+ !connectionInfoJson["ip"].IsString() || !connectionInfoJson.HasMember("port") ||
+ !connectionInfoJson["port"].IsNumber() || !connectionInfoJson.HasMember("authToken") ||
+ !connectionInfoJson["authToken"].IsString())
{
spdlog::error("Failed reading masterserver authentication response: malformed json object");
goto REQUEST_END_CLEANUP;
@@ -714,7 +766,8 @@ void MasterServerManager::AuthenticateWithServer(char* uid, char* playerToken, c
requestThread.detach();
}
-void MasterServerManager::AddSelfToServerList(int port, int authPort, char* name, char* description, char* map, char* playlist, int maxPlayers, char* password)
+void MasterServerManager::AddSelfToServerList(
+ int port, int authPort, char* name, char* description, char* map, char* playlist, int maxPlayers, char* password)
{
if (!Cvar_ns_report_server_to_masterserver->m_nValue)
return;
@@ -733,7 +786,8 @@ void MasterServerManager::AddSelfToServerList(int port, int authPort, char* name
std::string strPlaylist(playlist);
std::string strPassword(password);
- std::thread requestThread([this, port, authPort, strName, strDescription, strMap, strPlaylist, maxPlayers, strPassword]
+ std::thread requestThread(
+ [this, port, authPort, strName, strDescription, strMap, strPlaylist, maxPlayers, strPassword]
{
m_ownServerId[0] = 0;
m_ownServerAuthToken[0] = 0;
@@ -764,7 +818,13 @@ void MasterServerManager::AddSelfToServerList(int port, int authPort, char* name
char* playlistEscaped = curl_easy_escape(curl, strPlaylist.c_str(), strPlaylist.length());
char* passwordEscaped = curl_easy_escape(curl, strPassword.c_str(), strPassword.length());
- curl_easy_setopt(curl, CURLOPT_URL, fmt::format("{}/server/add_server?port={}&authPort={}&name={}&description={}&map={}&playlist={}&maxPlayers={}&password={}", Cvar_ns_masterserver_hostname->m_pszString, port, authPort, nameEscaped, descEscaped, mapEscaped, playlistEscaped, maxPlayers, passwordEscaped).c_str());
+ curl_easy_setopt(
+ curl, CURLOPT_URL,
+ fmt::format(
+ "{}/server/add_server?port={}&authPort={}&name={}&description={}&map={}&playlist={}&maxPlayers={}&password={}",
+ Cvar_ns_masterserver_hostname->m_pszString, port, authPort, nameEscaped, descEscaped, mapEscaped, playlistEscaped,
+ maxPlayers, passwordEscaped)
+ .c_str());
curl_free(nameEscaped);
curl_free(descEscaped);
@@ -784,7 +844,9 @@ void MasterServerManager::AddSelfToServerList(int port, int authPort, char* name
if (serverAddedJson.HasParseError())
{
- spdlog::error("Failed reading masterserver authentication response: encountered parse error \"{}\"", rapidjson::GetParseError_En(serverAddedJson.GetParseError()));
+ spdlog::error(
+ "Failed reading masterserver authentication response: encountered parse error \"{}\"",
+ rapidjson::GetParseError_En(serverAddedJson.GetParseError()));
goto REQUEST_END_CLEANUP;
}
@@ -807,7 +869,8 @@ void MasterServerManager::AddSelfToServerList(int port, int authPort, char* name
goto REQUEST_END_CLEANUP;
}
- if (!serverAddedJson.HasMember("id") || !serverAddedJson["id"].IsString() || !serverAddedJson.HasMember("serverAuthToken") || !serverAddedJson["serverAuthToken"].IsString())
+ if (!serverAddedJson.HasMember("id") || !serverAddedJson["id"].IsString() ||
+ !serverAddedJson.HasMember("serverAuthToken") || !serverAddedJson["serverAuthToken"].IsString())
{
spdlog::error("Failed reading masterserver response: malformed json object");
goto REQUEST_END_CLEANUP;
@@ -821,81 +884,95 @@ void MasterServerManager::AddSelfToServerList(int port, int authPort, char* name
// 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([this] {
- Sleep(5000);
-
- do
+ std::thread heartbeatThread(
+ [this]
{
- CURL* curl = curl_easy_init();
- SetCommonHttpClientOptions(curl);
+ Sleep(5000);
- std::string readBuffer;
- curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
- curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
-
- // 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:
+ do
{
- 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);
-
- int maxPlayers = 6;
- char* maxPlayersVar = GetCurrentPlaylistVar("max_players", false);
- if (maxPlayersVar) // GetCurrentPlaylistVar can return null so protect against this
- maxPlayers = std::stoi(maxPlayersVar);
-
- curl_easy_setopt(curl, CURLOPT_URL, fmt::format("{}/server/update_values?id={}&port={}&authPort={}&name={}&description={}&map={}&playlist={}&playerCount={}&maxPlayers={}&password={}", Cvar_ns_masterserver_hostname->m_pszString, m_ownServerId, Cvar_hostport->m_nValue, Cvar_ns_player_auth_port->m_nValue, escapedNameNew, escapedDescNew, escapedMapNew, escapedPlaylistNew, g_ServerAuthenticationManager->m_additionalPlayerData.size(), maxPlayers, escapedPasswordNew).c_str());
-
- curl_free(escapedNameNew);
- curl_free(escapedDescNew);
- curl_free(escapedMapNew);
- curl_free(escapedPlaylistNew);
- curl_free(escapedPasswordNew);
- }
+ CURL* curl = curl_easy_init();
+ SetCommonHttpClientOptions(curl);
- curl_mime* mime = curl_mime_init(curl);
- curl_mimepart* part = curl_mime_addpart(mime);
+ std::string readBuffer;
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
- curl_mime_data(part, m_ownModInfoJson.c_str(), m_ownModInfoJson.size());
- curl_mime_name(part, "modinfo");
- curl_mime_filename(part, "modinfo.json");
- curl_mime_type(part, "application/json");
+ // 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, 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);
+
+ int maxPlayers = 6;
+ char* maxPlayersVar = GetCurrentPlaylistVar("max_players", false);
+ if (maxPlayersVar) // GetCurrentPlaylistVar can return null so protect against this
+ maxPlayers = std::stoi(maxPlayersVar);
+
+ curl_easy_setopt(
+ curl, CURLOPT_URL,
+ fmt::format(
+ "{}/server/"
+ "update_values?id={}&port={}&authPort={}&name={}&description={}&map={}&playlist={}&playerCount={}&"
+ "maxPlayers={}&password={}",
+ Cvar_ns_masterserver_hostname->m_pszString, m_ownServerId, Cvar_hostport->m_nValue,
+ Cvar_ns_player_auth_port->m_nValue, escapedNameNew, escapedDescNew, escapedMapNew,
+ escapedPlaylistNew, g_ServerAuthenticationManager->m_additionalPlayerData.size(), maxPlayers,
+ escapedPasswordNew)
+ .c_str());
+
+ curl_free(escapedNameNew);
+ curl_free(escapedDescNew);
+ curl_free(escapedMapNew);
+ curl_free(escapedPlaylistNew);
+ curl_free(escapedPasswordNew);
+ }
- curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
-
- CURLcode result = curl_easy_perform(curl);
- if (result == CURLcode::CURLE_OK)
- {
- rapidjson_document serverAddedJson;
- serverAddedJson.Parse(readBuffer.c_str());
+ curl_mime* mime = curl_mime_init(curl);
+ curl_mimepart* part = curl_mime_addpart(mime);
+
+ curl_mime_data(part, m_ownModInfoJson.c_str(), m_ownModInfoJson.size());
+ curl_mime_name(part, "modinfo");
+ curl_mime_filename(part, "modinfo.json");
+ curl_mime_type(part, "application/json");
- if (!serverAddedJson.HasParseError() && serverAddedJson.IsObject())
+ curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
+
+ CURLcode result = curl_easy_perform(curl);
+ if (result == CURLcode::CURLE_OK)
{
- if (serverAddedJson.HasMember("id") && serverAddedJson["id"].IsString())
- {
- strncpy(m_ownServerId, serverAddedJson["id"].GetString(), sizeof(m_ownServerId));
- m_ownServerId[sizeof(m_ownServerId) - 1] = 0;
- }
+ rapidjson_document serverAddedJson;
+ serverAddedJson.Parse(readBuffer.c_str());
- if (serverAddedJson.HasMember("serverAuthToken") && serverAddedJson["serverAuthToken"].IsString())
+ if (!serverAddedJson.HasParseError() && serverAddedJson.IsObject())
{
- strncpy(m_ownServerAuthToken, serverAddedJson["serverAuthToken"].GetString(), sizeof(m_ownServerAuthToken));
- m_ownServerAuthToken[sizeof(m_ownServerAuthToken) - 1] = 0;
+ if (serverAddedJson.HasMember("id") && serverAddedJson["id"].IsString())
+ {
+ strncpy(m_ownServerId, serverAddedJson["id"].GetString(), sizeof(m_ownServerId));
+ m_ownServerId[sizeof(m_ownServerId) - 1] = 0;
+ }
+
+ if (serverAddedJson.HasMember("serverAuthToken") && serverAddedJson["serverAuthToken"].IsString())
+ {
+ strncpy(
+ m_ownServerAuthToken, serverAddedJson["serverAuthToken"].GetString(),
+ sizeof(m_ownServerAuthToken));
+ m_ownServerAuthToken[sizeof(m_ownServerAuthToken) - 1] = 0;
+ }
}
}
- }
- else
- spdlog::warn("Heartbeat failed with error {}", curl_easy_strerror(result));
+ else
+ spdlog::warn("Heartbeat failed with error {}", curl_easy_strerror(result));
- curl_easy_cleanup(curl);
- Sleep(10000);
- } while (*m_ownServerId);
- });
+ curl_easy_cleanup(curl);
+ Sleep(10000);
+ } while (*m_ownServerId);
+ });
heartbeatThread.detach();
}
@@ -922,7 +999,8 @@ void MasterServerManager::UpdateServerMapAndPlaylist(char* map, char* playlist,
std::string strMap(map);
std::string strPlaylist(playlist);
- std::thread requestThread([this, strMap, strPlaylist, maxPlayers]
+ std::thread requestThread(
+ [this, strMap, strPlaylist, maxPlayers]
{
CURL* curl = curl_easy_init();
SetCommonHttpClientOptions(curl);
@@ -937,8 +1015,13 @@ void MasterServerManager::UpdateServerMapAndPlaylist(char* map, char* playlist,
char* mapEscaped = curl_easy_escape(curl, strMap.c_str(), strMap.length());
char* playlistEscaped = curl_easy_escape(curl, strPlaylist.c_str(), strPlaylist.length());
- curl_easy_setopt(curl, CURLOPT_URL, fmt::format("{}/server/update_values?id={}&map={}&playlist={}&maxPlayers={}", Cvar_ns_masterserver_hostname->m_pszString, m_ownServerId, mapEscaped, playlistEscaped, maxPlayers).c_str());
-
+ curl_easy_setopt(
+ curl, CURLOPT_URL,
+ fmt::format(
+ "{}/server/update_values?id={}&map={}&playlist={}&maxPlayers={}", Cvar_ns_masterserver_hostname->m_pszString,
+ m_ownServerId, mapEscaped, playlistEscaped, maxPlayers)
+ .c_str());
+
curl_free(mapEscaped);
curl_free(playlistEscaped);
}
@@ -962,7 +1045,8 @@ void MasterServerManager::UpdateServerPlayerCount(int playerCount)
if (!*m_ownServerId)
return;
- std::thread requestThread([this, playerCount]
+ std::thread requestThread(
+ [this, playerCount]
{
CURL* curl = curl_easy_init();
SetCommonHttpClientOptions(curl);
@@ -971,7 +1055,11 @@ void MasterServerManager::UpdateServerPlayerCount(int playerCount)
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
- curl_easy_setopt(curl, CURLOPT_URL, fmt::format("{}/server/update_values?id={}&playerCount={}", Cvar_ns_masterserver_hostname->m_pszString, m_ownServerId, playerCount).c_str());
+ curl_easy_setopt(
+ curl, CURLOPT_URL,
+ fmt::format(
+ "{}/server/update_values?id={}&playerCount={}", Cvar_ns_masterserver_hostname->m_pszString, m_ownServerId, playerCount)
+ .c_str());
CURLcode result = curl_easy_perform(curl);
@@ -999,13 +1087,19 @@ void MasterServerManager::WritePlayerPersistentData(char* playerId, char* pdata,
std::string strPlayerId(playerId);
std::string strPdata(pdata, pdataSize);
- std::thread requestThread([this, strPlayerId, strPdata, pdataSize]
+ std::thread requestThread(
+ [this, strPlayerId, strPdata, pdataSize]
{
CURL* curl = curl_easy_init();
SetCommonHttpClientOptions(curl);
std::string readBuffer;
- curl_easy_setopt(curl, CURLOPT_URL, fmt::format("{}/accounts/write_persistence?id={}&serverId={}", Cvar_ns_masterserver_hostname->m_pszString, strPlayerId, m_ownServerId).c_str());
+ curl_easy_setopt(
+ curl, CURLOPT_URL,
+ fmt::format(
+ "{}/accounts/write_persistence?id={}&serverId={}", Cvar_ns_masterserver_hostname->m_pszString, strPlayerId,
+ m_ownServerId)
+ .c_str());
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
@@ -1041,7 +1135,9 @@ void MasterServerManager::RemoveSelfFromServerList()
if (!*m_ownServerId || !Cvar_ns_report_server_to_masterserver->m_nValue)
return;
- std::thread requestThread([this] {
+ std::thread requestThread(
+ [this]
+ {
CURL* curl = curl_easy_init();
SetCommonHttpClientOptions(curl);
@@ -1049,7 +1145,9 @@ void MasterServerManager::RemoveSelfFromServerList()
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
- curl_easy_setopt(curl, CURLOPT_URL, fmt::format("{}/server/remove_server?id={}", Cvar_ns_masterserver_hostname->m_pszString, m_ownServerId).c_str());
+ curl_easy_setopt(
+ curl, CURLOPT_URL,
+ fmt::format("{}/server/remove_server?id={}", Cvar_ns_masterserver_hostname->m_pszString, m_ownServerId).c_str());
CURLcode result = curl_easy_perform(curl);
@@ -1064,10 +1162,7 @@ void MasterServerManager::RemoveSelfFromServerList()
requestThread.detach();
}
-void ConCommand_ns_fetchservers(const CCommand& args)
-{
- g_MasterServerManager->RequestServerList();
-}
+void ConCommand_ns_fetchservers(const CCommand& args) { g_MasterServerManager->RequestServerList(); }
void CHostState__State_NewGameHook(CHostState* hostState)
{
@@ -1099,7 +1194,9 @@ void CHostState__State_NewGameHook(CHostState* hostState)
// 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_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();
g_ServerAuthenticationManager->m_bNeedLocalAuthForNewgame = false;
}
@@ -1146,16 +1243,13 @@ void CHostState__State_GameShutdownHook(CHostState* hostState)
CHostState__State_GameShutdown(hostState);
}
-MasterServerManager::MasterServerManager() : m_pendingConnectionInfo{}, m_ownServerId{ "" }, m_ownClientAuthToken{ "" }
-{
-
-}
+MasterServerManager::MasterServerManager() : m_pendingConnectionInfo{}, m_ownServerId{""}, m_ownClientAuthToken{""} {}
void InitialiseSharedMasterServer(HMODULE baseAddress)
{
Cvar_ns_masterserver_hostname = RegisterConVar("ns_masterserver_hostname", "127.0.0.1", FCVAR_NONE, "");
// unfortunately lib doesn't let us specify a port and still have https work
- //Cvar_ns_masterserver_port = RegisterConVar("ns_masterserver_port", "8080", FCVAR_NONE, "");
+ // Cvar_ns_masterserver_port = RegisterConVar("ns_masterserver_port", "8080", FCVAR_NONE, "");
Cvar_ns_server_name = RegisterConVar("ns_server_name", "Unnamed Northstar Server", FCVAR_GAMEDLL, "");
Cvar_ns_server_desc = RegisterConVar("ns_server_desc", "Default server description", FCVAR_GAMEDLL, "");
@@ -1170,8 +1264,15 @@ void InitialiseSharedMasterServer(HMODULE baseAddress)
RegisterConCommand("ns_fetchservers", ConCommand_ns_fetchservers, "", FCVAR_CLIENTDLL);
HookEnabler hook;
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x16E7D0, CHostState__State_NewGameHook, reinterpret_cast<LPVOID*>(&CHostState__State_NewGame));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x16E520, CHostState__State_ChangeLevelMPHook, reinterpret_cast<LPVOID*>(&CHostState__State_ChangeLevelMP));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x16E5D0, CHostState__State_ChangeLevelSPHook, reinterpret_cast<LPVOID*>(&CHostState__State_ChangeLevelSP));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x16E640, CHostState__State_GameShutdownHook, reinterpret_cast<LPVOID*>(&CHostState__State_GameShutdown));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x16E7D0, CHostState__State_NewGameHook, reinterpret_cast<LPVOID*>(&CHostState__State_NewGame));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x16E520, CHostState__State_ChangeLevelMPHook,
+ reinterpret_cast<LPVOID*>(&CHostState__State_ChangeLevelMP));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x16E5D0, CHostState__State_ChangeLevelSPHook,
+ reinterpret_cast<LPVOID*>(&CHostState__State_ChangeLevelSP));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x16E640, CHostState__State_GameShutdownHook,
+ reinterpret_cast<LPVOID*>(&CHostState__State_GameShutdown));
}
diff --git a/NorthstarDedicatedTest/masterserver.h b/NorthstarDedicatedTest/masterserver.h
index 2e7468b4..2eae2081 100644
--- a/NorthstarDedicatedTest/masterserver.h
+++ b/NorthstarDedicatedTest/masterserver.h
@@ -5,14 +5,14 @@
#include <cstring>
struct RemoteModInfo
{
-public:
+ public:
std::string Name;
std::string Version;
};
class RemoteServerInfo
{
-public:
+ public:
char id[33]; // 32 bytes + nullterminator
// server info
@@ -28,13 +28,15 @@ public:
// connection stuff
bool requiresPassword;
-public:
- RemoteServerInfo(const char* newId, const char* newName, const char* newDescription, const char* newMap, const char* newPlaylist, int newPlayerCount, int newMaxPlayers, bool newRequiresPassword);
+ public:
+ RemoteServerInfo(
+ const char* newId, const char* newName, const char* newDescription, const char* newMap, const char* newPlaylist, int newPlayerCount,
+ int newMaxPlayers, bool newRequiresPassword);
};
struct RemoteServerConnectionInfo
{
-public:
+ public:
char authToken[32];
in_addr ip;
@@ -43,7 +45,7 @@ public:
struct MainMenuPromoData
{
-public:
+ public:
std::string newInfoTitle1;
std::string newInfoTitle2;
std::string newInfoTitle3;
@@ -64,11 +66,11 @@ public:
class MasterServerManager
{
-private:
+ private:
bool m_requestingServerList = false;
bool m_authenticatingWithGameServer = false;
-public:
+ public:
char m_ownServerId[33];
char m_ownServerAuthToken[33];
char m_ownClientAuthToken[33];
@@ -98,10 +100,10 @@ public:
bool m_bHasMainMenuPromoData = false;
MainMenuPromoData m_MainMenuPromoData;
-private:
+ private:
void SetCommonHttpClientOptions(CURL* curl);
-public:
+ public:
MasterServerManager();
void ClearServerList();
void RequestServerList();
@@ -109,13 +111,14 @@ public:
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);
+ void
+ AddSelfToServerList(int port, int authPort, char* name, char* description, char* map, char* playlist, int maxPlayers, char* password);
void UpdateServerMapAndPlaylist(char* map, char* playlist, int playerCount);
void UpdateServerPlayerCount(int playerCount);
void WritePlayerPersistentData(char* playerId, char* pdata, size_t pdataSize);
void RemoveSelfFromServerList();
};
-std::string unescape_unicode(const std::string &str);
+std::string unescape_unicode(const std::string& str);
void UpdateServerInfoFromUnicodeToUTF8();
void InitialiseSharedMasterServer(HMODULE baseAddress);
diff --git a/NorthstarDedicatedTest/maxplayers.cpp b/NorthstarDedicatedTest/maxplayers.cpp
index 9d08e83f..674d3ef0 100644
--- a/NorthstarDedicatedTest/maxplayers.cpp
+++ b/NorthstarDedicatedTest/maxplayers.cpp
@@ -6,11 +6,10 @@
#define NEW_MAX_PLAYERS 64
// dg note: the theoretical limit is actually 100, 76 works without entity issues, and 64 works without clientside prediction issues.
-#define PAD_NUMBER(number, boundary) \
- ( ((number) + ((boundary)-1)) / (boundary) ) * (boundary)
+#define PAD_NUMBER(number, boundary) (((number) + ((boundary)-1)) / (boundary)) * (boundary)
// this is horrible
-constexpr int PlayerResource_Name_Start = 0; // Start of modded allocated space.
+constexpr int PlayerResource_Name_Start = 0; // Start of modded allocated space.
constexpr int PlayerResource_Name_Size = ((NEW_MAX_PLAYERS + 1) * 8); // const char* m_szName[MAX_PLAYERS + 1];
constexpr int PlayerResource_Ping_Start = PlayerResource_Name_Start + PlayerResource_Name_Size;
@@ -46,8 +45,7 @@ constexpr int Team_PlayerArray_AddedLength = NEW_MAX_PLAYERS - 32;
constexpr int Team_PlayerArray_AddedSize = PAD_NUMBER(Team_PlayerArray_AddedLength * 8, 4);
constexpr int Team_AddedSize = Team_PlayerArray_AddedSize;
-template<class T>
-void ChangeOffset(void* addr, unsigned int offset)
+template <class T> void ChangeOffset(void* addr, unsigned int offset)
{
TempReadWrite rw(addr);
*((T*)addr) = offset;
@@ -63,7 +61,7 @@ bool MatchRecvPropsToSendProps_R_Hook(__int64 lookup, __int64 tableNameBroken, _
spdlog::info("MatchRecvPropsToSendProps_R table name {}", tableName);
- bool orig = MatchRecvPropsToSendProps_R_Original(lookup, tableNameBroken, sendTable, recvTable);
+ bool orig = MatchRecvPropsToSendProps_R_Original(lookup, tableNameBroken, sendTable, recvTable);
return orig;
}
@@ -85,10 +83,12 @@ bool DataTable_SetupReceiveTableFromSendTable_Hook(__int64 sendTable, bool needs
}
*/
-typedef void* (*StringTables_CreateStringTable_Type)(__int64 thisptr, const char* name, int maxentries, int userdatafixedsize, int userdatanetworkbits, int flags);
+typedef void* (*StringTables_CreateStringTable_Type)(
+ __int64 thisptr, const char* name, int maxentries, int userdatafixedsize, int userdatanetworkbits, int flags);
StringTables_CreateStringTable_Type StringTables_CreateStringTable_Original;
-void* StringTables_CreateStringTable_Hook(__int64 thisptr, const char* name, int maxentries, int userdatafixedsize, int userdatanetworkbits, int flags)
+void* StringTables_CreateStringTable_Hook(
+ __int64 thisptr, const char* name, int maxentries, int userdatafixedsize, int userdatanetworkbits, int flags)
{
// Change the amount of entries to account for a bigger player amount
if (!strcmp(name, "userinfo"))
@@ -96,17 +96,14 @@ void* StringTables_CreateStringTable_Hook(__int64 thisptr, const char* name, int
int maxPlayersPowerOf2 = 1;
while (maxPlayersPowerOf2 < NEW_MAX_PLAYERS)
maxPlayersPowerOf2 <<= 1;
-
+
maxentries = maxPlayersPowerOf2;
}
return StringTables_CreateStringTable_Original(thisptr, name, maxentries, userdatafixedsize, userdatanetworkbits, flags);
}
-bool MaxPlayersIncreaseEnabled()
-{
- return CommandLine() && CommandLine()->CheckParm("-experimentalmaxplayersincrease");
-}
+bool MaxPlayersIncreaseEnabled() { return CommandLine() && CommandLine()->CheckParm("-experimentalmaxplayersincrease"); }
void InitialiseMaxPlayersOverride_Engine(HMODULE baseAddress)
{
@@ -142,20 +139,23 @@ void InitialiseMaxPlayersOverride_Engine(HMODULE baseAddress)
// proper fix below
// patch max players in userinfo stringtable creation loop
- ChangeOffset<unsigned char>((char*)baseAddress + 0x114C48 + 2, NEW_MAX_PLAYERS); // original: 32
+ ChangeOffset<unsigned char>((char*)baseAddress + 0x114C48 + 2, NEW_MAX_PLAYERS); // original: 32
// do not load prebaked SendTable message list
- ChangeOffset<unsigned char>((char*)baseAddress + 0x75859, 0xEB); // jnz -> jmp
+ ChangeOffset<unsigned char>((char*)baseAddress + 0x75859, 0xEB); // jnz -> jmp
HookEnabler hook;
-
- // ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x209000, &MatchRecvPropsToSendProps_R_Hook, reinterpret_cast<LPVOID*>(&MatchRecvPropsToSendProps_R_Original));
- // ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1FACD0, &DataTable_SetupReceiveTableFromSendTable_Hook, reinterpret_cast<LPVOID*>(&DataTable_SetupReceiveTableFromSendTable_Original));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x22E220, &StringTables_CreateStringTable_Hook, reinterpret_cast<LPVOID*>(&StringTables_CreateStringTable_Original));
+ // ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x209000, &MatchRecvPropsToSendProps_R_Hook,
+ // reinterpret_cast<LPVOID*>(&MatchRecvPropsToSendProps_R_Original)); ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1FACD0,
+ // &DataTable_SetupReceiveTableFromSendTable_Hook, reinterpret_cast<LPVOID*>(&DataTable_SetupReceiveTableFromSendTable_Original));
+
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x22E220, &StringTables_CreateStringTable_Hook,
+ reinterpret_cast<LPVOID*>(&StringTables_CreateStringTable_Original));
}
-typedef void(*RunUserCmds_Type)(bool a1, float a2);
+typedef void (*RunUserCmds_Type)(bool a1, float a2);
RunUserCmds_Type RunUserCmds_Original;
HMODULE serverBase = 0;
@@ -164,27 +164,27 @@ auto RandomIntZeroMax = (__int64(__fastcall*)())0;
// lazy rebuild
void RunUserCmds_Hook(bool a1, float a2)
{
- unsigned char v3; // bl
- int v5; // er14
- int i; // edi
- __int64 v7; // rax
- DWORD* v8; // rbx
- int v9; // edi
- __int64* v10; // rsi
- __int64 v11; // rax
- int v12; // er12
- __int64 v13; // rdi
- int v14; // ebx
- int v15; // eax
- __int64 v16; // r8
- int v17; // edx
- char v18; // r15
- char v19; // bp
- int v20; // esi
- __int64* v21; // rdi
- __int64 v22; // rcx
- bool v23; // al
- __int64 v24; // rax
+ unsigned char v3; // bl
+ int v5; // er14
+ int i; // edi
+ __int64 v7; // rax
+ DWORD* v8; // rbx
+ int v9; // edi
+ __int64* v10; // rsi
+ __int64 v11; // rax
+ int v12; // er12
+ __int64 v13; // rdi
+ int v14; // ebx
+ int v15; // eax
+ __int64 v16; // r8
+ int v17; // edx
+ char v18; // r15
+ char v19; // bp
+ int v20; // esi
+ __int64* v21; // rdi
+ __int64 v22; // rcx
+ bool v23; // al
+ __int64 v24; // rax
__int64 v25[NEW_MAX_PLAYERS]; // [rsp+20h] [rbp-138h] BYREF
uintptr_t base = (__int64)serverBase;
@@ -206,10 +206,10 @@ void RunUserCmds_Hook(bool a1, float a2)
auto sub_1805A6C20 = (void(__fastcall*)(__int64))(base + 0x5A6C20);
v3 = *(unsigned char*)(g_pGlobals + 73);
- if (*(DWORD*)(qword_1814D9648 + 92)
- && ((*(unsigned __int8(__fastcall**)(__int64))(*(__int64*)g_pEngineServer + 32i64))(g_pEngineServer)
- || !*(DWORD*)(qword_1814DA408 + 92))
- && v3)
+ if (*(DWORD*)(qword_1814D9648 + 92) &&
+ ((*(unsigned __int8(__fastcall**)(__int64))(*(__int64*)g_pEngineServer + 32i64))(g_pEngineServer) ||
+ !*(DWORD*)(qword_1814DA408 + 92)) &&
+ v3)
{
globals = g_pGlobals;
v5 = 1;
@@ -303,7 +303,7 @@ void RunUserCmds_Hook(bool a1, float a2)
}
}
-typedef __int64(*SendPropArray2_Type)(__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn, unsigned char unk1);
+typedef __int64 (*SendPropArray2_Type)(__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn, unsigned char unk1);
SendPropArray2_Type SendPropArray2_Original;
__int64 __fastcall SendPropArray2_Hook(__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn, unsigned char unk1)
@@ -481,7 +481,7 @@ void InitialiseMaxPlayersOverride_Server(HMODULE baseAddress)
DT_Team_Construct();
}
-typedef __int64(*RecvPropArray2_Type)(__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn);
+typedef __int64 (*RecvPropArray2_Type)(__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn);
RecvPropArray2_Type RecvPropArray2_Original;
__int64 __fastcall RecvPropArray2_Hook(__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn)
@@ -509,10 +509,12 @@ void InitialiseMaxPlayersOverride_Client(HMODULE baseAddress)
ChangeOffset<unsigned char>((char*)baseAddress + 0x1640C4 + 2, NEW_MAX_PLAYERS - 32);
// C_PlayerResource::C_PlayerResource - change m_szName address
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1640D0 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); // appended to the end of the class
-
+ ChangeOffset<unsigned int>(
+ (char*)baseAddress + 0x1640D0 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); // appended to the end of the class
+
// C_PlayerResource::C_PlayerResource - change m_szName address
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1640D0 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); // appended to the end of the class
+ ChangeOffset<unsigned int>(
+ (char*)baseAddress + 0x1640D0 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); // appended to the end of the class
// C_PlayerResource::C_PlayerResource - increase memset length to clean newly allocated data
ChangeOffset<unsigned int>((char*)baseAddress + 0x1640D0 + 3, 2244 + C_PlayerResource_AddedSize);
diff --git a/NorthstarDedicatedTest/memalloc.cpp b/NorthstarDedicatedTest/memalloc.cpp
index 1b9eaae8..f9186110 100644
--- a/NorthstarDedicatedTest/memalloc.cpp
+++ b/NorthstarDedicatedTest/memalloc.cpp
@@ -29,7 +29,6 @@ extern "C" void _free_base(void* p)
g_pMemAllocSingleton->m_vtable->Free(g_pMemAllocSingleton, p);
}
-
extern "C" void* _realloc_base(void* oldPtr, size_t size)
{
if (!g_pMemAllocSingleton)
@@ -66,12 +65,6 @@ extern "C" char* _strdup_base(const char* src)
return str;
}
-void* operator new(size_t n)
-{
- return _malloc_base(n);
-}
+void* operator new(size_t n) { return _malloc_base(n); }
-void operator delete(void* p)
-{
- _free_base(p);
-}// /FORCE:MULTIPLE \ No newline at end of file
+void operator delete(void* p) { _free_base(p); } // /FORCE:MULTIPLE \ No newline at end of file
diff --git a/NorthstarDedicatedTest/memalloc.h b/NorthstarDedicatedTest/memalloc.h
index 92ab9672..4ea080b4 100644
--- a/NorthstarDedicatedTest/memalloc.h
+++ b/NorthstarDedicatedTest/memalloc.h
@@ -7,36 +7,40 @@ extern "C" void* _malloc_base(size_t size);
extern "C" void* _calloc_base(size_t const count, size_t const size);
extern "C" void* _realloc_base(void* block, size_t size);
extern "C" void* _recalloc_base(void* const block, size_t const count, size_t const size);
-extern "C" void _free_base(void* const block);
+extern "C" void _free_base(void* const block);
extern "C" char* _strdup_base(const char* src);
void* operator new(size_t n);
void operator delete(void* p);
-//void* malloc(size_t n);
+// void* malloc(size_t n);
-class SourceAllocator {
-public:
- static const bool kNeedFree = true;
- void* Malloc(size_t size) {
- if (size) // behavior of malloc(0) is implementation defined.
- return _malloc_base(size);
- else
- return NULL; // standardize to returning NULL.
- }
- void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
- (void)originalSize;
- if (newSize == 0) {
- _free_base(originalPtr);
- return NULL;
- }
- return _realloc_base(originalPtr, newSize);
- }
- static void Free(void* ptr) { _free_base(ptr); }
+class SourceAllocator
+{
+ public:
+ static const bool kNeedFree = true;
+ void* Malloc(size_t size)
+ {
+ if (size) // behavior of malloc(0) is implementation defined.
+ return _malloc_base(size);
+ else
+ return NULL; // standardize to returning NULL.
+ }
+ void* Realloc(void* originalPtr, size_t originalSize, size_t newSize)
+ {
+ (void)originalSize;
+ if (newSize == 0)
+ {
+ _free_base(originalPtr);
+ return NULL;
+ }
+ return _realloc_base(originalPtr, newSize);
+ }
+ static void Free(void* ptr) { _free_base(ptr); }
};
typedef rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::MemoryPoolAllocator<SourceAllocator>, SourceAllocator> rapidjson_document;
-//typedef rapidjson::GenericDocument<rapidjson::UTF8<>, SourceAllocator, SourceAllocator> rapidjson_document;
-//typedef rapidjson::Document rapidjson_document;
-//using MyDocument = rapidjson::GenericDocument<rapidjson::UTF8<>, MemoryAllocator>;
-//using rapidjson_document = rapidjson::GenericDocument<rapidjson::UTF8<>, SourceAllocator, SourceAllocator>;
+// typedef rapidjson::GenericDocument<rapidjson::UTF8<>, SourceAllocator, SourceAllocator> rapidjson_document;
+// typedef rapidjson::Document rapidjson_document;
+// using MyDocument = rapidjson::GenericDocument<rapidjson::UTF8<>, MemoryAllocator>;
+// using rapidjson_document = rapidjson::GenericDocument<rapidjson::UTF8<>, SourceAllocator, SourceAllocator>;
diff --git a/NorthstarDedicatedTest/miscclientfixes.cpp b/NorthstarDedicatedTest/miscclientfixes.cpp
index dc68d18c..62ffd4a4 100644
--- a/NorthstarDedicatedTest/miscclientfixes.cpp
+++ b/NorthstarDedicatedTest/miscclientfixes.cpp
@@ -3,7 +3,7 @@
#include "hookutils.h"
#include "dedicated.h"
-typedef void*(*CrashingWeaponActivityFuncType)(void* a1);
+typedef void* (*CrashingWeaponActivityFuncType)(void* a1);
CrashingWeaponActivityFuncType CrashingWeaponActivityFunc0;
CrashingWeaponActivityFuncType CrashingWeaponActivityFunc1;
@@ -32,11 +32,14 @@ void InitialiseMiscClientFixes(HMODULE baseAddress)
HookEnabler hook;
- // these functions will occasionally pass a null pointer on respawn, unsure what causes this but seems easiest just to return null if null, which seems to work fine
- // fucking sucks this has to be fixed like this but unsure what exactly causes this serverside, breaks vanilla compatibility to a degree tho
- // will say i have about 0 clue what exactly these functions do, testing this it doesn't even seem like they do much of anything i can see tbh
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x5A92D0, &CrashingWeaponActivityFunc0Hook, reinterpret_cast<LPVOID*>(&CrashingWeaponActivityFunc0));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x5A9310, &CrashingWeaponActivityFunc1Hook, reinterpret_cast<LPVOID*>(&CrashingWeaponActivityFunc1));
+ // these functions will occasionally pass a null pointer on respawn, unsure what causes this but seems easiest just to return null if
+ // null, which seems to work fine fucking sucks this has to be fixed like this but unsure what exactly causes this serverside, breaks
+ // vanilla compatibility to a degree tho will say i have about 0 clue what exactly these functions do, testing this it doesn't even seem
+ // like they do much of anything i can see tbh
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x5A92D0, &CrashingWeaponActivityFunc0Hook, reinterpret_cast<LPVOID*>(&CrashingWeaponActivityFunc0));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x5A9310, &CrashingWeaponActivityFunc1Hook, reinterpret_cast<LPVOID*>(&CrashingWeaponActivityFunc1));
// experimental: allow cl_extrapolate to be enabled without cheats
{
diff --git a/NorthstarDedicatedTest/misccommands.cpp b/NorthstarDedicatedTest/misccommands.cpp
index a01948af..4a556fad 100644
--- a/NorthstarDedicatedTest/misccommands.cpp
+++ b/NorthstarDedicatedTest/misccommands.cpp
@@ -25,15 +25,17 @@ void SelfAuthAndLeaveToLobbyCommand(const CCommand& arg)
void EndSelfAuthAndLeaveToLobbyCommand(const CCommand& arg)
{
- Cbuf_AddText(Cbuf_GetCurrentPlayer(), fmt::format("serverfilter {}", g_ServerAuthenticationManager->m_authData.begin()->first).c_str(), cmd_source_t::kCommandSrcCode);
+ Cbuf_AddText(
+ Cbuf_GetCurrentPlayer(), fmt::format("serverfilter {}", g_ServerAuthenticationManager->m_authData.begin()->first).c_str(),
+ cmd_source_t::kCommandSrcCode);
Cbuf_Execute();
// weird way of checking, but check if client script vm is initialised, mainly just to allow players to cancel this
if (g_ClientSquirrelManager->sqvm)
{
g_ServerAuthenticationManager->m_bNeedLocalAuthForNewgame = true;
- // this won't set playlist correctly on remote clients, don't think they can set playlist until they've left which sorta fucks things
- // should maybe set this in HostState_NewGame?
+ // this won't set playlist correctly on remote clients, don't think they can set playlist until they've left which sorta fucks
+ // things should maybe set this in HostState_NewGame?
SetCurrentPlaylist("tdm");
strcpy(g_pHostState->m_levelName, "mp_lobby");
g_pHostState->m_iNextState = HS_NEW_GAME;
@@ -42,8 +44,12 @@ void EndSelfAuthAndLeaveToLobbyCommand(const CCommand& arg)
void AddMiscConCommands()
{
- RegisterConCommand("force_newgame", ForceLoadMapCommand, "forces a map load through directly setting g_pHostState->m_iNextState to HS_NEW_GAME", FCVAR_NONE);
- RegisterConCommand("ns_start_reauth_and_leave_to_lobby", SelfAuthAndLeaveToLobbyCommand, "called by the server, used to reauth and return the player to lobby when leaving a game", FCVAR_SERVER_CAN_EXECUTE);
+ RegisterConCommand(
+ "force_newgame", ForceLoadMapCommand, "forces a map load through directly setting g_pHostState->m_iNextState to HS_NEW_GAME",
+ FCVAR_NONE);
+ RegisterConCommand(
+ "ns_start_reauth_and_leave_to_lobby", SelfAuthAndLeaveToLobbyCommand,
+ "called by the server, used to reauth and return the player to lobby when leaving a game", FCVAR_SERVER_CAN_EXECUTE);
// this is a concommand because we make a deferred call to it from another thread
RegisterConCommand("ns_end_reauth_and_leave_to_lobby", EndSelfAuthAndLeaveToLobbyCommand, "", FCVAR_NONE);
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/miscserverfixes.cpp b/NorthstarDedicatedTest/miscserverfixes.cpp
index 5db9ebbd..334c5fa3 100644
--- a/NorthstarDedicatedTest/miscserverfixes.cpp
+++ b/NorthstarDedicatedTest/miscserverfixes.cpp
@@ -19,6 +19,6 @@ void InitialiseMiscServerFixes(HMODULE baseAddress)
*(ptr++) = 0x90; // nop
*(ptr++) = 0x90; // nop
*(ptr++) = 0x90; // nop
- *ptr = 0x90; // nop
+ *ptr = 0x90; // nop
}
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/miscserverscript.cpp b/NorthstarDedicatedTest/miscserverscript.cpp
index bc4b43c0..b2bf52ec 100644
--- a/NorthstarDedicatedTest/miscserverscript.cpp
+++ b/NorthstarDedicatedTest/miscserverscript.cpp
@@ -52,14 +52,15 @@ SQRESULT SQ_IsPlayerIndexLocalPlayer(void* sqvm)
ServerSq_pusherror(sqvm, fmt::format("Invalid playerindex {}", playerIndex).c_str());
return SQRESULT_ERROR;
}
-
+
ServerSq_pushbool(sqvm, !strcmp(g_LocalPlayerUserID, (char*)player + 0xF500));
return SQRESULT_NOTNULL;
}
void InitialiseMiscServerScriptCommand(HMODULE baseAddress)
{
- g_ServerSquirrelManager->AddFuncRegistration("void", "NSEarlyWritePlayerIndexPersistenceForLeave", "int playerIndex", "", SQ_EarlyWritePlayerIndexPersistenceForLeave);
+ 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);
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/modlocalisation.cpp b/NorthstarDedicatedTest/modlocalisation.cpp
index f86773fb..82eff242 100644
--- a/NorthstarDedicatedTest/modlocalisation.cpp
+++ b/NorthstarDedicatedTest/modlocalisation.cpp
@@ -4,7 +4,7 @@
#include "modmanager.h"
#include "dedicated.h"
-typedef bool(*AddLocalisationFileType)(void* g_pVguiLocalize, const char* path, const char* pathId, char unknown);
+typedef bool (*AddLocalisationFileType)(void* g_pVguiLocalize, const char* path, const char* pathId, char unknown);
AddLocalisationFileType AddLocalisationFile;
bool loadModLocalisationFiles = true;
diff --git a/NorthstarDedicatedTest/modmanager.cpp b/NorthstarDedicatedTest/modmanager.cpp
index 0134057e..7e6322cb 100644
--- a/NorthstarDedicatedTest/modmanager.cpp
+++ b/NorthstarDedicatedTest/modmanager.cpp
@@ -30,7 +30,9 @@ Mod::Mod(fs::path modDir, char* jsonBuf)
// fail if parse error
if (modJson.HasParseError())
{
- spdlog::error("Failed reading mod file {}: encountered parse error \"{}\" at offset {}", (modDir / "mod.json").string(), GetParseError_En(modJson.GetParseError()), modJson.GetErrorOffset());
+ spdlog::error(
+ "Failed reading mod file {}: encountered parse error \"{}\" at offset {}", (modDir / "mod.json").string(),
+ GetParseError_En(modJson.GetParseError()), modJson.GetErrorOffset());
return;
}
@@ -68,7 +70,7 @@ Mod::Mod(fs::path modDir, char* jsonBuf)
DownloadLink = modJson["DownloadLink"].GetString();
else
DownloadLink = "";
-
+
if (modJson.HasMember("RequiredOnClient"))
RequiredOnClient = modJson["RequiredOnClient"].GetBool();
else
@@ -118,7 +120,7 @@ Mod::Mod(fs::path modDir, char* jsonBuf)
{
if (!scriptObj.IsObject() || !scriptObj.HasMember("Path") || !scriptObj.HasMember("RunOn"))
continue;
-
+
ModScript script;
script.Path = scriptObj["Path"].GetString();
@@ -134,7 +136,7 @@ Mod::Mod(fs::path modDir, char* jsonBuf)
if (scriptObj["ServerCallback"].HasMember("After") && scriptObj["ServerCallback"]["After"].IsString())
callback.AfterCallback = scriptObj["ServerCallback"]["After"].GetString();
-
+
script.Callbacks.push_back(callback);
}
@@ -189,7 +191,8 @@ ModManager::ModManager()
// precaculated string hashes
// note: use backslashes for these, since we use lexically_normal for file paths which uses them
m_hScriptsRsonHash = std::hash<std::string>{}("scripts\\vscripts\\scripts.rson");
- m_hPdefHash = std::hash<std::string>{}("cfg\\server\\persistent_player_data_version_231.pdef"); // this can have multiple versions, but we use 231 so that's what we hash
+ m_hPdefHash = std::hash<std::string>{}(
+ "cfg\\server\\persistent_player_data_version_231.pdef"); // this can have multiple versions, but we use 231 so that's what we hash
LoadMods();
}
@@ -215,8 +218,9 @@ void ModManager::LoadMods()
enabledModsStringStream << (char)enabledModsStream.get();
enabledModsStream.close();
- m_enabledModsCfg.Parse<rapidjson::ParseFlag::kParseCommentsFlag | rapidjson::ParseFlag::kParseTrailingCommasFlag>(enabledModsStringStream.str().c_str());
-
+ m_enabledModsCfg.Parse<rapidjson::ParseFlag::kParseCommentsFlag | rapidjson::ParseFlag::kParseTrailingCommasFlag>(
+ enabledModsStringStream.str().c_str());
+
m_hasEnabledModsCfg = m_enabledModsCfg.IsObject();
}
@@ -230,7 +234,7 @@ void ModManager::LoadMods()
// read mod json file
std::ifstream jsonStream(modDir / "mod.json");
std::stringstream jsonStringStream;
-
+
// fail if no mod json
if (jsonStream.fail())
{
@@ -242,7 +246,7 @@ void ModManager::LoadMods()
jsonStringStream << (char)jsonStream.get();
jsonStream.close();
-
+
Mod mod(modDir, (char*)jsonStringStream.str().c_str());
if (m_hasEnabledModsCfg && m_enabledModsCfg.HasMember(mod.Name.c_str()))
@@ -265,9 +269,7 @@ void ModManager::LoadMods()
}
// sort by load prio, lowest-highest
- std::sort(m_loadedMods.begin(), m_loadedMods.end(), [](Mod& a, Mod& b) {
- return a.LoadPriority < b.LoadPriority;
- });
+ std::sort(m_loadedMods.begin(), m_loadedMods.end(), [](Mod& a, Mod& b) { return a.LoadPriority < b.LoadPriority; });
for (Mod& mod : m_loadedMods)
{
@@ -275,10 +277,13 @@ void ModManager::LoadMods()
continue;
// register convars
- // for reloads, this is sorta barebones, when we have a good findconvar method, we could probably reset flags and stuff on preexisting convars
- // note: we don't delete convars if they already exist because they're used for script stuff, unfortunately this causes us to leak memory on reload, but not much, potentially find a way to not do this at some point
+ // for reloads, this is sorta barebones, when we have a good findconvar method, we could probably reset flags and stuff on
+ // preexisting convars note: we don't delete convars if they already exist because they're used for script stuff, unfortunately this
+ // causes us to leak memory on reload, but not much, potentially find a way to not do this at some point
for (ModConVar* convar : mod.ConVars)
- if (g_CustomConvars.find(convar->Name) == g_CustomConvars.end()) // make sure convar isn't registered yet, unsure if necessary but idk what behaviour is for defining same convar multiple times
+ if (g_CustomConvars.find(convar->Name) ==
+ g_CustomConvars.end()) // make sure convar isn't registered yet, unsure if necessary but idk what behaviour is for defining
+ // same convar multiple times
RegisterConVar(convar->Name.c_str(), convar->DefaultValue.c_str(), convar->Flags, convar->HelpString.c_str());
// read vpk paths
@@ -288,21 +293,23 @@ void ModManager::LoadMods()
{
// a bunch of checks to make sure we're only adding dir vpks and their paths are good
// note: the game will literally only load vpks with the english prefix
- if (fs::is_regular_file(file) && file.path().extension() == ".vpk" &&
- file.path().string().find("english") != std::string::npos && file.path().string().find(".bsp.pak000_dir") != std::string::npos)
+ if (fs::is_regular_file(file) && file.path().extension() == ".vpk" &&
+ file.path().string().find("english") != std::string::npos &&
+ file.path().string().find(".bsp.pak000_dir") != std::string::npos)
{
std::string formattedPath = file.path().filename().string();
// this really fucking sucks but it'll work
- std::string vpkName = (file.path().parent_path() / formattedPath.substr(strlen("english"), formattedPath.find(".bsp") - 3)).string();
+ std::string vpkName =
+ (file.path().parent_path() / formattedPath.substr(strlen("english"), formattedPath.find(".bsp") - 3)).string();
mod.Vpks.push_back(vpkName);
-
+
if (m_hasLoadedMods)
(*g_Filesystem)->m_vtable->MountVPK(*g_Filesystem, vpkName.c_str());
}
}
}
-
+
// read keyvalues paths
if (fs::exists(mod.ModDirectory / "keyvalues"))
{
@@ -414,7 +421,7 @@ void ModManager::UnloadMods()
m_enabledModsCfg.SetObject();
for (Mod& mod : m_loadedMods)
- {
+ {
// remove all built kvs
for (std::pair<size_t, std::string> kvPaths : mod.KeyValues)
fs::remove(GetCompiledAssetsPath() / fs::path(kvPaths.second).lexically_relative(mod.ModDirectory));
@@ -423,9 +430,12 @@ void ModManager::UnloadMods()
// write to m_enabledModsCfg
// should we be doing this here or should scripts be doing this manually?
- // main issue with doing this here is when we reload mods for connecting to a server, we write enabled mods, which isn't necessarily what we wanna do
+ // main issue with doing this here is when we reload mods for connecting to a server, we write enabled mods, which isn't necessarily
+ // what we wanna do
if (!m_enabledModsCfg.HasMember(mod.Name.c_str()))
- m_enabledModsCfg.AddMember(rapidjson_document::StringRefType(mod.Name.c_str()), rapidjson_document::GenericValue(false), m_enabledModsCfg.GetAllocator());
+ m_enabledModsCfg.AddMember(
+ rapidjson_document::StringRefType(mod.Name.c_str()), rapidjson_document::GenericValue(false),
+ m_enabledModsCfg.GetAllocator());
m_enabledModsCfg[mod.Name.c_str()].SetBool(mod.Enabled);
}
@@ -464,10 +474,7 @@ void ModManager::CompileAssetsForFile(const char* filename)
}
}
-void ReloadModsCommand(const CCommand& args)
-{
- g_ModManager->LoadMods();
-}
+void ReloadModsCommand(const CCommand& args) { g_ModManager->LoadMods(); }
void InitialiseModManager(HMODULE baseAddress)
{
@@ -476,9 +483,5 @@ void InitialiseModManager(HMODULE baseAddress)
RegisterConCommand("reload_mods", ReloadModsCommand, "idk", FCVAR_NONE);
}
-fs::path GetModFolderPath() {
- return fs::path(GetNorthstarPrefix() + MOD_FOLDER_SUFFIX);
-}
-fs::path GetCompiledAssetsPath() {
- return fs::path(GetNorthstarPrefix() + COMPILED_ASSETS_SUFFIX);
-} \ No newline at end of file
+fs::path GetModFolderPath() { return fs::path(GetNorthstarPrefix() + MOD_FOLDER_SUFFIX); }
+fs::path GetCompiledAssetsPath() { return fs::path(GetNorthstarPrefix() + COMPILED_ASSETS_SUFFIX); } \ No newline at end of file
diff --git a/NorthstarDedicatedTest/modmanager.h b/NorthstarDedicatedTest/modmanager.h
index 445d757e..07e5bffb 100644
--- a/NorthstarDedicatedTest/modmanager.h
+++ b/NorthstarDedicatedTest/modmanager.h
@@ -14,7 +14,7 @@ const std::string COMPILED_ASSETS_SUFFIX = "/runtime/compiled";
struct ModConVar
{
-public:
+ public:
std::string Name;
std::string DefaultValue;
std::string HelpString;
@@ -23,9 +23,9 @@ public:
struct ModScriptCallback
{
-public:
+ public:
// would've liked to make it possible to hook arbitrary codecallbacks, but couldn't find a function that calls some ui ones
- //std::string HookedCodeCallback;
+ // std::string HookedCodeCallback;
ScriptContext Context;
@@ -37,7 +37,7 @@ public:
struct ModScript
{
-public:
+ public:
std::string Path;
std::string RsonRunOn;
@@ -46,7 +46,7 @@ public:
class Mod
{
-public:
+ public:
// runtime stuff
fs::path ModDirectory;
bool Enabled = true;
@@ -84,20 +84,20 @@ public:
bool wasReadSuccessfully = false;
-public:
+ public:
Mod(fs::path modPath, char* jsonBuf);
};
struct ModOverrideFile
{
-public:
+ public:
Mod* owningMod;
fs::path path;
};
class ModManager
{
-private:
+ private:
bool m_hasLoadedMods = false;
bool m_hasEnabledModsCfg;
rapidjson_document m_enabledModsCfg;
@@ -106,11 +106,11 @@ private:
size_t m_hScriptsRsonHash;
size_t m_hPdefHash;
-public:
+ public:
std::vector<Mod> m_loadedMods;
std::unordered_map<std::string, ModOverrideFile> m_modFiles;
-public:
+ public:
ModManager();
void LoadMods();
void UnloadMods();
diff --git a/NorthstarDedicatedTest/pch.h b/NorthstarDedicatedTest/pch.h
index a07d1401..653776ce 100644
--- a/NorthstarDedicatedTest/pch.h
+++ b/NorthstarDedicatedTest/pch.h
@@ -4,8 +4,8 @@
#define WIN32_LEAN_AND_MEAN
#define _CRT_SECURE_NO_WARNINGS
#define RAPIDJSON_NOMEMBERITERATORCLASS // need this for rapidjson
-#define NOMINMAX // this too
-#define _WINSOCK_DEPRECATED_NO_WARNINGS // temp because i'm very lazy and want to use inet_addr, remove later
+#define NOMINMAX // this too
+#define _WINSOCK_DEPRECATED_NO_WARNINGS // temp because i'm very lazy and want to use inet_addr, remove later
#define RAPIDJSON_HAS_STDSTRING 1
// httplib ssl
diff --git a/NorthstarDedicatedTest/pdef.cpp b/NorthstarDedicatedTest/pdef.cpp
index 20b4bea5..86642874 100644
--- a/NorthstarDedicatedTest/pdef.cpp
+++ b/NorthstarDedicatedTest/pdef.cpp
@@ -15,7 +15,7 @@ void ModManager::BuildPdef()
fs::remove(MOD_PDEF_PATH);
std::string pdef = ReadVPKOriginalFile(VPK_PDEF_PATH);
-
+
for (Mod& mod : m_loadedMods)
{
if (!mod.Enabled || !mod.Pdiff.size())
@@ -59,7 +59,8 @@ void ModManager::BuildPdef()
if (!currentLine.compare(start, 9, "$ENUM_END"))
inEnum = false;
else
- enumAdds[currentEnum].push_back(currentLine); // only need to push_back current line, if there's syntax errors then game pdef parser will handle them
+ enumAdds[currentEnum].push_back(currentLine); // only need to push_back current line, if there's syntax errors then game
+ // pdef parser will handle them
}
else if (!currentLine.compare(start, 9, "$ENUM_ADD"))
{
diff --git a/NorthstarDedicatedTest/playlist.cpp b/NorthstarDedicatedTest/playlist.cpp
index 5dfd4087..7447f9f8 100644
--- a/NorthstarDedicatedTest/playlist.cpp
+++ b/NorthstarDedicatedTest/playlist.cpp
@@ -7,10 +7,10 @@
#include "dedicated.h"
#include "squirrel.h"
-typedef char(*Onclc_SetPlaylistVarOverrideType)(void* a1, void* a2);
+typedef char (*Onclc_SetPlaylistVarOverrideType)(void* a1, void* a2);
Onclc_SetPlaylistVarOverrideType Onclc_SetPlaylistVarOverride;
-typedef int(*GetCurrentGamemodeMaxPlayersType)();
+typedef int (*GetCurrentGamemodeMaxPlayersType)();
GetCurrentGamemodeMaxPlayersType GetCurrentGamemodeMaxPlayers;
// function type defined in gameutils.h
@@ -76,19 +76,25 @@ void InitialisePlaylistHooks(HMODULE baseAddress)
{
RegisterConCommand("setplaylist", SetPlaylistCommand, "Sets the current playlist", FCVAR_NONE);
RegisterConCommand("setplaylistvaroverrides", SetPlaylistVarOverrideCommand, "sets a playlist var override", FCVAR_NONE);
- // note: clc_SetPlaylistVarOverride is pretty insecure, since it allows for entirely arbitrary playlist var overrides to be sent to the server
- // this is somewhat restricted on custom servers to prevent it being done outside of private matches, but ideally it should be disabled altogether, since the custom menus won't use it anyway
- // this should only really be accepted if you want vanilla client compatibility
- Cvar_ns_use_clc_SetPlaylistVarOverride = RegisterConVar("ns_use_clc_SetPlaylistVarOverride", "0", FCVAR_GAMEDLL, "Whether the server should accept clc_SetPlaylistVarOverride messages");
+ // note: clc_SetPlaylistVarOverride is pretty insecure, since it allows for entirely arbitrary playlist var overrides to be sent to the
+ // server this is somewhat restricted on custom servers to prevent it being done outside of private matches, but ideally it should be
+ // disabled altogether, since the custom menus won't use it anyway this should only really be accepted if you want vanilla client
+ // compatibility
+ Cvar_ns_use_clc_SetPlaylistVarOverride = RegisterConVar(
+ "ns_use_clc_SetPlaylistVarOverride", "0", FCVAR_GAMEDLL, "Whether the server should accept clc_SetPlaylistVarOverride messages");
HookEnabler hook;
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x222180, &Onclc_SetPlaylistVarOverrideHook, reinterpret_cast<LPVOID*>(&Onclc_SetPlaylistVarOverride));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x18ED00, &SetPlaylistVarOverrideHook, reinterpret_cast<LPVOID*>(&SetPlaylistVarOverrideOriginal));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x18C680, &GetCurrentPlaylistVarHook, reinterpret_cast<LPVOID*>(&GetCurrentPlaylistVarOriginal));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x18C430, &GetCurrentGamemodeMaxPlayersHook, reinterpret_cast<LPVOID*>(&GetCurrentGamemodeMaxPlayers));
-
- // patch to prevent clc_SetPlaylistVarOverride from being able to crash servers if we reach max overrides due to a call to Error (why is this possible respawn, wtf)
- // todo: add a warning for this
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x222180, &Onclc_SetPlaylistVarOverrideHook, reinterpret_cast<LPVOID*>(&Onclc_SetPlaylistVarOverride));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x18ED00, &SetPlaylistVarOverrideHook, reinterpret_cast<LPVOID*>(&SetPlaylistVarOverrideOriginal));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x18C680, &GetCurrentPlaylistVarHook, reinterpret_cast<LPVOID*>(&GetCurrentPlaylistVarOriginal));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x18C430, &GetCurrentGamemodeMaxPlayersHook, reinterpret_cast<LPVOID*>(&GetCurrentGamemodeMaxPlayers));
+
+ // patch to prevent clc_SetPlaylistVarOverride from being able to crash servers if we reach max overrides due to a call to Error (why is
+ // this possible respawn, wtf) todo: add a warning for this
{
void* ptr = (char*)baseAddress + 0x18ED8D;
TempReadWrite rw(ptr);
diff --git a/NorthstarDedicatedTest/rpakfilesystem.cpp b/NorthstarDedicatedTest/rpakfilesystem.cpp
index 5dfb2386..4da22b56 100644
--- a/NorthstarDedicatedTest/rpakfilesystem.cpp
+++ b/NorthstarDedicatedTest/rpakfilesystem.cpp
@@ -3,11 +3,11 @@
#include "hookutils.h"
#include "modmanager.h"
-typedef void*(*LoadCommonPaksForMapType)(char* map);
+typedef void* (*LoadCommonPaksForMapType)(char* map);
LoadCommonPaksForMapType LoadCommonPaksForMap;
-typedef void*(*LoadPakSyncType)(const char* path, void* unknownSingleton, int flags);
-typedef void*(*LoadPakAsyncType)(const char* path, void* unknownSingleton, int flags, void* callback0, void* callback1);
+typedef void* (*LoadPakSyncType)(const char* path, void* unknownSingleton, int flags);
+typedef void* (*LoadPakAsyncType)(const char* path, void* unknownSingleton, int flags, void* callback0, void* callback1);
// there are more i'm just too lazy to add
struct PakLoadFuncs
@@ -20,10 +20,7 @@ struct PakLoadFuncs
PakLoadFuncs* g_pakLoadApi;
void** pUnknownPakLoadSingleton;
-void LoadPakAsync(const char* path)
-{
- g_pakLoadApi->LoadPakAsync(path, *pUnknownPakLoadSingleton, 2, nullptr, nullptr);
-}
+void LoadPakAsync(const char* path) { g_pakLoadApi->LoadPakAsync(path, *pUnknownPakLoadSingleton, 2, nullptr, nullptr); }
void LoadCommonPaksForMapHook(char* map)
{
diff --git a/NorthstarDedicatedTest/scriptbrowserhooks.cpp b/NorthstarDedicatedTest/scriptbrowserhooks.cpp
index c5379da9..542df13a 100644
--- a/NorthstarDedicatedTest/scriptbrowserhooks.cpp
+++ b/NorthstarDedicatedTest/scriptbrowserhooks.cpp
@@ -3,7 +3,7 @@
#include "hookutils.h"
#include "dedicated.h"
-typedef void(*OpenExternalWebBrowserType)(char* url, char flags);
+typedef void (*OpenExternalWebBrowserType)(char* url, char flags);
OpenExternalWebBrowserType OpenExternalWebBrowser;
bool* bIsOriginOverlayEnabled;
@@ -26,5 +26,6 @@ void InitialiseScriptExternalBrowserHooks(HMODULE baseAddress)
bIsOriginOverlayEnabled = (bool*)baseAddress + 0x13978255;
HookEnabler hook;
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x184E40, &OpenExternalWebBrowserHook, reinterpret_cast<LPVOID*>(&OpenExternalWebBrowser));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x184E40, &OpenExternalWebBrowserHook, reinterpret_cast<LPVOID*>(&OpenExternalWebBrowser));
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/scriptmainmenupromos.cpp b/NorthstarDedicatedTest/scriptmainmenupromos.cpp
index 6f64e622..b19f1b13 100644
--- a/NorthstarDedicatedTest/scriptmainmenupromos.cpp
+++ b/NorthstarDedicatedTest/scriptmainmenupromos.cpp
@@ -15,11 +15,11 @@ enum eMainMenuPromoDataProperty
largeButtonText,
largeButtonUrl,
largeButtonImageIndex,
-
+
smallButton1Title,
smallButton1Url,
smallButton1ImageIndex,
-
+
smallButton2Title,
smallButton2Url,
smallButton2ImageIndex
@@ -47,85 +47,83 @@ SQRESULT SQ_GetCustomMainMenuPromoData(void* sqvm)
switch (ClientSq_getinteger(sqvm, 1))
{
- case eMainMenuPromoDataProperty::newInfoTitle1:
- {
- ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.newInfoTitle1.c_str(), -1);
- break;
- }
-
- case eMainMenuPromoDataProperty::newInfoTitle2:
- {
- ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.newInfoTitle2.c_str(), -1);
- break;
- }
-
- case eMainMenuPromoDataProperty::newInfoTitle3:
- {
- ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.newInfoTitle3.c_str(), -1);
- break;
- }
-
- case eMainMenuPromoDataProperty::largeButtonTitle:
- {
- ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.largeButtonTitle.c_str(), -1);
- break;
- }
-
- case eMainMenuPromoDataProperty::largeButtonText:
- {
- ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.largeButtonText.c_str(), -1);
- break;
- }
-
- case eMainMenuPromoDataProperty::largeButtonUrl:
- {
- ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.largeButtonUrl.c_str(), -1);
- break;
- }
-
- case eMainMenuPromoDataProperty::largeButtonImageIndex:
- {
- ClientSq_pushinteger(sqvm, g_MasterServerManager->m_MainMenuPromoData.largeButtonImageIndex);
- break;
- }
-
-
- case eMainMenuPromoDataProperty::smallButton1Title:
- {
- ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton1Title.c_str(), -1);
- break;
- }
-
- case eMainMenuPromoDataProperty::smallButton1Url:
- {
- ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton1Url.c_str(), -1);
- break;
- }
-
- case eMainMenuPromoDataProperty::smallButton1ImageIndex:
- {
- ClientSq_pushinteger(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton1ImageIndex);
- break;
- }
-
-
- case eMainMenuPromoDataProperty::smallButton2Title:
- {
- ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton2Title.c_str(), -1);
- break;
- }
-
- case eMainMenuPromoDataProperty::smallButton2Url:
- {
- ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton2Url.c_str(), -1);
- break;
- }
-
- case eMainMenuPromoDataProperty::smallButton2ImageIndex:
- {
- ClientSq_pushinteger(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton2ImageIndex);
- break;
- }
+ case eMainMenuPromoDataProperty::newInfoTitle1:
+ {
+ ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.newInfoTitle1.c_str(), -1);
+ break;
+ }
+
+ case eMainMenuPromoDataProperty::newInfoTitle2:
+ {
+ ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.newInfoTitle2.c_str(), -1);
+ break;
+ }
+
+ case eMainMenuPromoDataProperty::newInfoTitle3:
+ {
+ ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.newInfoTitle3.c_str(), -1);
+ break;
+ }
+
+ case eMainMenuPromoDataProperty::largeButtonTitle:
+ {
+ ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.largeButtonTitle.c_str(), -1);
+ break;
+ }
+
+ case eMainMenuPromoDataProperty::largeButtonText:
+ {
+ ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.largeButtonText.c_str(), -1);
+ break;
+ }
+
+ case eMainMenuPromoDataProperty::largeButtonUrl:
+ {
+ ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.largeButtonUrl.c_str(), -1);
+ break;
+ }
+
+ case eMainMenuPromoDataProperty::largeButtonImageIndex:
+ {
+ ClientSq_pushinteger(sqvm, g_MasterServerManager->m_MainMenuPromoData.largeButtonImageIndex);
+ break;
+ }
+
+ case eMainMenuPromoDataProperty::smallButton1Title:
+ {
+ ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton1Title.c_str(), -1);
+ break;
+ }
+
+ case eMainMenuPromoDataProperty::smallButton1Url:
+ {
+ ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton1Url.c_str(), -1);
+ break;
+ }
+
+ case eMainMenuPromoDataProperty::smallButton1ImageIndex:
+ {
+ ClientSq_pushinteger(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton1ImageIndex);
+ break;
+ }
+
+ case eMainMenuPromoDataProperty::smallButton2Title:
+ {
+ ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton2Title.c_str(), -1);
+ break;
+ }
+
+ case eMainMenuPromoDataProperty::smallButton2Url:
+ {
+ ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton2Url.c_str(), -1);
+ break;
+ }
+
+ case eMainMenuPromoDataProperty::smallButton2ImageIndex:
+ {
+ ClientSq_pushinteger(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton2ImageIndex);
+ break;
+ }
}
return SQRESULT_NOTNULL;
diff --git a/NorthstarDedicatedTest/scriptmodmenu.cpp b/NorthstarDedicatedTest/scriptmodmenu.cpp
index 47fa971d..aa12d5a7 100644
--- a/NorthstarDedicatedTest/scriptmodmenu.cpp
+++ b/NorthstarDedicatedTest/scriptmodmenu.cpp
@@ -59,7 +59,7 @@ SQRESULT SQ_SetModEnabled(void* sqvm)
SQRESULT SQ_GetModDescription(void* sqvm)
{
const SQChar* modName = ClientSq_getstring(sqvm, 1);
-
+
// manual lookup, not super performant but eh not a big deal
for (Mod& mod : g_ModManager->m_loadedMods)
{
@@ -182,14 +182,23 @@ void InitialiseScriptModMenu(HMODULE baseAddress)
return;
g_UISquirrelManager->AddFuncRegistration("array<string>", "NSGetModNames", "", "Returns the names of all loaded mods", SQ_GetModNames);
- g_UISquirrelManager->AddFuncRegistration("bool", "NSIsModEnabled", "string modName", "Returns whether a given mod is enabled", SQ_IsModEnabled);
- g_UISquirrelManager->AddFuncRegistration("void", "NSSetModEnabled", "string modName, bool enabled", "Sets whether a given mod is enabled", SQ_SetModEnabled);
- g_UISquirrelManager->AddFuncRegistration("string", "NSGetModDescriptionByModName", "string modName", "Returns a given mod's description", SQ_GetModDescription);
- g_UISquirrelManager->AddFuncRegistration("string", "NSGetModVersionByModName", "string modName", "Returns a given mod's version", SQ_GetModVersion);
- g_UISquirrelManager->AddFuncRegistration("string", "NSGetModDownloadLinkByModName", "string modName", "Returns a given mod's download link", SQ_GetModDownloadLink);
- g_UISquirrelManager->AddFuncRegistration("bool", "NSIsModRequiredOnClient", "string modName", "Returns whether a given mod is required on connecting clients", SQ_IsModRequiredOnClient);
- g_UISquirrelManager->AddFuncRegistration("int", "NSGetModLoadPriority", "string modName", "Returns a given mod's load priority", SQ_GetModLoadPriority);
- g_UISquirrelManager->AddFuncRegistration("array<string>", "NSGetModConvarsByModName", "string modName", "Returns the names of all a given mod's cvars", SQ_GetModConvars);
+ g_UISquirrelManager->AddFuncRegistration(
+ "bool", "NSIsModEnabled", "string modName", "Returns whether a given mod is enabled", SQ_IsModEnabled);
+ g_UISquirrelManager->AddFuncRegistration(
+ "void", "NSSetModEnabled", "string modName, bool enabled", "Sets whether a given mod is enabled", SQ_SetModEnabled);
+ g_UISquirrelManager->AddFuncRegistration(
+ "string", "NSGetModDescriptionByModName", "string modName", "Returns a given mod's description", SQ_GetModDescription);
+ g_UISquirrelManager->AddFuncRegistration(
+ "string", "NSGetModVersionByModName", "string modName", "Returns a given mod's version", SQ_GetModVersion);
+ g_UISquirrelManager->AddFuncRegistration(
+ "string", "NSGetModDownloadLinkByModName", "string modName", "Returns a given mod's download link", SQ_GetModDownloadLink);
+ g_UISquirrelManager->AddFuncRegistration(
+ "bool", "NSIsModRequiredOnClient", "string modName", "Returns whether a given mod is required on connecting clients",
+ SQ_IsModRequiredOnClient);
+ g_UISquirrelManager->AddFuncRegistration(
+ "int", "NSGetModLoadPriority", "string modName", "Returns a given mod's load priority", SQ_GetModLoadPriority);
+ g_UISquirrelManager->AddFuncRegistration(
+ "array<string>", "NSGetModConvarsByModName", "string modName", "Returns the names of all a given mod's cvars", SQ_GetModConvars);
g_UISquirrelManager->AddFuncRegistration("void", "NSReloadMods", "", "Reloads mods", SQ_ReloadMods);
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/scriptserverbrowser.cpp b/NorthstarDedicatedTest/scriptserverbrowser.cpp
index cc5dbcb5..00156856 100644
--- a/NorthstarDedicatedTest/scriptserverbrowser.cpp
+++ b/NorthstarDedicatedTest/scriptserverbrowser.cpp
@@ -50,7 +50,11 @@ SQRESULT SQ_GetServerName(void* sqvm)
if (serverIndex >= g_MasterServerManager->m_remoteServers.size())
{
- ClientSq_pusherror(sqvm, fmt::format("Tried to get name of server index {} when only {} servers are available", serverIndex, g_MasterServerManager->m_remoteServers.size()).c_str());
+ ClientSq_pusherror(
+ sqvm, fmt::format(
+ "Tried to get name of server index {} when only {} servers are available", serverIndex,
+ g_MasterServerManager->m_remoteServers.size())
+ .c_str());
return SQRESULT_ERROR;
}
@@ -65,7 +69,11 @@ SQRESULT SQ_GetServerDescription(void* sqvm)
if (serverIndex >= g_MasterServerManager->m_remoteServers.size())
{
- ClientSq_pusherror(sqvm, fmt::format("Tried to get description of server index {} when only {} servers are available", serverIndex, g_MasterServerManager->m_remoteServers.size()).c_str());
+ ClientSq_pusherror(
+ sqvm, fmt::format(
+ "Tried to get description of server index {} when only {} servers are available", serverIndex,
+ g_MasterServerManager->m_remoteServers.size())
+ .c_str());
return SQRESULT_ERROR;
}
@@ -80,7 +88,11 @@ SQInteger SQ_GetServerMap(void* sqvm)
if (serverIndex >= g_MasterServerManager->m_remoteServers.size())
{
- ClientSq_pusherror(sqvm, fmt::format("Tried to get map of server index {} when only {} servers are available", serverIndex, g_MasterServerManager->m_remoteServers.size()).c_str());
+ ClientSq_pusherror(
+ sqvm, fmt::format(
+ "Tried to get map of server index {} when only {} servers are available", serverIndex,
+ g_MasterServerManager->m_remoteServers.size())
+ .c_str());
return SQRESULT_ERROR;
}
@@ -95,7 +107,11 @@ SQRESULT SQ_GetServerPlaylist(void* sqvm)
if (serverIndex >= g_MasterServerManager->m_remoteServers.size())
{
- ClientSq_pusherror(sqvm, fmt::format("Tried to get playlist of server index {} when only {} servers are available", serverIndex, g_MasterServerManager->m_remoteServers.size()).c_str());
+ ClientSq_pusherror(
+ sqvm, fmt::format(
+ "Tried to get playlist of server index {} when only {} servers are available", serverIndex,
+ g_MasterServerManager->m_remoteServers.size())
+ .c_str());
return SQRESULT_ERROR;
}
@@ -110,7 +126,11 @@ SQRESULT SQ_GetServerPlayerCount(void* sqvm)
if (serverIndex >= g_MasterServerManager->m_remoteServers.size())
{
- ClientSq_pusherror(sqvm, fmt::format("Tried to get playercount of server index {} when only {} servers are available", serverIndex, g_MasterServerManager->m_remoteServers.size()).c_str());
+ ClientSq_pusherror(
+ sqvm, fmt::format(
+ "Tried to get playercount of server index {} when only {} servers are available", serverIndex,
+ g_MasterServerManager->m_remoteServers.size())
+ .c_str());
return SQRESULT_ERROR;
}
@@ -125,7 +145,11 @@ SQRESULT SQ_GetServerMaxPlayerCount(void* sqvm)
if (serverIndex >= g_MasterServerManager->m_remoteServers.size())
{
- ClientSq_pusherror(sqvm, fmt::format("Tried to get max playercount of server index {} when only {} servers are available", serverIndex, g_MasterServerManager->m_remoteServers.size()).c_str());
+ ClientSq_pusherror(
+ sqvm, fmt::format(
+ "Tried to get max playercount of server index {} when only {} servers are available", serverIndex,
+ g_MasterServerManager->m_remoteServers.size())
+ .c_str());
return SQRESULT_ERROR;
}
@@ -140,7 +164,11 @@ SQRESULT SQ_GetServerID(void* sqvm)
if (serverIndex >= g_MasterServerManager->m_remoteServers.size())
{
- ClientSq_pusherror(sqvm, fmt::format("Tried to get id of server index {} when only {} servers are available", serverIndex, g_MasterServerManager->m_remoteServers.size()).c_str());
+ ClientSq_pusherror(
+ sqvm, fmt::format(
+ "Tried to get id of server index {} when only {} servers are available", serverIndex,
+ g_MasterServerManager->m_remoteServers.size())
+ .c_str());
return SQRESULT_ERROR;
}
@@ -155,7 +183,11 @@ SQRESULT SQ_ServerRequiresPassword(void* sqvm)
if (serverIndex >= g_MasterServerManager->m_remoteServers.size())
{
- ClientSq_pusherror(sqvm, fmt::format("Tried to get hasPassword of server index {} when only {} servers are available", serverIndex, g_MasterServerManager->m_remoteServers.size()).c_str());
+ ClientSq_pusherror(
+ sqvm, fmt::format(
+ "Tried to get hasPassword of server index {} when only {} servers are available", serverIndex,
+ g_MasterServerManager->m_remoteServers.size())
+ .c_str());
return SQRESULT_ERROR;
}
@@ -170,7 +202,11 @@ SQRESULT SQ_GetServerRequiredModsCount(void* sqvm)
if (serverIndex >= g_MasterServerManager->m_remoteServers.size())
{
- ClientSq_pusherror(sqvm, fmt::format("Tried to get required mods count of server index {} when only {} servers are available", serverIndex, g_MasterServerManager->m_remoteServers.size()).c_str());
+ ClientSq_pusherror(
+ sqvm, fmt::format(
+ "Tried to get required mods count of server index {} when only {} servers are available", serverIndex,
+ g_MasterServerManager->m_remoteServers.size())
+ .c_str());
return SQRESULT_ERROR;
}
@@ -186,13 +222,21 @@ SQRESULT SQ_GetServerRequiredModName(void* sqvm)
if (serverIndex >= g_MasterServerManager->m_remoteServers.size())
{
- ClientSq_pusherror(sqvm, fmt::format("Tried to get hasPassword of server index {} when only {} servers are available", serverIndex, g_MasterServerManager->m_remoteServers.size()).c_str());
+ ClientSq_pusherror(
+ sqvm, fmt::format(
+ "Tried to get hasPassword of server index {} when only {} servers are available", serverIndex,
+ g_MasterServerManager->m_remoteServers.size())
+ .c_str());
return SQRESULT_ERROR;
}
if (modIndex >= g_MasterServerManager->m_remoteServers[serverIndex].requiredMods.size())
{
- ClientSq_pusherror(sqvm, fmt::format("Tried to get required mod name of mod index {} when only {} mod are available", modIndex, g_MasterServerManager->m_remoteServers[serverIndex].requiredMods.size()).c_str());
+ ClientSq_pusherror(
+ sqvm, fmt::format(
+ "Tried to get required mod name of mod index {} when only {} mod are available", modIndex,
+ g_MasterServerManager->m_remoteServers[serverIndex].requiredMods.size())
+ .c_str());
return SQRESULT_ERROR;
}
@@ -208,13 +252,21 @@ SQRESULT SQ_GetServerRequiredModVersion(void* sqvm)
if (serverIndex >= g_MasterServerManager->m_remoteServers.size())
{
- ClientSq_pusherror(sqvm, fmt::format("Tried to get required mod version of server index {} when only {} servers are available", serverIndex, g_MasterServerManager->m_remoteServers.size()).c_str());
+ ClientSq_pusherror(
+ sqvm, fmt::format(
+ "Tried to get required mod version of server index {} when only {} servers are available", serverIndex,
+ g_MasterServerManager->m_remoteServers.size())
+ .c_str());
return SQRESULT_ERROR;
}
if (modIndex >= g_MasterServerManager->m_remoteServers[serverIndex].requiredMods.size())
{
- ClientSq_pusherror(sqvm, fmt::format("Tried to get required mod version of mod index {} when only {} mod are available", modIndex, g_MasterServerManager->m_remoteServers[serverIndex].requiredMods.size()).c_str());
+ ClientSq_pusherror(
+ sqvm, fmt::format(
+ "Tried to get required mod version of mod index {} when only {} mod are available", modIndex,
+ g_MasterServerManager->m_remoteServers[serverIndex].requiredMods.size())
+ .c_str());
return SQRESULT_ERROR;
}
@@ -229,7 +281,6 @@ SQRESULT SQ_ClearRecievedServerList(void* sqvm)
return SQRESULT_NULL;
}
-
// functions for authenticating with servers
// void function NSTryAuthWithServer( int serverIndex, string password = "" )
@@ -240,17 +291,23 @@ SQRESULT SQ_TryAuthWithServer(void* sqvm)
if (serverIndex >= g_MasterServerManager->m_remoteServers.size())
{
- ClientSq_pusherror(sqvm, fmt::format("Tried to auth with server index {} when only {} servers are available", serverIndex, g_MasterServerManager->m_remoteServers.size()).c_str());
+ ClientSq_pusherror(
+ sqvm, fmt::format(
+ "Tried to auth with server index {} when only {} servers are available", serverIndex,
+ g_MasterServerManager->m_remoteServers.size())
+ .c_str());
return SQRESULT_ERROR;
}
- // send off persistent data first, don't worry about server/client stuff, since m_additionalPlayerData should only have entries when we're a local server
- // note: this seems like it could create a race condition, test later
+ // send off persistent data first, don't worry about server/client stuff, since m_additionalPlayerData should only have entries when
+ // we're a local server note: this seems like it could create a race condition, test later
for (auto& pair : g_ServerAuthenticationManager->m_additionalPlayerData)
g_ServerAuthenticationManager->WritePersistentData(pair.first);
// do auth
- g_MasterServerManager->AuthenticateWithServer(g_LocalPlayerUserID, g_MasterServerManager->m_ownClientAuthToken, g_MasterServerManager->m_remoteServers[serverIndex].id, (char*)password);
+ g_MasterServerManager->AuthenticateWithServer(
+ g_LocalPlayerUserID, g_MasterServerManager->m_ownClientAuthToken, g_MasterServerManager->m_remoteServers[serverIndex].id,
+ (char*)password);
return SQRESULT_NULL;
}
@@ -283,7 +340,13 @@ SQRESULT SQ_ConnectToAuthedServer(void* sqvm)
// set auth token, then try to connect
// i'm honestly not entirely sure how silentconnect works regarding ports and encryption so using connect for now
Cbuf_AddText(Cbuf_GetCurrentPlayer(), fmt::format("serverfilter {}", info.authToken).c_str(), cmd_source_t::kCommandSrcCode);
- Cbuf_AddText(Cbuf_GetCurrentPlayer(), fmt::format("connect {}.{}.{}.{}:{}", info.ip.S_un.S_un_b.s_b1, info.ip.S_un.S_un_b.s_b2, info.ip.S_un.S_un_b.s_b3, info.ip.S_un.S_un_b.s_b4, info.port).c_str(), cmd_source_t::kCommandSrcCode);
+ Cbuf_AddText(
+ Cbuf_GetCurrentPlayer(),
+ fmt::format(
+ "connect {}.{}.{}.{}:{}", info.ip.S_un.S_un_b.s_b1, info.ip.S_un.S_un_b.s_b2, info.ip.S_un.S_un_b.s_b3,
+ info.ip.S_un.S_un_b.s_b4, info.port)
+ .c_str(),
+ cmd_source_t::kCommandSrcCode);
g_MasterServerManager->m_hasPendingConnectionInfo = false;
return SQRESULT_NULL;
@@ -303,7 +366,9 @@ SQRESULT SQ_CompleteAuthWithLocalServer(void* sqvm)
{
// literally just set serverfilter
// note: this assumes we have no authdata other than our own
- Cbuf_AddText(Cbuf_GetCurrentPlayer(), fmt::format("serverfilter {}", g_ServerAuthenticationManager->m_authData.begin()->first).c_str(), cmd_source_t::kCommandSrcCode);
+ Cbuf_AddText(
+ Cbuf_GetCurrentPlayer(), fmt::format("serverfilter {}", g_ServerAuthenticationManager->m_authData.begin()->first).c_str(),
+ cmd_source_t::kCommandSrcCode);
return SQRESULT_NULL;
}
@@ -329,10 +394,13 @@ void InitialiseScriptServerBrowser(HMODULE baseAddress)
g_UISquirrelManager->AddFuncRegistration("string", "NSGetServerID", "int serverIndex", "", SQ_GetServerID);
g_UISquirrelManager->AddFuncRegistration("bool", "NSServerRequiresPassword", "int serverIndex", "", SQ_ServerRequiresPassword);
g_UISquirrelManager->AddFuncRegistration("int", "NSGetServerRequiredModsCount", "int serverIndex", "", SQ_GetServerRequiredModsCount);
- g_UISquirrelManager->AddFuncRegistration("string", "NSGetServerRequiredModName", "int serverIndex, int modIndex", "", SQ_GetServerRequiredModName);
- g_UISquirrelManager->AddFuncRegistration("string", "NSGetServerRequiredModVersion", "int serverIndex, int modIndex", "", SQ_GetServerRequiredModVersion);
+ g_UISquirrelManager->AddFuncRegistration(
+ "string", "NSGetServerRequiredModName", "int serverIndex, int modIndex", "", SQ_GetServerRequiredModName);
+ g_UISquirrelManager->AddFuncRegistration(
+ "string", "NSGetServerRequiredModVersion", "int serverIndex, int modIndex", "", SQ_GetServerRequiredModVersion);
- g_UISquirrelManager->AddFuncRegistration("void", "NSTryAuthWithServer", "int serverIndex, string password = \"\"", "", SQ_TryAuthWithServer);
+ g_UISquirrelManager->AddFuncRegistration(
+ "void", "NSTryAuthWithServer", "int serverIndex, string password = \"\"", "", SQ_TryAuthWithServer);
g_UISquirrelManager->AddFuncRegistration("bool", "NSIsAuthenticatingWithServer", "", "", SQ_IsAuthComplete);
g_UISquirrelManager->AddFuncRegistration("bool", "NSWasAuthSuccessful", "", "", SQ_WasAuthSuccessful);
g_UISquirrelManager->AddFuncRegistration("void", "NSConnectToAuthedServer", "", "", SQ_ConnectToAuthedServer);
diff --git a/NorthstarDedicatedTest/scriptsrson.cpp b/NorthstarDedicatedTest/scriptsrson.cpp
index a2bf2457..91a12737 100644
--- a/NorthstarDedicatedTest/scriptsrson.cpp
+++ b/NorthstarDedicatedTest/scriptsrson.cpp
@@ -62,6 +62,6 @@ void ModManager::BuildScriptsRson()
else
m_modFiles[VPK_SCRIPTS_RSON_PATH] = overrideFile;
- // todo: for preventing dupe scripts in scripts.rson, we could actually parse when conditions with the squirrel vm, just need a way to get a result out of squirrelmanager.ExecuteCode
- // this would probably be the best way to do this, imo
+ // todo: for preventing dupe scripts in scripts.rson, we could actually parse when conditions with the squirrel vm, just need a way to
+ // get a result out of squirrelmanager.ExecuteCode this would probably be the best way to do this, imo
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/securitypatches.cpp b/NorthstarDedicatedTest/securitypatches.cpp
index 3664e96a..3531ffa5 100644
--- a/NorthstarDedicatedTest/securitypatches.cpp
+++ b/NorthstarDedicatedTest/securitypatches.cpp
@@ -5,7 +5,7 @@
#include "dedicated.h"
#include "gameutils.h"
-typedef bool(*IsValveModType)();
+typedef bool (*IsValveModType)();
IsValveModType IsValveMod;
bool IsValveModHook()
@@ -25,7 +25,7 @@ void InitialiseClientEngineSecurityPatches(HMODULE baseAddress)
// note: this could break some things
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1C6360, &IsValveModHook, reinterpret_cast<LPVOID*>(&IsValveMod));
-
+
// patches to make commands run from client/ui script still work
// note: this is likely preventable in a nicer way? test prolly
{
@@ -49,7 +49,7 @@ void InitialiseClientEngineSecurityPatches(HMODULE baseAddress)
// disconnect concommand
void* ptr = (char*)baseAddress + 0x5ADA2D;
TempReadWrite rw(ptr);
-
+
*((int*)ptr) |= FCVAR_SERVER_CAN_EXECUTE;
}
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/serverauthentication.cpp b/NorthstarDedicatedTest/serverauthentication.cpp
index 5235761a..112db2a4 100644
--- a/NorthstarDedicatedTest/serverauthentication.cpp
+++ b/NorthstarDedicatedTest/serverauthentication.cpp
@@ -18,33 +18,36 @@ const char* AUTHSERVER_VERIFY_STRING = "I am a northstar server!";
// hook types
-typedef void*(*CBaseServer__ConnectClientType)(void* server, void* a2, void* a3, uint32_t a4, uint32_t a5, int32_t a6, void* a7, void* a8, char* serverFilter, void* a10, char a11, void* a12, char a13, char a14, int64_t uid, uint32_t a16, uint32_t a17);
+typedef void* (*CBaseServer__ConnectClientType)(
+ void* server, void* a2, void* a3, uint32_t a4, uint32_t a5, int32_t a6, void* a7, void* a8, char* serverFilter, void* a10, char a11,
+ void* a12, char a13, char a14, int64_t uid, uint32_t a16, uint32_t a17);
CBaseServer__ConnectClientType CBaseServer__ConnectClient;
-typedef bool(*CBaseClient__ConnectType)(void* self, char* name, __int64 netchan_ptr_arg, char b_fake_player_arg, __int64 a5, char* Buffer, void* a7);
+typedef bool (*CBaseClient__ConnectType)(
+ void* self, char* name, __int64 netchan_ptr_arg, char b_fake_player_arg, __int64 a5, char* Buffer, void* a7);
CBaseClient__ConnectType CBaseClient__Connect;
-typedef void(*CBaseClient__ActivatePlayerType)(void* self);
+typedef void (*CBaseClient__ActivatePlayerType)(void* self);
CBaseClient__ActivatePlayerType CBaseClient__ActivatePlayer;
CBaseClient__DisconnectType CBaseClient__Disconnect;
-typedef char(*CGameClient__ExecuteStringCommandType)(void* self, uint32_t unknown, const char* pCommandString);
+typedef char (*CGameClient__ExecuteStringCommandType)(void* self, uint32_t unknown, const char* pCommandString);
CGameClient__ExecuteStringCommandType CGameClient__ExecuteStringCommand;
-typedef char(*__fastcall CNetChan___ProcessMessagesType)(void* self, void* buf);
+typedef char (*__fastcall CNetChan___ProcessMessagesType)(void* self, void* buf);
CNetChan___ProcessMessagesType CNetChan___ProcessMessages;
-typedef char(*CBaseClient__SendServerInfoType)(void* self);
+typedef char (*CBaseClient__SendServerInfoType)(void* self);
CBaseClient__SendServerInfoType CBaseClient__SendServerInfo;
-typedef bool(*ProcessConnectionlessPacketType)(void* a1, netpacket_t* packet);
+typedef bool (*ProcessConnectionlessPacketType)(void* a1, netpacket_t* packet);
ProcessConnectionlessPacketType ProcessConnectionlessPacket;
-typedef void(*CServerGameDLL__OnRecievedSayTextMessageType)(void* self, unsigned int senderClientIndex, const char* message, char unknown);
+typedef void (*CServerGameDLL__OnRecievedSayTextMessageType)(void* self, unsigned int senderClientIndex, const char* message, char unknown);
CServerGameDLL__OnRecievedSayTextMessageType CServerGameDLL__OnRecievedSayTextMessage;
-typedef void(*ConCommand__DispatchType)(ConCommand* command, const CCommand& args, void* a3);
+typedef void (*ConCommand__DispatchType)(ConCommand* command, const CCommand& args, void* a3);
ConCommand__DispatchType ConCommand__Dispatch;
// global vars
@@ -71,23 +74,36 @@ void ServerAuthenticationManager::StartPlayerAuthServer()
m_runningPlayerAuthThread = true;
// listen is a blocking call so thread this
- std::thread serverThread([this] {
- // this is just a super basic way to verify that servers have ports open, masterserver will try to read this before ensuring server is legit
- m_playerAuthServer.Get("/verify", [](const httplib::Request& request, httplib::Response& response) {
- response.set_content(AUTHSERVER_VERIFY_STRING, "text/plain");
- });
-
- m_playerAuthServer.Post("/authenticate_incoming_player", [this](const httplib::Request& request, httplib::Response& response) {
- // can't just do request.remote_addr == Cvar_ns_masterserver_hostname->m_pszString because the cvar can be a url, gotta resolve an ip from it for comparisons
- //unsigned long remoteAddr = inet_addr(request.remote_addr.c_str());
+ std::thread serverThread(
+ [this]
+ {
+ // this is just a super basic way to verify that servers have ports open, masterserver will try to read this before ensuring
+ // server is legit
+ m_playerAuthServer.Get(
+ "/verify", [](const httplib::Request& request, httplib::Response& response)
+ { response.set_content(AUTHSERVER_VERIFY_STRING, "text/plain"); });
+
+ m_playerAuthServer.Post(
+ "/authenticate_incoming_player",
+ [this](const httplib::Request& request, httplib::Response& response)
+ {
+ // can't just do request.remote_addr == Cvar_ns_masterserver_hostname->m_pszString because the cvar can be a url, gotta
+ // resolve an ip from it for comparisons
+ // unsigned long remoteAddr = inet_addr(request.remote_addr.c_str());
//
- //char* addrPtr = Cvar_ns_masterserver_hostname->m_pszString;
- //char* typeStart = strstr(addrPtr, "://");
- //if (typeStart)
+ // char* addrPtr = Cvar_ns_masterserver_hostname->m_pszString;
+ // char* typeStart = strstr(addrPtr, "://");
+ // if (typeStart)
// addrPtr = typeStart + 3;
- //hostent* resolvedRemoteAddr = gethostbyname((const char*)addrPtr);
-
- if (!request.has_param("id") || !request.has_param("authToken") || request.body.size() >= 65335 || !request.has_param("serverAuthToken") || strcmp(g_MasterServerManager->m_ownServerAuthToken, request.get_param_value("serverAuthToken").c_str()))// || !resolvedRemoteAddr || ((in_addr**)resolvedRemoteAddr->h_addr_list)[0]->S_un.S_addr != remoteAddr)
+ // hostent* resolvedRemoteAddr = gethostbyname((const char*)addrPtr);
+
+ if (!request.has_param("id") || !request.has_param("authToken") || request.body.size() >= 65335 ||
+ !request.has_param("serverAuthToken") ||
+ strcmp(
+ g_MasterServerManager->m_ownServerAuthToken,
+ request.get_param_value("serverAuthToken")
+ .c_str())) // || !resolvedRemoteAddr || ((in_addr**)resolvedRemoteAddr->h_addr_list)[0]->S_un.S_addr !=
+ // remoteAddr)
{
response.set_content("{\"success\":false}", "application/json");
return;
@@ -109,7 +125,7 @@ void ServerAuthenticationManager::StartPlayerAuthServer()
m_playerAuthServer.listen("0.0.0.0", Cvar_ns_player_auth_port->m_nValue);
});
-
+
serverThread.detach();
}
@@ -170,7 +186,6 @@ bool ServerAuthenticationManager::AuthenticatePlayer(void* player, int64_t uid,
}
}
-
if (authFail)
{
// set persistent data as ready, we use 0x3 internally to mark the client as using local persistence
@@ -191,7 +206,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");
-
+
// get file length
pdataStream.seekg(0, pdataStream.end);
auto length = pdataStream.tellg();
@@ -238,7 +253,8 @@ void ServerAuthenticationManager::WritePersistentData(void* player)
// we use 0x4 internally to mark clients as using remote persistence
if (*((char*)player + 0x4A0) == (char)0x4)
{
- g_MasterServerManager->WritePlayerPersistentData((char*)player + 0xF500, (char*)player + 0x4FA, m_additionalPlayerData[player].pdataSize);
+ g_MasterServerManager->WritePlayerPersistentData(
+ (char*)player + 0xF500, (char*)player + 0x4FA, m_additionalPlayerData[player].pdataSize);
}
else if (CVar_ns_auth_allow_insecure_write->m_nValue)
{
@@ -246,7 +262,6 @@ void ServerAuthenticationManager::WritePersistentData(void* player)
}
}
-
// auth hooks
// store these in vars so we can use them in CBaseClient::Connect
@@ -254,7 +269,9 @@ void ServerAuthenticationManager::WritePersistentData(void* player)
char* nextPlayerToken;
uint64_t nextPlayerUid;
-void* CBaseServer__ConnectClientHook(void* server, void* a2, void* a3, uint32_t a4, uint32_t a5, int32_t a6, void* a7, void* a8, char* serverFilter, void* a10, char a11, void* a12, char a13, char a14, int64_t uid, uint32_t a16, uint32_t a17)
+void* CBaseServer__ConnectClientHook(
+ void* server, void* a2, void* a3, uint32_t a4, uint32_t a5, int32_t a6, void* a7, void* a8, char* serverFilter, void* a10, char a11,
+ void* a12, char a13, char a14, int64_t uid, uint32_t a16, uint32_t a17)
{
// auth tokens are sent with serverfilter, can't be accessed from player struct to my knowledge, so have to do this here
nextPlayerToken = serverFilter;
@@ -268,7 +285,7 @@ bool CBaseClient__ConnectHook(void* self, char* name, __int64 netchan_ptr_arg, c
// try to auth player, dc if it fails
// we connect irregardless of auth, because returning bad from this function can fuck client state p bad
bool ret = CBaseClient__Connect(self, name, netchan_ptr_arg, b_fake_player_arg, a5, Buffer, a7);
-
+
if (!ret)
return ret;
@@ -280,7 +297,9 @@ bool CBaseClient__ConnectHook(void* self, char* name, __int64 netchan_ptr_arg, c
if (strlen(name) >= 64) // fix for name overflow bug
CBaseClient__Disconnect(self, 1, "Invalid name");
- else if (!g_ServerAuthenticationManager->AuthenticatePlayer(self, nextPlayerUid, nextPlayerToken) && g_MasterServerManager->m_bRequireClientAuth)
+ else if (
+ !g_ServerAuthenticationManager->AuthenticatePlayer(self, nextPlayerUid, nextPlayerToken) &&
+ g_MasterServerManager->m_bRequireClientAuth)
CBaseClient__Disconnect(self, 1, "Authentication Failed");
if (!g_ServerAuthenticationManager->m_additionalPlayerData.count(self))
@@ -298,7 +317,8 @@ bool CBaseClient__ConnectHook(void* self, char* name, __int64 netchan_ptr_arg, c
void CBaseClient__ActivatePlayerHook(void* self)
{
// if we're authed, write our persistent data
- // RemovePlayerAuthData returns true if it removed successfully, i.e. on first call only, and we only want to write on >= second call (since this func is called on map loads)
+ // RemovePlayerAuthData returns true if it removed successfully, i.e. on first call only, and we only want to write on >= second call
+ // (since this func is called on map loads)
if (*((char*)self + 0x4A0) >= (char)0x3 && !g_ServerAuthenticationManager->RemovePlayerAuthData(self))
{
g_ServerAuthenticationManager->m_bForceReadLocalPlayerPersistenceFromDisk = false;
@@ -340,7 +360,7 @@ void CBaseClient__DisconnectHook(void* self, uint32_t unknownButAlways1, const c
}
// maybe this should be done outside of auth code, but effort to refactor rn and it sorta fits
-typedef bool(*CCommand__TokenizeType)(CCommand& self, const char* pCommandString, cmd_source_t commandSource);
+typedef bool (*CCommand__TokenizeType)(CCommand& self, const char* pCommandString, cmd_source_t commandSource);
CCommand__TokenizeType CCommand__Tokenize;
char CGameClient__ExecuteStringCommandHook(void* self, uint32_t unknown, const char* pCommandString)
@@ -357,7 +377,8 @@ char CGameClient__ExecuteStringCommandHook(void* self, uint32_t unknown, const c
}
g_ServerAuthenticationManager->m_additionalPlayerData[self].numClientCommandsInQuota++;
- if (g_ServerAuthenticationManager->m_additionalPlayerData[self].numClientCommandsInQuota > CVar_sv_quota_stringcmdspersecond->m_nValue)
+ if (g_ServerAuthenticationManager->m_additionalPlayerData[self].numClientCommandsInQuota >
+ CVar_sv_quota_stringcmdspersecond->m_nValue)
{
// too many stringcmds, dc player
CBaseClient__Disconnect(self, 1, "Sent too many stringcmd commands");
@@ -394,7 +415,7 @@ char __fastcall CNetChan___ProcessMessagesHook(void* self, void* buf)
{
double startTime = Plat_FloatTime();
char ret = CNetChan___ProcessMessages(self, buf);
-
+
// check processing limits, unless we're in a level transition
if (g_pHostState->m_iCurrentState == HostState_t::HS_RUN && ThreadInServerFrameThread())
{
@@ -407,17 +428,23 @@ char __fastcall CNetChan___ProcessMessagesHook(void* self, void* buf)
return ret;
// reset every second
- if (startTime - g_ServerAuthenticationManager->m_additionalPlayerData[sender].lastNetChanProcessingLimitStart >= 1.0 || g_ServerAuthenticationManager->m_additionalPlayerData[sender].lastNetChanProcessingLimitStart == -1.0)
+ if (startTime - g_ServerAuthenticationManager->m_additionalPlayerData[sender].lastNetChanProcessingLimitStart >= 1.0 ||
+ g_ServerAuthenticationManager->m_additionalPlayerData[sender].lastNetChanProcessingLimitStart == -1.0)
{
g_ServerAuthenticationManager->m_additionalPlayerData[sender].lastNetChanProcessingLimitStart = startTime;
g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime = 0.0;
}
- g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime += (Plat_FloatTime() * 1000) - (startTime * 1000);
+ g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime +=
+ (Plat_FloatTime() * 1000) - (startTime * 1000);
- if (g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime >= Cvar_net_chan_limit_msec_per_sec->m_nValue)
+ if (g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime >=
+ Cvar_net_chan_limit_msec_per_sec->m_nValue)
{
- spdlog::warn("Client {} hit netchan processing limit with {}ms of processing time this second (max is {})", (char*)sender + 0x16, g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime, Cvar_net_chan_limit_msec_per_sec->m_nValue);
-
+ spdlog::warn(
+ "Client {} hit netchan processing limit with {}ms of processing time this second (max is {})", (char*)sender + 0x16,
+ g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime,
+ Cvar_net_chan_limit_msec_per_sec->m_nValue);
+
// nonzero = kick, 0 = warn
if (Cvar_net_chan_limit_mode->m_nValue)
{
@@ -437,12 +464,14 @@ void CBaseClient__SendServerInfoHook(void* self)
bWasWritingStringTableSuccessful = true;
CBaseClient__SendServerInfo(self);
if (!bWasWritingStringTableSuccessful)
- CBaseClient__Disconnect(self, 1, "Overflowed CNetworkStringTableContainer::WriteBaselines, try restarting your client and reconnecting");
+ CBaseClient__Disconnect(
+ self, 1, "Overflowed CNetworkStringTableContainer::WriteBaselines, try restarting your client and reconnecting");
}
bool ProcessConnectionlessPacketHook(void* a1, netpacket_t* packet)
{
- if (packet->adr.type == NA_IP && (!(packet->data[4] == 'N' && Cvar_net_datablock_enabled->m_nValue) || !Cvar_net_datablock_enabled->m_nValue))
+ if (packet->adr.type == NA_IP &&
+ (!(packet->data[4] == 'N' && Cvar_net_datablock_enabled->m_nValue) || !Cvar_net_datablock_enabled->m_nValue))
{
// bad lookup: optimise later tm
UnconnectedPlayerSendData* sendData = nullptr;
@@ -474,7 +503,9 @@ bool ProcessConnectionlessPacketHook(void* a1, netpacket_t* packet)
if (sendData->packetCount >= Cvar_sv_querylimit_per_sec->m_nValue)
{
- spdlog::warn("Client went over connectionless ratelimit of {} per sec with packet of type {}", Cvar_sv_querylimit_per_sec->m_nValue, packet->data[4]);
+ spdlog::warn(
+ "Client went over connectionless ratelimit of {} per sec with packet of type {}", Cvar_sv_querylimit_per_sec->m_nValue,
+ packet->data[4]);
// timeout for a minute
sendData->timeoutEnd = Plat_FloatTime() + 60.0;
@@ -523,14 +554,23 @@ void InitialiseServerAuthentication(HMODULE baseAddress)
{
g_ServerAuthenticationManager = new ServerAuthenticationManager;
- Cvar_ns_erase_auth_info = RegisterConVar("ns_erase_auth_info", "1", FCVAR_GAMEDLL, "Whether auth info should be erased from this server on disconnect or crash");
- CVar_ns_auth_allow_insecure = RegisterConVar("ns_auth_allow_insecure", "0", FCVAR_GAMEDLL, "Whether this server will allow unauthenicated players to connect");
- CVar_ns_auth_allow_insecure_write = RegisterConVar("ns_auth_allow_insecure_write", "0", FCVAR_GAMEDLL, "Whether the pdata of unauthenticated clients will be written to disk when changed");
+ Cvar_ns_erase_auth_info = RegisterConVar(
+ "ns_erase_auth_info", "1", FCVAR_GAMEDLL, "Whether auth info should be erased from this server on disconnect or crash");
+ CVar_ns_auth_allow_insecure =
+ RegisterConVar("ns_auth_allow_insecure", "0", FCVAR_GAMEDLL, "Whether this server will allow unauthenicated players to connect");
+ CVar_ns_auth_allow_insecure_write = RegisterConVar(
+ "ns_auth_allow_insecure_write", "0", FCVAR_GAMEDLL,
+ "Whether the pdata of unauthenticated clients will be written to disk when changed");
// literally just stolen from a fix valve used in csgo
- CVar_sv_quota_stringcmdspersecond = RegisterConVar("sv_quota_stringcmdspersecond", "60", FCVAR_GAMEDLL, "How many string commands per second clients are allowed to submit, 0 to disallow all string commands");
+ CVar_sv_quota_stringcmdspersecond = RegisterConVar(
+ "sv_quota_stringcmdspersecond", "60", FCVAR_GAMEDLL,
+ "How many string commands per second clients are allowed to submit, 0 to disallow all string commands");
// https://blog.counter-strike.net/index.php/2019/07/24922/ but different because idk how to check what current tick number is
- Cvar_net_chan_limit_mode = RegisterConVar("net_chan_limit_mode", "0", FCVAR_GAMEDLL, "The mode for netchan processing limits: 0 = log, 1 = kick");
- Cvar_net_chan_limit_msec_per_sec = RegisterConVar("net_chan_limit_msec_per_sec", "0", FCVAR_GAMEDLL, "Netchannel processing is limited to so many milliseconds, abort connection if exceeding budget");
+ Cvar_net_chan_limit_mode =
+ RegisterConVar("net_chan_limit_mode", "0", FCVAR_GAMEDLL, "The mode for netchan processing limits: 0 = log, 1 = kick");
+ Cvar_net_chan_limit_msec_per_sec = RegisterConVar(
+ "net_chan_limit_msec_per_sec", "0", FCVAR_GAMEDLL,
+ "Netchannel processing is limited to so many milliseconds, abort connection if exceeding budget");
Cvar_ns_player_auth_port = RegisterConVar("ns_player_auth_port", "8081", FCVAR_GAMEDLL, "");
Cvar_sv_querylimit_per_sec = RegisterConVar("sv_querylimit_per_sec", "15", FCVAR_GAMEDLL, "");
Cvar_sv_max_chat_messages_per_sec = RegisterConVar("sv_max_chat_messages_per_sec", "5", FCVAR_GAMEDLL, "");
@@ -538,14 +578,22 @@ void InitialiseServerAuthentication(HMODULE baseAddress)
RegisterConCommand("ns_resetpersistence", ResetPdataCommand, "resets your pdata when you next enter the lobby", FCVAR_NONE);
HookEnabler hook;
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x114430, &CBaseServer__ConnectClientHook, reinterpret_cast<LPVOID*>(&CBaseServer__ConnectClient));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x114430, &CBaseServer__ConnectClientHook, reinterpret_cast<LPVOID*>(&CBaseServer__ConnectClient));
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x101740, &CBaseClient__ConnectHook, reinterpret_cast<LPVOID*>(&CBaseClient__Connect));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x100F80, &CBaseClient__ActivatePlayerHook, reinterpret_cast<LPVOID*>(&CBaseClient__ActivatePlayer));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1012C0, &CBaseClient__DisconnectHook, reinterpret_cast<LPVOID*>(&CBaseClient__Disconnect));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1022E0, &CGameClient__ExecuteStringCommandHook, reinterpret_cast<LPVOID*>(&CGameClient__ExecuteStringCommand));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x2140A0, &CNetChan___ProcessMessagesHook, reinterpret_cast<LPVOID*>(&CNetChan___ProcessMessages));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x104FB0, &CBaseClient__SendServerInfoHook, reinterpret_cast<LPVOID*>(&CBaseClient__SendServerInfo));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x117800, &ProcessConnectionlessPacketHook, reinterpret_cast<LPVOID*>(&ProcessConnectionlessPacket));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x100F80, &CBaseClient__ActivatePlayerHook, reinterpret_cast<LPVOID*>(&CBaseClient__ActivatePlayer));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x1012C0, &CBaseClient__DisconnectHook, reinterpret_cast<LPVOID*>(&CBaseClient__Disconnect));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x1022E0, &CGameClient__ExecuteStringCommandHook,
+ reinterpret_cast<LPVOID*>(&CGameClient__ExecuteStringCommand));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x2140A0, &CNetChan___ProcessMessagesHook, reinterpret_cast<LPVOID*>(&CNetChan___ProcessMessages));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x104FB0, &CBaseClient__SendServerInfoHook, reinterpret_cast<LPVOID*>(&CBaseClient__SendServerInfo));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x117800, &ProcessConnectionlessPacketHook, reinterpret_cast<LPVOID*>(&ProcessConnectionlessPacket));
CCommand__Tokenize = (CCommand__TokenizeType)((char*)baseAddress + 0x418380);
@@ -597,5 +645,7 @@ void InitialiseServerAuthentication(HMODULE baseAddress)
void InitialiseServerAuthenticationServerDLL(HMODULE baseAddress)
{
HookEnabler hook;
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1595C0, &CServerGameDLL__OnRecievedSayTextMessageHook, reinterpret_cast<LPVOID*>(&CServerGameDLL__OnRecievedSayTextMessage));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x1595C0, &CServerGameDLL__OnRecievedSayTextMessageHook,
+ reinterpret_cast<LPVOID*>(&CServerGameDLL__OnRecievedSayTextMessage));
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/serverauthentication.h b/NorthstarDedicatedTest/serverauthentication.h
index 55025d6e..faa7ae96 100644
--- a/NorthstarDedicatedTest/serverauthentication.h
+++ b/NorthstarDedicatedTest/serverauthentication.h
@@ -40,31 +40,31 @@ typedef enum
#pragma pack(push, 1)
typedef struct netadr_s
{
- netadrtype_t type;
- unsigned char ip[16]; // IPv6
+ netadrtype_t type;
+ unsigned char ip[16]; // IPv6
// IPv4's 127.0.0.1 is [::ffff:127.0.0.1], that is:
// 00 00 00 00 00 00 00 00 00 00 FF FF 7F 00 00 01
- unsigned short port;
+ unsigned short port;
} netadr_t;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct netpacket_s
{
- netadr_t adr; // sender address
- //int source; // received source
- char unk[10];
- double received_time;
- unsigned char* data; // pointer to raw packet data
- void* message; // easy bitbuf data access // 'inpacket.message' etc etc (pointer)
- char unk2[16];
- int size;
-
- //bf_read message; // easy bitbuf data access // 'inpacket.message' etc etc (pointer)
- //int size; // size in bytes
- //int wiresize; // size in bytes before decompression
- //bool stream; // was send as stream
- //struct netpacket_s* pNext; // for internal use, should be NULL in public
+ netadr_t adr; // sender address
+ // int source; // received source
+ char unk[10];
+ double received_time;
+ unsigned char* data; // pointer to raw packet data
+ void* message; // easy bitbuf data access // 'inpacket.message' etc etc (pointer)
+ char unk2[16];
+ int size;
+
+ // bf_read message; // easy bitbuf data access // 'inpacket.message' etc etc (pointer)
+ // int size; // size in bytes
+ // int wiresize; // size in bytes before decompression
+ // bool stream; // was send as stream
+ // struct netpacket_s* pNext; // for internal use, should be NULL in public
} netpacket_t;
#pragma pack(pop)
@@ -78,10 +78,10 @@ struct UnconnectedPlayerSendData
class ServerAuthenticationManager
{
-private:
+ private:
httplib::Server m_playerAuthServer;
-public:
+ public:
std::mutex m_authDataMutex;
std::unordered_map<std::string, AuthData> m_authData;
std::unordered_map<void*, AdditionalPlayerData> m_additionalPlayerData;
@@ -90,7 +90,7 @@ public:
bool m_bNeedLocalAuthForNewgame = false;
bool m_bForceReadLocalPlayerPersistenceFromDisk = false;
-public:
+ public:
void StartPlayerAuthServer();
void StopPlayerAuthServer();
bool AuthenticatePlayer(void* player, int64_t uid, char* authToken);
@@ -98,7 +98,7 @@ public:
void WritePersistentData(void* player);
};
-typedef void(*CBaseClient__DisconnectType)(void* self, uint32_t unknownButAlways1, const char* reason, ...);
+typedef void (*CBaseClient__DisconnectType)(void* self, uint32_t unknownButAlways1, const char* reason, ...);
extern CBaseClient__DisconnectType CBaseClient__Disconnect;
void InitialiseServerAuthentication(HMODULE baseAddress);
diff --git a/NorthstarDedicatedTest/sourceconsole.cpp b/NorthstarDedicatedTest/sourceconsole.cpp
index 98901737..e6f46c13 100644
--- a/NorthstarDedicatedTest/sourceconsole.cpp
+++ b/NorthstarDedicatedTest/sourceconsole.cpp
@@ -15,7 +15,7 @@ void ConCommand_toggleconsole(const CCommand& arg)
(*g_SourceGameConsole)->Activate();
}
-typedef void(*OnCommandSubmittedType)(CConsoleDialog* consoleDialog, const char* pCommand);
+typedef void (*OnCommandSubmittedType)(CConsoleDialog* consoleDialog, const char* pCommand);
OnCommandSubmittedType onCommandSubmittedOriginal;
void OnCommandSubmittedHook(CConsoleDialog* consoleDialog, const char* pCommand)
{
@@ -40,7 +40,9 @@ void InitialiseConsoleOnInterfaceCreation()
// hook OnCommandSubmitted so we print inputted commands
HookEnabler hook;
- ENABLER_CREATEHOOK(hook, (void*)((*g_SourceGameConsole)->m_pConsole->m_vtable->OnCommandSubmitted), &OnCommandSubmittedHook, reinterpret_cast<LPVOID*>(&onCommandSubmittedOriginal));
+ ENABLER_CREATEHOOK(
+ hook, (void*)((*g_SourceGameConsole)->m_pConsole->m_vtable->OnCommandSubmitted), &OnCommandSubmittedHook,
+ reinterpret_cast<LPVOID*>(&onCommandSubmittedOriginal));
}
void InitialiseSourceConsole(HMODULE baseAddress)
@@ -52,7 +54,6 @@ void InitialiseSourceConsole(HMODULE baseAddress)
RegisterConCommand("toggleconsole", ConCommand_toggleconsole, "toggles the console", FCVAR_NONE);
}
-
// logging stuff
SourceConsoleSink::SourceConsoleSink()
@@ -73,7 +74,8 @@ void SourceConsoleSink::sink_it_(const spdlog::details::log_msg& msg)
spdlog::memory_buf_t formatted;
spdlog::sinks::base_sink<std::mutex>::formatter_->format(msg, formatted);
- (*g_SourceGameConsole)->m_pConsole->m_pConsolePanel->ColorPrint(logColours[msg.level], fmt::to_string(formatted).c_str()); // todo needs colour support
+ (*g_SourceGameConsole)
+ ->m_pConsole->m_pConsolePanel->ColorPrint(logColours[msg.level], fmt::to_string(formatted).c_str()); // todo needs colour support
}
void SourceConsoleSink::flush_() {} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/sourceconsole.h b/NorthstarDedicatedTest/sourceconsole.h
index 79ab2267..cf65cbd3 100644
--- a/NorthstarDedicatedTest/sourceconsole.h
+++ b/NorthstarDedicatedTest/sourceconsole.h
@@ -6,85 +6,84 @@
class EditablePanel
{
-public:
- virtual ~EditablePanel() = 0;
- unsigned char unknown[0x2B0];
+ public:
+ virtual ~EditablePanel() = 0;
+ unsigned char unknown[0x2B0];
};
struct SourceColor
{
- unsigned char R;
- unsigned char G;
- unsigned char B;
- unsigned char A;
-
- SourceColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
- {
- R = r;
- G = g;
- B = b;
- A = a;
- }
-
- SourceColor()
- {
- R = 0;
- G = 0;
- B = 0;
- A = 0;
- }
+ unsigned char R;
+ unsigned char G;
+ unsigned char B;
+ unsigned char A;
+
+ SourceColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
+ {
+ R = r;
+ G = g;
+ B = b;
+ A = a;
+ }
+
+ SourceColor()
+ {
+ R = 0;
+ G = 0;
+ B = 0;
+ A = 0;
+ }
};
class IConsoleDisplayFunc
{
-public:
- virtual void ColorPrint(const SourceColor& clr, const char* pMessage) = 0;
- virtual void Print(const char* pMessage) = 0;
- virtual void DPrint(const char* pMessage) = 0;
+ public:
+ virtual void ColorPrint(const SourceColor& clr, const char* pMessage) = 0;
+ virtual void Print(const char* pMessage) = 0;
+ virtual void DPrint(const char* pMessage) = 0;
};
class CConsolePanel : public EditablePanel, public IConsoleDisplayFunc
{
-
};
class CConsoleDialog
{
-public:
- struct VTable
- {
- void* unknown[298];
- void(*OnCommandSubmitted)(CConsoleDialog* consoleDialog, const char* pCommand);
- };
-
- VTable* m_vtable;
- unsigned char unknown[0x398];
- CConsolePanel* m_pConsolePanel;
+ public:
+ struct VTable
+ {
+ void* unknown[298];
+ void (*OnCommandSubmitted)(CConsoleDialog* consoleDialog, const char* pCommand);
+ };
+
+ VTable* m_vtable;
+ unsigned char unknown[0x398];
+ CConsolePanel* m_pConsolePanel;
};
class CGameConsole
{
-public:
- virtual ~CGameConsole() = 0;
+ public:
+ virtual ~CGameConsole() = 0;
- // activates the console, makes it visible and brings it to the foreground
- virtual void Activate() = 0;
+ // activates the console, makes it visible and brings it to the foreground
+ virtual void Activate() = 0;
- virtual void Initialize() = 0;
+ virtual void Initialize() = 0;
- // hides the console
- virtual void Hide() = 0;
+ // hides the console
+ virtual void Hide() = 0;
- // clears the console
- virtual void Clear() = 0;
+ // clears the console
+ virtual void Clear() = 0;
- // return true if the console has focus
- virtual bool IsConsoleVisible() = 0;
+ // return true if the console has focus
+ virtual bool IsConsoleVisible() = 0;
- virtual void SetParent(int parent) = 0;
+ virtual void SetParent(int parent) = 0;
- bool m_bInitialized;
- CConsoleDialog* m_pConsole;
+ bool m_bInitialized;
+ CConsoleDialog* m_pConsole;
};
extern SourceInterface<CGameConsole>* g_SourceGameConsole;
@@ -92,15 +91,15 @@ extern SourceInterface<CGameConsole>* g_SourceGameConsole;
// spdlog logger
class SourceConsoleSink : public spdlog::sinks::base_sink<std::mutex>
{
-private:
- std::map<spdlog::level::level_enum, SourceColor> logColours;
+ private:
+ std::map<spdlog::level::level_enum, SourceColor> logColours;
-public:
- SourceConsoleSink();
+ public:
+ SourceConsoleSink();
-protected:
- void sink_it_(const spdlog::details::log_msg& msg) override;
- void flush_() override;
+ protected:
+ void sink_it_(const spdlog::details::log_msg& msg) override;
+ void flush_() override;
};
void InitialiseSourceConsole(HMODULE baseAddress);
diff --git a/NorthstarDedicatedTest/sourceinterface.cpp b/NorthstarDedicatedTest/sourceinterface.cpp
index bdcc4a3c..427bee63 100644
--- a/NorthstarDedicatedTest/sourceinterface.cpp
+++ b/NorthstarDedicatedTest/sourceinterface.cpp
@@ -45,19 +45,25 @@ void* EngineCreateInterfaceHook(const char* pName, int* pReturnCode)
void HookClientCreateInterface(HMODULE baseAddress)
{
HookEnabler hook;
- ENABLER_CREATEHOOK(hook, GetProcAddress(baseAddress, "CreateInterface"), &ClientCreateInterfaceHook, reinterpret_cast<LPVOID*>(&clientCreateInterfaceOriginal));
+ ENABLER_CREATEHOOK(
+ hook, GetProcAddress(baseAddress, "CreateInterface"), &ClientCreateInterfaceHook,
+ reinterpret_cast<LPVOID*>(&clientCreateInterfaceOriginal));
}
void HookServerCreateInterface(HMODULE baseAddress)
{
HookEnabler hook;
- ENABLER_CREATEHOOK(hook, GetProcAddress(baseAddress, "CreateInterface"), &ServerCreateInterfaceHook, reinterpret_cast<LPVOID*>(&serverCreateInterfaceOriginal));
+ ENABLER_CREATEHOOK(
+ hook, GetProcAddress(baseAddress, "CreateInterface"), &ServerCreateInterfaceHook,
+ reinterpret_cast<LPVOID*>(&serverCreateInterfaceOriginal));
}
void HookEngineCreateInterface(HMODULE baseAddress)
{
HookEnabler hook;
- ENABLER_CREATEHOOK(hook, GetProcAddress(baseAddress, "CreateInterface"), &EngineCreateInterfaceHook, reinterpret_cast<LPVOID*>(&engineCreateInterfaceOriginal));
+ ENABLER_CREATEHOOK(
+ hook, GetProcAddress(baseAddress, "CreateInterface"), &EngineCreateInterfaceHook,
+ reinterpret_cast<LPVOID*>(&engineCreateInterfaceOriginal));
}
void InitialiseInterfaceCreationHooks()
@@ -65,6 +71,6 @@ void InitialiseInterfaceCreationHooks()
AddDllLoadCallback("client.dll", HookClientCreateInterface);
// not used atm
- //AddDllLoadCallback("server.dll", HookServerCreateInterface);
- //AddDllLoadCallback("engine.dll", HookEngineCreateInterface);
+ // AddDllLoadCallback("server.dll", HookServerCreateInterface);
+ // AddDllLoadCallback("engine.dll", HookEngineCreateInterface);
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/sourceinterface.h b/NorthstarDedicatedTest/sourceinterface.h
index 11d73e76..a00f165e 100644
--- a/NorthstarDedicatedTest/sourceinterface.h
+++ b/NorthstarDedicatedTest/sourceinterface.h
@@ -2,32 +2,26 @@
#include <string>
// literally just copied from ttf2sdk definition
-typedef void*(*CreateInterfaceFn)(const char* pName, int* pReturnCode);
+typedef void* (*CreateInterfaceFn)(const char* pName, int* pReturnCode);
-template<typename T> class SourceInterface
+template <typename T> class SourceInterface
{
-private:
- T* m_interface;
+ private:
+ T* m_interface;
-public:
- SourceInterface(const std::string& moduleName, const std::string& interfaceName)
- {
- HMODULE handle = GetModuleHandleA(moduleName.c_str());
- CreateInterfaceFn createInterface = (CreateInterfaceFn)GetProcAddress(handle, "CreateInterface");
- m_interface = (T*)createInterface(interfaceName.c_str(), NULL);
- if (m_interface == nullptr)
- spdlog::error("Failed to call CreateInterface for %s in %s", interfaceName, moduleName);
- }
+ public:
+ SourceInterface(const std::string& moduleName, const std::string& interfaceName)
+ {
+ HMODULE handle = GetModuleHandleA(moduleName.c_str());
+ CreateInterfaceFn createInterface = (CreateInterfaceFn)GetProcAddress(handle, "CreateInterface");
+ m_interface = (T*)createInterface(interfaceName.c_str(), NULL);
+ if (m_interface == nullptr)
+ spdlog::error("Failed to call CreateInterface for %s in %s", interfaceName, moduleName);
+ }
- T* operator->() const
- {
- return m_interface;
- }
+ T* operator->() const { return m_interface; }
- operator T* () const
- {
- return m_interface;
- }
+ operator T*() const { return m_interface; }
};
// functions for interface creation callbacks
diff --git a/NorthstarDedicatedTest/squirrel.cpp b/NorthstarDedicatedTest/squirrel.cpp
index 1ea73fef..20f99967 100644
--- a/NorthstarDedicatedTest/squirrel.cpp
+++ b/NorthstarDedicatedTest/squirrel.cpp
@@ -9,31 +9,31 @@
#include <iostream>
// hook forward declarations
-typedef SQInteger(*SQPrintType)(void* sqvm, char* fmt, ...);
+typedef SQInteger (*SQPrintType)(void* sqvm, char* fmt, ...);
SQPrintType ClientSQPrint;
SQPrintType UISQPrint;
SQPrintType ServerSQPrint;
-template<ScriptContext context> SQInteger SQPrintHook(void* sqvm, char* fmt, ...);
+template <ScriptContext context> SQInteger SQPrintHook(void* sqvm, char* fmt, ...);
-typedef void*(*CreateNewVMType)(void* a1, ScriptContext contextArg);
+typedef void* (*CreateNewVMType)(void* a1, ScriptContext contextArg);
CreateNewVMType ClientCreateNewVM; // only need a client one since ui doesn't have its own func for this
CreateNewVMType ServerCreateNewVM;
-template<ScriptContext context> void* CreateNewVMHook(void* a1, ScriptContext contextArg);
+template <ScriptContext context> void* CreateNewVMHook(void* a1, ScriptContext contextArg);
-typedef void(*DestroyVMType)(void* a1, void* sqvm);
+typedef void (*DestroyVMType)(void* a1, void* sqvm);
DestroyVMType ClientDestroyVM; // only need a client one since ui doesn't have its own func for this
DestroyVMType ServerDestroyVM;
-template<ScriptContext context> void DestroyVMHook(void* a1, void* sqvm);
+template <ScriptContext context> void DestroyVMHook(void* a1, void* sqvm);
-typedef void(*ScriptCompileError)(void* sqvm, const char* error, const char* file, int line, int column);
+typedef void (*ScriptCompileError)(void* sqvm, const char* error, const char* file, int line, int column);
ScriptCompileError ClientSQCompileError; // only need a client one since ui doesn't have its own func for this
ScriptCompileError ServerSQCompileError;
-template<ScriptContext context> void ScriptCompileErrorHook(void* sqvm, const char* error, const char* file, int line, int column);
+template <ScriptContext context> void ScriptCompileErrorHook(void* sqvm, const char* error, const char* file, int line, int column);
-typedef char(*CallScriptInitCallbackType)(void* sqvm, const char* callback);
+typedef char (*CallScriptInitCallbackType)(void* sqvm, const char* callback);
CallScriptInitCallbackType ClientCallScriptInitCallback;
CallScriptInitCallbackType ServerCallScriptInitCallback;
-template<ScriptContext context> char CallScriptInitCallbackHook(void* sqvm, const char* callback);
+template <ScriptContext context> char CallScriptInitCallbackHook(void* sqvm, const char* callback);
// core sqvm funcs
sq_compilebufferType ClientSq_compilebuffer;
@@ -48,7 +48,6 @@ sq_callType ServerSq_call;
RegisterSquirrelFuncType ClientRegisterSquirrelFunc;
RegisterSquirrelFuncType ServerRegisterSquirrelFunc;
-
// sq stack array funcs
sq_newarrayType ClientSq_newarray;
sq_newarrayType ServerSq_newarray;
@@ -56,7 +55,6 @@ sq_newarrayType ServerSq_newarray;
sq_arrayappendType ClientSq_arrayappend;
sq_arrayappendType ServerSq_arrayappend;
-
// sq stack push funcs
sq_pushstringType ClientSq_pushstring;
sq_pushstringType ServerSq_pushstring;
@@ -73,7 +71,6 @@ sq_pushboolType ServerSq_pushbool;
sq_pusherrorType ClientSq_pusherror;
sq_pusherrorType ServerSq_pusherror;
-
// sq stack get funcs
sq_getstringType ClientSq_getstring;
sq_getstringType ServerSq_getstring;
@@ -87,18 +84,14 @@ sq_getfloatType ServerSq_getfloat;
sq_getboolType ClientSq_getbool;
sq_getboolType ServerSq_getbool;
-
-template<ScriptContext context> void ExecuteCodeCommand(const CCommand& args);
+template <ScriptContext context> void ExecuteCodeCommand(const CCommand& args);
// inits
SquirrelManager<ScriptContext::CLIENT>* g_ClientSquirrelManager;
SquirrelManager<ScriptContext::SERVER>* g_ServerSquirrelManager;
SquirrelManager<ScriptContext::UI>* g_UISquirrelManager;
-SQInteger NSTestFunc(void* sqvm)
-{
- return 1;
-}
+SQInteger NSTestFunc(void* sqvm) { return 1; }
void InitialiseClientSquirrel(HMODULE baseAddress)
{
@@ -110,13 +103,17 @@ void InitialiseClientSquirrel(HMODULE baseAddress)
// client inits
g_ClientSquirrelManager = new SquirrelManager<ScriptContext::CLIENT>();
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x12B00, &SQPrintHook<ScriptContext::CLIENT>, reinterpret_cast<LPVOID*>(&ClientSQPrint)); // client print function
- RegisterConCommand("script_client", ExecuteCodeCommand<ScriptContext::CLIENT>, "Executes script code on the client vm", FCVAR_CLIENTDLL);
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x12B00, &SQPrintHook<ScriptContext::CLIENT>,
+ reinterpret_cast<LPVOID*>(&ClientSQPrint)); // client print function
+ RegisterConCommand(
+ "script_client", ExecuteCodeCommand<ScriptContext::CLIENT>, "Executes script code on the client vm", FCVAR_CLIENTDLL);
// ui inits
g_UISquirrelManager = new SquirrelManager<ScriptContext::UI>();
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x12BA0, &SQPrintHook<ScriptContext::UI>, reinterpret_cast<LPVOID*>(&UISQPrint)); // ui print function
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x12BA0, &SQPrintHook<ScriptContext::UI>, reinterpret_cast<LPVOID*>(&UISQPrint)); // ui print function
RegisterConCommand("script_ui", ExecuteCodeCommand<ScriptContext::UI>, "Executes script code on the ui vm", FCVAR_CLIENTDLL);
// inits for both client and ui, since they share some functions
@@ -139,10 +136,18 @@ void InitialiseClientSquirrel(HMODULE baseAddress)
ClientSq_getfloat = (sq_getfloatType)((char*)baseAddress + 0x6100);
ClientSq_getbool = (sq_getboolType)((char*)baseAddress + 0x6130);
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x26130, &CreateNewVMHook<ScriptContext::CLIENT>, reinterpret_cast<LPVOID*>(&ClientCreateNewVM)); // client createnewvm function
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x26E70, &DestroyVMHook<ScriptContext::CLIENT>, reinterpret_cast<LPVOID*>(&ClientDestroyVM)); // client destroyvm function
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x79A50, &ScriptCompileErrorHook<ScriptContext::CLIENT>, reinterpret_cast<LPVOID*>(&ClientSQCompileError)); // client compileerror function
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x10190, &CallScriptInitCallbackHook<ScriptContext::CLIENT>, reinterpret_cast<LPVOID*>(&ClientCallScriptInitCallback)); // client callscriptinitcallback function
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x26130, &CreateNewVMHook<ScriptContext::CLIENT>,
+ reinterpret_cast<LPVOID*>(&ClientCreateNewVM)); // client createnewvm function
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x26E70, &DestroyVMHook<ScriptContext::CLIENT>,
+ reinterpret_cast<LPVOID*>(&ClientDestroyVM)); // client destroyvm function
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x79A50, &ScriptCompileErrorHook<ScriptContext::CLIENT>,
+ reinterpret_cast<LPVOID*>(&ClientSQCompileError)); // client compileerror function
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x10190, &CallScriptInitCallbackHook<ScriptContext::CLIENT>,
+ reinterpret_cast<LPVOID*>(&ClientCallScriptInitCallback)); // client callscriptinitcallback function
}
void InitialiseServerSquirrel(HMODULE baseAddress)
@@ -158,7 +163,7 @@ void InitialiseServerSquirrel(HMODULE baseAddress)
ServerSq_newarray = (sq_newarrayType)((char*)baseAddress + 0x39F0);
ServerSq_arrayappend = (sq_arrayappendType)((char*)baseAddress + 0x3C70);
-
+
ServerSq_pushstring = (sq_pushstringType)((char*)baseAddress + 0x3440);
ServerSq_pushinteger = (sq_pushintegerType)((char*)baseAddress + 0x36A0);
ServerSq_pushfloat = (sq_pushfloatType)((char*)baseAddress + 0x3800);
@@ -170,19 +175,31 @@ void InitialiseServerSquirrel(HMODULE baseAddress)
ServerSq_getfloat = (sq_getfloatType)((char*)baseAddress + 0x60E0);
ServerSq_getbool = (sq_getboolType)((char*)baseAddress + 0x6110);
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1FE90, &SQPrintHook<ScriptContext::SERVER>, reinterpret_cast<LPVOID*>(&ServerSQPrint)); // server print function
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x260E0, &CreateNewVMHook<ScriptContext::SERVER>, reinterpret_cast<LPVOID*>(&ServerCreateNewVM)); // server createnewvm function
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x26E20, &DestroyVMHook<ScriptContext::SERVER>, reinterpret_cast<LPVOID*>(&ServerDestroyVM)); // server destroyvm function
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x799E0, &ScriptCompileErrorHook<ScriptContext::SERVER>, reinterpret_cast<LPVOID*>(&ServerSQCompileError)); // server compileerror function
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1D5C0, &CallScriptInitCallbackHook<ScriptContext::SERVER>, reinterpret_cast<LPVOID*>(&ServerCallScriptInitCallback)); // server callscriptinitcallback function
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x1FE90, &SQPrintHook<ScriptContext::SERVER>,
+ reinterpret_cast<LPVOID*>(&ServerSQPrint)); // server print function
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x260E0, &CreateNewVMHook<ScriptContext::SERVER>,
+ reinterpret_cast<LPVOID*>(&ServerCreateNewVM)); // server createnewvm function
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x26E20, &DestroyVMHook<ScriptContext::SERVER>,
+ reinterpret_cast<LPVOID*>(&ServerDestroyVM)); // server destroyvm function
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x799E0, &ScriptCompileErrorHook<ScriptContext::SERVER>,
+ reinterpret_cast<LPVOID*>(&ServerSQCompileError)); // server compileerror function
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x1D5C0, &CallScriptInitCallbackHook<ScriptContext::SERVER>,
+ reinterpret_cast<LPVOID*>(&ServerCallScriptInitCallback)); // server callscriptinitcallback function
// cheat and clientcmd_can_execute allows clients to execute this, but since it's unsafe we only allow it when cheats are enabled
- // for script_client and script_ui, we don't use cheats, so clients can execute them on themselves all they want
- RegisterConCommand("script", ExecuteCodeCommand<ScriptContext::SERVER>, "Executes script code on the server vm", FCVAR_GAMEDLL | FCVAR_CLIENTCMD_CAN_EXECUTE | FCVAR_CHEAT);
+ // for script_client and script_ui, we don't use cheats, so clients can execute them on themselves all they want
+ RegisterConCommand(
+ "script", ExecuteCodeCommand<ScriptContext::SERVER>, "Executes script code on the server vm",
+ FCVAR_GAMEDLL | FCVAR_CLIENTCMD_CAN_EXECUTE | FCVAR_CHEAT);
}
// hooks
-template<ScriptContext context> SQInteger SQPrintHook(void* sqvm, char* fmt, ...)
+template <ScriptContext context> SQInteger SQPrintHook(void* sqvm, char* fmt, ...)
{
va_list va;
va_start(va, fmt);
@@ -202,8 +219,8 @@ template<ScriptContext context> SQInteger SQPrintHook(void* sqvm, char* fmt, ...
return 0;
}
-template<ScriptContext context> void* CreateNewVMHook(void* a1, ScriptContext realContext)
-{
+template <ScriptContext context> void* CreateNewVMHook(void* a1, ScriptContext realContext)
+{
void* sqvm;
if (context == ScriptContext::CLIENT)
@@ -225,7 +242,7 @@ template<ScriptContext context> void* CreateNewVMHook(void* a1, ScriptContext re
return sqvm;
}
-template<ScriptContext context> void DestroyVMHook(void* a1, void* sqvm)
+template <ScriptContext context> void DestroyVMHook(void* a1, void* sqvm)
{
ScriptContext realContext = context; // ui and client use the same function so we use this for prints
@@ -250,7 +267,7 @@ template<ScriptContext context> void DestroyVMHook(void* a1, void* sqvm)
spdlog::info("DestroyVM {} {}", GetContextName(realContext), sqvm);
}
-template<ScriptContext context> void ScriptCompileErrorHook(void* sqvm, const char* error, const char* file, int line, int column)
+template <ScriptContext context> void ScriptCompileErrorHook(void* sqvm, const char* error, const char* file, int line, int column)
{
ScriptContext realContext = context; // ui and client use the same function so we use this for prints
if (context == ScriptContext::CLIENT && sqvm == g_UISquirrelManager->sqvm)
@@ -265,7 +282,7 @@ template<ScriptContext context> void ScriptCompileErrorHook(void* sqvm, const ch
// though, that also has potential to be REALLY bad if we're compiling ui scripts lol
}
-template<ScriptContext context> char CallScriptInitCallbackHook(void* sqvm, const char* callback)
+template <ScriptContext context> char CallScriptInitCallbackHook(void* sqvm, const char* callback)
{
char ret;
@@ -273,7 +290,7 @@ template<ScriptContext context> char CallScriptInitCallbackHook(void* sqvm, cons
{
ScriptContext realContext = context; // ui and client use the same function so we use this for prints
bool shouldCallCustomCallbacks = false;
-
+
// since we don't hook arbitrary callbacks yet, make sure we're only doing callbacks on inits
if (!strcmp(callback, "UICodeCallback_UIInit"))
{
@@ -298,7 +315,8 @@ template<ScriptContext context> char CallScriptInitCallbackHook(void* sqvm, cons
{
if (modCallback.Context == realContext && modCallback.BeforeCallback.length())
{
- spdlog::info("Running custom {} script callback \"{}\"", GetContextName(realContext), modCallback.BeforeCallback);
+ spdlog::info(
+ "Running custom {} script callback \"{}\"", GetContextName(realContext), modCallback.BeforeCallback);
ClientCallScriptInitCallback(sqvm, modCallback.BeforeCallback.c_str());
}
}
@@ -325,7 +343,8 @@ template<ScriptContext context> char CallScriptInitCallbackHook(void* sqvm, cons
{
if (modCallback.Context == realContext && modCallback.AfterCallback.length())
{
- spdlog::info("Running custom {} script callback \"{}\"", GetContextName(realContext), modCallback.AfterCallback);
+ spdlog::info(
+ "Running custom {} script callback \"{}\"", GetContextName(realContext), modCallback.AfterCallback);
ClientCallScriptInitCallback(sqvm, modCallback.AfterCallback.c_str());
}
}
@@ -378,7 +397,7 @@ template<ScriptContext context> char CallScriptInitCallbackHook(void* sqvm, cons
{
for (ModScriptCallback modCallback : script.Callbacks)
{
- if (modCallback.Context == ScriptContext::SERVER && modCallback.AfterCallback.length())
+ if (modCallback.Context == ScriptContext::SERVER && modCallback.AfterCallback.length())
{
spdlog::info("Running custom {} script callback \"{}\"", GetContextName(context), modCallback.AfterCallback);
ServerCallScriptInitCallback(sqvm, modCallback.AfterCallback.c_str());
@@ -392,7 +411,7 @@ template<ScriptContext context> char CallScriptInitCallbackHook(void* sqvm, cons
return ret;
}
-template<ScriptContext context> void ExecuteCodeCommand(const CCommand& args)
+template <ScriptContext context> void ExecuteCodeCommand(const CCommand& args)
{
if (context == ScriptContext::CLIENT)
g_ClientSquirrelManager->ExecuteCode(args.ArgS());
diff --git a/NorthstarDedicatedTest/squirrel.h b/NorthstarDedicatedTest/squirrel.h
index 742c392c..8e851266 100644
--- a/NorthstarDedicatedTest/squirrel.h
+++ b/NorthstarDedicatedTest/squirrel.h
@@ -16,7 +16,7 @@ const SQRESULT SQRESULT_ERROR = -1;
const SQRESULT SQRESULT_NULL = 0;
const SQRESULT SQRESULT_NOTNULL = 1;
-typedef SQInteger(*SQFunction)(void* sqvm);
+typedef SQInteger (*SQFunction)(void* sqvm);
struct CompileBufferState
{
@@ -60,84 +60,81 @@ struct SQFuncRegistration
};
// core sqvm funcs
-typedef SQRESULT(*sq_compilebufferType)(void* sqvm, CompileBufferState* compileBuffer, const char* file, int a1, ScriptContext a2);
+typedef SQRESULT (*sq_compilebufferType)(void* sqvm, CompileBufferState* compileBuffer, const char* file, int a1, ScriptContext a2);
extern sq_compilebufferType ClientSq_compilebuffer;
extern sq_compilebufferType ServerSq_compilebuffer;
-typedef void(*sq_pushroottableType)(void* sqvm);
+typedef void (*sq_pushroottableType)(void* sqvm);
extern sq_pushroottableType ClientSq_pushroottable;
extern sq_pushroottableType ServerSq_pushroottable;
-typedef SQRESULT(*sq_callType)(void* sqvm, SQInteger s1, SQBool a2, SQBool a3);
+typedef SQRESULT (*sq_callType)(void* sqvm, SQInteger s1, SQBool a2, SQBool a3);
extern sq_callType ClientSq_call;
extern sq_callType ServerSq_call;
-typedef int64_t(*RegisterSquirrelFuncType)(void* sqvm, SQFuncRegistration* funcReg, char unknown);
+typedef int64_t (*RegisterSquirrelFuncType)(void* sqvm, SQFuncRegistration* funcReg, char unknown);
extern RegisterSquirrelFuncType ClientRegisterSquirrelFunc;
extern RegisterSquirrelFuncType ServerRegisterSquirrelFunc;
// sq stack array funcs
-typedef void(*sq_newarrayType)(void* sqvm, SQInteger stackpos);
+typedef void (*sq_newarrayType)(void* sqvm, SQInteger stackpos);
extern sq_newarrayType ClientSq_newarray;
extern sq_newarrayType ServerSq_newarray;
-typedef SQRESULT(*sq_arrayappendType)(void* sqvm, SQInteger stackpos);
+typedef SQRESULT (*sq_arrayappendType)(void* sqvm, SQInteger stackpos);
extern sq_arrayappendType ClientSq_arrayappend;
extern sq_arrayappendType ServerSq_arrayappend;
-
// sq stack push funcs
-typedef void(*sq_pushstringType)(void* sqvm, const SQChar* str, SQInteger stackpos);
+typedef void (*sq_pushstringType)(void* sqvm, const SQChar* str, SQInteger stackpos);
extern sq_pushstringType ClientSq_pushstring;
extern sq_pushstringType ServerSq_pushstring;
// weird how these don't take a stackpos arg?
-typedef void(*sq_pushintegerType)(void* sqvm, SQInteger i);
+typedef void (*sq_pushintegerType)(void* sqvm, SQInteger i);
extern sq_pushintegerType ClientSq_pushinteger;
extern sq_pushintegerType ServerSq_pushinteger;
-typedef void(*sq_pushfloatType)(void* sqvm, SQFloat f);
+typedef void (*sq_pushfloatType)(void* sqvm, SQFloat f);
extern sq_pushfloatType ClientSq_pushfloat;
extern sq_pushfloatType ServerSq_pushfloat;
-typedef void(*sq_pushboolType)(void* sqvm, SQBool b);
+typedef void (*sq_pushboolType)(void* sqvm, SQBool b);
extern sq_pushboolType ClientSq_pushbool;
extern sq_pushboolType ServerSq_pushbool;
-typedef SQInteger(*sq_pusherrorType)(void* sqvm, const SQChar* error);
+typedef SQInteger (*sq_pusherrorType)(void* sqvm, const SQChar* error);
extern sq_pusherrorType ClientSq_pusherror;
extern sq_pusherrorType ServerSq_pusherror;
-
// sq stack get funcs
-typedef const SQChar*(*sq_getstringType)(void* sqvm, SQInteger stackpos);
+typedef const SQChar* (*sq_getstringType)(void* sqvm, SQInteger stackpos);
extern sq_getstringType ClientSq_getstring;
extern sq_getstringType ServerSq_getstring;
-typedef SQInteger(*sq_getintegerType)(void* sqvm, SQInteger stackpos);
+typedef SQInteger (*sq_getintegerType)(void* sqvm, SQInteger stackpos);
extern sq_getintegerType ClientSq_getinteger;
extern sq_getintegerType ServerSq_getinteger;
-typedef SQFloat(*sq_getfloatType)(void*, SQInteger stackpos);
+typedef SQFloat (*sq_getfloatType)(void*, SQInteger stackpos);
extern sq_getfloatType ClientSq_getfloat;
extern sq_getfloatType ServerSq_getfloat;
-typedef SQBool(*sq_getboolType)(void*, SQInteger stackpos);
+typedef SQBool (*sq_getboolType)(void*, SQInteger stackpos);
extern sq_getboolType ClientSq_getbool;
extern sq_getboolType ServerSq_getbool;
-template<ScriptContext context> class SquirrelManager
+template <ScriptContext context> class SquirrelManager
{
-private:
+ private:
std::vector<SQFuncRegistration*> m_funcRegistrations;
-public:
+ public:
void* sqvm;
void* sqvm2;
-public:
- SquirrelManager() : sqvm(nullptr)
- {}
+ public:
+ SquirrelManager() : sqvm(nullptr) {}
void VMCreated(void* newSqvm)
{
@@ -155,10 +152,7 @@ public:
}
}
- void VMDestroyed()
- {
- sqvm = nullptr;
- }
+ void VMDestroyed() { sqvm = nullptr; }
void ExecuteCode(const char* code)
{