diff options
Diffstat (limited to 'NorthstarDLL/core')
29 files changed, 0 insertions, 4855 deletions
diff --git a/NorthstarDLL/core/convar/concommand.cpp b/NorthstarDLL/core/convar/concommand.cpp deleted file mode 100644 index 41f54c76..00000000 --- a/NorthstarDLL/core/convar/concommand.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "concommand.h" -#include "shared/misccommands.h" -#include "engine/r2engine.h" - -#include "plugins/pluginbackend.h" -#include "plugins/plugin_abi.h" - -#include <iostream> - -//----------------------------------------------------------------------------- -// Purpose: Returns true if this is a command -// Output : bool -//----------------------------------------------------------------------------- -bool ConCommand::IsCommand(void) const -{ - return true; -} - -//----------------------------------------------------------------------------- -// Purpose: Returns true if this is a command -// Output : bool -//----------------------------------------------------------------------------- -bool ConCommandBase::IsCommand(void) const -{ - return true; -} - -//----------------------------------------------------------------------------- -// Purpose: Has this cvar been registered -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -bool ConCommandBase::IsRegistered(void) const -{ - return m_bRegistered; -} - -//----------------------------------------------------------------------------- -// Purpose: Test each ConCommand query before execution. -// Input : *pCommandBase - nFlags -// Output : False if execution is permitted, true if not. -//----------------------------------------------------------------------------- -bool ConCommandBase::IsFlagSet(int nFlags) const -{ - return m_nFlags & nFlags; -} - -//----------------------------------------------------------------------------- -// Purpose: Checks if ConCommand has requested flags. -// Input : nFlags - -// Output : True if ConCommand has nFlags. -//----------------------------------------------------------------------------- -bool ConCommandBase::HasFlags(int nFlags) -{ - return m_nFlags & nFlags; -} - -//----------------------------------------------------------------------------- -// Purpose: Add's flags to ConCommand. -// Input : nFlags - -//----------------------------------------------------------------------------- -void ConCommandBase::AddFlags(int nFlags) -{ - m_nFlags |= nFlags; -} - -//----------------------------------------------------------------------------- -// Purpose: Removes flags from ConCommand. -// Input : nFlags - -//----------------------------------------------------------------------------- -void ConCommandBase::RemoveFlags(int nFlags) -{ - m_nFlags &= ~nFlags; -} - -//----------------------------------------------------------------------------- -// Purpose: Returns current flags. -// Output : int -//----------------------------------------------------------------------------- -int ConCommandBase::GetFlags(void) const -{ - return m_nFlags; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : const ConCommandBase -//----------------------------------------------------------------------------- -ConCommandBase* ConCommandBase::GetNext(void) const -{ - return m_pNext; -} - -//----------------------------------------------------------------------------- -// Purpose: Returns the ConCommandBase help text. -// Output : const char* -//----------------------------------------------------------------------------- -const char* ConCommandBase::GetHelpText(void) const -{ - return m_pszHelpString; -} - -//----------------------------------------------------------------------------- -// Purpose: Copies string using local new/delete operators -// Input : *szFrom - -// Output : char -//----------------------------------------------------------------------------- -char* ConCommandBase::CopyString(const char* szFrom) const -{ - size_t nLen; - char* szTo; - - nLen = strlen(szFrom); - if (nLen <= 0) - { - szTo = new char[1]; - szTo[0] = 0; - } - else - { - szTo = new char[nLen + 1]; - memmove(szTo, szFrom, nLen + 1); - } - return szTo; -} - -typedef void (*ConCommandConstructorType)( - ConCommand* newCommand, const char* name, FnCommandCallback_t callback, const char* helpString, int flags, void* parent); -ConCommandConstructorType ConCommandConstructor; - -void RegisterConCommand(const char* name, FnCommandCallback_t callback, const char* helpString, int flags) -{ - spdlog::info("Registering ConCommand {}", name); - - // no need to free this ever really, it should exist as long as game does - ConCommand* newCommand = new ConCommand; - ConCommandConstructor(newCommand, name, callback, helpString, flags, nullptr); -} - -void RegisterConCommand( - const char* name, FnCommandCallback_t callback, const char* helpString, int flags, FnCommandCompletionCallback completionCallback) -{ - spdlog::info("Registering ConCommand {}", name); - - // no need to free this ever really, it should exist as long as game does - ConCommand* newCommand = new ConCommand; - ConCommandConstructor(newCommand, name, callback, helpString, flags, nullptr); - newCommand->m_pCompletionCallback = completionCallback; -} - -ON_DLL_LOAD("engine.dll", ConCommand, (CModule module)) -{ - ConCommandConstructor = module.Offset(0x415F60).RCast<ConCommandConstructorType>(); - AddMiscConCommands(); - - g_pPluginCommunicationhandler->m_sEngineData.ConCommandConstructor = - reinterpret_cast<PluginConCommandConstructorType>(ConCommandConstructor); -} diff --git a/NorthstarDLL/core/convar/concommand.h b/NorthstarDLL/core/convar/concommand.h deleted file mode 100644 index 71a82fec..00000000 --- a/NorthstarDLL/core/convar/concommand.h +++ /dev/null @@ -1,139 +0,0 @@ -#pragma once - -// From Source SDK -class ConCommandBase; -class IConCommandBaseAccessor -{ -public: - // Flags is a combination of FCVAR flags in cvar.h. - // hOut is filled in with a handle to the variable. - virtual bool RegisterConCommandBase(ConCommandBase* pVar) = 0; -}; - -class CCommand -{ -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 - - static int MaxCommandLength(); - -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]; -}; - -inline int CCommand::MaxCommandLength() -{ - return COMMAND_MAX_LENGTH - 1; -} -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::ArgS() const -{ - return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : ""; -} -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]; -} -inline const char* CCommand::operator[](int nIndex) const -{ - return Arg(nIndex); -} - -//----------------------------------------------------------------------------- -// Called when a ConCommand needs to execute -//----------------------------------------------------------------------------- -typedef void (*FnCommandCallback_t)(const CCommand& command); - -#define COMMAND_COMPLETION_MAXITEMS 64 -#define COMMAND_COMPLETION_ITEM_LENGTH 128 - -//----------------------------------------------------------------------------- -// Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings -//----------------------------------------------------------------------------- -typedef int (*FnCommandCompletionCallback)(const char* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]); - -// From r5reloaded -class ConCommandBase -{ -public: - bool HasFlags(int nFlags); - void AddFlags(int nFlags); - void RemoveFlags(int nFlags); - - bool IsCommand(void) const; - bool IsRegistered(void) const; - bool IsFlagSet(int nFlags) const; - static bool IsFlagSet(ConCommandBase* pCommandBase, int nFlags); // For hooking to engine's implementation. - - int GetFlags(void) const; - ConCommandBase* GetNext(void) const; - const char* GetHelpText(void) const; - - char* CopyString(const char* szFrom) const; - - void* m_pConCommandBaseVTable; // 0x0000 - ConCommandBase* m_pNext; // 0x0008 - bool m_bRegistered; // 0x0010 - char pad_0011[7]; // 0x0011 <- 3 bytes padding + unk int32. - const char* m_pszName; // 0x0018 - const char* m_pszHelpString; // 0x0020 - int m_nFlags; // 0x0028 - ConCommandBase* s_pConCommandBases; // 0x002C - IConCommandBaseAccessor* s_pAccessor; // 0x0034 -}; // Size: 0x0040 - -// taken from ttf2sdk -class ConCommand : public ConCommandBase -{ - friend class CCVar; - -public: - ConCommand(void) {}; // !TODO: Rebuild engine constructor in SDK instead. - ConCommand(const char* szName, const char* szHelpString, int nFlags, void* pCallback, void* pCommandCompletionCallback); - void Init(void); - bool IsCommand(void) const; - - FnCommandCallback_t m_pCommandCallback {}; // 0x0040 <- starts from 0x40 since we inherit ConCommandBase. - FnCommandCompletionCallback m_pCompletionCallback {}; // 0x0048 <- defaults to sub_180417410 ('xor eax, eax'). - int m_nCallbackFlags {}; // 0x0050 - char pad_0054[4]; // 0x0054 - int unk0; // 0x0058 - int unk1; // 0x005C -}; // Size: 0x0060 - -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, FnCommandCompletionCallback completionCallback); diff --git a/NorthstarDLL/core/convar/convar.cpp b/NorthstarDLL/core/convar/convar.cpp deleted file mode 100644 index e77ae1fd..00000000 --- a/NorthstarDLL/core/convar/convar.cpp +++ /dev/null @@ -1,534 +0,0 @@ -#include "bits.h" -#include "cvar.h" -#include "convar.h" -#include "core/sourceinterface.h" - -#include "plugins/pluginbackend.h" -#include "plugins/plugin_abi.h" - -#include <float.h> - -typedef void (*ConVarRegisterType)( - ConVar* pConVar, - const char* pszName, - const char* pszDefaultValue, - int nFlags, - const char* pszHelpString, - bool bMin, - float fMin, - bool bMax, - float fMax, - void* pCallback); -ConVarRegisterType conVarRegister; - -typedef void (*ConVarMallocType)(void* pConVarMaloc, int a2, int a3); -ConVarMallocType conVarMalloc; - -void* g_pConVar_Vtable = nullptr; -void* g_pIConVar_Vtable = nullptr; - -//----------------------------------------------------------------------------- -// Purpose: ConVar interface initialization -//----------------------------------------------------------------------------- -ON_DLL_LOAD("engine.dll", ConVar, (CModule module)) -{ - conVarMalloc = module.Offset(0x415C20).RCast<ConVarMallocType>(); - conVarRegister = module.Offset(0x417230).RCast<ConVarRegisterType>(); - - g_pConVar_Vtable = module.Offset(0x67FD28); - g_pIConVar_Vtable = module.Offset(0x67FDC8); - - g_pCVarInterface = new SourceInterface<CCvar>("vstdlib.dll", "VEngineCvar007"); - g_pCVar = *g_pCVarInterface; - - g_pPluginCommunicationhandler->m_sEngineData.conVarMalloc = reinterpret_cast<PluginConVarMallocType>(conVarMalloc); - g_pPluginCommunicationhandler->m_sEngineData.conVarRegister = reinterpret_cast<PluginConVarRegisterType>(conVarRegister); - g_pPluginCommunicationhandler->m_sEngineData.ConVar_Vtable = reinterpret_cast<void*>(g_pConVar_Vtable); - g_pPluginCommunicationhandler->m_sEngineData.IConVar_Vtable = reinterpret_cast<void*>(g_pIConVar_Vtable); - g_pPluginCommunicationhandler->m_sEngineData.g_pCVar = reinterpret_cast<void*>(g_pCVar); -} - -//----------------------------------------------------------------------------- -// Purpose: constructor -//----------------------------------------------------------------------------- -ConVar::ConVar(const char* pszName, const char* pszDefaultValue, int nFlags, const char* pszHelpString) -{ - spdlog::info("Registering Convar {}", pszName); - - this->m_ConCommandBase.m_pConCommandBaseVTable = g_pConVar_Vtable; - this->m_ConCommandBase.s_pConCommandBases = (ConCommandBase*)g_pIConVar_Vtable; - - conVarMalloc(&this->m_pMalloc, 0, 0); // Allocate new memory for ConVar. - conVarRegister(this, pszName, pszDefaultValue, nFlags, pszHelpString, 0, 0, 0, 0, 0); -} - -//----------------------------------------------------------------------------- -// Purpose: constructor -//----------------------------------------------------------------------------- -ConVar::ConVar( - const char* pszName, - const char* pszDefaultValue, - int nFlags, - const char* pszHelpString, - bool bMin, - float fMin, - bool bMax, - float fMax, - FnChangeCallback_t pCallback) -{ - spdlog::info("Registering Convar {}", pszName); - - this->m_ConCommandBase.m_pConCommandBaseVTable = g_pConVar_Vtable; - this->m_ConCommandBase.s_pConCommandBases = (ConCommandBase*)g_pIConVar_Vtable; - - conVarMalloc(&this->m_pMalloc, 0, 0); // Allocate new memory for ConVar. - conVarRegister(this, pszName, pszDefaultValue, nFlags, pszHelpString, bMin, fMin, bMax, fMax, (void*)pCallback); -} - -//----------------------------------------------------------------------------- -// Purpose: destructor -//----------------------------------------------------------------------------- -ConVar::~ConVar(void) -{ - if (m_Value.m_pszString) - delete[] m_Value.m_pszString; -} - -//----------------------------------------------------------------------------- -// Purpose: Returns the base ConVar name. -// Output : const char* -//----------------------------------------------------------------------------- -const char* ConVar::GetBaseName(void) const -{ - return m_ConCommandBase.m_pszName; -} - -//----------------------------------------------------------------------------- -// Purpose: Returns the ConVar help text. -// Output : const char* -//----------------------------------------------------------------------------- -const char* ConVar::GetHelpText(void) const -{ - return m_ConCommandBase.m_pszHelpString; -} - -//----------------------------------------------------------------------------- -// Purpose: Add's flags to ConVar. -// Input : nFlags - -//----------------------------------------------------------------------------- -void ConVar::AddFlags(int nFlags) -{ - m_ConCommandBase.m_nFlags |= nFlags; -} - -//----------------------------------------------------------------------------- -// Purpose: Removes flags from ConVar. -// Input : nFlags - -//----------------------------------------------------------------------------- -void ConVar::RemoveFlags(int nFlags) -{ - m_ConCommandBase.m_nFlags &= ~nFlags; -} - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as a boolean. -// Output : bool -//----------------------------------------------------------------------------- -bool ConVar::GetBool(void) const -{ - return !!GetInt(); -} - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as a float. -// Output : float -//----------------------------------------------------------------------------- -float ConVar::GetFloat(void) const -{ - return m_Value.m_fValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as an integer. -// Output : int -//----------------------------------------------------------------------------- -int ConVar::GetInt(void) const -{ - return m_Value.m_nValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as a color. -// Output : Color -//----------------------------------------------------------------------------- -Color ConVar::GetColor(void) const -{ - unsigned char* pColorElement = ((unsigned char*)&m_Value.m_nValue); - return Color(pColorElement[0], pColorElement[1], pColorElement[2], pColorElement[3]); -} - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as a string. -// Output : const char * -//----------------------------------------------------------------------------- -const char* ConVar::GetString(void) const -{ - if (m_ConCommandBase.m_nFlags & FCVAR_NEVER_AS_STRING) - { - return "FCVAR_NEVER_AS_STRING"; - } - - char const* str = m_Value.m_pszString; - return str ? str : ""; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : flMinVal - -// Output : true if there is a min set. -//----------------------------------------------------------------------------- -bool ConVar::GetMin(float& flMinVal) const -{ - flMinVal = m_fMinVal; - return m_bHasMin; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : flMaxVal - -// Output : true if there is a max set. -//----------------------------------------------------------------------------- -bool ConVar::GetMax(float& flMaxVal) const -{ - flMaxVal = m_fMaxVal; - return m_bHasMax; -} - -//----------------------------------------------------------------------------- -// Purpose: returns the min value. -// Output : float -//----------------------------------------------------------------------------- -float ConVar::GetMinValue(void) const -{ - return m_fMinVal; -} - -//----------------------------------------------------------------------------- -// Purpose: returns the max value. -// Output : float -//----------------------------------------------------------------------------- -float ConVar::GetMaxValue(void) const -{ - return m_fMaxVal; - ; -} - -//----------------------------------------------------------------------------- -// Purpose: checks if ConVar has min value. -// Output : bool -//----------------------------------------------------------------------------- -bool ConVar::HasMin(void) const -{ - return m_bHasMin; -} - -//----------------------------------------------------------------------------- -// Purpose: checks if ConVar has max value. -// Output : bool -//----------------------------------------------------------------------------- -bool ConVar::HasMax(void) const -{ - return m_bHasMax; -} - -//----------------------------------------------------------------------------- -// Purpose: sets the ConVar int value. -// Input : nValue - -//----------------------------------------------------------------------------- -void ConVar::SetValue(int nValue) -{ - if (nValue == m_Value.m_nValue) - { - return; - } - - float flValue = (float)nValue; - - // Check bounds. - if (ClampValue(flValue)) - { - nValue = (int)(flValue); - } - - // Redetermine value. - float flOldValue = m_Value.m_fValue; - m_Value.m_fValue = flValue; - m_Value.m_nValue = nValue; - - if (!(m_ConCommandBase.m_nFlags & FCVAR_NEVER_AS_STRING)) - { - char szTempValue[32]; - snprintf(szTempValue, sizeof(szTempValue), "%d", m_Value.m_nValue); - ChangeStringValue(szTempValue, flOldValue); - } -} - -//----------------------------------------------------------------------------- -// Purpose: sets the ConVar float value. -// Input : flValue - -//----------------------------------------------------------------------------- -void ConVar::SetValue(float flValue) -{ - if (flValue == m_Value.m_fValue) - { - return; - } - - // Check bounds. - ClampValue(flValue); - - // Redetermine value. - float flOldValue = m_Value.m_fValue; - m_Value.m_fValue = flValue; - m_Value.m_nValue = (int)m_Value.m_fValue; - - if (!(m_ConCommandBase.m_nFlags & FCVAR_NEVER_AS_STRING)) - { - char szTempValue[32]; - snprintf(szTempValue, sizeof(szTempValue), "%f", m_Value.m_fValue); - ChangeStringValue(szTempValue, flOldValue); - } -} - -//----------------------------------------------------------------------------- -// Purpose: sets the ConVar string value. -// Input : *szValue - -//----------------------------------------------------------------------------- -void ConVar::SetValue(const char* pszValue) -{ - if (strcmp(this->m_Value.m_pszString, pszValue) == 0) - return; - - char szTempValue[32] {}; - const char* pszNewValue {}; - - float flOldValue = m_Value.m_fValue; - pszNewValue = (char*)pszValue; - if (!pszNewValue) - { - pszNewValue = ""; - } - - if (!SetColorFromString(pszValue)) - { - // Not a color, do the standard thing - float flNewValue = (float)atof(pszValue); - if (!std::isfinite(flNewValue)) - { - spdlog::warn("Warning: ConVar '{}' = '{}' is infinite, clamping value.\n", GetBaseName(), pszValue); - flNewValue = FLT_MAX; - } - - if (ClampValue(flNewValue)) - { - snprintf(szTempValue, sizeof(szTempValue), "%f", flNewValue); - pszNewValue = szTempValue; - } - - // Redetermine value - m_Value.m_fValue = flNewValue; - m_Value.m_nValue = (int)(m_Value.m_fValue); - } - - if (!(m_ConCommandBase.m_nFlags & FCVAR_NEVER_AS_STRING)) - { - ChangeStringValue(pszNewValue, flOldValue); - } -} - -//----------------------------------------------------------------------------- -// Purpose: sets the ConVar color value. -// Input : clValue - -//----------------------------------------------------------------------------- -void ConVar::SetValue(Color clValue) -{ - std::string svResult = ""; - - for (int i = 0; i < 4; i++) - { - if (!(clValue.GetValue(i) == 0 && svResult.size() == 0)) - { - svResult += std::to_string(clValue.GetValue(i)); - svResult.append(" "); - } - } - - this->m_Value.m_pszString = svResult.c_str(); -} - -//----------------------------------------------------------------------------- -// Purpose: changes the ConVar string value. -// Input : *pszTempVal - flOldValue -//----------------------------------------------------------------------------- -void ConVar::ChangeStringValue(const char* pszTempVal, float flOldValue) -{ - assert(!(m_ConCommandBase.m_nFlags & FCVAR_NEVER_AS_STRING)); - - char* pszOldValue = (char*)_malloca(m_Value.m_iStringLength); - if (pszOldValue != NULL) - { - memcpy(pszOldValue, m_Value.m_pszString, m_Value.m_iStringLength); - } - - if (pszTempVal) - { - int len = strlen(pszTempVal) + 1; - - if (len > m_Value.m_iStringLength) - { - if (m_Value.m_pszString) - delete[] m_Value.m_pszString; - - m_Value.m_pszString = new char[len]; - m_Value.m_iStringLength = len; - } - - memcpy((char*)m_Value.m_pszString, pszTempVal, len); - } - else - { - m_Value.m_pszString = NULL; - } - - pszOldValue = 0; -} - -//----------------------------------------------------------------------------- -// Purpose: sets the ConVar color value from string. -// Input : *pszValue - -//----------------------------------------------------------------------------- -bool ConVar::SetColorFromString(const char* pszValue) -{ - bool bColor = false; - - // Try pulling RGBA color values out of the string. - int nRGBA[4] {}; - int nParamsRead = sscanf_s(pszValue, "%i %i %i %i", &(nRGBA[0]), &(nRGBA[1]), &(nRGBA[2]), &(nRGBA[3])); - - if (nParamsRead >= 3) - { - // This is probably a color! - if (nParamsRead == 3) - { - // Assume they wanted full alpha. - nRGBA[3] = 255; - } - - if (nRGBA[0] >= 0 && nRGBA[0] <= 255 && nRGBA[1] >= 0 && nRGBA[1] <= 255 && nRGBA[2] >= 0 && nRGBA[2] <= 255 && nRGBA[3] >= 0 && - nRGBA[3] <= 255) - { - // printf("*** WOW! Found a color!! ***\n"); - - // This is definitely a color! - bColor = true; - - // Stuff all the values into each byte of our int. - unsigned char* pColorElement = ((unsigned char*)&m_Value.m_nValue); - pColorElement[0] = nRGBA[0]; - pColorElement[1] = nRGBA[1]; - pColorElement[2] = nRGBA[2]; - pColorElement[3] = nRGBA[3]; - - // Copy that value into our float. - m_Value.m_fValue = (float)(m_Value.m_nValue); - } - } - - return bColor; -} - -//----------------------------------------------------------------------------- -// Purpose: Checks if ConVar is registered. -// Output : bool -//----------------------------------------------------------------------------- -bool ConVar::IsRegistered(void) const -{ - return m_ConCommandBase.m_bRegistered; -} - -//----------------------------------------------------------------------------- -// Purpose: Returns true if this is a command -// Output : bool -//----------------------------------------------------------------------------- -bool ConVar::IsCommand(void) const -{ - return false; -} - -//----------------------------------------------------------------------------- -// Purpose: Test each ConVar query before setting the value. -// Input : nFlags -// Output : False if change is permitted, true if not. -//----------------------------------------------------------------------------- -bool ConVar::IsFlagSet(int nFlags) const -{ - return m_ConCommandBase.m_nFlags & nFlags; -} - -//----------------------------------------------------------------------------- -// Purpose: Check whether to clamp and then perform clamp. -// Input : flValue - -// Output : Returns true if value changed. -//----------------------------------------------------------------------------- -bool ConVar::ClampValue(float& flValue) -{ - if (m_bHasMin && (flValue < m_fMinVal)) - { - flValue = m_fMinVal; - return true; - } - - if (m_bHasMax && (flValue > m_fMaxVal)) - { - flValue = m_fMaxVal; - return true; - } - - return false; -} - -int ParseConVarFlagsString(std::string modName, std::string sFlags) -{ - int iFlags = 0; - std::stringstream stFlags(sFlags); - std::string sFlag; - - while (std::getline(stFlags, sFlag, '|')) - { - // trim the flag - sFlag.erase(sFlag.find_last_not_of(" \t\n\f\v\r") + 1); - sFlag.erase(0, sFlag.find_first_not_of(" \t\n\f\v\r")); - - // skip if empty - if (sFlag.empty()) - continue; - - // find the matching flag value - bool ok = false; - for (auto const& flagPair : g_PrintCommandFlags) - { - if (sFlag == flagPair.second) - { - iFlags |= flagPair.first; - ok = true; - break; - } - } - if (!ok) - { - spdlog::warn("Mod ConCommand {} has unknown flag {}", modName, sFlag); - } - } - - return iFlags; -} diff --git a/NorthstarDLL/core/convar/convar.h b/NorthstarDLL/core/convar/convar.h deleted file mode 100644 index f0366b46..00000000 --- a/NorthstarDLL/core/convar/convar.h +++ /dev/null @@ -1,194 +0,0 @@ -#pragma once -#include "core/sourceinterface.h" -#include "core/math/color.h" -#include "cvar.h" -#include "concommand.h" - -// taken directly from iconvar.h - -// The default, no flags at all -#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. - -// 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_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_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). - -// !!!NOTE!!! : this is likely incorrect, there are multiple concommands that the vanilla game registers with this flag that 100% should not -// be remotely executable i.e. multiple commands that only exist on client (screenshot, joystick_initialize) we now use -// FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS in all places this flag was previously used -#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 - -// TODO: could be cool to repurpose these for northstar use somehow? -// #define FCVAR_AVAILABLE (1<<26) -// #define FCVAR_AVAILABLE (1<<27) -// #define FCVAR_AVAILABLE (1<<31) - -// flag => string stuff -const std::multimap<int, const char*> g_PrintCommandFlags = { - {FCVAR_UNREGISTERED, "UNREGISTERED"}, - {FCVAR_DEVELOPMENTONLY, "DEVELOPMENTONLY"}, - {FCVAR_GAMEDLL, "GAMEDLL"}, - {FCVAR_CLIENTDLL, "CLIENTDLL"}, - {FCVAR_HIDDEN, "HIDDEN"}, - {FCVAR_PROTECTED, "PROTECTED"}, - {FCVAR_SPONLY, "SPONLY"}, - {FCVAR_ARCHIVE, "ARCHIVE"}, - {FCVAR_NOTIFY, "NOTIFY"}, - {FCVAR_USERINFO, "USERINFO"}, - - // TODO: PRINTABLEONLY and GAMEDLL_FOR_REMOTE_CLIENTS are both 1<<10, one is for vars and one is for commands - // this fucking sucks i think - {FCVAR_PRINTABLEONLY, "PRINTABLEONLY"}, - {FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS, "GAMEDLL_FOR_REMOTE_CLIENTS"}, - - {FCVAR_UNLOGGED, "UNLOGGED"}, - {FCVAR_NEVER_AS_STRING, "NEVER_AS_STRING"}, - {FCVAR_REPLICATED, "REPLICATED"}, - {FCVAR_CHEAT, "CHEAT"}, - {FCVAR_SS, "SS"}, - {FCVAR_DEMO, "DEMO"}, - {FCVAR_DONTRECORD, "DONTRECORD"}, - {FCVAR_SS_ADDED, "SS_ADDED"}, - {FCVAR_RELEASE, "RELEASE"}, - {FCVAR_RELOAD_MATERIALS, "RELOAD_MATERIALS"}, - {FCVAR_RELOAD_TEXTURES, "RELOAD_TEXTURES"}, - {FCVAR_NOT_CONNECTED, "NOT_CONNECTED"}, - {FCVAR_MATERIAL_SYSTEM_THREAD, "MATERIAL_SYSTEM_THREAD"}, - {FCVAR_ARCHIVE_PLAYERPROFILE, "ARCHIVE_PLAYERPROFILE"}, - {FCVAR_SERVER_CAN_EXECUTE, "SERVER_CAN_EXECUTE"}, - {FCVAR_SERVER_CANNOT_QUERY, "SERVER_CANNOT_QUERY"}, - {FCVAR_CLIENTCMD_CAN_EXECUTE, "UNKNOWN"}, - {FCVAR_ACCESSIBLE_FROM_THREADS, "ACCESSIBLE_FROM_THREADS"}}; - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -class ConCommandBase; -class ConCommand; -class ConVar; - -typedef void (*FnChangeCallback_t)(ConVar* var, const char* pOldValue, float flOldValue); - -//----------------------------------------------------------------------------- -// Purpose: A console variable -//----------------------------------------------------------------------------- -class ConVar -{ -public: - ConVar(void) {}; - ConVar(const char* pszName, const char* pszDefaultValue, int nFlags, const char* pszHelpString); - ConVar( - const char* pszName, - const char* pszDefaultValue, - int nFlags, - const char* pszHelpString, - bool bMin, - float fMin, - bool bMax, - float fMax, - FnChangeCallback_t pCallback); - ~ConVar(void); - - const char* GetBaseName(void) const; - const char* GetHelpText(void) const; - - void AddFlags(int nFlags); - void RemoveFlags(int nFlags); - - bool GetBool(void) const; - float GetFloat(void) const; - int GetInt(void) const; - Color GetColor(void) const; - const char* GetString(void) const; - - bool GetMin(float& flMinValue) const; - bool GetMax(float& flMaxValue) const; - float GetMinValue(void) const; - float GetMaxValue(void) const; - - bool HasMin(void) const; - bool HasMax(void) const; - - void SetValue(int nValue); - void SetValue(float flValue); - void SetValue(const char* pszValue); - void SetValue(Color clValue); - - void ChangeStringValue(const char* pszTempValue, float flOldValue); - bool SetColorFromString(const char* pszValue); - bool ClampValue(float& value); - - bool IsRegistered(void) const; - bool IsCommand(void) const; - bool IsFlagSet(int nFlags) const; - - struct CVValue_t - { - const char* m_pszString; - int64_t m_iStringLength; - float m_fValue; - int m_nValue; - }; - - ConCommandBase m_ConCommandBase {}; // 0x0000 - const char* m_pszDefaultValue {}; // 0x0040 - CVValue_t m_Value {}; // 0x0048 - bool m_bHasMin {}; // 0x005C - float m_fMinVal {}; // 0x0060 - bool m_bHasMax {}; // 0x0064 - float m_fMaxVal {}; // 0x0068 - void* m_pMalloc {}; // 0x0070 - char m_pPad80[10] {}; // 0x0080 -}; // Size: 0x0080 - -int ParseConVarFlagsString(std::string modName, std::string flags); diff --git a/NorthstarDLL/core/convar/cvar.cpp b/NorthstarDLL/core/convar/cvar.cpp deleted file mode 100644 index aa5f0365..00000000 --- a/NorthstarDLL/core/convar/cvar.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "cvar.h" -#include "convar.h" -#include "concommand.h" - -//----------------------------------------------------------------------------- -// Purpose: returns all ConVars -//----------------------------------------------------------------------------- -std::unordered_map<std::string, ConCommandBase*> CCvar::DumpToMap() -{ - std::stringstream ss; - CCVarIteratorInternal* itint = FactoryInternalIterator(); // Allocate new InternalIterator. - - std::unordered_map<std::string, ConCommandBase*> allConVars; - - for (itint->SetFirst(); itint->IsValid(); itint->Next()) // Loop through all instances. - { - ConCommandBase* pCommand = itint->Get(); - const char* pszCommandName = pCommand->m_pszName; - allConVars[pszCommandName] = pCommand; - } - - return allConVars; -} - -SourceInterface<CCvar>* g_pCVarInterface; -CCvar* g_pCVar; diff --git a/NorthstarDLL/core/convar/cvar.h b/NorthstarDLL/core/convar/cvar.h deleted file mode 100644 index beaa84f4..00000000 --- a/NorthstarDLL/core/convar/cvar.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once -#include "convar.h" - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -class ConCommandBase; -class ConCommand; -class ConVar; - -//----------------------------------------------------------------------------- -// Internals for ICVarIterator -//----------------------------------------------------------------------------- -class CCVarIteratorInternal // Fully reversed table, just look at the virtual function table and rename the function. -{ -public: - virtual void SetFirst(void) = 0; // 0 - virtual void Next(void) = 0; // 1 - virtual bool IsValid(void) = 0; // 2 - virtual ConCommandBase* Get(void) = 0; // 3 -}; - -//----------------------------------------------------------------------------- -// Default implementation -//----------------------------------------------------------------------------- -class CCvar -{ -public: - M_VMETHOD(ConCommandBase*, FindCommandBase, 14, (const char* pszCommandName), (this, pszCommandName)); - M_VMETHOD(ConVar*, FindVar, 16, (const char* pszVarName), (this, pszVarName)); - M_VMETHOD(ConCommand*, FindCommand, 18, (const char* pszCommandName), (this, pszCommandName)); - M_VMETHOD(CCVarIteratorInternal*, FactoryInternalIterator, 41, (), (this)); - - std::unordered_map<std::string, ConCommandBase*> DumpToMap(); -}; - -extern SourceInterface<CCvar>* g_pCVarInterface; -extern CCvar* g_pCVar; diff --git a/NorthstarDLL/core/filesystem/filesystem.cpp b/NorthstarDLL/core/filesystem/filesystem.cpp deleted file mode 100644 index b39939e4..00000000 --- a/NorthstarDLL/core/filesystem/filesystem.cpp +++ /dev/null @@ -1,177 +0,0 @@ -#include "filesystem.h" -#include "core/sourceinterface.h" -#include "mods/modmanager.h" - -#include <iostream> -#include <sstream> - -AUTOHOOK_INIT() - -bool bReadingOriginalFile = false; -std::string sCurrentModPath; - -ConVar* Cvar_ns_fs_log_reads; - -SourceInterface<IFileSystem>* g_pFilesystem; - -std::string ReadVPKFile(const char* path) -{ - // read scripts.rson file, todo: check if this can be overwritten - FileHandle_t fileHandle = (*g_pFilesystem)->m_vtable2->Open(&(*g_pFilesystem)->m_vtable2, path, "rb", "GAME", 0); - - std::stringstream fileStream; - int bytesRead = 0; - char data[4096]; - do - { - bytesRead = (*g_pFilesystem)->m_vtable2->Read(&(*g_pFilesystem)->m_vtable2, data, (int)std::size(data), fileHandle); - fileStream.write(data, bytesRead); - } while (bytesRead == std::size(data)); - - (*g_pFilesystem)->m_vtable2->Close(*g_pFilesystem, fileHandle); - - return fileStream.str(); -} - -std::string ReadVPKOriginalFile(const char* path) -{ - // todo: should probably set search path to be g_pModName here also - - bReadingOriginalFile = true; - std::string ret = ReadVPKFile(path); - bReadingOriginalFile = false; - - return ret; -} - -// clang-format off -HOOK(AddSearchPathHook, AddSearchPath, -void, __fastcall, (IFileSystem * fileSystem, const char* pPath, const char* pathID, SearchPathAdd_t addType)) -// clang-format on -{ - AddSearchPath(fileSystem, pPath, pathID, addType); - - // make sure current mod paths are at head - if (!strcmp(pathID, "GAME") && sCurrentModPath.compare(pPath) && addType == PATH_ADD_TO_HEAD) - { - AddSearchPath(fileSystem, sCurrentModPath.c_str(), "GAME", PATH_ADD_TO_HEAD); - AddSearchPath(fileSystem, GetCompiledAssetsPath().string().c_str(), "GAME", PATH_ADD_TO_HEAD); - } -} - -void SetNewModSearchPaths(Mod* mod) -{ - // put our new path to the head if we need to read from a different mod path - // in the future we could also determine whether the file we're setting paths for needs a mod dir, or compiled assets - if (mod != nullptr) - { - if ((fs::absolute(mod->m_ModDirectory) / MOD_OVERRIDE_DIR).string().compare(sCurrentModPath)) - { - AddSearchPath( - &*(*g_pFilesystem), (fs::absolute(mod->m_ModDirectory) / MOD_OVERRIDE_DIR).string().c_str(), "GAME", PATH_ADD_TO_HEAD); - sCurrentModPath = (fs::absolute(mod->m_ModDirectory) / MOD_OVERRIDE_DIR).string(); - } - } - else // push compiled to head - AddSearchPath(&*(*g_pFilesystem), fs::absolute(GetCompiledAssetsPath()).string().c_str(), "GAME", PATH_ADD_TO_HEAD); -} - -bool TryReplaceFile(const char* pPath, bool shouldCompile) -{ - if (bReadingOriginalFile) - return false; - - if (shouldCompile) - g_pModManager->CompileAssetsForFile(pPath); - - // idk how efficient the lexically normal check is - // can't just set all /s in path to \, since some paths aren't in writeable memory - auto file = g_pModManager->m_ModFiles.find(g_pModManager->NormaliseModFilePath(fs::path(pPath))); - if (file != g_pModManager->m_ModFiles.end()) - { - SetNewModSearchPaths(file->second.m_pOwningMod); - return true; - } - - return false; -} - -// force modded files to be read from mods, not cache -// clang-format off -HOOK(ReadFromCacheHook, ReadFromCache, -bool, __fastcall, (IFileSystem * filesystem, char* pPath, void* result)) -// clang-format off -{ - if (TryReplaceFile(pPath, true)) - return false; - - return ReadFromCache(filesystem, pPath, result); -} - -// force modded files to be read from mods, not vpk -// clang-format off -AUTOHOOK(ReadFileFromVPK, filesystem_stdio.dll + 0x5CBA0, -FileHandle_t, __fastcall, (VPKData* vpkInfo, uint64_t* b, char* filename)) -// clang-format on -{ - // don't compile here because this is only ever called from OpenEx, which already compiles - if (TryReplaceFile(filename, false)) - { - *b = -1; - return b; - } - - return ReadFileFromVPK(vpkInfo, b, filename); -} - -// clang-format off -AUTOHOOK(CBaseFileSystem__OpenEx, filesystem_stdio.dll + 0x15F50, -FileHandle_t, __fastcall, (IFileSystem* filesystem, const char* pPath, const char* pOptions, uint32_t flags, const char* pPathID, char **ppszResolvedFilename)) -// clang-format on -{ - TryReplaceFile(pPath, true); - return CBaseFileSystem__OpenEx(filesystem, pPath, pOptions, flags, pPathID, ppszResolvedFilename); -} - -HOOK(MountVPKHook, MountVPK, VPKData*, , (IFileSystem * fileSystem, const char* pVpkPath)) -{ - NS::log::fs->info("MountVPK {}", pVpkPath); - VPKData* ret = MountVPK(fileSystem, pVpkPath); - - for (Mod mod : g_pModManager->m_LoadedMods) - { - if (!mod.m_bEnabled) - continue; - - for (ModVPKEntry& vpkEntry : mod.Vpks) - { - // if we're autoloading, just load no matter what - if (!vpkEntry.m_bAutoLoad) - { - // resolve vpk name and try to load one with the same name - // todo: we should be unloading these on map unload manually - std::string mapName(fs::path(pVpkPath).filename().string()); - std::string modMapName(fs::path(vpkEntry.m_sVpkPath.c_str()).filename().string()); - if (mapName.compare(modMapName)) - continue; - } - - VPKData* loaded = MountVPK(fileSystem, vpkEntry.m_sVpkPath.c_str()); - if (!ret) // this is primarily for map vpks and stuff, so the map's vpk is what gets returned from here - ret = loaded; - } - } - - return ret; -} - -ON_DLL_LOAD("filesystem_stdio.dll", Filesystem, (CModule module)) -{ - AUTOHOOK_DISPATCH() - - g_pFilesystem = new SourceInterface<IFileSystem>("filesystem_stdio.dll", "VFileSystem017"); - - AddSearchPathHook.Dispatch((LPVOID)(*g_pFilesystem)->m_vtable->AddSearchPath); - ReadFromCacheHook.Dispatch((LPVOID)(*g_pFilesystem)->m_vtable->ReadFromCache); - MountVPKHook.Dispatch((LPVOID)(*g_pFilesystem)->m_vtable->MountVPK); -} diff --git a/NorthstarDLL/core/filesystem/filesystem.h b/NorthstarDLL/core/filesystem/filesystem.h deleted file mode 100644 index fcd1bb2f..00000000 --- a/NorthstarDLL/core/filesystem/filesystem.h +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once -#include "core/sourceinterface.h" - -// taken from ttf2sdk -typedef void* FileHandle_t; - -#pragma pack(push, 1) - -// clang-format off -OFFSET_STRUCT(VPKFileEntry) -{ - STRUCT_SIZE(0x44); - FIELDS(0x0, - char* directory; - char* filename; - char* extension; - ) -}; -// clang-format on -#pragma pack(pop) - -struct VPKData; - -enum SearchPathAdd_t -{ - PATH_ADD_TO_HEAD, // First path searched - PATH_ADD_TO_TAIL, // Last path searched -}; - -class CSearchPath -{ -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); - }; - - 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); - long long (*Seek)(IFileSystem::VTable2** fileSystem, FileHandle_t file, long long offset, long long whence); - void* unknown2[5]; - bool (*FileExists)(IFileSystem::VTable2** fileSystem, const char* pFileName, const char* pPathID); - }; - - VTable* m_vtable; - VTable2* m_vtable2; -}; - -extern SourceInterface<IFileSystem>* g_pFilesystem; - -std::string ReadVPKFile(const char* path); -std::string ReadVPKOriginalFile(const char* path); diff --git a/NorthstarDLL/core/filesystem/rpakfilesystem.cpp b/NorthstarDLL/core/filesystem/rpakfilesystem.cpp deleted file mode 100644 index da72646b..00000000 --- a/NorthstarDLL/core/filesystem/rpakfilesystem.cpp +++ /dev/null @@ -1,347 +0,0 @@ -#include "rpakfilesystem.h" -#include "mods/modmanager.h" -#include "dedicated/dedicated.h" -#include "core/tier0.h" - -AUTOHOOK_INIT() - -// there are more i'm just too lazy to add -struct PakLoadFuncs -{ - void* unk0[3]; - int (*LoadPakAsync)(const char* pPath, void* unknownSingleton, int flags, void* callback0, void* callback1); - void* unk1[2]; - void* (*UnloadPak)(int iPakHandle, void* callback); - void* unk2[6]; - void* (*LoadFile)(const char* path); // unsure - void* unk3[10]; - void* (*ReadFileAsync)(const char* pPath, void* a2); -}; - -PakLoadFuncs* g_pakLoadApi; - -PakLoadManager* g_pPakLoadManager; -void** pUnknownPakLoadSingleton; - -int PakLoadManager::LoadPakAsync(const char* pPath, const ePakLoadSource nLoadSource) -{ - int nHandle = g_pakLoadApi->LoadPakAsync(pPath, *pUnknownPakLoadSingleton, 2, nullptr, nullptr); - - // set the load source of the pak we just loaded - if (nHandle != -1) - GetPakInfo(nHandle)->m_nLoadSource = nLoadSource; - - return nHandle; -} - -void PakLoadManager::UnloadPak(const int nPakHandle) -{ - g_pakLoadApi->UnloadPak(nPakHandle, nullptr); -} - -void PakLoadManager::UnloadMapPaks() -{ - for (auto& pair : m_vLoadedPaks) - if (pair.second.m_nLoadSource == ePakLoadSource::MAP) - UnloadPak(pair.first); -} - -LoadedPak* PakLoadManager::TrackLoadedPak(ePakLoadSource nLoadSource, int nPakHandle, size_t nPakNameHash) -{ - LoadedPak pak; - pak.m_nLoadSource = nLoadSource; - pak.m_nPakHandle = nPakHandle; - pak.m_nPakNameHash = nPakNameHash; - - m_vLoadedPaks.insert(std::make_pair(nPakHandle, pak)); - return &m_vLoadedPaks.at(nPakHandle); -} - -void PakLoadManager::RemoveLoadedPak(int nPakHandle) -{ - m_vLoadedPaks.erase(nPakHandle); -} - -LoadedPak* PakLoadManager::GetPakInfo(const int nPakHandle) -{ - return &m_vLoadedPaks.at(nPakHandle); -} - -int PakLoadManager::GetPakHandle(const size_t nPakNameHash) -{ - for (auto& pair : m_vLoadedPaks) - if (pair.second.m_nPakNameHash == nPakNameHash) - return pair.first; - - return -1; -} - -int PakLoadManager::GetPakHandle(const char* pPath) -{ - return GetPakHandle(STR_HASH(pPath)); -} - -void* PakLoadManager::LoadFile(const char* path) -{ - return g_pakLoadApi->LoadFile(path); -} - -void HandlePakAliases(char** map) -{ - // convert the pak being loaded to it's aliased one, e.g. aliasing mp_hub_timeshift => sp_hub_timeshift - for (int64_t i = g_pModManager->m_LoadedMods.size() - 1; i > -1; i--) - { - Mod* mod = &g_pModManager->m_LoadedMods[i]; - if (!mod->m_bEnabled) - continue; - - if (mod->RpakAliases.find(*map) != mod->RpakAliases.end()) - { - *map = &mod->RpakAliases[*map][0]; - return; - } - } -} - -void LoadPreloadPaks() -{ - // note, loading from ./ is necessary otherwise paks will load from gamedir/r2/paks - for (Mod& mod : g_pModManager->m_LoadedMods) - { - if (!mod.m_bEnabled) - continue; - - // need to get a relative path of mod to mod folder - fs::path modPakPath("./" / mod.m_ModDirectory / "paks"); - - for (ModRpakEntry& pak : mod.Rpaks) - if (pak.m_bAutoLoad) - g_pPakLoadManager->LoadPakAsync((modPakPath / pak.m_sPakName).string().c_str(), ePakLoadSource::CONSTANT); - } -} - -void LoadPostloadPaks(const char* pPath) -{ - // note, loading from ./ is necessary otherwise paks will load from gamedir/r2/paks - for (Mod& mod : g_pModManager->m_LoadedMods) - { - if (!mod.m_bEnabled) - continue; - - // need to get a relative path of mod to mod folder - fs::path modPakPath("./" / mod.m_ModDirectory / "paks"); - - for (ModRpakEntry& pak : mod.Rpaks) - if (pak.m_sLoadAfterPak == pPath) - g_pPakLoadManager->LoadPakAsync((modPakPath / pak.m_sPakName).string().c_str(), ePakLoadSource::CONSTANT); - } -} - -void LoadCustomMapPaks(char** pakName, bool* bNeedToFreePakName) -{ - // whether the vanilla game has this rpak - bool bHasOriginalPak = fs::exists(fs::path("r2/paks/Win64/") / *pakName); - - // note, loading from ./ is necessary otherwise paks will load from gamedir/r2/paks - for (Mod& mod : g_pModManager->m_LoadedMods) - { - if (!mod.m_bEnabled) - continue; - - // need to get a relative path of mod to mod folder - fs::path modPakPath("./" / mod.m_ModDirectory / "paks"); - - for (ModRpakEntry& pak : mod.Rpaks) - { - if (!pak.m_bAutoLoad && !pak.m_sPakName.compare(*pakName)) - { - // if the game doesn't have the original pak, let it handle loading this one as if it was the one it was loading originally - if (!bHasOriginalPak) - { - std::string path = (modPakPath / pak.m_sPakName).string(); - *pakName = new char[path.size() + 1]; - strcpy(*pakName, &path[0]); - (*pakName)[path.size()] = '\0'; - - bHasOriginalPak = true; - *bNeedToFreePakName = - true; // we can't free this memory until we're done with the pak, so let whatever's calling this deal with it - } - else - g_pPakLoadManager->LoadPakAsync((modPakPath / pak.m_sPakName).string().c_str(), ePakLoadSource::MAP); - } - } - } -} - -// clang-format off -HOOK(LoadPakAsyncHook, LoadPakAsync, -int, __fastcall, (char* pPath, void* unknownSingleton, int flags, void* pCallback0, void* pCallback1)) -// clang-format on -{ - HandlePakAliases(&pPath); - - // dont load the pak if it's currently loaded already - size_t nPathHash = STR_HASH(pPath); - if (g_pPakLoadManager->GetPakHandle(nPathHash) != -1) - return -1; - - bool bNeedToFreePakName = false; - - static bool bShouldLoadPaks = true; - if (bShouldLoadPaks) - { - // make a copy of the path for comparing to determine whether we should load this pak on dedi, before it could get overwritten by - // LoadCustomMapPaks - std::string originalPath(pPath); - - // disable preloading while we're doing this - bShouldLoadPaks = false; - - LoadPreloadPaks(); - LoadCustomMapPaks(&pPath, &bNeedToFreePakName); - - bShouldLoadPaks = true; - - // do this after custom paks load and in bShouldLoadPaks so we only ever call this on the root pakload call - // todo: could probably add some way to flag custom paks to not be loaded on dedicated servers in rpak.json - - // dedicated only needs common, common_mp, common_sp, and sp_<map> rpaks - // sp_<map> rpaks contain tutorial ghost data - // sucks to have to load the entire rpak for that but sp was never meant to be done on dedi - if (IsDedicatedServer() && - (CommandLine()->CheckParm("-nopakdedi") || strncmp(&originalPath[0], "common", 6) && strncmp(&originalPath[0], "sp_", 3))) - { - if (bNeedToFreePakName) - delete[] pPath; - - NS::log::rpak->info("Not loading pak {} for dedicated server", originalPath); - return -1; - } - } - - int iPakHandle = LoadPakAsync(pPath, unknownSingleton, flags, pCallback0, pCallback1); - NS::log::rpak->info("LoadPakAsync {} {}", pPath, iPakHandle); - - // trak the pak - g_pPakLoadManager->TrackLoadedPak(ePakLoadSource::UNTRACKED, iPakHandle, nPathHash); - LoadPostloadPaks(pPath); - - if (bNeedToFreePakName) - delete[] pPath; - - return iPakHandle; -} - -// clang-format off -HOOK(UnloadPakHook, UnloadPak, -void*, __fastcall, (int nPakHandle, void* pCallback)) -// clang-format on -{ - // stop tracking the pak - g_pPakLoadManager->RemoveLoadedPak(nPakHandle); - - static bool bShouldUnloadPaks = true; - if (bShouldUnloadPaks) - { - bShouldUnloadPaks = false; - g_pPakLoadManager->UnloadMapPaks(); - bShouldUnloadPaks = true; - } - - NS::log::rpak->info("UnloadPak {}", nPakHandle); - return UnloadPak(nPakHandle, pCallback); -} - -// we hook this exclusively for resolving stbsp paths, but seemingly it's also used for other stuff like vpk, rpak, mprj and starpak loads -// tbh this actually might be for memory mapped files or something, would make sense i think -// clang-format off -HOOK(ReadFileAsyncHook, ReadFileAsync, -void*, __fastcall, (const char* pPath, void* pCallback)) -// clang-format on -{ - fs::path path(pPath); - std::string newPath = ""; - fs::path filename = path.filename(); - - if (path.extension() == ".stbsp") - { - if (IsDedicatedServer()) - return nullptr; - - NS::log::rpak->info("LoadStreamBsp: {}", filename.string()); - - // resolve modded stbsp path so we can load mod stbsps - auto modFile = g_pModManager->m_ModFiles.find(g_pModManager->NormaliseModFilePath(fs::path("maps" / filename))); - if (modFile != g_pModManager->m_ModFiles.end()) - { - newPath = (modFile->second.m_pOwningMod->m_ModDirectory / "mod" / modFile->second.m_Path).string(); - pPath = newPath.c_str(); - } - } - else if (path.extension() == ".starpak") - { - if (IsDedicatedServer()) - return nullptr; - - // code for this is mostly stolen from above - - // unfortunately I can't find a way to get the rpak that is causing this function call, so I have to - // store them on mod init and then compare the current path with the stored paths - - // game adds r2\ to every path, so assume that a starpak path that begins with r2\paks\ is a vanilla one - // modded starpaks will be in the mod's paks folder (but can be in folders within the paks folder) - - // this might look a bit confusing, but its just an iterator over the various directories in a path. - // path.begin() being the first directory, r2 in this case, which is guaranteed anyway, - // so increment the iterator with ++ to get the first actual directory, * just gets the actual value - // then we compare to "paks" to determine if it's a vanilla rpak or not - if (*++path.begin() != "paks") - { - // remove the r2\ from the start used for path lookups - std::string starpakPath = path.string().substr(3); - // hash the starpakPath to compare with stored entries - size_t hashed = STR_HASH(starpakPath); - - // loop through all loaded mods - for (Mod& mod : g_pModManager->m_LoadedMods) - { - // ignore non-loaded mods - if (!mod.m_bEnabled) - continue; - - // loop through the stored starpak paths - for (size_t hash : mod.StarpakPaths) - { - if (hash == hashed) - { - // construct new path - newPath = (mod.m_ModDirectory / "paks" / starpakPath).string(); - // set path to the new path - pPath = newPath.c_str(); - goto LOG_STARPAK; - } - } - } - } - - LOG_STARPAK: - NS::log::rpak->info("LoadStreamPak: {}", filename.string()); - } - - return ReadFileAsync(pPath, pCallback); -} - -ON_DLL_LOAD("engine.dll", RpakFilesystem, (CModule module)) -{ - AUTOHOOK_DISPATCH(); - - g_pPakLoadManager = new PakLoadManager; - - g_pakLoadApi = module.Offset(0x5BED78).Deref().RCast<PakLoadFuncs*>(); - pUnknownPakLoadSingleton = module.Offset(0x7C5E20).RCast<void**>(); - - LoadPakAsyncHook.Dispatch((LPVOID*)g_pakLoadApi->LoadPakAsync); - UnloadPakHook.Dispatch((LPVOID*)g_pakLoadApi->UnloadPak); - ReadFileAsyncHook.Dispatch((LPVOID*)g_pakLoadApi->ReadFileAsync); -} diff --git a/NorthstarDLL/core/filesystem/rpakfilesystem.h b/NorthstarDLL/core/filesystem/rpakfilesystem.h deleted file mode 100644 index bcd57a73..00000000 --- a/NorthstarDLL/core/filesystem/rpakfilesystem.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -enum class ePakLoadSource -{ - UNTRACKED = -1, // not a pak we loaded, we shouldn't touch this one - - CONSTANT, // should be loaded at all times - MAP // loaded from a map, should be unloaded when the map is unloaded -}; - -struct LoadedPak -{ - ePakLoadSource m_nLoadSource; - int m_nPakHandle; - size_t m_nPakNameHash; -}; - -class PakLoadManager -{ -private: - std::map<int, LoadedPak> m_vLoadedPaks {}; - std::unordered_map<size_t, int> m_HashToPakHandle {}; - -public: - int LoadPakAsync(const char* pPath, const ePakLoadSource nLoadSource); - void UnloadPak(const int nPakHandle); - void UnloadMapPaks(); - void* LoadFile(const char* path); // this is a guess - - LoadedPak* TrackLoadedPak(ePakLoadSource nLoadSource, int nPakHandle, size_t nPakNameHash); - void RemoveLoadedPak(int nPakHandle); - - LoadedPak* GetPakInfo(const int nPakHandle); - - int GetPakHandle(const size_t nPakNameHash); - int GetPakHandle(const char* pPath); -}; - -extern PakLoadManager* g_pPakLoadManager; diff --git a/NorthstarDLL/core/hooks.cpp b/NorthstarDLL/core/hooks.cpp deleted file mode 100644 index 26b3fe57..00000000 --- a/NorthstarDLL/core/hooks.cpp +++ /dev/null @@ -1,474 +0,0 @@ -#include "dedicated/dedicated.h" -#include "plugins/pluginbackend.h" - -#include <iostream> -#include <wchar.h> -#include <iostream> -#include <vector> -#include <fstream> -#include <sstream> -#include <filesystem> -#include <Psapi.h> - -#define XINPUT1_3_DLL "XInput1_3.dll" - -AUTOHOOK_INIT() - -// called from the ON_DLL_LOAD macros -__dllLoadCallback::__dllLoadCallback( - eDllLoadCallbackSide side, const std::string dllName, DllLoadCallbackFuncType callback, std::string uniqueStr, std::string reliesOn) -{ - // parse reliesOn array from string - std::vector<std::string> reliesOnArray; - - if (reliesOn.length() && reliesOn[0] != '(') - { - reliesOnArray.push_back(reliesOn); - } - else - { - // follows the format (tag, tag, tag) - std::string sCurrentTag; - for (int i = 1; i < reliesOn.length(); i++) - { - if (!isspace(reliesOn[i])) - { - if (reliesOn[i] == ',' || reliesOn[i] == ')') - { - reliesOnArray.push_back(sCurrentTag); - sCurrentTag = ""; - } - else - sCurrentTag += reliesOn[i]; - } - } - } - - switch (side) - { - case eDllLoadCallbackSide::UNSIDED: - { - AddDllLoadCallback(dllName, callback, uniqueStr, reliesOnArray); - break; - } - - case eDllLoadCallbackSide::CLIENT: - { - AddDllLoadCallbackForClient(dllName, callback, uniqueStr, reliesOnArray); - break; - } - - case eDllLoadCallbackSide::DEDICATED_SERVER: - { - AddDllLoadCallbackForDedicatedServer(dllName, callback, uniqueStr, reliesOnArray); - break; - } - } -} - -void __fileAutohook::Dispatch() -{ - for (__autovar* var : vars) - var->Dispatch(); - - for (__autohook* hook : hooks) - hook->Dispatch(); -} - -void __fileAutohook::DispatchForModule(const char* pModuleName) -{ - const int iModuleNameLen = strlen(pModuleName); - - for (__autohook* hook : hooks) - if ((hook->iAddressResolutionMode == __autohook::OFFSET_STRING && !strncmp(pModuleName, hook->pAddrString, iModuleNameLen)) || - (hook->iAddressResolutionMode == __autohook::PROCADDRESS && !strcmp(pModuleName, hook->pModuleName))) - hook->Dispatch(); -} - -ManualHook::ManualHook(const char* funcName, LPVOID func) : pHookFunc(func), ppOrigFunc(nullptr) -{ - const int iFuncNameStrlen = strlen(funcName); - pFuncName = new char[iFuncNameStrlen]; - memcpy(pFuncName, funcName, iFuncNameStrlen); -} - -ManualHook::ManualHook(const char* funcName, LPVOID* orig, LPVOID func) : pHookFunc(func), ppOrigFunc(orig) -{ - const int iFuncNameStrlen = strlen(funcName); - pFuncName = new char[iFuncNameStrlen]; - memcpy(pFuncName, funcName, iFuncNameStrlen); -} - -bool ManualHook::Dispatch(LPVOID addr, LPVOID* orig) -{ - if (orig) - ppOrigFunc = orig; - - if (MH_CreateHook(addr, pHookFunc, ppOrigFunc) == MH_OK) - { - if (MH_EnableHook(addr) == MH_OK) - { - spdlog::info("Enabling hook {}", pFuncName); - return true; - } - else - spdlog::error("MH_EnableHook failed for function {}", pFuncName); - } - else - spdlog::error("MH_CreateHook failed for function {}", pFuncName); - - return false; -} - -uintptr_t ParseDLLOffsetString(const char* pAddrString) -{ - // in the format server.dll + 0xDEADBEEF - int iDllNameEnd = 0; - for (; !isspace(pAddrString[iDllNameEnd]) && pAddrString[iDllNameEnd] != '+'; iDllNameEnd++) - ; - - char* pModuleName = new char[iDllNameEnd + 1]; - memcpy(pModuleName, pAddrString, iDllNameEnd); - pModuleName[iDllNameEnd] = '\0'; - - // get the module address - const HMODULE pModuleAddr = GetModuleHandleA(pModuleName); - - if (!pModuleAddr) - return 0; - - // get the offset string - uintptr_t iOffset = 0; - - int iOffsetBegin = iDllNameEnd; - int iOffsetEnd = strlen(pAddrString); - - // seek until we hit the start of the number offset - for (; !(pAddrString[iOffsetBegin] >= '0' && pAddrString[iOffsetBegin] <= '9') && pAddrString[iOffsetBegin]; iOffsetBegin++) - ; - - bool bIsHex = pAddrString[iOffsetBegin] == '0' && (pAddrString[iOffsetBegin + 1] == 'X' || pAddrString[iOffsetBegin + 1] == 'x'); - if (bIsHex) - iOffset = std::stoi(pAddrString + iOffsetBegin + 2, 0, 16); - else - iOffset = std::stoi(pAddrString + iOffsetBegin); - - return ((uintptr_t)pModuleAddr + iOffset); -} - -// dll load callback stuff -// this allows for code to register callbacks to be run as soon as a dll is loaded, mainly to allow for patches to be made on dll load -struct DllLoadCallback -{ - std::string dll; - DllLoadCallbackFuncType callback; - std::string tag; - std::vector<std::string> reliesOn; - bool called; -}; - -// HACK: declaring and initialising this vector at file scope crashes on debug builds due to static initialisation order -// using a static var like this ensures that the vector is initialised lazily when it's used -std::vector<DllLoadCallback>& GetDllLoadCallbacks() -{ - static std::vector<DllLoadCallback> vec = std::vector<DllLoadCallback>(); - return vec; -} - -void AddDllLoadCallback(std::string dll, DllLoadCallbackFuncType callback, std::string tag, std::vector<std::string> reliesOn) -{ - DllLoadCallback& callbackStruct = GetDllLoadCallbacks().emplace_back(); - - callbackStruct.dll = dll; - callbackStruct.callback = callback; - callbackStruct.tag = tag; - callbackStruct.reliesOn = reliesOn; - callbackStruct.called = false; -} - -void AddDllLoadCallbackForDedicatedServer( - std::string dll, DllLoadCallbackFuncType callback, std::string tag, std::vector<std::string> reliesOn) -{ - if (!IsDedicatedServer()) - return; - - AddDllLoadCallback(dll, callback, tag, reliesOn); -} - -void AddDllLoadCallbackForClient(std::string dll, DllLoadCallbackFuncType callback, std::string tag, std::vector<std::string> reliesOn) -{ - if (IsDedicatedServer()) - return; - - AddDllLoadCallback(dll, callback, tag, reliesOn); -} - -void MakeHook(LPVOID pTarget, LPVOID pDetour, void* ppOriginal, const char* pFuncName) -{ - char* pStrippedFuncName = (char*)pFuncName; - // strip & char from funcname - if (*pStrippedFuncName == '&') - pStrippedFuncName++; - - if (MH_CreateHook(pTarget, pDetour, (LPVOID*)ppOriginal) == MH_OK) - { - if (MH_EnableHook(pTarget) == MH_OK) - spdlog::info("Enabling hook {}", pStrippedFuncName); - else - spdlog::error("MH_EnableHook failed for function {}", pStrippedFuncName); - } - else - spdlog::error("MH_CreateHook failed for function {}", pStrippedFuncName); -} - -AUTOHOOK_ABSOLUTEADDR(_GetCommandLineA, (LPVOID)GetCommandLineA, LPSTR, WINAPI, ()) -{ - static char* cmdlineModified; - static char* cmdlineOrg; - - if (cmdlineOrg == nullptr || cmdlineModified == nullptr) - { - cmdlineOrg = _GetCommandLineA(); - bool isDedi = strstr(cmdlineOrg, "-dedicated"); // well, this one has to be a real argument - bool ignoreStartupArgs = strstr(cmdlineOrg, "-nostartupargs"); - - std::string args; - std::ifstream cmdlineArgFile; - - // it looks like CommandLine() prioritizes parameters apprearing first, so we want the real commandline to take priority - // not to mention that cmdlineOrg starts with the EXE path - args.append(cmdlineOrg); - args.append(" "); - - // append those from the file - - if (!ignoreStartupArgs) - { - - cmdlineArgFile = std::ifstream(!isDedi ? "ns_startup_args.txt" : "ns_startup_args_dedi.txt"); - - if (cmdlineArgFile) - { - std::stringstream argBuffer; - argBuffer << cmdlineArgFile.rdbuf(); - cmdlineArgFile.close(); - - // if some other command line option includes "-northstar" in the future then you have to refactor this check to check with - // both either space after or ending with - if (!isDedi && argBuffer.str().find("-northstar") != std::string::npos) - MessageBoxA( - NULL, - "The \"-northstar\" command line option is NOT supposed to go into ns_startup_args.txt file!\n\nThis option is " - "supposed to go into Origin/Steam game launch options, and then you are supposed to launch the original " - "Titanfall2.exe " - "rather than NorthstarLauncher.exe to make use of it.", - "Northstar Warning", - MB_ICONWARNING); - - args.append(argBuffer.str()); - } - } - - auto len = args.length(); - cmdlineModified = new char[len + 1]; - if (!cmdlineModified) - { - spdlog::error("malloc failed for command line"); - return cmdlineOrg; - } - memcpy(cmdlineModified, args.c_str(), len + 1); - } - - return cmdlineModified; -} - -std::vector<std::string> calledTags; -void CallLoadLibraryACallbacks(LPCSTR lpLibFileName, HMODULE moduleAddress) -{ - CModule cModule(moduleAddress); - - while (true) - { - bool bDoneCalling = true; - - for (auto& callbackStruct : GetDllLoadCallbacks()) - { - if (!callbackStruct.called && fs::path(lpLibFileName).filename() == fs::path(callbackStruct.dll).filename()) - { - bool bShouldContinue = false; - - if (!callbackStruct.reliesOn.empty()) - { - for (std::string tag : callbackStruct.reliesOn) - { - if (std::find(calledTags.begin(), calledTags.end(), tag) == calledTags.end()) - { - bDoneCalling = false; - bShouldContinue = true; - break; - } - } - } - - if (bShouldContinue) - continue; - - callbackStruct.callback(moduleAddress); - calledTags.push_back(callbackStruct.tag); - callbackStruct.called = true; - } - } - - if (bDoneCalling) - break; - } -} - -void CallLoadLibraryWCallbacks(LPCWSTR lpLibFileName, HMODULE moduleAddress) -{ - CModule cModule(moduleAddress); - - while (true) - { - bool bDoneCalling = true; - - for (auto& callbackStruct : GetDllLoadCallbacks()) - { - if (!callbackStruct.called && fs::path(lpLibFileName).filename() == fs::path(callbackStruct.dll).filename()) - { - bool bShouldContinue = false; - - if (!callbackStruct.reliesOn.empty()) - { - for (std::string tag : callbackStruct.reliesOn) - { - if (std::find(calledTags.begin(), calledTags.end(), tag) == calledTags.end()) - { - bDoneCalling = false; - bShouldContinue = true; - break; - } - } - } - - if (bShouldContinue) - continue; - - callbackStruct.callback(moduleAddress); - calledTags.push_back(callbackStruct.tag); - callbackStruct.called = true; - } - } - - if (bDoneCalling) - break; - } -} - -void CallAllPendingDLLLoadCallbacks() -{ - HMODULE hMods[1024]; - HANDLE hProcess = GetCurrentProcess(); - DWORD cbNeeded; - unsigned int i; - - // Get a list of all the modules in this process. - if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) - { - for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) - { - wchar_t szModName[MAX_PATH]; - - // Get the full path to the module's file. - if (GetModuleFileNameExW(hProcess, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) - { - CallLoadLibraryWCallbacks(szModName, hMods[i]); - } - } - } -} - -// clang-format off -AUTOHOOK_ABSOLUTEADDR(_LoadLibraryExA, (LPVOID)LoadLibraryExA, -HMODULE, WINAPI, (LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)) -// clang-format on -{ - HMODULE moduleAddress; - - LPCSTR lpLibFileNameEnd = lpLibFileName + strlen(lpLibFileName); - LPCSTR lpLibName = lpLibFileNameEnd - strlen(XINPUT1_3_DLL); - - // replace xinput dll with one that has ASLR - if (lpLibFileName <= lpLibName && !strncmp(lpLibName, XINPUT1_3_DLL, strlen(XINPUT1_3_DLL) + 1)) - { - moduleAddress = _LoadLibraryExA("XInput9_1_0.dll", hFile, dwFlags); - - if (!moduleAddress) - { - MessageBoxA(0, "Could not find XInput9_1_0.dll", "Northstar", MB_ICONERROR); - exit(EXIT_FAILURE); - - return nullptr; - } - } - else - moduleAddress = _LoadLibraryExA(lpLibFileName, hFile, dwFlags); - - if (moduleAddress) - { - CallLoadLibraryACallbacks(lpLibFileName, moduleAddress); - InformPluginsDLLLoad(fs::path(lpLibFileName), moduleAddress); - } - - return moduleAddress; -} - -// clang-format off -AUTOHOOK_ABSOLUTEADDR(_LoadLibraryA, (LPVOID)LoadLibraryA, -HMODULE, WINAPI, (LPCSTR lpLibFileName)) -// clang-format on -{ - HMODULE moduleAddress = _LoadLibraryA(lpLibFileName); - - if (moduleAddress) - CallLoadLibraryACallbacks(lpLibFileName, moduleAddress); - - return moduleAddress; -} - -// clang-format off -AUTOHOOK_ABSOLUTEADDR(_LoadLibraryExW, (LPVOID)LoadLibraryExW, -HMODULE, WINAPI, (LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)) -// clang-format on -{ - HMODULE moduleAddress = _LoadLibraryExW(lpLibFileName, hFile, dwFlags); - - if (moduleAddress) - CallLoadLibraryWCallbacks(lpLibFileName, moduleAddress); - - return moduleAddress; -} - -// clang-format off -AUTOHOOK_ABSOLUTEADDR(_LoadLibraryW, (LPVOID)LoadLibraryW, -HMODULE, WINAPI, (LPCWSTR lpLibFileName)) -// clang-format on -{ - HMODULE moduleAddress = _LoadLibraryW(lpLibFileName); - - if (moduleAddress) - { - CallLoadLibraryWCallbacks(lpLibFileName, moduleAddress); - InformPluginsDLLLoad(fs::path(lpLibFileName), moduleAddress); - } - - return moduleAddress; -} - -void InstallInitialHooks() -{ - if (MH_Initialize() != MH_OK) - spdlog::error("MH_Initialize (minhook initialization) failed"); - - AUTOHOOK_DISPATCH() -} diff --git a/NorthstarDLL/core/hooks.h b/NorthstarDLL/core/hooks.h deleted file mode 100644 index 15edbf0b..00000000 --- a/NorthstarDLL/core/hooks.h +++ /dev/null @@ -1,331 +0,0 @@ -#pragma once -#include "memory.h" - -#include <string> -#include <iostream> - -void InstallInitialHooks(); - -typedef void (*DllLoadCallbackFuncType)(CModule moduleAddress); -void AddDllLoadCallback(std::string dll, DllLoadCallbackFuncType callback, std::string tag = "", std::vector<std::string> reliesOn = {}); -void AddDllLoadCallbackForDedicatedServer( - std::string dll, DllLoadCallbackFuncType callback, std::string tag = "", std::vector<std::string> reliesOn = {}); -void AddDllLoadCallbackForClient( - std::string dll, DllLoadCallbackFuncType callback, std::string tag = "", std::vector<std::string> reliesOn = {}); - -void CallAllPendingDLLLoadCallbacks(); - -// new dll load callback stuff -enum class eDllLoadCallbackSide -{ - UNSIDED, - CLIENT, - DEDICATED_SERVER -}; - -class __dllLoadCallback -{ -public: - __dllLoadCallback() = delete; - __dllLoadCallback( - eDllLoadCallbackSide side, - const std::string dllName, - DllLoadCallbackFuncType callback, - std::string uniqueStr, - std::string reliesOn); -}; - -#define __CONCAT3(x, y, z) x##y##z -#define CONCAT3(x, y, z) __CONCAT3(x, y, z) -#define __CONCAT2(x, y) x##y -#define CONCAT2(x, y) __CONCAT2(x, y) -#define __STR(s) #s - -// adds a callback to be called when a given dll is loaded, for creating hooks and such -#define __ON_DLL_LOAD(dllName, side, uniquestr, reliesOn, args) \ - void CONCAT2(__dllLoadCallback, uniquestr) args; \ - namespace \ - { \ - __dllLoadCallback CONCAT2(__dllLoadCallbackInstance, __LINE__)( \ - side, dllName, CONCAT2(__dllLoadCallback, uniquestr), __STR(uniquestr), reliesOn); \ - } \ - void CONCAT2(__dllLoadCallback, uniquestr) args - -#define ON_DLL_LOAD(dllName, uniquestr, args) __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::UNSIDED, uniquestr, "", args) -#define ON_DLL_LOAD_RELIESON(dllName, uniquestr, reliesOn, args) \ - __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::UNSIDED, uniquestr, __STR(reliesOn), args) -#define ON_DLL_LOAD_CLIENT(dllName, uniquestr, args) __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::CLIENT, uniquestr, "", args) -#define ON_DLL_LOAD_CLIENT_RELIESON(dllName, uniquestr, reliesOn, args) \ - __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::CLIENT, uniquestr, __STR(reliesOn), args) -#define ON_DLL_LOAD_DEDI(dllName, uniquestr, args) __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::DEDICATED_SERVER, uniquestr, "", args) -#define ON_DLL_LOAD_DEDI_RELIESON(dllName, uniquestr, reliesOn, args) \ - __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::DEDICATED_SERVER, uniquestr, __STR(reliesOn), args) - -// new macro hook stuff -class __autohook; -class __autovar; - -class __fileAutohook -{ -public: - std::vector<__autohook*> hooks; - std::vector<__autovar*> vars; - - void Dispatch(); - void DispatchForModule(const char* pModuleName); -}; - -uintptr_t ParseDLLOffsetString(const char* pAddrString); - -// initialise autohooks for this file -#define AUTOHOOK_INIT() \ - namespace \ - { \ - __fileAutohook __FILEAUTOHOOK; \ - } - -// dispatch all autohooks in this file -#define AUTOHOOK_DISPATCH() __FILEAUTOHOOK.Dispatch(); - -#define AUTOHOOK_DISPATCH_MODULE(moduleName) __FILEAUTOHOOK.DispatchForModule(__STR(moduleName)); - -class __autohook -{ -public: - enum AddressResolutionMode - { - OFFSET_STRING, // we're using a string that of the format dllname.dll + offset - ABSOLUTE_ADDR, // we're using an absolute address, we don't need to process it at all - PROCADDRESS // resolve using GetModuleHandle and GetProcAddress - }; - - char* pFuncName; - - LPVOID pHookFunc; - LPVOID* ppOrigFunc; - - // address resolution props - AddressResolutionMode iAddressResolutionMode; - char* pAddrString = nullptr; // for OFFSET_STRING - LPVOID iAbsoluteAddress = nullptr; // for ABSOLUTE_ADDR - char* pModuleName; // for PROCADDRESS - char* pProcName; // for PROCADDRESS - -public: - __autohook() = delete; - - __autohook(__fileAutohook* autohook, const char* funcName, LPVOID absoluteAddress, LPVOID* orig, LPVOID func) - : pHookFunc(func), ppOrigFunc(orig), iAbsoluteAddress(absoluteAddress) - { - iAddressResolutionMode = ABSOLUTE_ADDR; - - const int iFuncNameStrlen = strlen(funcName) + 1; - pFuncName = new char[iFuncNameStrlen]; - memcpy(pFuncName, funcName, iFuncNameStrlen); - - autohook->hooks.push_back(this); - } - - __autohook(__fileAutohook* autohook, const char* funcName, const char* addrString, LPVOID* orig, LPVOID func) - : pHookFunc(func), ppOrigFunc(orig) - { - iAddressResolutionMode = OFFSET_STRING; - - const int iFuncNameStrlen = strlen(funcName) + 1; - pFuncName = new char[iFuncNameStrlen]; - memcpy(pFuncName, funcName, iFuncNameStrlen); - - const int iAddrStrlen = strlen(addrString) + 1; - pAddrString = new char[iAddrStrlen]; - memcpy(pAddrString, addrString, iAddrStrlen); - - autohook->hooks.push_back(this); - } - - __autohook(__fileAutohook* autohook, const char* funcName, const char* moduleName, const char* procName, LPVOID* orig, LPVOID func) - : pHookFunc(func), ppOrigFunc(orig) - { - iAddressResolutionMode = PROCADDRESS; - - const int iFuncNameStrlen = strlen(funcName) + 1; - pFuncName = new char[iFuncNameStrlen]; - memcpy(pFuncName, funcName, iFuncNameStrlen); - - const int iModuleNameStrlen = strlen(moduleName) + 1; - pModuleName = new char[iModuleNameStrlen]; - memcpy(pModuleName, moduleName, iModuleNameStrlen); - - const int iProcNameStrlen = strlen(procName) + 1; - pProcName = new char[iProcNameStrlen]; - memcpy(pProcName, procName, iProcNameStrlen); - - autohook->hooks.push_back(this); - } - - ~__autohook() - { - delete[] pFuncName; - - if (pAddrString) - delete[] pAddrString; - - if (pModuleName) - delete[] pModuleName; - - if (pProcName) - delete[] pProcName; - } - - void Dispatch() - { - LPVOID targetAddr = nullptr; - - // determine the address of the function we're hooking - switch (iAddressResolutionMode) - { - case ABSOLUTE_ADDR: - { - targetAddr = iAbsoluteAddress; - break; - } - - case OFFSET_STRING: - { - targetAddr = (LPVOID)ParseDLLOffsetString(pAddrString); - break; - } - - case PROCADDRESS: - { - targetAddr = (LPVOID)GetProcAddress(GetModuleHandleA(pModuleName), pProcName); - break; - } - } - - if (MH_CreateHook(targetAddr, pHookFunc, ppOrigFunc) == MH_OK) - { - if (MH_EnableHook(targetAddr) == MH_OK) - spdlog::info("Enabling hook {}", pFuncName); - else - spdlog::error("MH_EnableHook failed for function {}", pFuncName); - } - else - spdlog::error("MH_CreateHook failed for function {}", pFuncName); - } -}; - -// hook a function at a given offset from a dll to be dispatched with AUTOHOOK_DISPATCH() -#define AUTOHOOK(name, addrString, type, callingConvention, args) \ - type callingConvention CONCAT2(__autohookfunc, name) args; \ - namespace \ - { \ - type(*name) args; \ - __autohook CONCAT2(__autohook, __LINE__)( \ - &__FILEAUTOHOOK, __STR(name), __STR(addrString), (LPVOID*)&name, (LPVOID)CONCAT2(__autohookfunc, name)); \ - } \ - type callingConvention CONCAT2(__autohookfunc, name) args - -// hook a function at a given absolute constant address to be dispatched with AUTOHOOK_DISPATCH() -#define AUTOHOOK_ABSOLUTEADDR(name, addr, type, callingConvention, args) \ - type callingConvention CONCAT2(__autohookfunc, name) args; \ - namespace \ - { \ - type(*name) args; \ - __autohook \ - CONCAT2(__autohook, __LINE__)(&__FILEAUTOHOOK, __STR(name), addr, (LPVOID*)&name, (LPVOID)CONCAT2(__autohookfunc, name)); \ - } \ - type callingConvention CONCAT2(__autohookfunc, name) args - -// hook a function at a given module and exported function to be dispatched with AUTOHOOK_DISPATCH() -#define AUTOHOOK_PROCADDRESS(name, moduleName, procName, type, callingConvention, args) \ - type callingConvention CONCAT2(__autohookfunc, name) args; \ - namespace \ - { \ - type(*name) args; \ - __autohook CONCAT2(__autohook, __LINE__)( \ - &__FILEAUTOHOOK, __STR(name), __STR(moduleName), __STR(procName), (LPVOID*)&name, (LPVOID)CONCAT2(__autohookfunc, name)); \ - } \ - type callingConvention CONCAT2(__autohookfunc, name) \ - args - -class ManualHook -{ -public: - char* pFuncName; - - LPVOID pHookFunc; - LPVOID* ppOrigFunc; - -public: - ManualHook() = delete; - ManualHook(const char* funcName, LPVOID func); - ManualHook(const char* funcName, LPVOID* orig, LPVOID func); - bool Dispatch(LPVOID addr, LPVOID* orig = nullptr); -}; - -// hook a function to be dispatched manually later -#define HOOK(varName, originalFunc, type, callingConvention, args) \ - namespace \ - { \ - type(*originalFunc) args; \ - } \ - type callingConvention CONCAT2(__manualhookfunc, varName) args; \ - ManualHook varName = ManualHook(__STR(varName), (LPVOID*)&originalFunc, (LPVOID)CONCAT2(__manualhookfunc, varName)); \ - type callingConvention CONCAT2(__manualhookfunc, varName) args - -#define HOOK_NOORIG(varName, type, callingConvention, args) \ - type callingConvention CONCAT2(__manualhookfunc, varName) args; \ - ManualHook varName = ManualHook(__STR(varName), (LPVOID)CONCAT2(__manualhookfunc, varName)); \ - type callingConvention CONCAT2(__manualhookfunc, varName) \ - args - -void MakeHook(LPVOID pTarget, LPVOID pDetour, void* ppOriginal, const char* pFuncName = ""); -#define MAKEHOOK(pTarget, pDetour, ppOriginal) MakeHook((LPVOID)pTarget, (LPVOID)pDetour, (void*)ppOriginal, __STR(pDetour)) - -class __autovar -{ -public: - char* m_pAddrString; - void** m_pTarget; - -public: - __autovar(__fileAutohook* pAutohook, const char* pAddrString, void** pTarget) - { - m_pTarget = pTarget; - - const int iAddrStrlen = strlen(pAddrString) + 1; - m_pAddrString = new char[iAddrStrlen]; - memcpy(m_pAddrString, pAddrString, iAddrStrlen); - - pAutohook->vars.push_back(this); - } - - void Dispatch() - { - *m_pTarget = (void*)ParseDLLOffsetString(m_pAddrString); - } -}; - -// VAR_AT(engine.dll+0x404, ConVar*, Cvar_host_timescale) -#define VAR_AT(addrString, type, name) \ - type name; \ - namespace \ - { \ - __autovar CONCAT2(__autovar, __LINE__)(&__FILEAUTOHOOK, __STR(addrString), (void**)&name); \ - } - -// FUNCTION_AT(engine.dll + 0xDEADBEEF, void, __fastcall, SomeFunc, (void* a1)) -#define FUNCTION_AT(addrString, type, callingConvention, name, args) \ - type(*name) args; \ - namespace \ - { \ - __autovar CONCAT2(__autovar, __LINE__)(&__FILEAUTOHOOK, __STR(addrString), (void**)&name); \ - } - -// int* g_pSomeInt; -// DEFINED_VAR_AT(engine.dll + 0x5005, g_pSomeInt) -#define DEFINED_VAR_AT(addrString, name) \ - namespace \ - { \ - __autovar CONCAT2(__autovar, __LINE__)(&__FILEAUTOHOOK, __STR(addrString), (void**)&name); \ - } diff --git a/NorthstarDLL/core/macros.h b/NorthstarDLL/core/macros.h deleted file mode 100644 index ae944cca..00000000 --- a/NorthstarDLL/core/macros.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once -template <typename ReturnType, typename... Args> ReturnType CallVFunc(int index, void* thisPtr, Args... args) -{ - return (*reinterpret_cast<ReturnType(__fastcall***)(void*, Args...)>(thisPtr))[index](thisPtr, args...); -} - -template <typename T, size_t index, typename... Args> constexpr T CallVFunc_Alt(void* classBase, Args... args) noexcept -{ - return ((*(T(__thiscall***)(void*, Args...))(classBase))[index])(classBase, args...); -} - -#define STR_HASH(s) (std::hash<std::string>()(s)) - -// Example usage: M_VMETHOD(int, GetEntityIndex, 8, (CBaseEntity* ent), (this, ent)) -#define M_VMETHOD(returnType, name, index, args, argsRaw) \ - FORCEINLINE returnType name args noexcept \ - { \ - return CallVFunc_Alt<returnType, index> argsRaw; \ - } diff --git a/NorthstarDLL/core/math/bitbuf.h b/NorthstarDLL/core/math/bitbuf.h deleted file mode 100644 index 5ca75455..00000000 --- a/NorthstarDLL/core/math/bitbuf.h +++ /dev/null @@ -1,1148 +0,0 @@ -#pragma once - -#define INLINE inline - -#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)]; -} - -#undef BITS_PER_INT - -using u8 = uint8_t; -using u16 = uint16_t; -using u32 = uint32_t; -using u64 = uint64_t; -using uptr = uintptr_t; - -using i8 = int8_t; -using i16 = int16_t; -using i32 = int32_t; -using i64 = int64_t; -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 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, -}; - -enum EBitCoordType -{ - kCW_None, - kCW_LowPrecision, - kCW_Integral -}; - -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; - } - - INLINE const char* GetName() - { - return m_BufferName; - } - -private: - const char* m_BufferName = ""; - -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 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(); - - 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; - - bool m_Flushed = false; // :flushed: -}; - -#undef INLINE diff --git a/NorthstarDLL/core/math/bits.cpp b/NorthstarDLL/core/math/bits.cpp deleted file mode 100644 index c879a45c..00000000 --- a/NorthstarDLL/core/math/bits.cpp +++ /dev/null @@ -1,45 +0,0 @@ -//=============================================================================// -// -// Purpose: look for NANs, infinities, and underflows. -// -//=============================================================================// - -#include "bits.h" - -//----------------------------------------------------------------------------- -// This follows the ANSI/IEEE 754-1985 standard -//----------------------------------------------------------------------------- -unsigned long& FloatBits(float& f) -{ - return *reinterpret_cast<unsigned long*>(&f); -} - -unsigned long const& FloatBits(float const& f) -{ - return *reinterpret_cast<unsigned long const*>(&f); -} - -float BitsToFloat(unsigned long i) -{ - return *reinterpret_cast<float*>(&i); -} - -bool IsFinite(float f) -{ - return ((FloatBits(f) & 0x7F800000) != 0x7F800000); -} - -unsigned long FloatAbsBits(float f) -{ - return FloatBits(f) & 0x7FFFFFFF; -} - -float FloatMakePositive(float f) -{ - return fabsf(f); -} - -float FloatNegate(float f) -{ - return -f; // BitsToFloat( FloatBits(f) ^ 0x80000000 ); -} diff --git a/NorthstarDLL/core/math/bits.h b/NorthstarDLL/core/math/bits.h deleted file mode 100644 index 0532a9bd..00000000 --- a/NorthstarDLL/core/math/bits.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -unsigned long& FloatBits(float& f); -unsigned long const& FloatBits(float const& f); -float BitsToFloat(unsigned long i); -bool IsFinite(float f); -unsigned long FloatAbsBits(float f); - -#define FLOAT32_NAN_BITS (std::uint32_t)0x7FC00000 // NaN! -#define FLOAT32_NAN BitsToFloat(FLOAT32_NAN_BITS) diff --git a/NorthstarDLL/core/math/color.cpp b/NorthstarDLL/core/math/color.cpp deleted file mode 100644 index 7b98043a..00000000 --- a/NorthstarDLL/core/math/color.cpp +++ /dev/null @@ -1,27 +0,0 @@ - -// clang-format off -namespace NS::Colors -{ - Color SCRIPT_UI (100, 255, 255); - Color SCRIPT_CL (100, 255, 100); - Color SCRIPT_SV (255, 100, 255); - Color NATIVE_UI (50 , 150, 150); - Color NATIVE_CL (50 , 150, 50 ); - Color NATIVE_SV (150, 50 , 150); - Color NATIVE_ENGINE (252, 133, 153); - Color FILESYSTEM (0 , 150, 150); - Color RPAK (255, 190, 0 ); - Color NORTHSTAR (66 , 72 , 128); - Color ECHO (150, 150, 159); - Color PLUGINSYS (244, 60 , 14); - Color PLUGIN (244, 106, 14); - - Color TRACE (0 , 255, 255); - Color DEBUG (0 , 255, 255); - Color INFO (16 , 160, 16 ); - Color WARN (255, 255, 0 ); - Color ERR (255, 50 , 50 ); - Color CRIT (255, 0 , 0 ); - Color OFF (0 , 0 , 0 ); -}; -// clang-format on diff --git a/NorthstarDLL/core/math/color.h b/NorthstarDLL/core/math/color.h deleted file mode 100644 index 013c4e4c..00000000 --- a/NorthstarDLL/core/math/color.h +++ /dev/null @@ -1,199 +0,0 @@ -#pragma once - -struct color24 -{ - uint8_t r, g, b; -}; - -typedef struct color32_s -{ - bool operator!=(const struct color32_s& other) const - { - return r != other.r || g != other.g || b != other.b || a != other.a; - } - inline unsigned* asInt(void) - { - return reinterpret_cast<unsigned*>(this); - } - inline const unsigned* asInt(void) const - { - return reinterpret_cast<const unsigned*>(this); - } - inline void Copy(const color32_s& rhs) - { - *asInt() = *rhs.asInt(); - } - - uint8_t r, g, b, a; -} color32; - -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; - } -}; - -//----------------------------------------------------------------------------- -// Purpose: Basic handler for an rgb set of colors -// This class is fully inline -//----------------------------------------------------------------------------- -class Color -{ -public: - Color(int r, int g, int b, int a = 255) - { - _color[0] = (unsigned char)r; - _color[1] = (unsigned char)g; - _color[2] = (unsigned char)b; - _color[3] = (unsigned char)a; - } - void SetColor(int _r, int _g, int _b, int _a = 0) - { - _color[0] = (unsigned char)_r; - _color[1] = (unsigned char)_g; - _color[2] = (unsigned char)_b; - _color[3] = (unsigned char)_a; - } - void GetColor(int& _r, int& _g, int& _b, int& _a) const - { - _r = _color[0]; - _g = _color[1]; - _b = _color[2]; - _a = _color[3]; - } - int GetValue(int index) const - { - return _color[index]; - } - void SetRawColor(int color32) - { - *((int*)this) = color32; - } - int GetRawColor(void) const - { - return *((int*)this); - } - - inline int r() const - { - return _color[0]; - } - inline int g() const - { - return _color[1]; - } - inline int b() const - { - return _color[2]; - } - inline int a() const - { - return _color[3]; - } - - unsigned char& operator[](int index) - { - return _color[index]; - } - - const unsigned char& operator[](int index) const - { - return _color[index]; - } - - bool operator==(const Color& rhs) const - { - return (*((int*)this) == *((int*)&rhs)); - } - - bool operator!=(const Color& rhs) const - { - return !(operator==(rhs)); - } - - Color& operator=(const Color& rhs) - { - SetRawColor(rhs.GetRawColor()); - return *this; - } - - Color& operator=(const color32& rhs) - { - _color[0] = rhs.r; - _color[1] = rhs.g; - _color[2] = rhs.b; - _color[3] = rhs.a; - return *this; - } - - color32 ToColor32(void) const - { - color32 newColor {}; - newColor.r = _color[0]; - newColor.g = _color[1]; - newColor.b = _color[2]; - newColor.a = _color[3]; - return newColor; - } - - std::string ToANSIColor() - { - std::string out = "\033[38;2;"; - out += std::to_string(_color[0]) + ";"; - out += std::to_string(_color[1]) + ";"; - out += std::to_string(_color[2]) + ";"; - out += "49m"; - return out; - } - - SourceColor ToSourceColor() - { - return SourceColor(_color[0], _color[1], _color[2], _color[3]); - } - -private: - unsigned char _color[4]; -}; - -namespace NS::Colors -{ - extern Color SCRIPT_UI; - extern Color SCRIPT_CL; - extern Color SCRIPT_SV; - extern Color NATIVE_UI; - extern Color NATIVE_CL; - extern Color NATIVE_SV; - extern Color NATIVE_ENGINE; - extern Color FILESYSTEM; - extern Color RPAK; - extern Color NORTHSTAR; - extern Color ECHO; - extern Color PLUGINSYS; - extern Color PLUGIN; - - extern Color TRACE; - extern Color DEBUG; - extern Color INFO; - extern Color WARN; - extern Color ERR; - extern Color CRIT; - extern Color OFF; -}; // namespace NS::Colors diff --git a/NorthstarDLL/core/math/vector.h b/NorthstarDLL/core/math/vector.h deleted file mode 100644 index 8684908f..00000000 --- a/NorthstarDLL/core/math/vector.h +++ /dev/null @@ -1,47 +0,0 @@ -#include <cmath> - -#pragma once - -union Vector3 -{ - struct - { - float x; - float y; - float z; - }; - - float raw[3]; - - void MakeValid() - { - for (auto& fl : raw) - if (std::isnan(fl)) - fl = 0; - } - - // todo: more operators maybe - bool operator==(const Vector3& other) - { - return x == other.x && y == other.y && z == other.z; - } -}; - -union QAngle -{ - struct - { - float x; - float y; - float z; - float w; - }; - - float raw[4]; - - // todo: more operators maybe - bool operator==(const QAngle& other) - { - return x == other.x && y == other.y && z == other.z && w == other.w; - } -}; diff --git a/NorthstarDLL/core/memalloc.cpp b/NorthstarDLL/core/memalloc.cpp deleted file mode 100644 index 0a75bc2b..00000000 --- a/NorthstarDLL/core/memalloc.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "core/memalloc.h" -#include "core/tier0.h" - -// TODO: rename to malloc and free after removing statically compiled .libs - -extern "C" void* _malloc_base(size_t n) -{ - // allocate into static buffer if g_pMemAllocSingleton isn't initialised - if (!g_pMemAllocSingleton) - TryCreateGlobalMemAlloc(); - - return g_pMemAllocSingleton->m_vtable->Alloc(g_pMemAllocSingleton, n); -} - -/*extern "C" void* malloc(size_t n) -{ - return _malloc_base(n); -}*/ - -extern "C" void _free_base(void* p) -{ - if (!g_pMemAllocSingleton) - TryCreateGlobalMemAlloc(); - - g_pMemAllocSingleton->m_vtable->Free(g_pMemAllocSingleton, p); -} - -extern "C" void* _realloc_base(void* oldPtr, size_t size) -{ - if (!g_pMemAllocSingleton) - TryCreateGlobalMemAlloc(); - - return g_pMemAllocSingleton->m_vtable->Realloc(g_pMemAllocSingleton, oldPtr, size); -} - -extern "C" void* _calloc_base(size_t n, size_t size) -{ - size_t bytes = n * size; - void* memory = _malloc_base(bytes); - if (memory) - { - memset(memory, 0, bytes); - } - return memory; -} - -extern "C" char* _strdup_base(const char* src) -{ - char* str; - char* p; - int len = 0; - - while (src[len]) - len++; - str = reinterpret_cast<char*>(_malloc_base(len + 1)); - p = str; - while (*src) - *p++ = *src++; - *p = '\0'; - return str; -} - -void* operator new(size_t n) -{ - return _malloc_base(n); -} - -void operator delete(void* p) noexcept -{ - _free_base(p); -} // /FORCE:MULTIPLE diff --git a/NorthstarDLL/core/memalloc.h b/NorthstarDLL/core/memalloc.h deleted file mode 100644 index 2f383335..00000000 --- a/NorthstarDLL/core/memalloc.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "rapidjson/document.h" -// #include "include/rapidjson/allocators.h" - -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" char* _strdup_base(const char* src); - -void* operator new(size_t n); -void operator delete(void* p) noexcept; - -// 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); - } -}; - -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>; diff --git a/NorthstarDLL/core/memory.cpp b/NorthstarDLL/core/memory.cpp deleted file mode 100644 index 3770586f..00000000 --- a/NorthstarDLL/core/memory.cpp +++ /dev/null @@ -1,347 +0,0 @@ -#include "memory.h" - -CMemoryAddress::CMemoryAddress() : m_nAddress(0) {} -CMemoryAddress::CMemoryAddress(const uintptr_t nAddress) : m_nAddress(nAddress) {} -CMemoryAddress::CMemoryAddress(const void* pAddress) : m_nAddress(reinterpret_cast<uintptr_t>(pAddress)) {} - -// operators -CMemoryAddress::operator uintptr_t() const -{ - return m_nAddress; -} - -CMemoryAddress::operator void*() const -{ - return reinterpret_cast<void*>(m_nAddress); -} - -CMemoryAddress::operator bool() const -{ - return m_nAddress != 0; -} - -bool CMemoryAddress::operator==(const CMemoryAddress& other) const -{ - return m_nAddress == other.m_nAddress; -} - -bool CMemoryAddress::operator!=(const CMemoryAddress& other) const -{ - return m_nAddress != other.m_nAddress; -} - -bool CMemoryAddress::operator==(const uintptr_t& addr) const -{ - return m_nAddress == addr; -} - -bool CMemoryAddress::operator!=(const uintptr_t& addr) const -{ - return m_nAddress != addr; -} - -CMemoryAddress CMemoryAddress::operator+(const CMemoryAddress& other) const -{ - return Offset(other.m_nAddress); -} - -CMemoryAddress CMemoryAddress::operator-(const CMemoryAddress& other) const -{ - return CMemoryAddress(m_nAddress - other.m_nAddress); -} - -CMemoryAddress CMemoryAddress::operator+(const uintptr_t& addr) const -{ - return Offset(addr); -} - -CMemoryAddress CMemoryAddress::operator-(const uintptr_t& addr) const -{ - return CMemoryAddress(m_nAddress - addr); -} - -CMemoryAddress CMemoryAddress::operator*() const -{ - return Deref(); -} - -// traversal -CMemoryAddress CMemoryAddress::Offset(const uintptr_t nOffset) const -{ - return CMemoryAddress(m_nAddress + nOffset); -} - -CMemoryAddress CMemoryAddress::Deref(const int nNumDerefs) const -{ - uintptr_t ret = m_nAddress; - for (int i = 0; i < nNumDerefs; i++) - ret = *reinterpret_cast<uintptr_t*>(ret); - - return CMemoryAddress(ret); -} - -// patching -void CMemoryAddress::Patch(const uint8_t* pBytes, const size_t nSize) -{ - if (nSize) - WriteProcessMemory(GetCurrentProcess(), reinterpret_cast<LPVOID>(m_nAddress), pBytes, nSize, NULL); -} - -void CMemoryAddress::Patch(const std::initializer_list<uint8_t> bytes) -{ - uint8_t* pBytes = new uint8_t[bytes.size()]; - - int i = 0; - for (const uint8_t& byte : bytes) - pBytes[i++] = byte; - - Patch(pBytes, bytes.size()); - delete[] pBytes; -} - -inline std::vector<uint8_t> HexBytesToString(const char* pHexString) -{ - std::vector<uint8_t> ret; - - int size = strlen(pHexString); - for (int i = 0; i < size; i++) - { - // If this is a space character, ignore it - if (isspace(pHexString[i])) - continue; - - if (i < size - 1) - { - BYTE result = 0; - for (int j = 0; j < 2; j++) - { - int val = 0; - char c = *(pHexString + i + j); - if (c >= 'a') - { - val = c - 'a' + 0xA; - } - else if (c >= 'A') - { - val = c - 'A' + 0xA; - } - else if (isdigit(c)) - { - val = c - '0'; - } - else - { - assert_msg(false, "Failed to parse invalid hex string."); - val = -1; - } - - result += (j == 0) ? val * 16 : val; - } - ret.push_back(result); - } - - i++; - } - - return ret; -} - -void CMemoryAddress::Patch(const char* pBytes) -{ - std::vector<uint8_t> vBytes = HexBytesToString(pBytes); - Patch(vBytes.data(), vBytes.size()); -} - -void CMemoryAddress::NOP(const size_t nSize) -{ - uint8_t* pBytes = new uint8_t[nSize]; - - memset(pBytes, 0x90, nSize); - Patch(pBytes, nSize); - - delete[] pBytes; -} - -bool CMemoryAddress::IsMemoryReadable(const size_t nSize) -{ - static SYSTEM_INFO sysInfo; - if (!sysInfo.dwPageSize) - GetSystemInfo(&sysInfo); - - MEMORY_BASIC_INFORMATION memInfo; - if (!VirtualQuery(reinterpret_cast<LPCVOID>(m_nAddress), &memInfo, sizeof(memInfo))) - return false; - - return memInfo.RegionSize >= nSize && memInfo.State & MEM_COMMIT && !(memInfo.Protect & PAGE_NOACCESS); -} - -CModule::CModule(const HMODULE pModule) -{ - MODULEINFO mInfo {0}; - - if (pModule && pModule != INVALID_HANDLE_VALUE) - GetModuleInformation(GetCurrentProcess(), pModule, &mInfo, sizeof(MODULEINFO)); - - m_nModuleSize = static_cast<size_t>(mInfo.SizeOfImage); - m_pModuleBase = reinterpret_cast<uintptr_t>(mInfo.lpBaseOfDll); - m_nAddress = m_pModuleBase; - - if (!m_nModuleSize || !m_pModuleBase) - return; - - m_pDOSHeader = reinterpret_cast<IMAGE_DOS_HEADER*>(m_pModuleBase); - m_pNTHeaders = reinterpret_cast<IMAGE_NT_HEADERS64*>(m_pModuleBase + m_pDOSHeader->e_lfanew); - - const IMAGE_SECTION_HEADER* hSection = IMAGE_FIRST_SECTION(m_pNTHeaders); // Get first image section. - - for (WORD i = 0; i < m_pNTHeaders->FileHeader.NumberOfSections; i++) // Loop through the sections. - { - const IMAGE_SECTION_HEADER& hCurrentSection = hSection[i]; // Get current section. - - ModuleSections_t moduleSection = ModuleSections_t( - std::string(reinterpret_cast<const char*>(hCurrentSection.Name)), - static_cast<uintptr_t>(m_pModuleBase + hCurrentSection.VirtualAddress), - hCurrentSection.SizeOfRawData); - - if (!strcmp((const char*)hCurrentSection.Name, ".text")) - m_ExecutableCode = moduleSection; - else if (!strcmp((const char*)hCurrentSection.Name, ".pdata")) - m_ExceptionTable = moduleSection; - else if (!strcmp((const char*)hCurrentSection.Name, ".data")) - m_RunTimeData = moduleSection; - else if (!strcmp((const char*)hCurrentSection.Name, ".rdata")) - m_ReadOnlyData = moduleSection; - - m_vModuleSections.push_back(moduleSection); // Push back a struct with the section data. - } -} - -CModule::CModule(const char* pModuleName) : CModule(GetModuleHandleA(pModuleName)) {} - -CMemoryAddress CModule::GetExport(const char* pExportName) -{ - return CMemoryAddress(reinterpret_cast<uintptr_t>(GetProcAddress(reinterpret_cast<HMODULE>(m_nAddress), pExportName))); -} - -CMemoryAddress CModule::FindPattern(const uint8_t* pPattern, const char* pMask) -{ - if (!m_ExecutableCode.IsSectionValid()) - return CMemoryAddress(); - - uint64_t nBase = static_cast<uint64_t>(m_ExecutableCode.m_pSectionBase); - uint64_t nSize = static_cast<uint64_t>(m_ExecutableCode.m_nSectionSize); - - const uint8_t* pData = reinterpret_cast<uint8_t*>(nBase); - const uint8_t* pEnd = pData + static_cast<uint32_t>(nSize) - strlen(pMask); - - int nMasks[64]; // 64*16 = enough masks for 1024 bytes. - int iNumMasks = static_cast<int>(ceil(static_cast<float>(strlen(pMask)) / 16.f)); - - memset(nMasks, '\0', iNumMasks * sizeof(int)); - for (intptr_t i = 0; i < iNumMasks; ++i) - { - for (intptr_t j = strnlen(pMask + i * 16, 16) - 1; j >= 0; --j) - { - if (pMask[i * 16 + j] == 'x') - { - _bittestandset(reinterpret_cast<LONG*>(&nMasks[i]), j); - } - } - } - __m128i xmm1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pPattern)); - __m128i xmm2, xmm3, msks; - for (; pData != pEnd; _mm_prefetch(reinterpret_cast<const char*>(++pData + 64), _MM_HINT_NTA)) - { - if (pPattern[0] == pData[0]) - { - xmm2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pData)); - msks = _mm_cmpeq_epi8(xmm1, xmm2); - if ((_mm_movemask_epi8(msks) & nMasks[0]) == nMasks[0]) - { - for (uintptr_t i = 1; i < static_cast<uintptr_t>(iNumMasks); ++i) - { - xmm2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>((pData + i * 16))); - xmm3 = _mm_loadu_si128(reinterpret_cast<const __m128i*>((pPattern + i * 16))); - msks = _mm_cmpeq_epi8(xmm2, xmm3); - if ((_mm_movemask_epi8(msks) & nMasks[i]) == nMasks[i]) - { - if ((i + 1) == iNumMasks) - { - return CMemoryAddress(const_cast<uint8_t*>(pData)); - } - } - else - goto CONTINUE; - } - - return CMemoryAddress((&*(const_cast<uint8_t*>(pData)))); - } - } - - CONTINUE:; - } - - return CMemoryAddress(); -} - -inline std::pair<std::vector<uint8_t>, std::string> MaskedBytesFromPattern(const char* pPatternString) -{ - std::vector<uint8_t> vRet; - std::string sMask; - - int size = strlen(pPatternString); - for (int i = 0; i < size; i++) - { - // If this is a space character, ignore it - if (isspace(pPatternString[i])) - continue; - - if (pPatternString[i] == '?') - { - // Add a wildcard - vRet.push_back(0); - sMask.append("?"); - } - else if (i < size - 1) - { - BYTE result = 0; - for (int j = 0; j < 2; j++) - { - int val = 0; - char c = *(pPatternString + i + j); - if (c >= 'a') - { - val = c - 'a' + 0xA; - } - else if (c >= 'A') - { - val = c - 'A' + 0xA; - } - else if (isdigit(c)) - { - val = c - '0'; - } - else - { - assert_msg(false, "Failed to parse invalid pattern string."); - val = -1; - } - - result += (j == 0) ? val * 16 : val; - } - - vRet.push_back(result); - sMask.append("x"); - } - - i++; - } - - return std::make_pair(vRet, sMask); -} - -CMemoryAddress CModule::FindPattern(const char* pPattern) -{ - const auto pattern = MaskedBytesFromPattern(pPattern); - return FindPattern(pattern.first.data(), pattern.second.c_str()); -} diff --git a/NorthstarDLL/core/memory.h b/NorthstarDLL/core/memory.h deleted file mode 100644 index a978963e..00000000 --- a/NorthstarDLL/core/memory.h +++ /dev/null @@ -1,90 +0,0 @@ -#pragma once - -class CMemoryAddress -{ -public: - uintptr_t m_nAddress; - -public: - CMemoryAddress(); - CMemoryAddress(const uintptr_t nAddress); - CMemoryAddress(const void* pAddress); - - // operators - operator uintptr_t() const; - operator void*() const; - operator bool() const; - - bool operator==(const CMemoryAddress& other) const; - bool operator!=(const CMemoryAddress& other) const; - bool operator==(const uintptr_t& addr) const; - bool operator!=(const uintptr_t& addr) const; - - CMemoryAddress operator+(const CMemoryAddress& other) const; - CMemoryAddress operator-(const CMemoryAddress& other) const; - CMemoryAddress operator+(const uintptr_t& other) const; - CMemoryAddress operator-(const uintptr_t& other) const; - CMemoryAddress operator*() const; - - template <typename T> T RCast() - { - return reinterpret_cast<T>(m_nAddress); - } - - // traversal - CMemoryAddress Offset(const uintptr_t nOffset) const; - CMemoryAddress Deref(const int nNumDerefs = 1) const; - - // patching - void Patch(const uint8_t* pBytes, const size_t nSize); - void Patch(const std::initializer_list<uint8_t> bytes); - void Patch(const char* pBytes); - void NOP(const size_t nSize); - - bool IsMemoryReadable(const size_t nSize); -}; - -// based on https://github.com/Mauler125/r5sdk/blob/master/r5dev/public/include/module.h -class CModule : public CMemoryAddress -{ -public: - struct ModuleSections_t - { - ModuleSections_t(void) = default; - ModuleSections_t(const std::string& svSectionName, uintptr_t pSectionBase, size_t nSectionSize) - : m_svSectionName(svSectionName), m_pSectionBase(pSectionBase), m_nSectionSize(nSectionSize) - { - } - - bool IsSectionValid(void) const - { - return m_nSectionSize != 0; - } - - std::string m_svSectionName; // Name of section. - uintptr_t m_pSectionBase {}; // Start address of section. - size_t m_nSectionSize {}; // Size of section. - }; - - ModuleSections_t m_ExecutableCode; - ModuleSections_t m_ExceptionTable; - ModuleSections_t m_RunTimeData; - ModuleSections_t m_ReadOnlyData; - -private: - std::string m_svModuleName; - uintptr_t m_pModuleBase {}; - DWORD m_nModuleSize {}; - IMAGE_NT_HEADERS64* m_pNTHeaders = nullptr; - IMAGE_DOS_HEADER* m_pDOSHeader = nullptr; - std::vector<ModuleSections_t> m_vModuleSections; - -public: - CModule() = delete; // no default, we need a module name - CModule(const HMODULE pModule); - CModule(const char* pModuleName); - - CMemoryAddress GetExport(const char* pExportName); - CMemoryAddress FindPattern(const uint8_t* pPattern, const char* pMask); - CMemoryAddress FindPattern(const char* pPattern); -}; diff --git a/NorthstarDLL/core/sourceinterface.cpp b/NorthstarDLL/core/sourceinterface.cpp deleted file mode 100644 index 5a72beb0..00000000 --- a/NorthstarDLL/core/sourceinterface.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "sourceinterface.h" -#include "logging/sourceconsole.h" - -AUTOHOOK_INIT() - -// really wanted to do a modular callback system here but honestly couldn't be bothered so hardcoding stuff for now: todo later - -// clang-format off -AUTOHOOK_PROCADDRESS(ClientCreateInterface, client.dll, CreateInterface, -void*, __fastcall, (const char* pName, const int* pReturnCode)) -// clang-format on -{ - void* ret = ClientCreateInterface(pName, pReturnCode); - spdlog::info("CreateInterface CLIENT {}", pName); - - if (!strcmp(pName, "GameClientExports001")) - InitialiseConsoleOnInterfaceCreation(); - - return ret; -} - -// clang-format off -AUTOHOOK_PROCADDRESS(ServerCreateInterface, server.dll, CreateInterface, -void*, __fastcall, (const char* pName, const int* pReturnCode)) -// clang-format on -{ - void* ret = ServerCreateInterface(pName, pReturnCode); - spdlog::info("CreateInterface SERVER {}", pName); - - return ret; -} - -// clang-format off -AUTOHOOK_PROCADDRESS(EngineCreateInterface, engine.dll, CreateInterface, -void*, __fastcall, (const char* pName, const int* pReturnCode)) -// clang-format on -{ - void* ret = EngineCreateInterface(pName, pReturnCode); - spdlog::info("CreateInterface ENGINE {}", pName); - - return ret; -} - -// clang-format off -ON_DLL_LOAD("client.dll", ClientInterface, (CModule module)) {AUTOHOOK_DISPATCH_MODULE(client.dll)} -ON_DLL_LOAD("server.dll", ServerInterface, (CModule module)) {AUTOHOOK_DISPATCH_MODULE(server.dll)} -ON_DLL_LOAD("engine.dll", EngineInterface, (CModule module)) {AUTOHOOK_DISPATCH_MODULE(engine.dll)} -// clang-format on diff --git a/NorthstarDLL/core/sourceinterface.h b/NorthstarDLL/core/sourceinterface.h deleted file mode 100644 index 7b5e81f3..00000000 --- a/NorthstarDLL/core/sourceinterface.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once -#include <string> - -// literally just copied from ttf2sdk definition -typedef void* (*CreateInterfaceFn)(const char* pName, int* pReturnCode); - -template <typename T> class SourceInterface -{ -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); - } - - T* operator->() const - { - return m_interface; - } - - operator T*() const - { - return m_interface; - } -}; diff --git a/NorthstarDLL/core/structs.h b/NorthstarDLL/core/structs.h deleted file mode 100644 index 037233a6..00000000 --- a/NorthstarDLL/core/structs.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once -//clang-format off -// About this file: -// This file contains several macros used to define reversed structs -// The reason we use these macros is to make it easier to update existing structs -// when new fields are reversed -// This means we dont have to manually add padding, and recalculate when updating - -// Technical note: -// While functionally, these structs act like a regular struct, they are actually -// defined as unions with anonymous structs in them. -// This means that each field is essentially an offset into a union. -// We acknowledge that this goes against C++'s active-member guideline for unions -// However, this is not such a big deal here as these structs will not be constructed - -// Usage: -// To use these macros, define a struct like so: -/* -OFFSET_STRUCT(Name) -{ - STRUCT_SIZE(0x100) // Total in-memory struct size - FIELD(0x0, int field) // offset, signature -} -*/ - -#define OFFSET_STRUCT(name) union name -#define STRUCT_SIZE(size) char __size[size]; -#define STRUCT_FIELD_OFFSET(offset, signature) \ - struct \ - { \ - char CONCAT2(pad, __LINE__)[offset]; \ - signature; \ - }; - -// Special case for a 0-offset field -#define STRUCT_FIELD_NOOFFSET(offset, signature) signature; - -// Just puts two tokens next to each other, but -// allows us to force the preprocessor to do another pass -#define FX(f, x) f x - -// Macro used to detect if the given offset is 0 or not -#define TEST_0 , -// MSVC does no preprocessing of integer literals. -// On other compilers `0x0` gets processed into `0` -#define TEST_0x0 , - -// Concats the first and third argument and drops everything else -// Used with preprocessor expansion in later passes to move the third argument to the fourth and change the value -#define ZERO_P_I(a, b, c, ...) a##c - -// We use FX to prepare to use ZERO_P_I. -// The right block contains 3 arguments: -// NIF_ -// CONCAT2(TEST_, offset) -// 1 -// -// If offset is not 0 (or 0x0) the preprocessor replaces -// it with nothing and the third argument stays 1 -// -// If the offset is 0, TEST_0 expands to , and 1 becomes the fourth argument -// -// With those arguments we call ZERO_P_I and the first and third arugment get concat. -// We either end up with: -// NIF_ (if offset is 0) or -// NIF_1 (if offset is not 0) -#define IF_ZERO(m) FX(ZERO_P_I, (NIF_, CONCAT2(TEST_, m), 1)) - -// These macros are used to branch after we processed if the offset is zero or not -#define NIF_(t, ...) t -#define NIF_1(t, ...) __VA_ARGS__ - -// FIELD(S), generates an anonymous struct when a non 0 offset is given, otherwise just a signature -#define FIELD(offset, signature) IF_ZERO(offset)(STRUCT_FIELD_NOOFFSET, STRUCT_FIELD_OFFSET)(offset, signature) -#define FIELDS FIELD - -//clang-format on diff --git a/NorthstarDLL/core/tier0.cpp b/NorthstarDLL/core/tier0.cpp deleted file mode 100644 index 1f59722c..00000000 --- a/NorthstarDLL/core/tier0.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "tier0.h" - -IMemAlloc* g_pMemAllocSingleton = nullptr; - -CommandLineType CommandLine; -Plat_FloatTimeType Plat_FloatTime; -ThreadInServerFrameThreadType ThreadInServerFrameThread; - -typedef IMemAlloc* (*CreateGlobalMemAllocType)(); -CreateGlobalMemAllocType CreateGlobalMemAlloc; - -// needs to be a seperate function, since memalloc.cpp calls it -void TryCreateGlobalMemAlloc() -{ - // init memalloc stuff - CreateGlobalMemAlloc = - reinterpret_cast<CreateGlobalMemAllocType>(GetProcAddress(GetModuleHandleA("tier0.dll"), "CreateGlobalMemAlloc")); - g_pMemAllocSingleton = CreateGlobalMemAlloc(); // if it already exists, this returns the preexisting IMemAlloc instance -} - -ON_DLL_LOAD("tier0.dll", Tier0GameFuncs, (CModule module)) -{ - // shouldn't be necessary, but do this just in case - TryCreateGlobalMemAlloc(); - - // setup tier0 funcs - CommandLine = module.GetExport("CommandLine").RCast<CommandLineType>(); - Plat_FloatTime = module.GetExport("Plat_FloatTime").RCast<Plat_FloatTimeType>(); - ThreadInServerFrameThread = module.GetExport("ThreadInServerFrameThread").RCast<ThreadInServerFrameThreadType>(); -} diff --git a/NorthstarDLL/core/tier0.h b/NorthstarDLL/core/tier0.h deleted file mode 100644 index cc9af39e..00000000 --- a/NorthstarDLL/core/tier0.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -class IMemAlloc -{ -public: - struct VTable - { - void* unknown[1]; // alloc debug - 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* unknown4[2]; // nullsubs, maybe CrtSetDbgFlag - 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* unknown6[4]; - int (*heapchk)(IMemAlloc* memAlloc); - }; - - VTable* m_vtable; -}; - -class CCommandLine -{ -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) = 0; - virtual void CreateCmdLine(int argc, char** argv) = 0; - virtual void unknown() = 0; - virtual const char* GetCmdLine(void) const = 0; - - virtual const char* CheckParm(const char* psz, const char** ppszValue = 0) const = 0; - virtual void RemoveParm() const = 0; - virtual void AppendParm(const char* pszParm, const char* pszValues) = 0; - - virtual const char* ParmValue(const char* psz, const char* pDefaultVal = 0) const = 0; - virtual int ParmValue(const char* psz, int nDefaultVal) const = 0; - virtual float ParmValue(const char* psz, float flDefaultVal) const = 0; - - virtual int ParmCount() const = 0; - virtual int FindParm(const char* psz) const = 0; - virtual const char* GetParm(int nIndex) const = 0; - virtual void SetParm(int nIndex, char const* pParm) = 0; - - // virtual const char** GetParms() const {} -}; - -extern IMemAlloc* g_pMemAllocSingleton; - -typedef CCommandLine* (*CommandLineType)(); -extern CommandLineType CommandLine; - -typedef double (*Plat_FloatTimeType)(); -extern Plat_FloatTimeType Plat_FloatTime; - -typedef bool (*ThreadInServerFrameThreadType)(); -extern ThreadInServerFrameThreadType ThreadInServerFrameThread; - -void TryCreateGlobalMemAlloc(); diff --git a/NorthstarDLL/core/vanilla.h b/NorthstarDLL/core/vanilla.h deleted file mode 100644 index b0797803..00000000 --- a/NorthstarDLL/core/vanilla.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -/// Determines if we are in vanilla-compatibility mode. -/// In this mode we shouldn't auth with Atlas, which prevents users from joining a -/// non-trusted server. This means that we can unrestrict client/server commands -/// as well as various other small changes for compatibility -class VanillaCompatibility -{ -public: - void SetVanillaCompatibility(bool isVanilla) - { - static bool bInitialised = false; - if (bInitialised) - return; - - bInitialised = true; - m_bIsVanillaCompatible = isVanilla; - } - - bool GetVanillaCompatibility() - { - return m_bIsVanillaCompatible; - } - -private: - bool m_bIsVanillaCompatible = false; -}; - -inline VanillaCompatibility* g_pVanillaCompatibility; |