aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com>2024-01-24 02:29:20 +0100
committerGitHub <noreply@github.com>2024-01-24 02:29:20 +0100
commit3b7d9aaa95449a66be36a057aa49e35bcb8acec6 (patch)
tree2c772ba10530356a7bb4482fe61e207667081fc2
parentefff77f0941df9b6502f6c66a621c1c41a0d1e25 (diff)
parent7f84bdf8fd5c93286f000bc5f9314eab81128cee (diff)
downloadNorthstarLauncher-3b7d9aaa95449a66be36a057aa49e35bcb8acec6.tar.gz
NorthstarLauncher-3b7d9aaa95449a66be36a057aa49e35bcb8acec6.zip
Merge branch 'main' into feat/update-for-new-verified-json
-rw-r--r--primedev/Northstar.cmake1
-rw-r--r--primedev/client/audio.cpp2
-rw-r--r--primedev/config/profile.cpp6
-rw-r--r--primedev/core/convar/convar.cpp2
-rw-r--r--primedev/core/filesystem/filesystem.h15
-rw-r--r--primedev/core/hooks.cpp8
-rw-r--r--primedev/core/hooks.h14
-rw-r--r--primedev/core/math/bitbuf.h4
-rw-r--r--primedev/core/memory.cpp4
-rw-r--r--primedev/core/structs.h77
-rw-r--r--primedev/engine/r2engine.h175
-rw-r--r--primedev/logging/logging.cpp6
-rw-r--r--primedev/masterserver/masterserver.cpp128
-rw-r--r--primedev/mods/autodownload/moddownloader.cpp144
-rw-r--r--primedev/pch.h1
-rw-r--r--primedev/plugins/plugins.cpp2
-rw-r--r--primedev/primelauncher/main.cpp6
-rw-r--r--primedev/scripts/client/scriptserverbrowser.cpp4
-rw-r--r--primedev/scripts/scriptdatatables.cpp2
-rw-r--r--primedev/scripts/scripthttprequesthandler.cpp4
-rw-r--r--primedev/server/auth/bansystem.cpp4
-rw-r--r--primedev/server/auth/serverauthentication.cpp4
-rw-r--r--primedev/server/r2server.h337
-rw-r--r--primedev/shared/exploit_fixes/exploitfixes.cpp4
-rw-r--r--primedev/shared/misccommands.cpp4
-rw-r--r--primedev/squirrel/squirrel.cpp4
-rw-r--r--primedev/squirrel/squirrel.h4
-rw-r--r--primedev/thirdparty/rapidjson/document.h31
-rw-r--r--primedev/util/printcommands.cpp4
-rw-r--r--primedev/util/printmaps.cpp4
-rw-r--r--primedev/util/utils.h20
-rw-r--r--primedev/wsockproxy/loader.cpp6
32 files changed, 587 insertions, 444 deletions
diff --git a/primedev/Northstar.cmake b/primedev/Northstar.cmake
index 433326c2..8a4cec4e 100644
--- a/primedev/Northstar.cmake
+++ b/primedev/Northstar.cmake
@@ -51,7 +51,6 @@ add_library(
"core/memory.h"
"core/sourceinterface.cpp"
"core/sourceinterface.h"
- "core/structs.h"
"core/tier0.cpp"
"core/tier0.h"
"dedicated/dedicated.cpp"
diff --git a/primedev/client/audio.cpp b/primedev/client/audio.cpp
index aa32e390..099fdcee 100644
--- a/primedev/client/audio.cpp
+++ b/primedev/client/audio.cpp
@@ -445,7 +445,7 @@ bool, __fastcall, (void* sample, void* audioBuffer, unsigned int audioBufferLeng
else
{
data = dat->second.get();
- dataLength = dat->first;
+ dataLength = (unsigned int)dat->first;
}
}
diff --git a/primedev/config/profile.cpp b/primedev/config/profile.cpp
index d5361efa..f1d3f81c 100644
--- a/primedev/config/profile.cpp
+++ b/primedev/config/profile.cpp
@@ -15,15 +15,15 @@ void InitialiseNorthstarPrefix()
std::string cla = std::string(clachar);
if (strncmp(cla.substr(9, 1).c_str(), "\"", 1))
{
- int space = cla.find(" ");
+ size_t space = cla.find(" ");
std::string dirname = cla.substr(9, space - 9);
NORTHSTAR_FOLDER_PREFIX = dirname;
}
else
{
std::string quote = "\"";
- int quote1 = cla.find(quote);
- int quote2 = (cla.substr(quote1 + 1)).find(quote);
+ size_t quote1 = cla.find(quote);
+ size_t quote2 = (cla.substr(quote1 + 1)).find(quote);
std::string dirname = cla.substr(quote1 + 1, quote2);
NORTHSTAR_FOLDER_PREFIX = dirname;
}
diff --git a/primedev/core/convar/convar.cpp b/primedev/core/convar/convar.cpp
index e77ae1fd..94e41fee 100644
--- a/primedev/core/convar/convar.cpp
+++ b/primedev/core/convar/convar.cpp
@@ -382,7 +382,7 @@ void ConVar::ChangeStringValue(const char* pszTempVal, float flOldValue)
if (pszTempVal)
{
- int len = strlen(pszTempVal) + 1;
+ size_t len = strlen(pszTempVal) + 1;
if (len > m_Value.m_iStringLength)
{
diff --git a/primedev/core/filesystem/filesystem.h b/primedev/core/filesystem/filesystem.h
index fcd1bb2f..4e2c18d9 100644
--- a/primedev/core/filesystem/filesystem.h
+++ b/primedev/core/filesystem/filesystem.h
@@ -4,21 +4,6 @@
// 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
diff --git a/primedev/core/hooks.cpp b/primedev/core/hooks.cpp
index 26b3fe57..7ea435fe 100644
--- a/primedev/core/hooks.cpp
+++ b/primedev/core/hooks.cpp
@@ -77,7 +77,7 @@ void __fileAutohook::Dispatch()
void __fileAutohook::DispatchForModule(const char* pModuleName)
{
- const int iModuleNameLen = strlen(pModuleName);
+ const size_t iModuleNameLen = strlen(pModuleName);
for (__autohook* hook : hooks)
if ((hook->iAddressResolutionMode == __autohook::OFFSET_STRING && !strncmp(pModuleName, hook->pAddrString, iModuleNameLen)) ||
@@ -87,14 +87,14 @@ void __fileAutohook::DispatchForModule(const char* pModuleName)
ManualHook::ManualHook(const char* funcName, LPVOID func) : pHookFunc(func), ppOrigFunc(nullptr)
{
- const int iFuncNameStrlen = strlen(funcName);
+ const size_t 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);
+ const size_t iFuncNameStrlen = strlen(funcName);
pFuncName = new char[iFuncNameStrlen];
memcpy(pFuncName, funcName, iFuncNameStrlen);
}
@@ -141,7 +141,7 @@ uintptr_t ParseDLLOffsetString(const char* pAddrString)
uintptr_t iOffset = 0;
int iOffsetBegin = iDllNameEnd;
- int iOffsetEnd = strlen(pAddrString);
+ size_t iOffsetEnd = strlen(pAddrString);
// seek until we hit the start of the number offset
for (; !(pAddrString[iOffsetBegin] >= '0' && pAddrString[iOffsetBegin] <= '9') && pAddrString[iOffsetBegin]; iOffsetBegin++)
diff --git a/primedev/core/hooks.h b/primedev/core/hooks.h
index 15edbf0b..7c1b001c 100644
--- a/primedev/core/hooks.h
+++ b/primedev/core/hooks.h
@@ -119,7 +119,7 @@ public:
{
iAddressResolutionMode = ABSOLUTE_ADDR;
- const int iFuncNameStrlen = strlen(funcName) + 1;
+ const size_t iFuncNameStrlen = strlen(funcName) + 1;
pFuncName = new char[iFuncNameStrlen];
memcpy(pFuncName, funcName, iFuncNameStrlen);
@@ -131,11 +131,11 @@ public:
{
iAddressResolutionMode = OFFSET_STRING;
- const int iFuncNameStrlen = strlen(funcName) + 1;
+ const size_t iFuncNameStrlen = strlen(funcName) + 1;
pFuncName = new char[iFuncNameStrlen];
memcpy(pFuncName, funcName, iFuncNameStrlen);
- const int iAddrStrlen = strlen(addrString) + 1;
+ const size_t iAddrStrlen = strlen(addrString) + 1;
pAddrString = new char[iAddrStrlen];
memcpy(pAddrString, addrString, iAddrStrlen);
@@ -147,15 +147,15 @@ public:
{
iAddressResolutionMode = PROCADDRESS;
- const int iFuncNameStrlen = strlen(funcName) + 1;
+ const size_t iFuncNameStrlen = strlen(funcName) + 1;
pFuncName = new char[iFuncNameStrlen];
memcpy(pFuncName, funcName, iFuncNameStrlen);
- const int iModuleNameStrlen = strlen(moduleName) + 1;
+ const size_t iModuleNameStrlen = strlen(moduleName) + 1;
pModuleName = new char[iModuleNameStrlen];
memcpy(pModuleName, moduleName, iModuleNameStrlen);
- const int iProcNameStrlen = strlen(procName) + 1;
+ const size_t iProcNameStrlen = strlen(procName) + 1;
pProcName = new char[iProcNameStrlen];
memcpy(pProcName, procName, iProcNameStrlen);
@@ -293,7 +293,7 @@ public:
{
m_pTarget = pTarget;
- const int iAddrStrlen = strlen(pAddrString) + 1;
+ const size_t iAddrStrlen = strlen(pAddrString) + 1;
m_pAddrString = new char[iAddrStrlen];
memcpy(m_pAddrString, pAddrString, iAddrStrlen);
diff --git a/primedev/core/math/bitbuf.h b/primedev/core/math/bitbuf.h
index 5ca75455..a06dab17 100644
--- a/primedev/core/math/bitbuf.h
+++ b/primedev/core/math/bitbuf.h
@@ -630,7 +630,7 @@ public:
// at the head to make reading and detecting the end efficient.
int nHead = m_DataBytes & 3;
- int posBytes = startPos / 8;
+ size_t posBytes = startPos / 8;
if ((m_DataBytes < 4) || (nHead && (posBytes < nHead)))
{
// partial first dword
@@ -652,7 +652,7 @@ public:
}
else
{
- int adjustedPos = startPos - (nHead << 3);
+ size_t adjustedPos = startPos - (nHead << 3);
m_DataIn = reinterpret_cast<u32 const*>(reinterpret_cast<u8 const*>(m_Data) + ((adjustedPos / 32) << 2) + nHead);
diff --git a/primedev/core/memory.cpp b/primedev/core/memory.cpp
index 3770586f..41110aee 100644
--- a/primedev/core/memory.cpp
+++ b/primedev/core/memory.cpp
@@ -103,7 +103,7 @@ inline std::vector<uint8_t> HexBytesToString(const char* pHexString)
{
std::vector<uint8_t> ret;
- int size = strlen(pHexString);
+ size_t size = strlen(pHexString);
for (int i = 0; i < size; i++)
{
// If this is a space character, ignore it
@@ -289,7 +289,7 @@ inline std::pair<std::vector<uint8_t>, std::string> MaskedBytesFromPattern(const
std::vector<uint8_t> vRet;
std::string sMask;
- int size = strlen(pPatternString);
+ size_t size = strlen(pPatternString);
for (int i = 0; i < size; i++)
{
// If this is a space character, ignore it
diff --git a/primedev/core/structs.h b/primedev/core/structs.h
deleted file mode 100644
index 037233a6..00000000
--- a/primedev/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/primedev/engine/r2engine.h b/primedev/engine/r2engine.h
index e3bcc37e..c8b2e013 100644
--- a/primedev/engine/r2engine.h
+++ b/primedev/engine/r2engine.h
@@ -170,20 +170,50 @@ enum class eSignonState : int
CHANGELEVEL = 9, // server is changing level; please wait
};
-// clang-format off
-OFFSET_STRUCT(CBaseClient)
+class CBaseClient
{
- STRUCT_SIZE(0x2D728)
- FIELD(0x16, char m_Name[64])
- FIELD(0x258, KeyValues* m_ConVars)
- FIELD(0x2A0, eSignonState m_Signon)
- FIELD(0x358, char m_ClanTag[16])
- FIELD(0x484, bool m_bFakePlayer)
- FIELD(0x4A0, ePersistenceReady m_iPersistenceReady)
- FIELD(0x4FA, char m_PersistenceBuffer[PERSISTENCE_MAX_SIZE])
- FIELD(0xF500, char m_UID[32])
+public:
+ char _unk_0x0[22]; // 0x0 ( Size: 22 )
+ char m_Name[64]; // 0x16 ( Size: 64 )
+ char _unk_0x56[514]; // 0x56 ( Size: 514 )
+ KeyValues* m_ConVars; // 0x258 ( Size: 8 )
+ char _unk_0x260[64]; // 0x260 ( Size: 64 )
+ eSignonState m_Signon; // 0x2a0 ( Size: 4 )
+ int32_t m_nDeltaTick; // 0x2a4 ( Size: 4 )
+ uint64_t m_nOriginID; // 0x2a8 ( Size: 8 )
+ int32_t m_nStringTableAckTick; // 0x2b0 ( Size: 4 )
+ int32_t m_nSignonTick; // 0x2b4 ( Size: 4 )
+ char _unk_0x2b8[160]; // 0x2b8 ( Size: 180 )
+ char m_ClanTag[16]; // 0x358 ( Size: 16 )
+ char _unk_0x368[284]; // 0x368 ( Size: 284 )
+ bool m_bFakePlayer; // 0x484 ( Size: 1 )
+ bool m_bReceivedPacket; // 0x485 ( Size: 1 )
+ bool m_bLowViolence; // 0x486 ( Size: 1 )
+ bool m_bFullyAuthenticated; // 0x487 ( Size: 1 )
+ char _unk_0x488[24]; // 0x488 ( Size: 24 )
+ ePersistenceReady m_iPersistenceReady; // 0x4a0 ( Size: 1 )
+ char _unk_0x4a1[89]; // 0x4a1 ( Size: 89 )
+ char m_PersistenceBuffer[PERSISTENCE_MAX_SIZE]; // 0x4fa ( Size: 56781 )
+ char _unk_0xe2c7[4665]; // 0xe2c7 ( Size: 4665 )
+ char m_UID[32]; // 0xf500 ( Size: 32 )
+ char _unk_0xf520[123400]; // 0xf520 ( Size: 123400 )
};
-// clang-format on
+static_assert(sizeof(CBaseClient) == 0x2D728);
+static_assert(offsetof(CBaseClient, m_Name) == 0x16);
+static_assert(offsetof(CBaseClient, m_ConVars) == 0x258);
+static_assert(offsetof(CBaseClient, m_Signon) == 0x2A0);
+static_assert(offsetof(CBaseClient, m_nDeltaTick) == 0x2A4);
+static_assert(offsetof(CBaseClient, m_nOriginID) == 0x2A8);
+static_assert(offsetof(CBaseClient, m_nStringTableAckTick) == 0x2B0);
+static_assert(offsetof(CBaseClient, m_nSignonTick) == 0x2B4);
+static_assert(offsetof(CBaseClient, m_ClanTag) == 0x358);
+static_assert(offsetof(CBaseClient, m_bFakePlayer) == 0x484);
+static_assert(offsetof(CBaseClient, m_bReceivedPacket) == 0x485);
+static_assert(offsetof(CBaseClient, m_bLowViolence) == 0x486);
+static_assert(offsetof(CBaseClient, m_bFullyAuthenticated) == 0x487);
+static_assert(offsetof(CBaseClient, m_iPersistenceReady) == 0x4A0);
+static_assert(offsetof(CBaseClient, m_PersistenceBuffer) == 0x4FA);
+static_assert(offsetof(CBaseClient, m_UID) == 0xF500);
extern CBaseClient* g_pClientArray;
@@ -199,62 +229,73 @@ extern server_state_t* g_pServerState;
extern char* g_pModName;
-// clang-format off
-OFFSET_STRUCT(CGlobalVars)
+enum class GameMode_t : int
{
- FIELD(0x0,
- // Absolute time (per frame still - Use Plat_FloatTime() for a high precision real time
- // perf clock, but not that it doesn't obey host_timescale/host_framerate)
- double m_flRealTime);
-
- FIELDS(0x8,
- // Absolute frame counter - continues to increase even if game is paused
- int m_nFrameCount;
-
- // Non-paused frametime
- float m_flAbsoluteFrameTime;
-
- // Current time
- //
- // On the client, this (along with tickcount) takes a different meaning based on what
- // piece of code you're in:
- //
- // - While receiving network packets (like in PreDataUpdate/PostDataUpdate and proxies),
- // this is set to the SERVER TICKCOUNT for that packet. There is no interval between
- // the server ticks.
- // [server_current_Tick * tick_interval]
- //
- // - While rendering, this is the exact client clock
- // [client_current_tick * tick_interval + interpolation_amount]
- //
- // - During prediction, this is based on the client's current tick:
- // [client_current_tick * tick_interval]
- float m_flCurTime;
- )
-
- FIELDS(0x30,
- // Time spent on last server or client frame (has nothing to do with think intervals)
- float m_flFrameTime;
-
- // current maxplayers setting
- int m_nMaxClients;
- )
-
- FIELDS(0x3C,
- // Simulation ticks - does not increase when game is paused
- uint32_t m_nTickCount; // this is weird and doesn't seem to increase once per frame?
-
- // Simulation tick interval
- float m_flTickInterval;
- )
-
- FIELDS(0x60,
- const char* m_pMapName;
- int m_nMapVersion;
- )
-
- //FIELD(0x98, double m_flRealTime); // again?
+ NO_MODE = 0,
+ MP_MODE,
+ SP_MODE,
+};
+
+class CGlobalVars
+{
+public:
+ // Absolute time (per frame still - Use Plat_FloatTime() for a high precision real time
+ // perf clock, but not that it doesn't obey host_timescale/host_framerate)
+ double m_flRealTime; // 0x0 ( Size: 8 )
+
+ // Absolute frame counter - continues to increase even if game is paused
+ int m_nFrameCount; // 0x8 ( Size: 4 )
+
+ // Non-paused frametime
+ float m_flAbsoluteFrameTime; // 0xc ( Size: 4 )
+
+ // Current time
+ //
+ // On the client, this (along with tickcount) takes a different meaning based on what
+ // piece of code you're in:
+ //
+ // - While receiving network packets (like in PreDataUpdate/PostDataUpdate and proxies),
+ // this is set to the SERVER TICKCOUNT for that packet. There is no interval between
+ // the server ticks.
+ // [server_current_Tick * tick_interval]
+ //
+ // - While rendering, this is the exact client clock
+ // [client_current_tick * tick_interval + interpolation_amount]
+ //
+ // - During prediction, this is based on the client's current tick:
+ // [client_current_tick * tick_interval]
+ float m_flCurTime; // 0x10 ( Size: 4 )
+
+ char _unk_0x14[28]; // 0x14 ( Size: 28 )
+
+ // Time spent on last server or client frame (has nothing to do with think intervals)
+ float m_flFrameTime; // 0x30 ( Size: 4 )
+
+ // current maxplayers setting
+ int m_nMaxClients; // 0x34 ( Size: 4 )
+ GameMode_t m_nGameMode; // 0x38 ( Size: 4 )
+
+ // Simulation ticks - does not increase when game is paused
+ // this is weird and doesn't seem to increase once per frame?
+ uint32_t m_nTickCount; // 0x3c ( Size: 4 )
+
+ // Simulation tick interval
+ float m_flTickInterval; // 0x40 ( Size: 4 )
+ char _unk_0x44[28]; // 0x44 ( Size: 28 )
+
+ const char* m_pMapName; // 0x60 ( Size: 8 )
+ int m_nMapVersion; // 0x68 ( Size: 4 )
};
-// clang-format on
+static_assert(offsetof(CGlobalVars, m_flRealTime) == 0x0);
+static_assert(offsetof(CGlobalVars, m_nFrameCount) == 0x8);
+static_assert(offsetof(CGlobalVars, m_flAbsoluteFrameTime) == 0xc);
+static_assert(offsetof(CGlobalVars, m_flCurTime) == 0x10);
+static_assert(offsetof(CGlobalVars, m_flFrameTime) == 0x30);
+static_assert(offsetof(CGlobalVars, m_nMaxClients) == 0x34);
+static_assert(offsetof(CGlobalVars, m_nGameMode) == 0x38);
+static_assert(offsetof(CGlobalVars, m_nTickCount) == 0x3c);
+static_assert(offsetof(CGlobalVars, m_flTickInterval) == 0x40);
+static_assert(offsetof(CGlobalVars, m_pMapName) == 0x60);
+static_assert(offsetof(CGlobalVars, m_nMapVersion) == 0x68);
extern CGlobalVars* g_pGlobals;
diff --git a/primedev/logging/logging.cpp b/primedev/logging/logging.cpp
index 3416bb8c..ef9a6737 100644
--- a/primedev/logging/logging.cpp
+++ b/primedev/logging/logging.cpp
@@ -95,18 +95,18 @@ void ExternalConsoleSink::custom_sink_it_(const custom_log_msg& msg)
std::string name {msg.logger_name.begin(), msg.logger_name.end()};
std::string name_str = "[NAME]";
- int name_pos = str.find(name_str);
+ size_t name_pos = str.find(name_str);
str.replace(name_pos, name_str.length(), msg.origin->ANSIColor + "[" + name + "]" + default_color);
std::string level_str = "[LVL]";
- int level_pos = str.find(level_str);
+ size_t level_pos = str.find(level_str);
str.replace(level_pos, level_str.length(), levelColor + "[" + std::string(level_names[msg.level]) + "]" + default_color);
out += str;
}
// print the string to the console - this is definitely bad i think
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
- auto ignored = WriteConsoleA(handle, out.c_str(), std::strlen(out.c_str()), nullptr, nullptr);
+ auto ignored = WriteConsoleA(handle, out.c_str(), (DWORD)std::strlen(out.c_str()), nullptr, nullptr);
(void)ignored;
}
diff --git a/primedev/masterserver/masterserver.cpp b/primedev/masterserver/masterserver.cpp
index aa248464..a2d9f00e 100644
--- a/primedev/masterserver/masterserver.cpp
+++ b/primedev/masterserver/masterserver.cpp
@@ -7,6 +7,7 @@
#include "engine/r2engine.h"
#include "mods/modmanager.h"
#include "shared/misccommands.h"
+#include "util/utils.h"
#include "util/version.h"
#include "server/auth/bansystem.h"
#include "dedicated/dedicated.h"
@@ -118,6 +119,13 @@ void MasterServerManager::AuthenticateOriginWithMasterServer(const char* uid, co
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
CURLcode result = curl_easy_perform(curl);
+ ScopeGuard cleanup(
+ [&]
+ {
+ m_bOriginAuthWithMasterServerInProgress = false;
+ m_bOriginAuthWithMasterServerDone = true;
+ curl_easy_cleanup(curl);
+ });
if (result == CURLcode::CURLE_OK)
{
@@ -131,13 +139,13 @@ void MasterServerManager::AuthenticateOriginWithMasterServer(const char* uid, co
spdlog::error(
"Failed reading origin auth info response: encountered parse error \"{}\"",
rapidjson::GetParseError_En(originAuthInfo.GetParseError()));
- goto REQUEST_END_CLEANUP;
+ return;
}
if (!originAuthInfo.IsObject() || !originAuthInfo.HasMember("success"))
{
spdlog::error("Failed reading origin auth info response: malformed response object {}", readBuffer);
- goto REQUEST_END_CLEANUP;
+ return;
}
if (originAuthInfo["success"].IsTrue() && originAuthInfo.HasMember("token") && originAuthInfo["token"].IsString())
@@ -174,12 +182,6 @@ void MasterServerManager::AuthenticateOriginWithMasterServer(const char* uid, co
spdlog::error("Failed performing northstar origin auth: error {}", curl_easy_strerror(result));
m_bSuccessfullyConnected = false;
}
-
- // we goto this instead of returning so we always hit this
- REQUEST_END_CLEANUP:
- m_bOriginAuthWithMasterServerInProgress = false;
- m_bOriginAuthWithMasterServerDone = true;
- curl_easy_cleanup(curl);
});
requestThread.detach();
@@ -213,6 +215,13 @@ void MasterServerManager::RequestServerList()
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
CURLcode result = curl_easy_perform(curl);
+ ScopeGuard cleanup(
+ [&]
+ {
+ m_bRequestingServerList = false;
+ m_bScriptRequestingServerList = false;
+ curl_easy_cleanup(curl);
+ });
if (result == CURLcode::CURLE_OK)
{
@@ -226,20 +235,20 @@ void MasterServerManager::RequestServerList()
spdlog::error(
"Failed reading masterserver response: encountered parse error \"{}\"",
rapidjson::GetParseError_En(serverInfoJson.GetParseError()));
- goto REQUEST_END_CLEANUP;
+ return;
}
if (serverInfoJson.IsObject() && serverInfoJson.HasMember("error"))
{
spdlog::error("Failed reading masterserver response: got fastify error response");
spdlog::error(readBuffer);
- goto REQUEST_END_CLEANUP;
+ return;
}
if (!serverInfoJson.IsArray())
{
spdlog::error("Failed reading masterserver response: root object is not an array");
- goto REQUEST_END_CLEANUP;
+ return;
}
rapidjson::GenericArray<false, rapidjson_document::GenericValue> serverArray = serverInfoJson.GetArray();
@@ -251,7 +260,7 @@ void MasterServerManager::RequestServerList()
if (!serverObj.IsObject())
{
spdlog::error("Failed reading masterserver response: member of server array is not an object");
- goto REQUEST_END_CLEANUP;
+ return;
}
// todo: verify json props are fine before adding to m_remoteServers
@@ -342,12 +351,6 @@ void MasterServerManager::RequestServerList()
spdlog::error("Failed requesting servers: error {}", curl_easy_strerror(result));
m_bSuccessfullyConnected = false;
}
-
- // we goto this instead of returning so we always hit this
- REQUEST_END_CLEANUP:
- m_bRequestingServerList = false;
- m_bScriptRequestingServerList = false;
- curl_easy_cleanup(curl);
});
requestThread.detach();
@@ -374,6 +377,7 @@ void MasterServerManager::RequestMainMenuPromos()
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
CURLcode result = curl_easy_perform(curl);
+ ScopeGuard cleanup([&] { curl_easy_cleanup(curl); });
if (result == CURLcode::CURLE_OK)
{
@@ -387,20 +391,20 @@ void MasterServerManager::RequestMainMenuPromos()
spdlog::error(
"Failed reading masterserver main menu promos response: encountered parse error \"{}\"",
rapidjson::GetParseError_En(mainMenuPromoJson.GetParseError()));
- goto REQUEST_END_CLEANUP;
+ return;
}
if (!mainMenuPromoJson.IsObject())
{
spdlog::error("Failed reading masterserver main menu promos response: root object is not an object");
- goto REQUEST_END_CLEANUP;
+ return;
}
if (mainMenuPromoJson.HasMember("error"))
{
spdlog::error("Failed reading masterserver response: got fastify error response");
spdlog::error(readBuffer);
- goto REQUEST_END_CLEANUP;
+ return;
}
if (!mainMenuPromoJson.HasMember("newInfo") || !mainMenuPromoJson["newInfo"].IsObject() ||
@@ -428,7 +432,7 @@ void MasterServerManager::RequestMainMenuPromos()
!mainMenuPromoJson["smallButton2"]["ImageIndex"].IsNumber())
{
spdlog::error("Failed reading masterserver main menu promos response: malformed json object");
- goto REQUEST_END_CLEANUP;
+ return;
}
m_sMainMenuPromoData.newInfoTitle1 = mainMenuPromoJson["newInfo"]["Title1"].GetString();
@@ -455,10 +459,6 @@ void MasterServerManager::RequestMainMenuPromos()
spdlog::error("Failed requesting main menu promos: error {}", curl_easy_strerror(result));
m_bSuccessfullyConnected = false;
}
-
- REQUEST_END_CLEANUP:
- // nothing lol
- curl_easy_cleanup(curl);
});
requestThread.detach();
@@ -495,6 +495,21 @@ void MasterServerManager::AuthenticateWithOwnServer(const char* uid, const char*
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
CURLcode result = curl_easy_perform(curl);
+ ScopeGuard cleanup(
+ [&]
+ {
+ m_bAuthenticatingWithGameServer = false;
+ m_bScriptAuthenticatingWithGameServer = false;
+
+ if (m_bNewgameAfterSelfAuth)
+ {
+ // pretty sure this is threadsafe?
+ Cbuf_AddText(Cbuf_GetCurrentPlayer(), "ns_end_reauth_and_leave_to_lobby", cmd_source_t::kCommandSrcCode);
+ m_bNewgameAfterSelfAuth = false;
+ }
+
+ curl_easy_cleanup(curl);
+ });
if (result == CURLcode::CURLE_OK)
{
@@ -508,13 +523,13 @@ void MasterServerManager::AuthenticateWithOwnServer(const char* uid, const char*
spdlog::error(
"Failed reading masterserver authentication response: encountered parse error \"{}\"",
rapidjson::GetParseError_En(authInfoJson.GetParseError()));
- goto REQUEST_END_CLEANUP;
+ return;
}
if (!authInfoJson.IsObject())
{
spdlog::error("Failed reading masterserver authentication response: root object is not an object");
- goto REQUEST_END_CLEANUP;
+ return;
}
if (authInfoJson.HasMember("error"))
@@ -529,13 +544,13 @@ void MasterServerManager::AuthenticateWithOwnServer(const char* uid, const char*
else
m_sAuthFailureReason = "No error message provided";
- goto REQUEST_END_CLEANUP;
+ return;
}
if (!authInfoJson["success"].IsTrue())
{
spdlog::error("Authentication with masterserver failed: \"success\" is not true");
- goto REQUEST_END_CLEANUP;
+ return;
}
if (!authInfoJson.HasMember("success") || !authInfoJson.HasMember("id") || !authInfoJson["id"].IsString() ||
@@ -543,7 +558,7 @@ void MasterServerManager::AuthenticateWithOwnServer(const char* uid, const char*
!authInfoJson.HasMember("persistentData") || !authInfoJson["persistentData"].IsArray())
{
spdlog::error("Failed reading masterserver authentication response: malformed json object");
- goto REQUEST_END_CLEANUP;
+ return;
}
RemoteAuthData newAuthData {};
@@ -561,7 +576,7 @@ void MasterServerManager::AuthenticateWithOwnServer(const char* uid, const char*
if (!byte.IsUint() || byte.GetUint() > 255)
{
spdlog::error("Failed reading masterserver authentication response: malformed json object");
- goto REQUEST_END_CLEANUP;
+ return;
}
newAuthData.pdata[i++] = static_cast<char>(byte.GetUint());
@@ -581,19 +596,6 @@ void MasterServerManager::AuthenticateWithOwnServer(const char* uid, const char*
m_bSuccessfullyAuthenticatedWithGameServer = false;
m_bScriptAuthenticatingWithGameServer = false;
}
-
- REQUEST_END_CLEANUP:
- m_bAuthenticatingWithGameServer = false;
- m_bScriptAuthenticatingWithGameServer = false;
-
- if (m_bNewgameAfterSelfAuth)
- {
- // pretty sure this is threadsafe?
- Cbuf_AddText(Cbuf_GetCurrentPlayer(), "ns_end_reauth_and_leave_to_lobby", cmd_source_t::kCommandSrcCode);
- m_bNewgameAfterSelfAuth = false;
- }
-
- curl_easy_cleanup(curl);
});
requestThread.detach();
@@ -633,7 +635,7 @@ void MasterServerManager::AuthenticateWithServer(const char* uid, const char* pl
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
{
- char* escapedPassword = curl_easy_escape(curl, passwordStr.c_str(), passwordStr.length());
+ char* escapedPassword = curl_easy_escape(curl, passwordStr.c_str(), (int)passwordStr.length());
curl_easy_setopt(
curl,
@@ -651,6 +653,13 @@ void MasterServerManager::AuthenticateWithServer(const char* uid, const char* pl
}
CURLcode result = curl_easy_perform(curl);
+ ScopeGuard cleanup(
+ [&]
+ {
+ m_bAuthenticatingWithGameServer = false;
+ m_bScriptAuthenticatingWithGameServer = false;
+ curl_easy_cleanup(curl);
+ });
if (result == CURLcode::CURLE_OK)
{
@@ -664,13 +673,13 @@ void MasterServerManager::AuthenticateWithServer(const char* uid, const char* pl
spdlog::error(
"Failed reading masterserver authentication response: encountered parse error \"{}\"",
rapidjson::GetParseError_En(connectionInfoJson.GetParseError()));
- goto REQUEST_END_CLEANUP;
+ return;
}
if (!connectionInfoJson.IsObject())
{
spdlog::error("Failed reading masterserver authentication response: root object is not an object");
- goto REQUEST_END_CLEANUP;
+ return;
}
if (connectionInfoJson.HasMember("error"))
@@ -685,13 +694,13 @@ void MasterServerManager::AuthenticateWithServer(const char* uid, const char* pl
else
m_sAuthFailureReason = "No error message provided";
- goto REQUEST_END_CLEANUP;
+ return;
}
if (!connectionInfoJson["success"].IsTrue())
{
spdlog::error("Authentication with masterserver failed: \"success\" is not true");
- goto REQUEST_END_CLEANUP;
+ return;
}
if (!connectionInfoJson.HasMember("success") || !connectionInfoJson.HasMember("ip") ||
@@ -700,7 +709,7 @@ void MasterServerManager::AuthenticateWithServer(const char* uid, const char* pl
!connectionInfoJson["authToken"].IsString())
{
spdlog::error("Failed reading masterserver authentication response: malformed json object");
- goto REQUEST_END_CLEANUP;
+ return;
}
m_pendingConnectionInfo.ip.S_un.S_addr = inet_addr(connectionInfoJson["ip"].GetString());
@@ -725,11 +734,6 @@ void MasterServerManager::AuthenticateWithServer(const char* uid, const char* pl
m_bSuccessfullyAuthenticatedWithGameServer = false;
m_bScriptAuthenticatingWithGameServer = false;
}
-
- REQUEST_END_CLEANUP:
- m_bAuthenticatingWithGameServer = false;
- m_bScriptAuthenticatingWithGameServer = false;
- curl_easy_cleanup(curl);
});
requestThread.detach();
@@ -920,7 +924,7 @@ void MasterServerManager::ProcessConnectionlessPacketSigreq1(std::string data)
CURL* curl = curl_easy_init();
SetCommonHttpClientOptions(curl);
- char* rejectEnc = curl_easy_escape(curl, reject.c_str(), reject.length());
+ char* rejectEnc = curl_easy_escape(curl, reject.c_str(), (int)reject.length());
if (!rejectEnc)
{
spdlog::error("failed to handle Atlas connect request {}: failed to escape reject", token);
@@ -1281,6 +1285,16 @@ void MasterServerPresenceReporter::InternalAddServer(const ServerPresence* pServ
return ReturnCleanup(MasterServerReportPresenceResult::FailedNoRetry);
}
+ // Log request id for easier debugging when combining with logs on masterserver
+ if (serverAddedJson.HasMember("id"))
+ {
+ spdlog::info("Request id: {}", serverAddedJson["id"].GetString());
+ }
+ else
+ {
+ spdlog::error("Couldn't find request id in response");
+ }
+
if (serverAddedJson.HasMember("error"))
{
if (shouldLogError)
diff --git a/primedev/mods/autodownload/moddownloader.cpp b/primedev/mods/autodownload/moddownloader.cpp
index 9d79beaf..72ebb6f9 100644
--- a/primedev/mods/autodownload/moddownloader.cpp
+++ b/primedev/mods/autodownload/moddownloader.cpp
@@ -1,4 +1,5 @@
#include "moddownloader.h"
+#include "util/utils.h"
#include <rapidjson/fwd.h>
#include <mz_strm_mem.h>
#include <mz.h>
@@ -22,18 +23,18 @@ ModDownloader::ModDownloader()
if (clachar)
{
std::string url;
- int iFlagStringLength = strlen(CUSTOM_MODS_URL_FLAG);
+ size_t iFlagStringLength = strlen(CUSTOM_MODS_URL_FLAG);
std::string cla = std::string(clachar);
if (strncmp(cla.substr(iFlagStringLength, 1).c_str(), "\"", 1))
{
- int space = cla.find(" ");
+ size_t space = cla.find(" ");
url = cla.substr(iFlagStringLength, space - iFlagStringLength);
}
else
{
std::string quote = "\"";
- int quote1 = cla.find(quote);
- int quote2 = (cla.substr(quote1 + 1)).find(quote);
+ size_t quote1 = cla.find(quote);
+ size_t quote2 = (cla.substr(quote1 + 1)).find(quote);
url = cla.substr(quote1 + 1, quote2);
}
spdlog::info("Found custom verified mods URL in command line argument: {}", url);
@@ -75,6 +76,7 @@ void ModDownloader::FetchModsListFromAPI()
curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, &readBuffer);
curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, WriteToString);
result = curl_easy_perform(easyhandle);
+ ScopeGuard cleanup([&] { curl_easy_cleanup(easyhandle); });
if (result == CURLcode::CURLE_OK)
{
@@ -83,7 +85,7 @@ void ModDownloader::FetchModsListFromAPI()
else
{
spdlog::error("Fetching mods list failed: {}", curl_easy_strerror(result));
- goto REQUEST_END_CLEANUP;
+ return;
}
// Load mods list into local state
@@ -118,9 +120,6 @@ void ModDownloader::FetchModsListFromAPI()
}
spdlog::info("Done loading verified mods list.");
-
- REQUEST_END_CLEANUP:
- curl_easy_cleanup(easyhandle);
});
requestThread.detach();
}
@@ -172,29 +171,34 @@ std::optional<fs::path> ModDownloader::FetchModFromDistantStore(std::string_view
curl_easy_setopt(easyhandle, CURLOPT_URL, url.data());
curl_easy_setopt(easyhandle, CURLOPT_FAILONERROR, 1L);
+
+ // abort if slower than 30 bytes/sec during 10 seconds
+ curl_easy_setopt(easyhandle, CURLOPT_LOW_SPEED_TIME, 10L);
+ curl_easy_setopt(easyhandle, CURLOPT_LOW_SPEED_LIMIT, 30L);
+
curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, WriteData);
curl_easy_setopt(easyhandle, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(easyhandle, CURLOPT_XFERINFOFUNCTION, ModDownloader::ModFetchingProgressCallback);
curl_easy_setopt(easyhandle, CURLOPT_XFERINFODATA, this);
result = curl_easy_perform(easyhandle);
+ ScopeGuard cleanup(
+ [&]
+ {
+ curl_easy_cleanup(easyhandle);
+ fclose(fp);
+ });
if (result == CURLcode::CURLE_OK)
{
spdlog::info("Mod archive successfully fetched.");
- goto REQUEST_END_CLEANUP;
+ return std::optional<fs::path>(downloadPath);
}
else
{
spdlog::error("Fetching mod archive failed: {}", curl_easy_strerror(result));
- failed = true;
- goto REQUEST_END_CLEANUP;
+ return std::optional<fs::path>();
}
-
-REQUEST_END_CLEANUP:
- curl_easy_cleanup(easyhandle);
- fclose(fp);
- return failed ? std::optional<fs::path>() : std::optional<fs::path>(downloadPath);
}
bool ModDownloader::IsModLegit(fs::path modPath, std::string_view expectedChecksum)
@@ -220,6 +224,22 @@ bool ModDownloader::IsModLegit(fs::path modPath, std::string_view expectedChecks
std::vector<char> buffer(bufferSize, '\0');
std::ifstream fp(modPath.generic_string(), std::ios::binary);
+ ScopeGuard cleanup(
+ [&]
+ {
+ if (NULL != hashHandle)
+ {
+ BCryptDestroyHash(hashHandle); // Handle to hash/MAC object which needs to be destroyed
+ }
+
+ if (NULL != algorithmHandle)
+ {
+ BCryptCloseAlgorithmProvider(
+ algorithmHandle, // Handle to the algorithm provider which needs to be closed
+ 0); // Flags
+ }
+ });
+
// Open an algorithm handle
// This sample passes BCRYPT_HASH_REUSABLE_FLAG with BCryptAlgorithmProvider(...) to load a provider which supports reusable hash
status = BCryptOpenAlgorithmProvider(
@@ -230,7 +250,7 @@ bool ModDownloader::IsModLegit(fs::path modPath, std::string_view expectedChecks
if (!NT_SUCCESS(status))
{
modState.state = MOD_CORRUPTED;
- goto cleanup;
+ return false;
}
// Obtain the length of the hash
@@ -243,7 +263,6 @@ bool ModDownloader::IsModLegit(fs::path modPath, std::string_view expectedChecks
0); // Flags
if (!NT_SUCCESS(status))
{
- // goto cleanup;
modState.state = MOD_CORRUPTED;
return false;
}
@@ -260,7 +279,7 @@ bool ModDownloader::IsModLegit(fs::path modPath, std::string_view expectedChecks
if (!NT_SUCCESS(status))
{
modState.state = MOD_CORRUPTED;
- goto cleanup;
+ return false;
}
// Hash archive content
@@ -281,7 +300,7 @@ bool ModDownloader::IsModLegit(fs::path modPath, std::string_view expectedChecks
if (!NT_SUCCESS(status))
{
modState.state = MOD_CORRUPTED;
- goto cleanup;
+ return false;
}
}
}
@@ -297,7 +316,7 @@ bool ModDownloader::IsModLegit(fs::path modPath, std::string_view expectedChecks
if (!NT_SUCCESS(status))
{
modState.state = MOD_CORRUPTED;
- goto cleanup;
+ return false;
}
// Convert hash to string using bytes raw values
@@ -310,21 +329,6 @@ bool ModDownloader::IsModLegit(fs::path modPath, std::string_view expectedChecks
spdlog::info("Expected checksum: {}", expectedChecksum.data());
spdlog::info("Computed checksum: {}", ss.str());
return expectedChecksum.compare(ss.str()) == 0;
-
-cleanup:
- if (NULL != hashHandle)
- {
- BCryptDestroyHash(hashHandle); // Handle to hash/MAC object which needs to be destroyed
- }
-
- if (NULL != algorithmHandle)
- {
- BCryptCloseAlgorithmProvider(
- algorithmHandle, // Handle to the algorithm provider which needs to be closed
- 0); // Flags
- }
-
- return false;
}
bool ModDownloader::IsModAuthorized(std::string_view modName, std::string_view modVersion)
@@ -375,11 +379,20 @@ void ModDownloader::ExtractMod(fs::path modPath)
fs::path modDirectory;
file = unzOpen(modPath.generic_string().c_str());
+ ScopeGuard cleanup(
+ [&]
+ {
+ if (unzClose(file) != MZ_OK)
+ {
+ spdlog::error("Failed closing mod archive after extraction.");
+ }
+ });
+
if (file == NULL)
{
spdlog::error("Cannot open archive located at {}.", modPath.generic_string());
modState.state = FAILED_READING_ARCHIVE;
- goto EXTRACTION_CLEANUP;
+ return;
}
unz_global_info64 gi;
@@ -389,7 +402,7 @@ void ModDownloader::ExtractMod(fs::path modPath)
{
spdlog::error("Failed getting information from archive (error code: {})", status);
modState.state = FAILED_READING_ARCHIVE;
- goto EXTRACTION_CLEANUP;
+ return;
}
// Update state
@@ -422,7 +435,7 @@ void ModDownloader::ExtractMod(fs::path modPath)
{
spdlog::error("Parent directory ({}) creation failed.", fileDestination.parent_path().generic_string());
modState.state = FAILED_WRITING_TO_DISK;
- goto EXTRACTION_CLEANUP;
+ return;
}
}
@@ -434,7 +447,7 @@ void ModDownloader::ExtractMod(fs::path modPath)
{
spdlog::error("Directory creation failed: {}", ec.message());
modState.state = FAILED_WRITING_TO_DISK;
- goto EXTRACTION_CLEANUP;
+ return;
}
}
// ...else create file
@@ -445,7 +458,7 @@ void ModDownloader::ExtractMod(fs::path modPath)
{
spdlog::error("File \"{}\" was not found in archive.", zipFilename);
modState.state = FAILED_READING_ARCHIVE;
- goto EXTRACTION_CLEANUP;
+ return;
}
// Create file
@@ -460,7 +473,7 @@ void ModDownloader::ExtractMod(fs::path modPath)
{
spdlog::error("Could not open file {} from archive.", zipFilename);
modState.state = FAILED_READING_ARCHIVE;
- goto EXTRACTION_CLEANUP;
+ return;
}
// Create destination file
@@ -469,7 +482,7 @@ void ModDownloader::ExtractMod(fs::path modPath)
{
spdlog::error("Failed creating destination file.");
modState.state = FAILED_WRITING_TO_DISK;
- goto EXTRACTION_CLEANUP;
+ return;
}
// Allocate memory for buffer
@@ -478,7 +491,7 @@ void ModDownloader::ExtractMod(fs::path modPath)
{
spdlog::error("Error while allocating memory.");
modState.state = FAILED_WRITING_TO_DISK;
- goto EXTRACTION_CLEANUP;
+ return;
}
// Extract file to destination
@@ -509,7 +522,7 @@ void ModDownloader::ExtractMod(fs::path modPath)
{
spdlog::error("An error occurred during file extraction (code: {})", err);
modState.state = FAILED_WRITING_TO_DISK;
- goto EXTRACTION_CLEANUP;
+ return;
}
err = unzCloseCurrentFile(file);
if (err != UNZ_OK)
@@ -530,16 +543,10 @@ void ModDownloader::ExtractMod(fs::path modPath)
if (status != UNZ_OK)
{
spdlog::error("Error while browsing archive files (error code: {}).", status);
- goto EXTRACTION_CLEANUP;
+ return;
}
}
}
-
-EXTRACTION_CLEANUP:
- if (unzClose(file) != MZ_OK)
- {
- spdlog::error("Failed closing mod archive after extraction.");
- }
}
void ModDownloader::DownloadMod(std::string modName, std::string modVersion)
@@ -556,6 +563,22 @@ void ModDownloader::DownloadMod(std::string modName, std::string modVersion)
{
fs::path archiveLocation;
+ ScopeGuard cleanup(
+ [&]
+ {
+ try
+ {
+ remove(archiveLocation);
+ }
+ catch (const std::exception& a)
+ {
+ spdlog::error("Error while removing downloaded archive: {}", a.what());
+ }
+
+ modState.state = DONE;
+ spdlog::info("Done downloading {}.", modName);
+ });
+
// Download mod archive
std::string expectedHash = verifiedMods[modName].versions[modVersion].checksum;
std::optional<fs::path> fetchingResult = FetchModFromDistantStore(std::string_view(modName), std::string_view(modVersion));
@@ -563,31 +586,18 @@ void ModDownloader::DownloadMod(std::string modName, std::string modVersion)
{
spdlog::error("Something went wrong while fetching archive, aborting.");
modState.state = MOD_FETCHING_FAILED;
- goto REQUEST_END_CLEANUP;
+ return;
}
archiveLocation = fetchingResult.value();
if (!IsModLegit(archiveLocation, std::string_view(expectedHash)))
{
spdlog::warn("Archive hash does not match expected checksum, aborting.");
modState.state = MOD_CORRUPTED;
- goto REQUEST_END_CLEANUP;
+ return;
}
// Extract downloaded mod archive
ExtractMod(archiveLocation);
-
- REQUEST_END_CLEANUP:
- try
- {
- remove(archiveLocation);
- }
- catch (const std::exception& a)
- {
- spdlog::error("Error while removing downloaded archive: {}", a.what());
- }
-
- modState.state = DONE;
- spdlog::info("Done downloading {}.", modName);
});
requestThread.detach();
diff --git a/primedev/pch.h b/primedev/pch.h
index b9ba0e08..8a03b857 100644
--- a/primedev/pch.h
+++ b/primedev/pch.h
@@ -31,7 +31,6 @@ typedef void (*callable_v)(void* v);
#include "core/macros.h"
-#include "core/structs.h"
#include "core/math/color.h"
#include "spdlog/spdlog.h"
diff --git a/primedev/plugins/plugins.cpp b/primedev/plugins/plugins.cpp
index 72b64566..311285e1 100644
--- a/primedev/plugins/plugins.cpp
+++ b/primedev/plugins/plugins.cpp
@@ -188,7 +188,7 @@ std::optional<Plugin> PluginManager::LoadPlugin(fs::path path, PluginInitFuncs*
plugin.run_frame = (PLUGIN_RUNFRAME)GetProcAddress(pluginLib, "PLUGIN_RUNFRAME");
- plugin.handle = m_vLoadedPlugins.size();
+ plugin.handle = (int)m_vLoadedPlugins.size();
plugin.logger = std::make_shared<ColoredLogger>(plugin.displayName.c_str(), NS::Colors::PLUGIN);
RegisterLogger(plugin.logger);
NS::log::PLUGINSYS->info("Loading plugin {} version {}", plugin.displayName, plugin.version);
diff --git a/primedev/primelauncher/main.cpp b/primedev/primelauncher/main.cpp
index ae745672..96c96c04 100644
--- a/primedev/primelauncher/main.cpp
+++ b/primedev/primelauncher/main.cpp
@@ -281,7 +281,7 @@ bool LoadNorthstar()
std::string cla = std::string(clachar);
if (strncmp(cla.substr(9, 1).c_str(), "\"", 1))
{
- int space = cla.find(" ");
+ size_t space = cla.find(" ");
std::string dirname = cla.substr(9, space - 9);
std::cout << "[*] Found profile in command line arguments: " << dirname << std::endl;
strProfile = dirname.c_str();
@@ -289,8 +289,8 @@ bool LoadNorthstar()
else
{
std::string quote = "\"";
- int quote1 = cla.find(quote);
- int quote2 = (cla.substr(quote1 + 1)).find(quote);
+ size_t quote1 = cla.find(quote);
+ size_t quote2 = (cla.substr(quote1 + 1)).find(quote);
std::string dirname = cla.substr(quote1 + 1, quote2);
std::cout << "[*] Found profile in command line arguments: " << dirname << std::endl;
strProfile = dirname;
diff --git a/primedev/scripts/client/scriptserverbrowser.cpp b/primedev/scripts/client/scriptserverbrowser.cpp
index a142c3f4..21324535 100644
--- a/primedev/scripts/client/scriptserverbrowser.cpp
+++ b/primedev/scripts/client/scriptserverbrowser.cpp
@@ -26,7 +26,7 @@ ADD_SQFUNC("bool", NSMasterServerConnectionSuccessful, "", "", ScriptContext::UI
ADD_SQFUNC("int", NSGetServerCount, "", "", ScriptContext::UI)
{
- g_pSquirrel<context>->pushinteger(sqvm, g_pMasterServerManager->m_vRemoteServers.size());
+ g_pSquirrel<context>->pushinteger(sqvm, (SQInteger)g_pMasterServerManager->m_vRemoteServers.size());
return SQRESULT_NOTNULL;
}
@@ -146,7 +146,7 @@ ADD_SQFUNC("array<ServerInfo>", NSGetGameServers, "", "", ScriptContext::UI)
g_pSquirrel<context>->pushnewstructinstance(sqvm, 11);
// index
- g_pSquirrel<context>->pushinteger(sqvm, i);
+ g_pSquirrel<context>->pushinteger(sqvm, (SQInteger)i);
g_pSquirrel<context>->sealstructslot(sqvm, 0);
// id
diff --git a/primedev/scripts/scriptdatatables.cpp b/primedev/scripts/scriptdatatables.cpp
index 87a26dca..865b6243 100644
--- a/primedev/scripts/scriptdatatables.cpp
+++ b/primedev/scripts/scriptdatatables.cpp
@@ -308,7 +308,7 @@ REPLACE_SQFUNC(GetDataTableRowCount, (ScriptContext::UI | ScriptContext::CLIENT
return g_pSquirrel<context>->m_funcOriginals["GetDatatableRowCount"](sqvm);
CSVData* csv = *pData;
- g_pSquirrel<context>->pushinteger(sqvm, csv->dataPointers.size());
+ g_pSquirrel<context>->pushinteger(sqvm, (SQInteger)csv->dataPointers.size());
return SQRESULT_NOTNULL;
}
diff --git a/primedev/scripts/scripthttprequesthandler.cpp b/primedev/scripts/scripthttprequesthandler.cpp
index aa75127a..69828a5a 100644
--- a/primedev/scripts/scripthttprequesthandler.cpp
+++ b/primedev/scripts/scripthttprequesthandler.cpp
@@ -320,11 +320,11 @@ template <ScriptContext context> int HttpRequestHandler::MakeHttpRequest(const H
bool isFirstValue = true;
for (const auto& kv : requestParameters.queryParameters)
{
- char* key = curl_easy_escape(curl, kv.first.c_str(), kv.first.length());
+ char* key = curl_easy_escape(curl, kv.first.c_str(), (int)kv.first.length());
for (const std::string& queryValue : kv.second)
{
- char* value = curl_easy_escape(curl, queryValue.c_str(), queryValue.length());
+ char* value = curl_easy_escape(curl, queryValue.c_str(), (int)queryValue.length());
if (isFirstValue && !bUrlContainsQuery)
{
diff --git a/primedev/server/auth/bansystem.cpp b/primedev/server/auth/bansystem.cpp
index 6e4d1644..59bb6067 100644
--- a/primedev/server/auth/bansystem.cpp
+++ b/primedev/server/auth/bansystem.cpp
@@ -222,8 +222,8 @@ int ConCommand_banCompletion(const char* const partial, char commands[COMMAND_CO
const char* cmdName = partial;
const char* query = partial + (space == nullptr ? 0 : space - partial) + 1;
- const int queryLength = strlen(query);
- const int cmdLength = strlen(cmdName) - queryLength;
+ const size_t queryLength = strlen(query);
+ const size_t cmdLength = strlen(cmdName) - queryLength;
int numCompletions = 0;
for (int i = 0; i < GetMaxPlayers() && numCompletions < COMMAND_COMPLETION_MAXITEMS - 2; i++)
diff --git a/primedev/server/auth/serverauthentication.cpp b/primedev/server/auth/serverauthentication.cpp
index 0d46426f..7d656820 100644
--- a/primedev/server/auth/serverauthentication.cpp
+++ b/primedev/server/auth/serverauthentication.cpp
@@ -291,7 +291,7 @@ void,, (CBaseClient* self))
{
g_pServerAuthentication->m_bForceResetLocalPlayerPersistence = false;
g_pServerAuthentication->WritePersistentData(self);
- g_pServerPresence->SetPlayerCount(g_pServerAuthentication->m_PlayerAuthenticationData.size());
+ g_pServerPresence->SetPlayerCount((int)g_pServerAuthentication->m_PlayerAuthenticationData.size());
}
CBaseClient__ActivatePlayer(self);
@@ -326,7 +326,7 @@ void,, (CBaseClient* self, uint32_t unknownButAlways1, const char* pReason, ...)
g_pServerLimits->RemovePlayer(self);
}
- g_pServerPresence->SetPlayerCount(g_pServerAuthentication->m_PlayerAuthenticationData.size());
+ g_pServerPresence->SetPlayerCount((int)g_pServerAuthentication->m_PlayerAuthenticationData.size());
_CBaseClient__Disconnect(self, unknownButAlways1, buf);
}
diff --git a/primedev/server/r2server.h b/primedev/server/r2server.h
index c40cdc1f..1b7bc0b7 100644
--- a/primedev/server/r2server.h
+++ b/primedev/server/r2server.h
@@ -6,101 +6,250 @@
class CBaseEntity;
extern CBaseEntity* (*Server_GetEntityByIndex)(int index);
-// clang-format off
-OFFSET_STRUCT(CBasePlayer)
+#pragma pack(push, 1)
+class CBasePlayer
{
- FIELD(0x58, uint32_t m_nPlayerIndex)
-
- FIELD(0x23E8, bool m_grappleActive)
- FIELD(0x1D08, uint32_t m_platformUserId)
- FIELD(0x1D10, int32_t m_classModsActive)
- FIELD(0x1D8C, int32_t m_posClassModsActive)
- FIELD(0x1DCC, bool m_passives)
- FIELD(0x4948, int32_t m_selectedOffhand)
- FIELD(0x1358, int32_t m_selectedOffhandPendingHybridAction)
- FIELD(0x1E88, int32_t m_playerFlags)
- FIELD(0x26A8, int32_t m_lastUCmdSimulationTicks)
- FIELD(0x26AC, float m_lastUCmdSimulationRemainderTime)
- FIELD(0x1F04, int32_t m_remoteTurret)
- FIELD(0x414, int32_t m_hGroundEntity)
- FIELD(0x13B8, int32_t m_titanSoul)
- FIELD(0x2054, int32_t m_petTitan)
- FIELD(0x4D4, int32_t m_iHealth)
- FIELD(0x4D0, int32_t m_iMaxHealth)
- FIELD(0x4F1, int32_t m_lifeState)
- FIELD(0x50C, float m_flMaxspeed)
- FIELD(0x298, int32_t m_fFlags)
- FIELD(0x1F64, int32_t m_iObserverMode)
- FIELD(0x1F6C, int32_t m_hObserverTarget)
- FIELD(0x2098, int32_t m_hViewModel)
- FIELD(0x27E4, int32_t m_ubEFNointerpParity)
- FIELD(0x1FA4, int32_t m_activeBurnCardIndex)
- FIELD(0x1B68, int32_t m_hColorCorrectionCtrl)
- FIELD(0x19E0, int32_t m_PlayerFog__m_hCtrl)
- FIELD(0x26BC, bool m_bShouldDrawPlayerWhileUsingViewEntity)
- FIELD(0x2848, char m_title[32])
- FIELD(0x2964, bool m_useCredit)
- FIELD(0x1F40, float m_damageImpulseNoDecelEndTime)
- FIELD(0x1E8C, bool m_hasMic)
- FIELD(0x1E8D, bool m_inPartyChat)
- FIELD(0x1E90, float m_playerMoveSpeedScale)
- FIELD(0x1F58, float m_flDeathTime)
- FIELD(0x25A8, bool m_iSpawnParity)
- FIELD(0x102284, Vector3 m_upDir)
- FIELD(0x259C, float m_lastDodgeTime)
- FIELD(0x22E0, bool m_wallHanging)
- FIELD(0x22EC, int32_t m_traversalType)
- FIELD(0x22F0, int32_t m_traversalState)
- FIELD(0x2328, Vector3 m_traversalRefPos)
- FIELD(0x231C, Vector3 m_traversalForwardDir)
- FIELD(0x2354, float m_traversalYawDelta)
- FIELD(0x2358, int32_t m_traversalYawPoseParameter)
- FIELD(0x2050, int32_t m_grappleHook)
- FIELD(0x27C0, int32_t m_autoSprintForced)
- FIELD(0x27C4, bool m_fIsSprinting)
- FIELD(0x27CC, float m_sprintStartedTime)
- FIELD(0x27D0, float m_sprintStartedFrac)
- FIELD(0x27D4, float m_sprintEndedTime)
- FIELD(0x27D8, float m_sprintEndedFrac)
- FIELD(0x27DC, float m_stickySprintStartTime)
- FIELD(0x2998, float m_smartAmmoPreviousHighestLockOnMeFractionValue)
- FIELD(0x23FC, int32_t m_activeZipline)
- FIELD(0x2400, bool m_ziplineReverse)
- FIELD(0x2410, int32_t m_ziplineState)
- FIELD(0x2250, int32_t m_duckState)
- FIELD(0x2254, Vector3 m_StandHullMin)
- FIELD(0x2260, Vector3 m_StandHullMax)
- FIELD(0x226C, Vector3 m_DuckHullMin)
- FIELD(0x2278, Vector3 m_DuckHullMax)
- FIELD(0x205C, int32_t m_xp)
- FIELD(0x2060, int32_t m_generation)
- FIELD(0x2064, int32_t m_rank)
- FIELD(0x2068, int32_t m_serverForceIncreasePlayerListGenerationParity)
- FIELD(0x206C, bool m_isPlayingRanked)
- FIELD(0x2070, float m_skill_mu)
- FIELD(0x1E80, int32_t m_titanSoulBeingRodeoed)
- FIELD(0x1E84, int32_t m_entitySyncingWithMe)
- FIELD(0x2078, float m_nextTitanRespawnAvailable)
- FIELD(0x1C90, bool m_hasBadReputation)
- FIELD(0x1C91, char m_communityName[64])
- FIELD(0x1CD1, char m_communityClanTag[16])
- FIELD(0x1CE1, char m_factionName[16])
- FIELD(0x1CF1, char m_hardwareIcon[16])
- FIELD(0x1D01, bool m_happyHourActive)
- FIELD(0x1EF4, int32_t m_gestureAutoKillBitfield)
- FIELD(0x2EA8, int32_t m_pilotClassIndex)
- FIELD(0x100490, Vector3 m_vecAbsOrigin)
- FIELD(0x25BE, bool m_isPerformingBoostAction)
- FIELD(0x240C, bool m_ziplineValid3pWeaponLayerAnim)
- FIELD(0x345C, int32_t m_playerScriptNetDataGlobal)
- FIELD(0x1598, int32_t m_bZooming)
- FIELD(0x1599, bool m_zoomToggleOn)
- FIELD(0x159C, float m_zoomBaseFrac)
- FIELD(0x15A0, float m_zoomBaseTime)
- FIELD(0x15A4, float m_zoomFullStartTime)
- FIELD(0xA04, int32_t m_camoIndex)
- FIELD(0xA08, int32_t m_decalIndex)
+public:
+ char _unk_0x0[88]; // 0x0 ( Size: 88 )
+ uint32_t m_nPlayerIndex; // 0x58 ( Size: 4 )
+ char _unk_0x5c[572]; // 0x5c ( Size: 572 )
+ int32_t m_fFlags; // 0x298 ( Size: 4 )
+ char _unk_0x29c[376]; // 0x29c ( Size: 376 )
+ int32_t m_hGroundEntity; // 0x414 ( Size: 4 )
+ char _unk_0x418[184]; // 0x418 ( Size: 184 )
+ int32_t m_iMaxHealth; // 0x4d0 ( Size: 4 )
+ int32_t m_iHealth; // 0x4d4 ( Size: 4 )
+ char _unk_0x4d8[25]; // 0x4d8 ( Size: 25 )
+ int32_t m_lifeState; // 0x4f1 ( Size: 4 )
+ char _unk_0x4f5[23]; // 0x4f5 ( Size: 23 )
+ float m_flMaxspeed; // 0x50c ( Size: 4 )
+ char _unk_0x510[1268]; // 0x510 ( Size: 1268 )
+ int32_t m_camoIndex; // 0xa04 ( Size: 4 )
+ int32_t m_decalIndex; // 0xa08 ( Size: 4 )
+ char _unk_0xa0c[2380]; // 0xa0c ( Size: 2380 )
+ int32_t m_selectedOffhandPendingHybridAction; // 0x1358 ( Size: 4 )
+ char _unk_0x135c[92]; // 0x135c ( Size: 92 )
+ int32_t m_titanSoul; // 0x13b8 ( Size: 4 )
+ char _unk_0x13bc[476]; // 0x13bc ( Size: 476 )
+ bool m_bZooming; // 0x1598 ( Size: 1 )
+ bool m_zoomToggleOn; // 0x1599 ( Size: 1 )
+ char _unk_0x159a[2]; // 0x159a ( Size: 2 )
+ float m_zoomBaseFrac; // 0x159c ( Size: 4 )
+ float m_zoomBaseTime; // 0x15a0 ( Size: 4 )
+ float m_zoomFullStartTime; // 0x15a4 ( Size: 4 )
+ char _unk_0x15a8[1080]; // 0x15a8 ( Size: 1080 )
+ int32_t m_PlayerFog__m_hCtrl; // 0x19e0 ( Size: 4 )
+ char _unk_0x19e4[388]; // 0x19e4 ( Size: 388 )
+ int32_t m_hColorCorrectionCtrl; // 0x1b68 ( Size: 4 )
+ char _unk_0x1b6c[292]; // 0x1b6c ( Size: 292 )
+ bool m_hasBadReputation; // 0x1c90 ( Size: 1 )
+ char m_communityName[64]; // 0x1c91 ( Size: 64 )
+ char m_communityClanTag[16]; // 0x1cd1 ( Size: 16 )
+ char m_factionName[16]; // 0x1ce1 ( Size: 16 )
+ char m_hardwareIcon[16]; // 0x1cf1 ( Size: 16 )
+ bool m_happyHourActive; // 0x1d01 ( Size: 1 )
+ char _unk_0x1d02[6]; // 0x1d02 ( Size: 6 )
+ uint32_t m_platformUserId; // 0x1d08 ( Size: 4 )
+ char _unk_0x1d0c[4]; // 0x1d0c ( Size: 4 )
+ int32_t m_classModsActive; // 0x1d10 ( Size: 4 )
+ char _unk_0x1d14[120]; // 0x1d14 ( Size: 120 )
+ int32_t m_posClassModsActive; // 0x1d8c ( Size: 4 )
+ char _unk_0x1d90[60]; // 0x1d90 ( Size: 60 )
+ bool m_passives; // 0x1dcc ( Size: 1 )
+ char _unk_0x1dcd[179]; // 0x1dcd ( Size: 179 )
+ int32_t m_titanSoulBeingRodeoed; // 0x1e80 ( Size: 4 )
+ int32_t m_entitySyncingWithMe; // 0x1e84 ( Size: 4 )
+ int32_t m_playerFlags; // 0x1e88 ( Size: 4 )
+ bool m_hasMic; // 0x1e8c ( Size: 1 )
+ bool m_inPartyChat; // 0x1e8d ( Size: 1 )
+ char _unk_0x1e8e[2]; // 0x1e8e ( Size: 2 )
+ float m_playerMoveSpeedScale; // 0x1e90 ( Size: 4 )
+ char _unk_0x1e94[96]; // 0x1e94 ( Size: 96 )
+ int32_t m_gestureAutoKillBitfield; // 0x1ef4 ( Size: 4 )
+ char _unk_0x1ef8[12]; // 0x1ef8 ( Size: 12 )
+ int32_t m_remoteTurret; // 0x1f04 ( Size: 4 )
+ char _unk_0x1f08[56]; // 0x1f08 ( Size: 56 )
+ float m_damageImpulseNoDecelEndTime; // 0x1f40 ( Size: 4 )
+ char _unk_0x1f44[20]; // 0x1f44 ( Size: 20 )
+ float m_flDeathTime; // 0x1f58 ( Size: 4 )
+ char _unk_0x1f5c[8]; // 0x1f5c ( Size: 8 )
+ int32_t m_iObserverMode; // 0x1f64 ( Size: 4 )
+ char _unk_0x1f68[4]; // 0x1f68 ( Size: 4 )
+ int32_t m_hObserverTarget; // 0x1f6c ( Size: 4 )
+ char _unk_0x1f70[52]; // 0x1f70 ( Size: 52 )
+ int32_t m_activeBurnCardIndex; // 0x1fa4 ( Size: 4 )
+ char _unk_0x1fa8[168]; // 0x1fa8 ( Size: 168 )
+ int32_t m_grappleHook; // 0x2050 ( Size: 4 )
+ int32_t m_petTitan; // 0x2054 ( Size: 4 )
+ char _unk_0x2058[4]; // 0x2058 ( Size: 4 )
+ int32_t m_xp; // 0x205c ( Size: 4 )
+ int32_t m_generation; // 0x2060 ( Size: 4 )
+ int32_t m_rank; // 0x2064 ( Size: 4 )
+ int32_t m_serverForceIncreasePlayerListGenerationParity; // 0x2068 ( Size: 4 )
+ bool m_isPlayingRanked; // 0x206c ( Size: 1 )
+ char _unk_0x206d[3]; // 0x206d ( Size: 3 )
+ float m_skill_mu; // 0x2070 ( Size: 4 )
+ char _unk_0x2074[4]; // 0x2074 ( Size: 4 )
+ float m_nextTitanRespawnAvailable; // 0x2078 ( Size: 4 )
+ char _unk_0x207c[28]; // 0x207c ( Size: 28 )
+ int32_t m_hViewModel; // 0x2098 ( Size: 4 )
+ char _unk_0x209c[436]; // 0x209c ( Size: 436 )
+ int32_t m_duckState; // 0x2250 ( Size: 4 )
+ Vector3 m_StandHullMin; // 0x2254 ( Size: 12 )
+ Vector3 m_StandHullMax; // 0x2260 ( Size: 12 )
+ Vector3 m_DuckHullMin; // 0x226c ( Size: 12 )
+ Vector3 m_DuckHullMax; // 0x2278 ( Size: 12 )
+ char _unk_0x2284[92]; // 0x2284 ( Size: 92 )
+ bool m_wallHanging; // 0x22e0 ( Size: 1 )
+ char _unk_0x22e1[11]; // 0x22e1 ( Size: 11 )
+ int32_t m_traversalType; // 0x22ec ( Size: 4 )
+ int32_t m_traversalState; // 0x22f0 ( Size: 4 )
+ char _unk_0x22f4[40]; // 0x22f4 ( Size: 40 )
+ Vector3 m_traversalForwardDir; // 0x231c ( Size: 12 )
+ Vector3 m_traversalRefPos; // 0x2328 ( Size: 12 )
+ char _unk_0x2334[32]; // 0x2334 ( Size: 32 )
+ float m_traversalYawDelta; // 0x2354 ( Size: 4 )
+ int32_t m_traversalYawPoseParameter; // 0x2358 ( Size: 4 )
+ char _unk_0x235c[140]; // 0x235c ( Size: 140 )
+ bool m_grappleActive; // 0x23e8 ( Size: 1 )
+ char _unk_0x23e9[19]; // 0x23e9 ( Size: 19 )
+ int32_t m_activeZipline; // 0x23fc ( Size: 4 )
+ bool m_ziplineReverse; // 0x2400 ( Size: 1 )
+ char _unk_0x2401[11]; // 0x2401 ( Size: 11 )
+ bool m_ziplineValid3pWeaponLayerAnim; // 0x240c ( Size: 1 )
+ char _unk_0x240d[3]; // 0x240d ( Size: 3 )
+ int32_t m_ziplineState; // 0x2410 ( Size: 4 )
+ char _unk_0x2414[392]; // 0x2414 ( Size: 392 )
+ float m_lastDodgeTime; // 0x259c ( Size: 4 )
+ char _unk_0x25a0[8]; // 0x25a0 ( Size: 8 )
+ bool m_iSpawnParity; // 0x25a8 ( Size: 1 )
+ char _unk_0x25a9[21]; // 0x25a9 ( Size: 21 )
+ bool m_isPerformingBoostAction; // 0x25be ( Size: 1 )
+ char _unk_0x25bf[233]; // 0x25bf ( Size: 233 )
+ int32_t m_lastUCmdSimulationTicks; // 0x26a8 ( Size: 4 )
+ float m_lastUCmdSimulationRemainderTime; // 0x26ac ( Size: 4 )
+ char _unk_0x26b0[12]; // 0x26b0 ( Size: 12 )
+ bool m_bShouldDrawPlayerWhileUsingViewEntity; // 0x26bc ( Size: 1 )
+ char _unk_0x26bd[259]; // 0x26bd ( Size: 259 )
+ int32_t m_autoSprintForced; // 0x27c0 ( Size: 4 )
+ bool m_fIsSprinting; // 0x27c4 ( Size: 1 )
+ char _unk_0x27c5[7]; // 0x27c5 ( Size: 7 )
+ float m_sprintStartedTime; // 0x27cc ( Size: 4 )
+ float m_sprintStartedFrac; // 0x27d0 ( Size: 4 )
+ float m_sprintEndedTime; // 0x27d4 ( Size: 4 )
+ float m_sprintEndedFrac; // 0x27d8 ( Size: 4 )
+ float m_stickySprintStartTime; // 0x27dc ( Size: 4 )
+ char _unk_0x27e0[4]; // 0x27e0 ( Size: 4 )
+ int32_t m_ubEFNointerpParity; // 0x27e4 ( Size: 4 )
+ char _unk_0x27e8[96]; // 0x27e8 ( Size: 96 )
+ char m_title[32]; // 0x2848 ( Size: 32 )
+ char _unk_0x2868[252]; // 0x2868 ( Size: 252 )
+ bool m_useCredit; // 0x2964 ( Size: 1 )
+ char _unk_0x2965[51]; // 0x2965 ( Size: 51 )
+ float m_smartAmmoPreviousHighestLockOnMeFractionValue; // 0x2998 ( Size: 4 )
+ char _unk_0x299c[1292]; // 0x299c ( Size: 1292 )
+ int32_t m_pilotClassIndex; // 0x2ea8 ( Size: 4 )
+ char _unk_0x2eac[1456]; // 0x2eac ( Size: 1456 )
+ int32_t m_playerScriptNetDataGlobal; // 0x345c ( Size: 4 )
+ char _unk_0x3460[5352]; // 0x3460 ( Size: 5352 )
+ int32_t m_selectedOffhand; // 0x4948 ( Size: 4 )
+ char _unk_0x494c[1030980]; // 0x494c ( Size: 1030980 )
+ Vector3 m_vecAbsOrigin; // 0x100490 ( Size: 12 )
+ char _unk_0x10049c[7656]; // 0x10049c ( Size: 7656 )
+ Vector3 m_upDir; // 0x102284 ( Size: 12 )
};
-// clang-format on
+#pragma pack(pop)
+
+static_assert(offsetof(CBasePlayer, m_nPlayerIndex) == 0x58);
+
+static_assert(offsetof(CBasePlayer, m_grappleActive) == 0x23e8);
+static_assert(offsetof(CBasePlayer, m_platformUserId) == 0x1D08);
+static_assert(offsetof(CBasePlayer, m_classModsActive) == 0x1D10);
+static_assert(offsetof(CBasePlayer, m_posClassModsActive) == 0x1D8C);
+static_assert(offsetof(CBasePlayer, m_passives) == 0x1DCC);
+static_assert(offsetof(CBasePlayer, m_selectedOffhand) == 0x4948);
+static_assert(offsetof(CBasePlayer, m_selectedOffhandPendingHybridAction) == 0x1358);
+static_assert(offsetof(CBasePlayer, m_playerFlags) == 0x1E88);
+static_assert(offsetof(CBasePlayer, m_lastUCmdSimulationTicks) == 0x26A8);
+static_assert(offsetof(CBasePlayer, m_lastUCmdSimulationRemainderTime) == 0x26AC);
+static_assert(offsetof(CBasePlayer, m_remoteTurret) == 0x1F04);
+static_assert(offsetof(CBasePlayer, m_hGroundEntity) == 0x414);
+static_assert(offsetof(CBasePlayer, m_titanSoul) == 0x13B8);
+static_assert(offsetof(CBasePlayer, m_petTitan) == 0x2054);
+static_assert(offsetof(CBasePlayer, m_iHealth) == 0x4D4);
+static_assert(offsetof(CBasePlayer, m_iMaxHealth) == 0x4D0);
+static_assert(offsetof(CBasePlayer, m_lifeState) == 0x4F1);
+static_assert(offsetof(CBasePlayer, m_flMaxspeed) == 0x50C);
+static_assert(offsetof(CBasePlayer, m_fFlags) == 0x298);
+static_assert(offsetof(CBasePlayer, m_iObserverMode) == 0x1F64);
+static_assert(offsetof(CBasePlayer, m_hObserverTarget) == 0x1F6C);
+static_assert(offsetof(CBasePlayer, m_hViewModel) == 0x2098);
+static_assert(offsetof(CBasePlayer, m_ubEFNointerpParity) == 0x27E4);
+static_assert(offsetof(CBasePlayer, m_activeBurnCardIndex) == 0x1FA4);
+static_assert(offsetof(CBasePlayer, m_hColorCorrectionCtrl) == 0x1B68);
+static_assert(offsetof(CBasePlayer, m_PlayerFog__m_hCtrl) == 0x19E0);
+static_assert(offsetof(CBasePlayer, m_bShouldDrawPlayerWhileUsingViewEntity) == 0x26BC);
+static_assert(offsetof(CBasePlayer, m_title) == 0x2848);
+static_assert(offsetof(CBasePlayer, m_useCredit) == 0x2964);
+static_assert(offsetof(CBasePlayer, m_damageImpulseNoDecelEndTime) == 0x1F40);
+static_assert(offsetof(CBasePlayer, m_hasMic) == 0x1E8C);
+static_assert(offsetof(CBasePlayer, m_inPartyChat) == 0x1E8D);
+static_assert(offsetof(CBasePlayer, m_playerMoveSpeedScale) == 0x1E90);
+static_assert(offsetof(CBasePlayer, m_flDeathTime) == 0x1F58);
+static_assert(offsetof(CBasePlayer, m_iSpawnParity) == 0x25A8);
+static_assert(offsetof(CBasePlayer, m_upDir) == 0x102284);
+static_assert(offsetof(CBasePlayer, m_lastDodgeTime) == 0x259C);
+static_assert(offsetof(CBasePlayer, m_wallHanging) == 0x22E0);
+static_assert(offsetof(CBasePlayer, m_traversalType) == 0x22EC);
+static_assert(offsetof(CBasePlayer, m_traversalState) == 0x22F0);
+static_assert(offsetof(CBasePlayer, m_traversalRefPos) == 0x2328);
+static_assert(offsetof(CBasePlayer, m_traversalForwardDir) == 0x231C);
+static_assert(offsetof(CBasePlayer, m_traversalYawDelta) == 0x2354);
+static_assert(offsetof(CBasePlayer, m_traversalYawPoseParameter) == 0x2358);
+static_assert(offsetof(CBasePlayer, m_grappleHook) == 0x2050);
+static_assert(offsetof(CBasePlayer, m_autoSprintForced) == 0x27C0);
+static_assert(offsetof(CBasePlayer, m_fIsSprinting) == 0x27C4);
+static_assert(offsetof(CBasePlayer, m_sprintStartedTime) == 0x27CC);
+static_assert(offsetof(CBasePlayer, m_sprintStartedFrac) == 0x27D0);
+static_assert(offsetof(CBasePlayer, m_sprintEndedTime) == 0x27D4);
+static_assert(offsetof(CBasePlayer, m_sprintEndedFrac) == 0x27D8);
+static_assert(offsetof(CBasePlayer, m_stickySprintStartTime) == 0x27DC);
+static_assert(offsetof(CBasePlayer, m_smartAmmoPreviousHighestLockOnMeFractionValue) == 0x2998);
+static_assert(offsetof(CBasePlayer, m_activeZipline) == 0x23FC);
+static_assert(offsetof(CBasePlayer, m_ziplineReverse) == 0x2400);
+static_assert(offsetof(CBasePlayer, m_ziplineState) == 0x2410);
+static_assert(offsetof(CBasePlayer, m_duckState) == 0x2250);
+static_assert(offsetof(CBasePlayer, m_StandHullMin) == 0x2254);
+static_assert(offsetof(CBasePlayer, m_StandHullMax) == 0x2260);
+static_assert(offsetof(CBasePlayer, m_DuckHullMin) == 0x226C);
+static_assert(offsetof(CBasePlayer, m_DuckHullMax) == 0x2278);
+static_assert(offsetof(CBasePlayer, m_xp) == 0x205C);
+static_assert(offsetof(CBasePlayer, m_generation) == 0x2060);
+static_assert(offsetof(CBasePlayer, m_rank) == 0x2064);
+static_assert(offsetof(CBasePlayer, m_serverForceIncreasePlayerListGenerationParity) == 0x2068);
+static_assert(offsetof(CBasePlayer, m_isPlayingRanked) == 0x206C);
+static_assert(offsetof(CBasePlayer, m_skill_mu) == 0x2070);
+static_assert(offsetof(CBasePlayer, m_titanSoulBeingRodeoed) == 0x1E80);
+static_assert(offsetof(CBasePlayer, m_entitySyncingWithMe) == 0x1E84);
+static_assert(offsetof(CBasePlayer, m_nextTitanRespawnAvailable) == 0x2078);
+static_assert(offsetof(CBasePlayer, m_hasBadReputation) == 0x1C90);
+static_assert(offsetof(CBasePlayer, m_communityName) == 0x1C91);
+static_assert(offsetof(CBasePlayer, m_communityClanTag) == 0x1CD1);
+static_assert(offsetof(CBasePlayer, m_factionName) == 0x1CE1);
+static_assert(offsetof(CBasePlayer, m_hardwareIcon) == 0x1CF1);
+static_assert(offsetof(CBasePlayer, m_happyHourActive) == 0x1D01);
+static_assert(offsetof(CBasePlayer, m_gestureAutoKillBitfield) == 0x1EF4);
+static_assert(offsetof(CBasePlayer, m_pilotClassIndex) == 0x2EA8);
+static_assert(offsetof(CBasePlayer, m_vecAbsOrigin) == 0x100490);
+static_assert(offsetof(CBasePlayer, m_isPerformingBoostAction) == 0x25BE);
+static_assert(offsetof(CBasePlayer, m_ziplineValid3pWeaponLayerAnim) == 0x240C);
+static_assert(offsetof(CBasePlayer, m_playerScriptNetDataGlobal) == 0x345C);
+static_assert(offsetof(CBasePlayer, m_bZooming) == 0x1598);
+static_assert(offsetof(CBasePlayer, m_zoomToggleOn) == 0x1599);
+static_assert(offsetof(CBasePlayer, m_zoomBaseFrac) == 0x159C);
+static_assert(offsetof(CBasePlayer, m_zoomBaseTime) == 0x15A0);
+static_assert(offsetof(CBasePlayer, m_zoomFullStartTime) == 0x15A4);
+static_assert(offsetof(CBasePlayer, m_camoIndex) == 0xA04);
+static_assert(offsetof(CBasePlayer, m_decalIndex) == 0xA08);
extern CBasePlayer*(__fastcall* UTIL_PlayerByIndex)(int playerIndex);
diff --git a/primedev/shared/exploit_fixes/exploitfixes.cpp b/primedev/shared/exploit_fixes/exploitfixes.cpp
index 8064d5ac..44651b3c 100644
--- a/primedev/shared/exploit_fixes/exploitfixes.cpp
+++ b/primedev/shared/exploit_fixes/exploitfixes.cpp
@@ -262,7 +262,7 @@ bool, __fastcall, (const char* pModName)) // 48 83 EC 28 48 8B 0D ? ? ? ? 48 8D
// clang-format on
{
// somewhat temp, store the modname here, since we don't have a proper ptr in engine to it rn
- int iSize = strlen(pModName);
+ size_t iSize = strlen(pModName);
g_pModName = new char[iSize + 1];
strcpy(g_pModName, pModName);
@@ -323,7 +323,7 @@ bool, __fastcall, (CBaseClient* self, uint32_t unknown, const char* pCommandStri
"load_recent_checkpoint" // This is the instant-respawn exploit, literally just calls RespawnPlayer()
};
- int iCmdLength = strlen(tempCommand.Arg(0));
+ size_t iCmdLength = strlen(tempCommand.Arg(0));
bool bIsBadCommand = false;
for (auto& blockedCommand : blockedCommands)
diff --git a/primedev/shared/misccommands.cpp b/primedev/shared/misccommands.cpp
index 15da6767..648525b9 100644
--- a/primedev/shared/misccommands.cpp
+++ b/primedev/shared/misccommands.cpp
@@ -60,7 +60,7 @@ void ConCommand_cvar_setdefaultvalue(const CCommand& arg)
}
// unfortunately no way for us to not leak memory here, as default value might not be in writeable memory by default
- int nLen = strlen(arg.Arg(2));
+ size_t nLen = strlen(arg.Arg(2));
char* pBuf = new char[nLen + 1];
strncpy_s(pBuf, nLen + 1, arg.Arg(2), nLen);
@@ -83,7 +83,7 @@ void ConCommand_cvar_setvalueanddefaultvalue(const CCommand& arg)
}
// unfortunately no way for us to not leak memory here, as default value might not be in writeable memory by default
- int nLen = strlen(arg.Arg(2));
+ size_t nLen = strlen(arg.Arg(2));
char* pBuf = new char[nLen + 1];
strncpy_s(pBuf, nLen + 1, arg.Arg(2), nLen);
diff --git a/primedev/squirrel/squirrel.cpp b/primedev/squirrel/squirrel.cpp
index 43e43398..affedebb 100644
--- a/primedev/squirrel/squirrel.cpp
+++ b/primedev/squirrel/squirrel.cpp
@@ -659,7 +659,7 @@ template <ScriptContext context> void SquirrelManager<context>::ProcessMessageBu
pushobject(m_pSQVM->sqvm, &functionobj); // Push the function object
pushroottable(m_pSQVM->sqvm);
- int argsAmount = message.args.size();
+ size_t argsAmount = message.args.size();
if (message.isExternal && message.externalFunc != NULL)
{
@@ -674,7 +674,7 @@ template <ScriptContext context> void SquirrelManager<context>::ProcessMessageBu
}
}
- _call(m_pSQVM->sqvm, argsAmount);
+ _call(m_pSQVM->sqvm, (SQInteger)argsAmount);
}
}
diff --git a/primedev/squirrel/squirrel.h b/primedev/squirrel/squirrel.h
index a4932044..17f4186d 100644
--- a/primedev/squirrel/squirrel.h
+++ b/primedev/squirrel/squirrel.h
@@ -399,7 +399,7 @@ public:
v();
}
- return _call(m_pSQVM->sqvm, functionVector.size());
+ return _call(m_pSQVM->sqvm, (SQInteger)functionVector.size());
}
#pragma endregion
@@ -470,7 +470,7 @@ template <ScriptContext context, typename T>
requires (std::convertible_to<T, std::string> || std::is_constructible_v<std::string, T>)
inline VoidFunction SQMessageBufferPushArg(T& arg) {
auto converted = std::string(arg);
- return [converted]{ g_pSquirrel<context>->pushstring(g_pSquirrel<context>->m_pSQVM->sqvm, converted.c_str(), converted.length()); };
+ return [converted]{ g_pSquirrel<context>->pushstring(g_pSquirrel<context>->m_pSQVM->sqvm, converted.c_str(), (int)converted.length()); };
}
// Assets
template <ScriptContext context>
diff --git a/primedev/thirdparty/rapidjson/document.h b/primedev/thirdparty/rapidjson/document.h
index e3e20dfb..22fb2f56 100644
--- a/primedev/thirdparty/rapidjson/document.h
+++ b/primedev/thirdparty/rapidjson/document.h
@@ -198,17 +198,19 @@ private:
// class-based member iterator implementation disabled, use plain pointers
template <bool Const, typename Encoding, typename Allocator>
-struct GenericMemberIterator;
+class GenericMemberIterator;
//! non-const GenericMemberIterator
template <typename Encoding, typename Allocator>
-struct GenericMemberIterator<false,Encoding,Allocator> {
+class GenericMemberIterator<false,Encoding,Allocator> {
+public:
//! use plain pointer as iterator type
typedef GenericMember<Encoding,Allocator>* Iterator;
};
//! const GenericMemberIterator
template <typename Encoding, typename Allocator>
-struct GenericMemberIterator<true,Encoding,Allocator> {
+class GenericMemberIterator<true,Encoding,Allocator> {
+public:
//! use plain const pointer as iterator type
typedef const GenericMember<Encoding,Allocator>* Iterator;
};
@@ -1822,17 +1824,18 @@ private:
// Initial flags of different types.
kNullFlag = kNullType,
- kTrueFlag = kTrueType | kBoolFlag,
- kFalseFlag = kFalseType | kBoolFlag,
- kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,
- kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,
- kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,
- kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,
- kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,
- kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,
- kConstStringFlag = kStringType | kStringFlag,
- kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,
- kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag,
+ // These casts are added to suppress the warning on MSVC about bitwise operations between enums of different types.
+ kTrueFlag = static_cast<int>(kTrueType) | static_cast<int>(kBoolFlag),
+ kFalseFlag = static_cast<int>(kFalseType) | static_cast<int>(kBoolFlag),
+ kNumberIntFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag),
+ kNumberUintFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag),
+ kNumberInt64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kInt64Flag),
+ kNumberUint64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUint64Flag),
+ kNumberDoubleFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kDoubleFlag),
+ kNumberAnyFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag),
+ kConstStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag),
+ kCopyStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag),
+ kShortStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag | kInlineStrFlag),
kObjectFlag = kObjectType,
kArrayFlag = kArrayType,
diff --git a/primedev/util/printcommands.cpp b/primedev/util/printcommands.cpp
index 34d56666..20ebfffc 100644
--- a/primedev/util/printcommands.cpp
+++ b/primedev/util/printcommands.cpp
@@ -52,12 +52,12 @@ void PrintCommandHelpDialogue(const ConCommandBase* command, const char* name)
void TryPrintCvarHelpForCommand(const char* pCommand)
{
// try to display help text for an inputted command string from the console
- int pCommandLen = strlen(pCommand);
+ size_t pCommandLen = strlen(pCommand);
char* pCvarStr = new char[pCommandLen];
strcpy(pCvarStr, pCommand);
// trim whitespace from right
- for (int i = pCommandLen - 1; i; i--)
+ for (size_t i = pCommandLen - 1; i; i--)
{
if (isspace(pCvarStr[i]))
pCvarStr[i] = '\0';
diff --git a/primedev/util/printmaps.cpp b/primedev/util/printmaps.cpp
index d3253605..906bed06 100644
--- a/primedev/util/printmaps.cpp
+++ b/primedev/util/printmaps.cpp
@@ -136,9 +136,9 @@ int, __fastcall, (const char *const cmdname, const char *const partial, char com
RefreshMapList();
// use a custom autocomplete func for all map loading commands
- const int cmdLength = strlen(cmdname);
+ const size_t cmdLength = strlen(cmdname);
const char* query = partial + cmdLength;
- const int queryLength = strlen(query);
+ const size_t queryLength = strlen(query);
int numMaps = 0;
for (int i = 0; i < vMapList.size() && numMaps < COMMAND_COMPLETION_MAXITEMS; i++)
diff --git a/primedev/util/utils.h b/primedev/util/utils.h
index 85922692..1a419607 100644
--- a/primedev/util/utils.h
+++ b/primedev/util/utils.h
@@ -1,3 +1,23 @@
#pragma once
void RemoveAsciiControlSequences(char* str, bool allow_color_codes);
+
+class ScopeGuard
+{
+public:
+ auto operator=(ScopeGuard&) = delete;
+ ScopeGuard(ScopeGuard&) = delete;
+
+ ScopeGuard(std::function<void()> callback) : m_callback(callback) {}
+ ~ScopeGuard()
+ {
+ m_callback();
+ }
+ void Dismiss()
+ {
+ m_callback = [] {};
+ }
+
+private:
+ std::function<void()> m_callback;
+};
diff --git a/primedev/wsockproxy/loader.cpp b/primedev/wsockproxy/loader.cpp
index 3e46c1a6..0a299ba8 100644
--- a/primedev/wsockproxy/loader.cpp
+++ b/primedev/wsockproxy/loader.cpp
@@ -54,7 +54,7 @@ bool LoadNorthstar()
std::string cla = std::string(clachar);
if (strncmp(cla.substr(9, 1).c_str(), "\"", 1))
{
- int space = cla.find(" ");
+ size_t space = cla.find(" ");
std::string dirname = cla.substr(9, space - 9);
std::cout << "[*] Found profile in command line arguments: " << dirname << std::endl;
strProfile = dirname.c_str();
@@ -62,8 +62,8 @@ bool LoadNorthstar()
else
{
std::string quote = "\"";
- int quote1 = cla.find(quote);
- int quote2 = (cla.substr(quote1 + 1)).find(quote);
+ size_t quote1 = cla.find(quote);
+ size_t quote2 = (cla.substr(quote1 + 1)).find(quote);
std::string dirname = cla.substr(quote1 + 1, quote2);
std::cout << "[*] Found profile in command line arguments: " << dirname << std::endl;
strProfile = dirname;