aboutsummaryrefslogtreecommitdiff
path: root/NorthstarDLL/client
diff options
context:
space:
mode:
authorJack <66967891+ASpoonPlaysGames@users.noreply.github.com>2023-12-27 00:32:01 +0000
committerGitHub <noreply@github.com>2023-12-27 01:32:01 +0100
commitf5ab6fb5e8be7b73e6003d4145081d5e0c0ce287 (patch)
tree90f2c6a4885dbd181799e2325cf33588697674e1 /NorthstarDLL/client
parentbb8ed59f6891b1196c5f5bbe7346cd171c8215fa (diff)
downloadNorthstarLauncher-f5ab6fb5e8be7b73e6003d4145081d5e0c0ce287.tar.gz
NorthstarLauncher-f5ab6fb5e8be7b73e6003d4145081d5e0c0ce287.zip
Folder restructuring from primedev (#624)v1.21.2-rc3v1.21.2
Copies of over the primedev folder structure for easier cherry-picking of further changes Co-authored-by: F1F7Y <filip.bartos07@proton.me>
Diffstat (limited to 'NorthstarDLL/client')
-rw-r--r--NorthstarDLL/client/audio.cpp504
-rw-r--r--NorthstarDLL/client/audio.h46
-rw-r--r--NorthstarDLL/client/chatcommand.cpp36
-rw-r--r--NorthstarDLL/client/clientauthhooks.cpp72
-rw-r--r--NorthstarDLL/client/clientruihooks.cpp23
-rw-r--r--NorthstarDLL/client/clientvideooverrides.cpp41
-rw-r--r--NorthstarDLL/client/debugoverlay.cpp348
-rw-r--r--NorthstarDLL/client/demofixes.cpp25
-rw-r--r--NorthstarDLL/client/diskvmtfixes.cpp15
-rw-r--r--NorthstarDLL/client/languagehooks.cpp115
-rw-r--r--NorthstarDLL/client/latencyflex.cpp43
-rw-r--r--NorthstarDLL/client/localchatwriter.cpp449
-rw-r--r--NorthstarDLL/client/localchatwriter.h64
-rw-r--r--NorthstarDLL/client/modlocalisation.cpp55
-rw-r--r--NorthstarDLL/client/r2client.cpp13
-rw-r--r--NorthstarDLL/client/r2client.h7
-rw-r--r--NorthstarDLL/client/rejectconnectionfixes.cpp34
17 files changed, 0 insertions, 1890 deletions
diff --git a/NorthstarDLL/client/audio.cpp b/NorthstarDLL/client/audio.cpp
deleted file mode 100644
index aa32e390..00000000
--- a/NorthstarDLL/client/audio.cpp
+++ /dev/null
@@ -1,504 +0,0 @@
-#include "audio.h"
-#include "dedicated/dedicated.h"
-#include "core/convar/convar.h"
-
-#include "rapidjson/error/en.h"
-#include <fstream>
-#include <iostream>
-#include <sstream>
-#include <random>
-
-AUTOHOOK_INIT()
-
-static const char* pszAudioEventName;
-
-ConVar* Cvar_mileslog_enable;
-ConVar* Cvar_ns_print_played_sounds;
-
-CustomAudioManager g_CustomAudioManager;
-
-EventOverrideData::EventOverrideData()
-{
- spdlog::warn("Initialised struct EventOverrideData without any data!");
- LoadedSuccessfully = false;
-}
-
-// 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};
-
-EventOverrideData::EventOverrideData(const std::string& data, const fs::path& path)
-{
- if (data.length() <= 0)
- {
- spdlog::error("Failed reading audio override file {}: file is empty", path.string());
- return;
- }
-
- fs::path samplesFolder = path;
- samplesFolder = samplesFolder.replace_extension();
-
- 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());
- return;
- }
-
- rapidjson_document dataJson;
- dataJson.Parse<rapidjson::ParseFlag::kParseCommentsFlag | rapidjson::ParseFlag::kParseTrailingCommasFlag>(data);
-
- // 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());
- return;
- }
-
- // fail if it's not a json obj (could be an array, string, etc)
- if (!dataJson.IsObject())
- {
- spdlog::error("Failed reading audio override file {}: file is not a JSON object", path.string());
- return;
- }
-
- // fail if no event ids given
- if (!dataJson.HasMember("EventId"))
- {
- spdlog::error("Failed reading audio override file {}: JSON object does not have the EventId property", path.string());
- return;
- }
-
- // array of event ids
- if (dataJson["EventId"].IsArray())
- {
- for (auto& eventId : dataJson["EventId"].GetArray())
- {
- if (!eventId.IsString())
- {
- spdlog::error(
- "Failed reading audio override file {}: EventId array has a value of invalid type, all must be strings", path.string());
- return;
- }
-
- EventIds.push_back(eventId.GetString());
- }
- }
- // singular event id
- else if (dataJson["EventId"].IsString())
- {
- EventIds.push_back(dataJson["EventId"].GetString());
- }
- // 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());
- return;
- }
-
- if (dataJson.HasMember("EventIdRegex"))
- {
- // array of event id regex
- if (dataJson["EventIdRegex"].IsArray())
- {
- for (auto& eventId : dataJson["EventIdRegex"].GetArray())
- {
- if (!eventId.IsString())
- {
- 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 (...)
- {
- spdlog::error("Malformed regex \"{}\" in audio override file {}", regex, path.string());
- return;
- }
- }
- }
- // singular event id regex
- else if (dataJson["EventIdRegex"].IsString())
- {
- const std::string& regex = dataJson["EventIdRegex"].GetString();
- try
- {
- EventIdsRegex.push_back({regex, std::regex(regex)});
- }
- catch (...)
- {
- spdlog::error("Malformed regex \"{}\" in audio override file {}", regex, path.string());
- return;
- }
- }
- // 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());
- return;
- }
- }
-
- if (dataJson.HasMember("AudioSelectionStrategy"))
- {
- if (!dataJson["AudioSelectionStrategy"].IsString())
- {
- spdlog::error("Failed reading audio override file {}: AudioSelectionStrategy property must be a string", path.string());
- return;
- }
-
- std::string strategy = dataJson["AudioSelectionStrategy"].GetString();
-
- if (strategy == "sequential")
- {
- Strategy = AudioSelectionStrategy::SEQUENTIAL;
- }
- else if (strategy == "random")
- {
- Strategy = AudioSelectionStrategy::RANDOM;
- }
- else
- {
- spdlog::error(
- "Failed reading audio override file {}: AudioSelectionStrategy string must be either \"sequential\" or \"random\"",
- path.string());
- return;
- }
- }
-
- // load samples
- for (fs::directory_entry file : fs::recursive_directory_iterator(samplesFolder))
- {
- if (file.is_regular_file() && file.path().extension().string() == ".wav")
- {
- std::string pathString = file.path().string();
-
- // Open the file.
- std::ifstream wavStream(pathString, std::ios::binary);
-
- if (wavStream.fail())
- {
- spdlog::error("Failed reading audio sample {}", file.path().string());
- continue;
- }
-
- // Get file size.
- wavStream.seekg(0, std::ios::end);
- size_t fileSize = wavStream.tellg();
- wavStream.close();
-
- // Allocate enough memory for the file.
- // blank out the memory for now, then read it later
- uint8_t* data = new uint8_t[fileSize];
- memcpy(data, EMPTY_WAVE, sizeof(EMPTY_WAVE));
- Samples.push_back({fileSize, std::unique_ptr<uint8_t[]>(data)});
-
- // thread off the file read
- // should we spawn one thread per read? or should there be a cap to the number of reads at once?
- std::thread readThread(
- [pathString, fileSize, data]
- {
- std::shared_lock lock(g_CustomAudioManager.m_loadingMutex);
- std::ifstream wavStream(pathString, std::ios::binary);
-
- // would be weird if this got hit, since it would've worked previously
- if (wavStream.fail())
- {
- spdlog::error("Failed async read of audio sample {}", pathString);
- return;
- }
-
- // read from after the header first to preserve the empty header, then read the header last
- wavStream.seekg(0, std::ios::beg);
- wavStream.read(reinterpret_cast<char*>(data), fileSize);
- wavStream.close();
-
- spdlog::info("Finished async read of audio sample {}", pathString);
- });
-
- readThread.detach();
- }
- }
-
- /*
- if (dataJson.HasMember("EnableOnLoopedSounds"))
- {
- if (!dataJson["EnableOnLoopedSounds"].IsBool())
- {
- spdlog::error("Failed reading audio override file {}: EnableOnLoopedSounds property is of invalid type (must be a bool)",
- path.string()); return;
- }
-
- EnableOnLoopedSounds = dataJson["EnableOnLoopedSounds"].GetBool();
- }
- */
-
- if (Samples.size() == 0)
- spdlog::warn("Audio override {} has no valid samples! Sounds will not play for this event.", path.string());
-
- spdlog::info("Loaded audio override file {}", path.string());
-
- LoadedSuccessfully = true;
-}
-
-bool CustomAudioManager::TryLoadAudioOverride(const fs::path& defPath)
-{
- if (IsDedicatedServer())
- return true; // silently fail
-
- std::ifstream jsonStream(defPath);
- std::stringstream jsonStringStream;
-
- // fail if no audio json
- if (jsonStream.fail())
- {
- spdlog::warn("Unable to read audio override from file {}", defPath.string());
- return false;
- }
-
- while (jsonStream.peek() != EOF)
- jsonStringStream << (char)jsonStream.get();
-
- jsonStream.close();
-
- std::shared_ptr<EventOverrideData> data = std::make_shared<EventOverrideData>(jsonStringStream.str(), defPath);
-
- if (!data->LoadedSuccessfully)
- return false; // no logging, the constructor has probably already logged
-
- for (const std::string& eventId : data->EventIds)
- {
- spdlog::info("Registering sound event {}", eventId);
- 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});
- }
-
- return true;
-}
-
-typedef void (*MilesStopAll_Type)();
-MilesStopAll_Type MilesStopAll;
-
-void CustomAudioManager::ClearAudioOverrides()
-{
- if (IsDedicatedServer())
- return;
-
- if (m_loadedAudioOverrides.size() > 0 || m_loadedAudioOverridesRegex.size() > 0)
- {
- // stop all miles sounds beforehand
- // miles_stop_all
-
- MilesStopAll();
-
- // this is cancer but it works
- Sleep(50);
- }
-
- // slightly (very) bad
- // wait for all audio reads to complete so we don't kill preexisting audio buffers as we're writing to them
- std::unique_lock lock(m_loadingMutex);
-
- m_loadedAudioOverrides.clear();
- m_loadedAudioOverridesRegex.clear();
-}
-
-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)
-{
- static std::random_device rd;
- static std::mt19937 gen(rd());
- return select_randomly(start, end, gen);
-}
-
-bool ShouldPlayAudioEvent(const char* eventName, const std::shared_ptr<EventOverrideData>& data)
-{
- std::string eventNameString = eventName;
- std::string eventNameStringBlacklistEntry = ("!" + eventNameString);
-
- for (const std::string& name : data->EventIds)
- {
- if (name == eventNameStringBlacklistEntry)
- return false; // event blacklisted
-
- if (name == "*")
- {
- // check for bad sounds I guess?
- // really feel like this should be an option but whatever
- if (!!strstr(eventName, "_amb_") || !!strstr(eventName, "_emit_") || !!strstr(eventName, "amb_"))
- return false; // would play static noise, I hate this
- }
- }
-
- return true; // good to go
-}
-
-// clang-format off
-AUTOHOOK(LoadSampleMetadata, mileswin64.dll + 0xF110,
-bool, __fastcall, (void* sample, void* audioBuffer, unsigned int audioBufferLength, int audioType))
-// clang-format on
-{
- // Raw source, used for voice data only
- if (audioType == 0)
- return LoadSampleMetadata(sample, audioBuffer, audioBufferLength, audioType);
-
- const char* eventName = pszAudioEventName;
-
- if (Cvar_ns_print_played_sounds->GetInt() > 0)
- spdlog::info("[AUDIO] Playing event {}", eventName);
-
- auto iter = g_CustomAudioManager.m_loadedAudioOverrides.find(eventName);
- std::shared_ptr<EventOverrideData> overrideData;
-
- if (iter == g_CustomAudioManager.m_loadedAudioOverrides.end())
- {
- // override for that specific event not found, try wildcard
- iter = g_CustomAudioManager.m_loadedAudioOverrides.find("*");
-
- if (iter == g_CustomAudioManager.m_loadedAudioOverrides.end())
- {
- // not found
-
- // try regex
- for (const auto& item : g_CustomAudioManager.m_loadedAudioOverridesRegex)
- for (const auto& regexData : item.second->EventIdsRegex)
- if (std::regex_search(eventName, regexData.second))
- overrideData = item.second;
-
- if (!overrideData)
- // not found either
- return LoadSampleMetadata(sample, audioBuffer, audioBufferLength, audioType);
- else
- {
- // cache found pattern to improve performance
- g_CustomAudioManager.m_loadedAudioOverrides[eventName] = overrideData;
- }
- }
- else
- overrideData = iter->second;
- }
- else
- overrideData = iter->second;
-
- if (!ShouldPlayAudioEvent(eventName, overrideData))
- return LoadSampleMetadata(sample, audioBuffer, audioBufferLength, audioType);
-
- void* data = 0;
- unsigned int dataLength = 0;
-
- 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);
- }
- else
- {
- std::pair<size_t, std::unique_ptr<uint8_t[]>>* dat = NULL;
-
- switch (overrideData->Strategy)
- {
- case AudioSelectionStrategy::RANDOM:
- dat = &*select_randomly(overrideData->Samples.begin(), overrideData->Samples.end());
- break;
- case AudioSelectionStrategy::SEQUENTIAL:
- default:
- dat = &overrideData->Samples[overrideData->CurrentIndex++];
- if (overrideData->CurrentIndex >= overrideData->Samples.size())
- overrideData->CurrentIndex = 0; // reset back to the first sample entry
- break;
- }
-
- if (!dat)
- spdlog::warn("Could not get sample data from override struct for event {}! Shouldn't happen", eventName);
- else
- {
- data = dat->second.get();
- dataLength = dat->first;
- }
- }
-
- if (!data)
- {
- spdlog::warn("Could not fetch override sample data for event {}! Using original data instead.", eventName);
- return LoadSampleMetadata(sample, audioBuffer, audioBufferLength, audioType);
- }
-
- audioBuffer = data;
- audioBufferLength = dataLength;
-
- // most important change: set the sample class buffer so that the correct audio plays
- *(void**)((uintptr_t)sample + 0xE8) = audioBuffer;
- *(unsigned int*)((uintptr_t)sample + 0xF0) = audioBufferLength;
-
- // 64 - Auto-detect sample type
- bool res = LoadSampleMetadata(sample, audioBuffer, audioBufferLength, 64);
- if (!res)
- spdlog::error("LoadSampleMetadata failed! The game will crash :(");
-
- return res;
-}
-
-// clang-format off
-AUTOHOOK(sub_1800294C0, mileswin64.dll + 0x294C0,
-void*, __fastcall, (void* a1, void* a2))
-// clang-format on
-{
- pszAudioEventName = reinterpret_cast<const char*>((*((__int64*)a2 + 6)));
- return sub_1800294C0(a1, a2);
-}
-
-// clang-format off
-AUTOHOOK(MilesLog, client.dll + 0x57DAD0,
-void, __fastcall, (int level, const char* string))
-// clang-format on
-{
- if (!Cvar_mileslog_enable->GetBool())
- return;
-
- spdlog::info("[MSS] {} - {}", level, string);
-}
-
-ON_DLL_LOAD_RELIESON("engine.dll", MilesLogFuncHooks, ConVar, (CModule module))
-{
- Cvar_mileslog_enable = new ConVar("mileslog_enable", "0", FCVAR_NONE, "Enables/disables whether the mileslog func should be logged");
-}
-
-ON_DLL_LOAD_CLIENT_RELIESON("client.dll", AudioHooks, ConVar, (CModule module))
-{
- AUTOHOOK_DISPATCH()
-
- Cvar_ns_print_played_sounds = new ConVar("ns_print_played_sounds", "0", FCVAR_NONE, "");
- MilesStopAll = module.Offset(0x580850).RCast<MilesStopAll_Type>();
-}
diff --git a/NorthstarDLL/client/audio.h b/NorthstarDLL/client/audio.h
deleted file mode 100644
index 15fd1a35..00000000
--- a/NorthstarDLL/client/audio.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#pragma once
-
-#include <vector>
-#include <filesystem>
-#include <regex>
-#include <shared_mutex>
-
-enum class AudioSelectionStrategy
-{
- INVALID = -1,
- SEQUENTIAL,
- RANDOM
-};
-
-class EventOverrideData
-{
-public:
- EventOverrideData(const std::string&, const fs::path&);
- EventOverrideData();
-
-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;
-
- bool EnableOnLoopedSounds = false;
-};
-
-class CustomAudioManager
-{
-public:
- bool TryLoadAudioOverride(const fs::path&);
- void ClearAudioOverrides();
-
- std::shared_mutex m_loadingMutex;
- std::unordered_map<std::string, std::shared_ptr<EventOverrideData>> m_loadedAudioOverrides = {};
- std::unordered_map<std::string, std::shared_ptr<EventOverrideData>> m_loadedAudioOverridesRegex = {};
-};
-
-extern CustomAudioManager g_CustomAudioManager;
diff --git a/NorthstarDLL/client/chatcommand.cpp b/NorthstarDLL/client/chatcommand.cpp
deleted file mode 100644
index 9cf34e43..00000000
--- a/NorthstarDLL/client/chatcommand.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "core/convar/convar.h"
-#include "core/convar/concommand.h"
-#include "localchatwriter.h"
-
-// 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
-void(__fastcall* ClientSayText)(void* a1, const char* message, uint64_t isIngameChat, bool isTeamChat);
-
-void ConCommand_say(const CCommand& args)
-{
- if (args.ArgC() >= 2)
- ClientSayText(nullptr, args.ArgS(), true, false);
-}
-
-void ConCommand_say_team(const CCommand& args)
-{
- if (args.ArgC() >= 2)
- ClientSayText(nullptr, args.ArgS(), true, true);
-}
-
-void ConCommand_log(const CCommand& args)
-{
- if (args.ArgC() >= 2)
- {
- LocalChatWriter(LocalChatWriter::GameContext).WriteLine(args.ArgS());
- }
-}
-
-ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", ClientChatCommand, ConCommand, (CModule module))
-{
- ClientSayText =
- module.Offset(0x54780).RCast<void(__fastcall*)(void* a1, const char* message, uint64_t isIngameChat, bool isTeamChat)>();
- RegisterConCommand("say", ConCommand_say, "Enters a message in public chat", FCVAR_CLIENTDLL);
- RegisterConCommand("say_team", ConCommand_say_team, "Enters a message in team chat", FCVAR_CLIENTDLL);
- RegisterConCommand("log", ConCommand_log, "Log a message to the local chat window", FCVAR_CLIENTDLL);
-}
diff --git a/NorthstarDLL/client/clientauthhooks.cpp b/NorthstarDLL/client/clientauthhooks.cpp
deleted file mode 100644
index 35ae3aa7..00000000
--- a/NorthstarDLL/client/clientauthhooks.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-#include "masterserver/masterserver.h"
-#include "core/convar/convar.h"
-#include "client/r2client.h"
-#include "core/vanilla.h"
-
-AUTOHOOK_INIT()
-
-ConVar* Cvar_ns_has_agreed_to_send_token;
-
-// mirrored in script
-const int NOT_DECIDED_TO_SEND_TOKEN = 0;
-const int AGREED_TO_SEND_TOKEN = 1;
-const int DISAGREED_TO_SEND_TOKEN = 2;
-
-// clang-format off
-AUTOHOOK(AuthWithStryder, engine.dll + 0x1843A0,
-void, __fastcall, (void* a1))
-// clang-format on
-{
- // don't attempt to do Atlas auth if we are in vanilla compatibility mode
- // this prevents users from joining untrustworthy servers (unless they use a concommand or something)
- if (g_pVanillaCompatibility->GetVanillaCompatibility())
- {
- AuthWithStryder(a1);
- return;
- }
-
- // game will call this forever, until it gets a valid auth key
- // so, we need to manually invalidate our key until we're authed with northstar, then we'll allow game to auth with stryder
- if (!g_pMasterServerManager->m_bOriginAuthWithMasterServerDone && Cvar_ns_has_agreed_to_send_token->GetInt() != 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->GetInt() == AGREED_TO_SEND_TOKEN &&
- !g_pMasterServerManager->m_bOriginAuthWithMasterServerInProgress)
- g_pMasterServerManager->AuthenticateOriginWithMasterServer(g_pLocalPlayerUserID, g_pLocalPlayerOriginToken);
-
- // invalidate key so auth will fail
- *g_pLocalPlayerOriginToken = 0;
- }
-
- AuthWithStryder(a1);
-}
-
-char* p3PToken;
-
-// clang-format off
-AUTOHOOK(Auth3PToken, engine.dll + 0x183760,
-char*, __fastcall, ())
-// clang-format on
-{
- if (!g_pVanillaCompatibility->GetVanillaCompatibility() && g_pMasterServerManager->m_sOwnClientAuthToken[0])
- {
- memset(p3PToken, 0x0, 1024);
- strcpy(p3PToken, "Protocol 3: Protect the Pilot");
- }
-
- return Auth3PToken();
-}
-
-ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", ClientAuthHooks, ConVar, (CModule module))
-{
- AUTOHOOK_DISPATCH()
-
- p3PToken = module.Offset(0x13979D80).RCast<char*>();
-
- // this cvar will save to cfg once initially agreed with
- Cvar_ns_has_agreed_to_send_token = new ConVar(
- "ns_has_agreed_to_send_token",
- "0",
- FCVAR_ARCHIVE_PLAYERPROFILE,
- "whether the user has agreed to send their origin token to the northstar masterserver");
-}
diff --git a/NorthstarDLL/client/clientruihooks.cpp b/NorthstarDLL/client/clientruihooks.cpp
deleted file mode 100644
index ad50d11a..00000000
--- a/NorthstarDLL/client/clientruihooks.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "core/convar/convar.h"
-
-AUTOHOOK_INIT()
-
-ConVar* Cvar_rui_drawEnable;
-
-// clang-format off
-AUTOHOOK(DrawRUIFunc, engine.dll + 0xFC500,
-bool, __fastcall, (void* a1, float* a2))
-// clang-format on
-{
- if (!Cvar_rui_drawEnable->GetBool())
- return 0;
-
- return DrawRUIFunc(a1, a2);
-}
-
-ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", RUI, ConVar, (CModule module))
-{
- AUTOHOOK_DISPATCH()
-
- Cvar_rui_drawEnable = new ConVar("rui_drawEnable", "1", FCVAR_CLIENTDLL, "Controls whether RUI should be drawn");
-}
diff --git a/NorthstarDLL/client/clientvideooverrides.cpp b/NorthstarDLL/client/clientvideooverrides.cpp
deleted file mode 100644
index d8aa2754..00000000
--- a/NorthstarDLL/client/clientvideooverrides.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "mods/modmanager.h"
-
-AUTOHOOK_INIT()
-
-// clang-format off
-AUTOHOOK_PROCADDRESS(BinkOpen, bink2w64.dll, BinkOpen,
-void*, __fastcall, (const char* path, uint32_t flags))
-// clang-format on
-{
- std::string filename(fs::path(path).filename().string());
- spdlog::info("BinkOpen {}", filename);
-
- // figure out which mod is handling the bink
- Mod* fileOwner = nullptr;
- for (Mod& mod : g_pModManager->m_LoadedMods)
- {
- if (!mod.m_bEnabled)
- continue;
-
- if (std::find(mod.BinkVideos.begin(), mod.BinkVideos.end(), filename) != mod.BinkVideos.end())
- fileOwner = &mod;
- }
-
- if (fileOwner)
- {
- // create new path
- fs::path binkPath(fileOwner->m_ModDirectory / "media" / filename);
- return BinkOpen(binkPath.string().c_str(), flags);
- }
- else
- return BinkOpen(path, flags);
-}
-
-ON_DLL_LOAD_CLIENT("engine.dll", BinkVideo, (CModule module))
-{
- AUTOHOOK_DISPATCH()
-
- // remove engine check for whether the bik we're trying to load exists in r2/media, as this will fail for biks in mods
- // note: the check in engine is actually unnecessary, so it's just useless in practice and we lose nothing by removing it
- module.Offset(0x459AD).NOP(6);
-}
diff --git a/NorthstarDLL/client/debugoverlay.cpp b/NorthstarDLL/client/debugoverlay.cpp
deleted file mode 100644
index e231054d..00000000
--- a/NorthstarDLL/client/debugoverlay.cpp
+++ /dev/null
@@ -1,348 +0,0 @@
-#include "dedicated/dedicated.h"
-#include "core/convar/cvar.h"
-#include "core/math/vector.h"
-
-AUTOHOOK_INIT()
-
-enum OverlayType_t
-{
- OVERLAY_BOX = 0,
- OVERLAY_SPHERE,
- OVERLAY_LINE,
- OVERLAY_SMARTAMMO,
- OVERLAY_TRIANGLE,
- OVERLAY_SWEPT_BOX,
- // [Fifty]: the 2 bellow i did not confirm, rest are good
- OVERLAY_BOX2,
- OVERLAY_CAPSULE
-};
-
-struct OverlayBase_t
-{
- OverlayBase_t()
- {
- m_Type = OVERLAY_BOX;
- m_nServerCount = -1;
- m_nCreationTick = -1;
- m_flEndTime = 0.0f;
- m_pNextOverlay = NULL;
- }
-
- OverlayType_t m_Type; // What type of overlay is it?
- int m_nCreationTick; // Duration -1 means go away after this frame #
- int m_nServerCount; // Latch server count, too
- float m_flEndTime; // When does this box go away
- OverlayBase_t* m_pNextOverlay;
- __int64 m_pUnk;
-};
-
-struct OverlayLine_t : public OverlayBase_t
-{
- OverlayLine_t()
- {
- m_Type = OVERLAY_LINE;
- }
-
- Vector3 origin;
- Vector3 dest;
- int r;
- int g;
- int b;
- int a;
- bool noDepthTest;
-};
-
-struct OverlayBox_t : public OverlayBase_t
-{
- OverlayBox_t()
- {
- m_Type = OVERLAY_BOX;
- }
-
- Vector3 origin;
- Vector3 mins;
- Vector3 maxs;
- QAngle angles;
- int r;
- int g;
- int b;
- int a;
-};
-
-struct OverlayTriangle_t : public OverlayBase_t
-{
- OverlayTriangle_t()
- {
- m_Type = OVERLAY_TRIANGLE;
- }
-
- Vector3 p1;
- Vector3 p2;
- Vector3 p3;
- int r;
- int g;
- int b;
- int a;
- bool noDepthTest;
-};
-
-struct OverlaySweptBox_t : public OverlayBase_t
-{
- OverlaySweptBox_t()
- {
- m_Type = OVERLAY_SWEPT_BOX;
- }
-
- Vector3 start;
- Vector3 end;
- Vector3 mins;
- Vector3 maxs;
- QAngle angles;
- int r;
- int g;
- int b;
- int a;
-};
-
-struct OverlaySphere_t : public OverlayBase_t
-{
- OverlaySphere_t()
- {
- m_Type = OVERLAY_SPHERE;
- }
-
- Vector3 vOrigin;
- float flRadius;
- int nTheta;
- int nPhi;
- int r;
- int g;
- int b;
- int a;
- bool m_bWireframe;
-};
-
-typedef bool (*OverlayBase_t__IsDeadType)(OverlayBase_t* a1);
-static OverlayBase_t__IsDeadType OverlayBase_t__IsDead;
-typedef void (*OverlayBase_t__DestroyOverlayType)(OverlayBase_t* a1);
-static OverlayBase_t__DestroyOverlayType OverlayBase_t__DestroyOverlay;
-
-static ConVar* Cvar_enable_debug_overlays;
-
-LPCRITICAL_SECTION s_OverlayMutex;
-
-// Render Line
-typedef void (*RenderLineType)(const Vector3& v1, const Vector3& v2, Color c, bool bZBuffer);
-static RenderLineType RenderLine;
-
-// Render box
-typedef void (*RenderBoxType)(
- const Vector3& vOrigin, const QAngle& angles, const Vector3& vMins, const Vector3& vMaxs, Color c, bool bZBuffer, bool bInsideOut);
-static RenderBoxType RenderBox;
-
-// Render wireframe box
-static RenderBoxType RenderWireframeBox;
-
-// Render swept box
-typedef void (*RenderWireframeSweptBoxType)(
- const Vector3& vStart, const Vector3& vEnd, const QAngle& angles, const Vector3& vMins, const Vector3& vMaxs, Color c, bool bZBuffer);
-RenderWireframeSweptBoxType RenderWireframeSweptBox;
-
-// Render Triangle
-typedef void (*RenderTriangleType)(const Vector3& p1, const Vector3& p2, const Vector3& p3, Color c, bool bZBuffer);
-static RenderTriangleType RenderTriangle;
-
-// Render Axis
-typedef void (*RenderAxisType)(const Vector3& vOrigin, float flScale, bool bZBuffer);
-static RenderAxisType RenderAxis;
-
-// I dont know
-typedef void (*RenderUnknownType)(const Vector3& vUnk, float flUnk, bool bUnk);
-static RenderUnknownType RenderUnknown;
-
-// Render Sphere
-typedef void (*RenderSphereType)(const Vector3& vCenter, float flRadius, int nTheta, int nPhi, Color c, bool bZBuffer);
-static RenderSphereType RenderSphere;
-
-OverlayBase_t** s_pOverlays;
-
-int* g_nRenderTickCount;
-int* g_nOverlayTickCount;
-
-// clang-format off
-AUTOHOOK(DrawOverlay, engine.dll + 0xABCB0,
-void, __fastcall, (OverlayBase_t * pOverlay))
-// clang-format on
-{
- EnterCriticalSection(s_OverlayMutex);
-
- switch (pOverlay->m_Type)
- {
- case OVERLAY_SMARTAMMO:
- case OVERLAY_LINE:
- {
- OverlayLine_t* pLine = static_cast<OverlayLine_t*>(pOverlay);
- RenderLine(pLine->origin, pLine->dest, Color(pLine->r, pLine->g, pLine->b, pLine->a), pLine->noDepthTest);
- }
- break;
- case OVERLAY_BOX:
- {
- OverlayBox_t* pCurrBox = static_cast<OverlayBox_t*>(pOverlay);
- if (pCurrBox->a > 0)
- {
- RenderBox(
- pCurrBox->origin,
- pCurrBox->angles,
- pCurrBox->mins,
- pCurrBox->maxs,
- Color(pCurrBox->r, pCurrBox->g, pCurrBox->b, pCurrBox->a),
- false,
- false);
- }
- if (pCurrBox->a < 255)
- {
- RenderWireframeBox(
- pCurrBox->origin,
- pCurrBox->angles,
- pCurrBox->mins,
- pCurrBox->maxs,
- Color(pCurrBox->r, pCurrBox->g, pCurrBox->b, 255),
- false,
- false);
- }
- }
- break;
- case OVERLAY_TRIANGLE:
- {
- OverlayTriangle_t* pTriangle = static_cast<OverlayTriangle_t*>(pOverlay);
- RenderTriangle(
- pTriangle->p1,
- pTriangle->p2,
- pTriangle->p3,
- Color(pTriangle->r, pTriangle->g, pTriangle->b, pTriangle->a),
- pTriangle->noDepthTest);
- }
- break;
- case OVERLAY_SWEPT_BOX:
- {
- OverlaySweptBox_t* pBox = static_cast<OverlaySweptBox_t*>(pOverlay);
- RenderWireframeSweptBox(
- pBox->start, pBox->end, pBox->angles, pBox->mins, pBox->maxs, Color(pBox->r, pBox->g, pBox->b, pBox->a), false);
- }
- break;
- case OVERLAY_SPHERE:
- {
- OverlaySphere_t* pSphere = static_cast<OverlaySphere_t*>(pOverlay);
- RenderSphere(
- pSphere->vOrigin,
- pSphere->flRadius,
- pSphere->nTheta,
- pSphere->nPhi,
- Color(pSphere->r, pSphere->g, pSphere->b, pSphere->a),
- false);
- }
- break;
- default:
- {
- spdlog::warn("Unimplemented overlay type {}", pOverlay->m_Type);
- }
- break;
- }
-
- LeaveCriticalSection(s_OverlayMutex);
-}
-
-// clang-format off
-AUTOHOOK(DrawAllOverlays, engine.dll + 0xAB780,
-void, __fastcall, (bool bRender))
-// clang-format on
-{
- EnterCriticalSection(s_OverlayMutex);
-
- OverlayBase_t* pCurrOverlay = *s_pOverlays; // rbx
- OverlayBase_t* pPrevOverlay = nullptr; // rsi
- OverlayBase_t* pNextOverlay = nullptr; // rdi
-
- int m_nCreationTick; // eax
- bool bShouldDraw; // zf
- int m_pUnk; // eax
-
- while (pCurrOverlay)
- {
- if (OverlayBase_t__IsDead(pCurrOverlay))
- {
- if (pPrevOverlay)
- {
- pPrevOverlay->m_pNextOverlay = pCurrOverlay->m_pNextOverlay;
- }
- else
- {
- *s_pOverlays = pCurrOverlay->m_pNextOverlay;
- }
-
- pNextOverlay = pCurrOverlay->m_pNextOverlay;
- OverlayBase_t__DestroyOverlay(pCurrOverlay);
- pCurrOverlay = pNextOverlay;
- }
- else
- {
- if (pCurrOverlay->m_nCreationTick == -1)
- {
- m_pUnk = pCurrOverlay->m_pUnk;
-
- if (m_pUnk == -1)
- {
- bShouldDraw = true;
- }
- else
- {
- bShouldDraw = m_pUnk == *g_nOverlayTickCount;
- }
- }
- else
- {
- bShouldDraw = pCurrOverlay->m_nCreationTick == *g_nRenderTickCount;
- }
-
- if (bShouldDraw && bRender && (Cvar_enable_debug_overlays->GetBool() || pCurrOverlay->m_Type == OVERLAY_SMARTAMMO))
- {
- DrawOverlay(pCurrOverlay);
- }
-
- pPrevOverlay = pCurrOverlay;
- pCurrOverlay = pCurrOverlay->m_pNextOverlay;
- }
- }
-
- LeaveCriticalSection(s_OverlayMutex);
-}
-
-ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", DebugOverlay, ConVar, (CModule module))
-{
- AUTOHOOK_DISPATCH()
-
- OverlayBase_t__IsDead = module.Offset(0xACAC0).RCast<OverlayBase_t__IsDeadType>();
- OverlayBase_t__DestroyOverlay = module.Offset(0xAB680).RCast<OverlayBase_t__DestroyOverlayType>();
-
- RenderLine = module.Offset(0x192A70).RCast<RenderLineType>();
- RenderBox = module.Offset(0x192520).RCast<RenderBoxType>();
- RenderWireframeBox = module.Offset(0x193DA0).RCast<RenderBoxType>();
- RenderWireframeSweptBox = module.Offset(0x1945A0).RCast<RenderWireframeSweptBoxType>();
- RenderTriangle = module.Offset(0x193940).RCast<RenderTriangleType>();
- RenderAxis = module.Offset(0x1924D0).RCast<RenderAxisType>();
- RenderSphere = module.Offset(0x194170).RCast<RenderSphereType>();
- RenderUnknown = module.Offset(0x1924E0).RCast<RenderUnknownType>();
-
- s_OverlayMutex = module.Offset(0x10DB0A38).RCast<LPCRITICAL_SECTION>();
-
- s_pOverlays = module.Offset(0x10DB0968).RCast<OverlayBase_t**>();
-
- g_nRenderTickCount = module.Offset(0x10DB0984).RCast<int*>();
- g_nOverlayTickCount = module.Offset(0x10DB0980).RCast<int*>();
-
- // not in g_pCVar->FindVar by this point for whatever reason, so have to get from memory
- Cvar_enable_debug_overlays = module.Offset(0x10DB0990).RCast<ConVar*>();
- Cvar_enable_debug_overlays->SetValue(false);
- Cvar_enable_debug_overlays->m_pszDefaultValue = (char*)"0";
- Cvar_enable_debug_overlays->AddFlags(FCVAR_CHEAT);
-}
diff --git a/NorthstarDLL/client/demofixes.cpp b/NorthstarDLL/client/demofixes.cpp
deleted file mode 100644
index 344764ba..00000000
--- a/NorthstarDLL/client/demofixes.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-#include "core/convar/convar.h"
-
-ON_DLL_LOAD_CLIENT("engine.dll", EngineDemoFixes, (CModule module))
-{
- // allow demo recording on loopback
- module.Offset(0x8E1B1).NOP(2);
- module.Offset(0x56CC3).NOP(2);
-}
-
-ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ClientDemoFixes, ConVar, (CModule module))
-{
- // change default values of demo cvars to enable them by default, but not autorecord
- // this is before Host_Init, the setvalue calls here will get overwritten by custom cfgs/launch options
- ConVar* Cvar_demo_enableDemos = g_pCVar->FindVar("demo_enabledemos");
- Cvar_demo_enableDemos->m_pszDefaultValue = "1";
- Cvar_demo_enableDemos->SetValue(true);
-
- ConVar* Cvar_demo_writeLocalFile = g_pCVar->FindVar("demo_writeLocalFile");
- Cvar_demo_writeLocalFile->m_pszDefaultValue = "1";
- Cvar_demo_writeLocalFile->SetValue(true);
-
- ConVar* Cvar_demo_autoRecord = g_pCVar->FindVar("demo_autoRecord");
- Cvar_demo_autoRecord->m_pszDefaultValue = "0";
- Cvar_demo_autoRecord->SetValue(false);
-}
diff --git a/NorthstarDLL/client/diskvmtfixes.cpp b/NorthstarDLL/client/diskvmtfixes.cpp
deleted file mode 100644
index 4ab951c0..00000000
--- a/NorthstarDLL/client/diskvmtfixes.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-
-ON_DLL_LOAD_CLIENT("materialsystem_dx11.dll", DiskVMTFixes, (CModule module))
-{
- // in retail VMTs will never load if cache read is invalid due to a special case for them in KeyValues::LoadFromFile
- // this effectively makes it impossible to load them from mods because we invalidate cache for doing this
- // so uhh, stop that from happening
-
- // tbh idk why they even changed any of this what's the point it looks like it works fine who cares my god
-
- // matsystem KeyValues::LoadFromFile: patch special case on cache read failure for vmts
- module.Offset(0x1281B9).Patch("EB");
-
- // CMaterialSystem::FindMaterial: don't call function that crashes if previous patch is applied
- module.Offset(0x5F55A).NOP(5);
-}
diff --git a/NorthstarDLL/client/languagehooks.cpp b/NorthstarDLL/client/languagehooks.cpp
deleted file mode 100644
index 35ca5659..00000000
--- a/NorthstarDLL/client/languagehooks.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-#include "core/tier0.h"
-
-#include <filesystem>
-#include <regex>
-
-AUTOHOOK_INIT()
-
-typedef LANGID (*Tier0_DetectDefaultLanguageType)();
-
-bool CheckLangAudioExists(char* lang)
-{
- std::string path {"r2\\sound\\general_"};
- path += lang;
- path += ".mstr";
- return fs::exists(path);
-}
-
-std::vector<std::string> file_list(fs::path dir, std::regex ext_pattern)
-{
- std::vector<std::string> result;
-
- if (!fs::exists(dir) || !fs::is_directory(dir))
- return result;
-
- using iterator = fs::directory_iterator;
-
- const iterator end;
- for (iterator iter {dir}; iter != end; ++iter)
- {
- const std::string filename = iter->path().filename().string();
- std::smatch matches;
- if (fs::is_regular_file(*iter) && std::regex_match(filename, matches, ext_pattern))
- {
- result.push_back(std::move(matches.str(1)));
- }
- }
-
- return result;
-}
-
-std::string GetAnyInstalledAudioLanguage()
-{
- for (const auto& lang : file_list("r2\\sound\\", std::regex(".*?general_([a-z]+)_patch_1\\.mstr")))
- if (lang != "general" || lang != "")
- return lang;
- return "NO LANGUAGE DETECTED";
-}
-
-// clang-format off
-AUTOHOOK(GetGameLanguage, tier0.dll + 0xF560,
-char*, __fastcall, ())
-// clang-format on
-{
- auto tier0Handle = GetModuleHandleA("tier0.dll");
- auto Tier0_DetectDefaultLanguageType = GetProcAddress(tier0Handle, "Tier0_DetectDefaultLanguage");
- char* ingameLang1 = (char*)tier0Handle + 0xA9B60; // one of the globals we need to override if overriding lang (size: 256)
- bool& canOriginDictateLang = *(bool*)((char*)tier0Handle + 0xA9A90);
-
- const char* forcedLanguage;
- if (CommandLine()->CheckParm("-language", &forcedLanguage))
- {
- 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);
- }
- else
- {
- spdlog::info("User forcing the language (-language) to: {}", forcedLanguage);
- strncpy(ingameLang1, forcedLanguage, 256);
- return ingameLang1;
- }
- }
-
- canOriginDictateLang = true; // let it try
- {
- auto lang = GetGameLanguage();
- 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);
- }
- else
- {
- spdlog::info("Origin detected language: {}", lang);
- return lang;
- }
- }
-
- 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 = GetGameLanguage();
- 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.");
- auto lang = GetAnyInstalledAudioLanguage();
- spdlog::warn("Falling back to the first installed audio language: {}", lang.c_str());
- strncpy(ingameLang1, lang.c_str(), 256);
- return ingameLang1;
- }
-
- return lang;
-}
-
-ON_DLL_LOAD_CLIENT("tier0.dll", LanguageHooks, (CModule module))
-{
- AUTOHOOK_DISPATCH()
-}
diff --git a/NorthstarDLL/client/latencyflex.cpp b/NorthstarDLL/client/latencyflex.cpp
deleted file mode 100644
index 25e38c7a..00000000
--- a/NorthstarDLL/client/latencyflex.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-#include "core/convar/convar.h"
-
-AUTOHOOK_INIT()
-
-ConVar* Cvar_r_latencyflex;
-
-void (*m_winelfx_WaitAndBeginFrame)();
-
-// clang-format off
-AUTOHOOK(OnRenderStart, client.dll + 0x1952C0,
-void, __fastcall, ())
-// clang-format on
-{
- if (Cvar_r_latencyflex->GetBool() && m_winelfx_WaitAndBeginFrame)
- m_winelfx_WaitAndBeginFrame();
-
- OnRenderStart();
-}
-
-ON_DLL_LOAD_CLIENT_RELIESON("client.dll", LatencyFlex, ConVar, (CModule module))
-{
- // Connect to the LatencyFleX service
- // LatencyFleX is an open source vendor agnostic replacement for Nvidia Reflex input latency reduction technology.
- // https://ishitatsuyuki.github.io/post/latencyflex/
- HMODULE pLfxModule;
-
- if (pLfxModule = LoadLibraryA("latencyflex_layer.dll"))
- m_winelfx_WaitAndBeginFrame =
- reinterpret_cast<void (*)()>(reinterpret_cast<void*>(GetProcAddress(pLfxModule, "lfx_WaitAndBeginFrame")));
- else if (pLfxModule = LoadLibraryA("latencyflex_wine.dll"))
- m_winelfx_WaitAndBeginFrame =
- reinterpret_cast<void (*)()>(reinterpret_cast<void*>(GetProcAddress(pLfxModule, "winelfx_WaitAndBeginFrame")));
- else
- {
- spdlog::info("Unable to load LatencyFleX library, LatencyFleX disabled.");
- return;
- }
-
- AUTOHOOK_DISPATCH()
-
- spdlog::info("LatencyFleX initialized.");
- Cvar_r_latencyflex = new ConVar("r_latencyflex", "1", FCVAR_ARCHIVE, "Whether or not to use LatencyFleX input latency reduction.");
-}
diff --git a/NorthstarDLL/client/localchatwriter.cpp b/NorthstarDLL/client/localchatwriter.cpp
deleted file mode 100644
index 35cc065f..00000000
--- a/NorthstarDLL/client/localchatwriter.cpp
+++ /dev/null
@@ -1,449 +0,0 @@
-#include "localchatwriter.h"
-
-class vgui_BaseRichText_vtable;
-
-class vgui_BaseRichText
-{
-public:
- vgui_BaseRichText_vtable* vtable;
-};
-
-class vgui_BaseRichText_vtable
-{
-public:
- char unknown1[1880];
-
- void(__fastcall* InsertChar)(vgui_BaseRichText* self, wchar_t ch);
-
- // yes these are swapped from the Source 2013 code, who knows why
- void(__fastcall* InsertStringWide)(vgui_BaseRichText* self, const wchar_t* wszText);
- void(__fastcall* InsertStringAnsi)(vgui_BaseRichText* self, const char* text);
-
- void(__fastcall* SelectNone)(vgui_BaseRichText* self);
- void(__fastcall* SelectAllText)(vgui_BaseRichText* self);
- void(__fastcall* SelectNoText)(vgui_BaseRichText* self);
- void(__fastcall* CutSelected)(vgui_BaseRichText* self);
- void(__fastcall* CopySelected)(vgui_BaseRichText* self);
- void(__fastcall* SetPanelInteractive)(vgui_BaseRichText* self, bool bInteractive);
- void(__fastcall* SetUnusedScrollbarInvisible)(vgui_BaseRichText* self, bool bInvis);
-
- void* unknown2;
-
- void(__fastcall* GotoTextStart)(vgui_BaseRichText* self);
- void(__fastcall* GotoTextEnd)(vgui_BaseRichText* self);
-
- void* unknown3[3];
-
- void(__fastcall* SetVerticalScrollbar)(vgui_BaseRichText* self, bool state);
- void(__fastcall* SetMaximumCharCount)(vgui_BaseRichText* self, int maxChars);
- void(__fastcall* InsertColorChange)(vgui_BaseRichText* self, Color col);
- void(__fastcall* InsertIndentChange)(vgui_BaseRichText* self, int pixelsIndent);
- void(__fastcall* InsertClickableTextStart)(vgui_BaseRichText* self, const char* pchClickAction);
- void(__fastcall* InsertClickableTextEnd)(vgui_BaseRichText* self);
- void(__fastcall* InsertPossibleURLString)(vgui_BaseRichText* self, const char* text, Color URLTextColor, Color normalTextColor);
- void(__fastcall* InsertFade)(vgui_BaseRichText* self, float flSustain, float flLength);
- void(__fastcall* ResetAllFades)(vgui_BaseRichText* self, bool bHold, bool bOnlyExpired, float flNewSustain);
- void(__fastcall* SetToFullHeight)(vgui_BaseRichText* self);
- int(__fastcall* GetNumLines)(vgui_BaseRichText* self);
-};
-
-class CGameSettings
-{
-public:
- char unknown1[92];
- int isChatEnabled;
-};
-
-// Not sure what this actually refers to but chatFadeLength and chatFadeSustain
-// have their value at the same offset
-class CGameFloatVar
-{
-public:
- char unknown1[88];
- float value;
-};
-
-CGameSettings** gGameSettings;
-CGameFloatVar** gChatFadeLength;
-CGameFloatVar** gChatFadeSustain;
-
-CHudChat** CHudChat::allHuds;
-
-typedef void(__fastcall* ConvertANSIToUnicodeType)(LPCSTR ansi, int ansiCharLength, LPWSTR unicode, int unicodeCharLength);
-ConvertANSIToUnicodeType ConvertANSIToUnicode;
-
-LocalChatWriter::SwatchColor swatchColors[4] = {
- LocalChatWriter::MainTextColor,
- LocalChatWriter::SameTeamNameColor,
- LocalChatWriter::EnemyTeamNameColor,
- LocalChatWriter::NetworkNameColor,
-};
-
-Color darkColors[8] = {
- Color {0, 0, 0, 255},
- Color {205, 49, 49, 255},
- Color {13, 188, 121, 255},
- Color {229, 229, 16, 255},
- Color {36, 114, 200, 255},
- Color {188, 63, 188, 255},
- Color {17, 168, 205, 255},
- Color {229, 229, 229, 255}};
-
-Color lightColors[8] = {
- Color {102, 102, 102, 255},
- Color {241, 76, 76, 255},
- Color {35, 209, 139, 255},
- Color {245, 245, 67, 255},
- Color {59, 142, 234, 255},
- Color {214, 112, 214, 255},
- Color {41, 184, 219, 255},
- Color {255, 255, 255, 255}};
-
-class AnsiEscapeParser
-{
-public:
- explicit AnsiEscapeParser(LocalChatWriter* writer) : m_writer(writer) {}
-
- void HandleVal(unsigned long val)
- {
- switch (m_next)
- {
- case Next::ControlType:
- m_next = HandleControlType(val);
- break;
- case Next::ForegroundType:
- m_next = HandleForegroundType(val);
- break;
- case Next::Foreground8Bit:
- m_next = HandleForeground8Bit(val);
- break;
- case Next::ForegroundR:
- m_next = HandleForegroundR(val);
- break;
- case Next::ForegroundG:
- m_next = HandleForegroundG(val);
- break;
- case Next::ForegroundB:
- m_next = HandleForegroundB(val);
- break;
- }
- }
-
-private:
- enum class Next
- {
- ControlType,
- ForegroundType,
- Foreground8Bit,
- ForegroundR,
- ForegroundG,
- ForegroundB
- };
-
- LocalChatWriter* m_writer;
- Next m_next = Next::ControlType;
- Color m_expandedColor {0, 0, 0, 0};
-
- Next HandleControlType(unsigned long val)
- {
- // Reset
- if (val == 0 || val == 39)
- {
- m_writer->InsertSwatchColorChange(LocalChatWriter::MainTextColor);
- return Next::ControlType;
- }
-
- // Dark foreground color
- if (val >= 30 && val < 38)
- {
- m_writer->InsertColorChange(darkColors[val - 30]);
- return Next::ControlType;
- }
-
- // Light foreground color
- if (val >= 90 && val < 98)
- {
- m_writer->InsertColorChange(lightColors[val - 90]);
- return Next::ControlType;
- }
-
- // Game swatch color
- if (val >= 110 && val < 114)
- {
- m_writer->InsertSwatchColorChange(swatchColors[val - 110]);
- return Next::ControlType;
- }
-
- // Expanded foreground color
- if (val == 38)
- {
- return Next::ForegroundType;
- }
-
- return Next::ControlType;
- }
-
- Next HandleForegroundType(unsigned long val)
- {
- // Next values are r,g,b
- if (val == 2)
- {
- m_expandedColor.SetColor(0, 0, 0, 255);
- return Next::ForegroundR;
- }
- // Next value is 8-bit swatch color
- if (val == 5)
- {
- return Next::Foreground8Bit;
- }
-
- // Invalid
- return Next::ControlType;
- }
-
- Next HandleForeground8Bit(unsigned long val)
- {
- if (val < 8)
- {
- m_writer->InsertColorChange(darkColors[val]);
- }
- else if (val < 16)
- {
- m_writer->InsertColorChange(lightColors[val - 8]);
- }
- else if (val < 232)
- {
- unsigned char code = val - 16;
- unsigned char blue = code % 6;
- unsigned char green = ((code - blue) / 6) % 6;
- unsigned char red = (code - blue - (green * 6)) / 36;
- m_writer->InsertColorChange(Color {(unsigned char)(red * 51), (unsigned char)(green * 51), (unsigned char)(blue * 51), 255});
- }
- else if (val < UCHAR_MAX)
- {
- unsigned char brightness = (val - 232) * 10 + 8;
- m_writer->InsertColorChange(Color {brightness, brightness, brightness, 255});
- }
-
- return Next::ControlType;
- }
-
- Next HandleForegroundR(unsigned long val)
- {
- if (val >= UCHAR_MAX)
- return Next::ControlType;
-
- m_expandedColor[0] = (unsigned char)val;
- return Next::ForegroundG;
- }
-
- Next HandleForegroundG(unsigned long val)
- {
- if (val >= UCHAR_MAX)
- return Next::ControlType;
-
- m_expandedColor[1] = (unsigned char)val;
- return Next::ForegroundB;
- }
-
- Next HandleForegroundB(unsigned long val)
- {
- if (val >= UCHAR_MAX)
- return Next::ControlType;
-
- m_expandedColor[2] = (unsigned char)val;
- m_writer->InsertColorChange(m_expandedColor);
- return Next::ControlType;
- }
-};
-
-LocalChatWriter::LocalChatWriter(Context context) : m_context(context) {}
-
-void LocalChatWriter::Write(const char* str)
-{
- char writeBuffer[256];
-
- while (true)
- {
- const char* startOfEscape = strstr(str, "\033[");
-
- if (startOfEscape == NULL)
- {
- // No more escape sequences, write the remaining text and exit
- InsertText(str);
- break;
- }
-
- if (startOfEscape != str)
- {
- // There is some text before the escape sequence, just print that
- size_t copyChars = startOfEscape - str;
- if (copyChars > 255)
- copyChars = 255;
-
- strncpy_s(writeBuffer, copyChars + 1, str, copyChars);
-
- InsertText(writeBuffer);
- }
-
- const char* escape = startOfEscape + 2;
- str = ApplyAnsiEscape(escape);
- }
-}
-
-void LocalChatWriter::WriteLine(const char* str)
-{
- InsertChar(L'\n');
- InsertSwatchColorChange(MainTextColor);
- Write(str);
-}
-
-void LocalChatWriter::InsertChar(wchar_t ch)
-{
- for (CHudChat* hud = *CHudChat::allHuds; hud != NULL; hud = hud->next)
- {
- if (hud->m_unknownContext != (int)m_context)
- continue;
-
- hud->m_richText->vtable->InsertChar(hud->m_richText, ch);
- }
-
- if (ch != L'\n')
- {
- InsertDefaultFade();
- }
-}
-
-void LocalChatWriter::InsertText(const char* str)
-{
- spdlog::info(str);
-
- WCHAR messageUnicode[288];
- ConvertANSIToUnicode(str, -1, messageUnicode, 274);
-
- for (CHudChat* hud = *CHudChat::allHuds; hud != NULL; hud = hud->next)
- {
- if (hud->m_unknownContext != (int)m_context)
- continue;
-
- hud->m_richText->vtable->InsertStringWide(hud->m_richText, messageUnicode);
- }
-
- InsertDefaultFade();
-}
-
-void LocalChatWriter::InsertText(const wchar_t* str)
-{
- for (CHudChat* hud = *CHudChat::allHuds; hud != NULL; hud = hud->next)
- {
- if (hud->m_unknownContext != (int)m_context)
- continue;
-
- hud->m_richText->vtable->InsertStringWide(hud->m_richText, str);
- }
-
- InsertDefaultFade();
-}
-
-void LocalChatWriter::InsertColorChange(Color color)
-{
- for (CHudChat* hud = *CHudChat::allHuds; hud != NULL; hud = hud->next)
- {
- if (hud->m_unknownContext != (int)m_context)
- continue;
-
- hud->m_richText->vtable->InsertColorChange(hud->m_richText, color);
- }
-}
-
-static Color GetHudSwatchColor(CHudChat* hud, LocalChatWriter::SwatchColor swatchColor)
-{
- switch (swatchColor)
- {
- case LocalChatWriter::MainTextColor:
- return hud->m_mainTextColor;
-
- case LocalChatWriter::SameTeamNameColor:
- return hud->m_sameTeamColor;
-
- case LocalChatWriter::EnemyTeamNameColor:
- return hud->m_enemyTeamColor;
-
- case LocalChatWriter::NetworkNameColor:
- return hud->m_networkNameColor;
- }
-
- return Color(0, 0, 0, 0);
-}
-
-void LocalChatWriter::InsertSwatchColorChange(SwatchColor swatchColor)
-{
- for (CHudChat* hud = *CHudChat::allHuds; hud != NULL; hud = hud->next)
- {
- if (hud->m_unknownContext != (int)m_context)
- continue;
- hud->m_richText->vtable->InsertColorChange(hud->m_richText, GetHudSwatchColor(hud, swatchColor));
- }
-}
-
-const char* LocalChatWriter::ApplyAnsiEscape(const char* escape)
-{
- AnsiEscapeParser decoder(this);
- while (true)
- {
- char* afterControlType = NULL;
- unsigned long controlType = strtoul(escape, &afterControlType, 10);
-
- // Malformed cases:
- // afterControlType = NULL: strtoul errored
- // controlType = 0 and escape doesn't actually start with 0: wasn't a number
- if (afterControlType == NULL || (controlType == 0 && escape[0] != '0'))
- {
- return escape;
- }
-
- decoder.HandleVal(controlType);
-
- // m indicates the end of the sequence
- if (afterControlType[0] == 'm')
- {
- return afterControlType + 1;
- }
-
- // : or ; indicates more values remain, anything else is malformed
- if (afterControlType[0] != ':' && afterControlType[0] != ';')
- {
- return afterControlType;
- }
-
- escape = afterControlType + 1;
- }
-}
-
-void LocalChatWriter::InsertDefaultFade()
-{
- float fadeLength = 0.f;
- float fadeSustain = 0.f;
- if ((*gGameSettings)->isChatEnabled)
- {
- fadeLength = (*gChatFadeLength)->value;
- fadeSustain = (*gChatFadeSustain)->value;
- }
-
- for (CHudChat* hud = *CHudChat::allHuds; hud != NULL; hud = hud->next)
- {
- if (hud->m_unknownContext != (int)m_context)
- continue;
- hud->m_richText->vtable->InsertFade(hud->m_richText, fadeSustain, fadeLength);
- }
-}
-
-ON_DLL_LOAD_CLIENT("client.dll", LocalChatWriter, (CModule module))
-{
- gGameSettings = module.Offset(0x11BAA48).RCast<CGameSettings**>();
- gChatFadeLength = module.Offset(0x11BAB78).RCast<CGameFloatVar**>();
- gChatFadeSustain = module.Offset(0x11BAC08).RCast<CGameFloatVar**>();
- CHudChat::allHuds = module.Offset(0x11BA9E8).RCast<CHudChat**>();
-
- ConvertANSIToUnicode = module.Offset(0x7339A0).RCast<ConvertANSIToUnicodeType>();
-}
diff --git a/NorthstarDLL/client/localchatwriter.h b/NorthstarDLL/client/localchatwriter.h
deleted file mode 100644
index acf6f87e..00000000
--- a/NorthstarDLL/client/localchatwriter.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#pragma once
-#include "core/math/color.h"
-
-class vgui_BaseRichText;
-
-class CHudChat
-{
-public:
- static CHudChat** allHuds;
-
- char unknown1[720];
-
- Color m_sameTeamColor;
- Color m_enemyTeamColor;
- Color m_mainTextColor;
- Color m_networkNameColor;
-
- char unknown2[12];
-
- int m_unknownContext;
-
- char unknown3[8];
-
- vgui_BaseRichText* m_richText;
-
- CHudChat* next;
- CHudChat* previous;
-};
-
-class LocalChatWriter
-{
-public:
- enum Context
- {
- NetworkContext = 0,
- GameContext = 1
- };
- enum SwatchColor
- {
- MainTextColor,
- SameTeamNameColor,
- EnemyTeamNameColor,
- NetworkNameColor
- };
-
- explicit LocalChatWriter(Context context);
-
- // Custom chat writing with ANSI escape codes
- void Write(const char* str);
- void WriteLine(const char* str);
-
- // Low-level RichText access
- void InsertChar(wchar_t ch);
- void InsertText(const char* str);
- void InsertText(const wchar_t* str);
- void InsertColorChange(Color color);
- void InsertSwatchColorChange(SwatchColor color);
-
-private:
- Context m_context;
-
- const char* ApplyAnsiEscape(const char* escape);
- void InsertDefaultFade();
-};
diff --git a/NorthstarDLL/client/modlocalisation.cpp b/NorthstarDLL/client/modlocalisation.cpp
deleted file mode 100644
index 2b73876b..00000000
--- a/NorthstarDLL/client/modlocalisation.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "mods/modmanager.h"
-
-AUTOHOOK_INIT()
-
-void* g_pVguiLocalize;
-
-// clang-format off
-AUTOHOOK(CLocalize__AddFile, localize.dll + 0x6D80,
-bool, __fastcall, (void* pVguiLocalize, const char* path, const char* pathId, bool bIncludeFallbackSearchPaths))
-// clang-format on
-{
- // save this for later
- g_pVguiLocalize = pVguiLocalize;
-
- bool ret = CLocalize__AddFile(pVguiLocalize, path, pathId, bIncludeFallbackSearchPaths);
- if (ret)
- spdlog::info("Loaded localisation file {} successfully", path);
-
- return true;
-}
-
-// clang-format off
-AUTOHOOK(CLocalize__ReloadLocalizationFiles, localize.dll + 0xB830,
-void, __fastcall, (void* pVguiLocalize))
-// clang-format on
-{
- // load all mod localization manually, so we keep track of all files, not just previously loaded ones
- for (Mod mod : g_pModManager->m_LoadedMods)
- if (mod.m_bEnabled)
- for (std::string& localisationFile : mod.LocalisationFiles)
- CLocalize__AddFile(g_pVguiLocalize, localisationFile.c_str(), nullptr, false);
-
- spdlog::info("reloading localization...");
- CLocalize__ReloadLocalizationFiles(pVguiLocalize);
-}
-
-// clang-format off
-AUTOHOOK(CEngineVGui__Init, engine.dll + 0x247E10,
-void, __fastcall, (void* self))
-// clang-format on
-{
- CEngineVGui__Init(self); // this loads r1_english, valve_english, dev_english
-
- // previously we did this in CLocalize::AddFile, but for some reason it won't properly overwrite localization from
- // files loaded previously if done there, very weird but this works so whatever
- for (Mod mod : g_pModManager->m_LoadedMods)
- if (mod.m_bEnabled)
- for (std::string& localisationFile : mod.LocalisationFiles)
- CLocalize__AddFile(g_pVguiLocalize, localisationFile.c_str(), nullptr, false);
-}
-
-ON_DLL_LOAD_CLIENT("localize.dll", Localize, (CModule module))
-{
- AUTOHOOK_DISPATCH()
-}
diff --git a/NorthstarDLL/client/r2client.cpp b/NorthstarDLL/client/r2client.cpp
deleted file mode 100644
index c8e59d74..00000000
--- a/NorthstarDLL/client/r2client.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "r2client.h"
-
-char* g_pLocalPlayerUserID;
-char* g_pLocalPlayerOriginToken;
-GetBaseLocalClientType GetBaseLocalClient;
-
-ON_DLL_LOAD("engine.dll", R2EngineClient, (CModule module))
-{
- g_pLocalPlayerUserID = module.Offset(0x13F8E688).RCast<char*>();
- g_pLocalPlayerOriginToken = module.Offset(0x13979C80).RCast<char*>();
-
- GetBaseLocalClient = module.Offset(0x78200).RCast<GetBaseLocalClientType>();
-}
diff --git a/NorthstarDLL/client/r2client.h b/NorthstarDLL/client/r2client.h
deleted file mode 100644
index ea263dbc..00000000
--- a/NorthstarDLL/client/r2client.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-extern char* g_pLocalPlayerUserID;
-extern char* g_pLocalPlayerOriginToken;
-
-typedef void* (*GetBaseLocalClientType)();
-extern GetBaseLocalClientType GetBaseLocalClient;
diff --git a/NorthstarDLL/client/rejectconnectionfixes.cpp b/NorthstarDLL/client/rejectconnectionfixes.cpp
deleted file mode 100644
index 1b326a3c..00000000
--- a/NorthstarDLL/client/rejectconnectionfixes.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "engine/r2engine.h"
-
-AUTOHOOK_INIT()
-
-// this is called from when our connection is rejected, this is the only case we're hooking this for
-// clang-format off
-AUTOHOOK(COM_ExplainDisconnection, engine.dll + 0x1342F0,
-void,, (bool a1, const char* fmt, ...))
-// clang-format on
-{
- va_list va;
- va_start(va, fmt);
- char buf[4096];
- vsnprintf_s(buf, 4096, fmt, va);
- va_end(va);
-
- // slightly hacky comparison, but patching the function that calls this for reject would be worse
- if (!strncmp(fmt, "Connection rejected: ", 21))
- {
- // when COM_ExplainDisconnection is called from engine.dll + 19ff1c for connection rejected, it doesn't
- // call Host_Disconnect, which properly shuts down listen server
- // not doing this gets our client in a pretty weird state so we need to shut it down manually here
-
- // don't call Cbuf_Execute because we don't need this called immediately
- Cbuf_AddText(Cbuf_GetCurrentPlayer(), "disconnect", cmd_source_t::kCommandSrcCode);
- }
-
- return COM_ExplainDisconnection(a1, "%s", buf);
-}
-
-ON_DLL_LOAD_CLIENT("engine.dll", RejectConnectionFixes, (CModule module))
-{
- AUTOHOOK_DISPATCH()
-}