mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Compare commits
131 Commits
v2.5_rc5_e
...
p4sync
Author | SHA1 | Date | |
---|---|---|---|
|
d73ce9ed72 | ||
|
dea3888973 | ||
|
f2e332efa0 | ||
|
7de9196d7d | ||
|
905f496474 | ||
|
5d7c94ae2f | ||
|
def96b25a7 | ||
|
85d99364cb | ||
|
08646370c4 | ||
|
3c30d959dd | ||
|
1e1fe1beff | ||
|
0a0eeca20a | ||
|
b0423ee74b | ||
|
fdab5dea84 | ||
|
f491f3dfe3 | ||
|
b1d81e2dc5 | ||
|
e223cec9c2 | ||
|
7607ca073f | ||
|
8b0bdae883 | ||
|
f0f90e5c1b | ||
|
d36ea4d769 | ||
|
1331c3c67b | ||
|
26ec02f302 | ||
|
73b517600d | ||
|
bfe96e9ccd | ||
|
8646dfa516 | ||
|
fde639e167 | ||
|
bb566cd1fd | ||
|
e27fc72e25 | ||
|
18e71086b6 | ||
|
4188c13780 | ||
|
13301bceae | ||
|
d6cff51624 | ||
|
ff303d5de8 | ||
|
d7ebf62c38 | ||
|
27285fc087 | ||
|
eaf313ab7a | ||
|
e8fc542907 | ||
|
3ac646da64 | ||
|
e55975100e | ||
|
949b71a162 | ||
|
c4bf79376e | ||
|
72cbe5bc63 | ||
|
d810768895 | ||
|
456a68af05 | ||
|
b8550c9f32 | ||
|
24bce8ee73 | ||
|
8339c44c25 | ||
|
5a6c655196 | ||
|
56aba36b8c | ||
|
f18dd71f4b | ||
|
51931b59db | ||
|
b288d072db | ||
|
e63660b549 | ||
|
c8ee0d4333 | ||
|
b4f68d69ce | ||
|
0f17987599 | ||
|
452c226316 | ||
|
66a271d003 | ||
|
c8c321e924 | ||
|
a5bd66513a | ||
|
5584c2a87f | ||
|
5f5bbb9164 | ||
|
726b5c9fbc | ||
|
bf7f128acf | ||
|
291a99e3ae | ||
|
5742163756 | ||
|
bf3bd90dc7 | ||
|
9eeb0606e7 | ||
|
1766530af1 | ||
|
2dc28bb742 | ||
|
2083bc73fa | ||
|
aa405dc4c3 | ||
|
d3a2fd5238 | ||
|
d049b2df1c | ||
|
de4a3d294c | ||
|
9bcbf3187c | ||
|
18f2e27409 | ||
|
03dd7046a6 | ||
|
eee6aed033 | ||
|
ec9fc7d77f | ||
|
6827d1ed02 | ||
|
716a3efa0c | ||
|
c2deaaf3e8 | ||
|
74d8cdfb26 | ||
|
4d4fb66477 | ||
|
117e2d77e4 | ||
|
e9a2aea17c | ||
|
5d000db867 | ||
|
1a5a77f9c8 | ||
|
d8326575e5 | ||
|
4a2f5d2aa5 | ||
|
68271b9768 | ||
|
e1f0de0089 | ||
|
164c594486 | ||
|
37e3c8c653 | ||
|
4445edac6d | ||
|
561fc25c8e | ||
|
6d4de8c5b7 | ||
|
ca7b0d9981 | ||
|
b1ad2c19b8 | ||
|
3cbdab512d | ||
|
b617caf1d8 | ||
|
538df8e02c | ||
|
05f37cad73 | ||
|
e6c7c7d279 | ||
|
62d0dab7cd | ||
|
746660490b | ||
|
059f9fc82d | ||
|
aefebd846e | ||
|
aba1ed26b5 | ||
|
48e79faffa | ||
|
49d1f6f1fe | ||
|
3b44bbc6bc | ||
|
bd9beaa33a | ||
|
5e0c24ad84 | ||
|
36d2b3534a | ||
|
d20488c919 | ||
|
f0511a89a7 | ||
|
8720dde3cb | ||
|
6ae072386d | ||
|
6bf516f1ef | ||
|
b75655c101 | ||
|
4ffcc4ca75 | ||
|
bef61249fd | ||
|
c6d451c753 | ||
|
26f48507f4 | ||
|
2a357914da | ||
|
92842e4ac2 | ||
|
5f8afd9cf0 | ||
|
5369b21a64 |
@ -12,7 +12,6 @@ set( FOLDER_CONTEXT "Libraries" )
|
||||
add_subdirectory( mathlib )
|
||||
add_subdirectory( vpklib )
|
||||
add_subdirectory( vstdlib )
|
||||
add_subdirectory( vphysics )
|
||||
add_subdirectory( ebisusdk )
|
||||
add_subdirectory( codecs )
|
||||
add_subdirectory( geforce )
|
||||
@ -68,7 +67,9 @@ add_subdirectory( inputsystem )
|
||||
add_subdirectory( filesystem )
|
||||
add_subdirectory( datacache )
|
||||
add_subdirectory( studiorender )
|
||||
add_subdirectory( particles )
|
||||
add_subdirectory( localize )
|
||||
add_subdirectory( vphysics )
|
||||
add_subdirectory( engine )
|
||||
add_subdirectory( vguimatsurface )
|
||||
add_subdirectory( vgui )
|
||||
|
@ -117,6 +117,6 @@ void MilesCore::Detour(const bool bAttach) const
|
||||
DetourSetup(&v_AIL_LogFunc, &AIL_LogFunc, bAttach);
|
||||
DetourSetup(&v_Miles_Initialize, &Miles_Initialize, bAttach);
|
||||
DetourSetup(&v_MilesQueueEventRun, &MilesQueueEventRun, bAttach);
|
||||
DetourSetup(&v_MilesBankPatch, &MilesBankPatch, bAttach);
|
||||
//DetourSetup(&v_MilesBankPatch, &MilesBankPatch, bAttach);
|
||||
DetourSetup(&v_CSOM_AddEventToQueue, &CSOM_AddEventToQueue, bAttach);
|
||||
}
|
||||
|
@ -287,61 +287,59 @@ Mat_CrossHair_f
|
||||
Print the material under the crosshair.
|
||||
=====================
|
||||
*/
|
||||
static void PrintChildMat(const CMaterialGlue* const materialGlue, const char* const text)
|
||||
{
|
||||
Msg(eDLL_T::MS, " |-+\n");
|
||||
Msg(eDLL_T::MS, " | |-+ Child material ----------------------------------------\n");
|
||||
Msg(eDLL_T::MS, text, materialGlue);
|
||||
|
||||
if (materialGlue)
|
||||
{
|
||||
const MaterialGlue_s* const material = materialGlue->Get();
|
||||
|
||||
Msg(eDLL_T::MS, " | |-- Pak GUID: '%llX'\n", material->guid);
|
||||
Msg(eDLL_T::MS, " | |-- Material name: '%s'\n", material->name);
|
||||
}
|
||||
}
|
||||
|
||||
void Mat_CrossHair_f(const CCommand& args)
|
||||
{
|
||||
CMaterialGlue* material = v_GetMaterialAtCrossHair();
|
||||
if (material)
|
||||
{
|
||||
Msg(eDLL_T::MS, "______________________________________________________________\n");
|
||||
Msg(eDLL_T::MS, "-+ Material --------------------------------------------------\n");
|
||||
Msg(eDLL_T::MS, " |-- ADDR: '%llX'\n", material);
|
||||
Msg(eDLL_T::MS, " |-- GUID: '%llX'\n", material->assetGuid);
|
||||
Msg(eDLL_T::MS, " |-- Num Streaming Textures: '%d'\n", material->numStreamingTextureHandles);
|
||||
Msg(eDLL_T::MS, " |-- Material width: '%d'\n", material->width);
|
||||
Msg(eDLL_T::MS, " |-- Material height: '%d'\n", material->height);
|
||||
Msg(eDLL_T::MS, " |-- Samplers: '%08X'\n", material->samplers);
|
||||
const CMaterialGlue* const materialGlue = v_GetMaterialAtCrossHair();
|
||||
|
||||
std::function<void(CMaterialGlue*, const char*)> fnPrintChild = [](CMaterialGlue* material, const char* print)
|
||||
{
|
||||
Msg(eDLL_T::MS, " |-+\n");
|
||||
Msg(eDLL_T::MS, " | |-+ Child material ----------------------------------------\n");
|
||||
Msg(eDLL_T::MS, print, material);
|
||||
Msg(eDLL_T::MS, " | |-- GUID: '%llX'\n", material->assetGuid);
|
||||
Msg(eDLL_T::MS, " | |-- Material name: '%s'\n", material->name);
|
||||
};
|
||||
|
||||
Msg(eDLL_T::MS, " |-- Material name: '%s'\n", material->name);
|
||||
Msg(eDLL_T::MS, " |-- Material surface name 1: '%s'\n", material->surfaceProp);
|
||||
Msg(eDLL_T::MS, " |-- Material surface name 2: '%s'\n", material->surfaceProp2);
|
||||
Msg(eDLL_T::MS, " |-- DX buffer: '%llX'\n", material->dxBuffer);
|
||||
Msg(eDLL_T::MS, " |-- DX buffer VFTable: '%llX'\n", material->unkD3DPointer);
|
||||
|
||||
material->depthShadowMaterial
|
||||
? fnPrintChild(material->depthShadowMaterial, " | |-+ DepthShadow: '%llX'\n")
|
||||
: Msg(eDLL_T::MS, " | |-+ DepthShadow: 'NULL'\n");
|
||||
material->depthPrepassMaterial
|
||||
? fnPrintChild(material->depthPrepassMaterial, " | |-+ DepthPrepass: '%llX'\n")
|
||||
: Msg(eDLL_T::MS, " | |-+ DepthPrepass: 'NULL'\n");
|
||||
material->depthVSMMaterial
|
||||
? fnPrintChild(material->depthVSMMaterial, " | |-+ DepthVSM: '%llX'\n")
|
||||
: Msg(eDLL_T::MS, " | |-+ DepthVSM: 'NULL'\n");
|
||||
material->depthShadowTightMaterial
|
||||
? fnPrintChild(material->depthShadowTightMaterial, " | |-+ DepthShadowTight: '%llX'\n")
|
||||
: Msg(eDLL_T::MS, " | |-+ DepthShadowTight: 'NULL'\n");
|
||||
material->colpassMaterial
|
||||
? fnPrintChild(material->colpassMaterial, " | |-+ ColPass: '%llX'\n")
|
||||
: Msg(eDLL_T::MS, " | |-+ ColPass: 'NULL'\n");
|
||||
|
||||
Msg(eDLL_T::MS, "-+ Texture GUID map ------------------------------------------\n");
|
||||
Msg(eDLL_T::MS, " |-- Texture handles: '%llX'\n", material->textureHandles);
|
||||
Msg(eDLL_T::MS, " |-- Streaming texture handles: '%llX'\n", material->streamingTextureHandles);
|
||||
|
||||
Msg(eDLL_T::MS, "--------------------------------------------------------------\n");
|
||||
}
|
||||
else
|
||||
if (!materialGlue)
|
||||
{
|
||||
Msg(eDLL_T::MS, "%s: No material found >:(\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
const MaterialGlue_s* const material = materialGlue->Get();
|
||||
|
||||
Msg(eDLL_T::MS, "______________________________________________________________\n");
|
||||
Msg(eDLL_T::MS, "-+ Material --------------------------------------------------\n");
|
||||
Msg(eDLL_T::MS, " |-- Address: '%llX'\n", material);
|
||||
Msg(eDLL_T::MS, " |-- Pak GUID: '%llX'\n", material->guid);
|
||||
Msg(eDLL_T::MS, " |-- Samplers: '%08X'\n", *(uint32*)material->samplers);
|
||||
Msg(eDLL_T::MS, " |-- Streaming handles: '%hu'\n", material->streamingTextureHandleCount);
|
||||
Msg(eDLL_T::MS, " |-- Material width: '%hu'\n", material->width);
|
||||
Msg(eDLL_T::MS, " |-- Material height: '%hu'\n", material->height);
|
||||
|
||||
Msg(eDLL_T::MS, " |-- Material name: '%s'\n", material->name);
|
||||
Msg(eDLL_T::MS, " |-- Material surface name 1: '%s'\n", material->surfaceProp);
|
||||
Msg(eDLL_T::MS, " |-- Material surface name 2: '%s'\n", material->surfaceProp2);
|
||||
Msg(eDLL_T::MS, " |-- Uber buffer: '%llX'\n", material->uberBuffer);
|
||||
Msg(eDLL_T::MS, " |-- View buffer: '%llX'\n", material->viewBuffer);
|
||||
|
||||
PrintChildMat(material->depthMaterials[DEPTH_SHADOW], " | |-+ Depth shadow: '%llX'\n");
|
||||
PrintChildMat(material->depthMaterials[DEPTH_PREPASS], " | |-+ Depth prepass: '%llX'\n");
|
||||
PrintChildMat(material->depthMaterials[DEPTH_VSM], " | |-+ Depth VSM: '%llX'\n");
|
||||
PrintChildMat(material->depthMaterials[DEPTH_SHADOW_TIGHT], " | |-+ Depth shadow tight: '%llX'\n");
|
||||
PrintChildMat(material->colpassMaterial, " | |-+ Color pass: '%llX'\n");
|
||||
|
||||
Msg(eDLL_T::MS, "-+ Texture GUID map ------------------------------------------\n");
|
||||
Msg(eDLL_T::MS, " |-- Texture handles: '%llX'\n", material->textureHandles);
|
||||
Msg(eDLL_T::MS, " |-- Streaming texture handles: '%llX'\n", material->streamingTextureHandles);
|
||||
|
||||
Msg(eDLL_T::MS, "--------------------------------------------------------------\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -57,6 +57,7 @@ ConVar* r_visualizetraces_duration = nullptr;
|
||||
|
||||
ConVar* stream_overlay = nullptr;
|
||||
ConVar* stream_overlay_mode = nullptr;
|
||||
ConVar* gpu_driven_tex_stream = nullptr;
|
||||
|
||||
ConVar* eula_version = nullptr;
|
||||
ConVar* eula_version_accepted = nullptr;
|
||||
@ -186,8 +187,11 @@ void ConVar_InitShipped(void)
|
||||
#endif // !DEDICATED
|
||||
staticProp_no_fade_scalar = g_pCVar->FindVar("staticProp_no_fade_scalar");
|
||||
staticProp_gather_size_weight = g_pCVar->FindVar("staticProp_gather_size_weight");
|
||||
#ifndef DEDICATED
|
||||
stream_overlay = g_pCVar->FindVar("stream_overlay");
|
||||
stream_overlay_mode = g_pCVar->FindVar("stream_overlay_mode");
|
||||
gpu_driven_tex_stream = g_pCVar->FindVar("gpu_driven_tex_stream");
|
||||
#endif // !DEDICATED
|
||||
sv_cheats = g_pCVar->FindVar("sv_cheats");
|
||||
sv_visualizetraces = g_pCVar->FindVar("sv_visualizetraces");
|
||||
sv_visualizetraces_duration = g_pCVar->FindVar("sv_visualizetraces_duration");
|
||||
|
@ -39,10 +39,11 @@ extern ConVar* mp_gamemode;
|
||||
#ifndef DEDICATED
|
||||
extern ConVar* r_visualizetraces;
|
||||
extern ConVar* r_visualizetraces_duration;
|
||||
#endif // !DEDICATED
|
||||
|
||||
extern ConVar* stream_overlay;
|
||||
extern ConVar* stream_overlay_mode;
|
||||
extern ConVar* gpu_driven_tex_stream;
|
||||
#endif // !DEDICATED
|
||||
//-------------------------------------------------------------------------
|
||||
// SHARED |
|
||||
extern ConVar* eula_version;
|
||||
|
@ -4,10 +4,11 @@
|
||||
//
|
||||
//===========================================================================//
|
||||
#pragma once
|
||||
#include "netcon/INetCon.h"
|
||||
|
||||
typedef int SocketHandle_t;
|
||||
|
||||
enum class ServerDataRequestType_t : int
|
||||
enum class ServerDataRequestType_e : int
|
||||
{
|
||||
SERVERDATA_REQUEST_VALUE = 0,
|
||||
SERVERDATA_REQUEST_SETVALUE,
|
||||
@ -17,7 +18,7 @@ enum class ServerDataRequestType_t : int
|
||||
SERVERDATA_REQUEST_SEND_REMOTEBUG,
|
||||
};
|
||||
|
||||
enum class ServerDataResponseType_t : int
|
||||
enum class ServerDataResponseType_e : int
|
||||
{
|
||||
SERVERDATA_RESPONSE_VALUE = 0,
|
||||
SERVERDATA_RESPONSE_UPDATE,
|
||||
@ -27,20 +28,20 @@ enum class ServerDataResponseType_t : int
|
||||
SERVERDATA_RESPONSE_REMOTEBUG,
|
||||
};
|
||||
|
||||
class CConnectedNetConsoleData
|
||||
struct ConnectedNetConsoleData_s
|
||||
{
|
||||
public:
|
||||
SocketHandle_t m_hSocket;
|
||||
int m_nPayloadLen; // Num bytes for this message.
|
||||
int m_nPayloadRead; // Num read bytes from input buffer.
|
||||
int m_nFailedAttempts; // Num failed authentication attempts.
|
||||
int m_nIgnoredMessage; // Count how many times client ignored the no-auth message.
|
||||
u32 m_nPayloadLen; // Num bytes for this message.
|
||||
u32 m_nPayloadRead; // Num read bytes from input buffer.
|
||||
u32 m_nFailedAttempts; // Num failed authentication attempts.
|
||||
u32 m_nIgnoredMessage; // Count how many times client ignored the no-auth message.
|
||||
bool m_bValidated; // Revalidates netconsole if false.
|
||||
bool m_bAuthorized; // Set to true after successful netconsole auth.
|
||||
bool m_bInputOnly; // If set, don't send spew to this netconsole.
|
||||
vector<uint8_t> m_RecvBuffer;
|
||||
NetConFrameHeader_s m_FrameHeader; // Current frame header.
|
||||
vector<byte> m_RecvBuffer;
|
||||
|
||||
CConnectedNetConsoleData(SocketHandle_t hSocket = -1)
|
||||
ConnectedNetConsoleData_s(SocketHandle_t hSocket = -1)
|
||||
{
|
||||
m_hSocket = hSocket;
|
||||
m_nPayloadLen = 0;
|
||||
@ -50,22 +51,19 @@ public:
|
||||
m_bValidated = false;
|
||||
m_bAuthorized = false;
|
||||
m_bInputOnly = true;
|
||||
m_RecvBuffer.resize(sizeof(u_long)); // Reserve enough for length-prefix.
|
||||
m_FrameHeader.magic = 0;
|
||||
m_FrameHeader.length = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/* PACKET FORMAT **********************************
|
||||
|
||||
REQUEST:
|
||||
int requestID;
|
||||
int ServerDataRequestType_t;
|
||||
NullTerminatedString (variable or command)
|
||||
NullTerminatedString (value)
|
||||
NetConFrameHeader_s header;
|
||||
byte* data;
|
||||
|
||||
RESPONSE:
|
||||
int requestID;
|
||||
int ServerDataResponseType_t;
|
||||
NullTerminatedString (variable)
|
||||
NullTerminatedString (value)
|
||||
NetConFrameHeader_s header;
|
||||
byte* data;
|
||||
|
||||
***************************************************/
|
||||
|
@ -70,24 +70,24 @@ bool SVC_UserMessage::ProcessImpl()
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
bool SVC_SetClassVar::ReadFromBuffer(bf_read* buffer)
|
||||
{
|
||||
const bool set = buffer->ReadString(m_szSetting, sizeof(m_szSetting));
|
||||
const bool var = buffer->ReadString(m_szVariable, sizeof(m_szVariable));
|
||||
const bool key = buffer->ReadString(m_szKey, sizeof(m_szKey));
|
||||
const bool val = buffer->ReadString(m_szValue, sizeof(m_szValue));
|
||||
|
||||
return set && var;
|
||||
return key && val;
|
||||
}
|
||||
bool SVC_SetClassVar::WriteToBuffer(bf_write* buffer)
|
||||
{
|
||||
const bool set = buffer->WriteString(m_szSetting);
|
||||
const bool var = buffer->WriteString(m_szVariable);
|
||||
const bool key = buffer->WriteString(m_szKey);
|
||||
const bool val = buffer->WriteString(m_szValue);
|
||||
|
||||
return set && var;
|
||||
return key && val;
|
||||
}
|
||||
bool SVC_SetClassVar::Process(void)
|
||||
{
|
||||
const char* pArgs[3] = {
|
||||
"_setClassVarClient",
|
||||
m_szSetting,
|
||||
m_szVariable
|
||||
m_szKey,
|
||||
m_szValue
|
||||
};
|
||||
|
||||
CCommand command((int)V_ARRAYSIZE(pArgs), pArgs, cmd_source_t::kCommandSrcCode);
|
||||
|
@ -464,13 +464,13 @@ class SVC_SetClassVar : public CNetMessage
|
||||
{
|
||||
public:
|
||||
SVC_SetClassVar() = default;
|
||||
SVC_SetClassVar(const char* setting, const char* var)
|
||||
SVC_SetClassVar(const char* key, const char* value)
|
||||
{
|
||||
V_strncpy(m_szSetting, setting, sizeof(m_szSetting));
|
||||
V_strncpy(m_szVariable, var, sizeof(m_szVariable));
|
||||
V_strncpy(m_szKey, key, sizeof(m_szKey));
|
||||
V_strncpy(m_szValue, value, sizeof(m_szValue));
|
||||
|
||||
m_szSetting[sizeof(m_szSetting) - 1] = '\0';
|
||||
m_szVariable[sizeof(m_szVariable) - 1] = '\0';
|
||||
m_szKey[sizeof(m_szKey) - 1] = '\0';
|
||||
m_szValue[sizeof(m_szValue) - 1] = '\0';
|
||||
|
||||
m_nGroup = 2; // must be set to 2 to avoid being copied into replay buffer
|
||||
}
|
||||
@ -486,15 +486,15 @@ public:
|
||||
virtual const char* ToString(void) const
|
||||
{
|
||||
static char szBuf[4096];
|
||||
V_snprintf(szBuf, sizeof(szBuf), "%s: setting \"%s\", variable \"%s\"", this->GetName(), m_szSetting, m_szVariable);
|
||||
V_snprintf(szBuf, sizeof(szBuf), "%s: key \"%s\", value \"%s\"", this->GetName(), m_szKey, m_szValue);
|
||||
|
||||
return szBuf;
|
||||
};
|
||||
|
||||
virtual size_t GetSize(void) const { return sizeof(SVC_SetClassVar); }
|
||||
|
||||
char m_szSetting[128];
|
||||
char m_szVariable[128];
|
||||
char m_szKey[128];
|
||||
char m_szValue[128];
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -113,6 +113,8 @@ target_link_libraries( ${PROJECT_NAME} PRIVATE
|
||||
"vgui"
|
||||
"rui"
|
||||
|
||||
"particles"
|
||||
|
||||
"d3d11.lib"
|
||||
"${THIRDPARTY_SOURCE_DIR}/nvapi/amd64/nvapi64.lib"
|
||||
)
|
||||
|
@ -58,8 +58,8 @@ void Show_Emblem()
|
||||
|
||||
// Log the SDK's 'build_id' under the emblem.
|
||||
Msg(eDLL_T::SYSTEM_ERROR,
|
||||
"+------------------------------------------------[%s%010d%s]-+\n",
|
||||
g_svYellowF, g_SDKDll.GetNTHeaders()->FileHeader.TimeDateStamp, g_svRedF);
|
||||
"+------------------------------------------------[%s%010u%s]-+\n",
|
||||
g_svYellowF.c_str(), g_SDKDll.GetNTHeaders()->FileHeader.TimeDateStamp, g_svRedF.c_str());
|
||||
Msg(eDLL_T::SYSTEM_ERROR, "\n");
|
||||
}
|
||||
|
||||
|
@ -44,11 +44,13 @@
|
||||
#include "materialsystem/cmaterialsystem.h"
|
||||
#ifndef DEDICATED
|
||||
#include "materialsystem/cmaterialglue.h"
|
||||
#include "materialsystem/texturestreaming.h"
|
||||
#include "vgui/vgui_baseui_interface.h"
|
||||
#include "vgui/vgui_debugpanel.h"
|
||||
#include "vgui/vgui_fpspanel.h"
|
||||
#include "vgui/vgui_controls/RichText.h"
|
||||
#include "vguimatsurface/MatSystemSurface.h"
|
||||
#include "particles/particles.h"
|
||||
#include "engine/client/vengineclient_impl.h"
|
||||
#include "engine/client/cdll_engine_int.h"
|
||||
#include "engine/client/datablock_receiver.h"
|
||||
@ -561,6 +563,7 @@ void DetourRegister() // Register detour classes to be searched and hooked.
|
||||
#ifndef DEDICATED
|
||||
REGISTER(VMaterialGlue);
|
||||
REGISTER(VShaderGlue);
|
||||
REGISTER(VTextureStreaming);
|
||||
|
||||
// Studio
|
||||
REGISTER(VStudioRenderContext);
|
||||
@ -571,6 +574,9 @@ void DetourRegister() // Register detour classes to be searched and hooked.
|
||||
REGISTER(VVGUIRichText); // REGISTER CLIENT ONLY!
|
||||
REGISTER(VMatSystemSurface);
|
||||
|
||||
// Particles
|
||||
REGISTER(VParticles);
|
||||
|
||||
// Client
|
||||
REGISTER(HVEngineClient);
|
||||
REGISTER(VDll_Engine_Int);
|
||||
|
@ -2,13 +2,8 @@
|
||||
#include "core/logdef.h"
|
||||
|
||||
std::shared_ptr<spdlog::logger> g_TermLogger;
|
||||
std::shared_ptr<spdlog::logger> g_ImGuiLogger;
|
||||
|
||||
std::shared_ptr<spdlog::logger> g_SuppementalToolsLogger;
|
||||
|
||||
std::ostringstream g_LogStream;
|
||||
std::shared_ptr<spdlog::sinks::ostream_sink_st> g_LogSink;
|
||||
|
||||
#ifndef _TOOLS
|
||||
static void SpdLog_CreateRotatingLoggers()
|
||||
{
|
||||
@ -68,16 +63,6 @@ void SpdLog_Init(const bool bAnsiColor)
|
||||
}
|
||||
|
||||
g_LogSessionDirectory = fmt::format("platform/logs/{:s}", g_LogSessionUUID);
|
||||
/************************
|
||||
* IMGUI LOGGER SETUP *
|
||||
************************/
|
||||
{
|
||||
g_LogSink = std::make_shared<spdlog::sinks::ostream_sink_st>(g_LogStream);
|
||||
g_ImGuiLogger = std::make_shared<spdlog::logger>("game_console", g_LogSink);
|
||||
spdlog::register_logger(g_ImGuiLogger); // in-game console logger.
|
||||
g_ImGuiLogger->set_pattern("%v");
|
||||
g_ImGuiLogger->set_level(spdlog::level::trace);
|
||||
}
|
||||
#endif // !_TOOLS
|
||||
/************************
|
||||
* WINDOWS LOGGER SETUP *
|
||||
@ -99,7 +84,6 @@ void SpdLog_Init(const bool bAnsiColor)
|
||||
{
|
||||
g_TermLogger->set_pattern("%v");
|
||||
}
|
||||
//g_TermLogger->set_level(spdlog::level::trace);
|
||||
}
|
||||
|
||||
#ifndef _TOOLS
|
||||
|
@ -22,11 +22,6 @@ extern std::shared_ptr<spdlog::logger> g_ImGuiLogger;
|
||||
extern std::shared_ptr<spdlog::logger> g_SuppementalToolsLogger;
|
||||
#endif // _TOOLS
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// IMGUI CONSOLE SINK |
|
||||
extern std::ostringstream g_LogStream;
|
||||
extern std::shared_ptr<spdlog::sinks::ostream_sink_st> g_LogSink;
|
||||
|
||||
void SpdLog_Init(const bool bAnsiColor);
|
||||
void SpdLog_Shutdown(void);
|
||||
|
||||
|
@ -72,21 +72,24 @@ ImVec4 GetColorForContext(LogType_t type, eDLL_T context)
|
||||
}
|
||||
#endif // !DEDICATED && !_TOOLS
|
||||
|
||||
const char* GetContextNameByIndex(eDLL_T context, const bool ansiColor = false)
|
||||
static const char* GetContextNameByIndex(eDLL_T context, size_t& numTotalChars, size_t& numAnsiChars, const bool ansiColor)
|
||||
{
|
||||
int index = static_cast<int>(context);
|
||||
const char* contextName = s_DefaultAnsiColor;
|
||||
const int index = static_cast<int>(context);
|
||||
const char* contextName;
|
||||
|
||||
switch (context)
|
||||
{
|
||||
case eDLL_T::SCRIPT_SERVER:
|
||||
contextName = s_ScriptAnsiColor[0];
|
||||
numTotalChars = s_FullAnsiContextPrefixTextSize;
|
||||
break;
|
||||
case eDLL_T::SCRIPT_CLIENT:
|
||||
contextName = s_ScriptAnsiColor[1];
|
||||
numTotalChars = s_FullAnsiContextPrefixTextSize;
|
||||
break;
|
||||
case eDLL_T::SCRIPT_UI:
|
||||
contextName = s_ScriptAnsiColor[2];
|
||||
numTotalChars = s_FullAnsiContextPrefixTextSize;
|
||||
break;
|
||||
case eDLL_T::SERVER:
|
||||
case eDLL_T::CLIENT:
|
||||
@ -102,17 +105,22 @@ const char* GetContextNameByIndex(eDLL_T context, const bool ansiColor = false)
|
||||
case eDLL_T::SYSTEM_WARNING:
|
||||
case eDLL_T::SYSTEM_ERROR:
|
||||
contextName = s_DllAnsiColor[index];
|
||||
numTotalChars = context >= eDLL_T::COMMON ? s_AnsiColorTextSize : s_FullAnsiContextPrefixTextSize;
|
||||
break;
|
||||
case eDLL_T::NONE:
|
||||
default:
|
||||
contextName = s_DefaultAnsiColor;
|
||||
numTotalChars = s_AnsiColorTextSize;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ansiColor)
|
||||
{
|
||||
// Shift # chars to skip ANSI row.
|
||||
contextName += sizeof(s_DefaultAnsiColor) - 1;
|
||||
contextName += s_AnsiColorTextSize;
|
||||
numTotalChars -= s_AnsiColorTextSize;
|
||||
}
|
||||
else
|
||||
numAnsiChars = s_AnsiColorTextSize;
|
||||
|
||||
return contextName;
|
||||
}
|
||||
@ -147,11 +155,16 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
|
||||
const char* pszUpTime = pszUptimeOverride ? pszUptimeOverride : Plat_GetProcessUpTime();
|
||||
string message(pszUpTime);
|
||||
|
||||
const size_t contextTextStartIndex = message.length();
|
||||
|
||||
const bool bToConsole = (logLevel >= LogLevel_t::LEVEL_CONSOLE);
|
||||
const bool bUseColor = (bToConsole && g_bSpdLog_UseAnsiClr);
|
||||
|
||||
const char* pszContext = GetContextNameByIndex(context, bUseColor);
|
||||
message.append(pszContext);
|
||||
size_t numTotalContextTextChars = 0;
|
||||
size_t numAnsiContextChars = 0;
|
||||
|
||||
const char* pszContext = GetContextNameByIndex(context, numTotalContextTextChars, numAnsiContextChars, bUseColor);
|
||||
message.append(pszContext, numTotalContextTextChars);
|
||||
|
||||
#if !defined (DEDICATED) && !defined (_TOOLS)
|
||||
ImVec4 overlayColor = GetColorForContext(logType, context);
|
||||
@ -166,6 +179,9 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
|
||||
NOTE_UNUSED(pszLogger);
|
||||
#endif // !_TOOLS
|
||||
|
||||
const size_t messageTextStartIndex = message.length();
|
||||
size_t numMessageAnsiChars = 0;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Setup logger and context
|
||||
//-------------------------------------------------------------------------
|
||||
@ -178,6 +194,7 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
|
||||
if (bUseColor)
|
||||
{
|
||||
message.append(g_svYellowF);
|
||||
numMessageAnsiChars = g_svYellowF.length();
|
||||
}
|
||||
break;
|
||||
case LogType_t::LOG_ERROR:
|
||||
@ -187,6 +204,7 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
|
||||
if (bUseColor)
|
||||
{
|
||||
message.append(g_svRedF);
|
||||
numMessageAnsiChars = g_svRedF.length();
|
||||
}
|
||||
break;
|
||||
#ifndef _TOOLS
|
||||
@ -248,12 +266,28 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
|
||||
|
||||
if (bUseColor)
|
||||
{
|
||||
message.append(g_svRedF);
|
||||
if (logType != LogType_t::LOG_ERROR)
|
||||
{
|
||||
if (numMessageAnsiChars > 0)
|
||||
message.replace(messageTextStartIndex, numMessageAnsiChars, g_svRedF);
|
||||
else
|
||||
message.append(g_svRedF);
|
||||
|
||||
numMessageAnsiChars = g_svRedF.length();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bUseColor && bWarning)
|
||||
{
|
||||
message.append(g_svYellowF);
|
||||
if (logType != LogType_t::LOG_ERROR)
|
||||
{
|
||||
if (numMessageAnsiChars > 0)
|
||||
message.replace(messageTextStartIndex, numMessageAnsiChars, g_svYellowF);
|
||||
else
|
||||
message.append(g_svYellowF);
|
||||
|
||||
numMessageAnsiChars = g_svYellowF.length();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // !_TOOLS
|
||||
@ -267,9 +301,24 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
|
||||
{
|
||||
g_TermLogger->debug(message);
|
||||
|
||||
// Remove ANSI rows if we have them, before emitting to file or over wire.
|
||||
if (bUseColor)
|
||||
{
|
||||
// Remove ANSI rows before emitting to file or over wire.
|
||||
// Start with the message first because else the indices will shift.
|
||||
// The message colors comes after the context colors.
|
||||
if (numMessageAnsiChars > 0)
|
||||
{
|
||||
message.erase(messageTextStartIndex, numMessageAnsiChars);
|
||||
numMessageAnsiChars = 0;
|
||||
}
|
||||
|
||||
if (numAnsiContextChars > 0)
|
||||
{
|
||||
message.erase(contextTextStartIndex, numAnsiContextChars);
|
||||
numAnsiContextChars = 0;
|
||||
}
|
||||
|
||||
// Remove anything else that was passed in as a format argument.
|
||||
message = std::regex_replace(message, s_AnsiRowRegex, "");
|
||||
}
|
||||
}
|
||||
@ -282,38 +331,32 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
|
||||
// Output is always logged to the file.
|
||||
std::shared_ptr<spdlog::logger> ntlogger = spdlog::get(pszLogger); // <-- Obtain by 'pszLogger'.
|
||||
assert(ntlogger.get() != nullptr);
|
||||
ntlogger->debug(message);
|
||||
|
||||
if (ntlogger)
|
||||
ntlogger->debug(message);
|
||||
|
||||
if (bToConsole)
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
if (!LoggedFromClient(context) && RCONServer()->ShouldSend(netcon::response_e::SERVERDATA_RESPONSE_CONSOLE_LOG))
|
||||
{
|
||||
RCONServer()->SendEncoded(formatted.c_str(), pszUpTime, netcon::response_e::SERVERDATA_RESPONSE_CONSOLE_LOG,
|
||||
RCONServer()->SendEncoded(formatted.c_str(), formatted.length(), pszUpTime, contextTextStartIndex, netcon::response_e::SERVERDATA_RESPONSE_CONSOLE_LOG,
|
||||
int(context), int(logType));
|
||||
}
|
||||
#endif // !CLIENT_DLL
|
||||
#ifndef DEDICATED
|
||||
g_ImGuiLogger->debug(message);
|
||||
|
||||
const string logStreamBuf = g_LogStream.str();
|
||||
g_Console.AddLog(logStreamBuf.c_str(), ImGui::ColorConvertFloat4ToU32(overlayColor));
|
||||
g_Console.AddLog(message.c_str(), ImGui::ColorConvertFloat4ToU32(overlayColor));
|
||||
|
||||
// We can only log to the in-game overlay console when the SDK has
|
||||
// been fully initialized, due to the use of ConVar's.
|
||||
if (g_bSdkInitialized && logLevel >= LogLevel_t::LEVEL_NOTIFY)
|
||||
{
|
||||
// Draw to mini console.
|
||||
g_TextOverlay.AddLog(overlayContext, logStreamBuf.c_str());
|
||||
g_TextOverlay.AddLog(overlayContext, message.c_str(), (ssize_t)message.length());
|
||||
}
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
|
||||
#ifndef DEDICATED
|
||||
g_LogStream.str(string());
|
||||
g_LogStream.clear();
|
||||
#endif // !DEDICATED
|
||||
|
||||
#else
|
||||
if (g_SuppementalToolsLogger)
|
||||
{
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <functional>
|
||||
#include <charconv>
|
||||
|
||||
#include <smmintrin.h>
|
||||
|
||||
|
@ -25,6 +25,24 @@
|
||||
|
||||
#include "thirdparty/curl/include/curl/curl.h"
|
||||
|
||||
// RapidJSON uses 32 bit size types. Size types are
|
||||
// 64 bit wide on our target. Override it with ours.
|
||||
// this must be done before the rapidjson.h include.
|
||||
#define RAPIDJSON_NO_SIZETYPEDEFINE
|
||||
namespace rapidjson { typedef ::std::size_t SizeType; }
|
||||
|
||||
#include "rapidjson/rapidjson.h"
|
||||
|
||||
#ifdef RAPIDJSON_USE_CUSTOM_ALLOCATOR
|
||||
// Must be included before the RapidJSON includes
|
||||
// as this replaces the default allocator. The new
|
||||
// allocator takes SIMD alignment into account, but
|
||||
// isn't strictly necessary when using RAPIDJSON_SIMD.
|
||||
#include "tier2/jsonalloc.h"
|
||||
#define RAPIDJSON_DEFAULT_ALLOCATOR ::RAPIDJSON_NAMESPACE::MemoryPoolAllocator<JSONAllocator>
|
||||
#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR ::RAPIDJSON_NAMESPACE::MemoryPoolAllocator<JSONAllocator>
|
||||
#endif // RAPIDJSON_USE_CUSTOM_ALLOCATOR
|
||||
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/writer.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
|
@ -1,19 +1,19 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "core/termutil.h"
|
||||
|
||||
const char* g_svGreyF = "";
|
||||
const char* g_svRedF = "";
|
||||
const char* g_svGreenF = "";
|
||||
const char* g_svBlueF = "";
|
||||
const char* g_svYellowF = "";
|
||||
std::string g_svGreyF;
|
||||
std::string g_svRedF;
|
||||
std::string g_svGreenF;
|
||||
std::string g_svBlueF;
|
||||
std::string g_svYellowF;
|
||||
|
||||
const char* g_svGreyB = "";
|
||||
const char* g_svRedB = "";
|
||||
const char* g_svGreenB = "";
|
||||
const char* g_svBlueB = "";
|
||||
const char* g_svYellowB = "";
|
||||
std::string g_svGreyB;
|
||||
std::string g_svRedB;
|
||||
std::string g_svGreenB;
|
||||
std::string g_svBlueB;
|
||||
std::string g_svYellowB;
|
||||
|
||||
const char* g_svReset = "";
|
||||
std::string g_svReset;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the global ansi escape sequences.
|
||||
|
@ -1,16 +1,16 @@
|
||||
#pragma once
|
||||
extern const char* g_svGreyF;
|
||||
extern const char* g_svRedF;
|
||||
extern const char* g_svGreenF;
|
||||
extern const char* g_svBlueF;
|
||||
extern const char* g_svYellowF;
|
||||
extern std::string g_svGreyF;
|
||||
extern std::string g_svRedF;
|
||||
extern std::string g_svGreenF;
|
||||
extern std::string g_svBlueF;
|
||||
extern std::string g_svYellowF;
|
||||
|
||||
extern const char* g_svGreyB;
|
||||
extern const char* g_svRedB;
|
||||
extern const char* g_svGreenB;
|
||||
extern const char* g_svBlueB;
|
||||
extern const char* g_svYellowB;
|
||||
extern std::string g_svGreyB;
|
||||
extern std::string g_svRedB;
|
||||
extern std::string g_svGreenB;
|
||||
extern std::string g_svBlueB;
|
||||
extern std::string g_svYellowB;
|
||||
|
||||
extern const char* g_svReset;
|
||||
extern std::string g_svReset;
|
||||
|
||||
void AnsiColors_Init();
|
||||
|
@ -162,6 +162,8 @@ add_sources( SOURCE_GROUP "GameUI"
|
||||
"${ENGINE_SOURCE_DIR}/gameui/IBrowser.h"
|
||||
"${ENGINE_SOURCE_DIR}/gameui/IConsole.cpp"
|
||||
"${ENGINE_SOURCE_DIR}/gameui/IConsole.h"
|
||||
"${ENGINE_SOURCE_DIR}/gameui/IStreamOverlay.cpp"
|
||||
"${ENGINE_SOURCE_DIR}/gameui/IStreamOverlay.h"
|
||||
|
||||
"${ENGINE_SOURCE_DIR}/gameui/imgui_system.cpp"
|
||||
"${ENGINE_SOURCE_DIR}/gameui/imgui_system.h"
|
||||
@ -227,6 +229,8 @@ add_sources( SOURCE_GROUP "Public"
|
||||
"${ENGINE_SOURCE_DIR}/public/networkvar.h"
|
||||
"${ENGINE_SOURCE_DIR}/public/playerstate.h"
|
||||
|
||||
"${ENGINE_SOURCE_DIR}/public/netcon/INetCon.h"
|
||||
|
||||
# These probably need to go to 'bsplib' if we ever create that project.
|
||||
"${ENGINE_SOURCE_DIR}/public/bspflags.h"
|
||||
"${ENGINE_SOURCE_DIR}/public/bspfile.h"
|
||||
|
@ -73,7 +73,7 @@ void CRConClient::RunFrame(void)
|
||||
{
|
||||
if (IsInitialized() && IsConnected())
|
||||
{
|
||||
CConnectedNetConsoleData* pData = GetData();
|
||||
ConnectedNetConsoleData_s* pData = GetData();
|
||||
Assert(pData != nullptr);
|
||||
|
||||
if (pData)
|
||||
@ -105,7 +105,7 @@ void CRConClient::Disconnect(const char* szReason)
|
||||
// Input : *pMsgBug -
|
||||
// nMsgLen -
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConClient::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
|
||||
bool CRConClient::ProcessMessage(const byte* const pMsgBuf, const u32 nMsgLen)
|
||||
{
|
||||
netcon::response response;
|
||||
|
||||
@ -162,13 +162,13 @@ void CRConClient::RequestConsoleLog(const bool bWantLog)
|
||||
// sending logs will cause the print func to get called recursively forever.
|
||||
Assert(!(bWantLog && IsRemoteLocal()));
|
||||
|
||||
const char* szEnable = bWantLog ? "1" : "0";
|
||||
const char* const szEnable = bWantLog ? "1" : "0";
|
||||
const SocketHandle_t hSocket = GetSocket();
|
||||
|
||||
vector<char> vecMsg;
|
||||
bool ret = Serialize(vecMsg, "", szEnable, netcon::request_e::SERVERDATA_REQUEST_SEND_CONSOLE_LOG);
|
||||
vector<byte> vecMsg;
|
||||
const bool ret = Serialize(vecMsg, "", 0, szEnable, 1, netcon::request_e::SERVERDATA_REQUEST_SEND_CONSOLE_LOG);
|
||||
|
||||
if (ret && !Send(hSocket, vecMsg.data(), int(vecMsg.size())))
|
||||
if (ret && !Send(hSocket, vecMsg.data(), (u32)vecMsg.size()))
|
||||
{
|
||||
Error(eDLL_T::CLIENT, NO_ERROR, "Failed to send RCON message: (%s)\n", "SOCKET_ERROR");
|
||||
}
|
||||
@ -177,14 +177,16 @@ void CRConClient::RequestConsoleLog(const bool bWantLog)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: serializes input
|
||||
// Input : *svReqBuf -
|
||||
// nReqMsgLen -
|
||||
// *svReqVal -
|
||||
// nReqValLen -
|
||||
// request_t -
|
||||
// Output : serialized results as string
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConClient::Serialize(vector<char>& vecBuf, const char* szReqBuf,
|
||||
const char* szReqVal, const netcon::request_e requestType) const
|
||||
bool CRConClient::Serialize(vector<byte>& vecBuf, const char* szReqBuf, const size_t nReqMsgLen,
|
||||
const char* szReqVal, const size_t nReqValLen, const netcon::request_e requestType) const
|
||||
{
|
||||
return NetconClient_Serialize(this, vecBuf, szReqBuf, szReqVal, requestType,
|
||||
return NetconClient_Serialize(this, vecBuf, szReqBuf, nReqMsgLen, szReqVal, nReqValLen, requestType,
|
||||
rcon_encryptframes.GetBool(), rcon_debug.GetBool());
|
||||
}
|
||||
|
||||
@ -192,7 +194,7 @@ bool CRConClient::Serialize(vector<char>& vecBuf, const char* szReqBuf,
|
||||
// Purpose: retrieves the remote socket
|
||||
// Output : SOCKET_ERROR (-1) on failure
|
||||
//-----------------------------------------------------------------------------
|
||||
CConnectedNetConsoleData* CRConClient::GetData(void)
|
||||
ConnectedNetConsoleData_s* CRConClient::GetData(void)
|
||||
{
|
||||
return NetconShared_GetConnData(this, 0);
|
||||
}
|
||||
@ -321,7 +323,7 @@ static void RCON_CmdQuery_f(const CCommand& args)
|
||||
}
|
||||
else if (RCONClient()->IsConnected())
|
||||
{
|
||||
vector<char> vecMsg;
|
||||
vector<byte> vecMsg;
|
||||
bool bSuccess = false;
|
||||
const SocketHandle_t hSocket = RCONClient()->GetSocket();
|
||||
|
||||
@ -329,7 +331,10 @@ static void RCON_CmdQuery_f(const CCommand& args)
|
||||
{
|
||||
if (argCount > 2)
|
||||
{
|
||||
bSuccess = RCONClient()->Serialize(vecMsg, args.Arg(2), "", netcon::request_e::SERVERDATA_REQUEST_AUTH);
|
||||
const char* const pass = args.Arg(2);
|
||||
const size_t passLen = strlen(pass);
|
||||
|
||||
bSuccess = RCONClient()->Serialize(vecMsg, pass, passLen, "", 0, netcon::request_e::SERVERDATA_REQUEST_AUTH);
|
||||
}
|
||||
else // Need at least 3 arguments for a password in PASS command (rcon PASS <password>)
|
||||
{
|
||||
@ -339,7 +344,7 @@ static void RCON_CmdQuery_f(const CCommand& args)
|
||||
|
||||
if (bSuccess)
|
||||
{
|
||||
RCONClient()->Send(hSocket, vecMsg.data(), int(vecMsg.size()));
|
||||
RCONClient()->Send(hSocket, vecMsg.data(), (u32)vecMsg.size());
|
||||
}
|
||||
|
||||
return;
|
||||
@ -350,10 +355,16 @@ static void RCON_CmdQuery_f(const CCommand& args)
|
||||
return;
|
||||
}
|
||||
|
||||
bSuccess = RCONClient()->Serialize(vecMsg, args.Arg(1), args.ArgS(), netcon::request_e::SERVERDATA_REQUEST_EXECCOMMAND);
|
||||
const char* const request = args.Arg(1);
|
||||
const size_t requestLen = strlen(request);
|
||||
|
||||
const char* const value = args.ArgS();
|
||||
const size_t valueLen = strlen(value);
|
||||
|
||||
bSuccess = RCONClient()->Serialize(vecMsg, request, requestLen, value, valueLen, netcon::request_e::SERVERDATA_REQUEST_EXECCOMMAND);
|
||||
if (bSuccess)
|
||||
{
|
||||
RCONClient()->Send(hSocket, vecMsg.data(), int(vecMsg.size()));
|
||||
RCONClient()->Send(hSocket, vecMsg.data(), (u32)vecMsg.size());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -15,10 +15,10 @@ public:
|
||||
void RunFrame(void);
|
||||
|
||||
virtual void Disconnect(const char* szReason = nullptr) override;
|
||||
virtual bool ProcessMessage(const char* pMsgBuf, const int nMsgLen) override;
|
||||
virtual bool ProcessMessage(const byte* pMsgBuf, const u32 nMsgLen) override;
|
||||
|
||||
bool Serialize(vector<char>& vecBuf, const char* szReqBuf,
|
||||
const char* szReqVal, const netcon::request_e requestType) const;
|
||||
bool Serialize(vector<byte>& vecBuf, const char* szReqBuf, const size_t nReqMsgLen,
|
||||
const char* szReqVal, const size_t nReqValLen, const netcon::request_e requestType) const;
|
||||
|
||||
void RequestConsoleLog(const bool bWantLog);
|
||||
bool ShouldReceive(void);
|
||||
@ -27,7 +27,7 @@ public:
|
||||
bool IsInitialized(void) const;
|
||||
bool IsConnected(void);
|
||||
|
||||
CConnectedNetConsoleData* GetData(void);
|
||||
ConnectedNetConsoleData_s* GetData(void);
|
||||
SocketHandle_t GetSocket(void);
|
||||
|
||||
private:
|
||||
|
@ -158,5 +158,5 @@ static bool HK_ProcessDataBlock(ClientDataBlockReceiver* receiver, const double
|
||||
|
||||
void VClientDataBlockReceiver::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourAttach(&ClientDataBlockReceiver__ProcessDataBlock, HK_ProcessDataBlock);
|
||||
DetourSetup(&ClientDataBlockReceiver__ProcessDataBlock, HK_ProcessDataBlock, bAttach);
|
||||
}
|
||||
|
@ -31,13 +31,13 @@
|
||||
CUtlVector<CUtlString> g_InstalledMaps;
|
||||
CFmtStrN<MAX_MAP_NAME> s_CurrentLevelName;
|
||||
|
||||
static CustomPakData_t s_customPakData;
|
||||
static CustomPakData_s s_customPakData;
|
||||
static KeyValues* s_pLevelSetKV = nullptr;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: load a custom pak and add it to the list
|
||||
//-----------------------------------------------------------------------------
|
||||
PakHandle_t CustomPakData_t::LoadAndAddPak(const char* const pakFile)
|
||||
PakHandle_t CustomPakData_s::LoadAndAddPak(const char* const pakFile)
|
||||
{
|
||||
if (numHandles >= MAX_CUSTOM_PAKS)
|
||||
{
|
||||
@ -60,7 +60,7 @@ PakHandle_t CustomPakData_t::LoadAndAddPak(const char* const pakFile)
|
||||
// NOTE : the array must be kept contiguous; this means that the last pak in
|
||||
// the array should always be unloaded fist!
|
||||
//-----------------------------------------------------------------------------
|
||||
void CustomPakData_t::UnloadAndRemovePak(const int index)
|
||||
void CustomPakData_s::UnloadAndRemovePak(const int index)
|
||||
{
|
||||
const PakHandle_t pakId = handles[index];
|
||||
assert(pakId != PAK_INVALID_HANDLE); // invalid handles should not be inserted
|
||||
@ -75,12 +75,12 @@ void CustomPakData_t::UnloadAndRemovePak(const int index)
|
||||
// Purpose: preload a custom pak; this keeps it available throughout the
|
||||
// duration of the process, unless manually removed by user.
|
||||
//-----------------------------------------------------------------------------
|
||||
PakHandle_t CustomPakData_t::PreloadAndAddPak(const char* const pakFile)
|
||||
PakHandle_t CustomPakData_s::PreloadAndAddPak(const char* const pakFile)
|
||||
{
|
||||
// this must never be called after a non-preloaded pak has been added!
|
||||
// preloaded paks must always appear before custom user requested paks
|
||||
// due to the unload order: user-requested -> preloaded -> sdk -> core.
|
||||
assert(handles[CustomPakData_t::PAK_TYPE_COUNT+numPreload] == PAK_INVALID_HANDLE);
|
||||
assert(handles[CustomPakData_s::PAK_TYPE_COUNT+numPreload] == PAK_INVALID_HANDLE);
|
||||
|
||||
const PakHandle_t pakId = LoadAndAddPak(pakFile);
|
||||
|
||||
@ -93,38 +93,35 @@ PakHandle_t CustomPakData_t::PreloadAndAddPak(const char* const pakFile)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: unloads all non-preloaded custom pak handles
|
||||
//-----------------------------------------------------------------------------
|
||||
void CustomPakData_t::UnloadAndRemoveNonPreloaded()
|
||||
void CustomPakData_s::UnloadAndRemoveNonPreloaded()
|
||||
{
|
||||
// Preloaded paks should not be unloaded here, but only right before sdk /
|
||||
// engine paks are unloaded. Only unload user requested and level settings
|
||||
// paks from here. Also, the load and unload order here is FIFO, this is
|
||||
// needed because when you load a pak, and then load another pak which
|
||||
// happens to have an overlapping asset, the asset will be updated with
|
||||
// that of the newer pak. If we remove the newer pak, the engine will try
|
||||
// and revert the asset to its original state. However we asynchronously
|
||||
// unload everything on a single FIFO lock so this is undefined behavior.
|
||||
for (int i = CustomPakData_t::PAK_TYPE_COUNT+numPreload, n = numHandles; i < n; i++)
|
||||
// paks from here. Unload them in reverse order, the last pak loaded should
|
||||
// be the first one to be unloaded.
|
||||
for (int n = numHandles-1; n >= CustomPakData_s::PAK_TYPE_COUNT + numPreload; n--)
|
||||
{
|
||||
UnloadAndRemovePak(i);
|
||||
UnloadAndRemovePak(n);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: unloads all preloaded custom pak handles
|
||||
//-----------------------------------------------------------------------------
|
||||
void CustomPakData_t::UnloadAndRemovePreloaded()
|
||||
void CustomPakData_s::UnloadAndRemovePreloaded()
|
||||
{
|
||||
for (int i = 0, n = numPreload; i < n; i++)
|
||||
// Unload them in reverse order, the last pak loaded should be the first
|
||||
// one to be unloaded.
|
||||
for (; numPreload > 0; numPreload--)
|
||||
{
|
||||
UnloadAndRemovePak(CustomPakData_t::PAK_TYPE_COUNT + i);
|
||||
numPreload--;
|
||||
UnloadAndRemovePak(CustomPakData_s::PAK_TYPE_COUNT + (numPreload-1));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: loads the base SDK pak file by type
|
||||
//-----------------------------------------------------------------------------
|
||||
PakHandle_t CustomPakData_t::LoadBasePak(const char* const pakFile, const EPakType type)
|
||||
PakHandle_t CustomPakData_s::LoadBasePak(const char* const pakFile, const PakType_e type)
|
||||
{
|
||||
const PakHandle_t pakId = g_pakLoadApi->LoadAsync(pakFile, AlignedMemAlloc(), 4, 0);
|
||||
|
||||
@ -138,7 +135,7 @@ PakHandle_t CustomPakData_t::LoadBasePak(const char* const pakFile, const EPakTy
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: unload the SDK base pak file by type
|
||||
//-----------------------------------------------------------------------------
|
||||
void CustomPakData_t::UnloadBasePak(const EPakType type)
|
||||
void CustomPakData_s::UnloadBasePak(const PakType_e type)
|
||||
{
|
||||
const PakHandle_t pakId = handles[type];
|
||||
|
||||
@ -209,10 +206,71 @@ void Mod_GetAllInstalledMaps()
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns whether the load job for given pak id is finished
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool Mod_IsPakLoadFinished(const PakHandle_t pakId)
|
||||
{
|
||||
if (pakId == PAK_INVALID_HANDLE)
|
||||
return true;
|
||||
|
||||
const PakLoadedInfo_s* const pli = Pak_GetPakInfo(pakId);
|
||||
|
||||
if (pli->handle != pakId)
|
||||
return false;
|
||||
|
||||
const PakStatus_e stat = pli->status;
|
||||
|
||||
if (stat != PakStatus_e::PAK_STATUS_LOADED &&
|
||||
stat != PakStatus_e::PAK_STATUS_ERROR)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns whether the load job for custom pak batch for given common
|
||||
// pak is finished
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool CustomPakData_IsPakLoadFinished(const CommonPakData_s::PakType_e commonType)
|
||||
{
|
||||
switch (commonType)
|
||||
{
|
||||
case CommonPakData_s::PakType_e::PAK_TYPE_UI_GM:
|
||||
#ifndef DEDICATED
|
||||
return Mod_IsPakLoadFinished(s_customPakData.handles[CustomPakData_s::PakType_e::PAK_TYPE_UI_SDK]);
|
||||
#else // Dedicated doesn't load UI paks.
|
||||
return true;
|
||||
#endif // DEDICATED
|
||||
case CommonPakData_s::PakType_e::PAK_TYPE_COMMON:
|
||||
return true;
|
||||
case CommonPakData_s::PakType_e::PAK_TYPE_COMMON_GM:
|
||||
return Mod_IsPakLoadFinished(s_customPakData.handles[CustomPakData_s::PakType_e::PAK_TYPE_COMMON_SDK]);
|
||||
case CommonPakData_s::PakType_e::PAK_TYPE_LOBBY:
|
||||
// Check for preloaded paks at this stage (loaded from preload.rson).
|
||||
for (int i = 0, n = s_customPakData.numPreload; i < n; i++)
|
||||
{
|
||||
if (!Mod_IsPakLoadFinished(s_customPakData.handles[CustomPakData_s::PAK_TYPE_COUNT + i]))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case CommonPakData_s::PakType_e::PAK_TYPE_LEVEL:
|
||||
// Check for extra level paks at this stage (loaded from <levelname>.kv).
|
||||
for (int i = CustomPakData_s::PAK_TYPE_COUNT + s_customPakData.numPreload, n = s_customPakData.numHandles; i < n; i++)
|
||||
{
|
||||
if (!Mod_IsPakLoadFinished(s_customPakData.handles[i]))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: processes queued pak files
|
||||
//-----------------------------------------------------------------------------
|
||||
void Mod_QueuedPakCacheFrame()
|
||||
static void Mod_QueuedPakCacheFrame()
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
bool bUnconnected = !(*g_pClientState_Shifted)->IsConnected();
|
||||
@ -274,11 +332,11 @@ void Mod_QueuedPakCacheFrame()
|
||||
|
||||
const int numToProcess = startIndex;
|
||||
|
||||
if (startIndex <= CommonPakData_t::PAK_TYPE_LEVEL)
|
||||
if (startIndex < CommonPakData_s::PAK_TYPE_COUNT)
|
||||
{
|
||||
bool keepLoaded = false;
|
||||
int numLeftToProcess = 4;
|
||||
CommonPakData_t* data = &g_commonPakData[4];
|
||||
CommonPakData_s* data = &g_commonPakData[4];
|
||||
|
||||
do
|
||||
{
|
||||
@ -307,26 +365,24 @@ void Mod_QueuedPakCacheFrame()
|
||||
switch (numLeftToProcess)
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
case CommonPakData_t::PAK_TYPE_UI_GM:
|
||||
s_customPakData.UnloadBasePak(CustomPakData_t::PAK_TYPE_UI_SDK);
|
||||
case CommonPakData_s::PakType_e::PAK_TYPE_UI_GM:
|
||||
s_customPakData.UnloadBasePak(CustomPakData_s::PakType_e::PAK_TYPE_UI_SDK);
|
||||
break;
|
||||
#endif // !DEDICATED
|
||||
|
||||
case CommonPakData_t::PAK_TYPE_COMMON:
|
||||
case CommonPakData_s::PakType_e::PAK_TYPE_COMMON:
|
||||
g_StudioMdlFallbackHandler.Clear();
|
||||
break;
|
||||
|
||||
case CommonPakData_t::PAK_TYPE_COMMON_GM:
|
||||
s_customPakData.UnloadBasePak(CustomPakData_t::PAK_TYPE_COMMON_SDK);
|
||||
case CommonPakData_s::PakType_e::PAK_TYPE_COMMON_GM:
|
||||
s_customPakData.UnloadBasePak(CustomPakData_s::PakType_e::PAK_TYPE_COMMON_SDK);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_pakLoadApi->UnloadAsync(data->pakId);
|
||||
|
||||
if (numLeftToProcess == CommonPakData_t::PAK_TYPE_LEVEL)
|
||||
if (numLeftToProcess == CommonPakData_s::PakType_e::PAK_TYPE_LEVEL)
|
||||
{
|
||||
Mod_UnloadLevelPaks(); // Unload mod pak files.
|
||||
|
||||
@ -337,7 +393,10 @@ void Mod_QueuedPakCacheFrame()
|
||||
s_pLevelSetKV = nullptr;
|
||||
}
|
||||
}
|
||||
else if (numLeftToProcess == CommonPakData_t::PAK_TYPE_LOBBY)
|
||||
|
||||
g_pakLoadApi->UnloadAsync(data->pakId);
|
||||
|
||||
if (numLeftToProcess == CommonPakData_s::PakType_e::PAK_TYPE_LOBBY)
|
||||
{
|
||||
Mod_UnloadPreloadedPaks();
|
||||
s_customPakData.basePaksLoaded = false;
|
||||
@ -358,7 +417,7 @@ void Mod_QueuedPakCacheFrame()
|
||||
}
|
||||
|
||||
*g_pPakPrecacheJobFinished = true;
|
||||
CommonPakData_t* commonData = g_commonPakData;
|
||||
CommonPakData_s* commonData = g_commonPakData;
|
||||
|
||||
int it = 0;
|
||||
|
||||
@ -382,7 +441,7 @@ void Mod_QueuedPakCacheFrame()
|
||||
} while (c);
|
||||
|
||||
if (!v20)
|
||||
goto CHECK_FOR_FAILURE;
|
||||
goto CHECK_LOAD_STATUS;
|
||||
|
||||
V_strncpy(name, commonData->basePakName, MAX_PATH);
|
||||
|
||||
@ -419,7 +478,7 @@ void Mod_QueuedPakCacheFrame()
|
||||
{
|
||||
if (*g_bPakFifoLockAcquiredInMainThread)
|
||||
{
|
||||
*g_bPakFifoLockAcquiredInMainThread = 0;
|
||||
*g_bPakFifoLockAcquiredInMainThread = false;
|
||||
JT_ReleaseFifoLock(pakFifoLock);
|
||||
}
|
||||
}
|
||||
@ -438,39 +497,32 @@ void Mod_QueuedPakCacheFrame()
|
||||
}
|
||||
}
|
||||
|
||||
if (it == CommonPakData_t::PAK_TYPE_LOBBY)
|
||||
if (it == CommonPakData_s::PakType_e::PAK_TYPE_LOBBY)
|
||||
{
|
||||
Mod_PreloadPaks();
|
||||
s_customPakData.basePaksLoaded = true;
|
||||
}
|
||||
|
||||
if (s_customPakData.basePaksLoaded && !s_customPakData.levelResourcesLoaded)
|
||||
commonData->pakId = g_pakLoadApi->LoadAsync(name, AlignedMemAlloc(), 4, 0);
|
||||
|
||||
if (it == CommonPakData_s::PakType_e::PAK_TYPE_LEVEL)
|
||||
{
|
||||
Mod_LoadLevelPaks(s_CurrentLevelName.String());
|
||||
s_customPakData.levelResourcesLoaded = true;
|
||||
}
|
||||
|
||||
commonData->pakId = g_pakLoadApi->LoadAsync(name, AlignedMemAlloc(), 4, 0);
|
||||
|
||||
#ifndef DEDICATED
|
||||
if (it == CommonPakData_t::PAK_TYPE_UI_GM)
|
||||
s_customPakData.LoadBasePak("ui_sdk.rpak", CustomPakData_t::PAK_TYPE_UI_SDK);
|
||||
if (it == CommonPakData_s::PakType_e::PAK_TYPE_UI_GM)
|
||||
s_customPakData.LoadBasePak("ui_sdk.rpak", CustomPakData_s::PakType_e::PAK_TYPE_UI_SDK);
|
||||
else
|
||||
#endif // !DEDICATED
|
||||
if (it == CommonPakData_t::PAK_TYPE_COMMON_GM)
|
||||
s_customPakData.LoadBasePak("common_sdk.rpak", CustomPakData_t::PAK_TYPE_COMMON_SDK);
|
||||
if (it == CommonPakData_s::PakType_e::PAK_TYPE_COMMON_GM)
|
||||
s_customPakData.LoadBasePak("common_sdk.rpak", CustomPakData_s::PakType_e::PAK_TYPE_COMMON_SDK);
|
||||
|
||||
CHECK_FOR_FAILURE:
|
||||
CHECK_LOAD_STATUS:
|
||||
|
||||
if (commonData->pakId != PAK_INVALID_HANDLE)
|
||||
{
|
||||
const PakLoadedInfo_s* const pli = Pak_GetPakInfo(commonData->pakId);
|
||||
|
||||
if (pli->handle != commonData->pakId || ((pli->status - 9) & 0xFFFFFFFB) != 0)
|
||||
{
|
||||
*g_pPakPrecacheJobFinished = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!Mod_IsPakLoadFinished(commonData->pakId) || !CustomPakData_IsPakLoadFinished(CommonPakData_s::PakType_e(it)))
|
||||
*g_pPakPrecacheJobFinished = false;
|
||||
|
||||
goto LOOP_AGAIN_OR_FINISH;
|
||||
}
|
||||
|
@ -12,9 +12,9 @@ class KeyValues;
|
||||
// loads for a level, this is used for load/unload management during level
|
||||
// changes or engine shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CommonPakData_t
|
||||
struct CommonPakData_s
|
||||
{
|
||||
enum EPakType
|
||||
enum PakType_e
|
||||
{
|
||||
// the UI pak assigned to the current gamemode (range in GameMode_t)
|
||||
PAK_TYPE_UI_GM = 0,
|
||||
@ -32,7 +32,7 @@ struct CommonPakData_t
|
||||
PAK_TYPE_COUNT
|
||||
};
|
||||
|
||||
CommonPakData_t()
|
||||
CommonPakData_s()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
@ -62,9 +62,9 @@ struct CommonPakData_t
|
||||
// loaded with the settings KV for that level, these paks are loaded after the
|
||||
// common paks are loaded, but unloaded before the common paks are unloaded
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CustomPakData_t
|
||||
struct CustomPakData_s
|
||||
{
|
||||
enum EPakType
|
||||
enum PakType_e
|
||||
{
|
||||
// the pak that loads after CommonPakData_t::PAK_TYPE_UI_GM has loaded, and
|
||||
// unloads before CommonPakData_t::PAK_TYPE_UI_GM gets unloaded
|
||||
@ -83,10 +83,10 @@ struct CustomPakData_t
|
||||
// the absolute max number of custom paks, note that the engine's limit
|
||||
// could still be reached before this number as game scripts and other
|
||||
// code still loads paks such as gladiator cards or load screens
|
||||
MAX_CUSTOM_PAKS = (PAK_MAX_LOADED_PAKS - CommonPakData_t::PAK_TYPE_COUNT)
|
||||
MAX_CUSTOM_PAKS = (PAK_MAX_LOADED_PAKS - CommonPakData_s::PAK_TYPE_COUNT)
|
||||
};
|
||||
|
||||
CustomPakData_t()
|
||||
CustomPakData_s()
|
||||
{
|
||||
for (size_t i = 0; i < V_ARRAYSIZE(handles); i++)
|
||||
{
|
||||
@ -107,8 +107,8 @@ struct CustomPakData_t
|
||||
void UnloadAndRemoveNonPreloaded();
|
||||
void UnloadAndRemovePreloaded();
|
||||
|
||||
PakHandle_t LoadBasePak(const char* const pakFile, const EPakType type);
|
||||
void UnloadBasePak(const EPakType type);
|
||||
PakHandle_t LoadBasePak(const char* const pakFile, const PakType_e type);
|
||||
void UnloadBasePak(const PakType_e type);
|
||||
|
||||
private:
|
||||
void UnloadAndRemovePak(const int index);
|
||||
@ -128,7 +128,7 @@ public:
|
||||
};
|
||||
|
||||
// array size = CommonPakData_t::PAK_TYPE_COUNT
|
||||
inline CommonPakData_t* g_commonPakData;
|
||||
inline CommonPakData_s* g_commonPakData;
|
||||
|
||||
inline void(*v_Mod_LoadPakForMap)(const char* szLevelName);
|
||||
inline void(*v_Mod_QueuedPakCacheFrame)(void);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "tier0/commandline.h"
|
||||
#include "rtech/pak/pakstate.h"
|
||||
#include "host_cmd.h"
|
||||
#include "common.h"
|
||||
#include "client/client.h"
|
||||
@ -7,6 +8,60 @@
|
||||
#include "windows/id3dx.h"
|
||||
#endif // !DEDICATED
|
||||
|
||||
static void DoNothing(){};
|
||||
|
||||
static const char* const s_paksToLoad[] =
|
||||
{
|
||||
// Used to store assets that must be loaded after common_early.rpak, but
|
||||
// before common.rpak is being loaded. One use case is to preserve the
|
||||
// fixed linked list structure for the player settings layouts, we must
|
||||
// load SDK layouts before common.rpak as the Game DLL expects the linked
|
||||
// list to be ordered in a specific manner that is determined by bakery.
|
||||
"common_roots.rpak",
|
||||
#ifndef DEDICATED
|
||||
// Used to load UI assets associated with the main menu.
|
||||
"ui_mainmenu.rpak"
|
||||
#endif // !DEDICATED
|
||||
};
|
||||
|
||||
/*
|
||||
==================
|
||||
Host_SetupUIMaterials
|
||||
|
||||
setup and initialize
|
||||
UI materials
|
||||
==================
|
||||
*/
|
||||
static void Host_SetupUIMaterials()
|
||||
{
|
||||
// Don't sync during video init as this is where this function is called
|
||||
// from. We restore the function pointer after we loaded the pak file.
|
||||
void* const oldSyncFn = g_pakGlobals->threadSyncFunc;
|
||||
g_pakGlobals->threadSyncFunc = DoNothing;
|
||||
|
||||
for (size_t i = 0; i < V_ARRAYSIZE(s_paksToLoad); i++)
|
||||
{
|
||||
const char* const pakFileName = s_paksToLoad[i];
|
||||
|
||||
// NOTE: make sure to wait for the async load request, as these paks
|
||||
// must be loaded before we continue processing anything else.
|
||||
const PakHandle_t pakHandle = g_pakLoadApi->LoadAsyncAndWait(pakFileName, AlignedMemAlloc(), 3, DoNothing);
|
||||
|
||||
if (pakHandle == PAK_INVALID_HANDLE)
|
||||
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Failed to load pak file '%s'\n", pakFileName);
|
||||
}
|
||||
|
||||
g_pakGlobals->threadSyncFunc = oldSyncFn;
|
||||
|
||||
// For dedicated, we shouldn't continue with setting up ui materials.
|
||||
// Return out here. This is the only place we can reliably load core
|
||||
// paks directly after common_early.rpak and ui.rpak without having
|
||||
// the engine do anything in between.
|
||||
#ifndef DEDICATED
|
||||
v_Host_SetupUIMaterials();
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Host_Shutdown
|
||||
@ -15,7 +70,7 @@ Host_Shutdown
|
||||
systems
|
||||
==================
|
||||
*/
|
||||
void Host_Shutdown()
|
||||
static void Host_Shutdown()
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
DirectX_Shutdown();
|
||||
@ -31,7 +86,7 @@ Host_Status_PrintClient
|
||||
to console
|
||||
==================
|
||||
*/
|
||||
void Host_Status_PrintClient(CClient* client, bool bShowAddress, void (*print) (const char* fmt, ...))
|
||||
static void Host_Status_PrintClient(CClient* client, bool bShowAddress, void (*print) (const char* fmt, ...))
|
||||
{
|
||||
CNetChan* nci = client->GetNetChan();
|
||||
const char* state = "challenging";
|
||||
@ -45,7 +100,7 @@ void Host_Status_PrintClient(CClient* client, bool bShowAddress, void (*print) (
|
||||
|
||||
if (nci != NULL)
|
||||
{
|
||||
print("# %i \"%s\" %llu %s %i %i %s %d\n",
|
||||
print("# %hu \"%s\" %llu %s %i %i %s %d\n",
|
||||
client->GetHandle(), client->GetServerName(), client->GetNucleusID(), COM_FormatSeconds(static_cast<int>(nci->GetTimeConnected())),
|
||||
static_cast<int>(1000.0f * nci->GetAvgLatency(FLOW_OUTGOING)), static_cast<int>(100.0f * nci->GetAvgLoss(FLOW_INCOMING)), state, nci->GetDataRate());
|
||||
|
||||
@ -56,7 +111,7 @@ void Host_Status_PrintClient(CClient* client, bool bShowAddress, void (*print) (
|
||||
}
|
||||
else
|
||||
{
|
||||
print("#%2i \"%s\" %llu %s\n", client->GetHandle(), client->GetServerName(), client->GetNucleusID(), state);
|
||||
print("#%2hu \"%s\" %llu %s\n", client->GetHandle(), client->GetServerName(), client->GetNucleusID(), state);
|
||||
}
|
||||
|
||||
//print("\n");
|
||||
@ -70,7 +125,7 @@ DFS_InitializeFeatureFlagDefinitions
|
||||
flag definitions
|
||||
==================
|
||||
*/
|
||||
bool DFS_InitializeFeatureFlagDefinitions(const char* pszFeatureFlags)
|
||||
static bool DFS_InitializeFeatureFlagDefinitions(const char* pszFeatureFlags)
|
||||
{
|
||||
if (CommandLine()->CheckParm("-nodfs"))
|
||||
return false;
|
||||
@ -81,6 +136,7 @@ bool DFS_InitializeFeatureFlagDefinitions(const char* pszFeatureFlags)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void VHostCmd::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourSetup(&v_Host_SetupUIMaterials, &Host_SetupUIMaterials, bAttach);
|
||||
DetourSetup(&v_Host_Shutdown, &Host_Shutdown, bAttach);
|
||||
DetourSetup(&v_Host_Status_PrintClient, &Host_Status_PrintClient, bAttach);
|
||||
DetourSetup(&v_DFS_InitializeFeatureFlagDefinitions, &DFS_InitializeFeatureFlagDefinitions, bAttach);
|
||||
|
@ -19,8 +19,11 @@ extern EngineParms_t* g_pEngineParms;
|
||||
|
||||
/* ==== HOST ============================================================================================================================================================ */
|
||||
inline void(*v_Host_Init)();
|
||||
#ifndef DEDICATED
|
||||
inline void(*v_Host_Init_DuringVideo)(bool* bDedicated);
|
||||
inline void(*v_Host_Init_PostVideo)(bool* bDedicated);
|
||||
#endif // !DEDICATED
|
||||
inline void(*v_Host_SetupUIMaterials)();
|
||||
inline void(*v_Host_Shutdown)();
|
||||
inline bool(*v_Host_NewGame)(char* pszMapName, char* pszMapGroup, bool bLoadGame, char bBackground, LARGE_INTEGER PerformanceCount);
|
||||
inline void(*v_Host_Disconnect)(bool bShowMainMenu);
|
||||
@ -38,8 +41,11 @@ class VHostCmd : public IDetour
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("Host_Init", v_Host_Init);
|
||||
#ifndef DEDICATED
|
||||
LogFunAdr("Host_Init_DuringVideo", v_Host_Init_DuringVideo);
|
||||
LogFunAdr("Host_Init_PostVideo", v_Host_Init_PostVideo);
|
||||
#endif // !DEDICATED
|
||||
LogFunAdr("Host_SetupUIMaterials", v_Host_SetupUIMaterials);
|
||||
LogFunAdr("Host_Shutdown", v_Host_Shutdown);
|
||||
LogFunAdr("Host_Disconnect", v_Host_Disconnect);
|
||||
LogFunAdr("Host_NewGame", v_Host_NewGame);
|
||||
@ -53,11 +59,14 @@ class VHostCmd : public IDetour
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
g_GameDll.FindPatternSIMD("88 4C 24 08 53 55 56 57 48 83 EC 68").GetPtr(v_Host_Init);
|
||||
#ifndef DEDICATED
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B D9").GetPtr(v_Host_Init_DuringVideo);
|
||||
g_GameDll.FindPatternSIMD("48 8B C4 41 56 48 81 EC ?? ?? ?? ?? 45 33 F6").GetPtr(v_Host_Init_PostVideo);
|
||||
#endif // !DEDICATED
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC ?? 48 8B 05 ?? ?? ?? ?? 48 8D 3D").GetPtr(v_Host_SetupUIMaterials);
|
||||
g_GameDll.FindPatternSIMD("48 8B C4 ?? 41 54 41 55 48 81 EC 70 04 ?? ?? F2 0F 10 05 ?? ?? ?? 0B").GetPtr(v_Host_NewGame);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 30 0F B6 D9").GetPtr(v_Host_Disconnect);
|
||||
g_GameDll.FindPatternSIMD("40 56 57 41 56 48 81 EC ?? ?? ?? ??").GetPtr(v_Host_ChangeLevel);
|
||||
g_GameDll.FindPatternSIMD("48 8B C4 41 56 48 81 EC ?? ?? ?? ?? 45 33 F6").GetPtr(v_Host_Init_PostVideo);
|
||||
g_GameDll.FindPatternSIMD("48 8B C4 48 83 EC ?? 80 3D ?? ?? ?? ?? ?? 0F 85 ?? ?? ?? ?? 8B 15 ?? ?? ?? ??").GetPtr(v_Host_Shutdown);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 56 57 41 56 48 83 EC 60 48 8B A9 ?? ?? ?? ??").GetPtr(v_Host_Status_PrintClient);
|
||||
|
||||
|
@ -121,8 +121,8 @@ static void HostState_KeepAlive()
|
||||
{
|
||||
g_ServerHostManager.SetCurrentToken(hostToken);
|
||||
Msg(eDLL_T::SERVER, "Published server with token: %s'%s%s%s'\n",
|
||||
g_svReset, g_svGreyB,
|
||||
hostToken.c_str(), g_svReset);
|
||||
g_svReset.c_str(), g_svGreyB.c_str(),
|
||||
hostToken.c_str(), g_svReset.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ void NET_Config()
|
||||
void NET_PrintKey()
|
||||
{
|
||||
Msg(eDLL_T::ENGINE, "Installed NetKey: %s'%s%s%s'\n",
|
||||
g_svReset, g_svGreyB, g_pNetKey->GetBase64NetKey(), g_svReset);
|
||||
g_svReset.c_str(), g_svGreyB.c_str(), g_pNetKey->GetBase64NetKey(), g_svReset.c_str());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -247,12 +247,7 @@ void NET_PrintFunc(const char* fmt, ...)
|
||||
result = FormatV(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (result.back() != '\n')
|
||||
{
|
||||
result.push_back('\n');
|
||||
}
|
||||
|
||||
Msg(context, "%s", result.c_str());
|
||||
Msg(context, result.back() == '\n' ? "%s" : "%s\n", result.c_str());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -388,7 +383,7 @@ const char* NET_ErrorString(int iCode)
|
||||
case WSA_QOS_EFILTERCOUNT : return "WSA_QOS_EFILTERCOUNT";
|
||||
case WSA_QOS_EOBJLENGTH : return "WSA_QOS_EOBJLENGTH";
|
||||
case WSA_QOS_EFLOWCOUNT : return "WSA_QOS_EFLOWCOUNT";
|
||||
case WSA_QOS_EUNKOWNPSOBJ : return "WSA_QOS_EUNKOWNPSOBJ";
|
||||
case WSA_QOS_EUNKOWNPSOBJ : return "WSA_QOS_EUNKNOWNPSOBJ";
|
||||
case WSA_QOS_EPOLICYOBJ : return "WSA_QOS_EPOLICYOBJ";
|
||||
case WSA_QOS_EFLOWDESC : return "WSA_QOS_EFLOWDESC";
|
||||
case WSA_QOS_EPSFLOWSPEC : return "WSA_QOS_EPSFLOWSPEC";
|
||||
|
@ -116,7 +116,7 @@ CClient* CServer::ConnectClient(CServer* pServer, user_creds_s* pChallenge)
|
||||
return nullptr;
|
||||
|
||||
char* pszPersonaName = pChallenge->personaName;
|
||||
uint64_t nNucleusID = pChallenge->personaId;
|
||||
NucleusID_t nNucleusID = pChallenge->personaId;
|
||||
|
||||
char pszAddresBuffer[128]; // Render the client's address.
|
||||
pChallenge->netAdr.ToString(pszAddresBuffer, sizeof(pszAddresBuffer), true);
|
||||
|
@ -23,7 +23,7 @@ struct user_creds_s
|
||||
int32_t protocolVer;
|
||||
int32_t challenge;
|
||||
uint32_t reservation;
|
||||
uint64_t personaId;
|
||||
NucleusID_t personaId;
|
||||
char* personaName;
|
||||
};
|
||||
|
||||
|
@ -39,7 +39,7 @@ void SV_CheckForBanAndDisconnect(CClient* const pClient, const string& svIPAddr,
|
||||
{
|
||||
const int nUserID = pClient->GetUserID();
|
||||
|
||||
pClient->Disconnect(Reputation_t::REP_MARK_BAD, svError.c_str());
|
||||
pClient->Disconnect(Reputation_t::REP_MARK_BAD, "%s", svError.c_str());
|
||||
Warning(eDLL_T::SERVER, "Removed client '[%s]:%i' from slot #%i ('%llu' is banned globally!)\n",
|
||||
svIPAddr.c_str(), nPort, nUserID, nNucleusID);
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ static ConVar sv_rcon_maxignores("sv_rcon_maxignores", "15", FCVAR_RELEASE, "Max
|
||||
static ConVar sv_rcon_maxsockets("sv_rcon_maxsockets", "32", FCVAR_RELEASE, "Max number of accepted sockets before the server starts closing redundant sockets", true, 1.f, true, MAX_PLAYERS);
|
||||
|
||||
static ConVar sv_rcon_maxconnections("sv_rcon_maxconnections", "1", FCVAR_RELEASE, "Max number of authenticated connections before the server closes the listen socket", true, 1.f, true, MAX_PLAYERS, &RCON_ConnectionCountChanged_f);
|
||||
static ConVar sv_rcon_maxframesize("sv_rcon_maxframesize", "1024", FCVAR_RELEASE, "Max number of bytes allowed in a message frame from a non-authenticated netconsole", true, 0.f, false, 0.f);
|
||||
static ConVar sv_rcon_maxframesize("sv_rcon_maxframesize", "1024", FCVAR_RELEASE, "Max number of bytes allowed in a message frame from a non-authenticated netconsole", true, 0.f, true, 4096.f);
|
||||
static ConVar sv_rcon_whitelistaddress("sv_rcon_whitelistaddress", "", FCVAR_RELEASE, "This address is not considered a 'redundant' socket and will never be banned for failed authentication attempts", &RCON_WhiteListAddresChanged_f, "Format: '::ffff:127.0.0.1'");
|
||||
|
||||
static ConVar sv_rcon_useloopbacksocket("sv_rcon_useloopbacksocket", "0", FCVAR_RELEASE, "Whether to bind rcon server to the loopback socket", &RCON_UseLoopbackSocketChanged_f);
|
||||
@ -95,7 +95,7 @@ void CRConServer::Init(const char* pPassword, const char* pNetKey)
|
||||
m_Socket.CreateListenSocket(m_Address);
|
||||
|
||||
Msg(eDLL_T::SERVER, "Remote server access initialized ('%s') with key %s'%s%s%s'\n",
|
||||
m_Address.ToString(), g_svReset, g_svGreyB, GetKey(), g_svReset);
|
||||
m_Address.ToString(), g_svReset.c_str(), g_svGreyB.c_str(), GetKey(), g_svReset.c_str());
|
||||
|
||||
m_bInitialized = true;
|
||||
}
|
||||
@ -155,7 +155,7 @@ void CRConServer::Think(void)
|
||||
const netadr_t& netAdr = m_Socket.GetAcceptedSocketAddress(m_nConnIndex);
|
||||
if (!m_WhiteListAddress.CompareAdr(netAdr))
|
||||
{
|
||||
const CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(m_nConnIndex);
|
||||
const ConnectedNetConsoleData_s& data = m_Socket.GetAcceptedSocketData(m_nConnIndex);
|
||||
if (!data.m_bAuthorized)
|
||||
{
|
||||
Disconnect("redundant");
|
||||
@ -248,11 +248,11 @@ void CRConServer::RunFrame(void)
|
||||
const int nCount = m_Socket.GetAcceptedSocketCount();
|
||||
for (m_nConnIndex = nCount - 1; m_nConnIndex >= 0; m_nConnIndex--)
|
||||
{
|
||||
CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(m_nConnIndex);
|
||||
ConnectedNetConsoleData_s& data = m_Socket.GetAcceptedSocketData(m_nConnIndex);
|
||||
|
||||
if (CheckForBan(data))
|
||||
{
|
||||
SendEncoded(data.m_hSocket, s_BannedMessage, "",
|
||||
SendEncoded(data.m_hSocket, s_BannedMessage, sizeof(s_BannedMessage)-1, "", 0,
|
||||
netcon::response_e::SERVERDATA_RESPONSE_AUTH, int(eDLL_T::NETCON));
|
||||
|
||||
Disconnect("banned");
|
||||
@ -270,25 +270,18 @@ void CRConServer::RunFrame(void)
|
||||
// nMsgLen -
|
||||
// Output: true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConServer::SendToAll(const char* pMsgBuf, const int nMsgLen) const
|
||||
bool CRConServer::SendToAll(const byte* pMsgBuf, const u32 nMsgLen) const
|
||||
{
|
||||
ostringstream sendbuf;
|
||||
const u_long nLen = htonl(u_long(nMsgLen));
|
||||
|
||||
const int nCount = m_Socket.GetAcceptedSocketCount();
|
||||
bool bSuccess = true;
|
||||
|
||||
sendbuf.write(reinterpret_cast<const char*>(&nLen), sizeof(u_long));
|
||||
sendbuf.write(pMsgBuf, nMsgLen);
|
||||
|
||||
const int nCount = m_Socket.GetAcceptedSocketCount();
|
||||
for (int i = nCount - 1; i >= 0; i--)
|
||||
{
|
||||
const CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(i);
|
||||
const ConnectedNetConsoleData_s& data = m_Socket.GetAcceptedSocketData(i);
|
||||
|
||||
if (data.m_bAuthorized && !data.m_bInputOnly)
|
||||
{
|
||||
int ret = ::send(data.m_hSocket, sendbuf.str().data(),
|
||||
int(sendbuf.str().size()), MSG_NOSIGNAL);
|
||||
const int ret = ::send(data.m_hSocket, (const char*)pMsgBuf, (i32)nMsgLen, MSG_NOSIGNAL);
|
||||
|
||||
if (ret == SOCKET_ERROR)
|
||||
{
|
||||
@ -306,17 +299,19 @@ bool CRConServer::SendToAll(const char* pMsgBuf, const int nMsgLen) const
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: encode and send message to all connected sockets
|
||||
// Input : *pResponseMsg -
|
||||
// nResponseMsgLen -
|
||||
// *pResponseVal -
|
||||
// nResponseValLen -
|
||||
// responseType -
|
||||
// nMessageId -
|
||||
// nMessageType -
|
||||
// Output: true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConServer::SendEncoded(const char* pResponseMsg, const char* pResponseVal,
|
||||
bool CRConServer::SendEncoded(const char* pResponseMsg, const size_t nResponseMsgLen, const char* pResponseVal, const size_t nResponseValLen,
|
||||
const netcon::response_e responseType, const int nMessageId, const int nMessageType) const
|
||||
{
|
||||
vector<char> vecMsg;
|
||||
if (!Serialize(vecMsg, pResponseMsg, pResponseVal,
|
||||
vector<byte> vecMsg;
|
||||
if (!Serialize(vecMsg, pResponseMsg, nResponseMsgLen, pResponseVal, nResponseValLen,
|
||||
responseType, nMessageId, nMessageType))
|
||||
{
|
||||
return false;
|
||||
@ -334,17 +329,20 @@ bool CRConServer::SendEncoded(const char* pResponseMsg, const char* pResponseVal
|
||||
// Purpose: encode and send message to specific socket
|
||||
// Input : hSocket -
|
||||
// *pResponseMsg -
|
||||
// nResponseMsgLen -
|
||||
// *pResponseVal -
|
||||
// nResponseValLen -
|
||||
// responseType -
|
||||
// nMessageId -
|
||||
// nMessageType -
|
||||
// Output: true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConServer::SendEncoded(const SocketHandle_t hSocket, const char* pResponseMsg, const char* pResponseVal,
|
||||
bool CRConServer::SendEncoded(const SocketHandle_t hSocket,
|
||||
const char* pResponseMsg, const size_t nResponseMsgLen, const char* pResponseVal, const size_t nResponseValLen,
|
||||
const netcon::response_e responseType, const int nMessageId, const int nMessageType) const
|
||||
{
|
||||
vector<char> vecMsg;
|
||||
if (!Serialize(vecMsg, pResponseMsg, pResponseVal,
|
||||
vector<byte> vecMsg;
|
||||
if (!Serialize(vecMsg, pResponseMsg, nResponseMsgLen, pResponseVal, nResponseValLen,
|
||||
responseType, nMessageId, nMessageType))
|
||||
{
|
||||
return false;
|
||||
@ -362,16 +360,19 @@ bool CRConServer::SendEncoded(const SocketHandle_t hSocket, const char* pRespons
|
||||
// Purpose: serializes input
|
||||
// Input : &vecBuf -
|
||||
// *responseMsg -
|
||||
// nResponseMsgLen -
|
||||
// *responseVal -
|
||||
// nResponseValLen -
|
||||
// responseType -
|
||||
// nMessageId -
|
||||
// nMessageType -
|
||||
// Output : serialized results as string
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConServer::Serialize(vector<char>& vecBuf, const char* pResponseMsg, const char* pResponseVal,
|
||||
bool CRConServer::Serialize(vector<byte>& vecBuf,
|
||||
const char* pResponseMsg, const size_t nResponseMsgLen, const char* pResponseVal, const size_t nResponseValLen,
|
||||
const netcon::response_e responseType, const int nMessageId, const int nMessageType) const
|
||||
{
|
||||
return NetconServer_Serialize(this, vecBuf, pResponseMsg, pResponseVal, responseType, nMessageId, nMessageType,
|
||||
return NetconServer_Serialize(this, vecBuf, pResponseMsg, nResponseMsgLen, pResponseVal, nResponseValLen, responseType, nMessageId, nMessageType,
|
||||
rcon_encryptframes.GetBool(), rcon_debug.GetBool());
|
||||
}
|
||||
|
||||
@ -380,7 +381,7 @@ bool CRConServer::Serialize(vector<char>& vecBuf, const char* pResponseMsg, cons
|
||||
// Input : &request -
|
||||
// &data -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConServer::Authenticate(const netcon::request& request, CConnectedNetConsoleData& data)
|
||||
void CRConServer::Authenticate(const netcon::request& request, ConnectedNetConsoleData_s& data)
|
||||
{
|
||||
if (data.m_bAuthorized)
|
||||
{
|
||||
@ -399,7 +400,7 @@ void CRConServer::Authenticate(const netcon::request& request, CConnectedNetCons
|
||||
|
||||
const char* pSendLogs = (!sv_rcon_sendlogs.GetBool() || data.m_bInputOnly) ? "0" : "1";
|
||||
|
||||
SendEncoded(data.m_hSocket, s_AuthMessage, pSendLogs,
|
||||
SendEncoded(data.m_hSocket, s_AuthMessage, sizeof(s_AuthMessage)-1, pSendLogs, 1,
|
||||
netcon::response_e::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON));
|
||||
}
|
||||
else // Bad password.
|
||||
@ -410,7 +411,7 @@ void CRConServer::Authenticate(const netcon::request& request, CConnectedNetCons
|
||||
Msg(eDLL_T::SERVER, "Bad RCON password attempt from '%s'\n", netAdr.ToString());
|
||||
}
|
||||
|
||||
SendEncoded(data.m_hSocket, s_WrongPwMessage, "",
|
||||
SendEncoded(data.m_hSocket, s_WrongPwMessage, sizeof(s_WrongPwMessage)-1, "", 0,
|
||||
netcon::response_e::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON));
|
||||
|
||||
data.m_bAuthorized = false;
|
||||
@ -444,7 +445,7 @@ bool CRConServer::Comparator(const string& svPassword) const
|
||||
// nMsgLen -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConServer::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
|
||||
bool CRConServer::ProcessMessage(const byte* pMsgBuf, const u32 nMsgLen)
|
||||
{
|
||||
netcon::request request;
|
||||
|
||||
@ -454,13 +455,13 @@ bool CRConServer::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
|
||||
return false;
|
||||
}
|
||||
|
||||
CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(m_nConnIndex);
|
||||
ConnectedNetConsoleData_s& data = m_Socket.GetAcceptedSocketData(m_nConnIndex);
|
||||
|
||||
if (!data.m_bAuthorized &&
|
||||
request.requesttype() != netcon::request_e::SERVERDATA_REQUEST_AUTH)
|
||||
{
|
||||
// Notify netconsole that authentication is required.
|
||||
SendEncoded(data.m_hSocket, s_NoAuthMessage, "",
|
||||
SendEncoded(data.m_hSocket, s_NoAuthMessage, sizeof(s_NoAuthMessage)-1, "", 0,
|
||||
netcon::response_e::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON));
|
||||
|
||||
data.m_bValidated = false;
|
||||
@ -521,7 +522,7 @@ void CRConServer::Execute(const netcon::request& request) const
|
||||
// Purpose: checks for amount of failed attempts and bans netconsole accordingly
|
||||
// Input : &data -
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConServer::CheckForBan(CConnectedNetConsoleData& data)
|
||||
bool CRConServer::CheckForBan(ConnectedNetConsoleData_s& data)
|
||||
{
|
||||
if (data.m_bValidated)
|
||||
{
|
||||
@ -596,7 +597,7 @@ void CRConServer::Disconnect(const char* szReason) // NETMGR
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRConServer::Disconnect(const int nIndex, const char* szReason) // NETMGR
|
||||
{
|
||||
CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(nIndex);
|
||||
ConnectedNetConsoleData_s& data = m_Socket.GetAcceptedSocketData(nIndex);
|
||||
if (data.m_bAuthorized)
|
||||
{
|
||||
// Inform server owner when authenticated connection has been closed.
|
||||
@ -621,7 +622,7 @@ void CRConServer::CloseNonAuthConnection(void)
|
||||
int nCount = m_Socket.GetAcceptedSocketCount();
|
||||
for (int i = nCount - 1; i >= 0; i--)
|
||||
{
|
||||
CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(i);
|
||||
ConnectedNetConsoleData_s& data = m_Socket.GetAcceptedSocketData(i);
|
||||
|
||||
if (!data.m_bAuthorized)
|
||||
{
|
||||
|
@ -25,27 +25,27 @@ public:
|
||||
void Think(void);
|
||||
void RunFrame(void);
|
||||
|
||||
bool SendEncoded(const char* pResponseMsg, const char* pResponseVal,
|
||||
bool SendEncoded(const char* pResponseMsg, const size_t nResponseMsgLen, const char* pResponseVal, const size_t nResponseValLen,
|
||||
const netcon::response_e responseType,
|
||||
const int nMessageId = static_cast<int>(eDLL_T::NETCON),
|
||||
const int nMessageType = static_cast<int>(LogType_t::LOG_NET)) const;
|
||||
|
||||
bool SendEncoded(const SocketHandle_t hSocket, const char* pResponseMsg,
|
||||
const char* pResponseVal, const netcon::response_e responseType,
|
||||
bool SendEncoded(const SocketHandle_t hSocket, const char* pResponseMsg, const size_t nResponseMsgLen,
|
||||
const char* pResponseVal, const size_t nResponseValLen, const netcon::response_e responseType,
|
||||
const int nMessageId = static_cast<int>(eDLL_T::NETCON),
|
||||
const int nMessageType = static_cast<int>(LogType_t::LOG_NET)) const;
|
||||
|
||||
bool SendToAll(const char* pMsgBuf, const int nMsgLen) const;
|
||||
bool Serialize(vector<char>& vecBuf, const char* pResponseMsg, const char* pResponseVal, const netcon::response_e responseType,
|
||||
const int nMessageId = static_cast<int>(eDLL_T::NETCON), const int nMessageType = static_cast<int>(LogType_t::LOG_NET)) const;
|
||||
bool SendToAll(const byte* pMsgBuf, const u32 nMsgLen) const;
|
||||
bool Serialize(vector<byte>& vecBuf, const char* pResponseMsg, const size_t nResponseMsgLen, const char* pResponseVal, const size_t nResponseValLen,
|
||||
const netcon::response_e responseType, const int nMessageId = static_cast<int>(eDLL_T::NETCON), const int nMessageType = static_cast<int>(LogType_t::LOG_NET)) const;
|
||||
|
||||
void Authenticate(const netcon::request& request, CConnectedNetConsoleData& data);
|
||||
void Authenticate(const netcon::request& request, ConnectedNetConsoleData_s& data);
|
||||
bool Comparator(const string& svPassword) const;
|
||||
|
||||
virtual bool ProcessMessage(const char* pMsgBuf, const int nMsgLen) override;
|
||||
virtual bool ProcessMessage(const byte* pMsgBuf, const u32 nMsgLen) override;
|
||||
|
||||
void Execute(const netcon::request& request) const;
|
||||
bool CheckForBan(CConnectedNetConsoleData& data);
|
||||
bool CheckForBan(ConnectedNetConsoleData_s& data);
|
||||
|
||||
virtual void Disconnect(const char* szReason = nullptr) override;
|
||||
void Disconnect(const int nIndex, const char* szReason = nullptr);
|
||||
|
@ -144,72 +144,88 @@ bool CNetConBase::Connect(const char* pHostName, const int nPort)
|
||||
// nMaxLen -
|
||||
// Output: true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetConBase::ProcessBuffer(CConnectedNetConsoleData& data,
|
||||
const char* pRecvBuf, int nRecvLen, const int nMaxLen)
|
||||
bool CNetConBase::ProcessBuffer(ConnectedNetConsoleData_s& data, const byte* pRecvBuf, u32 nRecvLen, const int nMaxLen)
|
||||
{
|
||||
bool bSuccess = true;
|
||||
|
||||
while (nRecvLen > 0)
|
||||
{
|
||||
// Read payload if it's already in progress.
|
||||
if (data.m_nPayloadLen)
|
||||
{
|
||||
if (data.m_nPayloadRead < data.m_nPayloadLen)
|
||||
{
|
||||
data.m_RecvBuffer[data.m_nPayloadRead++] = *pRecvBuf;
|
||||
const u32 bytesToCopy = Min(nRecvLen, data.m_nPayloadLen - data.m_nPayloadRead);
|
||||
memcpy(&data.m_RecvBuffer[data.m_nPayloadRead], pRecvBuf, bytesToCopy);
|
||||
|
||||
data.m_nPayloadRead += bytesToCopy;
|
||||
|
||||
pRecvBuf += bytesToCopy;
|
||||
nRecvLen -= bytesToCopy;
|
||||
|
||||
pRecvBuf++;
|
||||
nRecvLen--;
|
||||
}
|
||||
if (data.m_nPayloadRead == data.m_nPayloadLen)
|
||||
{
|
||||
if (!ProcessMessage(
|
||||
reinterpret_cast<const char*>(data.m_RecvBuffer.data()), data.m_nPayloadLen)
|
||||
&& bSuccess)
|
||||
{
|
||||
bSuccess = false;
|
||||
}
|
||||
if (!ProcessMessage(data.m_RecvBuffer.data(), data.m_nPayloadLen))
|
||||
return false;
|
||||
|
||||
// Reset state.
|
||||
data.m_nPayloadLen = 0;
|
||||
data.m_nPayloadRead = 0;
|
||||
}
|
||||
}
|
||||
else if (data.m_nPayloadRead < sizeof(int)) // Read size field.
|
||||
else if (data.m_nPayloadRead < sizeof(NetConFrameHeader_s)) // Read the header if we haven't fully recv'd it.
|
||||
{
|
||||
data.m_RecvBuffer[data.m_nPayloadRead++] = *pRecvBuf;
|
||||
const u32 bytesToCopy = Min(nRecvLen, int(sizeof(NetConFrameHeader_s)) - data.m_nPayloadRead);
|
||||
memcpy(reinterpret_cast<char*>(&data.m_FrameHeader) + data.m_nPayloadRead, pRecvBuf, bytesToCopy);
|
||||
|
||||
pRecvBuf++;
|
||||
nRecvLen--;
|
||||
}
|
||||
else // Build prefix.
|
||||
{
|
||||
data.m_nPayloadLen = int(ntohl(*reinterpret_cast<u_long*>(&data.m_RecvBuffer[0])));
|
||||
data.m_nPayloadRead = 0;
|
||||
data.m_nPayloadRead += bytesToCopy;
|
||||
|
||||
if (!data.m_bAuthorized && nMaxLen > -1)
|
||||
pRecvBuf += bytesToCopy;
|
||||
nRecvLen -= bytesToCopy;
|
||||
|
||||
if (data.m_nPayloadRead == sizeof(NetConFrameHeader_s))
|
||||
{
|
||||
if (data.m_nPayloadLen > nMaxLen)
|
||||
NetConFrameHeader_s& header = data.m_FrameHeader;
|
||||
|
||||
// Convert byte order and check for desync.
|
||||
header.magic = ntohl(header.magic);
|
||||
const char* desyncReason = nullptr;
|
||||
|
||||
if (header.magic != RCON_FRAME_MAGIC)
|
||||
{
|
||||
Disconnect("overflow"); // Sending large messages while not authenticated.
|
||||
desyncReason = "invalid magic";
|
||||
}
|
||||
|
||||
if (!desyncReason)
|
||||
{
|
||||
header.length = ntohl(header.length);
|
||||
|
||||
if (header.length == 0)
|
||||
{
|
||||
desyncReason = "empty frame";
|
||||
}
|
||||
}
|
||||
|
||||
if (desyncReason)
|
||||
{
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "RCON Cmd: sync error (%s)\n", desyncReason);
|
||||
Disconnect("desync");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (data.m_nPayloadLen < 0 ||
|
||||
data.m_nPayloadLen > data.m_RecvBuffer.max_size())
|
||||
{
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "RCON Cmd: sync error (%d)\n", data.m_nPayloadLen);
|
||||
Disconnect("desync"); // Out of sync (irrecoverable).
|
||||
if ((!data.m_bAuthorized && nMaxLen > -1 && header.length > (u32)nMaxLen) ||
|
||||
header.length > RCON_FRAME_MAX_SIZE)
|
||||
{
|
||||
Disconnect("overflow");
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.m_RecvBuffer.resize(data.m_nPayloadLen);
|
||||
data.m_nPayloadLen = header.length;
|
||||
data.m_nPayloadRead = 0;
|
||||
|
||||
data.m_RecvBuffer.resize(header.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bSuccess;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -220,13 +236,12 @@ bool CNetConBase::ProcessBuffer(CConnectedNetConsoleData& data,
|
||||
// nDataLen -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetConBase::Encrypt(CryptoContext_s& ctx, const char* pInBuf,
|
||||
char* pOutBuf, const size_t nDataLen) const
|
||||
bool CNetConBase::Encrypt(CryptoContext_s& ctx, const byte* pInBuf, byte* pOutBuf, const u32 nDataLen) const
|
||||
{
|
||||
if (Crypto_GenerateIV(ctx, reinterpret_cast<const unsigned char*>(pInBuf), nDataLen))
|
||||
return Crypto_CTREncrypt(ctx, reinterpret_cast<const unsigned char*>(pInBuf),
|
||||
reinterpret_cast<unsigned char*>(pOutBuf), m_NetKey, nDataLen);
|
||||
if (Crypto_GenerateIV(ctx, pInBuf, nDataLen))
|
||||
return Crypto_CTREncrypt(ctx, pInBuf, pOutBuf, m_NetKey, nDataLen);
|
||||
|
||||
Assert(0);
|
||||
return false; // failure
|
||||
}
|
||||
|
||||
@ -238,11 +253,9 @@ bool CNetConBase::Encrypt(CryptoContext_s& ctx, const char* pInBuf,
|
||||
// nDataLen -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetConBase::Decrypt(CryptoContext_s& ctx, const char* pInBuf,
|
||||
char* pOutBuf, const size_t nDataLen) const
|
||||
bool CNetConBase::Decrypt(CryptoContext_s& ctx, const byte* pInBuf, byte* pOutBuf, const u32 nDataLen) const
|
||||
{
|
||||
return Crypto_CTRDecrypt(ctx, reinterpret_cast<const unsigned char*>(pInBuf),
|
||||
reinterpret_cast<unsigned char*>(pOutBuf), m_NetKey, nDataLen);
|
||||
return Crypto_CTRDecrypt(ctx, pInBuf, pOutBuf, m_NetKey, nDataLen);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -252,10 +265,9 @@ bool CNetConBase::Decrypt(CryptoContext_s& ctx, const char* pInBuf,
|
||||
// nMsgLen -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetConBase::Encode(google::protobuf::MessageLite* pMsg,
|
||||
char* pMsgBuf, const size_t nMsgLen) const
|
||||
bool CNetConBase::Encode(google::protobuf::MessageLite* pMsg, byte* pMsgBuf, const u32 nMsgLen) const
|
||||
{
|
||||
return pMsg->SerializeToArray(pMsgBuf, int(nMsgLen));
|
||||
return pMsg->SerializeToArray(pMsgBuf, (i32)nMsgLen);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -265,10 +277,9 @@ bool CNetConBase::Encode(google::protobuf::MessageLite* pMsg,
|
||||
// nMsgLen -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetConBase::Decode(google::protobuf::MessageLite* pMsg,
|
||||
const char* pMsgBuf, const size_t nMsgLen) const
|
||||
bool CNetConBase::Decode(google::protobuf::MessageLite* pMsg, const byte* pMsgBuf, const u32 nMsgLen) const
|
||||
{
|
||||
return pMsg->ParseFromArray(pMsgBuf, int(nMsgLen));
|
||||
return pMsg->ParseFromArray(pMsgBuf, (i32)nMsgLen);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -278,18 +289,9 @@ bool CNetConBase::Decode(google::protobuf::MessageLite* pMsg,
|
||||
// nMsgLen -
|
||||
// Output: true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetConBase::Send(const SocketHandle_t hSocket, const char* pMsgBuf,
|
||||
const int nMsgLen) const
|
||||
bool CNetConBase::Send(const SocketHandle_t hSocket, const byte* pMsgBuf, const u32 nMsgLen) const
|
||||
{
|
||||
std::ostringstream sendbuf;
|
||||
const u_long nLen = htonl(u_long(nMsgLen));
|
||||
|
||||
sendbuf.write(reinterpret_cast<const char*>(&nLen), sizeof(u_long));
|
||||
sendbuf.write(pMsgBuf, nMsgLen);
|
||||
|
||||
int ret = ::send(hSocket, sendbuf.str().data(), int(sendbuf.str().size()),
|
||||
MSG_NOSIGNAL);
|
||||
|
||||
const int ret = ::send(hSocket, (char*)pMsgBuf, (i32)nMsgLen, MSG_NOSIGNAL);
|
||||
return (ret != SOCKET_ERROR);
|
||||
}
|
||||
|
||||
@ -299,19 +301,19 @@ bool CNetConBase::Send(const SocketHandle_t hSocket, const char* pMsgBuf,
|
||||
// nMaxLen -
|
||||
// Output: true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNetConBase::Recv(CConnectedNetConsoleData& data, const int nMaxLen)
|
||||
void CNetConBase::Recv(ConnectedNetConsoleData_s& data, const int nMaxLen)
|
||||
{
|
||||
static char szRecvBuf[1024];
|
||||
|
||||
{//////////////////////////////////////////////
|
||||
const int nPendingLen = ::recv(data.m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK);
|
||||
const int nPendingLen = ::recv(data.m_hSocket, szRecvBuf, sizeof(szRecvBuf), MSG_PEEK);
|
||||
if (nPendingLen == SOCKET_ERROR && m_Socket.IsSocketBlocking())
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (nPendingLen == 0) // Socket was closed.
|
||||
{
|
||||
Disconnect("remote closed socket");
|
||||
Disconnect("socket closed prematurely");
|
||||
return;
|
||||
}
|
||||
else if (nPendingLen < 0)
|
||||
@ -321,8 +323,8 @@ void CNetConBase::Recv(CConnectedNetConsoleData& data, const int nMaxLen)
|
||||
}
|
||||
}//////////////////////////////////////////////
|
||||
|
||||
int nReadLen = 0; // Find out how much we have to read.
|
||||
int iResult = ::ioctlsocket(data.m_hSocket, FIONREAD, reinterpret_cast<u_long*>(&nReadLen));
|
||||
u_long nReadLen = 0; // Find out how much we have to read.
|
||||
const int iResult = ::ioctlsocket(data.m_hSocket, FIONREAD, &nReadLen);
|
||||
|
||||
if (iResult == SOCKET_ERROR)
|
||||
{
|
||||
@ -344,8 +346,10 @@ void CNetConBase::Recv(CConnectedNetConsoleData& data, const int nMaxLen)
|
||||
break;
|
||||
}
|
||||
|
||||
nReadLen -= nRecvLen; // Process what we've got.
|
||||
ProcessBuffer(data, szRecvBuf, nRecvLen, nMaxLen);
|
||||
nReadLen -= static_cast<u_long>(nRecvLen); // Process what we've got.
|
||||
|
||||
if (!ProcessBuffer(data, reinterpret_cast<byte*>(&szRecvBuf), static_cast<u32>(nRecvLen), nMaxLen))
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -1,14 +1,12 @@
|
||||
#ifndef BASE_RCON_H
|
||||
#define BASE_RCON_H
|
||||
|
||||
#include "netcon/INetCon.h"
|
||||
#include "tier1/NetAdr.h"
|
||||
#include "tier2/cryptutils.h"
|
||||
#include "tier2/socketcreator.h"
|
||||
#include "protobuf/message_lite.h"
|
||||
|
||||
// Max size of the payload in the envelope frame
|
||||
#define RCON_MAX_PAYLOAD_SIZE 1024*1024
|
||||
|
||||
class CNetConBase
|
||||
{
|
||||
public:
|
||||
@ -23,17 +21,17 @@ public:
|
||||
virtual bool Connect(const char* pHostName, const int nHostPort = SOCKET_ERROR);
|
||||
virtual void Disconnect(const char* szReason = nullptr) { NOTE_UNUSED(szReason); };
|
||||
|
||||
virtual bool ProcessBuffer(CConnectedNetConsoleData& data, const char* pRecvBuf, int nRecvLen, const int nMaxLen = SOCKET_ERROR);
|
||||
virtual bool ProcessMessage(const char* /*pMsgBuf*/, int /*nMsgLen*/) { return true; };
|
||||
virtual bool ProcessBuffer(ConnectedNetConsoleData_s& data, const byte* pRecvBuf, u32 nRecvLen, const int nMaxLen = SOCKET_ERROR);
|
||||
virtual bool ProcessMessage(const byte* /*pMsgBuf*/, const u32 /*nMsgLen*/) { return true; };
|
||||
|
||||
virtual bool Encrypt(CryptoContext_s& ctx, const char* pInBuf, char* pOutBuf, const size_t nDataLen) const;
|
||||
virtual bool Decrypt(CryptoContext_s& ctx, const char* pInBuf, char* pOutBuf, const size_t nDataLen) const;
|
||||
virtual bool Encrypt(CryptoContext_s& ctx, const byte* pInBuf, byte* pOutBuf, const u32 nDataLen) const;
|
||||
virtual bool Decrypt(CryptoContext_s& ctx, const byte* pInBuf, byte* pOutBuf, const u32 nDataLen) const;
|
||||
|
||||
virtual bool Encode(google::protobuf::MessageLite* pMsg, char* pMsgBuf, const size_t nMsgLen) const;
|
||||
virtual bool Decode(google::protobuf::MessageLite* pMsg, const char* pMsgBuf, const size_t nMsgLen) const;
|
||||
virtual bool Encode(google::protobuf::MessageLite* pMsg, byte* pMsgBuf, const u32 nMsgLen) const;
|
||||
virtual bool Decode(google::protobuf::MessageLite* pMsg, const byte* pMsgBuf, const u32 nMsgLen) const;
|
||||
|
||||
virtual bool Send(const SocketHandle_t hSocket, const char* pMsgBuf, const int nMsgLen) const;
|
||||
virtual void Recv(CConnectedNetConsoleData& data, const int nMaxLen = SOCKET_ERROR);
|
||||
virtual bool Send(const SocketHandle_t hSocket, const byte* pMsgBuf, const u32 nMsgLen) const;
|
||||
virtual void Recv(ConnectedNetConsoleData_s& data, const int nMaxLen = SOCKET_ERROR);
|
||||
|
||||
CSocketCreator* GetSocketCreator(void) { return &m_Socket; }
|
||||
netadr_t* GetNetAddress(void) { return &m_Address; }
|
||||
|
@ -13,7 +13,9 @@
|
||||
// Input : *pBase -
|
||||
// &vecBuf -
|
||||
// *pResponseMsg -
|
||||
// nResponseMsgLen -
|
||||
// *pResponseVal -
|
||||
// nResponseValLen -
|
||||
// responseType -
|
||||
// nMessageId -
|
||||
// nMessageType -
|
||||
@ -21,7 +23,8 @@
|
||||
// bDebug -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool NetconServer_Serialize(const CNetConBase* pBase, vector<char>& vecBuf, const char* pResponseMsg, const char* pResponseVal,
|
||||
bool NetconServer_Serialize(const CNetConBase* pBase, vector<byte>& vecBuf,
|
||||
const char* pResponseMsg, const size_t nResponseMsgLen, const char* pResponseVal, const size_t nResponseValLen,
|
||||
const netcon::response_e responseType, const int nMessageId, const int nMessageType, const bool bEncrypt, const bool bDebug)
|
||||
{
|
||||
netcon::response response;
|
||||
@ -29,10 +32,10 @@ bool NetconServer_Serialize(const CNetConBase* pBase, vector<char>& vecBuf, cons
|
||||
response.set_messageid(nMessageId);
|
||||
response.set_messagetype(nMessageType);
|
||||
response.set_responsetype(responseType);
|
||||
response.set_responsemsg(pResponseMsg);
|
||||
response.set_responseval(pResponseVal);
|
||||
response.set_responsemsg(pResponseMsg, nResponseMsgLen);
|
||||
response.set_responseval(pResponseVal, nResponseValLen);
|
||||
|
||||
if (!NetconShared_PackEnvelope(pBase, vecBuf, response.ByteSizeLong(), &response, bEncrypt, bDebug))
|
||||
if (!NetconShared_PackEnvelope(pBase, vecBuf, (u32)response.ByteSizeLong(), &response, bEncrypt, bDebug))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -45,23 +48,25 @@ bool NetconServer_Serialize(const CNetConBase* pBase, vector<char>& vecBuf, cons
|
||||
// Input : *pBase -
|
||||
// &vecBuf -
|
||||
// *szReqBuf -
|
||||
// nReqMsgLen -
|
||||
// *szReqVal -
|
||||
// nReqValLen -
|
||||
// *requestType -
|
||||
// bEncrypt -
|
||||
// bDebug -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool NetconClient_Serialize(const CNetConBase* pBase, vector<char>& vecBuf, const char* szReqBuf,
|
||||
const char* szReqVal, const netcon::request_e requestType, const bool bEncrypt, const bool bDebug)
|
||||
bool NetconClient_Serialize(const CNetConBase* pBase, vector<byte>& vecBuf, const char* szReqBuf, const size_t nReqMsgLen,
|
||||
const char* szReqVal, const size_t nReqValLen, const netcon::request_e requestType, const bool bEncrypt, const bool bDebug)
|
||||
{
|
||||
netcon::request request;
|
||||
|
||||
request.set_messageid(-1);
|
||||
request.set_requesttype(requestType);
|
||||
request.set_requestmsg(szReqBuf);
|
||||
request.set_requestval(szReqVal);
|
||||
request.set_requestmsg(szReqBuf, nReqMsgLen);
|
||||
request.set_requestval(szReqVal, nReqValLen);
|
||||
|
||||
if (!NetconShared_PackEnvelope(pBase, vecBuf, request.ByteSizeLong(), &request, bEncrypt, bDebug))
|
||||
if (!NetconShared_PackEnvelope(pBase, vecBuf, (u32)request.ByteSizeLong(), &request, bEncrypt, bDebug))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -124,11 +129,11 @@ bool NetconClient_Connect(CNetConBase* pBase, const char* pHostAdr, const int nH
|
||||
// bDebug -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool NetconShared_PackEnvelope(const CNetConBase* pBase, vector<char>& outMsgBuf, const size_t nMsgLen,
|
||||
google::protobuf::MessageLite* inMsg, const bool bEncrypt, const bool bDebug)
|
||||
bool NetconShared_PackEnvelope(const CNetConBase* pBase, vector<byte>& outMsgBuf, const u32 nMsgLen,
|
||||
google::protobuf::MessageLite* const inMsg, const bool bEncrypt, const bool bDebug)
|
||||
{
|
||||
char* encodeBuf = new char[nMsgLen];
|
||||
std::unique_ptr<char[]> encodedContainer(encodeBuf);
|
||||
byte* const encodeBuf = new byte[nMsgLen];
|
||||
std::unique_ptr<byte[]> encodedContainer(encodeBuf);
|
||||
|
||||
if (!pBase->Encode(inMsg, encodeBuf, nMsgLen))
|
||||
{
|
||||
@ -143,12 +148,12 @@ bool NetconShared_PackEnvelope(const CNetConBase* pBase, vector<char>& outMsgBuf
|
||||
netcon::envelope envelope;
|
||||
envelope.set_encrypted(bEncrypt);
|
||||
|
||||
const char* dataBuf = encodeBuf;
|
||||
std::unique_ptr<char[]> container;
|
||||
const byte* dataBuf = encodeBuf;
|
||||
std::unique_ptr<byte[]> container;
|
||||
|
||||
if (bEncrypt)
|
||||
{
|
||||
char* encryptBuf = new char[nMsgLen];
|
||||
byte* encryptBuf = new byte[nMsgLen];
|
||||
container.reset(encryptBuf);
|
||||
|
||||
CryptoContext_s ctx;
|
||||
@ -167,11 +172,12 @@ bool NetconShared_PackEnvelope(const CNetConBase* pBase, vector<char>& outMsgBuf
|
||||
}
|
||||
|
||||
envelope.set_data(dataBuf, nMsgLen);
|
||||
const size_t envelopeSize = envelope.ByteSizeLong();
|
||||
const u32 envelopeSize = (u32)envelope.ByteSizeLong();
|
||||
|
||||
outMsgBuf.resize(envelopeSize);
|
||||
outMsgBuf.resize(sizeof(NetConFrameHeader_s) + envelopeSize);
|
||||
byte* const scratch = outMsgBuf.data();
|
||||
|
||||
if (!pBase->Encode(&envelope, &outMsgBuf[0], envelopeSize))
|
||||
if (!pBase->Encode(&envelope, &scratch[sizeof(NetConFrameHeader_s)], envelopeSize))
|
||||
{
|
||||
if (bDebug)
|
||||
{
|
||||
@ -181,6 +187,12 @@ bool NetconShared_PackEnvelope(const CNetConBase* pBase, vector<char>& outMsgBuf
|
||||
return false;
|
||||
}
|
||||
|
||||
NetConFrameHeader_s* const header = reinterpret_cast<NetConFrameHeader_s*>(scratch);
|
||||
|
||||
// Write out magic and frame size in network byte order.
|
||||
header->magic = htonl(RCON_FRAME_MAGIC);
|
||||
header->length = htonl(u32(envelopeSize));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -194,8 +206,8 @@ bool NetconShared_PackEnvelope(const CNetConBase* pBase, vector<char>& outMsgBuf
|
||||
// bDebug -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool NetconShared_UnpackEnvelope(const CNetConBase* pBase, const char* pMsgBuf, const size_t nMsgLen,
|
||||
google::protobuf::MessageLite* outMsg, const bool bDebug)
|
||||
bool NetconShared_UnpackEnvelope(const CNetConBase* pBase, const byte* pMsgBuf, const u32 nMsgLen,
|
||||
google::protobuf::MessageLite* const outMsg, const bool bDebug)
|
||||
{
|
||||
netcon::envelope envelope;
|
||||
|
||||
@ -209,33 +221,33 @@ bool NetconShared_UnpackEnvelope(const CNetConBase* pBase, const char* pMsgBuf,
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t msgLen = envelope.data().size();
|
||||
const u32 msgLen = (u32)envelope.data().size();
|
||||
|
||||
if (msgLen > RCON_MAX_PAYLOAD_SIZE)
|
||||
if (msgLen > RCON_FRAME_MAX_SIZE)
|
||||
{
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Data in RCON message envelope is too large (%zu > %zu)\n",
|
||||
msgLen, RCON_MAX_PAYLOAD_SIZE);
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Data in RCON message envelope is too large (%u > %u)\n",
|
||||
msgLen, RCON_FRAME_MAX_SIZE);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* netMsg = envelope.data().c_str();
|
||||
const char* dataBuf = netMsg;
|
||||
const byte* netMsg = reinterpret_cast<const byte*>(envelope.data().c_str());
|
||||
const byte* dataBuf = netMsg;
|
||||
|
||||
std::unique_ptr<char[]> container;
|
||||
std::unique_ptr<byte[]> container;
|
||||
|
||||
if (envelope.encrypted())
|
||||
{
|
||||
char* decryptBuf = new char[msgLen];
|
||||
byte* decryptBuf = new byte[msgLen];
|
||||
container.reset(decryptBuf);
|
||||
|
||||
const size_t ivLen = envelope.nonce().size();
|
||||
const u32 ivLen = (u32)envelope.nonce().size();
|
||||
|
||||
if (ivLen != sizeof(CryptoIV_t))
|
||||
{
|
||||
if (bDebug)
|
||||
{
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Nonce in RCON message envelope is invalid (%zu != %zu)\n",
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Nonce in RCON message envelope is invalid (%u != %u)\n",
|
||||
ivLen, sizeof(CryptoIV_t));
|
||||
}
|
||||
|
||||
@ -279,7 +291,7 @@ bool NetconShared_UnpackEnvelope(const CNetConBase* pBase, const char* pMsgBuf,
|
||||
// iSocket -
|
||||
// Output : nullptr on failure
|
||||
//-----------------------------------------------------------------------------
|
||||
CConnectedNetConsoleData* NetconShared_GetConnData(CNetConBase* pBase, const int iSocket)
|
||||
ConnectedNetConsoleData_s* NetconShared_GetConnData(CNetConBase* pBase, const int iSocket)
|
||||
{
|
||||
CSocketCreator* pCreator = pBase->GetSocketCreator();
|
||||
Assert(iSocket >= 0 && (pCreator->GetAcceptedSocketCount() == 0
|
||||
@ -301,7 +313,7 @@ CConnectedNetConsoleData* NetconShared_GetConnData(CNetConBase* pBase, const int
|
||||
//-----------------------------------------------------------------------------
|
||||
SocketHandle_t NetconShared_GetSocketHandle(CNetConBase* pBase, const int iSocket)
|
||||
{
|
||||
const CConnectedNetConsoleData* pData = NetconShared_GetConnData(pBase, iSocket);
|
||||
const ConnectedNetConsoleData_s* pData = NetconShared_GetConnData(pBase, iSocket);
|
||||
if (!pData)
|
||||
{
|
||||
return SOCKET_ERROR;
|
||||
@ -344,19 +356,19 @@ void RCON_KeyChanged_f(IConVar* pConVar, const char* pOldString, float flOldValu
|
||||
RCONClient()->SetKey(RCONServer()->GetKey()); // Sync server & client keys
|
||||
|
||||
Msg(eDLL_T::ENGINE, "Installed RCON Key: %s'%s%s%s'\n",
|
||||
g_svReset, g_svGreyB, RCONClient()->GetKey(), g_svReset);
|
||||
g_svReset.c_str(), g_svGreyB.c_str(), RCONClient()->GetKey(), g_svReset.c_str());
|
||||
#else
|
||||
#ifdef DEDICATED
|
||||
RCONServer()->SetKey(pNewString);
|
||||
|
||||
Msg(eDLL_T::SERVER, "Installed RCON Key: %s'%s%s%s'\n",
|
||||
g_svReset, g_svGreyB, RCONServer()->GetKey(), g_svReset);
|
||||
g_svReset.c_str(), g_svGreyB.c_str(), RCONServer()->GetKey(), g_svReset.c_str());
|
||||
#endif // DEDICATED
|
||||
#ifdef CLIENT_DLL
|
||||
RCONClient()->SetKey(pNewString);
|
||||
|
||||
Msg(eDLL_T::CLIENT, "Installed RCON Key: %s'%s%s%s'\n",
|
||||
g_svReset, g_svGreyB, RCONClient()->GetKey(), g_svReset);
|
||||
g_svReset.c_str(), g_svGreyB.c_str(), RCONClient()->GetKey(), g_svReset.c_str());
|
||||
#endif // CLIENT_DLL
|
||||
|
||||
#endif // !DEDICATED && !CLIENT_DLL
|
||||
|
@ -16,17 +16,18 @@ extern void RCON_InitClientAndTrySyncKeys();
|
||||
#endif // !DEDICATED
|
||||
#endif // _TOOLS
|
||||
|
||||
bool NetconServer_Serialize(const CNetConBase* pBase, vector<char>& vecBuf, const char* pResponseMsg, const char* pResponseVal,
|
||||
bool NetconServer_Serialize(const CNetConBase* pBase, vector<byte>& vecBuf,
|
||||
const char* pResponseMsg, const size_t nResponseMsgLen, const char* pResponseVal, const size_t nResponseValLen,
|
||||
const netcon::response_e responseType, const int nMessageId, const int nMessageType, const bool bEncrypt, const bool bDebug);
|
||||
|
||||
bool NetconClient_Serialize(const CNetConBase* pBase, vector<char>& vecBuf, const char* szReqBuf,
|
||||
const char* szReqVal, const netcon::request_e requestType, const bool bEncrypt, const bool bDebug);
|
||||
bool NetconClient_Serialize(const CNetConBase* pBase, vector<byte>& vecBuf, const char* szReqBuf, const size_t nReqMsgLen,
|
||||
const char* szReqVal, const size_t nReqValLen, const netcon::request_e requestType, const bool bEncrypt, const bool bDebug);
|
||||
bool NetconClient_Connect(CNetConBase* pBase, const char* pHostAdr, const int nHostPort);
|
||||
|
||||
bool NetconShared_PackEnvelope(const CNetConBase* pBase, vector<char>& outMsgBuf, const size_t nMsgLen, google::protobuf::MessageLite* inMsg, const bool bEncrypt, const bool bDebug);
|
||||
bool NetconShared_UnpackEnvelope(const CNetConBase* pBase, const char* pMsgBuf, const size_t nMsgLen, google::protobuf::MessageLite* outMsg, const bool bDebug);
|
||||
bool NetconShared_PackEnvelope(const CNetConBase* pBase, vector<byte>& outMsgBuf, const u32 nMsgLen, google::protobuf::MessageLite* const inMsg, const bool bEncrypt, const bool bDebug);
|
||||
bool NetconShared_UnpackEnvelope(const CNetConBase* pBase, const byte* pMsgBuf, const u32 nMsgLen, google::protobuf::MessageLite* const outMsg, const bool bDebug);
|
||||
|
||||
CConnectedNetConsoleData* NetconShared_GetConnData(CNetConBase* pBase, const int iSocket);
|
||||
ConnectedNetConsoleData_s* NetconShared_GetConnData(CNetConBase* pBase, const int iSocket);
|
||||
SocketHandle_t NetconShared_GetSocketHandle(CNetConBase* pBase, const int iSocket);
|
||||
|
||||
#endif // SHARED_RCON_H
|
||||
|
@ -1,5 +1,52 @@
|
||||
#include "cliententitylist.h"
|
||||
|
||||
// Note: 'entList' points directly at the vtable member
|
||||
// of CClientEntityList; sub classed data is truncated.
|
||||
static IClientNetworkable* ClientEntityList_GetClientNetworkable(IClientEntityList* const entList, const int entNum)
|
||||
{
|
||||
// entNum is used to index into m_EntPtrArray, which is of size
|
||||
// NUM_ENT_ENTRIES. However, both the lower and upper bounds
|
||||
// checks were missing; check it here.
|
||||
if (entNum < 0 || entNum >= NUM_ENT_ENTRIES)
|
||||
{
|
||||
Assert(0);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return v_ClientEntityList_GetClientNetworkable(entList, entNum);
|
||||
}
|
||||
|
||||
// Note: 'entList' points directly at the vtable member
|
||||
// of CClientEntityList; sub classed data is truncated.
|
||||
static IClientEntity* ClientEntityList_GetClientEntity(IClientEntityList* const entList, const int entNum)
|
||||
{
|
||||
// Numbers < -2 will be used to index into the array as follows:
|
||||
// m_EntPtrArray[ (MAX_EDICTS-2) - entNum ]. However, the code
|
||||
// doesn't have a clamp for underflows; check it here. -1 cases
|
||||
// are ignored here as they already are handled correctly.
|
||||
if (entNum < -(MAX_EDICTS - 2))
|
||||
{
|
||||
Assert(0);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// m_EntPtrArray is as large as NUM_ENT_ENTRIES, but there is no
|
||||
// overflow clamp; check it here.
|
||||
if (entNum >= NUM_ENT_ENTRIES)
|
||||
{
|
||||
Assert(0);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return v_ClientEntityList_GetClientEntity(entList, entNum);
|
||||
}
|
||||
|
||||
void VClientEntityList::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourSetup(&v_ClientEntityList_GetClientNetworkable, &ClientEntityList_GetClientNetworkable, bAttach);
|
||||
DetourSetup(&v_ClientEntityList_GetClientEntity, &ClientEntityList_GetClientEntity, bAttach);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: a global list of all the entities in the game. All iteration through
|
||||
// entities is done through this object.
|
||||
|
@ -59,8 +59,10 @@ private:
|
||||
};
|
||||
COMPILE_TIME_ASSERT(sizeof(CClientEntityList) == 0x3800C0);
|
||||
|
||||
inline IClientEntityList* g_pClientEntityList = nullptr;
|
||||
inline IClientNetworkable* (*v_ClientEntityList_GetClientNetworkable)(IClientEntityList* const entList, const int entNum);
|
||||
inline IClientEntity* (*v_ClientEntityList_GetClientEntity)(IClientEntityList* const entList, const int entNum);
|
||||
|
||||
inline IClientEntityList* g_pClientEntityList = nullptr;
|
||||
extern CClientEntityList* g_clientEntityList;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -73,14 +75,18 @@ class VClientEntityList : public IDetour
|
||||
{
|
||||
LogVarAdr("g_clientEntityList", g_clientEntityList);
|
||||
}
|
||||
virtual void GetFun(void) const { }
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
g_GameDll.FindPatternSIMD("48 63 C2 48 03 C0 48 8B 44 C1").GetPtr(v_ClientEntityList_GetClientNetworkable);
|
||||
g_GameDll.FindPatternSIMD("83 FA ?? 7F ?? B8 ?? ?? ?? ?? 2B C2 48 63 D0 48 C1 E2 ?? 48 8B 8C 0A ?? ?? ?? ?? EB ?? 85 D2 78 ?? 48 63 C2 48 C1 E0 ?? 48 8B 8C 08 ?? ?? ?? ?? 48 85 C9 74 ?? 48 8B 01 48 FF 60 ?? 33 C0 C3 CC 80 FA").GetPtr(v_ClientEntityList_GetClientEntity);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
g_GameDll.FindPatternSIMD("48 8D 0D ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 44 89 0D").
|
||||
ResolveRelativeAddressSelf(3, 7).ResolveRelativeAddressSelf(3, 7).GetPtr(g_clientEntityList);
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Detour(const bool bAttach) const { };
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -144,7 +144,7 @@ namespace VScriptCode
|
||||
else
|
||||
{
|
||||
hiddenServerRequestMessage = Format("Request failed: %s", hiddenServerRequestMessage.c_str());
|
||||
sq_pushstring(v, hiddenServerRequestMessage.c_str(), -1);
|
||||
sq_pushstring(v, hiddenServerRequestMessage.c_str(), (SQInteger)hiddenServerRequestMessage.length());
|
||||
}
|
||||
|
||||
SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
|
||||
@ -157,12 +157,12 @@ namespace VScriptCode
|
||||
else
|
||||
hiddenServerRequestMessage = Format("Server listing empty: %s", hiddenServerRequestMessage.c_str());
|
||||
|
||||
sq_pushstring(v, hiddenServerRequestMessage.c_str(), -1);
|
||||
sq_pushstring(v, hiddenServerRequestMessage.c_str(), (SQInteger)hiddenServerRequestMessage.length());
|
||||
}
|
||||
else
|
||||
{
|
||||
hiddenServerRequestMessage = Format("Found server: %s", serverListing.name.c_str());
|
||||
sq_pushstring(v, hiddenServerRequestMessage.c_str(), -1);
|
||||
sq_pushstring(v, hiddenServerRequestMessage.c_str(), (SQInteger)hiddenServerRequestMessage.length());
|
||||
}
|
||||
|
||||
SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
|
||||
@ -182,7 +182,7 @@ namespace VScriptCode
|
||||
SCRIPT_CHECK_AND_RETURN(v, SQ_ERROR);
|
||||
|
||||
const string& serverName = g_ServerListManager.m_vServerList[iServer].name;
|
||||
sq_pushstring(v, serverName.c_str(), -1);
|
||||
sq_pushstring(v, serverName.c_str(), (SQInteger)serverName.length());
|
||||
|
||||
SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
|
||||
}
|
||||
@ -201,7 +201,7 @@ namespace VScriptCode
|
||||
SCRIPT_CHECK_AND_RETURN(v, SQ_ERROR);
|
||||
|
||||
const string& serverDescription = g_ServerListManager.m_vServerList[iServer].description;
|
||||
sq_pushstring(v, serverDescription.c_str(), -1);
|
||||
sq_pushstring(v, serverDescription.c_str(), (SQInteger)serverDescription.length());
|
||||
|
||||
SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
|
||||
}
|
||||
@ -219,8 +219,8 @@ namespace VScriptCode
|
||||
if (!Script_CheckServerIndexAndFailure(v, iServer))
|
||||
SCRIPT_CHECK_AND_RETURN(v, SQ_ERROR);
|
||||
|
||||
const string& svServerMapName = g_ServerListManager.m_vServerList[iServer].map;
|
||||
sq_pushstring(v, svServerMapName.c_str(), -1);
|
||||
const string& serverMapName = g_ServerListManager.m_vServerList[iServer].map;
|
||||
sq_pushstring(v, serverMapName.c_str(), (SQInteger)serverMapName.length());
|
||||
|
||||
SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
|
||||
}
|
||||
@ -239,7 +239,7 @@ namespace VScriptCode
|
||||
SCRIPT_CHECK_AND_RETURN(v, SQ_ERROR);
|
||||
|
||||
const string& serverPlaylist = g_ServerListManager.m_vServerList[iServer].playlist;
|
||||
sq_pushstring(v, serverPlaylist.c_str(), -1);
|
||||
sq_pushstring(v, serverPlaylist.c_str(), (SQInteger)serverPlaylist.length());
|
||||
|
||||
SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
|
||||
}
|
||||
@ -356,14 +356,14 @@ namespace VScriptCode
|
||||
// set EULA version cvar to the newly fetched EULA version
|
||||
eula_version->SetValue(eulaData.version);
|
||||
|
||||
sq_pushstring(v, eulaData.contents.c_str(), -1);
|
||||
sq_pushstring(v, eulaData.contents.c_str(), (SQInteger)eulaData.contents.length());
|
||||
}
|
||||
else
|
||||
{
|
||||
string error = Format("Failed to load EULA Data: %s", eulaRequestMessage.c_str());
|
||||
const string error = Format("Failed to load EULA Data: %s", eulaRequestMessage.c_str());
|
||||
|
||||
Warning(eDLL_T::UI, "%s\n", error.c_str());
|
||||
sq_pushstring(v, error.c_str(), -1);
|
||||
sq_pushstring(v, error.c_str(), (SQInteger)error.length());
|
||||
}
|
||||
|
||||
SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
|
||||
|
@ -120,7 +120,7 @@ private:
|
||||
CTether m_tethers[2];
|
||||
EHANDLE m_titanSoul;
|
||||
Vector3D m_lastFootstepDamagePos;
|
||||
bool m_lastFoostepDamageOnGround;
|
||||
bool m_lastFootstepDamageOnGround;
|
||||
char gap_1781[3];
|
||||
int m_muzzleAttachment[2];
|
||||
int m_weaponHandAttachment;
|
||||
|
@ -26,6 +26,75 @@
|
||||
#define LIVEAPI_SHA512_HASH_SIZE 64
|
||||
|
||||
|
||||
/*
|
||||
███████╗██╗ ██╗███████╗███╗ ██╗████████╗ ███╗ ███╗███████╗███████╗███████╗ █████╗ ██████╗ ███████╗███████╗
|
||||
██╔════╝██║ ██║██╔════╝████╗ ██║╚══██╔══╝ ████╗ ████║██╔════╝██╔════╝██╔════╝██╔══██╗██╔════╝ ██╔════╝██╔════╝
|
||||
█████╗ ██║ ██║█████╗ ██╔██╗ ██║ ██║ ██╔████╔██║█████╗ ███████╗███████╗███████║██║ ███╗█████╗ ███████╗
|
||||
██╔══╝ ╚██╗ ██╔╝██╔══╝ ██║╚██╗██║ ██║ ██║╚██╔╝██║██╔══╝ ╚════██║╚════██║██╔══██║██║ ██║██╔══╝ ╚════██║
|
||||
███████╗ ╚████╔╝ ███████╗██║ ╚████║ ██║ ██║ ╚═╝ ██║███████╗███████║███████║██║ ██║╚██████╔╝███████╗███████║
|
||||
╚══════╝ ╚═══╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝
|
||||
NOTE: messages are statically allocated to save on runtime overhead, each message is cleared after usage.
|
||||
*/
|
||||
|
||||
static rtech::liveapi::AmmoUsed s_ammoUsed;
|
||||
static rtech::liveapi::ArenasItemDeselected s_arenasItemDeselected;
|
||||
static rtech::liveapi::ArenasItemSelected s_arenasItemSelected;
|
||||
static rtech::liveapi::BannerCollected s_bannerCollected;
|
||||
static rtech::liveapi::BlackMarketAction s_blackMarketAction;
|
||||
//static rtech::liveapi::ChangeCamera s_changeCamera;
|
||||
static rtech::liveapi::CharacterSelected s_characterSelected;
|
||||
//static rtech::liveapi::CustomMatch_CreateLobby s_customMatch_CreateLobby;
|
||||
//static rtech::liveapi::CustomMatch_GetLobbyPlayers s_customMatch_GetLobbyPlayers;
|
||||
//static rtech::liveapi::CustomMatch_GetSettings s_customMatch_GetSettings;
|
||||
//static rtech::liveapi::CustomMatch_JoinLobby s_customMatch_JoinLobby;
|
||||
//static rtech::liveapi::CustomMatch_KickPlayer s_customMatch_KickPlayer;
|
||||
//static rtech::liveapi::CustomMatch_LeaveLobby s_customMatch_LeaveLobby;
|
||||
//static rtech::liveapi::CustomMatch_LobbyPlayers s_customMatch_LobbyPlayers;
|
||||
//static rtech::liveapi::CustomMatch_SendChat s_customMatch_SendChat;
|
||||
//static rtech::liveapi::CustomMatch_SetMatchmaking s_customMatch_SetMatchmaking;
|
||||
//static rtech::liveapi::CustomMatch_SetReady s_customMatch_SetReady;
|
||||
//static rtech::liveapi::CustomMatch_SetSettings s_customMatch_SetSettings;
|
||||
//static rtech::liveapi::CustomMatch_SetTeam s_customMatch_SetTeam;
|
||||
//static rtech::liveapi::CustomMatch_SetTeamName s_customMatch_SetTeamName;
|
||||
static rtech::liveapi::CustomEvent s_customEvent;
|
||||
static rtech::liveapi::GameStateChanged s_gameStateChanged;
|
||||
static rtech::liveapi::GibraltarShieldAbsorbed s_gibraltarShieldAbsorbed;
|
||||
static rtech::liveapi::GrenadeThrown s_grenadeThrown;
|
||||
static rtech::liveapi::Init s_init;
|
||||
static rtech::liveapi::InventoryDrop s_inventoryDrop;
|
||||
static rtech::liveapi::InventoryPickUp s_inventoryPickUp;
|
||||
static rtech::liveapi::InventoryUse s_inventoryUse;
|
||||
static rtech::liveapi::LegendUpgradeSelected s_legendUpgradeSelected;
|
||||
static rtech::liveapi::LiveAPIEvent s_liveAPIEvent;
|
||||
static rtech::liveapi::MatchSetup s_matchSetup;
|
||||
static rtech::liveapi::MatchStateEnd s_matchStateEnd;
|
||||
static rtech::liveapi::ObserverAnnotation s_observerAnnotation;
|
||||
static rtech::liveapi::ObserverSwitched s_observerSwitched;
|
||||
//static rtech::liveapi::PauseToggle s_pauseToggle;
|
||||
static rtech::liveapi::PlayerAbilityUsed s_playerAbilityUsed;
|
||||
static rtech::liveapi::PlayerAssist s_playerAssist;
|
||||
static rtech::liveapi::PlayerConnected s_playerConnected;
|
||||
static rtech::liveapi::PlayerDamaged s_playerDamaged;
|
||||
static rtech::liveapi::PlayerDisconnected s_playerDisconnected;
|
||||
static rtech::liveapi::PlayerDowned s_playerDowned;
|
||||
static rtech::liveapi::PlayerKilled s_playerKilled;
|
||||
static rtech::liveapi::PlayerRespawnTeam s_playerRespawnTeam;
|
||||
static rtech::liveapi::PlayerRevive s_playerRevive;
|
||||
static rtech::liveapi::PlayerStatChanged s_playerStatChanged;
|
||||
static rtech::liveapi::PlayerUpgradeTierChanged s_playerUpgradeTierChanged;
|
||||
//static rtech::liveapi::Request s_request;
|
||||
//static rtech::liveapi::RequestStatus s_requestStatus;
|
||||
//static rtech::liveapi::Response s_response;
|
||||
static rtech::liveapi::RevenantForgedShadowDamaged s_revenantForgedShadowDamaged;
|
||||
static rtech::liveapi::RingFinishedClosing s_ringFinishedClosing;
|
||||
static rtech::liveapi::RingStartClosing s_ringStartClosing;
|
||||
static rtech::liveapi::SquadEliminated s_squadEliminated;
|
||||
static rtech::liveapi::WarpGateUsed s_warpGateUsed;
|
||||
static rtech::liveapi::WeaponSwitched s_weaponSwitched;
|
||||
static rtech::liveapi::WraithPortal s_wraithPortal;
|
||||
static rtech::liveapi::ZiplineUsed s_ziplineUsed;
|
||||
|
||||
|
||||
/*
|
||||
███████╗███╗ ██╗██╗ ██╗███╗ ███╗███████╗██████╗ █████╗ ████████╗██╗ ██████╗ ███╗ ██╗███████╗
|
||||
██╔════╝████╗ ██║██║ ██║████╗ ████║██╔════╝██╔══██╗██╔══██╗╚══██╔══╝██║██╔═══██╗████╗ ██║██╔════╝
|
||||
@ -1883,110 +1952,16 @@ static bool LiveAPI_HandleCustomEvent(HSQUIRRELVM const v, const SQObject& obj,
|
||||
|
||||
static void LiveAPI_SendEvent(const google::protobuf::Message* const msg)
|
||||
{
|
||||
rtech::liveapi::LiveAPIEvent envelope;
|
||||
s_liveAPIEvent.set_event_size(msg->ByteSize());
|
||||
s_liveAPIEvent.mutable_gamemessage()->PackFrom(*msg);
|
||||
|
||||
envelope.set_event_size(msg->ByteSize());
|
||||
envelope.mutable_gamemessage()->PackFrom(*msg);
|
||||
|
||||
LiveAPISystem()->LogEvent(&envelope, &envelope.gamemessage());
|
||||
}
|
||||
|
||||
static google::protobuf::Message* LiveAPI_AllocMessage(const eLiveAPI_EventTypes eventType)
|
||||
{
|
||||
switch (eventType)
|
||||
{
|
||||
case eLiveAPI_EventTypes::init:
|
||||
return new rtech::liveapi::Init();
|
||||
case eLiveAPI_EventTypes::matchSetup:
|
||||
return new rtech::liveapi::MatchSetup();
|
||||
case eLiveAPI_EventTypes::ammoUsed:
|
||||
return new rtech::liveapi::AmmoUsed();
|
||||
case eLiveAPI_EventTypes::arenasItemDeselected:
|
||||
return new rtech::liveapi::ArenasItemDeselected();
|
||||
case eLiveAPI_EventTypes::arenasItemSelected:
|
||||
return new rtech::liveapi::ArenasItemSelected();
|
||||
case eLiveAPI_EventTypes::bannerCollected:
|
||||
return new rtech::liveapi::BannerCollected();
|
||||
case eLiveAPI_EventTypes::customEvent:
|
||||
return new rtech::liveapi::CustomEvent();
|
||||
case eLiveAPI_EventTypes::inventoryPickUp:
|
||||
return new rtech::liveapi::InventoryPickUp();
|
||||
case eLiveAPI_EventTypes::inventoryDrop:
|
||||
return new rtech::liveapi::InventoryDrop();
|
||||
case eLiveAPI_EventTypes::inventoryUse:
|
||||
return new rtech::liveapi::InventoryUse();
|
||||
case eLiveAPI_EventTypes::gameStateChanged:
|
||||
return new rtech::liveapi::GameStateChanged();
|
||||
case eLiveAPI_EventTypes::matchStateEnd:
|
||||
return new rtech::liveapi::MatchStateEnd();
|
||||
case eLiveAPI_EventTypes::characterSelected:
|
||||
return new rtech::liveapi::CharacterSelected();
|
||||
case eLiveAPI_EventTypes::warpGateUsed:
|
||||
return new rtech::liveapi::WarpGateUsed();
|
||||
case eLiveAPI_EventTypes::wraithPortal:
|
||||
return new rtech::liveapi::WraithPortal();
|
||||
case eLiveAPI_EventTypes::playerConnected:
|
||||
return new rtech::liveapi::PlayerConnected();
|
||||
case eLiveAPI_EventTypes::playerRevive:
|
||||
return new rtech::liveapi::PlayerRevive();
|
||||
case eLiveAPI_EventTypes::playerDisconnected:
|
||||
return new rtech::liveapi::PlayerDisconnected();
|
||||
case eLiveAPI_EventTypes::playerDamaged:
|
||||
return new rtech::liveapi::PlayerDamaged();
|
||||
case eLiveAPI_EventTypes::playerDowned:
|
||||
return new rtech::liveapi::PlayerDowned();
|
||||
case eLiveAPI_EventTypes::playerKilled:
|
||||
return new rtech::liveapi::PlayerKilled();
|
||||
case eLiveAPI_EventTypes::playerAssist:
|
||||
return new rtech::liveapi::PlayerAssist();
|
||||
case eLiveAPI_EventTypes::playerRespawnTeam:
|
||||
return new rtech::liveapi::PlayerRespawnTeam();
|
||||
case eLiveAPI_EventTypes::playerStatChanged:
|
||||
return new rtech::liveapi::PlayerStatChanged();
|
||||
case eLiveAPI_EventTypes::playerUpgradeTierChanged:
|
||||
return new rtech::liveapi::PlayerUpgradeTierChanged();
|
||||
case eLiveAPI_EventTypes::legendUpgradeSelected:
|
||||
return new rtech::liveapi::LegendUpgradeSelected();
|
||||
case eLiveAPI_EventTypes::gibraltarShieldAbsorbed:
|
||||
return new rtech::liveapi::GibraltarShieldAbsorbed();
|
||||
case eLiveAPI_EventTypes::revenantForgedShadowDamaged:
|
||||
return new rtech::liveapi::RevenantForgedShadowDamaged();
|
||||
case eLiveAPI_EventTypes::ringStartClosing:
|
||||
return new rtech::liveapi::RingStartClosing();
|
||||
case eLiveAPI_EventTypes::ringFinishedClosing:
|
||||
return new rtech::liveapi::RingFinishedClosing();
|
||||
case eLiveAPI_EventTypes::squadEliminated:
|
||||
return new rtech::liveapi::SquadEliminated();
|
||||
case eLiveAPI_EventTypes::ziplineUsed:
|
||||
return new rtech::liveapi::ZiplineUsed();
|
||||
case eLiveAPI_EventTypes::grenadeThrown:
|
||||
return new rtech::liveapi::GrenadeThrown();
|
||||
case eLiveAPI_EventTypes::playerAbilityUsed:
|
||||
return new rtech::liveapi::PlayerAbilityUsed();
|
||||
case eLiveAPI_EventTypes::weaponSwitched:
|
||||
return new rtech::liveapi::WeaponSwitched();
|
||||
case eLiveAPI_EventTypes::blackMarketAction:
|
||||
return new rtech::liveapi::BlackMarketAction();
|
||||
case eLiveAPI_EventTypes::observerSwitched:
|
||||
return new rtech::liveapi::ObserverSwitched();
|
||||
case eLiveAPI_EventTypes::observerAnnotation:
|
||||
return new rtech::liveapi::ObserverAnnotation();
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
LiveAPISystem()->LogEvent(&s_liveAPIEvent, &s_liveAPIEvent.gamemessage());
|
||||
s_liveAPIEvent.Clear();
|
||||
}
|
||||
|
||||
static bool LiveAPI_HandleEventByCategory(HSQUIRRELVM const v, const SQTable* const table, const eLiveAPI_EventTypes eventType)
|
||||
{
|
||||
google::protobuf::Message* const msg = LiveAPI_AllocMessage(eventType);
|
||||
|
||||
if (!msg)
|
||||
{
|
||||
v_SQVM_RaiseError(v, "Event type \"%d\" not found.", eventType);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ranLoop = false;
|
||||
google::protobuf::Message* msg = nullptr;
|
||||
|
||||
SQ_FOR_EACH_TABLE(table, i)
|
||||
{
|
||||
@ -1995,15 +1970,8 @@ static bool LiveAPI_HandleEventByCategory(HSQUIRRELVM const v, const SQTable* co
|
||||
if (sq_isnull(node.key))
|
||||
continue;
|
||||
|
||||
ranLoop = true;
|
||||
|
||||
if (!LiveAPI_CheckSwitchType(v, node.key))
|
||||
{
|
||||
Assert(msg);
|
||||
delete msg;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const SQInteger fieldNum = _integer(node.key);
|
||||
const SQObjectPtr& obj = node.val;
|
||||
@ -2013,146 +1981,179 @@ static bool LiveAPI_HandleEventByCategory(HSQUIRRELVM const v, const SQTable* co
|
||||
switch (eventType)
|
||||
{
|
||||
case eLiveAPI_EventTypes::init:
|
||||
ret = LiveAPI_HandleInitEvent(reinterpret_cast<rtech::liveapi::Init*>(msg), eventType);
|
||||
msg = &s_init;
|
||||
ret = LiveAPI_HandleInitEvent(&s_init, eventType);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::matchSetup:
|
||||
ret = LiveAPI_HandleMatchSetup(v, obj, reinterpret_cast<rtech::liveapi::MatchSetup*>(msg), eventType, fieldNum);
|
||||
msg = &s_matchSetup;
|
||||
ret = LiveAPI_HandleMatchSetup(v, obj, &s_matchSetup, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::ammoUsed:
|
||||
ret = LiveAPI_HandleAmmoUsed(v, obj, reinterpret_cast<rtech::liveapi::AmmoUsed*>(msg), eventType, fieldNum);
|
||||
msg = &s_ammoUsed;
|
||||
ret = LiveAPI_HandleAmmoUsed(v, obj, &s_ammoUsed, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::arenasItemDeselected:
|
||||
ret = LiveAPI_HandleInventoryChange(v, obj, reinterpret_cast<rtech::liveapi::ArenasItemDeselected*>(msg), eventType, fieldNum);
|
||||
msg = &s_arenasItemDeselected;
|
||||
ret = LiveAPI_HandleInventoryChange(v, obj, &s_arenasItemDeselected, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::arenasItemSelected:
|
||||
ret = LiveAPI_HandleInventoryChange(v, obj, reinterpret_cast<rtech::liveapi::ArenasItemSelected*>(msg), eventType, fieldNum);
|
||||
msg = &s_arenasItemSelected;
|
||||
ret = LiveAPI_HandleInventoryChange(v, obj, &s_arenasItemSelected, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::bannerCollected:
|
||||
ret = LiveAPI_HandleBannerCollected(v, obj, reinterpret_cast<rtech::liveapi::BannerCollected*>(msg), eventType, fieldNum);
|
||||
msg = &s_bannerCollected;
|
||||
ret = LiveAPI_HandleBannerCollected(v, obj, &s_bannerCollected, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::customEvent:
|
||||
ret = LiveAPI_HandleCustomEvent(v, obj, reinterpret_cast<rtech::liveapi::CustomEvent*>(msg), eventType, fieldNum);
|
||||
msg = &s_customEvent;
|
||||
ret = LiveAPI_HandleCustomEvent(v, obj, &s_customEvent, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::inventoryPickUp:
|
||||
ret = LiveAPI_HandleInventoryChange(v, obj, reinterpret_cast<rtech::liveapi::InventoryPickUp*>(msg), eventType, fieldNum);
|
||||
msg = &s_inventoryPickUp;
|
||||
ret = LiveAPI_HandleInventoryChange(v, obj, &s_inventoryPickUp, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::inventoryDrop:
|
||||
ret = LiveAPI_HandleInventoryDrop(v, obj, reinterpret_cast<rtech::liveapi::InventoryDrop*>(msg), eventType, fieldNum);
|
||||
msg = &s_inventoryDrop;
|
||||
ret = LiveAPI_HandleInventoryDrop(v, obj, &s_inventoryDrop, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::inventoryUse:
|
||||
ret = LiveAPI_HandleInventoryChange(v, obj, reinterpret_cast<rtech::liveapi::InventoryUse*>(msg), eventType, fieldNum);
|
||||
msg = &s_inventoryUse;
|
||||
ret = LiveAPI_HandleInventoryChange(v, obj, &s_inventoryUse, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::gameStateChanged:
|
||||
ret = LiveAPI_HandleGameStateChanged(v, obj, reinterpret_cast<rtech::liveapi::GameStateChanged*>(msg), eventType, fieldNum);
|
||||
msg = &s_gameStateChanged;
|
||||
ret = LiveAPI_HandleGameStateChanged(v, obj, &s_gameStateChanged, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::matchStateEnd:
|
||||
ret = LiveAPI_HandleMatchStateEnd(v, obj, reinterpret_cast<rtech::liveapi::MatchStateEnd*>(msg), eventType, fieldNum);
|
||||
msg = &s_matchStateEnd;
|
||||
ret = LiveAPI_HandleMatchStateEnd(v, obj, &s_matchStateEnd, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::characterSelected:
|
||||
ret = LiveAPI_HandleSimplePlayerMessage(v, obj, reinterpret_cast<rtech::liveapi::CharacterSelected*>(msg), eventType, fieldNum);
|
||||
msg = &s_characterSelected;
|
||||
ret = LiveAPI_HandleSimplePlayerMessage(v, obj, &s_characterSelected, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::warpGateUsed:
|
||||
ret = LiveAPI_HandleSimplePlayerMessage(v, obj, reinterpret_cast<rtech::liveapi::WarpGateUsed*>(msg), eventType, fieldNum);
|
||||
msg = &s_warpGateUsed;
|
||||
ret = LiveAPI_HandleSimplePlayerMessage(v, obj, &s_warpGateUsed, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::wraithPortal:
|
||||
ret = LiveAPI_HandleSimplePlayerMessage(v, obj, reinterpret_cast<rtech::liveapi::WraithPortal*>(msg), eventType, fieldNum);
|
||||
msg = &s_wraithPortal;
|
||||
ret = LiveAPI_HandleSimplePlayerMessage(v, obj, &s_wraithPortal, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::playerConnected:
|
||||
ret = LiveAPI_HandleSimplePlayerMessage(v, obj, reinterpret_cast<rtech::liveapi::PlayerConnected*>(msg), eventType, fieldNum);
|
||||
msg = &s_playerConnected;
|
||||
ret = LiveAPI_HandleSimplePlayerMessage(v, obj, &s_playerConnected, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::playerRevive:
|
||||
ret = LiveAPI_HandlePlayerRevive(v, obj, reinterpret_cast<rtech::liveapi::PlayerRevive*>(msg), eventType, fieldNum);
|
||||
msg = &s_playerRevive;
|
||||
ret = LiveAPI_HandlePlayerRevive(v, obj, &s_playerRevive, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::playerDisconnected:
|
||||
ret = LiveAPI_HandlePlayerDisconnected(v, obj, reinterpret_cast<rtech::liveapi::PlayerDisconnected*>(msg), eventType, fieldNum);
|
||||
msg = &s_playerDisconnected;
|
||||
ret = LiveAPI_HandlePlayerDisconnected(v, obj, &s_playerDisconnected, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::playerDamaged:
|
||||
ret = LiveAPI_HandlePlayerDamaged(v, obj, reinterpret_cast<rtech::liveapi::PlayerDamaged*>(msg), eventType, fieldNum);
|
||||
msg = &s_playerDamaged;
|
||||
ret = LiveAPI_HandlePlayerDamaged(v, obj, &s_playerDamaged, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::playerDowned:
|
||||
ret = LiveAPI_HandlePlayerDowned(v, obj, reinterpret_cast<rtech::liveapi::PlayerDowned*>(msg), eventType, fieldNum);
|
||||
msg = &s_playerDowned;
|
||||
ret = LiveAPI_HandlePlayerDowned(v, obj, &s_playerDowned, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::playerKilled:
|
||||
ret = LiveAPI_HandlePlayerKilled(v, obj, reinterpret_cast<rtech::liveapi::PlayerKilled*>(msg), eventType, fieldNum);
|
||||
msg = &s_playerKilled;
|
||||
ret = LiveAPI_HandlePlayerKilled(v, obj, &s_playerKilled, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::playerAssist:
|
||||
ret = LiveAPI_HandlePlayerAssist(v, obj, reinterpret_cast<rtech::liveapi::PlayerAssist*>(msg), eventType, fieldNum);
|
||||
msg = &s_playerAssist;
|
||||
ret = LiveAPI_HandlePlayerAssist(v, obj, &s_playerAssist, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::playerRespawnTeam:
|
||||
ret = LiveAPI_HandlePlayerRespawnTeam(v, obj, reinterpret_cast<rtech::liveapi::PlayerRespawnTeam*>(msg), eventType, fieldNum);
|
||||
msg = &s_playerRespawnTeam;
|
||||
ret = LiveAPI_HandlePlayerRespawnTeam(v, obj, &s_playerRespawnTeam, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::playerStatChanged:
|
||||
ret = LiveAPI_HandlePlayerStatChanged(v, obj, reinterpret_cast<rtech::liveapi::PlayerStatChanged*>(msg), eventType, fieldNum);
|
||||
msg = &s_playerStatChanged;
|
||||
ret = LiveAPI_HandlePlayerStatChanged(v, obj, &s_playerStatChanged, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::playerUpgradeTierChanged:
|
||||
ret = LiveAPI_HandlePlayerUpgradeTierChanged(v, obj, reinterpret_cast<rtech::liveapi::PlayerUpgradeTierChanged*>(msg), eventType, fieldNum);
|
||||
msg = &s_playerUpgradeTierChanged;
|
||||
ret = LiveAPI_HandlePlayerUpgradeTierChanged(v, obj, &s_playerUpgradeTierChanged, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::legendUpgradeSelected:
|
||||
ret = LiveAPI_HandleLegendUpgradeSelected(v, obj, reinterpret_cast<rtech::liveapi::LegendUpgradeSelected*>(msg), eventType, fieldNum);
|
||||
msg = &s_legendUpgradeSelected;
|
||||
ret = LiveAPI_HandleLegendUpgradeSelected(v, obj, &s_legendUpgradeSelected, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::gibraltarShieldAbsorbed:
|
||||
ret = LiveAPI_HandleAbilityDamaged(v, obj, reinterpret_cast<rtech::liveapi::GibraltarShieldAbsorbed*>(msg), eventType, fieldNum);
|
||||
msg = &s_gibraltarShieldAbsorbed;
|
||||
ret = LiveAPI_HandleAbilityDamaged(v, obj, &s_gibraltarShieldAbsorbed, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::revenantForgedShadowDamaged:
|
||||
ret = LiveAPI_HandleAbilityDamaged(v, obj, reinterpret_cast<rtech::liveapi::RevenantForgedShadowDamaged*>(msg), eventType, fieldNum);
|
||||
msg = &s_revenantForgedShadowDamaged;
|
||||
ret = LiveAPI_HandleAbilityDamaged(v, obj, &s_revenantForgedShadowDamaged, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::ringStartClosing:
|
||||
ret = LiveAPI_HandleDeathFieldStartClosing(v, obj, reinterpret_cast<rtech::liveapi::RingStartClosing*>(msg), eventType, fieldNum);
|
||||
msg = &s_ringStartClosing;
|
||||
ret = LiveAPI_HandleDeathFieldStartClosing(v, obj, &s_ringStartClosing, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::ringFinishedClosing:
|
||||
ret = LiveAPI_HandleRingFinishedClosing(v, obj, reinterpret_cast<rtech::liveapi::RingFinishedClosing*>(msg), eventType, fieldNum);
|
||||
msg = &s_ringFinishedClosing;
|
||||
ret = LiveAPI_HandleRingFinishedClosing(v, obj, &s_ringFinishedClosing, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::squadEliminated:
|
||||
ret = LiveAPI_HandleSquadEliminated(v, obj, reinterpret_cast<rtech::liveapi::SquadEliminated*>(msg), eventType, fieldNum);
|
||||
msg = &s_squadEliminated;
|
||||
ret = LiveAPI_HandleSquadEliminated(v, obj, &s_squadEliminated, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::ziplineUsed:
|
||||
ret = LiveAPI_HandleLinkedEntityEvent(v, obj, reinterpret_cast<rtech::liveapi::ZiplineUsed*>(msg), eventType, fieldNum);
|
||||
msg = &s_ziplineUsed;
|
||||
ret = LiveAPI_HandleLinkedEntityEvent(v, obj, &s_ziplineUsed, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::grenadeThrown:
|
||||
ret = LiveAPI_HandleLinkedEntityEvent(v, obj, reinterpret_cast<rtech::liveapi::GrenadeThrown*>(msg), eventType, fieldNum);
|
||||
msg = &s_grenadeThrown;
|
||||
ret = LiveAPI_HandleLinkedEntityEvent(v, obj, &s_grenadeThrown, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::playerAbilityUsed:
|
||||
ret = LiveAPI_HandleLinkedEntityEvent(v, obj, reinterpret_cast<rtech::liveapi::PlayerAbilityUsed*>(msg), eventType, fieldNum);
|
||||
msg = &s_playerAbilityUsed;
|
||||
ret = LiveAPI_HandleLinkedEntityEvent(v, obj, &s_playerAbilityUsed, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::weaponSwitched:
|
||||
ret = LiveAPI_HandleWeaponSwitchedEvent(v, obj, reinterpret_cast<rtech::liveapi::WeaponSwitched*>(msg), eventType, fieldNum);
|
||||
msg = &s_weaponSwitched;
|
||||
ret = LiveAPI_HandleWeaponSwitchedEvent(v, obj, &s_weaponSwitched, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::blackMarketAction:
|
||||
ret = LiveAPI_HandleBlackMarketActionEvent(v, obj, reinterpret_cast<rtech::liveapi::BlackMarketAction*>(msg), eventType, fieldNum);
|
||||
msg = &s_blackMarketAction;
|
||||
ret = LiveAPI_HandleBlackMarketActionEvent(v, obj, &s_blackMarketAction, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::observerSwitched:
|
||||
ret = LiveAPI_HandleObserverSwitched(v, obj, reinterpret_cast<rtech::liveapi::ObserverSwitched*>(msg), eventType, fieldNum);
|
||||
msg = &s_observerSwitched;
|
||||
ret = LiveAPI_HandleObserverSwitched(v, obj, &s_observerSwitched, eventType, fieldNum);
|
||||
break;
|
||||
case eLiveAPI_EventTypes::observerAnnotation:
|
||||
ret = LiveAPI_HandleObserverAnnotation(v, obj, reinterpret_cast<rtech::liveapi::ObserverAnnotation*>(msg), eventType, fieldNum);
|
||||
msg = &s_observerAnnotation;
|
||||
ret = LiveAPI_HandleObserverAnnotation(v, obj, &s_observerAnnotation, eventType, fieldNum);
|
||||
break;
|
||||
default:
|
||||
// LiveAPI_AllocMessage() will fail if the user provided an invalid
|
||||
// event type, if you reached this there is a code bug somewhere.
|
||||
UNREACHABLE();
|
||||
v_SQVM_RaiseError(v, "Event type \"%d\" not found.", eventType);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
Assert(msg);
|
||||
delete msg;
|
||||
|
||||
msg->Clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ranLoop) // Script bug, e.g. giving an empty table (either completely empty or filled with null)
|
||||
if (!msg) // Script bug, e.g. giving an empty table (either completely empty or filled with null)
|
||||
{
|
||||
v_SQVM_RaiseError(v, "Empty table on event type \"%d\".", eventType);
|
||||
|
||||
Assert(msg);
|
||||
delete msg;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
LiveAPI_SendEvent(msg);
|
||||
delete msg;
|
||||
msg->Clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ namespace VScriptCode
|
||||
|
||||
if (!VALID_CHARSTAR(val))
|
||||
{
|
||||
v_SQVM_ScriptError("Empty or null class var");
|
||||
v_SQVM_ScriptError("Empty or null class value");
|
||||
SCRIPT_CHECK_AND_RETURN(v, SQ_ERROR);
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ namespace VScriptCode
|
||||
//-----------------------------------------------------------------------------
|
||||
SQRESULT GetSDKVersion(HSQUIRRELVM v)
|
||||
{
|
||||
sq_pushstring(v, SDK_VERSION, -1);
|
||||
sq_pushstring(v, SDK_VERSION, sizeof(SDK_VERSION)-1);
|
||||
SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ namespace VScriptCode
|
||||
{
|
||||
const CUtlString& mapName = g_InstalledMaps[i];
|
||||
|
||||
sq_pushstring(v, mapName.String(), -1);
|
||||
sq_pushstring(v, mapName.String(), (SQInteger)mapName.Length());
|
||||
sq_arrayappend(v, -2);
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ namespace VScriptCode
|
||||
sq_newarray(v, 0);
|
||||
for (const CUtlString& it : g_vecAllPlaylists)
|
||||
{
|
||||
sq_pushstring(v, it.String(), -1);
|
||||
sq_pushstring(v, it.String(), (SQInteger)it.Length());
|
||||
sq_arrayappend(v, -2);
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@ CBrowser::CBrowser(void)
|
||||
: m_reclaimFocusOnTokenField(false)
|
||||
, m_queryNewListNonRecursive(false)
|
||||
, m_queryGlobalBanList(true)
|
||||
, m_lockedIconShaderResource(nullptr)
|
||||
, m_hostMessageColor(1.00f, 1.00f, 1.00f, 1.00f)
|
||||
, m_hiddenServerMessageColor(0.00f, 1.00f, 0.00f, 1.00f)
|
||||
{
|
||||
@ -57,8 +58,6 @@ CBrowser::CBrowser(void)
|
||||
memset(m_serverAddressTextBuf, '\0', sizeof(m_serverAddressTextBuf));
|
||||
memset(m_serverNetKeyTextBuf, '\0', sizeof(m_serverNetKeyTextBuf));
|
||||
|
||||
m_lockedIconDataResource = GetModuleResource(IDB_PNG2);
|
||||
|
||||
m_levelName = "mp_lobby";
|
||||
m_gameMode = "dev_default";
|
||||
}
|
||||
@ -78,7 +77,10 @@ bool CBrowser::Init(void)
|
||||
{
|
||||
SetStyleVar(927.f, 524.f, -500.f, 50.f);
|
||||
|
||||
bool ret = LoadTextureBuffer(reinterpret_cast<unsigned char*>(m_lockedIconDataResource.m_pData), int(m_lockedIconDataResource.m_nSize),
|
||||
HMODULE sdkModule = reinterpret_cast<HMODULE>(g_SDKDll.GetModuleBase());
|
||||
m_lockedIconDataResource = GetModuleResource(sdkModule, IDB_PNG2);
|
||||
|
||||
const bool ret = LoadTextureBuffer(reinterpret_cast<unsigned char*>(m_lockedIconDataResource.m_pData), int(m_lockedIconDataResource.m_nSize),
|
||||
&m_lockedIconShaderResource, &m_lockedIconDataResource.m_nWidth, &m_lockedIconDataResource.m_nHeight);
|
||||
|
||||
IM_ASSERT(ret && m_lockedIconShaderResource);
|
||||
@ -191,6 +193,9 @@ void CBrowser::RunTask()
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBrowser::DrawSurface(void)
|
||||
{
|
||||
if (!IsVisible())
|
||||
return false;
|
||||
|
||||
if (!ImGui::Begin(m_surfaceLabel, &m_activated, ImGuiWindowFlags_None, &ResetInput))
|
||||
{
|
||||
ImGui::End();
|
||||
@ -276,9 +281,9 @@ void CBrowser::DrawBrowserPanel(void)
|
||||
const char* pszHostMap = server.map.c_str();
|
||||
const char* pszPlaylist = server.playlist.c_str();
|
||||
|
||||
if (m_serverBrowserTextFilter.PassFilter(pszHostName)
|
||||
|| m_serverBrowserTextFilter.PassFilter(pszHostMap)
|
||||
|| m_serverBrowserTextFilter.PassFilter(pszPlaylist))
|
||||
if (m_serverBrowserTextFilter.PassFilter(pszHostName, &pszHostName[server.name.length()])
|
||||
|| m_serverBrowserTextFilter.PassFilter(pszHostMap, &pszHostMap[server.map.length()])
|
||||
|| m_serverBrowserTextFilter.PassFilter(pszPlaylist, &pszPlaylist[server.playlist.length()]))
|
||||
{
|
||||
filteredServers.push_back(&server);
|
||||
}
|
||||
@ -292,28 +297,32 @@ void CBrowser::DrawBrowserPanel(void)
|
||||
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
|
||||
{
|
||||
const NetGameServer_t* const server = filteredServers[i];
|
||||
|
||||
const char* pszHostName = server->name.c_str();
|
||||
const char* pszHostMap = server->map.c_str();
|
||||
const char* pszPlaylist = server->playlist.c_str();
|
||||
|
||||
char pszHostPort[32];
|
||||
sprintf(pszHostPort, "%d", server->port);
|
||||
const ImGuiTextFlags textFlags = ImGuiTextFlags_NoWidthForLargeClippedText;
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", pszHostName);
|
||||
|
||||
const char* const pszHostName = server->name.c_str();
|
||||
ImGui::TextEx(pszHostName, &pszHostName[server->name.length()], textFlags);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", pszHostMap);
|
||||
|
||||
const char* const pszHostMap = server->map.c_str();
|
||||
ImGui::TextEx(pszHostMap, &pszHostMap[server->map.length()], textFlags);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", pszPlaylist);
|
||||
|
||||
const char* const pszPlaylist = server->playlist.c_str();
|
||||
ImGui::TextEx(pszPlaylist, &pszPlaylist[server->playlist.length()], textFlags);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", Format("%3d/%3d", server->numPlayers, server->maxPlayers).c_str());
|
||||
|
||||
const std::string playerNums = Format("%3d/%3d", server->numPlayers, server->maxPlayers);
|
||||
|
||||
const char* const pszPlayerNums = playerNums.c_str();
|
||||
ImGui::TextEx(pszPlayerNums, &pszPlayerNums[playerNums.length()], textFlags);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", pszHostPort);
|
||||
ImGui::Text("%d", server->port);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
string svConnectBtn = "Connect##";
|
||||
@ -809,11 +818,11 @@ void CBrowser::UpdateHostingStatus(void)
|
||||
break;
|
||||
}
|
||||
|
||||
const NetGameServer_t netGameServer
|
||||
NetGameServer_t netGameServer
|
||||
{
|
||||
hostname->GetString(),
|
||||
hostdesc.GetString(),
|
||||
serverVisibility == ServerVisibility_e::PUBLIC,
|
||||
serverVisibility == ServerVisibility_e::HIDDEN,
|
||||
g_pHostState->m_levelName,
|
||||
v_Playlists_GetCurrent(),
|
||||
hostip->GetString(),
|
||||
@ -842,10 +851,10 @@ void CBrowser::UpdateHostingStatus(void)
|
||||
// host data on the server browser
|
||||
// Input : &gameServer -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBrowser::SendHostingPostRequest(const NetGameServer_t& gameServer)
|
||||
void CBrowser::SendHostingPostRequest(NetGameServer_t& gameServer)
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
std::thread request([&, gameServer]
|
||||
std::thread request([&, gameServer = std::move(gameServer)]
|
||||
{
|
||||
string hostRequestMessage;
|
||||
string hostToken;
|
||||
@ -855,7 +864,7 @@ void CBrowser::SendHostingPostRequest(const NetGameServer_t& gameServer)
|
||||
|
||||
g_TaskQueue.Dispatch([&, result, hostRequestMessage, hostToken, hostIp]
|
||||
{
|
||||
InstallHostingDetails(result, hostRequestMessage.c_str(), hostToken.c_str(), hostIp);
|
||||
InstallHostingDetails(result, hostRequestMessage, hostToken, hostIp);
|
||||
}, 0);
|
||||
}
|
||||
);
|
||||
@ -870,7 +879,7 @@ void CBrowser::SendHostingPostRequest(const NetGameServer_t& gameServer)
|
||||
// *hostToken -
|
||||
// &hostIp -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBrowser::InstallHostingDetails(const bool postFailed, const char* const hostMessage, const char* const hostToken, const string& hostIp)
|
||||
void CBrowser::InstallHostingDetails(const bool postFailed, const string& hostMessage, const string& hostToken, const string& hostIp)
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
m_hostMessage = hostMessage;
|
||||
@ -884,14 +893,10 @@ void CBrowser::InstallHostingDetails(const bool postFailed, const char* const ho
|
||||
if (postFailed)
|
||||
{
|
||||
m_hostMessageColor = ImVec4(0.00f, 1.00f, 0.00f, 1.00f);
|
||||
stringstream ssMessage;
|
||||
ssMessage << "Broadcasting";
|
||||
if (!m_hostToken.empty())
|
||||
{
|
||||
ssMessage << ": share the following token for clients to connect: ";
|
||||
}
|
||||
|
||||
m_hostMessage = ssMessage.str();
|
||||
m_hostMessage = m_hostToken.empty()
|
||||
? "Broadcasting"
|
||||
: "Broadcasting: share the following token for clients to connect: ";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -31,8 +31,8 @@ public:
|
||||
void DrawHostPanel(void);
|
||||
|
||||
void UpdateHostingStatus(void);
|
||||
void InstallHostingDetails(const bool postFailed, const char* const hostMessage, const char* const hostToken, const string& hostIp);
|
||||
void SendHostingPostRequest(const NetGameServer_t& gameServer);
|
||||
void InstallHostingDetails(const bool postFailed, const string& hostMessage, const string& hostToken, const string& hostIp);
|
||||
void SendHostingPostRequest(NetGameServer_t& gameServer);
|
||||
|
||||
void ProcessCommand(const char* pszCommand) const;
|
||||
|
||||
|
@ -129,8 +129,6 @@ void CConsole::RunFrame(void)
|
||||
if (m_surfaceStyle == ImGuiStyle_t::MODERN)
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 8.f, 10.f }); baseWindowStyleVars++;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_fadeAlpha); baseWindowStyleVars++;
|
||||
|
||||
minBaseWindowRect = ImVec2(621.f, 532.f);
|
||||
}
|
||||
else
|
||||
@ -140,9 +138,9 @@ void CConsole::RunFrame(void)
|
||||
: ImVec2(618.f, 524.f);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 6.f, 6.f }); baseWindowStyleVars++;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_fadeAlpha); baseWindowStyleVars++;
|
||||
}
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_fadeAlpha); baseWindowStyleVars++;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, minBaseWindowRect); baseWindowStyleVars++;
|
||||
|
||||
const bool drawn = DrawSurface();
|
||||
@ -188,6 +186,9 @@ void CConsole::RunFrame(void)
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CConsole::DrawSurface(void)
|
||||
{
|
||||
if (!IsVisible())
|
||||
return false;
|
||||
|
||||
if (!ImGui::Begin(m_surfaceLabel, &m_activated, ImGuiWindowFlags_None, &ResetInput))
|
||||
{
|
||||
ImGui::End();
|
||||
@ -359,7 +360,7 @@ void CConsole::DrawOptionsPanel(void)
|
||||
m_colorTextLogger.Copy(true);
|
||||
}
|
||||
|
||||
ImGui::Text("Console HotKey:");
|
||||
ImGui::TextEx("Console HotKey:", nullptr, ImGuiTextFlags_NoWidthForLargeClippedText);
|
||||
ImGui::SameLine();
|
||||
|
||||
int selected = g_ImGuiConfig.m_ConsoleConfig.m_nBind0;
|
||||
@ -381,7 +382,7 @@ void CConsole::DrawOptionsPanel(void)
|
||||
g_ImGuiConfig.Save();
|
||||
}
|
||||
|
||||
ImGui::Text("Browser HotKey:");
|
||||
ImGui::TextEx("Browser HotKey:", nullptr, ImGuiTextFlags_NoWidthForLargeClippedText);
|
||||
ImGui::SameLine();
|
||||
|
||||
selected = g_ImGuiConfig.m_BrowserConfig.m_nBind0;
|
||||
@ -507,7 +508,7 @@ static void AddHint(const ConVarFlags::FlagDesc_t& cvarInfo, const vector<MODULE
|
||||
|
||||
ImGui::Image(hintRes.m_idIcon, ImVec2(float(hintRes.m_nWidth), float(hintRes.m_nHeight)));
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", cvarInfo.shortdesc);
|
||||
ImGui::TextEx(cvarInfo.shortdesc, nullptr, ImGuiTextFlags_NoWidthForLargeClippedText);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -589,7 +590,7 @@ void CConsole::DrawAutoCompletePanel(void)
|
||||
m_canAutoComplete = true;
|
||||
m_reclaimFocus = true;
|
||||
|
||||
BuildSummaryText(newInputText.c_str());
|
||||
BuildSummaryText(newInputText.c_str(), newInputText.size());
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
@ -664,7 +665,7 @@ bool CConsole::RunAutoComplete(void)
|
||||
{
|
||||
const char c = m_inputTextBuf[i];
|
||||
|
||||
if (c == '\0' || isspace(c))
|
||||
if (c == '\0' || V_isspace(c))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -687,7 +688,8 @@ bool CConsole::RunAutoComplete(void)
|
||||
|
||||
for (int j = 0; j < iret; ++j)
|
||||
{
|
||||
m_vecSuggest.push_back(ConAutoCompleteSuggest_s(commands[j].String(), COMMAND_COMPLETION_MARKER));
|
||||
const CUtlString& cmdToAdd = commands[j];
|
||||
m_vecSuggest.emplace_back(cmdToAdd.String(), cmdToAdd.Length(), COMMAND_COMPLETION_MARKER);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -717,14 +719,25 @@ void CConsole::ResetAutoCompleteData(void)
|
||||
m_vecSuggest.clear();
|
||||
}
|
||||
|
||||
template <size_t N1, size_t N2>
|
||||
static void EncaseAppendString(string& targetString, const char* toEncase, const char(&open)[N1], const char(&close)[N2])
|
||||
{
|
||||
const size_t appLen = strlen(toEncase);
|
||||
const size_t newLen = targetString.length() + (N1-1) + (N2-1) + appLen+1;
|
||||
|
||||
targetString.reserve(newLen);
|
||||
|
||||
targetString.append(open, N1-1);
|
||||
targetString.append(toEncase, appLen);
|
||||
targetString.append(close, N2-1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: format appends the value string
|
||||
//-----------------------------------------------------------------------------
|
||||
static void AppendValueString(string& targetString, const char* const toAppend)
|
||||
{
|
||||
targetString.append(" = ["); // Assign current value to string if its a ConVar.
|
||||
targetString.append(toAppend);
|
||||
targetString.append("]");
|
||||
EncaseAppendString(targetString, toAppend, " = [", "]");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -732,12 +745,12 @@ static void AppendValueString(string& targetString, const char* const toAppend)
|
||||
//-----------------------------------------------------------------------------
|
||||
static void AppendDocString(string& targetString, const char* const toAppend)
|
||||
{
|
||||
if (VALID_CHARSTAR(toAppend))
|
||||
if (!VALID_CHARSTAR(toAppend))
|
||||
{
|
||||
targetString.append(" - \"");
|
||||
targetString.append(toAppend);
|
||||
targetString.append("\"");
|
||||
return;
|
||||
}
|
||||
|
||||
EncaseAppendString(targetString, toAppend, " - \"", "\"");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -786,7 +799,7 @@ void CConsole::CreateSuggestionsFromPartial(void)
|
||||
AppendDocString(docString, commandBase->GetHelpText());
|
||||
AppendDocString(docString, commandBase->GetUsageText());
|
||||
}
|
||||
m_vecSuggest.push_back(ConAutoCompleteSuggest_s(commandName + docString, commandBase->GetFlags()));
|
||||
m_vecSuggest.emplace_back(commandName + docString, commandBase->GetFlags());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -826,11 +839,11 @@ void CConsole::ProcessCommand(const char* const inputText)
|
||||
// formats the number of history items instead
|
||||
// Input : inputText -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CConsole::BuildSummaryText(const char* const inputText)
|
||||
void CConsole::BuildSummaryText(const char* const inputText, const size_t textLen)
|
||||
{
|
||||
if (*inputText)
|
||||
if (textLen > 0)
|
||||
{
|
||||
string conVarFormatted(inputText);
|
||||
string conVarFormatted(inputText, textLen);
|
||||
|
||||
// Remove trailing space and/or semicolon before we call 'g_pCVar->FindVar(..)'.
|
||||
StringRTrim(conVarFormatted, " ;", true);
|
||||
@ -911,22 +924,19 @@ void CConsole::DetermineAutoCompleteWindowRect(void)
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CConsole::LoadFlagIcons(void)
|
||||
{
|
||||
HMODULE sdkModule = reinterpret_cast<HMODULE>(g_SDKDll.GetModuleBase());
|
||||
bool ret = false;
|
||||
|
||||
// Get all flag image resources for displaying flags.
|
||||
for (int i = IDB_PNG3, k = NULL; i <= IDB_PNG32; i++, k++)
|
||||
{
|
||||
m_vecFlagIcons.push_back(MODULERESOURCE(GetModuleResource(i)));
|
||||
m_vecFlagIcons.emplace_back(GetModuleResource(sdkModule, i));
|
||||
MODULERESOURCE& rFlagIcon = m_vecFlagIcons[k];
|
||||
|
||||
ret = LoadTextureBuffer(reinterpret_cast<unsigned char*>(rFlagIcon.m_pData), // !TODO: Fall-back texture.
|
||||
static_cast<int>(rFlagIcon.m_nSize), &rFlagIcon.m_idIcon, &rFlagIcon.m_nWidth, &rFlagIcon.m_nHeight);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
Assert(0, "Texture flags load failed for %i", i);
|
||||
break;
|
||||
}
|
||||
Assert(ret, "Texture flags load failed for %i", i);
|
||||
}
|
||||
|
||||
m_autoCompleteTexturesLoaded = ret;
|
||||
@ -1023,7 +1033,7 @@ int CConsole::TextEditCallback(ImGuiInputTextCallbackData* iData)
|
||||
}
|
||||
}
|
||||
|
||||
BuildSummaryText(iData->Buf);
|
||||
BuildSummaryText(iData->Buf, iData->BufTextLen);
|
||||
break;
|
||||
}
|
||||
case ImGuiInputTextFlags_CallbackAlways:
|
||||
@ -1088,7 +1098,7 @@ int CConsole::TextEditCallback(ImGuiInputTextCallbackData* iData)
|
||||
ResetAutoCompleteData();
|
||||
}
|
||||
|
||||
BuildSummaryText(iData->Buf);
|
||||
BuildSummaryText(iData->Buf, iData->BufTextLen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1120,7 +1130,7 @@ void CConsole::HandleCommand()
|
||||
m_inputTextBufModified = true;
|
||||
}
|
||||
|
||||
BuildSummaryText("");
|
||||
BuildSummaryText("", 0);
|
||||
m_reclaimFocus = true;
|
||||
}
|
||||
|
||||
@ -1145,7 +1155,7 @@ void CConsole::HandleSuggest()
|
||||
const int vecIndex = parked ? 0 : m_suggestPos;
|
||||
|
||||
DetermineInputTextFromSelectedSuggestion(m_vecSuggest[vecIndex], m_selectedSuggestionText);
|
||||
BuildSummaryText(m_selectedSuggestionText.c_str());
|
||||
BuildSummaryText(m_selectedSuggestionText.c_str(), m_selectedSuggestionText.size());
|
||||
|
||||
m_inputTextBufModified = true;
|
||||
m_reclaimFocus = true;
|
||||
@ -1267,7 +1277,7 @@ void CConsole::ClampLogSize(void)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: adds a command to the history vector; this is the only place text
|
||||
// is added to the vector, do not call 'm_History.push_back' elsewhere as we
|
||||
// is added to the vector, do not call 'm_History.emplace_back' elsewhere as we
|
||||
// also manage the size of the vector here !!!
|
||||
//-----------------------------------------------------------------------------
|
||||
void CConsole::AddHistory(const char* const command)
|
||||
@ -1283,7 +1293,7 @@ void CConsole::AddHistory(const char* const command)
|
||||
}
|
||||
}
|
||||
|
||||
m_vecHistory.push_back(command);
|
||||
m_vecHistory.emplace_back(command);
|
||||
ClampHistorySize();
|
||||
}
|
||||
|
||||
@ -1302,7 +1312,7 @@ const vector<string>& CConsole::GetHistory(void) const
|
||||
void CConsole::ClearHistory(void)
|
||||
{
|
||||
m_vecHistory.clear();
|
||||
BuildSummaryText("");
|
||||
BuildSummaryText("", 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -30,7 +30,7 @@ private:
|
||||
void CreateSuggestionsFromPartial(void);
|
||||
void ProcessCommand(const char* const inputText);
|
||||
|
||||
void BuildSummaryText(const char* const inputText);
|
||||
void BuildSummaryText(const char* const inputText, const size_t textLen);
|
||||
|
||||
struct ConAutoCompleteSuggest_s;
|
||||
void DetermineInputTextFromSelectedSuggestion(const ConAutoCompleteSuggest_s& suggest, string& svInput);
|
||||
@ -83,6 +83,11 @@ private:
|
||||
text = inText;
|
||||
flags = inFlags;
|
||||
}
|
||||
ConAutoCompleteSuggest_s(const char* inText, const size_t len, const int inFlags)
|
||||
{
|
||||
text.assign(inText, len);
|
||||
flags = inFlags;
|
||||
}
|
||||
bool operator==(const string& a) const
|
||||
{
|
||||
return text.compare(a) == 0;
|
||||
|
218
src/gameui/IStreamOverlay.cpp
Normal file
218
src/gameui/IStreamOverlay.cpp
Normal file
@ -0,0 +1,218 @@
|
||||
/******************************************************************************
|
||||
-------------------------------------------------------------------------------
|
||||
File : IStreamOverlay.cpp
|
||||
Date : 08:01:2025
|
||||
Author : Kawe Mazidjatari
|
||||
Purpose: Implements the in-game texture streaming debug overlay
|
||||
-------------------------------------------------------------------------------
|
||||
History:
|
||||
- 08:01:2025 | 19:05 : Created by Kawe Mazidjatari
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "windows/id3dx.h"
|
||||
#include "materialsystem/texturestreaming.h"
|
||||
#include "IStreamOverlay.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Console variables
|
||||
//-----------------------------------------------------------------------------
|
||||
static ConVar stream_overlay_memory("stream_overlay_memory", "524288", FCVAR_DEVELOPMENTONLY, "Total string memory to allocate for the texture streaming debug overlay.", true, 1.f, false, 0.0f);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Console commands
|
||||
//-----------------------------------------------------------------------------
|
||||
static ConCommand stream_dumpinfo("stream_dumpinfo", CStreamOverlay::DumpStreamInfo_f, "Dump texture streaming debug info to the console", FCVAR_DEVELOPMENTONLY, nullptr, "tex mtl bsp short");
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: constructor/destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CStreamOverlay::CStreamOverlay(void)
|
||||
{
|
||||
m_surfaceLabel = "Stream Overlay";
|
||||
m_scratchBuffer = nullptr;
|
||||
m_scratchBufferSize = 0;
|
||||
m_lastAvailability = false;
|
||||
}
|
||||
CStreamOverlay::~CStreamOverlay(void)
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: stream overlay initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CStreamOverlay::Init(void)
|
||||
{
|
||||
SetStyleVar(1200, 524, -1000, 50);
|
||||
|
||||
m_initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: stream overlay shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStreamOverlay::Shutdown(void)
|
||||
{
|
||||
FreeScratchBuffer();
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: check value of stream_overlay and determine availability of window
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStreamOverlay::UpdateWindowAvailability(void)
|
||||
{
|
||||
const bool enabled = stream_overlay->GetBool();
|
||||
|
||||
if (enabled == m_lastAvailability)
|
||||
return;
|
||||
|
||||
if (!enabled && m_activated)
|
||||
{
|
||||
m_activated = false;
|
||||
ResetInput();
|
||||
}
|
||||
|
||||
else if (enabled && !m_activated)
|
||||
m_activated = true;
|
||||
|
||||
m_lastAvailability = enabled;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: run stream overlay frame
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStreamOverlay::RunFrame(void)
|
||||
{
|
||||
if (!m_initialized)
|
||||
Init();
|
||||
|
||||
Animate();
|
||||
|
||||
int baseWindowStyleVars = 0;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_fadeAlpha); baseWindowStyleVars++;
|
||||
|
||||
const bool drawn = DrawSurface();
|
||||
ImGui::PopStyleVar(baseWindowStyleVars);
|
||||
|
||||
if (!drawn)
|
||||
FreeScratchBuffer();
|
||||
|
||||
UpdateWindowAvailability();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: syncs the cvar and updates the availability of mouse/key inputs
|
||||
//-----------------------------------------------------------------------------
|
||||
static void StreamOverlay_HandleClose(void)
|
||||
{
|
||||
stream_overlay->SetValue(false);
|
||||
ResetInput();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: draw stream overlay
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CStreamOverlay::DrawSurface(void)
|
||||
{
|
||||
if (!IsVisible())
|
||||
return false;
|
||||
|
||||
if (!ImGui::Begin(m_surfaceLabel, &m_activated, ImGuiWindowFlags_None, &StreamOverlay_HandleClose))
|
||||
{
|
||||
ImGui::End();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ImGui::BeginChild("##StreamReport", ImVec2(-1, -1), ImGuiChildFlags_Border, ImGuiWindowFlags_None))
|
||||
{
|
||||
ResizeScratchBuffer(stream_overlay_memory.GetInt());
|
||||
|
||||
TextureStreamMgr_GetStreamOverlay(stream_overlay_mode->GetString(), m_scratchBuffer, m_scratchBufferSize);
|
||||
ImGui::TextUnformatted(m_scratchBuffer);
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
ImGui::End();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: dynamically scale the scratch buffer if it became smaller or larger
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStreamOverlay::ResizeScratchBuffer(const size_t newSize)
|
||||
{
|
||||
Assert(newSize > 0);
|
||||
|
||||
if (newSize == m_scratchBufferSize)
|
||||
return; // Same size.
|
||||
|
||||
if (m_scratchBuffer)
|
||||
delete[] m_scratchBuffer;
|
||||
|
||||
m_scratchBuffer = new char[newSize];
|
||||
m_scratchBufferSize = newSize;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: free the scratch buffer if we have one
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStreamOverlay::FreeScratchBuffer(void)
|
||||
{
|
||||
if (m_scratchBuffer)
|
||||
{
|
||||
delete[] m_scratchBuffer;
|
||||
|
||||
m_scratchBuffer = nullptr;
|
||||
m_scratchBufferSize = 0;
|
||||
}
|
||||
else
|
||||
Assert(m_scratchBufferSize == 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: render current streaming data to console with given or default mode
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStreamOverlay::RenderToConsole(const char* const mode)
|
||||
{
|
||||
const bool isTemp = m_scratchBuffer == nullptr;
|
||||
|
||||
// If we have a buffer already, use that to render the overlay report into
|
||||
// it. Else create a temporary buffer and free it afterwards.
|
||||
if (isTemp)
|
||||
{
|
||||
const size_t targetBufLen = stream_overlay_memory.GetInt();
|
||||
|
||||
m_scratchBuffer = new char[targetBufLen];
|
||||
m_scratchBufferSize = targetBufLen;
|
||||
}
|
||||
|
||||
TextureStreamMgr_GetStreamOverlay(mode ? mode : stream_overlay_mode->GetString(), m_scratchBuffer, m_scratchBufferSize);
|
||||
Msg(eDLL_T::MS, "%s\n", m_scratchBuffer);
|
||||
|
||||
if (isTemp)
|
||||
{
|
||||
delete[] m_scratchBuffer;
|
||||
|
||||
m_scratchBuffer = nullptr;
|
||||
m_scratchBufferSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CStreamOverlay g_streamOverlay;
|
||||
|
||||
/*
|
||||
=====================
|
||||
DumpStreamInfo_f
|
||||
|
||||
Dumps the stream info to the console.
|
||||
=====================
|
||||
*/
|
||||
void CStreamOverlay::DumpStreamInfo_f(const CCommand& args)
|
||||
{
|
||||
const char* const mode = args.ArgC() >= 2 ? args.Arg(1) : nullptr;
|
||||
g_streamOverlay.RenderToConsole(mode);
|
||||
}
|
36
src/gameui/IStreamOverlay.h
Normal file
36
src/gameui/IStreamOverlay.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include "imgui/misc/imgui_logger.h"
|
||||
#include "imgui/misc/imgui_utility.h"
|
||||
|
||||
#include "imgui_surface.h"
|
||||
|
||||
class CStreamOverlay : public CImguiSurface
|
||||
{
|
||||
public:
|
||||
CStreamOverlay(void);
|
||||
~CStreamOverlay(void);
|
||||
|
||||
virtual bool Init(void);
|
||||
virtual void Shutdown(void);
|
||||
|
||||
virtual void RunFrame(void);
|
||||
virtual bool DrawSurface(void);
|
||||
|
||||
void UpdateWindowAvailability(void);
|
||||
|
||||
void ResizeScratchBuffer(const size_t newSize);
|
||||
void FreeScratchBuffer(void);
|
||||
|
||||
void RenderToConsole(const char* const mode);
|
||||
|
||||
// Command callbacks.
|
||||
static void DumpStreamInfo_f(const CCommand& args);
|
||||
|
||||
private:
|
||||
char* m_scratchBuffer;
|
||||
size_t m_scratchBufferSize;
|
||||
|
||||
bool m_lastAvailability;
|
||||
};
|
||||
|
||||
extern CStreamOverlay g_streamOverlay;
|
@ -23,8 +23,8 @@ public:
|
||||
// inlines:
|
||||
inline void ToggleActive() { m_activated ^= true; }
|
||||
|
||||
inline bool IsActivated() { return m_activated; }
|
||||
inline bool IsVisible() { return m_fadeAlpha > 0.0f; }
|
||||
inline bool IsActivated() const { return m_activated; }
|
||||
inline bool IsVisible() const { return m_fadeAlpha > 0.0f; }
|
||||
|
||||
protected:
|
||||
const char* m_surfaceLabel;
|
||||
|
@ -91,6 +91,8 @@ void CImguiSystem::Shutdown()
|
||||
|
||||
m_initialized = false;
|
||||
m_hasNewFrame = false;
|
||||
|
||||
m_surfaceList.Purge();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -10,6 +10,8 @@ add_sources( SOURCE_GROUP "Private"
|
||||
"cmaterialsystem.h"
|
||||
"cshaderglue.cpp"
|
||||
"cshaderglue.h"
|
||||
"texturestreaming.cpp"
|
||||
"texturestreaming.h"
|
||||
)
|
||||
|
||||
add_sources( SOURCE_GROUP "Public"
|
||||
|
@ -5,75 +5,89 @@
|
||||
#include "public/materialsystem/shader_vcs_version.h"
|
||||
#include "public/rendersystem/schema/texture.g.h"
|
||||
|
||||
struct MaterialDXState_t
|
||||
#define MATERIAL_RENDER_PARAMS_COUNT 2 // the same for r2 and r5
|
||||
#define MATERIAL_SAMPLER_COUNT 4
|
||||
|
||||
class CMaterialGlue;
|
||||
|
||||
enum MaterialDepthPass_e
|
||||
{
|
||||
uint32_t blendState[8];
|
||||
unsigned int unkFlags;
|
||||
unsigned __int16 depthStencilFlags;
|
||||
unsigned __int16 rasterizerFlags;
|
||||
char pad[8];
|
||||
DEPTH_SHADOW,
|
||||
DEPTH_PREPASS,
|
||||
DEPTH_VSM,
|
||||
DEPTH_SHADOW_TIGHT,
|
||||
|
||||
MATERIAL_DEPTH_PASS_MAT_COUNT,
|
||||
};
|
||||
|
||||
// Virtual function-less material instance.
|
||||
struct MaterialGlue_s
|
||||
{
|
||||
PakGuid_t guid;
|
||||
const char* name;
|
||||
|
||||
const char* surfaceProp;
|
||||
const char* surfaceProp2;
|
||||
|
||||
CMaterialGlue* depthMaterials[MATERIAL_DEPTH_PASS_MAT_COUNT];
|
||||
CMaterialGlue* colpassMaterial;
|
||||
|
||||
CShaderGlue* shaderset;
|
||||
|
||||
TextureAsset_s** textureHandles;
|
||||
TextureAsset_s** streamingTextureHandles;
|
||||
uint16 streamingTextureHandleCount;
|
||||
|
||||
uint16 width;
|
||||
uint16 height;
|
||||
uint16 depth;
|
||||
|
||||
// An array of indices into sampler states array. must be set properly to
|
||||
// have accurate texture tiling. Used in CShaderGlue::SetupShader (1403B3C60)
|
||||
byte samplers[MATERIAL_SAMPLER_COUNT];// example: 0x1D0300;
|
||||
|
||||
uint32 unk_7C;
|
||||
|
||||
// some features? mostly differs per material with different shader types, but
|
||||
// it seems mostly unused by the runtime too.
|
||||
uint32 unk_80_0x1F5A92BD;
|
||||
uint32 unk_84;
|
||||
|
||||
uint32 materialFlags;
|
||||
uint32 materialFlags2;
|
||||
|
||||
MaterialRenderParams_s renderParams[MATERIAL_RENDER_PARAMS_COUNT];
|
||||
uint16 numAnimationFrames;
|
||||
MaterialShaderType_e materialType;
|
||||
uint8 uberBufferFlags;
|
||||
|
||||
int dwordf4;
|
||||
void* textureAnim;
|
||||
ID3D11Buffer* uberBuffer;
|
||||
void** pID3D11BufferVTable;
|
||||
void* viewBuffer;
|
||||
|
||||
// Last frame this material was used to shift the texture streaming histogram.
|
||||
uint32 lastFrame;
|
||||
|
||||
uint16 m_iUnknown4;
|
||||
uint16 m_iUnknown5;
|
||||
uint16 m_iUnknown6;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
class CMaterialGlue : public IMaterialInternal
|
||||
{
|
||||
public:
|
||||
uint8_t pad_0008[8]; //0x0008
|
||||
uint64_t assetGuid; //0x0010
|
||||
const char* name; //0x0018
|
||||
inline const MaterialGlue_s* Get() const { return &material; }
|
||||
inline MaterialGlue_s* Get() { return &material; }
|
||||
|
||||
const char* surfaceProp; //0x0020
|
||||
const char* surfaceProp2; //0x0028
|
||||
private:
|
||||
byte reserved[8];
|
||||
MaterialGlue_s material;
|
||||
|
||||
CMaterialGlue* depthShadowMaterial; //0x0030
|
||||
CMaterialGlue* depthPrepassMaterial; //0x0038
|
||||
CMaterialGlue* depthVSMMaterial; //0x0040
|
||||
CMaterialGlue* depthShadowTightMaterial; //0x0048
|
||||
CMaterialGlue* colpassMaterial; //0x0050
|
||||
|
||||
CShaderGlue* shaderset; //0x0058
|
||||
|
||||
TextureHeader_t** textureHandles; //0x0060
|
||||
TextureHeader_t** streamingTextureHandles; //0x0068
|
||||
|
||||
int16_t numStreamingTextureHandles; //0x0070
|
||||
|
||||
int16_t width; //0x0072
|
||||
int16_t height; //0x0074
|
||||
int16_t depth; //0x0076
|
||||
|
||||
uint32_t samplers; //0x0078
|
||||
|
||||
char padding_7C[4]; //0x007C
|
||||
|
||||
uint32_t unk_80;
|
||||
uint32_t unk_84;
|
||||
|
||||
uint64_t flags; // 0x0088
|
||||
|
||||
MaterialDXState_t dxStates[2];
|
||||
|
||||
uint16_t numAnimationFrames; // used in CMaterialGlue::GetNumAnimationFrames (0x1403B4250), which is called from GetSpriteInfo @ 0x1402561FC
|
||||
uint8_t materialType;
|
||||
uint8_t bytef3;
|
||||
|
||||
char padding_F4[4];
|
||||
|
||||
void* textureAnim;
|
||||
void** dxBuffer;
|
||||
void** unkD3DPointer; // was m_pID3D11BufferVTable
|
||||
void* viewsBuffer;
|
||||
|
||||
uint32_t unknown3; //0x0118
|
||||
uint16_t unknown4; //0x011C
|
||||
uint16_t unknown5; //0x011E
|
||||
uint16_t unknown6; //0x0120
|
||||
uint64_t unknown7; //0x0122
|
||||
uint32_t unknown8; //0x012A
|
||||
uint16_t unknown9; //0x012E
|
||||
}; //Size: 0x0130 confirmed end size.
|
||||
|
||||
static_assert(sizeof(CMaterialGlue) == 0x130);
|
||||
#pragma pack(pop)
|
||||
#endif // !DEDICATED
|
||||
|
||||
inline void* g_pMaterialGlueVFTable = nullptr;
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "windows/id3dx.h"
|
||||
#include "gameui/imgui_system.h"
|
||||
#include "materialsystem/cmaterialglue.h"
|
||||
#include "materialsystem/texturestreaming.h"
|
||||
#endif // !MATERIALSYSTEM_NODX
|
||||
#include "materialsystem/cmaterialsystem.h"
|
||||
|
||||
@ -46,10 +47,10 @@ static bool s_useLowLatency = false;
|
||||
InitReturnVal_t CMaterialSystem::Init(CMaterialSystem* thisptr)
|
||||
{
|
||||
#ifdef MATERIALSYSTEM_NODX
|
||||
// Only load the 'startup.rpak' file, as 'common_early.rpak' has assets
|
||||
// Only load the startup pak files, as 'common_early.rpak' has assets
|
||||
// that references assets in 'startup.rpak'.
|
||||
const PakHandle_t pakHandle = g_pakLoadApi->LoadAsync("startup.rpak", AlignedMemAlloc(), 5, 0);
|
||||
g_pakLoadApi->WaitForAsyncLoad(pakHandle, nullptr);
|
||||
g_pakLoadApi->LoadAsyncAndWait("startup.rpak", AlignedMemAlloc(), 5, 0);
|
||||
g_pakLoadApi->LoadAsyncAndWait("startup_sdk.rpak", AlignedMemAlloc(), 5, 0);
|
||||
|
||||
// Trick: return INIT_FAILED to disable the loading of hardware
|
||||
// configuration data, since we don't need it on the dedi.
|
||||
@ -70,7 +71,14 @@ InitReturnVal_t CMaterialSystem::Init(CMaterialSystem* thisptr)
|
||||
g_PCLStatsAvailable = true;
|
||||
}
|
||||
|
||||
return CMaterialSystem__Init(thisptr);
|
||||
const InitReturnVal_t result = CMaterialSystem__Init(thisptr);
|
||||
|
||||
// Must be loaded after the call to CMaterialSystem::Init() as we want
|
||||
// to load startup_sdk.rpak after startup.rpak. This pak file can be
|
||||
// used to load paks as early as startup.rpak, while still offering the
|
||||
// ability to patch/update its containing assets on time.
|
||||
g_pakLoadApi->LoadAsyncAndWait("startup_sdk.rpak", AlignedMemAlloc(), 5, 0);
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -94,33 +102,6 @@ int CMaterialSystem::Shutdown(CMaterialSystem* thisptr)
|
||||
}
|
||||
|
||||
#ifndef MATERIALSYSTEM_NODX
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: loads and processes STBSP files
|
||||
// (overrides level name if stbsp field has value in prerequisites file)
|
||||
// Input : *pszLevelName -
|
||||
//---------------------------------------------------------------------------------
|
||||
void StreamDB_Init(const char* pszLevelName)
|
||||
{
|
||||
KeyValues* pSettingsKV = Mod_GetLevelSettings(pszLevelName);
|
||||
|
||||
if (pSettingsKV)
|
||||
{
|
||||
KeyValues* pStreamKV = pSettingsKV->FindKey("StreamDB");
|
||||
|
||||
if (pStreamKV)
|
||||
{
|
||||
const char* pszColumnName = pStreamKV->GetString();
|
||||
Msg(eDLL_T::MS, "StreamDB_Init: Loading override STBSP file '%s.stbsp'\n", pszColumnName);
|
||||
|
||||
v_StreamDB_Init(pszColumnName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Msg(eDLL_T::MS, "StreamDB_Init: Loading STBSP file '%s.stbsp'\n", pszLevelName);
|
||||
v_StreamDB_Init(pszLevelName);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: draw frame
|
||||
//---------------------------------------------------------------------------------
|
||||
@ -200,6 +181,57 @@ Vector2D CMaterialSystem::GetScreenSize(CMaterialSystem* pMatSys)
|
||||
|
||||
return vecScreenSize;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: same as StreamDB_CreditWorldTextures, but also takes the coverage
|
||||
// of the dynamic model into account.
|
||||
// Input : *pMatSys -
|
||||
// *materialGlue -
|
||||
// a3 -
|
||||
// a4 -
|
||||
// a5 -
|
||||
// *pViewOrigin -
|
||||
// tanOfHalfFov -
|
||||
// viewWidthPixels -
|
||||
// a9 -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMaterialSystem::CreditModelTextures(CMaterialSystem* const pMatSys, CMaterialGlue* const materialGlue, __int64 a3, __int64 a4, unsigned int a5, const Vector3D* const pViewOrigin, const float tanOfHalfFov, const float viewWidthPixels, int a9)
|
||||
{
|
||||
if (!materialGlue->CanCreditModelTextures())
|
||||
return;
|
||||
|
||||
// If we use the GPU driven texture streaming system, do not run this code
|
||||
// as the compute shaders deals with both static and dynamic model textures.
|
||||
if (gpu_driven_tex_stream->GetBool())
|
||||
return;
|
||||
|
||||
MaterialGlue_s* const material = materialGlue->Get();
|
||||
material->lastFrame = s_textureStreamMgr->thisFrame;
|
||||
|
||||
v_StreamDB_CreditModelTextures(material->streamingTextureHandles, material->streamingTextureHandleCount, a3, a4, a5, pViewOrigin, tanOfHalfFov, viewWidthPixels, a9);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: updates the stream camera used for getting the column from the STBSP
|
||||
// Input : *pMatSys -
|
||||
// *camPos -
|
||||
// *camAng -
|
||||
// halfFovX -
|
||||
// viewWidth -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMaterialSystem::UpdateStreamCamera(CMaterialSystem* const pMatSys, const Vector3D* const camPos,
|
||||
const QAngle* const camAng, const float halfFovX, const float viewWidth)
|
||||
{
|
||||
// The stream camera is only used for the STBSP. If we use the GPU feedback
|
||||
// driven texture streaming system instead, do not run this code.
|
||||
if (gpu_driven_tex_stream->GetBool())
|
||||
return;
|
||||
|
||||
// NOTE: 'camAng' is set and provided to the function below, but the actual
|
||||
// function that updates the global state (StreamDB_SetCameraPosition)
|
||||
// isn't using it. The parameter is unused.
|
||||
CMaterialSystem__UpdateStreamCamera(pMatSys, camPos, camAng, halfFovX, viewWidth);
|
||||
}
|
||||
#endif // !MATERIALSYSTEM_NODX
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -215,7 +247,9 @@ void VMaterialSystem::Detour(const bool bAttach) const
|
||||
DetourSetup(&CMaterialSystem__SwapBuffers, &CMaterialSystem::SwapBuffers, bAttach);
|
||||
DetourSetup(&CMaterialSystem__FindMaterialEx, &CMaterialSystem::FindMaterialEx, bAttach);
|
||||
|
||||
DetourSetup(&v_StreamDB_Init, &StreamDB_Init, bAttach);
|
||||
DetourSetup(&CMaterialSystem__CreditModelTextures, &CMaterialSystem::CreditModelTextures, bAttach);
|
||||
DetourSetup(&CMaterialSystem__UpdateStreamCamera, &CMaterialSystem::UpdateStreamCamera, bAttach);
|
||||
|
||||
DetourSetup(&v_DispatchDrawCall, &DispatchDrawCall, bAttach);
|
||||
DetourSetup(&v_SpinPresent, &SpinPresent, bAttach);
|
||||
#endif // !MATERIALSYSTEM_NODX
|
||||
|
@ -3,8 +3,6 @@
|
||||
#include "cmaterialglue.h"
|
||||
#include "public/imaterialsystem.h"
|
||||
|
||||
#define STREAM_DB_EXT "stbsp"
|
||||
|
||||
class CMaterialSystem
|
||||
{
|
||||
public:
|
||||
@ -17,6 +15,9 @@ public:
|
||||
static void* SwapBuffers(CMaterialSystem* pMatSys);
|
||||
static CMaterialGlue* FindMaterialEx(CMaterialSystem* pMatSys, const char* pMaterialName, uint8_t nMaterialType, int nUnk, bool bComplain);
|
||||
static Vector2D GetScreenSize(CMaterialSystem* pMatSys = nullptr);
|
||||
|
||||
static void CreditModelTextures(CMaterialSystem* const pMatSys, CMaterialGlue* const materialGlue, __int64 a3, __int64 a4, unsigned int a5, const Vector3D* const pViewOrigin, const float tanOfHalfFov, const float viewWidthPixels, int a9);
|
||||
static void UpdateStreamCamera(CMaterialSystem* const pMatSys, const Vector3D* const camPos, const QAngle* const camAng, const float halfFovX, const float viewWidth);
|
||||
#endif // !MATERIALSYSTEM_NODX
|
||||
|
||||
// TODO: reverse the vftable!
|
||||
@ -75,20 +76,15 @@ inline void*(*CMaterialSystem__SwapBuffers)(CMaterialSystem* pMatSys);
|
||||
inline CMaterialGlue*(*CMaterialSystem__FindMaterialEx)(CMaterialSystem* pMatSys, const char* pMaterialName, uint8_t nMaterialType, int nUnk, bool bComplain);
|
||||
inline void(*CMaterialSystem__GetScreenSize)(CMaterialSystem* pMatSys, float* outX, float* outY);
|
||||
|
||||
inline void(*CMaterialSystem__CreditModelTextures)(CMaterialSystem* const pMatSys, CMaterialGlue* const materialGlue, __int64 a3, __int64 a4, unsigned int a5, const Vector3D* const pViewOrigin, const float tanOfHalfFov, const float viewWidthPixels, int a9);
|
||||
inline void(*CMaterialSystem__UpdateStreamCamera)(CMaterialSystem* const pMatSys, const Vector3D* const camPos, const QAngle* const camAng, const float halfFovX, const float viewWidth);
|
||||
|
||||
inline void*(*v_DispatchDrawCall)(int64_t a1, uint64_t a2, int a3, int a4, int64_t a5, int a6, uint8_t a7, int64_t a8, uint32_t a9, uint32_t a10, int a11, __m128* a12, int a13, int64_t a14);
|
||||
inline ssize_t(*v_SpinPresent)(void);
|
||||
inline void(*CMaterialSystem__GetStreamOverlay)(const char* mode, char* buf, size_t bufSize);
|
||||
inline const char*(*CMaterialSystem__DrawStreamOverlay)(void* thisptr, uint8_t* a2, void* unused, void* a4);
|
||||
#endif // !MATERIALSYSTEM_NODX
|
||||
|
||||
inline void(*v_StreamDB_Init)(const char* const pszLevelName);
|
||||
|
||||
#ifndef MATERIALSYSTEM_NODX
|
||||
inline void** s_pRenderContext; // NOTE: This is some CMaterial instance or array.
|
||||
|
||||
inline ssize_t* g_nTotalStreamingTextureMemory = nullptr;
|
||||
inline ssize_t* g_nUnfreeStreamingTextureMemory = nullptr;
|
||||
inline ssize_t* g_nUnusableStreamingTextureMemory = nullptr;
|
||||
#endif // !MATERIALSYSTEM_NODX
|
||||
|
||||
// TODO: move to materialsystem_global.h!
|
||||
@ -112,17 +108,13 @@ class VMaterialSystem : public IDetour
|
||||
LogFunAdr("CMaterialSystem::SwapBuffers", CMaterialSystem__SwapBuffers);
|
||||
LogFunAdr("CMaterialSystem::FindMaterialEx", CMaterialSystem__FindMaterialEx);
|
||||
LogFunAdr("CMaterialSystem::GetScreenSize", CMaterialSystem__GetScreenSize);
|
||||
LogFunAdr("CMaterialSystem::GetStreamOverlay", CMaterialSystem__GetStreamOverlay);
|
||||
LogFunAdr("CMaterialSystem::DrawStreamOverlay", CMaterialSystem__DrawStreamOverlay);
|
||||
LogFunAdr("CMaterialSystem::CreditModelTextures", CMaterialSystem__CreditModelTextures);
|
||||
LogFunAdr("CMaterialSystem::UpdateStreamCamera", CMaterialSystem__UpdateStreamCamera);
|
||||
LogFunAdr("DispatchDrawCall", v_DispatchDrawCall);
|
||||
LogFunAdr("SpinPresent", v_SpinPresent);
|
||||
#endif // !MATERIALSYSTEM_NODX
|
||||
LogFunAdr("StreamDB_Init", v_StreamDB_Init);
|
||||
|
||||
#ifndef MATERIALSYSTEM_NODX
|
||||
LogVarAdr("g_nTotalStreamingTextureMemory", g_nTotalStreamingTextureMemory);
|
||||
LogVarAdr("g_nUnfreeStreamingTextureMemory", g_nUnfreeStreamingTextureMemory);
|
||||
LogVarAdr("g_nUnusableStreamingTextureMemory", g_nUnusableStreamingTextureMemory);
|
||||
LogVarAdr("s_pRenderContext", s_pRenderContext);
|
||||
LogVarAdr("g_MaterialAdapterMgr", g_pMaterialAdapterMgr);
|
||||
#endif // !MATERIALSYSTEM_NODX
|
||||
@ -140,22 +132,17 @@ class VMaterialSystem : public IDetour
|
||||
|
||||
g_GameDll.FindPatternSIMD("44 89 4C 24 ?? 44 88 44 24 ?? 48 89 4C 24 ??").GetPtr(CMaterialSystem__FindMaterialEx);
|
||||
g_GameDll.FindPatternSIMD("8B 05 ?? ?? ?? ?? 89 02 8B 05 ?? ?? ?? ?? 41 89 ?? C3 CC CC CC CC CC CC CC CC CC CC CC CC CC CC 8B 05 ?? ?? ?? ??").GetPtr(CMaterialSystem__GetScreenSize);
|
||||
g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 80 7C 24 ?? ?? 0F 84 ?? ?? ?? ?? 48 89 9C 24 ?? ?? ?? ??").FollowNearCallSelf().GetPtr(CMaterialSystem__GetStreamOverlay);
|
||||
g_GameDll.FindPatternSIMD("41 56 B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 C6 02 ??").GetPtr(CMaterialSystem__DrawStreamOverlay);
|
||||
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC ?? 48 8B 02 48 8B CA 49 8B F9").GetPtr(CMaterialSystem__CreditModelTextures);
|
||||
g_GameDll.FindPatternSIMD("48 83 EC ?? 48 8B 05 ?? ?? ?? ?? 44 0F 29 44 24").GetPtr(CMaterialSystem__UpdateStreamCamera);
|
||||
|
||||
g_GameDll.FindPatternSIMD("44 89 4C 24 ?? 44 89 44 24 ?? 48 89 4C 24 ?? 55 53 56").GetPtr(v_DispatchDrawCall);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 8B 15 ?? ?? ?? ??").GetPtr(v_SpinPresent);
|
||||
#endif // !MATERIALSYSTEM_NODX
|
||||
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 54 41 56 41 57 48 83 EC 40 48 8B E9").GetPtr(v_StreamDB_Init);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
#ifndef MATERIALSYSTEM_NODX
|
||||
CMemory(CMaterialSystem__DrawStreamOverlay).Offset(0x1C).FindPatternSelf("48 8B 05", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).GetPtr(g_nTotalStreamingTextureMemory);
|
||||
CMemory(CMaterialSystem__DrawStreamOverlay).Offset(0x2D).FindPatternSelf("48 8B 05", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).GetPtr(g_nUnfreeStreamingTextureMemory);
|
||||
CMemory(CMaterialSystem__DrawStreamOverlay).Offset(0x50).FindPatternSelf("48 8B 05", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).GetPtr(g_nUnusableStreamingTextureMemory);
|
||||
|
||||
CMemory(v_DispatchDrawCall).FindPattern("48 8B ?? ?? ?? ?? 01").ResolveRelativeAddressSelf(0x3, 0x7).GetPtr(s_pRenderContext);
|
||||
CMemory(CMaterialSystem__Disconnect).FindPattern("48 8D").ResolveRelativeAddressSelf(0x3, 0x7).GetPtr(g_pMaterialAdapterMgr);
|
||||
#endif // !MATERIALSYSTEM_NODX
|
||||
|
69
src/materialsystem/texturestreaming.cpp
Normal file
69
src/materialsystem/texturestreaming.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "engine/cmodel_bsp.h"
|
||||
#include "materialsystem/texturestreaming.h"
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: loads and processes STBSP files
|
||||
// (overrides level name if stbsp field has value in prerequisites file)
|
||||
// Input : *pszLevelName -
|
||||
//---------------------------------------------------------------------------------
|
||||
static void StreamDB_Init(const char* const pszLevelName)
|
||||
{
|
||||
KeyValues* const pSettingsKV = Mod_GetLevelSettings(pszLevelName);
|
||||
const char* targetStreamDB = pszLevelName;
|
||||
|
||||
if (pSettingsKV)
|
||||
{
|
||||
KeyValues* const pStreamKV = pSettingsKV->FindKey("StreamDB");
|
||||
|
||||
if (pStreamKV)
|
||||
targetStreamDB = pStreamKV->GetString();
|
||||
}
|
||||
|
||||
v_StreamDB_Init(targetStreamDB);
|
||||
|
||||
// If the requested STBSP file doesn't exist, then enable the GPU driven
|
||||
// texture streaming system.
|
||||
const bool gpuDriven = s_textureStreamMgr->fileHandle == FS_ASYNC_FILE_INVALID;
|
||||
gpu_driven_tex_stream->SetValue(gpuDriven);
|
||||
|
||||
if (!gpuDriven)
|
||||
Msg(eDLL_T::MS, "StreamDB_Init: Loaded STBSP file '%s.stbsp'\n", targetStreamDB);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: shift and scale the texture's histogram to accommodate varying screen
|
||||
// FOV, screen resolutions and texture resolutions.
|
||||
// Input : *taskList -
|
||||
//---------------------------------------------------------------------------------
|
||||
static void StreamDB_CreditWorldTextures(TextureStreamMgr_TaskList_s* const taskList)
|
||||
{
|
||||
// If we use the GPU driven texture streaming system, do not credit the textures
|
||||
// based on the STBSP pages.
|
||||
if (gpu_driven_tex_stream->GetBool())
|
||||
return;
|
||||
|
||||
v_StreamDB_CreditWorldTextures(taskList);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: same as above, except for older (legacy) STBSP's (v8.0).
|
||||
// Input : *taskList -
|
||||
//---------------------------------------------------------------------------------
|
||||
static void StreamDB_CreditWorldTextures_Legacy(TextureStreamMgr_TaskList_s* const taskList)
|
||||
{
|
||||
// If we use the GPU driven texture streaming system, do not credit the textures
|
||||
// based on the STBSP pages.
|
||||
if (gpu_driven_tex_stream->GetBool())
|
||||
return;
|
||||
|
||||
v_StreamDB_CreditWorldTextures_Legacy(taskList);
|
||||
}
|
||||
|
||||
void VTextureStreaming::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourSetup(&v_StreamDB_Init, &StreamDB_Init, bAttach);
|
||||
|
||||
DetourSetup(&v_StreamDB_CreditWorldTextures, &StreamDB_CreditWorldTextures, bAttach);
|
||||
DetourSetup(&v_StreamDB_CreditWorldTextures_Legacy, &StreamDB_CreditWorldTextures_Legacy, bAttach);
|
||||
}
|
178
src/materialsystem/texturestreaming.h
Normal file
178
src/materialsystem/texturestreaming.h
Normal file
@ -0,0 +1,178 @@
|
||||
//=============================================================================//
|
||||
//
|
||||
// Purpose: texture streaming and runtime management
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// Some of these structs are based on the presentation held by the developer of
|
||||
// the texture streaming system in Titanfall 2 and Apex Legends, see the links:
|
||||
// - https://www.gdcvault.com/play/1024418/Efficient-Texture-Streaming-in-Titanfall
|
||||
// - https://www.youtube.com/watch?v=q0aKNGH8WbA
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TEXTURESTREAMING_H
|
||||
#define TEXTURESTREAMING_H
|
||||
#include "public/rtech/istreamdb.h"
|
||||
|
||||
struct MaterialGlue_s;
|
||||
struct TextureAsset_s;
|
||||
|
||||
struct TextureStreamMgr_Task_s
|
||||
{
|
||||
TextureAsset_s* textureAsset;
|
||||
|
||||
// The mip level count to load or drop.
|
||||
uint8 mipLevelCount;
|
||||
char padding[3];
|
||||
|
||||
// The 'cost vs benefit' metric used to partially sort the task list to get
|
||||
// the best and worst 16 textures.
|
||||
float metric;
|
||||
};
|
||||
|
||||
struct TextureStreamMgr_TaskList_s
|
||||
{
|
||||
// STBSP async file handle and index to the current page.
|
||||
int fileHandle;
|
||||
int pageIndex;
|
||||
|
||||
// Whether we should update the current page state.
|
||||
bool updatePageState;
|
||||
int padding;
|
||||
|
||||
// Offset to the page in the STBSP to read up to size bytes.
|
||||
uint64 pageOffset;
|
||||
uint64 pageSize;
|
||||
|
||||
// - loadBegin points to the first texture load task.
|
||||
// - loadEnd points to the last texture load task.
|
||||
// - loadLimit points to the absolute end of the load task buffer.
|
||||
TextureStreamMgr_Task_s* loadBegin;
|
||||
TextureStreamMgr_Task_s* loadEnd;
|
||||
TextureStreamMgr_Task_s* loadLimit;
|
||||
|
||||
// - dropBegin points to the first texture drop task.
|
||||
// - dropEnd points to the last texture drop task.
|
||||
// - dropLimit points to the absolute end of the drop task buffer.
|
||||
TextureStreamMgr_Task_s* dropBegin;
|
||||
TextureStreamMgr_Task_s* dropEnd;
|
||||
TextureStreamMgr_Task_s* dropLimit;
|
||||
};
|
||||
|
||||
enum TextureStreamMode_e : uint8
|
||||
{
|
||||
TSM_OPMODE_LEGACY_PICMIP = 0,
|
||||
TSM_OPMODE_DYNAMIC,
|
||||
TSM_OPMODE_ALL,
|
||||
TSM_OPMODE_NONE,
|
||||
TSM_OPMODE_PAUSED,
|
||||
};
|
||||
|
||||
struct TextureStreamMgr_s
|
||||
{
|
||||
bool initialised;
|
||||
bool hasResidentPages;
|
||||
char filePath[260]; // size=MAX_PATH.
|
||||
char gap_105[2];
|
||||
int fileHandle; // STBSP file handle.
|
||||
char gap_10b[4];
|
||||
char* stringBuffer;
|
||||
StreamDB_Header_s header;
|
||||
StreamDB_ResidentPage_s* residentPages;
|
||||
MaterialGlue_s** materials;
|
||||
StreamDB_Material_s* materialInfo;
|
||||
int64 maxResidentPageSize;
|
||||
StreamDB_PageState_s pageStates[4];
|
||||
bool unk_320;
|
||||
char gap_321[3];
|
||||
TextureStreamMode_e texStreamMode;
|
||||
int picMip;
|
||||
float streamBspBucketBias;
|
||||
float streamBspDistScale;
|
||||
uint64 highPriorityMemoryBudget;
|
||||
uint32 streamBspCellX;
|
||||
uint32 streamBspCellY;
|
||||
int loadedLinkedTextureCount;
|
||||
int totalMipLevelCount;
|
||||
int loadedMipLevelCount;
|
||||
int unk_34;
|
||||
int64 usedStreamingMemory;
|
||||
int64 totalStreamingMemory;
|
||||
int thisFrame;
|
||||
int unk_50;
|
||||
Vector3D streamBspCameraPos;
|
||||
float streamBspHalfFovX;
|
||||
float streamBspViewWidth;
|
||||
TextureAsset_s* streamableTextures[4];
|
||||
};
|
||||
|
||||
enum TextureStreamMemory_e
|
||||
{
|
||||
TML_TRACKER_UNFREE,
|
||||
|
||||
TML_TRACKER_UNKNOWN_1, // Appears unused by the retail runtime.
|
||||
TML_TRACKER_UNKNOWN_2, // Appears unused by the retail runtime.
|
||||
|
||||
TML_TRACKER_UNUSABE,
|
||||
|
||||
// Not a memory tracker!
|
||||
STREAMING_TEXTURES_MEMORY_LATENCY_FRAME_COUNT,
|
||||
};
|
||||
|
||||
inline void(*v_StreamDB_Init)(const char* const pszLevelName);
|
||||
inline void(*v_StreamDB_CreditWorldTextures)(TextureStreamMgr_TaskList_s* const taskList);
|
||||
inline void(*v_StreamDB_CreditWorldTextures_Legacy)(TextureStreamMgr_TaskList_s* const taskList);
|
||||
inline void(*v_StreamDB_CreditModelTextures)(TextureAsset_s** const textureAssets, const int textureCount, __int64 a3, __int64 a4, unsigned int a5, const Vector3D* const pViewOrigin, const float tanOfHalfFov, const float viewWidthPixels, int a9);
|
||||
|
||||
inline void(*TextureStreamMgr_GetStreamOverlay)(const char* const mode, char* const buf, const size_t bufSize);
|
||||
inline const char* (*TextureStreamMgr_DrawStreamOverlayToInterface)(void* thisptr, uint8_t* a2, void* unused, void* debugOverlayIface);
|
||||
|
||||
inline ssize_t* g_textureStreamMemoryUsed = nullptr; // array size = STREAMING_TEXTURES_MEMORY_LATENCY_FRAME_COUNT.
|
||||
inline ssize_t* g_textureStreamMemoryTarget = nullptr; // pointer to single size var.
|
||||
|
||||
inline TextureStreamMgr_s* s_textureStreamMgr;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VTextureStreaming : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("StreamDB_Init", v_StreamDB_Init);
|
||||
LogFunAdr("StreamDB_CreditWorldTextures", v_StreamDB_CreditWorldTextures);
|
||||
LogFunAdr("StreamDB_CreditWorldTextures_Legacy", v_StreamDB_CreditWorldTextures_Legacy);
|
||||
|
||||
LogFunAdr("StreamDB_CreditModelTextures", v_StreamDB_CreditModelTextures);
|
||||
|
||||
LogFunAdr("TextureStreamMgr_GetStreamOverlay", TextureStreamMgr_GetStreamOverlay);
|
||||
LogFunAdr("TextureStreamMgr_DrawStreamOverlayToInterface", TextureStreamMgr_DrawStreamOverlayToInterface);
|
||||
|
||||
LogVarAdr("g_textureStreamMemoryUsed", g_textureStreamMemoryUsed);
|
||||
LogVarAdr("g_textureStreamMemoryTarget", g_textureStreamMemoryTarget);
|
||||
|
||||
LogVarAdr("s_textureStreamMgr", s_textureStreamMgr);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 54 41 56 41 57 48 83 EC 40 48 8B E9").GetPtr(v_StreamDB_Init);
|
||||
|
||||
g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? EB ?? 48 8B CF E8 ?? ?? ?? ?? 4C 8D 25").FollowNearCallSelf().GetPtr(v_StreamDB_CreditWorldTextures);
|
||||
g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 4C 8D 25 ?? ?? ?? ?? 4C 89 64 24").FollowNearCallSelf().GetPtr(v_StreamDB_CreditWorldTextures_Legacy);
|
||||
|
||||
g_GameDll.FindPatternSIMD("4C 89 44 24 ?? 89 54 24 ?? 48 89 4C 24 ?? 55 56").GetPtr(v_StreamDB_CreditModelTextures);
|
||||
|
||||
g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 80 7C 24 ?? ?? 0F 84 ?? ?? ?? ?? 48 89 9C 24 ?? ?? ?? ??").FollowNearCallSelf().GetPtr(TextureStreamMgr_GetStreamOverlay);
|
||||
g_GameDll.FindPatternSIMD("41 56 B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 C6 02 ??").GetPtr(TextureStreamMgr_DrawStreamOverlayToInterface);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
CMemory(TextureStreamMgr_DrawStreamOverlayToInterface).Offset(0x2D).FindPatternSelf("48 8B 05", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).GetPtr(g_textureStreamMemoryUsed);
|
||||
CMemory(TextureStreamMgr_DrawStreamOverlayToInterface).Offset(0x1C).FindPatternSelf("48 8B 05", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).GetPtr(g_textureStreamMemoryTarget);
|
||||
|
||||
CMemory(v_StreamDB_Init).FindPattern("C6 05").ResolveRelativeAddressSelf(0x2, 0x7).GetPtr(s_textureStreamMgr);
|
||||
}
|
||||
virtual void GetCon(void) const
|
||||
{ }
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // TEXTURESTREAMING_H
|
@ -35,7 +35,7 @@ void scanDirectoryAppend(const string& path, const string& ext, vector<string>&
|
||||
|
||||
do
|
||||
{
|
||||
filelist.push_back(dir.name);
|
||||
filelist.emplace_back(dir.name);
|
||||
}
|
||||
while (_findnext(fh, &dir) == 0);
|
||||
_findclose(fh);
|
||||
@ -53,7 +53,7 @@ void scanDirectoryAppend(const string& path, const string& ext, vector<string>&
|
||||
int len = strlen(current->d_name);
|
||||
if (len > extLen && strncmp(current->d_name + len - extLen, ext.c_str(), extLen) == 0)
|
||||
{
|
||||
filelist.push_back(current->d_name);
|
||||
filelist.emplace_back(current->d_name);
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
|
@ -277,7 +277,7 @@ bool sdl_init(SDL_Window*& window, SDL_Renderer*& renderer, int &width, int &hei
|
||||
SDL_DisplayMode displayMode;
|
||||
SDL_GetCurrentDisplayMode(0, &displayMode);
|
||||
|
||||
Uint32 flags = SDL_WINDOW_OPENGL | SDL_RENDERER_PRESENTVSYNC;
|
||||
Uint32 flags = SDL_WINDOW_OPENGL | SDL_RENDERER_PRESENTVSYNC | SDL_WINDOW_RESIZABLE;
|
||||
if (presentationMode)
|
||||
{
|
||||
// Create a fullscreen window at the native resolution.
|
||||
@ -752,6 +752,24 @@ int not_main(int argc, char** argv)
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
{
|
||||
if (event.window.event == SDL_WINDOWEVENT_RESIZED)
|
||||
{
|
||||
// Get the new window size
|
||||
width = event.window.data1;
|
||||
height = event.window.data2;
|
||||
|
||||
// Update OpenGL viewport
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(50.0f, (float)width / (float)height, 1.0f, camr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_QUIT:
|
||||
done = true;
|
||||
break;
|
||||
|
@ -24,6 +24,10 @@ add_sources( SOURCE_GROUP "Engine"
|
||||
"${ENGINE_SOURCE_DIR}/engine/shared/shared_rcon.h"
|
||||
)
|
||||
|
||||
add_sources( SOURCE_GROUP "Public"
|
||||
"${ENGINE_SOURCE_DIR}/public/netcon/INetCon.h"
|
||||
)
|
||||
|
||||
add_sources( SOURCE_GROUP "Windows"
|
||||
"${ENGINE_SOURCE_DIR}/windows/console.cpp"
|
||||
"${ENGINE_SOURCE_DIR}/windows/console.h"
|
||||
|
@ -172,8 +172,10 @@ BOOL WINAPI CNetCon::CloseHandler(DWORD eventCode)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNetCon::TermSetup(const bool bAnsiColor)
|
||||
{
|
||||
if (bAnsiColor)
|
||||
Console_ColorInit();
|
||||
|
||||
SpdLog_Init(bAnsiColor);
|
||||
Console_Init(bAnsiColor);
|
||||
|
||||
// Handle ctrl+x or X close events, give the application time to shutdown
|
||||
// properly and flush all logging buffers.
|
||||
@ -193,7 +195,7 @@ void CNetCon::TrySetKey(const char* const pKey)
|
||||
if (!*pKey)
|
||||
{
|
||||
Warning(eDLL_T::CLIENT, "No key provided; using default %s'%s%s%s'\n",
|
||||
g_svReset, g_svGreyB, DEFAULT_NET_ENCRYPTION_KEY, g_svReset);
|
||||
g_svReset.c_str(), g_svGreyB.c_str(), DEFAULT_NET_ENCRYPTION_KEY, g_svReset.c_str());
|
||||
|
||||
SetKey(DEFAULT_NET_ENCRYPTION_KEY, true);
|
||||
}
|
||||
@ -233,7 +235,7 @@ void CNetCon::RunInput(const string& lineInput)
|
||||
return;
|
||||
}
|
||||
|
||||
vector<char> vecMsg;
|
||||
vector<byte> vecMsg;
|
||||
|
||||
const SocketHandle_t hSocket = GetSocket();
|
||||
bool bSend = false;
|
||||
@ -242,18 +244,27 @@ void CNetCon::RunInput(const string& lineInput)
|
||||
{
|
||||
if (V_strcmp(cmd.Arg(0), "PASS") == 0) // Auth with RCON server.
|
||||
{
|
||||
bSend = Serialize(vecMsg, cmd.Arg(1), "",
|
||||
const char* const pass = cmd.Arg(1);
|
||||
const size_t passLen = strlen(pass);
|
||||
|
||||
bSend = Serialize(vecMsg, pass, passLen, "", 0,
|
||||
netcon::request_e::SERVERDATA_REQUEST_AUTH);
|
||||
}
|
||||
else // Execute command query.
|
||||
{
|
||||
bSend = Serialize(vecMsg, cmd.Arg(0), cmd.GetCommandString(),
|
||||
const char* const request = cmd.Arg(0);
|
||||
const size_t requestLen = strlen(request);
|
||||
|
||||
const char* const command = cmd.GetCommandString();
|
||||
const size_t commandLen = strlen(command);
|
||||
|
||||
bSend = Serialize(vecMsg, request, requestLen, command, commandLen,
|
||||
netcon::request_e::SERVERDATA_REQUEST_EXECCOMMAND);
|
||||
}
|
||||
}
|
||||
else // Single arg command query.
|
||||
{
|
||||
bSend = Serialize(vecMsg, lineInput.c_str(), "", netcon::request_e::SERVERDATA_REQUEST_EXECCOMMAND);
|
||||
bSend = Serialize(vecMsg, lineInput.c_str(), lineInput.length(), "", 0, netcon::request_e::SERVERDATA_REQUEST_EXECCOMMAND);
|
||||
}
|
||||
|
||||
if (bSend) // Only send if serialization process was successful.
|
||||
@ -315,7 +326,7 @@ bool CNetCon::RunFrame(void)
|
||||
|
||||
if (IsConnected())
|
||||
{
|
||||
CConnectedNetConsoleData& pData = GetSocketCreator()->GetAcceptedSocketData(0);
|
||||
ConnectedNetConsoleData_s& pData = GetSocketCreator()->GetAcceptedSocketData(0);
|
||||
Recv(pData);
|
||||
}
|
||||
else if (GetPrompting())
|
||||
@ -377,7 +388,7 @@ bool CNetCon::Connect(const char* pHostName, const int nPort)
|
||||
if (m_bEncryptFrames)
|
||||
{
|
||||
Msg(eDLL_T::CLIENT, "Attempting connection to '%s' with key %s'%s%s%s'\n",
|
||||
pHostName, g_svReset, g_svGreyB, GetKey(), g_svReset);
|
||||
pHostName, g_svReset.c_str(), g_svGreyB.c_str(), GetKey(), g_svReset.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -413,7 +424,7 @@ void CNetCon::Disconnect(const char* szReason)
|
||||
// nMsgLen -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetCon::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
|
||||
bool CNetCon::ProcessMessage(const byte* pMsgBuf, const u32 nMsgLen)
|
||||
{
|
||||
netcon::response response;
|
||||
|
||||
@ -432,10 +443,10 @@ bool CNetCon::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
|
||||
const long i = strtol(response.responseval().c_str(), NULL, NULL);
|
||||
if (!i) // Means we are marked 'input only' on the rcon server.
|
||||
{
|
||||
vector<char> vecMsg;
|
||||
bool ret = Serialize(vecMsg, "", "1", netcon::request_e::SERVERDATA_REQUEST_SEND_CONSOLE_LOG);
|
||||
vector<byte> vecMsg;
|
||||
const bool ret = Serialize(vecMsg, "", 0, "1", 1, netcon::request_e::SERVERDATA_REQUEST_SEND_CONSOLE_LOG);
|
||||
|
||||
if (ret && !Send(GetSocket(), vecMsg.data(), int(vecMsg.size())))
|
||||
if (ret && !Send(GetSocket(), vecMsg.data(), (u32)vecMsg.size()))
|
||||
{
|
||||
Error(eDLL_T::CLIENT, NO_ERROR, "Failed to send RCON message: (%s)\n", "SOCKET_ERROR");
|
||||
}
|
||||
@ -465,14 +476,16 @@ bool CNetCon::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
|
||||
// Purpose: serializes message to vector
|
||||
// Input : &vecBuf -
|
||||
// *szReqBuf -
|
||||
// nReqMsgLen -
|
||||
// *svReqVal -
|
||||
// nReqValLen -
|
||||
// requestType -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetCon::Serialize(vector<char>& vecBuf, const char* szReqBuf,
|
||||
const char* szReqVal, const netcon::request_e requestType) const
|
||||
bool CNetCon::Serialize(vector<byte>& vecBuf, const char* szReqBuf, const size_t nReqMsgLen,
|
||||
const char* szReqVal, const size_t nReqValLen, const netcon::request_e requestType) const
|
||||
{
|
||||
return NetconClient_Serialize(this, vecBuf, szReqBuf, szReqVal, requestType, m_bEncryptFrames, true);
|
||||
return NetconClient_Serialize(this, vecBuf, szReqBuf, nReqMsgLen, szReqVal, nReqValLen, requestType, m_bEncryptFrames, true);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -511,27 +524,23 @@ int main(int argc, char* argv[])
|
||||
|
||||
bool bEnableColor = false;
|
||||
|
||||
for (int i = 0; i < argc; i++)
|
||||
if (argc >= 2)
|
||||
{
|
||||
if (V_strcmp(argv[i], "-ansicolor") == NULL)
|
||||
{
|
||||
bEnableColor = true;
|
||||
break;
|
||||
}
|
||||
bEnableColor = V_strcmp(argv[1], "-ansicolor") == NULL;
|
||||
}
|
||||
|
||||
// The address and key from command line if passed in.
|
||||
const char* pAdr = nullptr;
|
||||
const char* pKey = nullptr;
|
||||
|
||||
if (argc >= 2)
|
||||
if (argc >= 2 + bEnableColor)
|
||||
{
|
||||
pAdr = argv[1];
|
||||
pAdr = argv[1 + bEnableColor];
|
||||
}
|
||||
|
||||
if (argc >= 3)
|
||||
if (argc >= 3 + bEnableColor)
|
||||
{
|
||||
pKey = argv[2];
|
||||
pKey = argv[2 + bEnableColor];
|
||||
}
|
||||
|
||||
if (!NetConsole()->Init(bEnableColor, pAdr, pKey))
|
||||
|
@ -35,11 +35,11 @@ public:
|
||||
virtual bool Connect(const char* pHostName, const int nHostPort = SOCKET_ERROR) override;
|
||||
virtual void Disconnect(const char* szReason = nullptr) override;
|
||||
|
||||
virtual bool ProcessMessage(const char* pMsgBuf, const int nMsgLen) override;
|
||||
virtual bool ProcessMessage(const byte* pMsgBuf, const u32 nMsgLen) override;
|
||||
|
||||
void TrySetKey(const char* const pKey);
|
||||
bool Serialize(vector<char>& vecBuf, const char* szReqBuf,
|
||||
const char* szReqVal, const netcon::request_e requestType) const;
|
||||
bool Serialize(vector<byte>& vecBuf, const char* szReqBuf, const size_t nReqMsgLen,
|
||||
const char* szReqVal, const size_t nReqValLen, const netcon::request_e requestType) const;
|
||||
|
||||
SocketHandle_t GetSocket(void);
|
||||
bool IsInitialized(void) const;
|
||||
|
@ -36,7 +36,7 @@ void CBanSystem::LoadList(void)
|
||||
pBuf[nRead] = '\0'; // Null terminate the string buffer containing our banned list.
|
||||
|
||||
rapidjson::Document document;
|
||||
if (document.Parse(pBuf.get()).HasParseError())
|
||||
if (document.Parse(pBuf.get(), nRead).HasParseError())
|
||||
{
|
||||
Warning(eDLL_T::SERVER, "%s: JSON parse error at position %zu: %s\n",
|
||||
__FUNCTION__, document.GetErrorOffset(), rapidjson::GetParseError_En(document.GetParseError()));
|
||||
@ -62,7 +62,7 @@ void CBanSystem::LoadList(void)
|
||||
|
||||
rapidjson::Value::ConstMemberIterator entryIt;
|
||||
|
||||
if (JSON_GetIterator(document, idx, JSONFieldType_e::kObject, entryIt))
|
||||
if (JSON_GetIterator(document, rapidjson::StringRef(idx, strlen(idx)), JSONFieldType_e::kObject, entryIt))
|
||||
{
|
||||
const rapidjson::Value& entry = entryIt->value;
|
||||
|
||||
@ -107,7 +107,7 @@ void CBanSystem::SaveList(void) const
|
||||
|
||||
rapidjson::Value obj(rapidjson::kObjectType);
|
||||
|
||||
obj.AddMember("ipAddress", rapidjson::Value(banned.m_Address.String(), allocator), allocator);
|
||||
obj.AddMember("ipAddress", rapidjson::Value(banned.m_Address.String(), banned.m_Address.Length(), allocator), allocator);
|
||||
obj.AddMember("nucleusId", banned.m_NucleusID, allocator);
|
||||
|
||||
document.AddMember(rapidjson::Value(idx, allocator), obj, allocator);
|
||||
@ -324,7 +324,7 @@ void CBanSystem::AuthorPlayerByName(const char* playerName, const bool shouldBan
|
||||
{
|
||||
if (strcmp(playerName, pNetChan->GetName()) == NULL) // Our wanted name?
|
||||
{
|
||||
if (shouldBan && AddEntry(pNetChan->GetAddress(), pClient->GetNucleusID()) && !bSave)
|
||||
if (shouldBan && AddEntry(pNetChan->GetAddress(true), pClient->GetNucleusID()) && !bSave)
|
||||
bSave = true;
|
||||
|
||||
pClient->Disconnect(REP_MARK_BAD, reason);
|
||||
@ -389,7 +389,7 @@ void CBanSystem::AuthorPlayerById(const char* playerHandle, const bool shouldBan
|
||||
continue;
|
||||
}
|
||||
|
||||
if (shouldBan && AddEntry(pNetChan->GetAddress(), pClient->GetNucleusID()) && !bSave)
|
||||
if (shouldBan && AddEntry(pNetChan->GetAddress(true), pClient->GetNucleusID()) && !bSave)
|
||||
bSave = true;
|
||||
|
||||
pClient->Disconnect(REP_MARK_BAD, reason);
|
||||
@ -397,10 +397,12 @@ void CBanSystem::AuthorPlayerById(const char* playerHandle, const bool shouldBan
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strcmp(playerHandle, pNetChan->GetAddress()) != NULL)
|
||||
const char* const chanAddr = pNetChan->GetAddress(true);
|
||||
|
||||
if (strcmp(playerHandle, chanAddr) != NULL)
|
||||
continue;
|
||||
|
||||
if (shouldBan && AddEntry(pNetChan->GetAddress(), pClient->GetNucleusID()) && !bSave)
|
||||
if (shouldBan && AddEntry(chanAddr, pClient->GetNucleusID()) && !bSave)
|
||||
bSave = true;
|
||||
|
||||
pClient->Disconnect(REP_MARK_BAD, reason);
|
||||
|
@ -48,7 +48,8 @@ static bool GetServerListingFromJSON(const rapidjson::Value& value, NetGameServe
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets a vector of hosted servers.
|
||||
// Input : &outMessage -
|
||||
// Input : &outServerList -
|
||||
// &outMessage -
|
||||
// Output : true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CPylon::GetServerList(vector<NetGameServer_t>& outServerList, string& outMessage) const
|
||||
@ -95,7 +96,7 @@ bool CPylon::GetServerList(vector<NetGameServer_t>& outServerList, string& outMe
|
||||
continue;
|
||||
}
|
||||
|
||||
outServerList.push_back(gameServer);
|
||||
outServerList.emplace_back(std::move(gameServer));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -121,8 +122,8 @@ bool CPylon::GetServerByToken(NetGameServer_t& outGameServer,
|
||||
requestJson.SetObject();
|
||||
|
||||
rapidjson::Document::AllocatorType& allocator = requestJson.GetAllocator();
|
||||
requestJson.AddMember("version", rapidjson::Value(SDK_VERSION, requestJson.GetAllocator()), allocator);
|
||||
requestJson.AddMember("token", rapidjson::Value(token.c_str(), requestJson.GetAllocator()), allocator);
|
||||
requestJson.AddMember("version", rapidjson::Value(SDK_VERSION, sizeof(SDK_VERSION)-1, requestJson.GetAllocator()), allocator);
|
||||
requestJson.AddMember("token", rapidjson::Value(token.c_str(), token.length(), requestJson.GetAllocator()), allocator);
|
||||
|
||||
rapidjson::Document responseJson;
|
||||
CURLINFO status;
|
||||
@ -156,6 +157,7 @@ bool CPylon::GetServerByToken(NetGameServer_t& outGameServer,
|
||||
// Purpose: Sends host server POST request.
|
||||
// Input : &outMessage -
|
||||
// &outToken -
|
||||
// &outHostIp -
|
||||
// &netGameServer -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -172,16 +174,16 @@ bool CPylon::PostServerHost(string& outMessage, string& outToken, string& outHos
|
||||
|
||||
rapidjson::Document::AllocatorType& allocator = requestJson.GetAllocator();
|
||||
|
||||
requestJson.AddMember("name", rapidjson::Value(netGameServer.name.c_str(), allocator), allocator);
|
||||
requestJson.AddMember("description", rapidjson::Value(netGameServer.description.c_str(), allocator), allocator);
|
||||
requestJson.AddMember("name", rapidjson::Value(netGameServer.name.c_str(), netGameServer.name.length(), allocator), allocator);
|
||||
requestJson.AddMember("description", rapidjson::Value(netGameServer.description.c_str(), netGameServer.description.length(), allocator), allocator);
|
||||
requestJson.AddMember("hidden", netGameServer.hidden, allocator);
|
||||
requestJson.AddMember("map", rapidjson::Value(netGameServer.map.c_str(), allocator), allocator);
|
||||
requestJson.AddMember("playlist", rapidjson::Value(netGameServer.playlist.c_str(), allocator), allocator);
|
||||
requestJson.AddMember("ip", rapidjson::Value(netGameServer.address.c_str(), allocator), allocator);
|
||||
requestJson.AddMember("map", rapidjson::Value(netGameServer.map.c_str(), netGameServer.map.length(), allocator), allocator);
|
||||
requestJson.AddMember("playlist", rapidjson::Value(netGameServer.playlist.c_str(), netGameServer.playlist.length(), allocator), allocator);
|
||||
requestJson.AddMember("ip", rapidjson::Value(netGameServer.address.c_str(), netGameServer.address.length(), allocator), allocator);
|
||||
requestJson.AddMember("port", netGameServer.port, allocator);
|
||||
requestJson.AddMember("key", rapidjson::Value(netGameServer.netKey.c_str(), allocator), allocator);
|
||||
requestJson.AddMember("key", rapidjson::Value(netGameServer.netKey.c_str(), netGameServer.netKey.length(), allocator), allocator);
|
||||
requestJson.AddMember("checksum", netGameServer.checksum, allocator);
|
||||
requestJson.AddMember("version", rapidjson::Value(netGameServer.versionId.c_str(), allocator), allocator);
|
||||
requestJson.AddMember("version", rapidjson::Value(netGameServer.versionId.c_str(), netGameServer.versionId.length(), allocator), allocator);
|
||||
requestJson.AddMember("numPlayers", netGameServer.numPlayers, allocator);
|
||||
requestJson.AddMember("maxPlayers", netGameServer.maxPlayers, allocator);
|
||||
requestJson.AddMember("timeStamp", netGameServer.timeStamp, allocator);
|
||||
@ -244,7 +246,7 @@ bool CPylon::GetBannedList(const CBanSystem::BannedList_t& inBannedVec, CBanSyst
|
||||
rapidjson::Value player(rapidjson::kObjectType);
|
||||
|
||||
player.AddMember("id", banned.m_NucleusID, allocator);
|
||||
player.AddMember("ip", rapidjson::Value(banned.m_Address.String(), allocator), allocator);
|
||||
player.AddMember("ip", rapidjson::Value(banned.m_Address.String(), banned.m_Address.Length(), allocator), allocator);
|
||||
|
||||
playersArray.PushBack(player, allocator);
|
||||
}
|
||||
@ -296,6 +298,7 @@ bool CPylon::GetBannedList(const CBanSystem::BannedList_t& inBannedVec, CBanSyst
|
||||
// Purpose: Checks if client is banned on the comp server.
|
||||
// Input : &ipAddress -
|
||||
// nucleusId -
|
||||
// &personaName -
|
||||
// &outReason - <- contains banned reason if any.
|
||||
// Output : True if banned, false if not banned.
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -477,7 +480,7 @@ bool CPylon::SendRequest(const char* endpoint, const rapidjson::Document& reques
|
||||
|
||||
if (status == 200) // STATUS_OK
|
||||
{
|
||||
responseJson.Parse(responseBody.c_str());
|
||||
responseJson.Parse(responseBody.c_str(), responseBody.length()+1);
|
||||
|
||||
if (responseJson.HasParseError())
|
||||
{
|
||||
@ -617,7 +620,7 @@ void CPylon::ExtractError(const string& response, string& outMessage,
|
||||
if (!response.empty())
|
||||
{
|
||||
rapidjson::Document resultBody;
|
||||
resultBody.Parse(response.c_str());
|
||||
resultBody.Parse(response.c_str(), response.length()+1);
|
||||
|
||||
ExtractError(resultBody, outMessage, status, errorText);
|
||||
}
|
||||
|
13
src/particles/CMakeLists.txt
Normal file
13
src/particles/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
cmake_minimum_required( VERSION 3.16 )
|
||||
add_module( "lib" "particles" "vpc" ${FOLDER_CONTEXT} TRUE TRUE )
|
||||
|
||||
start_sources()
|
||||
|
||||
add_sources( SOURCE_GROUP "Runtime"
|
||||
"particles.cpp"
|
||||
"particles.h"
|
||||
)
|
||||
|
||||
end_sources()
|
||||
|
||||
target_include_directories( ${PROJECT_NAME} PRIVATE "${ENGINE_SOURCE_DIR}/tier0/" "${ENGINE_SOURCE_DIR}/tier1/" )
|
34
src/particles/particles.cpp
Normal file
34
src/particles/particles.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
//===========================================================================//
|
||||
//
|
||||
// Purpose: particle system code
|
||||
//
|
||||
//===========================================================================//
|
||||
#include "tier0/commandline.h"
|
||||
#include "rtech/pak/pakstate.h"
|
||||
#include "particles.h"
|
||||
|
||||
static void ParticleSystem_Init()
|
||||
{
|
||||
// Call the original function to load the core particle files, and then
|
||||
// load our effects rpak afterwards to we can patch what is loaded in the
|
||||
// effects.rpak loaded by the engine.
|
||||
v_ParticleSystem_Init();
|
||||
|
||||
// This tells the engine to load the raw DMX files instead, which are
|
||||
// listed inside the particles_manifest.txt file as PCF files.
|
||||
const bool loadUnbaked = CommandLine()->FindParm("-tools") || CommandLine()->FindParm("-nobakedparticles");
|
||||
|
||||
if (!loadUnbaked || CommandLine()->FindParm("-bakedparticles"))
|
||||
{
|
||||
const char* const pakName = "effects_sdk.rpak";
|
||||
const PakHandle_t pakId = g_pakLoadApi->LoadAsyncAndWait(pakName, AlignedMemAlloc(), 3, nullptr);
|
||||
|
||||
if (pakId == PAK_INVALID_HANDLE)
|
||||
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Failed to load pak file '%s'\n", pakName);
|
||||
}
|
||||
}
|
||||
|
||||
void VParticles::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourSetup(&v_ParticleSystem_Init, ParticleSystem_Init, bAttach);
|
||||
}
|
28
src/particles/particles.h
Normal file
28
src/particles/particles.h
Normal file
@ -0,0 +1,28 @@
|
||||
//===========================================================================//
|
||||
//
|
||||
// Purpose: particle system definitions
|
||||
//
|
||||
//===========================================================================//
|
||||
#ifndef PARTICLES_H
|
||||
#define PARTICLES_H
|
||||
|
||||
inline void (*v_ParticleSystem_Init)(void);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VParticles : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("ParticleSystem_Init", v_ParticleSystem_Init);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
g_GameDll.FindPatternSIMD("48 89 4C 24 ?? 55 53 56 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 33 F6").GetPtr(v_ParticleSystem_Init);
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // PARTICLES_H
|
@ -103,7 +103,7 @@ public:
|
||||
|
||||
// Utilities for convars accessed by the material system thread
|
||||
virtual bool IsMaterialThreadSetAllowed() const = 0;
|
||||
virtual void QueueMaterialThreadSetValue(ConVar* pConVar, const char* pValue) = 0;
|
||||
virtual void QueueMaterialThreadSetValue(ConVar* pConVar, const char* pValue/*pValue is allowed to be null*/) = 0;
|
||||
virtual void QueueMaterialThreadSetValue(ConVar* pConVar, int nValue) = 0;
|
||||
virtual void QueueMaterialThreadSetValue(ConVar* pConVar, float flValue) = 0;
|
||||
virtual bool HasQueuedMaterialThreadConVarSets() const = 0;
|
||||
|
@ -1,6 +1,87 @@
|
||||
#ifndef IMATERIAL_H
|
||||
#define IMATERIAL_H
|
||||
|
||||
// See https://www.gdcvault.com/play/1024418/Efficient-Texture-Streaming-in-Titanfall
|
||||
#define MATERIAL_HISTOGRAM_BIN_COUNT 16
|
||||
#define MATERIAL_BLEND_STATE_COUNT 8 // R2 is 4
|
||||
|
||||
struct MaterialBlendState_s
|
||||
{
|
||||
MaterialBlendState_s() = default;
|
||||
|
||||
MaterialBlendState_s(const bool bUnknown, const bool bBlendEnable,
|
||||
const D3D11_BLEND _srcBlend, const D3D11_BLEND _destBlend,
|
||||
const D3D11_BLEND_OP _blendOp, const D3D11_BLEND _srcBlendAlpha,
|
||||
const D3D11_BLEND _destBlendAlpha, const D3D11_BLEND_OP _blendOpAlpha,
|
||||
const int8 _renderTargetWriteMask)
|
||||
{
|
||||
unknown = bUnknown ? 1 : 0;
|
||||
blendEnable = bBlendEnable ? 1 : 0;
|
||||
|
||||
srcBlend = _srcBlend;
|
||||
destBlend = _destBlend;
|
||||
blendOp = _blendOp;
|
||||
srcBlendAlpha = _srcBlendAlpha;
|
||||
destBlendAlpha = _destBlendAlpha;
|
||||
blendOpAlpha = _blendOpAlpha;
|
||||
|
||||
renderTargetWriteMask = _renderTargetWriteMask & 0xF;
|
||||
}
|
||||
|
||||
MaterialBlendState_s(const uint32 _flags)
|
||||
{
|
||||
unknown = (_flags & 1);
|
||||
blendEnable = ((_flags >> 1) & 1);
|
||||
|
||||
srcBlend = ((_flags >> 2) & 0x1F);
|
||||
destBlend = ((_flags >> 7) & 0x1F);
|
||||
blendOp = ((_flags >> 12) & 7);
|
||||
srcBlendAlpha = ((_flags >> 15) & 0x1F);
|
||||
destBlendAlpha = ((_flags >> 20) & 0x1F);
|
||||
blendOpAlpha = ((_flags >> 25) & 7);
|
||||
|
||||
renderTargetWriteMask = (_flags >> 28) & 0xF;
|
||||
}
|
||||
|
||||
uint32 unknown : 1;
|
||||
uint32 blendEnable : 1;
|
||||
uint32 srcBlend : 5;
|
||||
uint32 destBlend : 5;
|
||||
uint32 blendOp : 3;
|
||||
uint32 srcBlendAlpha : 5;
|
||||
uint32 destBlendAlpha : 5;
|
||||
uint32 blendOpAlpha : 3;
|
||||
uint32 renderTargetWriteMask : 4;
|
||||
};
|
||||
|
||||
// Aligned to 16 bytes so this struct can be loaded with 3 SIMD instructions.
|
||||
struct ALIGN16 MaterialRenderParams_s
|
||||
{
|
||||
// Bitfield defining a D3D11_RENDER_TARGET_BLEND_DESC for each of the 8 possible DX render targets
|
||||
MaterialBlendState_s blendState[MATERIAL_BLEND_STATE_COUNT];
|
||||
uint32 blendStateMask;
|
||||
|
||||
// Flags to determine how the D3D11_DEPTH_STENCIL_DESC is defined for this material.
|
||||
uint16 depthStencilFlags;
|
||||
|
||||
// Flags to determine how the D3D11_RASTERIZER_DESC is defined.
|
||||
uint16 rasterizerFlags;
|
||||
};
|
||||
|
||||
enum MaterialShaderType_e : uint8 // From RSX and RePak
|
||||
{
|
||||
RGDU, // Static model with regular vertices.
|
||||
RGDP, // Static model with packed vertices.
|
||||
RGDC, // Static model with packed vertices.
|
||||
SKNU, // Skinned model with regular vertices.
|
||||
SKNP, // Skinned model with packed vertices.
|
||||
SKNC, // Skinned model with packed vertices.
|
||||
WLDU, // World geometry with regular vertices.
|
||||
WLDC, // World geometry with packed vertices.
|
||||
PTCU, // Particles with regular vertices.
|
||||
PTCS, // Particles sprites?.
|
||||
};
|
||||
|
||||
abstract_class IMaterial
|
||||
{
|
||||
public:
|
||||
@ -55,7 +136,11 @@ private:
|
||||
virtual void stub_34() const = 0;
|
||||
virtual void stub_35() const = 0;
|
||||
virtual void stub_36() const = 0;
|
||||
virtual void stub_37() const = 0;
|
||||
|
||||
public:
|
||||
virtual bool CanCreditModelTextures() = 0;
|
||||
|
||||
private:
|
||||
virtual void stub_38() const = 0;
|
||||
virtual void stub_39() const = 0;
|
||||
virtual void stub_40() const = 0;
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define IMATERIALSYSTEM_H
|
||||
|
||||
#define NVIDIA_VENDOR_ID 0x10DE
|
||||
#define AMD_VENDOR_ID 0x10EE
|
||||
#define AMD_VENDOR_ID 0x1002
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Material adapter info..
|
||||
|
@ -37,12 +37,12 @@ enum JoystickAxis_t
|
||||
MAX_JOYSTICK_AXES,
|
||||
};
|
||||
|
||||
enum JoystickDeadzoneIndex_t
|
||||
enum JoystickType_t
|
||||
{
|
||||
JOYSTICK_DEADZONE_NONE = 0,
|
||||
JOYSTICK_DEADZONE_XBOX360,
|
||||
JOYSTICK_DEADZONE_XBOX1,
|
||||
JOYSTICK_DEADZONE_OTHER
|
||||
JOYSTICK_TYPE_NONE = 0,
|
||||
JOYSTICK_TYPE_XBOX360,
|
||||
JOYSTICK_TYPE_XBOX1,
|
||||
JOYSTICK_TYPE_PS4
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -75,7 +75,7 @@ public:
|
||||
virtual int GetButtonPressedTick( const ButtonCode_t code ) const = 0;
|
||||
|
||||
/// Returns the joystick deadzone index for connected hardware.
|
||||
virtual JoystickDeadzoneIndex_t GetJoystickDeadzoneIndex( ) const = 0;
|
||||
virtual JoystickType_t GetJoystickType( ) const = 0;
|
||||
|
||||
/// DoNothing; VFTable padding.
|
||||
virtual bool ReturnFalse( ) const = 0;
|
||||
|
20
src/public/netcon/INetCon.h
Normal file
20
src/public/netcon/INetCon.h
Normal file
@ -0,0 +1,20 @@
|
||||
//===========================================================================//
|
||||
//
|
||||
// Purpose: Net console types
|
||||
//
|
||||
//===========================================================================//
|
||||
#ifndef INETCON_H
|
||||
#define INETCON_H
|
||||
|
||||
#define RCON_FRAME_MAGIC ('R'+('C'<<8)+('o'<<16)+('n'<<24))
|
||||
#define RCON_FRAME_MAX_SIZE 1024*1024 // Max size of envelope and its payload.
|
||||
|
||||
// Wire struct for each individual net console frame. Fields are transmitted in
|
||||
// network byte order and must be flipped to platform's endianness on receive.
|
||||
struct NetConFrameHeader_s
|
||||
{
|
||||
u32 magic;
|
||||
u32 length;
|
||||
};
|
||||
|
||||
#endif // INETCON_H
|
@ -1,122 +1,127 @@
|
||||
#ifndef TEXTURE_G_H
|
||||
#define TEXTURE_G_H
|
||||
#include <rtech/ipakfile.h>
|
||||
#include <imaterial.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structure definitions
|
||||
//-----------------------------------------------------------------------------
|
||||
/*schema*/ struct TextureDesc_t
|
||||
/*schema*/ struct TextureDesc_s
|
||||
{
|
||||
uint64_t m_AssetGuid;
|
||||
const char* m_pDebugName;
|
||||
uint16 m_nWidth;
|
||||
uint16 m_nHeight;
|
||||
uint16 m_nDepth;
|
||||
uint16_t m_nImageFormat;
|
||||
PakGuid_t assetGuid;
|
||||
const char* debugName;
|
||||
uint16 width;
|
||||
uint16 height;
|
||||
uint16 depth;
|
||||
uint16 imageFormat;
|
||||
};
|
||||
|
||||
/*schema*/ struct TextureHeader_t : public TextureDesc_t
|
||||
/*schema*/ struct TextureAsset_s : public TextureDesc_s
|
||||
{
|
||||
uint32_t m_nDataLength;
|
||||
uint8_t unknown_2;
|
||||
uint8_t m_nOptStreamedMipCount;
|
||||
uint8_t m_nArraySize;
|
||||
uint8_t m_nLayerCount;
|
||||
uint8_t m_nCPUAccessFlag; // [ PIXIE ]: In RTech::CreateDXBuffer textureDescription Usage is determined by the CPU Access Flag so I assume it's the same case here.
|
||||
uint8_t m_nPermanentMipCount;
|
||||
uint8_t m_nStreamedMipCount;
|
||||
uint8_t unknown_4[13];
|
||||
__int64 m_nPixelCount;
|
||||
uint8_t unknown_5[3];
|
||||
uint8_t m_nTotalStreamedMipCount; // Does not get set until after RTech::CreateDXTexture.
|
||||
uint8_t unk4[228];
|
||||
uint8_t unk5[57];
|
||||
ID3D11Texture2D* m_ppTexture;
|
||||
ID3D11ShaderResourceView* m_ppShaderResourceView;
|
||||
uint8_t m_nTextureMipLevels;
|
||||
uint8_t m_nTextureMipLevelsStreamedOpt;
|
||||
uint32 dataSize;
|
||||
uint8 swizzleType;
|
||||
uint8 optStreamedMipLevels;
|
||||
uint8 arraySize;
|
||||
uint8 layerCount;
|
||||
uint8 usageFlags; // [ PIXIE ]: In RTech::CreateDXBuffer textureDescription Usage is determined by the CPU Access Flag so I assume it's the same case here.
|
||||
uint8 permanentMipLevels;
|
||||
uint8 streamedMipLevels;
|
||||
uint8 unkPerMip[13];
|
||||
uint64 texelCount;
|
||||
uint16 streamedTextureIndex;
|
||||
uint8 loadedStreamedMipLevelCount;
|
||||
uint8 totalStreamedMipLevelCount; // Does not get set until after RTech::CreateDXTexture.
|
||||
|
||||
int lastUsedFrame;
|
||||
int lastFrame;
|
||||
|
||||
int unknown;
|
||||
|
||||
float accumStreamDB[MATERIAL_HISTOGRAM_BIN_COUNT];
|
||||
float accumGPUDriven[MATERIAL_HISTOGRAM_BIN_COUNT];
|
||||
|
||||
char unk_84[88];
|
||||
uint8 unk5[57];
|
||||
|
||||
ID3D11Texture2D* pInputTexture;
|
||||
ID3D11ShaderResourceView* pShaderResourceView;
|
||||
uint8 textureMipLevels;
|
||||
uint8 textureMipLevelsStreamedOpt;
|
||||
};
|
||||
|
||||
struct TextureBytesPerPixel_s
|
||||
{
|
||||
uint8 x;
|
||||
uint8 y;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Table definitions
|
||||
//-----------------------------------------------------------------------------
|
||||
static const pair<uint8_t, uint8_t> s_pBytesPerPixel[] =
|
||||
static inline const TextureBytesPerPixel_s s_pBytesPerPixel[] =
|
||||
{
|
||||
{ uint8_t(8u), uint8_t(4u) },
|
||||
{ uint8_t(8u), uint8_t(4u) },
|
||||
{ uint8_t(16u), uint8_t(4u) },
|
||||
{ uint8_t(16u), uint8_t(4u) },
|
||||
{ uint8_t(16u), uint8_t(4u) },
|
||||
{ uint8_t(16u), uint8_t(4u) },
|
||||
{ uint8_t(8u), uint8_t(4u) },
|
||||
{ uint8_t(8u), uint8_t(4u) },
|
||||
{ uint8_t(16u), uint8_t(4u) },
|
||||
{ uint8_t(16u), uint8_t(4u) },
|
||||
{ uint8_t(16u), uint8_t(4u) },
|
||||
{ uint8_t(16u), uint8_t(4u) },
|
||||
{ uint8_t(16u), uint8_t(4u) },
|
||||
{ uint8_t(16u), uint8_t(4u) },
|
||||
{ uint8_t(16u), uint8_t(1u) },
|
||||
{ uint8_t(16u), uint8_t(1u) },
|
||||
{ uint8_t(16u), uint8_t(1u) },
|
||||
{ uint8_t(12u), uint8_t(1u) },
|
||||
{ uint8_t(12u), uint8_t(1u) },
|
||||
{ uint8_t(12u), uint8_t(1u) },
|
||||
{ uint8_t(8u), uint8_t(1u) },
|
||||
{ uint8_t(8u), uint8_t(1u) },
|
||||
{ uint8_t(8u), uint8_t(1u) },
|
||||
{ uint8_t(8u), uint8_t(1u) },
|
||||
{ uint8_t(8u), uint8_t(1u) },
|
||||
{ uint8_t(8u), uint8_t(1u) },
|
||||
{ uint8_t(8u), uint8_t(1u) },
|
||||
{ uint8_t(8u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(2u), uint8_t(1u) },
|
||||
{ uint8_t(2u), uint8_t(1u) },
|
||||
{ uint8_t(2u), uint8_t(1u) },
|
||||
{ uint8_t(2u), uint8_t(1u) },
|
||||
{ uint8_t(2u), uint8_t(1u) },
|
||||
{ uint8_t(2u), uint8_t(1u) },
|
||||
{ uint8_t(2u), uint8_t(1u) },
|
||||
{ uint8_t(2u), uint8_t(1u) },
|
||||
{ uint8_t(2u), uint8_t(1u) },
|
||||
{ uint8_t(1u), uint8_t(1u) },
|
||||
{ uint8_t(1u), uint8_t(1u) },
|
||||
{ uint8_t(1u), uint8_t(1u) },
|
||||
{ uint8_t(1u), uint8_t(1u) },
|
||||
{ uint8_t(1u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(4u), uint8_t(1u) },
|
||||
{ uint8_t(2u), uint8_t(1u) },
|
||||
{ uint8_t(0u), uint8_t(0u) },
|
||||
{ uint8_t(0u), uint8_t(0u) },
|
||||
{ uint8_t(5u), uint8_t(0u) },
|
||||
{ uint8_t(0u), uint8_t(0u) },
|
||||
{ uint8_t(5u), uint8_t(0u) },
|
||||
{ uint8_t(0u), uint8_t(0u) },
|
||||
{ uint8_t(1u), uint8_t(0u) },
|
||||
{ uint8_t(0u), uint8_t(0u) },
|
||||
{ uint8_t(2u), uint8_t(0u) },
|
||||
{ uint8_t(0u), uint8_t(0u) },
|
||||
{ uint8_t(0u), uint8_t(0u) },
|
||||
{ uint8_t(0u), uint8_t(0u) },
|
||||
{ uint8_t(1u), uint8_t(0u) },
|
||||
{ uint8_t(0u), uint8_t(0u) }
|
||||
{ u8(8u), u8(4u) },
|
||||
{ u8(8u), u8(4u) },
|
||||
{ u8(16u), u8(4u) },
|
||||
{ u8(16u), u8(4u) },
|
||||
{ u8(16u), u8(4u) },
|
||||
{ u8(16u), u8(4u) },
|
||||
{ u8(8u), u8(4u) },
|
||||
{ u8(8u), u8(4u) },
|
||||
{ u8(16u), u8(4u) },
|
||||
{ u8(16u), u8(4u) },
|
||||
{ u8(16u), u8(4u) },
|
||||
{ u8(16u), u8(4u) },
|
||||
{ u8(16u), u8(4u) },
|
||||
{ u8(16u), u8(4u) },
|
||||
{ u8(16u), u8(1u) },
|
||||
{ u8(16u), u8(1u) },
|
||||
{ u8(16u), u8(1u) },
|
||||
{ u8(12u), u8(1u) },
|
||||
{ u8(12u), u8(1u) },
|
||||
{ u8(12u), u8(1u) },
|
||||
{ u8(8u), u8(1u) },
|
||||
{ u8(8u), u8(1u) },
|
||||
{ u8(8u), u8(1u) },
|
||||
{ u8(8u), u8(1u) },
|
||||
{ u8(8u), u8(1u) },
|
||||
{ u8(8u), u8(1u) },
|
||||
{ u8(8u), u8(1u) },
|
||||
{ u8(8u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(2u), u8(1u) },
|
||||
{ u8(2u), u8(1u) },
|
||||
{ u8(2u), u8(1u) },
|
||||
{ u8(2u), u8(1u) },
|
||||
{ u8(2u), u8(1u) },
|
||||
{ u8(2u), u8(1u) },
|
||||
{ u8(2u), u8(1u) },
|
||||
{ u8(2u), u8(1u) },
|
||||
{ u8(2u), u8(1u) },
|
||||
{ u8(1u), u8(1u) },
|
||||
{ u8(1u), u8(1u) },
|
||||
{ u8(1u), u8(1u) },
|
||||
{ u8(1u), u8(1u) },
|
||||
{ u8(1u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(4u), u8(1u) },
|
||||
{ u8(2u), u8(1u) },
|
||||
};
|
||||
|
||||
// Map dxgi format to txtr asset format
|
||||
@ -192,7 +197,7 @@ inline int DxgiFormatToTxtrAsset(DXGI_FORMAT dxgi)
|
||||
}
|
||||
|
||||
// Map txtr asset format to dxgi format
|
||||
static const DXGI_FORMAT g_TxtrAssetToDxgiFormat[] =
|
||||
static inline const DXGI_FORMAT g_TxtrAssetToDxgiFormat[] =
|
||||
{
|
||||
DXGI_FORMAT_BC1_UNORM,
|
||||
DXGI_FORMAT_BC1_UNORM_SRGB,
|
||||
|
@ -36,11 +36,11 @@
|
||||
#define PAK_MAX_TRACKED_ASSETS (PAK_MAX_LOADED_ASSETS/2)
|
||||
#define PAK_MAX_TRACKED_ASSETS_MASK (PAK_MAX_TRACKED_ASSETS-1)
|
||||
|
||||
// max amount of segments a pak file could have
|
||||
#define PAK_MAX_SEGMENTS 20
|
||||
// max amount of slabs a pak file could have
|
||||
#define PAK_MAX_SLABS 20
|
||||
|
||||
// max amount of buffers in which segments get copied in
|
||||
#define PAK_SEGMENT_BUFFER_TYPES 4
|
||||
// max amount of buffers in which slabs get copied in
|
||||
#define PAK_SLAB_BUFFER_TYPES 4
|
||||
|
||||
// max amount of streaming files that could be opened per set for a pak, so if a
|
||||
// pak uses more than one set, this number would be used per set
|
||||
@ -112,7 +112,7 @@ typedef uint64_t PakGuid_t;
|
||||
//-----------------------------------------------------------------------------
|
||||
struct PakPageHeader_s
|
||||
{
|
||||
uint32_t segmentIdx;
|
||||
uint32_t slabIndex;
|
||||
uint32_t pageAlignment;
|
||||
uint32_t dataSize;
|
||||
};
|
||||
@ -203,9 +203,9 @@ struct PakAssetBinding_s
|
||||
|
||||
CAlignedMemAlloc* allocator;
|
||||
|
||||
unsigned int headerSize;
|
||||
unsigned int nativeClassSize; // Native class size, for 'material' it would be CMaterialGlue full size.
|
||||
unsigned int headerAlignment;
|
||||
uint32_t headerSize;
|
||||
uint32_t structSize; // Native class size, for 'material' it would be CMaterialGlue full size.
|
||||
uint32_t headerAlignment;
|
||||
|
||||
// the type of this asset bind
|
||||
// NOTE: the asset bind will be stubbed if its 'NONE' in runtime!
|
||||
@ -229,11 +229,12 @@ struct PakAsset_s
|
||||
uint16_t pageEnd;
|
||||
|
||||
// the number of remaining dependencies that are yet to be resolved
|
||||
uint16_t numRemainingDependencies;
|
||||
int16_t numRemainingDependencies;
|
||||
|
||||
uint32_t dependentsIndex;
|
||||
uint32_t dependenciesIndex;
|
||||
uint32_t usesIndex;
|
||||
uint32_t dependentsCount;
|
||||
uint32_t dependenciesCount;
|
||||
uint32_t usesCount;
|
||||
|
||||
// size of the asset's header
|
||||
uint32_t headerSize;
|
||||
@ -313,8 +314,8 @@ public:
|
||||
uint32_t assetCount;
|
||||
const char* fileName;
|
||||
CAlignedMemAlloc* allocator;
|
||||
PakGuid_t* assetGuids; //size of the array is m_nAssetCount
|
||||
void* segmentBuffers[PAK_SEGMENT_BUFFER_TYPES];
|
||||
PakGuid_t* assetGuids; // size of the array is assetCount
|
||||
void* slabBuffers[PAK_SLAB_BUFFER_TYPES];
|
||||
void* guidDestriptors;
|
||||
FILETIME fileTime;
|
||||
PakFile_s* pakFile;
|
||||
@ -485,20 +486,20 @@ struct PakFileHeader_s
|
||||
// size of the string array containing paths to external streaming files
|
||||
uint16_t streamingFilesBufSize[STREAMING_SET_COUNT];
|
||||
|
||||
// number of segments in this pak; absolute max = PAK_MAX_SEGMENTS
|
||||
uint16_t virtualSegmentCount;
|
||||
// number of memory slabs in this pak in which pages get allocated to; absolute max = PAK_MAX_SLABS
|
||||
uint16_t memSlabCount;
|
||||
|
||||
// number of memory pages to allocate for this pak
|
||||
uint16_t memPageCount;
|
||||
|
||||
uint16_t patchIndex;
|
||||
|
||||
uint32_t descriptorCount;
|
||||
uint16_t alignment;
|
||||
|
||||
// number of assets in this pak
|
||||
uint32_t assetCount;
|
||||
uint32_t guidDescriptorCount;
|
||||
uint32_t relationsCounts;
|
||||
uint32_t pointerCount;
|
||||
uint32_t assetCount; // number of assets in this pak
|
||||
uint32_t usesCount;
|
||||
uint32_t dependentsCount;
|
||||
|
||||
uint8_t unk2[0x10];
|
||||
|
||||
@ -508,26 +509,28 @@ struct PakFileHeader_s
|
||||
uint8_t unk3[0x8];
|
||||
}; static_assert(sizeof(PakFileHeader_s) == 0x80);
|
||||
|
||||
// segment flags
|
||||
#define SF_HEAD (0)
|
||||
#define SF_TEMP (1 << 0) // 0x1
|
||||
#define SF_CPU (1 << 1) // 0x2
|
||||
#define SF_DEV (1 << 8) // 0x80
|
||||
// slab flags
|
||||
#define SF_HEAD (0)
|
||||
#define SF_CPU (1 << 0)
|
||||
#define SF_TEMP (1 << 1)
|
||||
#define SF_SERVER (1 << 5)
|
||||
#define SF_CLIENT (1 << 6)
|
||||
#define SF_DEV (1 << 8)
|
||||
|
||||
struct PakSegmentHeader_s
|
||||
struct PakSlabHeader_s
|
||||
{
|
||||
int typeFlags;
|
||||
int dataAlignment;
|
||||
size_t dataSize;
|
||||
};
|
||||
|
||||
struct PakSegmentDescriptor_s
|
||||
struct PakSlabDescriptor_s
|
||||
{
|
||||
size_t assetTypeCount[PAK_MAX_TRACKED_TYPES];
|
||||
int64_t segmentSizes[PAK_MAX_SEGMENTS];
|
||||
int64_t slabSizes[PAK_MAX_SLABS];
|
||||
|
||||
size_t segmentSizeForType[PAK_SEGMENT_BUFFER_TYPES];
|
||||
int segmentAlignmentForType[PAK_SEGMENT_BUFFER_TYPES];
|
||||
size_t slabSizeForType[PAK_SLAB_BUFFER_TYPES];
|
||||
int slabAlignmentForType[PAK_SLAB_BUFFER_TYPES];
|
||||
};
|
||||
|
||||
struct PakDecoder_s
|
||||
@ -687,7 +690,7 @@ struct PakMemoryData_s
|
||||
|
||||
char* streamingFilePaths[STREAMING_SET_COUNT];
|
||||
|
||||
PakSegmentHeader_s* segmentHeaders;
|
||||
PakSlabHeader_s* slabHeaders;
|
||||
PakPageHeader_s* pageHeaders;
|
||||
|
||||
PakPage_u* virtualPointers;
|
||||
@ -704,7 +707,7 @@ struct PakMemoryData_s
|
||||
int someAssetCount;
|
||||
int numShiftedPointers;
|
||||
|
||||
// array of sizes/offsets in the SF_HEAD segment buffer
|
||||
// array of sizes/offsets in the SF_HEAD slab buffer
|
||||
__int64 unkAssetTypeBindingSizes[PAK_MAX_TRACKED_TYPES];
|
||||
|
||||
const char* fileName;
|
||||
@ -760,7 +763,7 @@ struct PakFile_s
|
||||
|
||||
inline uint32_t GetPointerCount() const
|
||||
{
|
||||
return GetHeader().descriptorCount;
|
||||
return GetHeader().pointerCount;
|
||||
}
|
||||
|
||||
// --- pages ---
|
||||
@ -819,17 +822,17 @@ struct PakFile_s
|
||||
return memoryData.memPageBuffers[ptr->index] + ptr->offset;
|
||||
}
|
||||
|
||||
// --- segments ---
|
||||
inline uint16_t GetSegmentCount() const
|
||||
// --- slabs ---
|
||||
inline uint16_t GetSlabCount() const
|
||||
{
|
||||
return GetHeader().virtualSegmentCount;
|
||||
return GetHeader().memSlabCount;
|
||||
}
|
||||
|
||||
inline const PakSegmentHeader_s* GetSegmentHeader(const uint32_t i) const
|
||||
inline const PakSlabHeader_s* GetSlabHeader(const uint32_t i) const
|
||||
{
|
||||
assert(i < GetSegmentCount());
|
||||
assert(i < GetSlabCount());
|
||||
|
||||
return &memoryData.segmentHeaders[i];
|
||||
return &memoryData.slabHeaders[i];
|
||||
}
|
||||
};
|
||||
|
||||
|
59
src/public/rtech/istreamdb.h
Normal file
59
src/public/rtech/istreamdb.h
Normal file
@ -0,0 +1,59 @@
|
||||
//=============================================================================//
|
||||
//
|
||||
// Purpose: stream database constants and types
|
||||
//
|
||||
//=============================================================================//
|
||||
#ifndef RTECH_ISTREAMDB
|
||||
#define RTECH_ISTREAMDB
|
||||
#include "ipakfile.h"
|
||||
|
||||
#define STBSP_FILE_EXTENSION "stbsp"
|
||||
#define STBSP_NOMINAL_TEX_RES 4096
|
||||
|
||||
struct StreamDB_Lump_s
|
||||
{
|
||||
uint64 offset;
|
||||
uint64 count;
|
||||
};
|
||||
|
||||
struct StreamDB_Material_s
|
||||
{
|
||||
int nameOffset;
|
||||
char unk[4];
|
||||
PakGuid_t materialGUID;
|
||||
char unk2[8];
|
||||
};
|
||||
|
||||
struct StreamDB_Header_s
|
||||
{
|
||||
uint32 magic;
|
||||
uint16 majorVersion;
|
||||
uint16 minorVersion;
|
||||
char unkPad1[20];
|
||||
float unk1;
|
||||
float unk2;
|
||||
char unkPad2[130];
|
||||
StreamDB_Lump_s lumps[6];
|
||||
char unkPad3[128];
|
||||
};
|
||||
|
||||
struct StreamDB_PageState_s
|
||||
{
|
||||
int page;
|
||||
int unk;
|
||||
char* pageData;
|
||||
char gap_10[8];
|
||||
};
|
||||
|
||||
struct StreamDB_ResidentPage_s
|
||||
{
|
||||
uint64 dataOffset;
|
||||
int dataSize;
|
||||
float coverageScale;
|
||||
uint16 minCellX;
|
||||
uint16 minCellY;
|
||||
uint16 maxCellX;
|
||||
uint16 maxCellY;
|
||||
};
|
||||
|
||||
#endif // RTECH_ISTREAMDB
|
@ -3,32 +3,39 @@
|
||||
class CIOStream
|
||||
{
|
||||
public:
|
||||
enum Mode_t
|
||||
enum class Mode_e
|
||||
{
|
||||
NONE = 0,
|
||||
READ = std::ios::in,
|
||||
WRITE = std::ios::out,
|
||||
BINARY = std::ios::binary,
|
||||
None = 0,
|
||||
Read,
|
||||
Write,
|
||||
ReadWrite, // For existing files only.
|
||||
ReadWriteCreate
|
||||
};
|
||||
|
||||
CIOStream();
|
||||
~CIOStream();
|
||||
|
||||
bool Open(const char* const pFilePath, const int nFlags);
|
||||
bool Open(const char* const filePath, const Mode_e mode);
|
||||
inline bool Open(const std::string& filePath, const Mode_e mode) { return Open(filePath.c_str(), mode); };
|
||||
|
||||
void Close();
|
||||
void Reset();
|
||||
void Flush();
|
||||
|
||||
std::streampos TellGet();
|
||||
std::streampos TellPut();
|
||||
std::streamoff TellGet();
|
||||
std::streamoff TellPut();
|
||||
|
||||
void SeekGet(const std::streampos nOffset);
|
||||
void SeekPut(const std::streampos nOffset);
|
||||
void Seek(const std::streampos nOffset);
|
||||
void SeekGet(const std::streamoff offset, const std::ios_base::seekdir way = std::ios::beg);
|
||||
void SeekPut(const std::streamoff offset, const std::ios_base::seekdir way = std::ios::beg);
|
||||
void Seek(const std::streamoff offset, const std::ios_base::seekdir way = std::ios::beg);
|
||||
|
||||
const std::filebuf* GetData() const;
|
||||
const std::streampos GetSize() const;
|
||||
const std::streamoff GetSize() const;
|
||||
|
||||
bool IsReadable();
|
||||
bool IsReadMode() const;
|
||||
bool IsWriteMode() const;
|
||||
|
||||
bool IsReadable() const;
|
||||
bool IsWritable() const;
|
||||
|
||||
bool IsEof() const;
|
||||
@ -37,39 +44,39 @@ public:
|
||||
// Purpose: reads any value from the file
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void Read(T& tValue)
|
||||
inline void Read(T& value)
|
||||
{
|
||||
if (IsReadable())
|
||||
m_Stream.read(reinterpret_cast<char*>(&tValue), sizeof(tValue));
|
||||
m_stream.read(reinterpret_cast<char*>(&value), sizeof(value));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: reads any value from the file with specified size
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void Read(T* tValue, const size_t nSize)
|
||||
inline void Read(T* const value, const size_t size)
|
||||
{
|
||||
if (IsReadable())
|
||||
m_Stream.read(reinterpret_cast<char*>(tValue), nSize);
|
||||
m_stream.read(reinterpret_cast<char*>(value), size);
|
||||
}
|
||||
template<typename T>
|
||||
void Read(T& tValue, const size_t nSize)
|
||||
inline void Read(T& value, const size_t size)
|
||||
{
|
||||
if (IsReadable())
|
||||
m_Stream.read(reinterpret_cast<char*>(&tValue), nSize);
|
||||
m_stream.read(reinterpret_cast<char*>(&value), size);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: reads any value from the file and returns it
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T Read()
|
||||
inline T Read()
|
||||
{
|
||||
T value{};
|
||||
if (!IsReadable())
|
||||
return value;
|
||||
|
||||
m_Stream.read(reinterpret_cast<char*>(&value), sizeof(value));
|
||||
m_stream.read(reinterpret_cast<char*>(&value), sizeof(value));
|
||||
return value;
|
||||
}
|
||||
bool ReadString(std::string& svOut);
|
||||
@ -79,31 +86,40 @@ public:
|
||||
// Purpose: writes any value to the file
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void Write(T tValue)
|
||||
inline void Write(const T& value)
|
||||
{
|
||||
if (!IsWritable())
|
||||
return;
|
||||
|
||||
m_Stream.write(reinterpret_cast<const char*>(&tValue), sizeof(tValue));
|
||||
m_nSize += sizeof(tValue);
|
||||
const size_t count = sizeof(value);
|
||||
|
||||
m_stream.write(reinterpret_cast<const char*>(&value), count);
|
||||
CalcAddDelta(count);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: writes any value to the file with specified size
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void Write(T* tValue, size_t nSize)
|
||||
inline void Write(const T* const value, const size_t size)
|
||||
{
|
||||
if (!IsWritable())
|
||||
return;
|
||||
|
||||
m_Stream.write(reinterpret_cast<const char*>(tValue), nSize);
|
||||
m_nSize += nSize;
|
||||
m_stream.write(reinterpret_cast<const char*>(value), size);
|
||||
CalcAddDelta(size);
|
||||
}
|
||||
bool WriteString(const std::string& svInput);
|
||||
bool WriteString(const std::string& svInput, const bool nullterminate);
|
||||
void Pad(const size_t count);
|
||||
|
||||
protected:
|
||||
void CalcAddDelta(const size_t count);
|
||||
void CalcSkipDelta(const std::streamoff offset, const std::ios_base::seekdir way);
|
||||
|
||||
private:
|
||||
std::streampos m_nSize; // File size.
|
||||
int m_nFlags; // Stream flags.
|
||||
std::fstream m_Stream; // I/O stream.
|
||||
std::fstream m_stream; // I/O stream.
|
||||
std::streamoff m_size; // File size.
|
||||
std::streamoff m_skip; // Amount skipped back.
|
||||
std::ios_base::openmode m_flags; // Stream flags.
|
||||
Mode_e m_mode; // Stream mode.
|
||||
};
|
||||
|
@ -95,6 +95,11 @@ constexpr const char* s_ScriptAnsiColor[4] =
|
||||
"\033[38;2;151;149;163mScript(X):"
|
||||
};
|
||||
|
||||
// "Native", "Script" and "Netcon" have the same length, so we can cheat here.
|
||||
constexpr size_t s_ContextPrefixTextSize = sizeof("Native(X):") - 1;
|
||||
constexpr size_t s_AnsiColorTextSize = sizeof(s_CommonAnsiColor) - 1;
|
||||
constexpr size_t s_FullAnsiContextPrefixTextSize = s_AnsiColorTextSize + s_ContextPrefixTextSize;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Legacy Logging System
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -69,9 +69,9 @@ void FourCCToString(FourCCString_t& buf, const int n);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Bytes
|
||||
vector<int> StringToBytes(const char* const szInput, const bool bNullTerminator);
|
||||
vector<uint8_t> StringToBytes(const char* const szInput, const bool bNullTerminator);
|
||||
pair<vector<uint8_t>, string> StringToMaskedBytes(const char* const szInput, const bool bNullTerminator);
|
||||
vector<int> PatternToBytes(const char* const szInput);
|
||||
vector<uint16_t> PatternToBytes(const char* const szInput);
|
||||
pair<vector<uint8_t>, string> PatternToMaskedBytes(const char* const szInput);
|
||||
vector<int> IntToDigits(int iValue);
|
||||
|
||||
|
@ -244,7 +244,7 @@ private:
|
||||
virtual void InternalSetColorValue(Color value);
|
||||
|
||||
// DoNothing in the engine, probably for tracking/debugging cvar strings in debug.
|
||||
virtual void TrackDefaultValue(const char* value) { };
|
||||
virtual void TrackValueChange(const char* value) { };
|
||||
|
||||
virtual bool ClampValue(float& flValue);
|
||||
|
||||
|
@ -159,13 +159,12 @@ public:
|
||||
extern ConVarFlags g_ConVarFlags;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
bool ConVar_ParseFlagString(const char* pszFlags, int& nFlags, const char* pszConVarName = "<<unspecified>>");
|
||||
void ConVar_PrintDescription(ConCommandBase* pVar);
|
||||
bool ConVar_ParseFlagString(const char* const pszFlags, int& nFlags, const char* const pszConVarName = "<<unspecified>>");
|
||||
|
||||
inline bool (*CCvar__Connect)(CCvar* thisptr, CreateInterfaceFn factory);
|
||||
inline void (*CCvar__Disconnect)(CCvar* thisptr);
|
||||
|
||||
inline void (*v_ConVar_PrintDescription)(ConCommandBase* pVar);
|
||||
inline void (*v_ConVar_PrintDescription)(const ConCommandBase* const pVar);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VCVar : public IDetour
|
||||
|
74
src/public/tier2/jsonalloc.h
Normal file
74
src/public/tier2/jsonalloc.h
Normal file
@ -0,0 +1,74 @@
|
||||
//===========================================================================//
|
||||
//
|
||||
// Purpose: RapidJSON allocator class
|
||||
//
|
||||
//===========================================================================//
|
||||
#ifndef TIER2_JSONALLOC_H
|
||||
#define TIER2_JSONALLOC_H
|
||||
|
||||
// 16 byte alignment as we only support up to 128 bits SIMD.
|
||||
#define JSON_SIMD_ALIGNMENT 16
|
||||
|
||||
class JSONAllocator
|
||||
{
|
||||
public:
|
||||
static const bool kNeedFree; //!< Whether this allocator needs to call Free().
|
||||
|
||||
// Allocate a memory block.
|
||||
// \param size of the memory block in bytes.
|
||||
// \returns pointer to the memory block.
|
||||
void* Malloc(size_t size)
|
||||
{
|
||||
if (!size)
|
||||
return nullptr;
|
||||
|
||||
#ifdef RAPIDJSON_SIMD
|
||||
return _aligned_malloc(AlignValue(size, JSON_SIMD_ALIGNMENT), JSON_SIMD_ALIGNMENT);
|
||||
#else
|
||||
return malloc(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Resize a memory block.
|
||||
// \param originalPtr The pointer to current memory block. Null pointer is permitted.
|
||||
// \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.)
|
||||
// \param newSize the new size in bytes.
|
||||
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize)
|
||||
{
|
||||
(void)originalSize;
|
||||
|
||||
if (newSize == 0)
|
||||
{
|
||||
Free(originalPtr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef RAPIDJSON_SIMD
|
||||
return _aligned_realloc(originalPtr, AlignValue(newSize, JSON_SIMD_ALIGNMENT), JSON_SIMD_ALIGNMENT);
|
||||
#else
|
||||
return realloc(originalPtr, newSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Free a memory block.
|
||||
// \param pointer to the memory block. Null pointer is permitted.
|
||||
static void Free(void* ptr) noexcept
|
||||
{
|
||||
#ifdef RAPIDJSON_SIMD
|
||||
_aligned_free(ptr);
|
||||
#else
|
||||
free(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool operator==(const JSONAllocator&) const noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool operator!=(const JSONAllocator&) const noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // TIER2_JSONALLOC_H
|
@ -11,11 +11,11 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
enum class JSONFieldType_e
|
||||
{
|
||||
kInvalid = -1,
|
||||
|
||||
kNull = 0,
|
||||
kObject,
|
||||
|
||||
kBool,
|
||||
kNumber,
|
||||
|
||||
kSint32,
|
||||
kUint32,
|
||||
@ -29,14 +29,52 @@ enum class JSONFieldType_e
|
||||
kDouble,
|
||||
kLDouble,
|
||||
|
||||
kNumber,
|
||||
|
||||
kString,
|
||||
kArray
|
||||
kArray,
|
||||
kObject,
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline JSONFieldType_e JSON_ExtractType(const T& data)
|
||||
{
|
||||
if (data.IsNull())
|
||||
return JSONFieldType_e::kNull;
|
||||
if (data.IsBool())
|
||||
return JSONFieldType_e::kBool;
|
||||
if (data.IsInt())
|
||||
return JSONFieldType_e::kSint32;
|
||||
if (data.IsUint())
|
||||
return JSONFieldType_e::kUint32;
|
||||
if (data.IsInt64())
|
||||
return JSONFieldType_e::kSint64;
|
||||
if (data.IsUint64())
|
||||
return JSONFieldType_e::kUint64;
|
||||
if (data.IsFloat())
|
||||
return JSONFieldType_e::kFloat;
|
||||
if (data.IsLosslessFloat())
|
||||
return JSONFieldType_e::kLFloat;
|
||||
if (data.IsDouble())
|
||||
return JSONFieldType_e::kDouble;
|
||||
if (data.IsLosslessDouble())
|
||||
return JSONFieldType_e::kLDouble;
|
||||
if (data.IsNumber())
|
||||
return JSONFieldType_e::kNumber;
|
||||
if (data.IsString())
|
||||
return JSONFieldType_e::kString;
|
||||
if (data.IsArray())
|
||||
return JSONFieldType_e::kArray;
|
||||
if (data.IsObject())
|
||||
return JSONFieldType_e::kObject;
|
||||
|
||||
return JSONFieldType_e::kInvalid;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the object type as string
|
||||
//-----------------------------------------------------------------------------
|
||||
inline const char* JSON_TypeToString(const rapidjson::Type type)
|
||||
inline const char* JSON_InternalTypeToString(const rapidjson::Type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@ -50,8 +88,40 @@ inline const char* JSON_TypeToString(const rapidjson::Type type)
|
||||
}
|
||||
}
|
||||
|
||||
inline const char* JSON_TypeToString(const JSONFieldType_e type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case JSONFieldType_e::kNull: return "null";
|
||||
case JSONFieldType_e::kBool: return "bool";
|
||||
case JSONFieldType_e::kSint32: return "signed int32";
|
||||
case JSONFieldType_e::kUint32: return "unsigned int32";
|
||||
case JSONFieldType_e::kSint64: return "signed int64";
|
||||
case JSONFieldType_e::kUint64: return "unsigned int64";
|
||||
case JSONFieldType_e::kFloat: return "float";
|
||||
case JSONFieldType_e::kLFloat: return "lossless float";
|
||||
case JSONFieldType_e::kDouble: return "double";
|
||||
case JSONFieldType_e::kLDouble: return "lossless double";
|
||||
case JSONFieldType_e::kNumber: return "number";
|
||||
case JSONFieldType_e::kString: return "string";
|
||||
case JSONFieldType_e::kArray: return "array";
|
||||
case JSONFieldType_e::kObject: return "object";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool JSON_TypeToString(const T& data)
|
||||
{
|
||||
return JSON_TypeToString(JSON_ExtractType(data));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if the member's value is of type provided
|
||||
// NOTE : the switch case was done intentionally instead of JSON_ExtractType
|
||||
// on the object as this function gets used in most accessors that
|
||||
// check on types, and this approach is faster as we already know the
|
||||
// type beforehand
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline bool JSON_IsOfType(const T& data, const JSONFieldType_e type)
|
||||
@ -60,12 +130,8 @@ inline bool JSON_IsOfType(const T& data, const JSONFieldType_e type)
|
||||
{
|
||||
case JSONFieldType_e::kNull:
|
||||
return data.IsNull();
|
||||
case JSONFieldType_e::kObject:
|
||||
return data.IsObject();
|
||||
case JSONFieldType_e::kBool:
|
||||
return data.IsBool();
|
||||
case JSONFieldType_e::kNumber:
|
||||
return data.IsNumber();
|
||||
case JSONFieldType_e::kSint32:
|
||||
return data.IsInt();
|
||||
case JSONFieldType_e::kUint32:
|
||||
@ -82,10 +148,14 @@ inline bool JSON_IsOfType(const T& data, const JSONFieldType_e type)
|
||||
return data.IsDouble();
|
||||
case JSONFieldType_e::kLDouble:
|
||||
return data.IsLosslessDouble();
|
||||
case JSONFieldType_e::kNumber:
|
||||
return data.IsNumber();
|
||||
case JSONFieldType_e::kString:
|
||||
return data.IsString();
|
||||
case JSONFieldType_e::kArray:
|
||||
return data.IsArray();
|
||||
case JSONFieldType_e::kObject:
|
||||
return data.IsObject();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@ -116,16 +186,16 @@ inline JSONFieldType_e JSON_GetTypeForType()
|
||||
else if constexpr (std::is_same<T, std::string>::value)
|
||||
return JSONFieldType_e::kString;
|
||||
else
|
||||
static_assert(false, "Cannot classify data type; unsupported.");
|
||||
static_assert(std::is_same_v<T, void>, "Cannot classify data type; unsupported.");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if the member exists and if its value is of type provided
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline bool JSON_HasMemberAndIsOfType(const T& data, const char* const member, const JSONFieldType_e type)
|
||||
inline bool JSON_HasMemberAndIsOfType(const T& data, typename T::StringRefType member, const JSONFieldType_e type)
|
||||
{
|
||||
const T::ConstMemberIterator it = data.FindMember(member);
|
||||
const T::ConstMemberIterator it = data.FindMember(rapidjson::Value(member));
|
||||
|
||||
if (it != data.MemberEnd())
|
||||
{
|
||||
@ -135,25 +205,63 @@ inline bool JSON_HasMemberAndIsOfType(const T& data, const char* const member, c
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if the member exists, and sets 'out' to its iterator if the
|
||||
// aforementioned condition is met
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline bool JSON_GetIterator(const T& data, typename T::StringRefType member, typename T::ConstMemberIterator& out)
|
||||
{
|
||||
const T::ConstMemberIterator it = data.FindMember(rapidjson::Value(member));
|
||||
|
||||
if (it != data.MemberEnd())
|
||||
{
|
||||
out = it;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Not found.
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if the member exists and if its value is of type provided,
|
||||
// and sets 'out' to its iterator if all aforementioned conditions
|
||||
// are met
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline bool JSON_GetIterator(const T& data, typename T::StringRefType member,
|
||||
const JSONFieldType_e type, typename T::ConstMemberIterator& out)
|
||||
{
|
||||
const T::ConstMemberIterator it = data.FindMember(rapidjson::Value(member));
|
||||
|
||||
if (it != data.MemberEnd())
|
||||
{
|
||||
if (JSON_IsOfType(it->value, type))
|
||||
{
|
||||
out = it;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Not found or didn't match specified type.
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if the member exists and if its value is of specified type,
|
||||
// and sets 'out' to its value if all aforementioned conditions
|
||||
// are met
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class T, class V>
|
||||
inline bool JSON_GetValue(const T& data, const char* const member, const JSONFieldType_e type, V& out)
|
||||
inline bool JSON_GetValue(const T& data, typename T::StringRefType member, const JSONFieldType_e type, V& out)
|
||||
{
|
||||
const T::ConstMemberIterator it = data.FindMember(member);
|
||||
rapidjson::Document::ConstMemberIterator it;
|
||||
|
||||
if (it != data.MemberEnd())
|
||||
if (JSON_GetIterator(data, member, type, it))
|
||||
{
|
||||
const rapidjson::Value& val = it->value;
|
||||
|
||||
if (JSON_IsOfType(val, type))
|
||||
{
|
||||
out = val.Get<V>();
|
||||
return true;
|
||||
}
|
||||
out = it->value.Get<V>();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Not found or didn't match specified type.
|
||||
@ -165,26 +273,21 @@ inline bool JSON_GetValue(const T& data, const char* const member, const JSONFie
|
||||
// and sets 'out' to its value if all aforementioned conditions are met
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class T, class V>
|
||||
inline bool JSON_GetValue(const T& data, const char* const member, V& out)
|
||||
inline bool JSON_GetValue(const T& data, typename T::StringRefType member, V& out)
|
||||
{
|
||||
const T::ConstMemberIterator it = data.FindMember(member);
|
||||
rapidjson::Document::ConstMemberIterator it;
|
||||
|
||||
if (it != data.MemberEnd())
|
||||
if (JSON_GetIterator(data, member, JSON_GetTypeForType<V>(), it))
|
||||
{
|
||||
const rapidjson::Value& val = it->value;
|
||||
|
||||
if (JSON_IsOfType(val, JSON_GetTypeForType<V>()))
|
||||
{
|
||||
out = val.Get<V>();
|
||||
return true;
|
||||
}
|
||||
out = it->value.Get<V>();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Not found or didn't match classified type.
|
||||
return false;
|
||||
}
|
||||
template <class T>
|
||||
inline bool JSON_GetValue(const T& data, const char* const member, std::string& out)
|
||||
inline bool JSON_GetValue(const T& data, typename T::StringRefType member, std::string& out)
|
||||
{
|
||||
const char* stringVal;
|
||||
|
||||
@ -203,7 +306,7 @@ inline bool JSON_GetValue(const T& data, const char* const member, std::string&
|
||||
// else the provided default gets returned
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class T, class V>
|
||||
inline V JSON_GetValueOrDefault(const T& data, const char* const member, const V def)
|
||||
inline V JSON_GetValueOrDefault(const T& data, typename T::StringRefType member, const V def)
|
||||
{
|
||||
V val;
|
||||
|
||||
@ -215,47 +318,25 @@ inline V JSON_GetValueOrDefault(const T& data, const char* const member, const V
|
||||
return def;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if the member exists and if its value is of type provided,
|
||||
// and sets 'out' to its iterator if all aforementioned conditions
|
||||
// are met
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline bool JSON_GetIterator(const T& data, const char* const member,
|
||||
const JSONFieldType_e type, typename T::ConstMemberIterator& out)
|
||||
template <class V>
|
||||
inline bool JSON_StringToNumber(const char* const str, const size_t len, V& num)
|
||||
{
|
||||
const T::ConstMemberIterator it = data.FindMember(member);
|
||||
const char* const end = &str[len];
|
||||
std::from_chars_result result;
|
||||
|
||||
if (it != data.MemberEnd())
|
||||
if constexpr ((std::is_same<V, int32_t>::value) || (std::is_same<V, int64_t>::value) ||
|
||||
(std::is_same<V, uint32_t>::value) || (std::is_same<V, uint64_t>::value))
|
||||
{
|
||||
if (JSON_IsOfType(it->value, type))
|
||||
{
|
||||
out = it;
|
||||
return true;
|
||||
}
|
||||
result = std::from_chars(str, end, num, 0);
|
||||
}
|
||||
|
||||
// Not found or didn't match specified type.
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if the member exists, and sets 'out' to its iterator if the
|
||||
// aforementioned condition is met
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline bool JSON_GetIterator(const T& data, const char* const member, typename T::ConstMemberIterator& out)
|
||||
{
|
||||
const T::ConstMemberIterator it = data.FindMember(member);
|
||||
|
||||
if (it != data.MemberEnd())
|
||||
else if constexpr ((std::is_same<V, float>::value) || (std::is_same<V, double>::value))
|
||||
{
|
||||
out = it;
|
||||
return true;
|
||||
result = std::from_chars(str, end, num, std::chars_format::general);
|
||||
}
|
||||
else
|
||||
static_assert(std::is_same_v<V, void>, "Cannot classify numeric type; unsupported.");
|
||||
|
||||
// Not found.
|
||||
return false;
|
||||
return (result.ptr == end) && (result.ec == std::errc());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -272,37 +353,19 @@ inline bool JSON_ParseNumber(const T& data, V& num)
|
||||
}
|
||||
else if (JSON_IsOfType(data, JSONFieldType_e::kString))
|
||||
{
|
||||
const char* const string = data.GetString();
|
||||
char* end = nullptr;
|
||||
|
||||
if constexpr (std::is_same<V, int32_t>::value)
|
||||
num = strtol(string, &end, 0);
|
||||
else if constexpr (std::is_same<V, int64_t>::value)
|
||||
num = strtoll(string, &end, 0);
|
||||
else if constexpr (std::is_same<V, uint32_t>::value)
|
||||
num = strtoul(string, &end, 0);
|
||||
else if constexpr (std::is_same<V, uint64_t>::value)
|
||||
num = strtoull(string, &end, 0);
|
||||
else if constexpr (std::is_same<V, float>::value)
|
||||
num = static_cast<float>(strtod(string, &end));
|
||||
else if constexpr (std::is_same<V, double>::value)
|
||||
num = strtod(string, &end);
|
||||
else
|
||||
static_assert(false, "Cannot classify numeric type; unsupported.");
|
||||
|
||||
return end == &string[data.GetStringLength()];
|
||||
return JSON_StringToNumber(data.GetString(), data.GetStringLength(), num);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
template <class T, class V>
|
||||
inline bool JSON_ParseNumber(const T& data, const char* const member, V& num)
|
||||
inline bool JSON_ParseNumber(const T& data, typename T::StringRefType member, V& num)
|
||||
{
|
||||
rapidjson::Document::ConstMemberIterator it;
|
||||
|
||||
if (JSON_GetIterator(data, member, it))
|
||||
{
|
||||
return JSON_ParseNumber(it->value, num);;
|
||||
return JSON_ParseNumber(it->value, num);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -314,7 +377,7 @@ inline bool JSON_ParseNumber(const T& data, const char* const member, V& num)
|
||||
// else the provided default gets returned
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class T, class V>
|
||||
inline V JSON_GetNumberOrDefault(const T& data, const char* const member, V def)
|
||||
inline V JSON_GetNumberOrDefault(const T& data, typename T::StringRefType member, V def)
|
||||
{
|
||||
V num;
|
||||
|
||||
|
@ -35,8 +35,8 @@ public:
|
||||
|
||||
SocketHandle_t GetAcceptedSocketHandle(int nIndex) const;
|
||||
const netadr_t& GetAcceptedSocketAddress(int nIndex) const;
|
||||
CConnectedNetConsoleData& GetAcceptedSocketData(int nIndex);
|
||||
const CConnectedNetConsoleData& GetAcceptedSocketData(int nIndex) const;
|
||||
ConnectedNetConsoleData_s& GetAcceptedSocketData(int nIndex);
|
||||
const ConnectedNetConsoleData_s& GetAcceptedSocketData(int nIndex) const;
|
||||
|
||||
public:
|
||||
struct AcceptedSocket_t
|
||||
@ -48,7 +48,7 @@ public:
|
||||
|
||||
SocketHandle_t m_hSocket;
|
||||
netadr_t m_Address;
|
||||
CConnectedNetConsoleData m_Data;
|
||||
ConnectedNetConsoleData_s m_Data;
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -53,6 +53,13 @@
|
||||
0x1E3CB6: "xor rax, rax" // NULL RAX instead of mov'ing '0xDEADFEEDDEADFEED' to cache ptr in 'Pak_UpdateModelAsset()'
|
||||
0x1E3EE2: "xor rax, rax" // NULL RAX instead of mov'ing '0xDEADFEEDDEADFEED' to cache ptr in 'Pak_UpdateAnimRigAsset()'
|
||||
|
||||
// If we don't have an STBSP file, the field s_textureStreamMgr.hasResidentPages will be false. But if the texture
|
||||
// stream manager is initialized and the stream mode is set to default, the code will force the stream mode to disabled.
|
||||
// However, our engine has a working implementation of the GPU driven texture streaming system, and the correct thing
|
||||
// to do here is to not force anything, since our SDK will enable the GPU driven texture streaming system if an STBSP
|
||||
// file wasn't provided for the level. We turn the conditional jump to an unconditional jump here to skip this code.
|
||||
0x3E0363: "jmp 0Fh"
|
||||
|
||||
/////////////////////////////
|
||||
/////////////////////////////
|
||||
//// Code defects ////
|
||||
|
@ -232,7 +232,13 @@ static void ReVPK_Unpack(const CCommand& args)
|
||||
return;
|
||||
}
|
||||
|
||||
CUtlString baseName = PackedStore_GetDirBaseName(vpk.m_DirFilePath);
|
||||
CUtlString baseName;
|
||||
|
||||
if (!PackedStore_GetDirBaseName(vpk.m_DirFilePath, baseName))
|
||||
{
|
||||
Error(eDLL_T::FS, NO_ERROR, "Failed to retrieve directory file stem from \"%s\"!\n", vpk.m_DirFilePath.String());
|
||||
return;
|
||||
}
|
||||
|
||||
// Write the unpack log to a file.
|
||||
CFmtStr1024 textFileName("%s%s%s.log", outPath, UNPACK_LOG_DIR, baseName.String());
|
||||
|
@ -42,6 +42,7 @@ add_sources( SOURCE_GROUP "LiveAPI"
|
||||
add_sources( SOURCE_GROUP "Public"
|
||||
"${ENGINE_SOURCE_DIR}/public/rtech/iasync.h"
|
||||
"${ENGINE_SOURCE_DIR}/public/rtech/ipakfile.h"
|
||||
"${ENGINE_SOURCE_DIR}/public/rtech/istreamdb.h"
|
||||
)
|
||||
|
||||
end_sources()
|
||||
|
@ -87,8 +87,7 @@ class V_AsyncIO : public IDetour
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
extern void(*v_StreamDB_Init)(const char* const pszLevelName);
|
||||
const CMemory streamDbBase(v_StreamDB_Init);
|
||||
const CMemory streamDbBase = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 54 41 56 41 57 48 83 EC 40 48 8B E9");
|
||||
|
||||
g_pAsyncFileSlots = streamDbBase.Offset(0x70).FindPatternSelf("4C 8D", CMemory::Direction::DOWN, 512, 1).ResolveRelativeAddress(0x3, 0x7).RCast<AsyncHandleTracker_s*>();
|
||||
g_pAsyncFileSlotMgr = streamDbBase.Offset(0x70).FindPatternSelf("48 8D 0D", CMemory::Direction::DOWN, 512, 2).ResolveRelativeAddress(0x3, 0x7).RCast<RHashMap_MT*>();
|
||||
|
@ -8,12 +8,12 @@
|
||||
#include "pakalloc.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// aligns the segment headers for each asset type
|
||||
// aligns the slab headers for each asset type
|
||||
//-----------------------------------------------------------------------------
|
||||
void Pak_AlignSegmentHeaders(PakFile_s* const pak, PakSegmentDescriptor_s* const desc)
|
||||
void Pak_AlignSlabHeaders(PakFile_s* const pak, PakSlabDescriptor_s* const desc)
|
||||
{
|
||||
uint64_t headersSize = 0;
|
||||
uint8_t headerSegmentAlignment = static_cast<int8_t>(desc->segmentAlignmentForType[SF_HEAD]);
|
||||
uint32_t slabHeaderAlignment = desc->slabAlignmentForType[SF_HEAD];
|
||||
|
||||
for (uint8_t i = 0; i < PAK_MAX_TRACKED_TYPES; ++i)
|
||||
{
|
||||
@ -21,19 +21,16 @@ void Pak_AlignSegmentHeaders(PakFile_s* const pak, PakSegmentDescriptor_s* const
|
||||
|
||||
if (desc->assetTypeCount[i])
|
||||
{
|
||||
// asset header alignment really shouldn't be above 255
|
||||
// if this needs raising, headerSegmentAlignment should be made wider
|
||||
assert(binding.headerAlignment <= UINT8_MAX);
|
||||
|
||||
assert(binding.headerAlignment > 0 && IsPowerOfTwo(binding.headerAlignment));
|
||||
const size_t alignedSize = ALIGN_VALUE(headersSize, static_cast<size_t>(binding.headerAlignment));
|
||||
|
||||
pak->memoryData.unkAssetTypeBindingSizes[i] = alignedSize;
|
||||
headersSize = alignedSize + (desc->assetTypeCount[i] * binding.nativeClassSize);
|
||||
headersSize = alignedSize + (desc->assetTypeCount[i] * binding.structSize);
|
||||
|
||||
desc->segmentSizeForType[SF_HEAD] = headersSize;
|
||||
desc->slabSizeForType[SF_HEAD] = headersSize;
|
||||
|
||||
headerSegmentAlignment = Max(headerSegmentAlignment, static_cast<uint8_t>(binding.headerAlignment));
|
||||
desc->segmentAlignmentForType[SF_HEAD] = headerSegmentAlignment;
|
||||
slabHeaderAlignment = Max(slabHeaderAlignment, binding.headerAlignment);
|
||||
desc->slabAlignmentForType[SF_HEAD] = slabHeaderAlignment;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -41,69 +38,66 @@ void Pak_AlignSegmentHeaders(PakFile_s* const pak, PakSegmentDescriptor_s* const
|
||||
//-----------------------------------------------------------------------------
|
||||
// aligns each individual non-header segment
|
||||
//-----------------------------------------------------------------------------
|
||||
void Pak_AlignSegments(PakFile_s* const pak, PakSegmentDescriptor_s* const desc)
|
||||
void Pak_AlignSlabData(PakFile_s* const pak, PakSlabDescriptor_s* const desc)
|
||||
{
|
||||
for (uint16_t i = 0; i < pak->GetSegmentCount(); ++i)
|
||||
for (uint16_t i = 0; i < pak->GetSlabCount(); ++i)
|
||||
{
|
||||
const PakSegmentHeader_s* const segHeader = pak->GetSegmentHeader(i);
|
||||
const PakSlabHeader_s* const slabHeader = pak->GetSlabHeader(i);
|
||||
const uint8_t slabType = slabHeader->typeFlags & (SF_CPU | SF_TEMP);
|
||||
|
||||
const uint8_t segmentType = segHeader->typeFlags & (SF_TEMP | SF_CPU);
|
||||
|
||||
if (segmentType != SF_HEAD) // if not a header segment
|
||||
if (slabType != SF_HEAD) // if not a header slab
|
||||
{
|
||||
// should this be a hard error on release?
|
||||
// segment alignment must not be 0 and must be a power of two
|
||||
assert(segHeader->dataAlignment > 0 && IsPowerOfTwo(segHeader->dataAlignment));
|
||||
// slab alignment must not be 0 and must be a power of two
|
||||
assert(slabHeader->dataAlignment > 0 && IsPowerOfTwo(slabHeader->dataAlignment));
|
||||
const size_t alignedSlabSize = ALIGN_VALUE(desc->slabSizeForType[slabType], static_cast<size_t>(slabHeader->dataAlignment));
|
||||
|
||||
const size_t alignedSegmentSize = ALIGN_VALUE(desc->segmentSizeForType[segmentType], static_cast<size_t>(segHeader->dataAlignment));
|
||||
//const size_t sizeAligned = ~(m_align - 1) & (m_align - 1 + segmentSizeForType[segmentType]);
|
||||
desc->slabSizes[i] = alignedSlabSize;
|
||||
desc->slabSizeForType[slabType] = alignedSlabSize + slabHeader->dataSize;
|
||||
|
||||
desc->segmentSizes[i] = alignedSegmentSize;
|
||||
desc->segmentSizeForType[segmentType] = alignedSegmentSize + segHeader->dataSize;
|
||||
|
||||
// check if this segment's alignment is higher than the previous highest for this type
|
||||
// if so, increase the alignment to accommodate this segment
|
||||
desc->segmentAlignmentForType[segmentType] = Max(desc->segmentAlignmentForType[segmentType], segHeader->dataAlignment);
|
||||
// check if this slab's alignment is higher than the previous highest for this type
|
||||
// if so, increase the alignment to accommodate this slab
|
||||
desc->slabAlignmentForType[slabType] = Max(desc->slabAlignmentForType[slabType], slabHeader->dataAlignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// copy's pages into pre-allocated and aligned segments
|
||||
// copy's pages into pre-allocated and aligned slabs
|
||||
//-----------------------------------------------------------------------------
|
||||
void Pak_CopyPagesToSegments(PakFile_s* const pak, PakLoadedInfo_s* const loadedInfo, PakSegmentDescriptor_s* const desc)
|
||||
void Pak_CopyPagesToSlabs(PakFile_s* const pak, PakLoadedInfo_s* const loadedInfo, PakSlabDescriptor_s* const desc)
|
||||
{
|
||||
for (uint32_t i = 0; i < pak->GetPageCount(); ++i)
|
||||
{
|
||||
const PakPageHeader_s* const pageHeader = pak->GetPageHeader(i);
|
||||
const uint32_t segmentIndex = pageHeader->segmentIdx;
|
||||
const uint32_t slabIndex = pageHeader->slabIndex;
|
||||
|
||||
const PakSegmentHeader_s* const segHeader = pak->GetSegmentHeader(segmentIndex);
|
||||
const int typeFlags = segHeader->typeFlags;
|
||||
const PakSlabHeader_s* const slabHeader = pak->GetSlabHeader(slabIndex);
|
||||
const int typeFlags = slabHeader->typeFlags;
|
||||
|
||||
// check if header page
|
||||
if ((typeFlags & (SF_TEMP | SF_CPU)) != 0)
|
||||
if ((typeFlags & (SF_CPU | SF_TEMP)) != 0)
|
||||
{
|
||||
// align the segment's current size to the alignment of the new page to get copied in
|
||||
// align the slab's current size to the alignment of the new page to get copied in
|
||||
// this ensures that the location holding the page is aligned as required
|
||||
//
|
||||
// since the segment will always have alignment equal to or greater than the page, and that alignment will always be a power of 2
|
||||
// the page does not have to be aligned to the same alignment as the segment, as aligning it to its own alignment is sufficient as long as
|
||||
// since the slab will always have alignment equal to or greater than the page, and that alignment will always be a power of 2
|
||||
// the page does not have to be aligned to the same alignment as the slab, as aligning it to its own alignment is sufficient as long as
|
||||
// every subsequent page does the same thing
|
||||
const size_t alignedSegmentSize = ALIGN_VALUE(desc->segmentSizes[segmentIndex], static_cast<size_t>(pageHeader->pageAlignment));
|
||||
const size_t alignedSlabSize = ALIGN_VALUE(desc->slabSizes[slabIndex], static_cast<size_t>(pageHeader->pageAlignment));
|
||||
|
||||
// get a pointer to the newly aligned location within the segment for this page
|
||||
pak->memoryData.memPageBuffers[i] = reinterpret_cast<uint8_t*>(loadedInfo->segmentBuffers[typeFlags & (SF_TEMP | SF_CPU)]) + alignedSegmentSize;
|
||||
// get a pointer to the newly aligned location within the slab for this page
|
||||
pak->memoryData.memPageBuffers[i] = reinterpret_cast<uint8_t*>(loadedInfo->slabBuffers[typeFlags & (SF_CPU | SF_TEMP)]) + alignedSlabSize;
|
||||
|
||||
// update the segment size to reflect the new alignment and page size
|
||||
desc->segmentSizes[segmentIndex] = alignedSegmentSize + pak->memoryData.pageHeaders[i].dataSize;
|
||||
// update the slab size to reflect the new alignment and page size
|
||||
desc->slabSizes[slabIndex] = alignedSlabSize + pak->memoryData.pageHeaders[i].dataSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
// all headers go into one segment and are dealt with separately in Pak_ProcessPakFile
|
||||
// all headers go into one slab and are dealt with separately in Pak_ProcessPakFile
|
||||
// since headers must be copied individually into a buffer that is big enough for the "native class" version of the header
|
||||
// instead of just the file version
|
||||
pak->memoryData.memPageBuffers[i] = reinterpret_cast<uint8_t*>(loadedInfo->segmentBuffers[SF_HEAD]);
|
||||
pak->memoryData.memPageBuffers[i] = reinterpret_cast<uint8_t*>(loadedInfo->slabBuffers[SF_HEAD]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,9 @@
|
||||
#define RTECH_PAKALLOC_H
|
||||
#include "rtech/ipakfile.h"
|
||||
|
||||
extern void Pak_AlignSegmentHeaders(PakFile_s* const pak, PakSegmentDescriptor_s* const desc);
|
||||
extern void Pak_AlignSegments(PakFile_s* const pak, PakSegmentDescriptor_s* const desc);
|
||||
extern void Pak_CopyPagesToSegments(PakFile_s* const pak, PakLoadedInfo_s* const loadedInfo, PakSegmentDescriptor_s* const desc);
|
||||
extern void Pak_AlignSlabHeaders(PakFile_s* const pak, PakSlabDescriptor_s* const desc);
|
||||
extern void Pak_AlignSlabData(PakFile_s* const pak, PakSlabDescriptor_s* const desc);
|
||||
extern void Pak_CopyPagesToSlabs(PakFile_s* const pak, PakLoadedInfo_s* const loadedInfo, PakSlabDescriptor_s* const desc);
|
||||
|
||||
// something with sorting pages?
|
||||
inline void (*sub_140442740)(PakAsset_s** assetEntries, PakAsset_s** assetEntry, __int64 idx, PakFile_s* pak);
|
||||
|
@ -135,7 +135,7 @@ static const unsigned char /*141313180*/ s_defaultDecoderLUT[] =
|
||||
//-----------------------------------------------------------------------------
|
||||
// checks if we have enough output buffer room to decode the data stream
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Pak_HasEnoughDecodeBufferAvailable(PakDecoder_s* const decoder, const size_t outLen)
|
||||
static bool Pak_HasEnoughDecodeBufferAvailable(PakDecoder_s* const decoder, const size_t outLen)
|
||||
{
|
||||
// make sure caller has copied all data out the ring buffer first before
|
||||
// overwriting it with new decoded data
|
||||
@ -146,7 +146,7 @@ bool Pak_HasEnoughDecodeBufferAvailable(PakDecoder_s* const decoder, const size_
|
||||
//-----------------------------------------------------------------------------
|
||||
// checks if we have enough source data streamed to decode the next block
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Pak_HasEnoughStreamedDataForDecode(PakDecoder_s* const decoder, const size_t inLen)
|
||||
static bool Pak_HasEnoughStreamedDataForDecode(PakDecoder_s* const decoder, const size_t inLen)
|
||||
{
|
||||
// the decoder needs at least this amount of input data streamed in order
|
||||
// to decode the rest of the pak file, as this is where reading has stopped
|
||||
@ -160,7 +160,7 @@ bool Pak_HasEnoughStreamedDataForDecode(PakDecoder_s* const decoder, const size_
|
||||
// gets the frame for the data in the ring buffer, the frame returned is always
|
||||
// ending to the end of the ring buffer, or the end of the data itself
|
||||
//-----------------------------------------------------------------------------
|
||||
PakRingBufferFrame_s Pak_DetermineRingBufferFrame(const uint64_t bufMask, const size_t seekPos, const size_t dataLen)
|
||||
static PakRingBufferFrame_s Pak_DetermineRingBufferFrame(const uint64_t bufMask, const size_t seekPos, const size_t dataLen)
|
||||
{
|
||||
PakRingBufferFrame_s ring;
|
||||
ring.bufIndex = seekPos & bufMask;
|
||||
@ -178,7 +178,7 @@ PakRingBufferFrame_s Pak_DetermineRingBufferFrame(const uint64_t bufMask, const
|
||||
//-----------------------------------------------------------------------------
|
||||
// initializes the RTech decoder
|
||||
//-----------------------------------------------------------------------------
|
||||
size_t Pak_RTechDecoderInit(PakDecoder_s* const decoder, const uint8_t* const fileBuffer,
|
||||
static size_t Pak_RTechDecoderInit(PakDecoder_s* const decoder, const uint8_t* const fileBuffer,
|
||||
const uint64_t inputMask, const size_t dataSize, const size_t dataOffset, const size_t headerSize)
|
||||
{
|
||||
uint64_t frameHeader = *(_QWORD*)((inputMask & (dataOffset + headerSize)) + fileBuffer);
|
||||
@ -243,7 +243,7 @@ size_t Pak_RTechDecoderInit(PakDecoder_s* const decoder, const uint8_t* const fi
|
||||
//-----------------------------------------------------------------------------
|
||||
// decodes the RTech data stream up to available buffer or data
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Pak_RTechStreamDecode(PakDecoder_s* const decoder, const size_t inLen, const size_t outLen)
|
||||
static bool Pak_RTechStreamDecode(PakDecoder_s* const decoder, const size_t inLen, const size_t outLen)
|
||||
{
|
||||
bool result; // al
|
||||
uint64_t outBufBytePos; // r15
|
||||
@ -570,7 +570,7 @@ LABEL_69:
|
||||
//-----------------------------------------------------------------------------
|
||||
// initializes the ZStd decoder
|
||||
//-----------------------------------------------------------------------------
|
||||
size_t Pak_ZStdDecoderInit(PakDecoder_s* const decoder, const uint8_t* frameHeader,
|
||||
static size_t Pak_ZStdDecoderInit(PakDecoder_s* const decoder, const uint8_t* frameHeader,
|
||||
const size_t dataSize, const size_t headerSize)
|
||||
{
|
||||
ZSTD_DStream* const dctx = ZSTD_createDStream();
|
||||
@ -608,7 +608,7 @@ size_t Pak_ZStdDecoderInit(PakDecoder_s* const decoder, const uint8_t* frameHead
|
||||
// decodes the ZStd data stream up to available buffer or data, whichever ends
|
||||
// first
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Pak_ZStdStreamDecode(PakDecoder_s* const decoder, const PakRingBufferFrame_s& outFrame, const PakRingBufferFrame_s& inFrame)
|
||||
static bool Pak_ZStdStreamDecode(PakDecoder_s* const decoder, const PakRingBufferFrame_s& outFrame, const PakRingBufferFrame_s& inFrame)
|
||||
{
|
||||
ZSTD_outBuffer outBuffer = {
|
||||
&decoder->outputBuf[outFrame.bufIndex],
|
||||
@ -807,7 +807,7 @@ bool Pak_DecodePakFile(const char* const inPakFile, const char* const outPakFile
|
||||
|
||||
CIOStream inPakStream;
|
||||
|
||||
if (!inPakStream.Open(inPakFile, CIOStream::READ | CIOStream::BINARY))
|
||||
if (!inPakStream.Open(inPakFile, CIOStream::Mode_e::Read))
|
||||
{
|
||||
Error(eDLL_T::RTECH, NO_ERROR, "%s: failed to open pak file '%s' for read!\n",
|
||||
__FUNCTION__, inPakFile);
|
||||
@ -817,7 +817,7 @@ bool Pak_DecodePakFile(const char* const inPakFile, const char* const outPakFile
|
||||
|
||||
CIOStream outPakStream;
|
||||
|
||||
if (!outPakStream.Open(outPakFile, CIOStream::WRITE | CIOStream::BINARY))
|
||||
if (!outPakStream.Open(outPakFile, CIOStream::Mode_e::Write))
|
||||
{
|
||||
Error(eDLL_T::RTECH, NO_ERROR, "%s: failed to open pak file '%s' for write!\n",
|
||||
__FUNCTION__, outPakFile);
|
||||
|
@ -84,7 +84,7 @@ bool Pak_EncodePakFile(const char* const inPakFile, const char* const outPakFile
|
||||
|
||||
CIOStream inPakStream;
|
||||
|
||||
if (!inPakStream.Open(inPakFile, CIOStream::READ | CIOStream::BINARY))
|
||||
if (!inPakStream.Open(inPakFile, CIOStream::Mode_e::Read))
|
||||
{
|
||||
Error(eDLL_T::RTECH, NO_ERROR, "%s: failed to open pak file '%s' for read!\n",
|
||||
__FUNCTION__, inPakFile);
|
||||
@ -94,7 +94,7 @@ bool Pak_EncodePakFile(const char* const inPakFile, const char* const outPakFile
|
||||
|
||||
CIOStream outPakStream;
|
||||
|
||||
if (!outPakStream.Open(outPakFile, CIOStream::WRITE | CIOStream::BINARY))
|
||||
if (!outPakStream.Open(outPakFile, CIOStream::Mode_e::Write))
|
||||
{
|
||||
Error(eDLL_T::RTECH, NO_ERROR, "%s: failed to open pak file '%s' for write!\n",
|
||||
__FUNCTION__, outPakFile);
|
||||
|
@ -49,16 +49,16 @@ static bool Pak_ResolveAssetDependency(const PakFile_s* const pak, PakGuid_t cur
|
||||
//-----------------------------------------------------------------------------
|
||||
// resolve guid relations for asset
|
||||
//-----------------------------------------------------------------------------
|
||||
void Pak_ResolveAssetRelations(PakFile_s* const pak, const PakAsset_s* const asset)
|
||||
static void Pak_ResolveAssetRelations(PakFile_s* const pak, const PakAsset_s* const asset)
|
||||
{
|
||||
PakPage_u* const pageDescriptors = &pak->memoryData.pageDescriptors[asset->dependenciesIndex];
|
||||
PakPage_u* const pageDescriptors = &pak->memoryData.pageDescriptors[asset->usesIndex];
|
||||
uint32_t* const guidDestriptors = (uint32_t*)g_pakGlobals->loadedPaks[pak->memoryData.pakId & PAK_MAX_LOADED_PAKS_MASK].guidDestriptors;
|
||||
|
||||
if (pak_debugrelations.GetBool())
|
||||
Msg(eDLL_T::RTECH, "Resolving relations for asset: '0x%-16llX', dependencies: %-4u; in pak '%s'\n",
|
||||
asset->guid, asset->dependenciesCount, pak->memoryData.fileName);
|
||||
asset->guid, asset->usesCount, pak->memoryData.fileName);
|
||||
|
||||
for (uint32_t i = 0; i < asset->dependenciesCount; i++)
|
||||
for (uint32_t i = 0; i < asset->usesCount; i++)
|
||||
{
|
||||
void** const pCurrentGuid = reinterpret_cast<void**>(pak->memoryData.memPageBuffers[pageDescriptors[i].index] + pageDescriptors[i].offset);
|
||||
|
||||
@ -93,7 +93,7 @@ void Pak_ResolveAssetRelations(PakFile_s* const pak, const PakAsset_s* const ass
|
||||
"pak: '%s'\n"
|
||||
"asset: '0x%llX'\n"
|
||||
"target: '0x%llX'\n",
|
||||
i, asset->dependenciesCount,
|
||||
i, asset->usesCount,
|
||||
pak->memoryData.fileName,
|
||||
asset->guid,
|
||||
targetGuid);
|
||||
@ -112,7 +112,7 @@ void Pak_ResolveAssetRelations(PakFile_s* const pak, const PakAsset_s* const ass
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t Pak_ProcessRemainingPagePointers(PakFile_s* const pak)
|
||||
static uint32_t Pak_ProcessRemainingPagePointers(PakFile_s* const pak)
|
||||
{
|
||||
uint32_t processedPointers = 0;
|
||||
|
||||
@ -134,7 +134,7 @@ uint32_t Pak_ProcessRemainingPagePointers(PakFile_s* const pak)
|
||||
return processedPointers;
|
||||
}
|
||||
|
||||
void Pak_RunAssetLoadingJobs(PakFile_s* const pak)
|
||||
static void Pak_RunAssetLoadingJobs(PakFile_s* const pak)
|
||||
{
|
||||
pak->numProcessedPointers = Pak_ProcessRemainingPagePointers(pak);
|
||||
|
||||
@ -167,7 +167,7 @@ void Pak_RunAssetLoadingJobs(PakFile_s* const pak)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_InterlockedExchangeAdd16((volatile signed __int16*)&pakAsset->numRemainingDependencies, 0xFFFFu) == 1)
|
||||
if (_InterlockedExchangeAdd16(&pakAsset->numRemainingDependencies, -1) == 1)
|
||||
Pak_ProcessAssetRelationsAndResolveDependencies(pak, pakAsset, currentAsset, assetBind);
|
||||
|
||||
_InterlockedDecrement16(&g_pakGlobals->numAssetLoadJobs);
|
||||
@ -191,7 +191,7 @@ void Pak_RunAssetLoadingJobs(PakFile_s* const pak)
|
||||
//-----------------------------------------------------------------------------
|
||||
// load user-requested pak files on-demand
|
||||
//-----------------------------------------------------------------------------
|
||||
PakHandle_t Pak_LoadAsync(const char* const fileName, CAlignedMemAlloc* const allocator, const int logChannel, const bool bUnk)
|
||||
static PakHandle_t Pak_LoadAsync(const char* const fileName, CAlignedMemAlloc* const allocator, const int logChannel, const bool bUnk)
|
||||
{
|
||||
if (!Pak_FileExists(fileName))
|
||||
{
|
||||
@ -216,7 +216,7 @@ PakHandle_t Pak_LoadAsync(const char* const fileName, CAlignedMemAlloc* const al
|
||||
//-----------------------------------------------------------------------------
|
||||
// unloads loaded pak files
|
||||
//-----------------------------------------------------------------------------
|
||||
void Pak_UnloadAsync(const PakHandle_t handle)
|
||||
static void Pak_UnloadAsync(const PakHandle_t handle)
|
||||
{
|
||||
const PakLoadedInfo_s* const pakInfo = Pak_GetPakInfo(handle);
|
||||
|
||||
@ -238,9 +238,8 @@ static const int s_patchCmdToBytesToProcess[] = { CMD_INVALID, CMD_INVALID, CMD_
|
||||
#undef CMD_INVALID
|
||||
//----------------------------------------------------------------------------------
|
||||
// loads and processes a pak file (handles decompression and patching)
|
||||
// TODO: !!! FINISH REBUILD !!!
|
||||
//----------------------------------------------------------------------------------
|
||||
bool Pak_ProcessPakFile(PakFile_s* const pak)
|
||||
static bool Pak_ProcessPakFile(PakFile_s* const pak)
|
||||
{
|
||||
PakFileStream_s* const fileStream = &pak->fileStream;
|
||||
PakMemoryData_s* const memoryData = &pak->memoryData;
|
||||
@ -522,9 +521,9 @@ bool Pak_ProcessPakFile(PakFile_s* const pak)
|
||||
return memoryData->patchSrcSize == 0;
|
||||
}
|
||||
|
||||
// sets patch variables for copying the next unprocessed page into the relevant segment buffer
|
||||
// sets patch variables for copying the next unprocessed page into the relevant slab buffer
|
||||
// if this is a header page, fetch info from the next unprocessed asset and copy over the asset's header
|
||||
bool Pak_PrepareNextPageForPatching(PakLoadedInfo_s* const loadedInfo, PakFile_s* const pak)
|
||||
static bool Pak_PrepareNextPageForPatching(PakLoadedInfo_s* const loadedInfo, PakFile_s* const pak)
|
||||
{
|
||||
Pak_RunAssetLoadingJobs(pak);
|
||||
|
||||
@ -542,7 +541,7 @@ bool Pak_PrepareNextPageForPatching(PakLoadedInfo_s* const loadedInfo, PakFile_s
|
||||
: highestProcessedPageIdx - pak->GetPageCount();
|
||||
|
||||
const PakPageHeader_s* const nextMemPageHeader = &pak->memoryData.pageHeaders[currentPageIndex];
|
||||
if ((pak->memoryData.segmentHeaders[nextMemPageHeader->segmentIdx].typeFlags & (SF_TEMP | SF_CPU)) != 0)
|
||||
if ((pak->memoryData.slabHeaders[nextMemPageHeader->slabIndex].typeFlags & (SF_CPU | SF_TEMP)) != 0)
|
||||
{
|
||||
pak->memoryData.patchSrcSize = nextMemPageHeader->dataSize;
|
||||
pak->memoryData.patchDstPtr = reinterpret_cast<char*>(pak->memoryData.memPageBuffers[currentPageIndex]);
|
||||
@ -556,13 +555,13 @@ bool Pak_PrepareNextPageForPatching(PakLoadedInfo_s* const loadedInfo, PakFile_s
|
||||
pak->memoryData.patchSrcSize = pakAsset->headerSize;
|
||||
const int assetTypeIdx = pakAsset->HashTableIndexForAssetType();
|
||||
|
||||
pak->memoryData.patchDstPtr = reinterpret_cast<char*>(loadedInfo->segmentBuffers[0]) + pak->memoryData.unkAssetTypeBindingSizes[assetTypeIdx];
|
||||
pak->memoryData.unkAssetTypeBindingSizes[assetTypeIdx] += g_pakGlobals->assetBindings[assetTypeIdx].nativeClassSize;
|
||||
pak->memoryData.patchDstPtr = reinterpret_cast<char*>(loadedInfo->slabBuffers[0]) + pak->memoryData.unkAssetTypeBindingSizes[assetTypeIdx];
|
||||
pak->memoryData.unkAssetTypeBindingSizes[assetTypeIdx] += g_pakGlobals->assetBindings[assetTypeIdx].structSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Pak_ProcessAssets(PakLoadedInfo_s* const loadedInfo)
|
||||
static bool Pak_ProcessAssets(PakLoadedInfo_s* const loadedInfo)
|
||||
{
|
||||
PakFile_s* const pak = loadedInfo->pakFile;
|
||||
|
||||
@ -593,8 +592,8 @@ bool Pak_ProcessAssets(PakLoadedInfo_s* const loadedInfo)
|
||||
if (v4 >= pageCount)
|
||||
shiftedPageIndex -= pageCount;
|
||||
|
||||
// if "temp_" segment
|
||||
if ((pak->memoryData.segmentHeaders[pak->memoryData.pageHeaders[shiftedPageIndex].segmentIdx].typeFlags & (SF_TEMP | SF_CPU)) != 0)
|
||||
// if "temp_" slab
|
||||
if ((pak->memoryData.slabHeaders[pak->memoryData.pageHeaders[shiftedPageIndex].slabIndex].typeFlags & (SF_CPU | SF_TEMP)) != 0)
|
||||
{
|
||||
if (Pak_PrepareNextPageForPatching(loadedInfo, pak))
|
||||
continue;
|
||||
@ -606,12 +605,12 @@ bool Pak_ProcessAssets(PakLoadedInfo_s* const loadedInfo)
|
||||
const uint32_t headPageOffset = asset->headPtr.offset;
|
||||
char* const v8 = pak->memoryData.patchDstPtr - asset->headerSize;
|
||||
|
||||
const uint32_t newOffsetFromSegmentBufferToHeader = LODWORD(pak->memoryData.patchDstPtr)
|
||||
const uint32_t newOffsetFromSlabBufferToHeader = LODWORD(pak->memoryData.patchDstPtr)
|
||||
- asset->headerSize
|
||||
- LODWORD(loadedInfo->segmentBuffers[0]);
|
||||
asset->headPtr.offset = newOffsetFromSegmentBufferToHeader;
|
||||
- LODWORD(loadedInfo->slabBuffers[0]);
|
||||
asset->headPtr.offset = newOffsetFromSlabBufferToHeader;
|
||||
|
||||
const uint32_t offsetSize = newOffsetFromSegmentBufferToHeader - headPageOffset;
|
||||
const uint32_t offsetSize = newOffsetFromSlabBufferToHeader - headPageOffset;
|
||||
|
||||
for (uint32_t i = pak->memoryData.numShiftedPointers; i < pak->GetPointerCount(); pak->memoryData.numShiftedPointers = i)
|
||||
{
|
||||
@ -638,9 +637,9 @@ bool Pak_ProcessAssets(PakLoadedInfo_s* const loadedInfo)
|
||||
i = pak->memoryData.numShiftedPointers + 1;
|
||||
}
|
||||
|
||||
for (uint32_t j = 0; j < asset->dependenciesCount; ++j)
|
||||
for (uint32_t j = 0; j < asset->usesCount; ++j)
|
||||
{
|
||||
PakPage_u* const descriptor = &pak->memoryData.pageDescriptors[asset->dependenciesIndex + j];
|
||||
PakPage_u* const descriptor = &pak->memoryData.pageDescriptors[asset->usesIndex + j];
|
||||
|
||||
if (descriptor->index == shiftedPageIndex)
|
||||
descriptor->offset += offsetSize;
|
||||
@ -655,9 +654,9 @@ bool Pak_ProcessAssets(PakLoadedInfo_s* const loadedInfo)
|
||||
pak->memoryData.patchSrcSize = v17->headerSize;
|
||||
const uint8_t assetTypeIdx = v17->HashTableIndexForAssetType();
|
||||
|
||||
pak->memoryData.patchDstPtr = reinterpret_cast<char*>(loadedInfo->segmentBuffers[0]) + pak->memoryData.unkAssetTypeBindingSizes[assetTypeIdx];
|
||||
pak->memoryData.patchDstPtr = reinterpret_cast<char*>(loadedInfo->slabBuffers[0]) + pak->memoryData.unkAssetTypeBindingSizes[assetTypeIdx];
|
||||
|
||||
pak->memoryData.unkAssetTypeBindingSizes[assetTypeIdx] += g_pakGlobals->assetBindings[assetTypeIdx].nativeClassSize;
|
||||
pak->memoryData.unkAssetTypeBindingSizes[assetTypeIdx] += g_pakGlobals->assetBindings[assetTypeIdx].structSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -735,7 +734,7 @@ bool Pak_ProcessAssets(PakLoadedInfo_s* const loadedInfo)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Pak_StubInvalidAssetBinds(PakFile_s* const pak, PakSegmentDescriptor_s* const desc)
|
||||
static void Pak_StubInvalidAssetBinds(PakFile_s* const pak, PakSlabDescriptor_s* const desc)
|
||||
{
|
||||
for (uint32_t i = 0; i < pak->GetAssetCount(); ++i)
|
||||
{
|
||||
@ -757,7 +756,7 @@ void Pak_StubInvalidAssetBinds(PakFile_s* const pak, PakSegmentDescriptor_s* con
|
||||
assetBinding->replaceAssetFunc = nullptr;
|
||||
assetBinding->allocator = AlignedMemAlloc();
|
||||
assetBinding->headerSize = asset->headerSize;
|
||||
assetBinding->nativeClassSize = asset->headerSize;
|
||||
assetBinding->structSize = asset->headerSize;
|
||||
assetBinding->headerAlignment = pak->memoryData.pageHeaders[asset->headPtr.index].pageAlignment;
|
||||
assetBinding->type = PakAssetBinding_s::STUB;
|
||||
}
|
||||
@ -781,16 +780,16 @@ void Pak_StubInvalidAssetBinds(PakFile_s* const pak, PakSegmentDescriptor_s* con
|
||||
}
|
||||
}
|
||||
|
||||
bool Pak_StartLoadingPak(PakLoadedInfo_s* const loadedInfo)
|
||||
static bool Pak_StartLoadingPak(PakLoadedInfo_s* const loadedInfo)
|
||||
{
|
||||
PakFile_s* const pakFile = loadedInfo->pakFile;
|
||||
|
||||
if (pakFile->memoryData.patchSrcSize && !Pak_ProcessPakFile(pakFile))
|
||||
return false;
|
||||
|
||||
PakSegmentDescriptor_s pakDescriptor = {};
|
||||
PakSlabDescriptor_s slabDesc = {};
|
||||
|
||||
Pak_StubInvalidAssetBinds(pakFile, &pakDescriptor);
|
||||
Pak_StubInvalidAssetBinds(pakFile, &slabDesc);
|
||||
|
||||
const uint32_t numAssets = pakFile->GetAssetCount();
|
||||
|
||||
@ -799,33 +798,33 @@ bool Pak_StartLoadingPak(PakLoadedInfo_s* const loadedInfo)
|
||||
|
||||
sub_140442740(pakFile->memoryData.ppAssetEntries, &pakFile->memoryData.ppAssetEntries[numAssets], numAssets, pakFile);
|
||||
|
||||
// pak must have no more than PAK_MAX_SEGMENTS segments as otherwise we will overrun the above "segmentSizes" array
|
||||
// pak must have no more than PAK_MAX_SLABS slabs as otherwise we will overrun the above "slabSizes" array
|
||||
// and write to arbitrary locations on the stack
|
||||
if (pakFile->GetSegmentCount() > PAK_MAX_SEGMENTS)
|
||||
if (pakFile->GetSlabCount() > PAK_MAX_SLABS)
|
||||
{
|
||||
Error(eDLL_T::RTECH, EXIT_FAILURE, "Too many segments in pakfile '%s'. Max %i, found %i.\n", pakFile->GetName(), PAK_MAX_SEGMENTS, pakFile->GetSegmentCount());
|
||||
Error(eDLL_T::RTECH, EXIT_FAILURE, "Too many slabs in pakfile '%s'. Max %hu, found %hu.\n", pakFile->GetName(), PAK_MAX_SLABS, pakFile->GetSlabCount());
|
||||
return false;
|
||||
}
|
||||
|
||||
Pak_AlignSegmentHeaders(pakFile, &pakDescriptor);
|
||||
Pak_AlignSegments(pakFile, &pakDescriptor);
|
||||
Pak_AlignSlabHeaders(pakFile, &slabDesc);
|
||||
Pak_AlignSlabData(pakFile, &slabDesc);
|
||||
|
||||
// allocate segment buffers with predetermined alignments; pages will be
|
||||
// allocate slab buffers with predetermined alignments; pages will be
|
||||
// copied into here
|
||||
for (int8_t i = 0; i < PAK_SEGMENT_BUFFER_TYPES; ++i)
|
||||
for (int8_t i = 0; i < PAK_SLAB_BUFFER_TYPES; ++i)
|
||||
{
|
||||
if (pakDescriptor.segmentSizeForType[i])
|
||||
loadedInfo->segmentBuffers[i] = AlignedMemAlloc()->Alloc(pakDescriptor.segmentSizeForType[i], pakDescriptor.segmentAlignmentForType[i]);
|
||||
if (slabDesc.slabSizeForType[i])
|
||||
loadedInfo->slabBuffers[i] = AlignedMemAlloc()->Alloc(slabDesc.slabSizeForType[i], slabDesc.slabAlignmentForType[i]);
|
||||
}
|
||||
|
||||
Pak_CopyPagesToSegments(pakFile, loadedInfo, &pakDescriptor);
|
||||
Pak_CopyPagesToSlabs(pakFile, loadedInfo, &slabDesc);
|
||||
|
||||
const PakFileHeader_s& pakHdr = pakFile->GetHeader();
|
||||
|
||||
if (Pak_StreamingEnabled())
|
||||
Pak_LoadStreamingData(loadedInfo);
|
||||
|
||||
const __int64 v106 = pakHdr.descriptorCount + 2 * (pakHdr.patchIndex + pakHdr.assetCount + 4ull * pakHdr.assetCount + pakHdr.virtualSegmentCount);
|
||||
const __int64 v106 = pakHdr.pointerCount + 2 * (pakHdr.patchIndex + pakHdr.assetCount + 4ull * pakHdr.assetCount + pakHdr.memSlabCount);
|
||||
const __int64 patchDestOffset = pakHdr.GetTotalHeaderSize() + 2 * (pakHdr.patchIndex + 6ull * pakHdr.memPageCount + 4 * v106);
|
||||
|
||||
pakFile->dword14 = 1;
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "rtech/ipakfile.h"
|
||||
#include "pakpatch.h"
|
||||
|
||||
bool PATCH_CMD_0(PakFile_s* const pak, size_t* const numAvailableBytes)
|
||||
static bool PATCH_CMD_0(PakFile_s* const pak, size_t* const numAvailableBytes)
|
||||
{
|
||||
unsigned __int64 m_numBytesToProcess_maybe; // r9
|
||||
unsigned __int64 v4; // rdi
|
||||
@ -83,65 +83,55 @@ bool PATCH_CMD_0(PakFile_s* const pak, size_t* const numAvailableBytes)
|
||||
return pak->memoryData.numPatchBytesToProcess == 0;
|
||||
}
|
||||
|
||||
bool PATCH_CMD_1(PakFile_s* const pak, size_t* const numAvailableBytes)
|
||||
static bool PATCH_CMD_1(PakFile_s* const pak, size_t* const pNumBytesAvailable)
|
||||
{
|
||||
unsigned __int64 m_numBytesToProcess_maybe; // r8
|
||||
size_t v3; // r9
|
||||
uint64_t m_processedPatchedDataSize; // rax
|
||||
const size_t numBytesToProcess = pak->memoryData.numPatchBytesToProcess;
|
||||
const size_t numBytesAvailable = *pNumBytesAvailable;
|
||||
const size_t processedPatchedDataSize = pak->memoryData.processedPatchedDataSize;
|
||||
|
||||
m_numBytesToProcess_maybe = pak->memoryData.numPatchBytesToProcess;
|
||||
v3 = *numAvailableBytes;
|
||||
m_processedPatchedDataSize = pak->memoryData.processedPatchedDataSize;
|
||||
|
||||
if (*numAvailableBytes > m_numBytesToProcess_maybe)
|
||||
if (*pNumBytesAvailable > numBytesToProcess)
|
||||
{
|
||||
pak->memoryData.numPatchBytesToProcess = 0i64;
|
||||
pak->memoryData.processedPatchedDataSize += m_numBytesToProcess_maybe;
|
||||
*numAvailableBytes = v3 - m_numBytesToProcess_maybe;
|
||||
pak->memoryData.numPatchBytesToProcess = 0ull;
|
||||
pak->memoryData.processedPatchedDataSize += numBytesToProcess;
|
||||
*pNumBytesAvailable = numBytesAvailable - numBytesToProcess;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pak->memoryData.processedPatchedDataSize += v3;
|
||||
pak->memoryData.numPatchBytesToProcess -= v3;
|
||||
*numAvailableBytes = NULL;
|
||||
pak->memoryData.processedPatchedDataSize += numBytesAvailable;
|
||||
pak->memoryData.numPatchBytesToProcess -= numBytesAvailable;
|
||||
*pNumBytesAvailable = NULL;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool PATCH_CMD_2(PakFile_s* const pak, size_t* const numAvailableBytes)
|
||||
static bool PATCH_CMD_2(PakFile_s* const pak, size_t* const pNumBytesAvailable)
|
||||
{
|
||||
NOTE_UNUSED(numAvailableBytes);
|
||||
NOTE_UNUSED(pNumBytesAvailable);
|
||||
|
||||
unsigned __int64 m_numBytesToProcess_maybe;
|
||||
unsigned __int64 v3;
|
||||
const char* m_patchDataPtr;
|
||||
|
||||
m_numBytesToProcess_maybe = pak->memoryData.numPatchBytesToProcess;
|
||||
v3 = pak->memoryData.field_2A8;
|
||||
size_t numBytesToProcess = pak->memoryData.numPatchBytesToProcess;
|
||||
const size_t v3 = pak->memoryData.field_2A8;
|
||||
|
||||
if (v3)
|
||||
{
|
||||
m_patchDataPtr = pak->memoryData.patchDataPtr;
|
||||
|
||||
if (m_numBytesToProcess_maybe <= v3)
|
||||
if (numBytesToProcess <= v3)
|
||||
{
|
||||
pak->memoryData.numPatchBytesToProcess = 0i64;
|
||||
pak->memoryData.patchDataPtr += m_numBytesToProcess_maybe;
|
||||
pak->memoryData.field_2A8 = v3 - m_numBytesToProcess_maybe;
|
||||
pak->memoryData.numPatchBytesToProcess = 0ull;
|
||||
pak->memoryData.patchDataPtr += numBytesToProcess;
|
||||
pak->memoryData.field_2A8 = v3 - numBytesToProcess;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pak->memoryData.field_2A8 = 0i64;
|
||||
m_numBytesToProcess_maybe -= v3;
|
||||
numBytesToProcess -= v3;
|
||||
pak->memoryData.patchDataPtr += v3;
|
||||
pak->memoryData.numPatchBytesToProcess = m_numBytesToProcess_maybe;
|
||||
pak->memoryData.numPatchBytesToProcess = numBytesToProcess;
|
||||
}
|
||||
|
||||
const size_t patchSrcSize = min(m_numBytesToProcess_maybe, pak->memoryData.patchSrcSize);
|
||||
const size_t patchSrcSize = Min(numBytesToProcess, pak->memoryData.patchSrcSize);
|
||||
|
||||
memcpy(pak->memoryData.patchDstPtr, pak->memoryData.patchDataPtr, patchSrcSize);
|
||||
|
||||
@ -153,13 +143,10 @@ bool PATCH_CMD_2(PakFile_s* const pak, size_t* const numAvailableBytes)
|
||||
return pak->memoryData.numPatchBytesToProcess == 0;
|
||||
}
|
||||
|
||||
bool PATCH_CMD_3(PakFile_s* const pak, size_t* const numAvailableBytes)
|
||||
static bool PATCH_CMD_3(PakFile_s* const pak, size_t* const pNumBytesAvailable)
|
||||
{
|
||||
size_t patchSrcSize = pak->memoryData.patchSrcSize;
|
||||
|
||||
size_t v9 = min(*numAvailableBytes, pak->memoryData.numPatchBytesToProcess);
|
||||
|
||||
patchSrcSize = min(v9, patchSrcSize);
|
||||
const size_t numBytesLeft = Min(*pNumBytesAvailable, pak->memoryData.numPatchBytesToProcess);
|
||||
const size_t patchSrcSize = Min(numBytesLeft, pak->memoryData.patchSrcSize);
|
||||
|
||||
memcpy(pak->memoryData.patchDstPtr, pak->memoryData.patchDataPtr, patchSrcSize);
|
||||
pak->memoryData.patchDataPtr += patchSrcSize;
|
||||
@ -167,15 +154,16 @@ bool PATCH_CMD_3(PakFile_s* const pak, size_t* const numAvailableBytes)
|
||||
pak->memoryData.patchSrcSize -= patchSrcSize;
|
||||
pak->memoryData.patchDstPtr += patchSrcSize;
|
||||
pak->memoryData.numPatchBytesToProcess -= patchSrcSize;
|
||||
*numAvailableBytes = *numAvailableBytes - patchSrcSize;
|
||||
*pNumBytesAvailable = *pNumBytesAvailable - patchSrcSize;
|
||||
|
||||
return pak->memoryData.numPatchBytesToProcess == 0;
|
||||
}
|
||||
|
||||
bool PATCH_CMD_4_5(PakFile_s* const pak, size_t* const numAvailableBytes)
|
||||
static bool PATCH_CMD_4_5(PakFile_s* const pak, size_t* const pNumBytesAvailable)
|
||||
{
|
||||
const size_t v2 = *numAvailableBytes;
|
||||
if (!v2)
|
||||
const size_t numBytesAvailable = *pNumBytesAvailable;
|
||||
|
||||
if (!numBytesAvailable)
|
||||
return false;
|
||||
|
||||
*pak->memoryData.patchDstPtr = *(_BYTE*)pak->memoryData.patchDataPtr++;
|
||||
@ -183,29 +171,29 @@ bool PATCH_CMD_4_5(PakFile_s* const pak, size_t* const numAvailableBytes)
|
||||
--pak->memoryData.patchSrcSize;
|
||||
++pak->memoryData.patchDstPtr;
|
||||
pak->memoryData.patchFunc = PATCH_CMD_0;
|
||||
*numAvailableBytes = v2 - 1;
|
||||
*pNumBytesAvailable = numBytesAvailable - 1;
|
||||
|
||||
return PATCH_CMD_0(pak, numAvailableBytes);
|
||||
return PATCH_CMD_0(pak, pNumBytesAvailable);
|
||||
}
|
||||
|
||||
bool PATCH_CMD_6(PakFile_s* const pak, size_t* const numAvailableBytes)
|
||||
static bool PATCH_CMD_6(PakFile_s* const pak, size_t* const pNumBytesAvailable)
|
||||
{
|
||||
const size_t v2 = *numAvailableBytes;
|
||||
size_t v3 = 2;
|
||||
const size_t numBytesAvailable = *pNumBytesAvailable;
|
||||
size_t numBytesToSkip = 2;
|
||||
|
||||
if (*numAvailableBytes < 2)
|
||||
if (*pNumBytesAvailable < 2)
|
||||
{
|
||||
if (!*numAvailableBytes)
|
||||
if (!*pNumBytesAvailable)
|
||||
return false;
|
||||
|
||||
v3 = *numAvailableBytes;
|
||||
numBytesToSkip = *pNumBytesAvailable;
|
||||
}
|
||||
|
||||
const void* const patchDataPtr = (const void*)pak->memoryData.patchDataPtr;
|
||||
const size_t patchSrcSize = pak->memoryData.patchSrcSize;
|
||||
char* const patchDstPtr = pak->memoryData.patchDstPtr;
|
||||
|
||||
if (v3 > patchSrcSize)
|
||||
if (numBytesToSkip > patchSrcSize)
|
||||
{
|
||||
memcpy(patchDstPtr, patchDataPtr, patchSrcSize);
|
||||
pak->memoryData.patchDataPtr += patchSrcSize;
|
||||
@ -213,26 +201,26 @@ bool PATCH_CMD_6(PakFile_s* const pak, size_t* const numAvailableBytes)
|
||||
pak->memoryData.patchSrcSize -= patchSrcSize;
|
||||
pak->memoryData.patchDstPtr += patchSrcSize;
|
||||
pak->memoryData.patchFunc = PATCH_CMD_4_5;
|
||||
*numAvailableBytes = v2 - patchSrcSize;
|
||||
*pNumBytesAvailable = numBytesAvailable - patchSrcSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(patchDstPtr, patchDataPtr, v3);
|
||||
pak->memoryData.patchDataPtr += v3;
|
||||
pak->memoryData.processedPatchedDataSize += v3;
|
||||
pak->memoryData.patchSrcSize -= v3;
|
||||
pak->memoryData.patchDstPtr += v3;
|
||||
memcpy(patchDstPtr, patchDataPtr, numBytesToSkip);
|
||||
pak->memoryData.patchDataPtr += numBytesToSkip;
|
||||
pak->memoryData.processedPatchedDataSize += numBytesToSkip;
|
||||
pak->memoryData.patchSrcSize -= numBytesToSkip;
|
||||
pak->memoryData.patchDstPtr += numBytesToSkip;
|
||||
|
||||
if (v2 >= 2)
|
||||
if (numBytesAvailable >= 2)
|
||||
{
|
||||
pak->memoryData.patchFunc = PATCH_CMD_0;
|
||||
*numAvailableBytes = v2 - v3;
|
||||
*pNumBytesAvailable = numBytesAvailable - numBytesToSkip;
|
||||
|
||||
return PATCH_CMD_0(pak, numAvailableBytes);
|
||||
return PATCH_CMD_0(pak, pNumBytesAvailable);
|
||||
}
|
||||
|
||||
pak->memoryData.patchFunc = PATCH_CMD_4_5;
|
||||
*numAvailableBytes = NULL;
|
||||
*pNumBytesAvailable = NULL;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -22,7 +22,7 @@ static void Pak_ListPaks_f()
|
||||
|
||||
uint32_t numLoaded = 0;
|
||||
|
||||
for (int16_t i = 0, n = g_pakGlobals->loadedPakCount; i < n; ++i)
|
||||
for (uint16_t i = 0, n = PAK_MAX_LOADED_PAKS; i < n; ++i)
|
||||
{
|
||||
const PakLoadedInfo_s& info = g_pakGlobals->loadedPaks[i];
|
||||
|
||||
@ -31,11 +31,11 @@ static void Pak_ListPaks_f()
|
||||
|
||||
const char* const pakStatus = Pak_StatusToString(info.status);
|
||||
|
||||
Msg(eDLL_T::RTECH, "| %04i | %-50s | %-36s | %11i |\n", info.handle, info.fileName, pakStatus, info.assetCount);
|
||||
Msg(eDLL_T::RTECH, "| %04i | %-50s | %-36s | %11u |\n", info.handle, info.fileName, pakStatus, info.assetCount);
|
||||
numLoaded++;
|
||||
}
|
||||
Msg(eDLL_T::RTECH, "|------|----------------------------------------------------|--------------------------------------|-------------|\n");
|
||||
Msg(eDLL_T::RTECH, "| %18i loaded paks. |\n", numLoaded);
|
||||
Msg(eDLL_T::RTECH, "| %18u loaded paks. |\n", numLoaded);
|
||||
Msg(eDLL_T::RTECH, "|------|----------------------------------------------------|--------------------------------------|-------------|\n");
|
||||
}
|
||||
|
||||
@ -46,12 +46,12 @@ Pak_ListTypes_f
|
||||
*/
|
||||
static void Pak_ListTypes_f()
|
||||
{
|
||||
Msg(eDLL_T::RTECH, "| ext | description | version | header size | native size |\n");
|
||||
Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-------------|-------------|\n");
|
||||
Msg(eDLL_T::RTECH, "| ext | description | version | alignment | header size | struct size |\n");
|
||||
Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-----------|-------------|-------------|\n");
|
||||
|
||||
uint32_t numRegistered = 0;
|
||||
|
||||
for (int8_t i = 0; i < PAK_MAX_TRACKED_TYPES; ++i)
|
||||
for (uint8_t i = 0; i < PAK_MAX_TRACKED_TYPES; ++i)
|
||||
{
|
||||
const PakAssetBinding_s& type = g_pakGlobals->assetBindings[i];
|
||||
|
||||
@ -61,12 +61,14 @@ static void Pak_ListTypes_f()
|
||||
FourCCString_t assetExtension;
|
||||
FourCCToString(assetExtension, type.extension);
|
||||
|
||||
Msg(eDLL_T::RTECH, "| %-4s | %-25s | %7i | %11i | %11i |\n", assetExtension, type.description, type.version, type.headerSize, type.nativeClassSize);
|
||||
Msg(eDLL_T::RTECH, "| %-4s | %-25s | %7u | %9u | %11u | %11u |\n",
|
||||
assetExtension, type.description, type.version, type.headerAlignment, type.headerSize, type.structSize);
|
||||
|
||||
numRegistered++;
|
||||
}
|
||||
Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-------------|-------------|\n");
|
||||
Msg(eDLL_T::RTECH, "| %18i registered types. |\n", numRegistered);
|
||||
Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-------------|-------------|\n");
|
||||
Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-----------|-------------|-------------|\n");
|
||||
Msg(eDLL_T::RTECH, "| %18u registered types. |\n", numRegistered);
|
||||
Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-----------|-------------|-------------|\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -60,8 +60,8 @@ struct PakLoadFuncs_s
|
||||
void (*HelpWithPendingRequests)();
|
||||
|
||||
// lock and wait for a specific pakfile to load by pakid, and help with other
|
||||
// allocated jobs in the mean time
|
||||
void (*WaitForAsyncLoad)(const PakHandle_t handle, void(* const finishCallback));
|
||||
// allocated jobs in the mean time. returns false if status is PAK_STATUS_ERROR
|
||||
bool (*WaitForAsyncLoad)(const PakHandle_t handle, void(* const finishCallback));
|
||||
|
||||
// lock and wait for a specific pakfile to unload by pakid, and help with other
|
||||
// allocated jobs in the mean time
|
||||
|
@ -263,7 +263,14 @@ PakLoadedInfo_s* Pak_GetPakInfo(const PakHandle_t pakId)
|
||||
//-----------------------------------------------------------------------------
|
||||
const PakLoadedInfo_s* Pak_GetPakInfo(const char* const pakName)
|
||||
{
|
||||
for (int16_t i = 0; i < g_pakGlobals->loadedPakCount; ++i)
|
||||
// a pak under the same name can be loaded more than once, the hotswap
|
||||
// system just switches the asset pointers to the new 'live' pak if
|
||||
// there are assets that overlap the ones in the previous pak. we want
|
||||
// to find the most recently loaded pak under the provided name and
|
||||
// return that to the caller. the higher the handle, the newer it is.
|
||||
PakHandle_t highestHandle = PAK_INVALID_HANDLE;
|
||||
|
||||
for (uint16_t i = 0; i < PAK_MAX_LOADED_PAKS; ++i)
|
||||
{
|
||||
const PakLoadedInfo_s* const info = &g_pakGlobals->loadedPaks[i];
|
||||
if (!info)
|
||||
@ -275,11 +282,17 @@ const PakLoadedInfo_s* Pak_GetPakInfo(const char* const pakName)
|
||||
if (strcmp(pakName, info->fileName) != 0)
|
||||
continue;
|
||||
|
||||
return info;
|
||||
if (info->handle > highestHandle)
|
||||
highestHandle = info->handle;
|
||||
}
|
||||
|
||||
DevWarning(eDLL_T::RTECH, "%s - Failed to retrieve pak info for name '%s'\n", __FUNCTION__, pakName);
|
||||
return nullptr;
|
||||
if (highestHandle == PAK_INVALID_HANDLE)
|
||||
{
|
||||
DevWarning(eDLL_T::RTECH, "%s - Failed to retrieve pak info for name '%s'\n", __FUNCTION__, pakName);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Pak_GetPakInfo(highestHandle);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -287,7 +300,7 @@ const PakLoadedInfo_s* Pak_GetPakInfo(const char* const pakName)
|
||||
//-----------------------------------------------------------------------------
|
||||
PakPatchDataHeader_s* Pak_GetPatchDataHeader(PakFileHeader_s* const pakHeader)
|
||||
{
|
||||
// shouldn't be called if the pak doesn1't have patches!
|
||||
// shouldn't be called if the pak doesn't have patches!
|
||||
assert(pakHeader->patchIndex > 0);
|
||||
return reinterpret_cast<PakPatchDataHeader_s*>(reinterpret_cast<uint8_t* const>(pakHeader) + sizeof(PakFileHeader_s));
|
||||
}
|
||||
@ -365,7 +378,7 @@ bool Pak_UpdatePatchHeaders(uint8_t* const inBuf, const char* const outPakFile)
|
||||
|
||||
// unable to open patch while there should be one, we must calculate
|
||||
// new file sizes here, or else the runtime would fail to load them
|
||||
if (!inPatch.Open(patchFile, CIOStream::READ | CIOStream::BINARY))
|
||||
if (!inPatch.Open(patchFile, CIOStream::Mode_e::Read))
|
||||
return false;
|
||||
|
||||
const size_t fileSize = inPatch.GetSize();
|
||||
|
@ -104,7 +104,7 @@ void CSurface::Init()
|
||||
this->m_PlaylistLabel->SetSize({ 50, 25 });
|
||||
this->m_PlaylistLabel->SetLocation({ 365, 53 });
|
||||
this->m_PlaylistLabel->SetTabIndex(0);
|
||||
this->m_PlaylistLabel->SetText("Playlist");
|
||||
this->m_PlaylistLabel->SetText("Mode");
|
||||
this->m_PlaylistLabel->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
this->m_PlaylistLabel->SetTextAlign(Drawing::ContentAlignment::TopLeft);
|
||||
this->m_GameGroup->AddControl(this->m_PlaylistLabel);
|
||||
@ -871,7 +871,7 @@ void CSurface::ReloadPlaylists(Forms::Control* pSender)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSurface::AddLog(const LogType_t type, const char* const pszText)
|
||||
{
|
||||
m_LogList.push_back(LogList_t(type, pszText));
|
||||
m_LogList.emplace_back(type, pszText);
|
||||
|
||||
// Clamp the log list size, as we cannot fit more elements than
|
||||
// 8 in the console window.
|
||||
|
@ -303,7 +303,7 @@ void CLauncher::SetupLaunchContext(const char* szConfig, const char* szGameDll,
|
||||
{
|
||||
cfgFileName.Format(GAME_CFG_PATH"%s", szConfig);
|
||||
|
||||
if (cfgFile.Open(cfgFileName.String(), CIOStream::READ))
|
||||
if (cfgFile.Open(cfgFileName.String(), CIOStream::Mode_e::Read))
|
||||
{
|
||||
if (!cfgFile.ReadString(commandLine.Access(), commandLine.GetMaxLength()))
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user