Compare commits

..

No commits in common. "p4sync" and "v2.5_rc5_event" have entirely different histories.

122 changed files with 1642 additions and 3124 deletions

View File

@ -12,6 +12,7 @@ set( FOLDER_CONTEXT "Libraries" )
add_subdirectory( mathlib ) add_subdirectory( mathlib )
add_subdirectory( vpklib ) add_subdirectory( vpklib )
add_subdirectory( vstdlib ) add_subdirectory( vstdlib )
add_subdirectory( vphysics )
add_subdirectory( ebisusdk ) add_subdirectory( ebisusdk )
add_subdirectory( codecs ) add_subdirectory( codecs )
add_subdirectory( geforce ) add_subdirectory( geforce )
@ -67,9 +68,7 @@ add_subdirectory( inputsystem )
add_subdirectory( filesystem ) add_subdirectory( filesystem )
add_subdirectory( datacache ) add_subdirectory( datacache )
add_subdirectory( studiorender ) add_subdirectory( studiorender )
add_subdirectory( particles )
add_subdirectory( localize ) add_subdirectory( localize )
add_subdirectory( vphysics )
add_subdirectory( engine ) add_subdirectory( engine )
add_subdirectory( vguimatsurface ) add_subdirectory( vguimatsurface )
add_subdirectory( vgui ) add_subdirectory( vgui )

View File

@ -117,6 +117,6 @@ void MilesCore::Detour(const bool bAttach) const
DetourSetup(&v_AIL_LogFunc, &AIL_LogFunc, bAttach); DetourSetup(&v_AIL_LogFunc, &AIL_LogFunc, bAttach);
DetourSetup(&v_Miles_Initialize, &Miles_Initialize, bAttach); DetourSetup(&v_Miles_Initialize, &Miles_Initialize, bAttach);
DetourSetup(&v_MilesQueueEventRun, &MilesQueueEventRun, bAttach); DetourSetup(&v_MilesQueueEventRun, &MilesQueueEventRun, bAttach);
//DetourSetup(&v_MilesBankPatch, &MilesBankPatch, bAttach); DetourSetup(&v_MilesBankPatch, &MilesBankPatch, bAttach);
DetourSetup(&v_CSOM_AddEventToQueue, &CSOM_AddEventToQueue, bAttach); DetourSetup(&v_CSOM_AddEventToQueue, &CSOM_AddEventToQueue, bAttach);
} }

View File

@ -287,59 +287,61 @@ Mat_CrossHair_f
Print the material under the crosshair. 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) void Mat_CrossHair_f(const CCommand& args)
{ {
const CMaterialGlue* const materialGlue = v_GetMaterialAtCrossHair(); 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);
if (!materialGlue) 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
{ {
Msg(eDLL_T::MS, "%s: No material found >:(\n", __FUNCTION__); 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");
} }
/* /*

View File

@ -57,7 +57,6 @@ ConVar* r_visualizetraces_duration = nullptr;
ConVar* stream_overlay = nullptr; ConVar* stream_overlay = nullptr;
ConVar* stream_overlay_mode = nullptr; ConVar* stream_overlay_mode = nullptr;
ConVar* gpu_driven_tex_stream = nullptr;
ConVar* eula_version = nullptr; ConVar* eula_version = nullptr;
ConVar* eula_version_accepted = nullptr; ConVar* eula_version_accepted = nullptr;
@ -187,11 +186,8 @@ void ConVar_InitShipped(void)
#endif // !DEDICATED #endif // !DEDICATED
staticProp_no_fade_scalar = g_pCVar->FindVar("staticProp_no_fade_scalar"); staticProp_no_fade_scalar = g_pCVar->FindVar("staticProp_no_fade_scalar");
staticProp_gather_size_weight = g_pCVar->FindVar("staticProp_gather_size_weight"); staticProp_gather_size_weight = g_pCVar->FindVar("staticProp_gather_size_weight");
#ifndef DEDICATED
stream_overlay = g_pCVar->FindVar("stream_overlay"); stream_overlay = g_pCVar->FindVar("stream_overlay");
stream_overlay_mode = g_pCVar->FindVar("stream_overlay_mode"); 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_cheats = g_pCVar->FindVar("sv_cheats");
sv_visualizetraces = g_pCVar->FindVar("sv_visualizetraces"); sv_visualizetraces = g_pCVar->FindVar("sv_visualizetraces");
sv_visualizetraces_duration = g_pCVar->FindVar("sv_visualizetraces_duration"); sv_visualizetraces_duration = g_pCVar->FindVar("sv_visualizetraces_duration");

View File

@ -39,11 +39,10 @@ extern ConVar* mp_gamemode;
#ifndef DEDICATED #ifndef DEDICATED
extern ConVar* r_visualizetraces; extern ConVar* r_visualizetraces;
extern ConVar* r_visualizetraces_duration; extern ConVar* r_visualizetraces_duration;
#endif // !DEDICATED
extern ConVar* stream_overlay; extern ConVar* stream_overlay;
extern ConVar* stream_overlay_mode; extern ConVar* stream_overlay_mode;
extern ConVar* gpu_driven_tex_stream;
#endif // !DEDICATED
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// SHARED | // SHARED |
extern ConVar* eula_version; extern ConVar* eula_version;

View File

@ -4,11 +4,10 @@
// //
//===========================================================================// //===========================================================================//
#pragma once #pragma once
#include "netcon/INetCon.h"
typedef int SocketHandle_t; typedef int SocketHandle_t;
enum class ServerDataRequestType_e : int enum class ServerDataRequestType_t : int
{ {
SERVERDATA_REQUEST_VALUE = 0, SERVERDATA_REQUEST_VALUE = 0,
SERVERDATA_REQUEST_SETVALUE, SERVERDATA_REQUEST_SETVALUE,
@ -18,7 +17,7 @@ enum class ServerDataRequestType_e : int
SERVERDATA_REQUEST_SEND_REMOTEBUG, SERVERDATA_REQUEST_SEND_REMOTEBUG,
}; };
enum class ServerDataResponseType_e : int enum class ServerDataResponseType_t : int
{ {
SERVERDATA_RESPONSE_VALUE = 0, SERVERDATA_RESPONSE_VALUE = 0,
SERVERDATA_RESPONSE_UPDATE, SERVERDATA_RESPONSE_UPDATE,
@ -28,20 +27,20 @@ enum class ServerDataResponseType_e : int
SERVERDATA_RESPONSE_REMOTEBUG, SERVERDATA_RESPONSE_REMOTEBUG,
}; };
struct ConnectedNetConsoleData_s class CConnectedNetConsoleData
{ {
public:
SocketHandle_t m_hSocket; SocketHandle_t m_hSocket;
u32 m_nPayloadLen; // Num bytes for this message. int m_nPayloadLen; // Num bytes for this message.
u32 m_nPayloadRead; // Num read bytes from input buffer. int m_nPayloadRead; // Num read bytes from input buffer.
u32 m_nFailedAttempts; // Num failed authentication attempts. int m_nFailedAttempts; // Num failed authentication attempts.
u32 m_nIgnoredMessage; // Count how many times client ignored the no-auth message. int m_nIgnoredMessage; // Count how many times client ignored the no-auth message.
bool m_bValidated; // Revalidates netconsole if false. bool m_bValidated; // Revalidates netconsole if false.
bool m_bAuthorized; // Set to true after successful netconsole auth. bool m_bAuthorized; // Set to true after successful netconsole auth.
bool m_bInputOnly; // If set, don't send spew to this netconsole. bool m_bInputOnly; // If set, don't send spew to this netconsole.
NetConFrameHeader_s m_FrameHeader; // Current frame header. vector<uint8_t> m_RecvBuffer;
vector<byte> m_RecvBuffer;
ConnectedNetConsoleData_s(SocketHandle_t hSocket = -1) CConnectedNetConsoleData(SocketHandle_t hSocket = -1)
{ {
m_hSocket = hSocket; m_hSocket = hSocket;
m_nPayloadLen = 0; m_nPayloadLen = 0;
@ -51,19 +50,22 @@ struct ConnectedNetConsoleData_s
m_bValidated = false; m_bValidated = false;
m_bAuthorized = false; m_bAuthorized = false;
m_bInputOnly = true; m_bInputOnly = true;
m_FrameHeader.magic = 0; m_RecvBuffer.resize(sizeof(u_long)); // Reserve enough for length-prefix.
m_FrameHeader.length = 0;
} }
}; };
/* PACKET FORMAT ********************************** /* PACKET FORMAT **********************************
REQUEST: REQUEST:
NetConFrameHeader_s header; int requestID;
byte* data; int ServerDataRequestType_t;
NullTerminatedString (variable or command)
NullTerminatedString (value)
RESPONSE: RESPONSE:
NetConFrameHeader_s header; int requestID;
byte* data; int ServerDataResponseType_t;
NullTerminatedString (variable)
NullTerminatedString (value)
***************************************************/ ***************************************************/

View File

@ -70,24 +70,24 @@ bool SVC_UserMessage::ProcessImpl()
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
bool SVC_SetClassVar::ReadFromBuffer(bf_read* buffer) bool SVC_SetClassVar::ReadFromBuffer(bf_read* buffer)
{ {
const bool key = buffer->ReadString(m_szKey, sizeof(m_szKey)); const bool set = buffer->ReadString(m_szSetting, sizeof(m_szSetting));
const bool val = buffer->ReadString(m_szValue, sizeof(m_szValue)); const bool var = buffer->ReadString(m_szVariable, sizeof(m_szVariable));
return key && val; return set && var;
} }
bool SVC_SetClassVar::WriteToBuffer(bf_write* buffer) bool SVC_SetClassVar::WriteToBuffer(bf_write* buffer)
{ {
const bool key = buffer->WriteString(m_szKey); const bool set = buffer->WriteString(m_szSetting);
const bool val = buffer->WriteString(m_szValue); const bool var = buffer->WriteString(m_szVariable);
return key && val; return set && var;
} }
bool SVC_SetClassVar::Process(void) bool SVC_SetClassVar::Process(void)
{ {
const char* pArgs[3] = { const char* pArgs[3] = {
"_setClassVarClient", "_setClassVarClient",
m_szKey, m_szSetting,
m_szValue m_szVariable
}; };
CCommand command((int)V_ARRAYSIZE(pArgs), pArgs, cmd_source_t::kCommandSrcCode); CCommand command((int)V_ARRAYSIZE(pArgs), pArgs, cmd_source_t::kCommandSrcCode);

View File

@ -464,13 +464,13 @@ class SVC_SetClassVar : public CNetMessage
{ {
public: public:
SVC_SetClassVar() = default; SVC_SetClassVar() = default;
SVC_SetClassVar(const char* key, const char* value) SVC_SetClassVar(const char* setting, const char* var)
{ {
V_strncpy(m_szKey, key, sizeof(m_szKey)); V_strncpy(m_szSetting, setting, sizeof(m_szSetting));
V_strncpy(m_szValue, value, sizeof(m_szValue)); V_strncpy(m_szVariable, var, sizeof(m_szVariable));
m_szKey[sizeof(m_szKey) - 1] = '\0'; m_szSetting[sizeof(m_szSetting) - 1] = '\0';
m_szValue[sizeof(m_szValue) - 1] = '\0'; m_szVariable[sizeof(m_szVariable) - 1] = '\0';
m_nGroup = 2; // must be set to 2 to avoid being copied into replay buffer 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 virtual const char* ToString(void) const
{ {
static char szBuf[4096]; static char szBuf[4096];
V_snprintf(szBuf, sizeof(szBuf), "%s: key \"%s\", value \"%s\"", this->GetName(), m_szKey, m_szValue); V_snprintf(szBuf, sizeof(szBuf), "%s: setting \"%s\", variable \"%s\"", this->GetName(), m_szSetting, m_szVariable);
return szBuf; return szBuf;
}; };
virtual size_t GetSize(void) const { return sizeof(SVC_SetClassVar); } virtual size_t GetSize(void) const { return sizeof(SVC_SetClassVar); }
char m_szKey[128]; char m_szSetting[128];
char m_szValue[128]; char m_szVariable[128];
}; };
/////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////

View File

@ -113,8 +113,6 @@ target_link_libraries( ${PROJECT_NAME} PRIVATE
"vgui" "vgui"
"rui" "rui"
"particles"
"d3d11.lib" "d3d11.lib"
"${THIRDPARTY_SOURCE_DIR}/nvapi/amd64/nvapi64.lib" "${THIRDPARTY_SOURCE_DIR}/nvapi/amd64/nvapi64.lib"
) )

View File

@ -58,8 +58,8 @@ void Show_Emblem()
// Log the SDK's 'build_id' under the emblem. // Log the SDK's 'build_id' under the emblem.
Msg(eDLL_T::SYSTEM_ERROR, Msg(eDLL_T::SYSTEM_ERROR,
"+------------------------------------------------[%s%010u%s]-+\n", "+------------------------------------------------[%s%010d%s]-+\n",
g_svYellowF.c_str(), g_SDKDll.GetNTHeaders()->FileHeader.TimeDateStamp, g_svRedF.c_str()); g_svYellowF, g_SDKDll.GetNTHeaders()->FileHeader.TimeDateStamp, g_svRedF);
Msg(eDLL_T::SYSTEM_ERROR, "\n"); Msg(eDLL_T::SYSTEM_ERROR, "\n");
} }

View File

@ -44,13 +44,11 @@
#include "materialsystem/cmaterialsystem.h" #include "materialsystem/cmaterialsystem.h"
#ifndef DEDICATED #ifndef DEDICATED
#include "materialsystem/cmaterialglue.h" #include "materialsystem/cmaterialglue.h"
#include "materialsystem/texturestreaming.h"
#include "vgui/vgui_baseui_interface.h" #include "vgui/vgui_baseui_interface.h"
#include "vgui/vgui_debugpanel.h" #include "vgui/vgui_debugpanel.h"
#include "vgui/vgui_fpspanel.h" #include "vgui/vgui_fpspanel.h"
#include "vgui/vgui_controls/RichText.h" #include "vgui/vgui_controls/RichText.h"
#include "vguimatsurface/MatSystemSurface.h" #include "vguimatsurface/MatSystemSurface.h"
#include "particles/particles.h"
#include "engine/client/vengineclient_impl.h" #include "engine/client/vengineclient_impl.h"
#include "engine/client/cdll_engine_int.h" #include "engine/client/cdll_engine_int.h"
#include "engine/client/datablock_receiver.h" #include "engine/client/datablock_receiver.h"
@ -563,7 +561,6 @@ void DetourRegister() // Register detour classes to be searched and hooked.
#ifndef DEDICATED #ifndef DEDICATED
REGISTER(VMaterialGlue); REGISTER(VMaterialGlue);
REGISTER(VShaderGlue); REGISTER(VShaderGlue);
REGISTER(VTextureStreaming);
// Studio // Studio
REGISTER(VStudioRenderContext); REGISTER(VStudioRenderContext);
@ -574,9 +571,6 @@ void DetourRegister() // Register detour classes to be searched and hooked.
REGISTER(VVGUIRichText); // REGISTER CLIENT ONLY! REGISTER(VVGUIRichText); // REGISTER CLIENT ONLY!
REGISTER(VMatSystemSurface); REGISTER(VMatSystemSurface);
// Particles
REGISTER(VParticles);
// Client // Client
REGISTER(HVEngineClient); REGISTER(HVEngineClient);
REGISTER(VDll_Engine_Int); REGISTER(VDll_Engine_Int);

View File

@ -2,8 +2,13 @@
#include "core/logdef.h" #include "core/logdef.h"
std::shared_ptr<spdlog::logger> g_TermLogger; std::shared_ptr<spdlog::logger> g_TermLogger;
std::shared_ptr<spdlog::logger> g_ImGuiLogger;
std::shared_ptr<spdlog::logger> g_SuppementalToolsLogger; std::shared_ptr<spdlog::logger> g_SuppementalToolsLogger;
std::ostringstream g_LogStream;
std::shared_ptr<spdlog::sinks::ostream_sink_st> g_LogSink;
#ifndef _TOOLS #ifndef _TOOLS
static void SpdLog_CreateRotatingLoggers() static void SpdLog_CreateRotatingLoggers()
{ {
@ -63,6 +68,16 @@ void SpdLog_Init(const bool bAnsiColor)
} }
g_LogSessionDirectory = fmt::format("platform/logs/{:s}", g_LogSessionUUID); 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 #endif // !_TOOLS
/************************ /************************
* WINDOWS LOGGER SETUP * * WINDOWS LOGGER SETUP *
@ -84,6 +99,7 @@ void SpdLog_Init(const bool bAnsiColor)
{ {
g_TermLogger->set_pattern("%v"); g_TermLogger->set_pattern("%v");
} }
//g_TermLogger->set_level(spdlog::level::trace);
} }
#ifndef _TOOLS #ifndef _TOOLS

View File

@ -22,6 +22,11 @@ extern std::shared_ptr<spdlog::logger> g_ImGuiLogger;
extern std::shared_ptr<spdlog::logger> g_SuppementalToolsLogger; extern std::shared_ptr<spdlog::logger> g_SuppementalToolsLogger;
#endif // _TOOLS #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_Init(const bool bAnsiColor);
void SpdLog_Shutdown(void); void SpdLog_Shutdown(void);

View File

@ -72,24 +72,21 @@ ImVec4 GetColorForContext(LogType_t type, eDLL_T context)
} }
#endif // !DEDICATED && !_TOOLS #endif // !DEDICATED && !_TOOLS
static const char* GetContextNameByIndex(eDLL_T context, size_t& numTotalChars, size_t& numAnsiChars, const bool ansiColor) const char* GetContextNameByIndex(eDLL_T context, const bool ansiColor = false)
{ {
const int index = static_cast<int>(context); int index = static_cast<int>(context);
const char* contextName; const char* contextName = s_DefaultAnsiColor;
switch (context) switch (context)
{ {
case eDLL_T::SCRIPT_SERVER: case eDLL_T::SCRIPT_SERVER:
contextName = s_ScriptAnsiColor[0]; contextName = s_ScriptAnsiColor[0];
numTotalChars = s_FullAnsiContextPrefixTextSize;
break; break;
case eDLL_T::SCRIPT_CLIENT: case eDLL_T::SCRIPT_CLIENT:
contextName = s_ScriptAnsiColor[1]; contextName = s_ScriptAnsiColor[1];
numTotalChars = s_FullAnsiContextPrefixTextSize;
break; break;
case eDLL_T::SCRIPT_UI: case eDLL_T::SCRIPT_UI:
contextName = s_ScriptAnsiColor[2]; contextName = s_ScriptAnsiColor[2];
numTotalChars = s_FullAnsiContextPrefixTextSize;
break; break;
case eDLL_T::SERVER: case eDLL_T::SERVER:
case eDLL_T::CLIENT: case eDLL_T::CLIENT:
@ -105,22 +102,17 @@ static const char* GetContextNameByIndex(eDLL_T context, size_t& numTotalChars,
case eDLL_T::SYSTEM_WARNING: case eDLL_T::SYSTEM_WARNING:
case eDLL_T::SYSTEM_ERROR: case eDLL_T::SYSTEM_ERROR:
contextName = s_DllAnsiColor[index]; contextName = s_DllAnsiColor[index];
numTotalChars = context >= eDLL_T::COMMON ? s_AnsiColorTextSize : s_FullAnsiContextPrefixTextSize;
break; break;
case eDLL_T::NONE:
default: default:
contextName = s_DefaultAnsiColor;
numTotalChars = s_AnsiColorTextSize;
break; break;
} }
if (!ansiColor) if (!ansiColor)
{ {
// Shift # chars to skip ANSI row. // Shift # chars to skip ANSI row.
contextName += s_AnsiColorTextSize; contextName += sizeof(s_DefaultAnsiColor) - 1;
numTotalChars -= s_AnsiColorTextSize;
} }
else
numAnsiChars = s_AnsiColorTextSize;
return contextName; return contextName;
} }
@ -155,16 +147,11 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
const char* pszUpTime = pszUptimeOverride ? pszUptimeOverride : Plat_GetProcessUpTime(); const char* pszUpTime = pszUptimeOverride ? pszUptimeOverride : Plat_GetProcessUpTime();
string message(pszUpTime); string message(pszUpTime);
const size_t contextTextStartIndex = message.length();
const bool bToConsole = (logLevel >= LogLevel_t::LEVEL_CONSOLE); const bool bToConsole = (logLevel >= LogLevel_t::LEVEL_CONSOLE);
const bool bUseColor = (bToConsole && g_bSpdLog_UseAnsiClr); const bool bUseColor = (bToConsole && g_bSpdLog_UseAnsiClr);
size_t numTotalContextTextChars = 0; const char* pszContext = GetContextNameByIndex(context, bUseColor);
size_t numAnsiContextChars = 0; message.append(pszContext);
const char* pszContext = GetContextNameByIndex(context, numTotalContextTextChars, numAnsiContextChars, bUseColor);
message.append(pszContext, numTotalContextTextChars);
#if !defined (DEDICATED) && !defined (_TOOLS) #if !defined (DEDICATED) && !defined (_TOOLS)
ImVec4 overlayColor = GetColorForContext(logType, context); ImVec4 overlayColor = GetColorForContext(logType, context);
@ -179,9 +166,6 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
NOTE_UNUSED(pszLogger); NOTE_UNUSED(pszLogger);
#endif // !_TOOLS #endif // !_TOOLS
const size_t messageTextStartIndex = message.length();
size_t numMessageAnsiChars = 0;
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Setup logger and context // Setup logger and context
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -194,7 +178,6 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
if (bUseColor) if (bUseColor)
{ {
message.append(g_svYellowF); message.append(g_svYellowF);
numMessageAnsiChars = g_svYellowF.length();
} }
break; break;
case LogType_t::LOG_ERROR: case LogType_t::LOG_ERROR:
@ -204,7 +187,6 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
if (bUseColor) if (bUseColor)
{ {
message.append(g_svRedF); message.append(g_svRedF);
numMessageAnsiChars = g_svRedF.length();
} }
break; break;
#ifndef _TOOLS #ifndef _TOOLS
@ -266,28 +248,12 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
if (bUseColor) if (bUseColor)
{ {
if (logType != LogType_t::LOG_ERROR) message.append(g_svRedF);
{
if (numMessageAnsiChars > 0)
message.replace(messageTextStartIndex, numMessageAnsiChars, g_svRedF);
else
message.append(g_svRedF);
numMessageAnsiChars = g_svRedF.length();
}
} }
} }
else if (bUseColor && bWarning) else if (bUseColor && bWarning)
{ {
if (logType != LogType_t::LOG_ERROR) message.append(g_svYellowF);
{
if (numMessageAnsiChars > 0)
message.replace(messageTextStartIndex, numMessageAnsiChars, g_svYellowF);
else
message.append(g_svYellowF);
numMessageAnsiChars = g_svYellowF.length();
}
} }
} }
#endif // !_TOOLS #endif // !_TOOLS
@ -301,24 +267,9 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
{ {
g_TermLogger->debug(message); g_TermLogger->debug(message);
// Remove ANSI rows if we have them, before emitting to file or over wire.
if (bUseColor) if (bUseColor)
{ {
// Start with the message first because else the indices will shift. // Remove ANSI rows before emitting to file or over wire.
// 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, ""); message = std::regex_replace(message, s_AnsiRowRegex, "");
} }
} }
@ -331,32 +282,38 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
// Output is always logged to the file. // Output is always logged to the file.
std::shared_ptr<spdlog::logger> ntlogger = spdlog::get(pszLogger); // <-- Obtain by 'pszLogger'. std::shared_ptr<spdlog::logger> ntlogger = spdlog::get(pszLogger); // <-- Obtain by 'pszLogger'.
assert(ntlogger.get() != nullptr); assert(ntlogger.get() != nullptr);
ntlogger->debug(message);
if (ntlogger)
ntlogger->debug(message);
if (bToConsole) if (bToConsole)
{ {
#ifndef CLIENT_DLL #ifndef CLIENT_DLL
if (!LoggedFromClient(context) && RCONServer()->ShouldSend(netcon::response_e::SERVERDATA_RESPONSE_CONSOLE_LOG)) if (!LoggedFromClient(context) && RCONServer()->ShouldSend(netcon::response_e::SERVERDATA_RESPONSE_CONSOLE_LOG))
{ {
RCONServer()->SendEncoded(formatted.c_str(), formatted.length(), pszUpTime, contextTextStartIndex, netcon::response_e::SERVERDATA_RESPONSE_CONSOLE_LOG, RCONServer()->SendEncoded(formatted.c_str(), pszUpTime, netcon::response_e::SERVERDATA_RESPONSE_CONSOLE_LOG,
int(context), int(logType)); int(context), int(logType));
} }
#endif // !CLIENT_DLL #endif // !CLIENT_DLL
#ifndef DEDICATED #ifndef DEDICATED
g_Console.AddLog(message.c_str(), ImGui::ColorConvertFloat4ToU32(overlayColor)); g_ImGuiLogger->debug(message);
const string logStreamBuf = g_LogStream.str();
g_Console.AddLog(logStreamBuf.c_str(), ImGui::ColorConvertFloat4ToU32(overlayColor));
// We can only log to the in-game overlay console when the SDK has // We can only log to the in-game overlay console when the SDK has
// been fully initialized, due to the use of ConVar's. // been fully initialized, due to the use of ConVar's.
if (g_bSdkInitialized && logLevel >= LogLevel_t::LEVEL_NOTIFY) if (g_bSdkInitialized && logLevel >= LogLevel_t::LEVEL_NOTIFY)
{ {
// Draw to mini console. // Draw to mini console.
g_TextOverlay.AddLog(overlayContext, message.c_str(), (ssize_t)message.length()); g_TextOverlay.AddLog(overlayContext, logStreamBuf.c_str());
} }
#endif // !DEDICATED #endif // !DEDICATED
} }
#ifndef DEDICATED
g_LogStream.str(string());
g_LogStream.clear();
#endif // !DEDICATED
#else #else
if (g_SuppementalToolsLogger) if (g_SuppementalToolsLogger)
{ {

View File

@ -47,7 +47,6 @@
#include <set> #include <set>
#include <unordered_set> #include <unordered_set>
#include <functional> #include <functional>
#include <charconv>
#include <smmintrin.h> #include <smmintrin.h>

View File

@ -25,24 +25,6 @@
#include "thirdparty/curl/include/curl/curl.h" #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/document.h"
#include "rapidjson/writer.h" #include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h" #include "rapidjson/stringbuffer.h"

View File

@ -1,19 +1,19 @@
#include "core/stdafx.h" #include "core/stdafx.h"
#include "core/termutil.h" #include "core/termutil.h"
std::string g_svGreyF; const char* g_svGreyF = "";
std::string g_svRedF; const char* g_svRedF = "";
std::string g_svGreenF; const char* g_svGreenF = "";
std::string g_svBlueF; const char* g_svBlueF = "";
std::string g_svYellowF; const char* g_svYellowF = "";
std::string g_svGreyB; const char* g_svGreyB = "";
std::string g_svRedB; const char* g_svRedB = "";
std::string g_svGreenB; const char* g_svGreenB = "";
std::string g_svBlueB; const char* g_svBlueB = "";
std::string g_svYellowB; const char* g_svYellowB = "";
std::string g_svReset; const char* g_svReset = "";
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: sets the global ansi escape sequences. // Purpose: sets the global ansi escape sequences.

View File

@ -1,16 +1,16 @@
#pragma once #pragma once
extern std::string g_svGreyF; extern const char* g_svGreyF;
extern std::string g_svRedF; extern const char* g_svRedF;
extern std::string g_svGreenF; extern const char* g_svGreenF;
extern std::string g_svBlueF; extern const char* g_svBlueF;
extern std::string g_svYellowF; extern const char* g_svYellowF;
extern std::string g_svGreyB; extern const char* g_svGreyB;
extern std::string g_svRedB; extern const char* g_svRedB;
extern std::string g_svGreenB; extern const char* g_svGreenB;
extern std::string g_svBlueB; extern const char* g_svBlueB;
extern std::string g_svYellowB; extern const char* g_svYellowB;
extern std::string g_svReset; extern const char* g_svReset;
void AnsiColors_Init(); void AnsiColors_Init();

View File

@ -162,8 +162,6 @@ add_sources( SOURCE_GROUP "GameUI"
"${ENGINE_SOURCE_DIR}/gameui/IBrowser.h" "${ENGINE_SOURCE_DIR}/gameui/IBrowser.h"
"${ENGINE_SOURCE_DIR}/gameui/IConsole.cpp" "${ENGINE_SOURCE_DIR}/gameui/IConsole.cpp"
"${ENGINE_SOURCE_DIR}/gameui/IConsole.h" "${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.cpp"
"${ENGINE_SOURCE_DIR}/gameui/imgui_system.h" "${ENGINE_SOURCE_DIR}/gameui/imgui_system.h"
@ -229,8 +227,6 @@ add_sources( SOURCE_GROUP "Public"
"${ENGINE_SOURCE_DIR}/public/networkvar.h" "${ENGINE_SOURCE_DIR}/public/networkvar.h"
"${ENGINE_SOURCE_DIR}/public/playerstate.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. # These probably need to go to 'bsplib' if we ever create that project.
"${ENGINE_SOURCE_DIR}/public/bspflags.h" "${ENGINE_SOURCE_DIR}/public/bspflags.h"
"${ENGINE_SOURCE_DIR}/public/bspfile.h" "${ENGINE_SOURCE_DIR}/public/bspfile.h"

View File

@ -73,7 +73,7 @@ void CRConClient::RunFrame(void)
{ {
if (IsInitialized() && IsConnected()) if (IsInitialized() && IsConnected())
{ {
ConnectedNetConsoleData_s* pData = GetData(); CConnectedNetConsoleData* pData = GetData();
Assert(pData != nullptr); Assert(pData != nullptr);
if (pData) if (pData)
@ -105,7 +105,7 @@ void CRConClient::Disconnect(const char* szReason)
// Input : *pMsgBug - // Input : *pMsgBug -
// nMsgLen - // nMsgLen -
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CRConClient::ProcessMessage(const byte* const pMsgBuf, const u32 nMsgLen) bool CRConClient::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
{ {
netcon::response response; 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. // sending logs will cause the print func to get called recursively forever.
Assert(!(bWantLog && IsRemoteLocal())); Assert(!(bWantLog && IsRemoteLocal()));
const char* const szEnable = bWantLog ? "1" : "0"; const char* szEnable = bWantLog ? "1" : "0";
const SocketHandle_t hSocket = GetSocket(); const SocketHandle_t hSocket = GetSocket();
vector<byte> vecMsg; vector<char> vecMsg;
const bool ret = Serialize(vecMsg, "", 0, szEnable, 1, netcon::request_e::SERVERDATA_REQUEST_SEND_CONSOLE_LOG); bool ret = Serialize(vecMsg, "", szEnable, netcon::request_e::SERVERDATA_REQUEST_SEND_CONSOLE_LOG);
if (ret && !Send(hSocket, vecMsg.data(), (u32)vecMsg.size())) if (ret && !Send(hSocket, vecMsg.data(), int(vecMsg.size())))
{ {
Error(eDLL_T::CLIENT, NO_ERROR, "Failed to send RCON message: (%s)\n", "SOCKET_ERROR"); Error(eDLL_T::CLIENT, NO_ERROR, "Failed to send RCON message: (%s)\n", "SOCKET_ERROR");
} }
@ -177,16 +177,14 @@ void CRConClient::RequestConsoleLog(const bool bWantLog)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: serializes input // Purpose: serializes input
// Input : *svReqBuf - // Input : *svReqBuf -
// nReqMsgLen -
// *svReqVal - // *svReqVal -
// nReqValLen -
// request_t - // request_t -
// Output : serialized results as string // Output : serialized results as string
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CRConClient::Serialize(vector<byte>& vecBuf, const char* szReqBuf, const size_t nReqMsgLen, bool CRConClient::Serialize(vector<char>& vecBuf, const char* szReqBuf,
const char* szReqVal, const size_t nReqValLen, const netcon::request_e requestType) const const char* szReqVal, const netcon::request_e requestType) const
{ {
return NetconClient_Serialize(this, vecBuf, szReqBuf, nReqMsgLen, szReqVal, nReqValLen, requestType, return NetconClient_Serialize(this, vecBuf, szReqBuf, szReqVal, requestType,
rcon_encryptframes.GetBool(), rcon_debug.GetBool()); rcon_encryptframes.GetBool(), rcon_debug.GetBool());
} }
@ -194,7 +192,7 @@ bool CRConClient::Serialize(vector<byte>& vecBuf, const char* szReqBuf, const si
// Purpose: retrieves the remote socket // Purpose: retrieves the remote socket
// Output : SOCKET_ERROR (-1) on failure // Output : SOCKET_ERROR (-1) on failure
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
ConnectedNetConsoleData_s* CRConClient::GetData(void) CConnectedNetConsoleData* CRConClient::GetData(void)
{ {
return NetconShared_GetConnData(this, 0); return NetconShared_GetConnData(this, 0);
} }
@ -323,7 +321,7 @@ static void RCON_CmdQuery_f(const CCommand& args)
} }
else if (RCONClient()->IsConnected()) else if (RCONClient()->IsConnected())
{ {
vector<byte> vecMsg; vector<char> vecMsg;
bool bSuccess = false; bool bSuccess = false;
const SocketHandle_t hSocket = RCONClient()->GetSocket(); const SocketHandle_t hSocket = RCONClient()->GetSocket();
@ -331,10 +329,7 @@ static void RCON_CmdQuery_f(const CCommand& args)
{ {
if (argCount > 2) if (argCount > 2)
{ {
const char* const pass = args.Arg(2); bSuccess = RCONClient()->Serialize(vecMsg, args.Arg(2), "", netcon::request_e::SERVERDATA_REQUEST_AUTH);
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>) else // Need at least 3 arguments for a password in PASS command (rcon PASS <password>)
{ {
@ -344,7 +339,7 @@ static void RCON_CmdQuery_f(const CCommand& args)
if (bSuccess) if (bSuccess)
{ {
RCONClient()->Send(hSocket, vecMsg.data(), (u32)vecMsg.size()); RCONClient()->Send(hSocket, vecMsg.data(), int(vecMsg.size()));
} }
return; return;
@ -355,16 +350,10 @@ static void RCON_CmdQuery_f(const CCommand& args)
return; return;
} }
const char* const request = args.Arg(1); bSuccess = RCONClient()->Serialize(vecMsg, args.Arg(1), args.ArgS(), netcon::request_e::SERVERDATA_REQUEST_EXECCOMMAND);
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) if (bSuccess)
{ {
RCONClient()->Send(hSocket, vecMsg.data(), (u32)vecMsg.size()); RCONClient()->Send(hSocket, vecMsg.data(), int(vecMsg.size()));
} }
return; return;
} }

View File

@ -15,10 +15,10 @@ public:
void RunFrame(void); void RunFrame(void);
virtual void Disconnect(const char* szReason = nullptr) override; virtual void Disconnect(const char* szReason = nullptr) override;
virtual bool ProcessMessage(const byte* pMsgBuf, const u32 nMsgLen) override; virtual bool ProcessMessage(const char* pMsgBuf, const int nMsgLen) override;
bool Serialize(vector<byte>& vecBuf, const char* szReqBuf, const size_t nReqMsgLen, bool Serialize(vector<char>& vecBuf, const char* szReqBuf,
const char* szReqVal, const size_t nReqValLen, const netcon::request_e requestType) const; const char* szReqVal, const netcon::request_e requestType) const;
void RequestConsoleLog(const bool bWantLog); void RequestConsoleLog(const bool bWantLog);
bool ShouldReceive(void); bool ShouldReceive(void);
@ -27,7 +27,7 @@ public:
bool IsInitialized(void) const; bool IsInitialized(void) const;
bool IsConnected(void); bool IsConnected(void);
ConnectedNetConsoleData_s* GetData(void); CConnectedNetConsoleData* GetData(void);
SocketHandle_t GetSocket(void); SocketHandle_t GetSocket(void);
private: private:

View File

@ -158,5 +158,5 @@ static bool HK_ProcessDataBlock(ClientDataBlockReceiver* receiver, const double
void VClientDataBlockReceiver::Detour(const bool bAttach) const void VClientDataBlockReceiver::Detour(const bool bAttach) const
{ {
DetourSetup(&ClientDataBlockReceiver__ProcessDataBlock, HK_ProcessDataBlock, bAttach); DetourAttach(&ClientDataBlockReceiver__ProcessDataBlock, HK_ProcessDataBlock);
} }

View File

@ -31,13 +31,13 @@
CUtlVector<CUtlString> g_InstalledMaps; CUtlVector<CUtlString> g_InstalledMaps;
CFmtStrN<MAX_MAP_NAME> s_CurrentLevelName; CFmtStrN<MAX_MAP_NAME> s_CurrentLevelName;
static CustomPakData_s s_customPakData; static CustomPakData_t s_customPakData;
static KeyValues* s_pLevelSetKV = nullptr; static KeyValues* s_pLevelSetKV = nullptr;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: load a custom pak and add it to the list // Purpose: load a custom pak and add it to the list
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
PakHandle_t CustomPakData_s::LoadAndAddPak(const char* const pakFile) PakHandle_t CustomPakData_t::LoadAndAddPak(const char* const pakFile)
{ {
if (numHandles >= MAX_CUSTOM_PAKS) if (numHandles >= MAX_CUSTOM_PAKS)
{ {
@ -60,7 +60,7 @@ PakHandle_t CustomPakData_s::LoadAndAddPak(const char* const pakFile)
// NOTE : the array must be kept contiguous; this means that the last pak in // NOTE : the array must be kept contiguous; this means that the last pak in
// the array should always be unloaded fist! // the array should always be unloaded fist!
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CustomPakData_s::UnloadAndRemovePak(const int index) void CustomPakData_t::UnloadAndRemovePak(const int index)
{ {
const PakHandle_t pakId = handles[index]; const PakHandle_t pakId = handles[index];
assert(pakId != PAK_INVALID_HANDLE); // invalid handles should not be inserted assert(pakId != PAK_INVALID_HANDLE); // invalid handles should not be inserted
@ -75,12 +75,12 @@ void CustomPakData_s::UnloadAndRemovePak(const int index)
// Purpose: preload a custom pak; this keeps it available throughout the // Purpose: preload a custom pak; this keeps it available throughout the
// duration of the process, unless manually removed by user. // duration of the process, unless manually removed by user.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
PakHandle_t CustomPakData_s::PreloadAndAddPak(const char* const pakFile) PakHandle_t CustomPakData_t::PreloadAndAddPak(const char* const pakFile)
{ {
// this must never be called after a non-preloaded pak has been added! // this must never be called after a non-preloaded pak has been added!
// preloaded paks must always appear before custom user requested paks // preloaded paks must always appear before custom user requested paks
// due to the unload order: user-requested -> preloaded -> sdk -> core. // due to the unload order: user-requested -> preloaded -> sdk -> core.
assert(handles[CustomPakData_s::PAK_TYPE_COUNT+numPreload] == PAK_INVALID_HANDLE); assert(handles[CustomPakData_t::PAK_TYPE_COUNT+numPreload] == PAK_INVALID_HANDLE);
const PakHandle_t pakId = LoadAndAddPak(pakFile); const PakHandle_t pakId = LoadAndAddPak(pakFile);
@ -93,35 +93,38 @@ PakHandle_t CustomPakData_s::PreloadAndAddPak(const char* const pakFile)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: unloads all non-preloaded custom pak handles // Purpose: unloads all non-preloaded custom pak handles
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CustomPakData_s::UnloadAndRemoveNonPreloaded() void CustomPakData_t::UnloadAndRemoveNonPreloaded()
{ {
// Preloaded paks should not be unloaded here, but only right before sdk / // Preloaded paks should not be unloaded here, but only right before sdk /
// engine paks are unloaded. Only unload user requested and level settings // engine paks are unloaded. Only unload user requested and level settings
// paks from here. Unload them in reverse order, the last pak loaded should // paks from here. Also, the load and unload order here is FIFO, this is
// be the first one to be unloaded. // needed because when you load a pak, and then load another pak which
for (int n = numHandles-1; n >= CustomPakData_s::PAK_TYPE_COUNT + numPreload; n--) // 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++)
{ {
UnloadAndRemovePak(n); UnloadAndRemovePak(i);
} }
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: unloads all preloaded custom pak handles // Purpose: unloads all preloaded custom pak handles
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CustomPakData_s::UnloadAndRemovePreloaded() void CustomPakData_t::UnloadAndRemovePreloaded()
{ {
// Unload them in reverse order, the last pak loaded should be the first for (int i = 0, n = numPreload; i < n; i++)
// one to be unloaded.
for (; numPreload > 0; numPreload--)
{ {
UnloadAndRemovePak(CustomPakData_s::PAK_TYPE_COUNT + (numPreload-1)); UnloadAndRemovePak(CustomPakData_t::PAK_TYPE_COUNT + i);
numPreload--;
} }
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: loads the base SDK pak file by type // Purpose: loads the base SDK pak file by type
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
PakHandle_t CustomPakData_s::LoadBasePak(const char* const pakFile, const PakType_e type) PakHandle_t CustomPakData_t::LoadBasePak(const char* const pakFile, const EPakType type)
{ {
const PakHandle_t pakId = g_pakLoadApi->LoadAsync(pakFile, AlignedMemAlloc(), 4, 0); const PakHandle_t pakId = g_pakLoadApi->LoadAsync(pakFile, AlignedMemAlloc(), 4, 0);
@ -135,7 +138,7 @@ PakHandle_t CustomPakData_s::LoadBasePak(const char* const pakFile, const PakTyp
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: unload the SDK base pak file by type // Purpose: unload the SDK base pak file by type
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CustomPakData_s::UnloadBasePak(const PakType_e type) void CustomPakData_t::UnloadBasePak(const EPakType type)
{ {
const PakHandle_t pakId = handles[type]; const PakHandle_t pakId = handles[type];
@ -206,71 +209,10 @@ 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 // Purpose: processes queued pak files
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void Mod_QueuedPakCacheFrame() void Mod_QueuedPakCacheFrame()
{ {
#ifndef DEDICATED #ifndef DEDICATED
bool bUnconnected = !(*g_pClientState_Shifted)->IsConnected(); bool bUnconnected = !(*g_pClientState_Shifted)->IsConnected();
@ -332,11 +274,11 @@ static void Mod_QueuedPakCacheFrame()
const int numToProcess = startIndex; const int numToProcess = startIndex;
if (startIndex < CommonPakData_s::PAK_TYPE_COUNT) if (startIndex <= CommonPakData_t::PAK_TYPE_LEVEL)
{ {
bool keepLoaded = false; bool keepLoaded = false;
int numLeftToProcess = 4; int numLeftToProcess = 4;
CommonPakData_s* data = &g_commonPakData[4]; CommonPakData_t* data = &g_commonPakData[4];
do do
{ {
@ -365,24 +307,26 @@ static void Mod_QueuedPakCacheFrame()
switch (numLeftToProcess) switch (numLeftToProcess)
{ {
#ifndef DEDICATED #ifndef DEDICATED
case CommonPakData_s::PakType_e::PAK_TYPE_UI_GM: case CommonPakData_t::PAK_TYPE_UI_GM:
s_customPakData.UnloadBasePak(CustomPakData_s::PakType_e::PAK_TYPE_UI_SDK); s_customPakData.UnloadBasePak(CustomPakData_t::PAK_TYPE_UI_SDK);
break; break;
#endif // !DEDICATED #endif // !DEDICATED
case CommonPakData_s::PakType_e::PAK_TYPE_COMMON: case CommonPakData_t::PAK_TYPE_COMMON:
g_StudioMdlFallbackHandler.Clear(); g_StudioMdlFallbackHandler.Clear();
break; break;
case CommonPakData_s::PakType_e::PAK_TYPE_COMMON_GM: case CommonPakData_t::PAK_TYPE_COMMON_GM:
s_customPakData.UnloadBasePak(CustomPakData_s::PakType_e::PAK_TYPE_COMMON_SDK); s_customPakData.UnloadBasePak(CustomPakData_t::PAK_TYPE_COMMON_SDK);
break; break;
default: default:
break; break;
} }
if (numLeftToProcess == CommonPakData_s::PakType_e::PAK_TYPE_LEVEL) g_pakLoadApi->UnloadAsync(data->pakId);
if (numLeftToProcess == CommonPakData_t::PAK_TYPE_LEVEL)
{ {
Mod_UnloadLevelPaks(); // Unload mod pak files. Mod_UnloadLevelPaks(); // Unload mod pak files.
@ -393,10 +337,7 @@ static void Mod_QueuedPakCacheFrame()
s_pLevelSetKV = nullptr; 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(); Mod_UnloadPreloadedPaks();
s_customPakData.basePaksLoaded = false; s_customPakData.basePaksLoaded = false;
@ -417,7 +358,7 @@ static void Mod_QueuedPakCacheFrame()
} }
*g_pPakPrecacheJobFinished = true; *g_pPakPrecacheJobFinished = true;
CommonPakData_s* commonData = g_commonPakData; CommonPakData_t* commonData = g_commonPakData;
int it = 0; int it = 0;
@ -441,7 +382,7 @@ static void Mod_QueuedPakCacheFrame()
} while (c); } while (c);
if (!v20) if (!v20)
goto CHECK_LOAD_STATUS; goto CHECK_FOR_FAILURE;
V_strncpy(name, commonData->basePakName, MAX_PATH); V_strncpy(name, commonData->basePakName, MAX_PATH);
@ -478,7 +419,7 @@ static void Mod_QueuedPakCacheFrame()
{ {
if (*g_bPakFifoLockAcquiredInMainThread) if (*g_bPakFifoLockAcquiredInMainThread)
{ {
*g_bPakFifoLockAcquiredInMainThread = false; *g_bPakFifoLockAcquiredInMainThread = 0;
JT_ReleaseFifoLock(pakFifoLock); JT_ReleaseFifoLock(pakFifoLock);
} }
} }
@ -497,32 +438,39 @@ static void Mod_QueuedPakCacheFrame()
} }
} }
if (it == CommonPakData_s::PakType_e::PAK_TYPE_LOBBY) if (it == CommonPakData_t::PAK_TYPE_LOBBY)
{ {
Mod_PreloadPaks(); Mod_PreloadPaks();
s_customPakData.basePaksLoaded = true; s_customPakData.basePaksLoaded = true;
} }
commonData->pakId = g_pakLoadApi->LoadAsync(name, AlignedMemAlloc(), 4, 0); if (s_customPakData.basePaksLoaded && !s_customPakData.levelResourcesLoaded)
if (it == CommonPakData_s::PakType_e::PAK_TYPE_LEVEL)
{ {
Mod_LoadLevelPaks(s_CurrentLevelName.String()); Mod_LoadLevelPaks(s_CurrentLevelName.String());
s_customPakData.levelResourcesLoaded = true; s_customPakData.levelResourcesLoaded = true;
} }
commonData->pakId = g_pakLoadApi->LoadAsync(name, AlignedMemAlloc(), 4, 0);
#ifndef DEDICATED #ifndef DEDICATED
if (it == CommonPakData_s::PakType_e::PAK_TYPE_UI_GM) if (it == CommonPakData_t::PAK_TYPE_UI_GM)
s_customPakData.LoadBasePak("ui_sdk.rpak", CustomPakData_s::PakType_e::PAK_TYPE_UI_SDK); s_customPakData.LoadBasePak("ui_sdk.rpak", CustomPakData_t::PAK_TYPE_UI_SDK);
else
#endif // !DEDICATED #endif // !DEDICATED
if (it == CommonPakData_s::PakType_e::PAK_TYPE_COMMON_GM) if (it == CommonPakData_t::PAK_TYPE_COMMON_GM)
s_customPakData.LoadBasePak("common_sdk.rpak", CustomPakData_s::PakType_e::PAK_TYPE_COMMON_SDK); s_customPakData.LoadBasePak("common_sdk.rpak", CustomPakData_t::PAK_TYPE_COMMON_SDK);
CHECK_LOAD_STATUS: CHECK_FOR_FAILURE:
if (!Mod_IsPakLoadFinished(commonData->pakId) || !CustomPakData_IsPakLoadFinished(CommonPakData_s::PakType_e(it))) if (commonData->pakId != PAK_INVALID_HANDLE)
*g_pPakPrecacheJobFinished = false; {
const PakLoadedInfo_s* const pli = Pak_GetPakInfo(commonData->pakId);
if (pli->handle != commonData->pakId || ((pli->status - 9) & 0xFFFFFFFB) != 0)
{
*g_pPakPrecacheJobFinished = false;
return;
}
}
goto LOOP_AGAIN_OR_FINISH; goto LOOP_AGAIN_OR_FINISH;
} }

View File

@ -12,9 +12,9 @@ class KeyValues;
// loads for a level, this is used for load/unload management during level // loads for a level, this is used for load/unload management during level
// changes or engine shutdown // changes or engine shutdown
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
struct CommonPakData_s struct CommonPakData_t
{ {
enum PakType_e enum EPakType
{ {
// the UI pak assigned to the current gamemode (range in GameMode_t) // the UI pak assigned to the current gamemode (range in GameMode_t)
PAK_TYPE_UI_GM = 0, PAK_TYPE_UI_GM = 0,
@ -32,7 +32,7 @@ struct CommonPakData_s
PAK_TYPE_COUNT PAK_TYPE_COUNT
}; };
CommonPakData_s() CommonPakData_t()
{ {
Reset(); Reset();
} }
@ -62,9 +62,9 @@ struct CommonPakData_s
// loaded with the settings KV for that level, these paks are loaded after the // 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 // common paks are loaded, but unloaded before the common paks are unloaded
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
struct CustomPakData_s struct CustomPakData_t
{ {
enum PakType_e enum EPakType
{ {
// the pak that loads after CommonPakData_t::PAK_TYPE_UI_GM has loaded, and // the pak that loads after CommonPakData_t::PAK_TYPE_UI_GM has loaded, and
// unloads before CommonPakData_t::PAK_TYPE_UI_GM gets unloaded // unloads before CommonPakData_t::PAK_TYPE_UI_GM gets unloaded
@ -83,10 +83,10 @@ struct CustomPakData_s
// the absolute max number of custom paks, note that the engine's limit // 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 // could still be reached before this number as game scripts and other
// code still loads paks such as gladiator cards or load screens // code still loads paks such as gladiator cards or load screens
MAX_CUSTOM_PAKS = (PAK_MAX_LOADED_PAKS - CommonPakData_s::PAK_TYPE_COUNT) MAX_CUSTOM_PAKS = (PAK_MAX_LOADED_PAKS - CommonPakData_t::PAK_TYPE_COUNT)
}; };
CustomPakData_s() CustomPakData_t()
{ {
for (size_t i = 0; i < V_ARRAYSIZE(handles); i++) for (size_t i = 0; i < V_ARRAYSIZE(handles); i++)
{ {
@ -107,8 +107,8 @@ struct CustomPakData_s
void UnloadAndRemoveNonPreloaded(); void UnloadAndRemoveNonPreloaded();
void UnloadAndRemovePreloaded(); void UnloadAndRemovePreloaded();
PakHandle_t LoadBasePak(const char* const pakFile, const PakType_e type); PakHandle_t LoadBasePak(const char* const pakFile, const EPakType type);
void UnloadBasePak(const PakType_e type); void UnloadBasePak(const EPakType type);
private: private:
void UnloadAndRemovePak(const int index); void UnloadAndRemovePak(const int index);
@ -128,7 +128,7 @@ public:
}; };
// array size = CommonPakData_t::PAK_TYPE_COUNT // array size = CommonPakData_t::PAK_TYPE_COUNT
inline CommonPakData_s* g_commonPakData; inline CommonPakData_t* g_commonPakData;
inline void(*v_Mod_LoadPakForMap)(const char* szLevelName); inline void(*v_Mod_LoadPakForMap)(const char* szLevelName);
inline void(*v_Mod_QueuedPakCacheFrame)(void); inline void(*v_Mod_QueuedPakCacheFrame)(void);

View File

@ -1,6 +1,5 @@
#include "core/stdafx.h" #include "core/stdafx.h"
#include "tier0/commandline.h" #include "tier0/commandline.h"
#include "rtech/pak/pakstate.h"
#include "host_cmd.h" #include "host_cmd.h"
#include "common.h" #include "common.h"
#include "client/client.h" #include "client/client.h"
@ -8,60 +7,6 @@
#include "windows/id3dx.h" #include "windows/id3dx.h"
#endif // !DEDICATED #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 Host_Shutdown
@ -70,7 +15,7 @@ Host_Shutdown
systems systems
================== ==================
*/ */
static void Host_Shutdown() void Host_Shutdown()
{ {
#ifndef DEDICATED #ifndef DEDICATED
DirectX_Shutdown(); DirectX_Shutdown();
@ -86,7 +31,7 @@ Host_Status_PrintClient
to console to console
================== ==================
*/ */
static void Host_Status_PrintClient(CClient* client, bool bShowAddress, void (*print) (const char* fmt, ...)) void Host_Status_PrintClient(CClient* client, bool bShowAddress, void (*print) (const char* fmt, ...))
{ {
CNetChan* nci = client->GetNetChan(); CNetChan* nci = client->GetNetChan();
const char* state = "challenging"; const char* state = "challenging";
@ -100,7 +45,7 @@ static void Host_Status_PrintClient(CClient* client, bool bShowAddress, void (*p
if (nci != NULL) if (nci != NULL)
{ {
print("# %hu \"%s\" %llu %s %i %i %s %d\n", print("# %i \"%s\" %llu %s %i %i %s %d\n",
client->GetHandle(), client->GetServerName(), client->GetNucleusID(), COM_FormatSeconds(static_cast<int>(nci->GetTimeConnected())), 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()); static_cast<int>(1000.0f * nci->GetAvgLatency(FLOW_OUTGOING)), static_cast<int>(100.0f * nci->GetAvgLoss(FLOW_INCOMING)), state, nci->GetDataRate());
@ -111,7 +56,7 @@ static void Host_Status_PrintClient(CClient* client, bool bShowAddress, void (*p
} }
else else
{ {
print("#%2hu \"%s\" %llu %s\n", client->GetHandle(), client->GetServerName(), client->GetNucleusID(), state); print("#%2i \"%s\" %llu %s\n", client->GetHandle(), client->GetServerName(), client->GetNucleusID(), state);
} }
//print("\n"); //print("\n");
@ -125,7 +70,7 @@ DFS_InitializeFeatureFlagDefinitions
flag definitions flag definitions
================== ==================
*/ */
static bool DFS_InitializeFeatureFlagDefinitions(const char* pszFeatureFlags) bool DFS_InitializeFeatureFlagDefinitions(const char* pszFeatureFlags)
{ {
if (CommandLine()->CheckParm("-nodfs")) if (CommandLine()->CheckParm("-nodfs"))
return false; return false;
@ -136,7 +81,6 @@ static bool DFS_InitializeFeatureFlagDefinitions(const char* pszFeatureFlags)
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void VHostCmd::Detour(const bool bAttach) const void VHostCmd::Detour(const bool bAttach) const
{ {
DetourSetup(&v_Host_SetupUIMaterials, &Host_SetupUIMaterials, bAttach);
DetourSetup(&v_Host_Shutdown, &Host_Shutdown, bAttach); DetourSetup(&v_Host_Shutdown, &Host_Shutdown, bAttach);
DetourSetup(&v_Host_Status_PrintClient, &Host_Status_PrintClient, bAttach); DetourSetup(&v_Host_Status_PrintClient, &Host_Status_PrintClient, bAttach);
DetourSetup(&v_DFS_InitializeFeatureFlagDefinitions, &DFS_InitializeFeatureFlagDefinitions, bAttach); DetourSetup(&v_DFS_InitializeFeatureFlagDefinitions, &DFS_InitializeFeatureFlagDefinitions, bAttach);

View File

@ -19,11 +19,8 @@ extern EngineParms_t* g_pEngineParms;
/* ==== HOST ============================================================================================================================================================ */ /* ==== HOST ============================================================================================================================================================ */
inline void(*v_Host_Init)(); inline void(*v_Host_Init)();
#ifndef DEDICATED
inline void(*v_Host_Init_DuringVideo)(bool* bDedicated); inline void(*v_Host_Init_DuringVideo)(bool* bDedicated);
inline void(*v_Host_Init_PostVideo)(bool* bDedicated); inline void(*v_Host_Init_PostVideo)(bool* bDedicated);
#endif // !DEDICATED
inline void(*v_Host_SetupUIMaterials)();
inline void(*v_Host_Shutdown)(); inline void(*v_Host_Shutdown)();
inline bool(*v_Host_NewGame)(char* pszMapName, char* pszMapGroup, bool bLoadGame, char bBackground, LARGE_INTEGER PerformanceCount); inline bool(*v_Host_NewGame)(char* pszMapName, char* pszMapGroup, bool bLoadGame, char bBackground, LARGE_INTEGER PerformanceCount);
inline void(*v_Host_Disconnect)(bool bShowMainMenu); inline void(*v_Host_Disconnect)(bool bShowMainMenu);
@ -41,11 +38,8 @@ class VHostCmd : public IDetour
virtual void GetAdr(void) const virtual void GetAdr(void) const
{ {
LogFunAdr("Host_Init", v_Host_Init); LogFunAdr("Host_Init", v_Host_Init);
#ifndef DEDICATED
LogFunAdr("Host_Init_DuringVideo", v_Host_Init_DuringVideo); LogFunAdr("Host_Init_DuringVideo", v_Host_Init_DuringVideo);
LogFunAdr("Host_Init_PostVideo", v_Host_Init_PostVideo); LogFunAdr("Host_Init_PostVideo", v_Host_Init_PostVideo);
#endif // !DEDICATED
LogFunAdr("Host_SetupUIMaterials", v_Host_SetupUIMaterials);
LogFunAdr("Host_Shutdown", v_Host_Shutdown); LogFunAdr("Host_Shutdown", v_Host_Shutdown);
LogFunAdr("Host_Disconnect", v_Host_Disconnect); LogFunAdr("Host_Disconnect", v_Host_Disconnect);
LogFunAdr("Host_NewGame", v_Host_NewGame); LogFunAdr("Host_NewGame", v_Host_NewGame);
@ -59,14 +53,11 @@ class VHostCmd : public IDetour
virtual void GetFun(void) const virtual void GetFun(void) const
{ {
g_GameDll.FindPatternSIMD("88 4C 24 08 53 55 56 57 48 83 EC 68").GetPtr(v_Host_Init); 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 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("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 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("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 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); 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);

View File

@ -121,8 +121,8 @@ static void HostState_KeepAlive()
{ {
g_ServerHostManager.SetCurrentToken(hostToken); g_ServerHostManager.SetCurrentToken(hostToken);
Msg(eDLL_T::SERVER, "Published server with token: %s'%s%s%s'\n", Msg(eDLL_T::SERVER, "Published server with token: %s'%s%s%s'\n",
g_svReset.c_str(), g_svGreyB.c_str(), g_svReset, g_svGreyB,
hostToken.c_str(), g_svReset.c_str()); hostToken.c_str(), g_svReset);
} }
} }

View File

@ -181,7 +181,7 @@ void NET_Config()
void NET_PrintKey() void NET_PrintKey()
{ {
Msg(eDLL_T::ENGINE, "Installed NetKey: %s'%s%s%s'\n", Msg(eDLL_T::ENGINE, "Installed NetKey: %s'%s%s%s'\n",
g_svReset.c_str(), g_svGreyB.c_str(), g_pNetKey->GetBase64NetKey(), g_svReset.c_str()); g_svReset, g_svGreyB, g_pNetKey->GetBase64NetKey(), g_svReset);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -247,7 +247,12 @@ void NET_PrintFunc(const char* fmt, ...)
result = FormatV(fmt, args); result = FormatV(fmt, args);
va_end(args); va_end(args);
Msg(context, result.back() == '\n' ? "%s" : "%s\n", result.c_str()); if (result.back() != '\n')
{
result.push_back('\n');
}
Msg(context, "%s", result.c_str());
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -383,7 +388,7 @@ const char* NET_ErrorString(int iCode)
case WSA_QOS_EFILTERCOUNT : return "WSA_QOS_EFILTERCOUNT"; case WSA_QOS_EFILTERCOUNT : return "WSA_QOS_EFILTERCOUNT";
case WSA_QOS_EOBJLENGTH : return "WSA_QOS_EOBJLENGTH"; case WSA_QOS_EOBJLENGTH : return "WSA_QOS_EOBJLENGTH";
case WSA_QOS_EFLOWCOUNT : return "WSA_QOS_EFLOWCOUNT"; case WSA_QOS_EFLOWCOUNT : return "WSA_QOS_EFLOWCOUNT";
case WSA_QOS_EUNKOWNPSOBJ : return "WSA_QOS_EUNKNOWNPSOBJ"; case WSA_QOS_EUNKOWNPSOBJ : return "WSA_QOS_EUNKOWNPSOBJ";
case WSA_QOS_EPOLICYOBJ : return "WSA_QOS_EPOLICYOBJ"; case WSA_QOS_EPOLICYOBJ : return "WSA_QOS_EPOLICYOBJ";
case WSA_QOS_EFLOWDESC : return "WSA_QOS_EFLOWDESC"; case WSA_QOS_EFLOWDESC : return "WSA_QOS_EFLOWDESC";
case WSA_QOS_EPSFLOWSPEC : return "WSA_QOS_EPSFLOWSPEC"; case WSA_QOS_EPSFLOWSPEC : return "WSA_QOS_EPSFLOWSPEC";

View File

@ -116,7 +116,7 @@ CClient* CServer::ConnectClient(CServer* pServer, user_creds_s* pChallenge)
return nullptr; return nullptr;
char* pszPersonaName = pChallenge->personaName; char* pszPersonaName = pChallenge->personaName;
NucleusID_t nNucleusID = pChallenge->personaId; uint64_t nNucleusID = pChallenge->personaId;
char pszAddresBuffer[128]; // Render the client's address. char pszAddresBuffer[128]; // Render the client's address.
pChallenge->netAdr.ToString(pszAddresBuffer, sizeof(pszAddresBuffer), true); pChallenge->netAdr.ToString(pszAddresBuffer, sizeof(pszAddresBuffer), true);

View File

@ -23,7 +23,7 @@ struct user_creds_s
int32_t protocolVer; int32_t protocolVer;
int32_t challenge; int32_t challenge;
uint32_t reservation; uint32_t reservation;
NucleusID_t personaId; uint64_t personaId;
char* personaName; char* personaName;
}; };

View File

@ -39,7 +39,7 @@ void SV_CheckForBanAndDisconnect(CClient* const pClient, const string& svIPAddr,
{ {
const int nUserID = pClient->GetUserID(); const int nUserID = pClient->GetUserID();
pClient->Disconnect(Reputation_t::REP_MARK_BAD, "%s", svError.c_str()); pClient->Disconnect(Reputation_t::REP_MARK_BAD, svError.c_str());
Warning(eDLL_T::SERVER, "Removed client '[%s]:%i' from slot #%i ('%llu' is banned globally!)\n", Warning(eDLL_T::SERVER, "Removed client '[%s]:%i' from slot #%i ('%llu' is banned globally!)\n",
svIPAddr.c_str(), nPort, nUserID, nNucleusID); svIPAddr.c_str(), nPort, nUserID, nNucleusID);
} }

View File

@ -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_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_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, true, 4096.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_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_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); 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); m_Socket.CreateListenSocket(m_Address);
Msg(eDLL_T::SERVER, "Remote server access initialized ('%s') with key %s'%s%s%s'\n", Msg(eDLL_T::SERVER, "Remote server access initialized ('%s') with key %s'%s%s%s'\n",
m_Address.ToString(), g_svReset.c_str(), g_svGreyB.c_str(), GetKey(), g_svReset.c_str()); m_Address.ToString(), g_svReset, g_svGreyB, GetKey(), g_svReset);
m_bInitialized = true; m_bInitialized = true;
} }
@ -155,7 +155,7 @@ void CRConServer::Think(void)
const netadr_t& netAdr = m_Socket.GetAcceptedSocketAddress(m_nConnIndex); const netadr_t& netAdr = m_Socket.GetAcceptedSocketAddress(m_nConnIndex);
if (!m_WhiteListAddress.CompareAdr(netAdr)) if (!m_WhiteListAddress.CompareAdr(netAdr))
{ {
const ConnectedNetConsoleData_s& data = m_Socket.GetAcceptedSocketData(m_nConnIndex); const CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(m_nConnIndex);
if (!data.m_bAuthorized) if (!data.m_bAuthorized)
{ {
Disconnect("redundant"); Disconnect("redundant");
@ -248,11 +248,11 @@ void CRConServer::RunFrame(void)
const int nCount = m_Socket.GetAcceptedSocketCount(); const int nCount = m_Socket.GetAcceptedSocketCount();
for (m_nConnIndex = nCount - 1; m_nConnIndex >= 0; m_nConnIndex--) for (m_nConnIndex = nCount - 1; m_nConnIndex >= 0; m_nConnIndex--)
{ {
ConnectedNetConsoleData_s& data = m_Socket.GetAcceptedSocketData(m_nConnIndex); CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(m_nConnIndex);
if (CheckForBan(data)) if (CheckForBan(data))
{ {
SendEncoded(data.m_hSocket, s_BannedMessage, sizeof(s_BannedMessage)-1, "", 0, SendEncoded(data.m_hSocket, s_BannedMessage, "",
netcon::response_e::SERVERDATA_RESPONSE_AUTH, int(eDLL_T::NETCON)); netcon::response_e::SERVERDATA_RESPONSE_AUTH, int(eDLL_T::NETCON));
Disconnect("banned"); Disconnect("banned");
@ -270,18 +270,25 @@ void CRConServer::RunFrame(void)
// nMsgLen - // nMsgLen -
// Output: true on success, false otherwise // Output: true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CRConServer::SendToAll(const byte* pMsgBuf, const u32 nMsgLen) const bool CRConServer::SendToAll(const char* pMsgBuf, const int nMsgLen) const
{ {
const int nCount = m_Socket.GetAcceptedSocketCount(); ostringstream sendbuf;
const u_long nLen = htonl(u_long(nMsgLen));
bool bSuccess = true; 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--) for (int i = nCount - 1; i >= 0; i--)
{ {
const ConnectedNetConsoleData_s& data = m_Socket.GetAcceptedSocketData(i); const CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(i);
if (data.m_bAuthorized && !data.m_bInputOnly) if (data.m_bAuthorized && !data.m_bInputOnly)
{ {
const int ret = ::send(data.m_hSocket, (const char*)pMsgBuf, (i32)nMsgLen, MSG_NOSIGNAL); int ret = ::send(data.m_hSocket, sendbuf.str().data(),
int(sendbuf.str().size()), MSG_NOSIGNAL);
if (ret == SOCKET_ERROR) if (ret == SOCKET_ERROR)
{ {
@ -299,19 +306,17 @@ bool CRConServer::SendToAll(const byte* pMsgBuf, const u32 nMsgLen) const
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: encode and send message to all connected sockets // Purpose: encode and send message to all connected sockets
// Input : *pResponseMsg - // Input : *pResponseMsg -
// nResponseMsgLen -
// *pResponseVal - // *pResponseVal -
// nResponseValLen -
// responseType - // responseType -
// nMessageId - // nMessageId -
// nMessageType - // nMessageType -
// Output: true on success, false otherwise // Output: true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CRConServer::SendEncoded(const char* pResponseMsg, const size_t nResponseMsgLen, const char* pResponseVal, const size_t nResponseValLen, bool CRConServer::SendEncoded(const char* pResponseMsg, const char* pResponseVal,
const netcon::response_e responseType, const int nMessageId, const int nMessageType) const const netcon::response_e responseType, const int nMessageId, const int nMessageType) const
{ {
vector<byte> vecMsg; vector<char> vecMsg;
if (!Serialize(vecMsg, pResponseMsg, nResponseMsgLen, pResponseVal, nResponseValLen, if (!Serialize(vecMsg, pResponseMsg, pResponseVal,
responseType, nMessageId, nMessageType)) responseType, nMessageId, nMessageType))
{ {
return false; return false;
@ -329,20 +334,17 @@ bool CRConServer::SendEncoded(const char* pResponseMsg, const size_t nResponseMs
// Purpose: encode and send message to specific socket // Purpose: encode and send message to specific socket
// Input : hSocket - // Input : hSocket -
// *pResponseMsg - // *pResponseMsg -
// nResponseMsgLen -
// *pResponseVal - // *pResponseVal -
// nResponseValLen -
// responseType - // responseType -
// nMessageId - // nMessageId -
// nMessageType - // nMessageType -
// Output: true on success, false otherwise // Output: true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CRConServer::SendEncoded(const SocketHandle_t hSocket, bool CRConServer::SendEncoded(const SocketHandle_t hSocket, const char* pResponseMsg, const char* pResponseVal,
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 const netcon::response_e responseType, const int nMessageId, const int nMessageType) const
{ {
vector<byte> vecMsg; vector<char> vecMsg;
if (!Serialize(vecMsg, pResponseMsg, nResponseMsgLen, pResponseVal, nResponseValLen, if (!Serialize(vecMsg, pResponseMsg, pResponseVal,
responseType, nMessageId, nMessageType)) responseType, nMessageId, nMessageType))
{ {
return false; return false;
@ -360,19 +362,16 @@ bool CRConServer::SendEncoded(const SocketHandle_t hSocket,
// Purpose: serializes input // Purpose: serializes input
// Input : &vecBuf - // Input : &vecBuf -
// *responseMsg - // *responseMsg -
// nResponseMsgLen -
// *responseVal - // *responseVal -
// nResponseValLen -
// responseType - // responseType -
// nMessageId - // nMessageId -
// nMessageType - // nMessageType -
// Output : serialized results as string // Output : serialized results as string
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CRConServer::Serialize(vector<byte>& vecBuf, bool CRConServer::Serialize(vector<char>& vecBuf, const char* pResponseMsg, const char* pResponseVal,
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 const netcon::response_e responseType, const int nMessageId, const int nMessageType) const
{ {
return NetconServer_Serialize(this, vecBuf, pResponseMsg, nResponseMsgLen, pResponseVal, nResponseValLen, responseType, nMessageId, nMessageType, return NetconServer_Serialize(this, vecBuf, pResponseMsg, pResponseVal, responseType, nMessageId, nMessageType,
rcon_encryptframes.GetBool(), rcon_debug.GetBool()); rcon_encryptframes.GetBool(), rcon_debug.GetBool());
} }
@ -381,7 +380,7 @@ bool CRConServer::Serialize(vector<byte>& vecBuf,
// Input : &request - // Input : &request -
// &data - // &data -
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::Authenticate(const netcon::request& request, ConnectedNetConsoleData_s& data) void CRConServer::Authenticate(const netcon::request& request, CConnectedNetConsoleData& data)
{ {
if (data.m_bAuthorized) if (data.m_bAuthorized)
{ {
@ -400,7 +399,7 @@ void CRConServer::Authenticate(const netcon::request& request, ConnectedNetConso
const char* pSendLogs = (!sv_rcon_sendlogs.GetBool() || data.m_bInputOnly) ? "0" : "1"; const char* pSendLogs = (!sv_rcon_sendlogs.GetBool() || data.m_bInputOnly) ? "0" : "1";
SendEncoded(data.m_hSocket, s_AuthMessage, sizeof(s_AuthMessage)-1, pSendLogs, 1, SendEncoded(data.m_hSocket, s_AuthMessage, pSendLogs,
netcon::response_e::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON)); netcon::response_e::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON));
} }
else // Bad password. else // Bad password.
@ -411,7 +410,7 @@ void CRConServer::Authenticate(const netcon::request& request, ConnectedNetConso
Msg(eDLL_T::SERVER, "Bad RCON password attempt from '%s'\n", netAdr.ToString()); Msg(eDLL_T::SERVER, "Bad RCON password attempt from '%s'\n", netAdr.ToString());
} }
SendEncoded(data.m_hSocket, s_WrongPwMessage, sizeof(s_WrongPwMessage)-1, "", 0, SendEncoded(data.m_hSocket, s_WrongPwMessage, "",
netcon::response_e::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON)); netcon::response_e::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON));
data.m_bAuthorized = false; data.m_bAuthorized = false;
@ -445,7 +444,7 @@ bool CRConServer::Comparator(const string& svPassword) const
// nMsgLen - // nMsgLen -
// Output : true on success, false otherwise // Output : true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CRConServer::ProcessMessage(const byte* pMsgBuf, const u32 nMsgLen) bool CRConServer::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
{ {
netcon::request request; netcon::request request;
@ -455,13 +454,13 @@ bool CRConServer::ProcessMessage(const byte* pMsgBuf, const u32 nMsgLen)
return false; return false;
} }
ConnectedNetConsoleData_s& data = m_Socket.GetAcceptedSocketData(m_nConnIndex); CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(m_nConnIndex);
if (!data.m_bAuthorized && if (!data.m_bAuthorized &&
request.requesttype() != netcon::request_e::SERVERDATA_REQUEST_AUTH) request.requesttype() != netcon::request_e::SERVERDATA_REQUEST_AUTH)
{ {
// Notify netconsole that authentication is required. // Notify netconsole that authentication is required.
SendEncoded(data.m_hSocket, s_NoAuthMessage, sizeof(s_NoAuthMessage)-1, "", 0, SendEncoded(data.m_hSocket, s_NoAuthMessage, "",
netcon::response_e::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON)); netcon::response_e::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON));
data.m_bValidated = false; data.m_bValidated = false;
@ -522,7 +521,7 @@ void CRConServer::Execute(const netcon::request& request) const
// Purpose: checks for amount of failed attempts and bans netconsole accordingly // Purpose: checks for amount of failed attempts and bans netconsole accordingly
// Input : &data - // Input : &data -
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CRConServer::CheckForBan(ConnectedNetConsoleData_s& data) bool CRConServer::CheckForBan(CConnectedNetConsoleData& data)
{ {
if (data.m_bValidated) if (data.m_bValidated)
{ {
@ -597,7 +596,7 @@ void CRConServer::Disconnect(const char* szReason) // NETMGR
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::Disconnect(const int nIndex, const char* szReason) // NETMGR void CRConServer::Disconnect(const int nIndex, const char* szReason) // NETMGR
{ {
ConnectedNetConsoleData_s& data = m_Socket.GetAcceptedSocketData(nIndex); CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(nIndex);
if (data.m_bAuthorized) if (data.m_bAuthorized)
{ {
// Inform server owner when authenticated connection has been closed. // Inform server owner when authenticated connection has been closed.
@ -622,7 +621,7 @@ void CRConServer::CloseNonAuthConnection(void)
int nCount = m_Socket.GetAcceptedSocketCount(); int nCount = m_Socket.GetAcceptedSocketCount();
for (int i = nCount - 1; i >= 0; i--) for (int i = nCount - 1; i >= 0; i--)
{ {
ConnectedNetConsoleData_s& data = m_Socket.GetAcceptedSocketData(i); CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(i);
if (!data.m_bAuthorized) if (!data.m_bAuthorized)
{ {

View File

@ -25,27 +25,27 @@ public:
void Think(void); void Think(void);
void RunFrame(void); void RunFrame(void);
bool SendEncoded(const char* pResponseMsg, const size_t nResponseMsgLen, const char* pResponseVal, const size_t nResponseValLen, bool SendEncoded(const char* pResponseMsg, const char* pResponseVal,
const netcon::response_e responseType, const netcon::response_e responseType,
const int nMessageId = static_cast<int>(eDLL_T::NETCON), const int nMessageId = static_cast<int>(eDLL_T::NETCON),
const int nMessageType = static_cast<int>(LogType_t::LOG_NET)) const; const int nMessageType = static_cast<int>(LogType_t::LOG_NET)) const;
bool SendEncoded(const SocketHandle_t hSocket, const char* pResponseMsg, const size_t nResponseMsgLen, bool SendEncoded(const SocketHandle_t hSocket, const char* pResponseMsg,
const char* pResponseVal, const size_t nResponseValLen, const netcon::response_e responseType, const char* pResponseVal, const netcon::response_e responseType,
const int nMessageId = static_cast<int>(eDLL_T::NETCON), const int nMessageId = static_cast<int>(eDLL_T::NETCON),
const int nMessageType = static_cast<int>(LogType_t::LOG_NET)) const; const int nMessageType = static_cast<int>(LogType_t::LOG_NET)) const;
bool SendToAll(const byte* pMsgBuf, const u32 nMsgLen) const; bool SendToAll(const char* pMsgBuf, const int nMsgLen) const;
bool Serialize(vector<byte>& vecBuf, const char* pResponseMsg, const size_t nResponseMsgLen, const char* pResponseVal, const size_t nResponseValLen, bool Serialize(vector<char>& vecBuf, const char* pResponseMsg, const char* pResponseVal, const netcon::response_e responseType,
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; 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, ConnectedNetConsoleData_s& data); void Authenticate(const netcon::request& request, CConnectedNetConsoleData& data);
bool Comparator(const string& svPassword) const; bool Comparator(const string& svPassword) const;
virtual bool ProcessMessage(const byte* pMsgBuf, const u32 nMsgLen) override; virtual bool ProcessMessage(const char* pMsgBuf, const int nMsgLen) override;
void Execute(const netcon::request& request) const; void Execute(const netcon::request& request) const;
bool CheckForBan(ConnectedNetConsoleData_s& data); bool CheckForBan(CConnectedNetConsoleData& data);
virtual void Disconnect(const char* szReason = nullptr) override; virtual void Disconnect(const char* szReason = nullptr) override;
void Disconnect(const int nIndex, const char* szReason = nullptr); void Disconnect(const int nIndex, const char* szReason = nullptr);

View File

@ -144,88 +144,72 @@ bool CNetConBase::Connect(const char* pHostName, const int nPort)
// nMaxLen - // nMaxLen -
// Output: true on success, false otherwise // Output: true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CNetConBase::ProcessBuffer(ConnectedNetConsoleData_s& data, const byte* pRecvBuf, u32 nRecvLen, const int nMaxLen) bool CNetConBase::ProcessBuffer(CConnectedNetConsoleData& data,
const char* pRecvBuf, int nRecvLen, const int nMaxLen)
{ {
bool bSuccess = true;
while (nRecvLen > 0) while (nRecvLen > 0)
{ {
// Read payload if it's already in progress.
if (data.m_nPayloadLen) if (data.m_nPayloadLen)
{ {
const u32 bytesToCopy = Min(nRecvLen, data.m_nPayloadLen - data.m_nPayloadRead); if (data.m_nPayloadRead < data.m_nPayloadLen)
memcpy(&data.m_RecvBuffer[data.m_nPayloadRead], pRecvBuf, bytesToCopy); {
data.m_RecvBuffer[data.m_nPayloadRead++] = *pRecvBuf;
data.m_nPayloadRead += bytesToCopy;
pRecvBuf += bytesToCopy;
nRecvLen -= bytesToCopy;
pRecvBuf++;
nRecvLen--;
}
if (data.m_nPayloadRead == data.m_nPayloadLen) if (data.m_nPayloadRead == data.m_nPayloadLen)
{ {
if (!ProcessMessage(data.m_RecvBuffer.data(), data.m_nPayloadLen)) if (!ProcessMessage(
return false; reinterpret_cast<const char*>(data.m_RecvBuffer.data()), data.m_nPayloadLen)
&& bSuccess)
{
bSuccess = false;
}
// Reset state.
data.m_nPayloadLen = 0; data.m_nPayloadLen = 0;
data.m_nPayloadRead = 0; data.m_nPayloadRead = 0;
} }
} }
else if (data.m_nPayloadRead < sizeof(NetConFrameHeader_s)) // Read the header if we haven't fully recv'd it. else if (data.m_nPayloadRead < sizeof(int)) // Read size field.
{ {
const u32 bytesToCopy = Min(nRecvLen, int(sizeof(NetConFrameHeader_s)) - data.m_nPayloadRead); data.m_RecvBuffer[data.m_nPayloadRead++] = *pRecvBuf;
memcpy(reinterpret_cast<char*>(&data.m_FrameHeader) + data.m_nPayloadRead, pRecvBuf, bytesToCopy);
data.m_nPayloadRead += bytesToCopy; pRecvBuf++;
nRecvLen--;
}
else // Build prefix.
{
data.m_nPayloadLen = int(ntohl(*reinterpret_cast<u_long*>(&data.m_RecvBuffer[0])));
data.m_nPayloadRead = 0;
pRecvBuf += bytesToCopy; if (!data.m_bAuthorized && nMaxLen > -1)
nRecvLen -= bytesToCopy;
if (data.m_nPayloadRead == sizeof(NetConFrameHeader_s))
{ {
NetConFrameHeader_s& header = data.m_FrameHeader; if (data.m_nPayloadLen > nMaxLen)
// Convert byte order and check for desync.
header.magic = ntohl(header.magic);
const char* desyncReason = nullptr;
if (header.magic != RCON_FRAME_MAGIC)
{ {
desyncReason = "invalid magic"; Disconnect("overflow"); // Sending large messages while not authenticated.
}
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; return false;
} }
}
if ((!data.m_bAuthorized && nMaxLen > -1 && header.length > (u32)nMaxLen) || if (data.m_nPayloadLen < 0 ||
header.length > RCON_FRAME_MAX_SIZE) data.m_nPayloadLen > data.m_RecvBuffer.max_size())
{ {
Disconnect("overflow"); Error(eDLL_T::ENGINE, NO_ERROR, "RCON Cmd: sync error (%d)\n", data.m_nPayloadLen);
return false; Disconnect("desync"); // Out of sync (irrecoverable).
}
data.m_nPayloadLen = header.length; return false;
data.m_nPayloadRead = 0; }
else
data.m_RecvBuffer.resize(header.length); {
data.m_RecvBuffer.resize(data.m_nPayloadLen);
} }
} }
} }
return true; return bSuccess;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -236,12 +220,13 @@ bool CNetConBase::ProcessBuffer(ConnectedNetConsoleData_s& data, const byte* pRe
// nDataLen - // nDataLen -
// Output : true on success, false otherwise // Output : true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CNetConBase::Encrypt(CryptoContext_s& ctx, const byte* pInBuf, byte* pOutBuf, const u32 nDataLen) const bool CNetConBase::Encrypt(CryptoContext_s& ctx, const char* pInBuf,
char* pOutBuf, const size_t nDataLen) const
{ {
if (Crypto_GenerateIV(ctx, pInBuf, nDataLen)) if (Crypto_GenerateIV(ctx, reinterpret_cast<const unsigned char*>(pInBuf), nDataLen))
return Crypto_CTREncrypt(ctx, pInBuf, pOutBuf, m_NetKey, nDataLen); return Crypto_CTREncrypt(ctx, reinterpret_cast<const unsigned char*>(pInBuf),
reinterpret_cast<unsigned char*>(pOutBuf), m_NetKey, nDataLen);
Assert(0);
return false; // failure return false; // failure
} }
@ -253,9 +238,11 @@ bool CNetConBase::Encrypt(CryptoContext_s& ctx, const byte* pInBuf, byte* pOutBu
// nDataLen - // nDataLen -
// Output : true on success, false otherwise // Output : true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CNetConBase::Decrypt(CryptoContext_s& ctx, const byte* pInBuf, byte* pOutBuf, const u32 nDataLen) const bool CNetConBase::Decrypt(CryptoContext_s& ctx, const char* pInBuf,
char* pOutBuf, const size_t nDataLen) const
{ {
return Crypto_CTRDecrypt(ctx, pInBuf, pOutBuf, m_NetKey, nDataLen); return Crypto_CTRDecrypt(ctx, reinterpret_cast<const unsigned char*>(pInBuf),
reinterpret_cast<unsigned char*>(pOutBuf), m_NetKey, nDataLen);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -265,9 +252,10 @@ bool CNetConBase::Decrypt(CryptoContext_s& ctx, const byte* pInBuf, byte* pOutBu
// nMsgLen - // nMsgLen -
// Output : true on success, false otherwise // Output : true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CNetConBase::Encode(google::protobuf::MessageLite* pMsg, byte* pMsgBuf, const u32 nMsgLen) const bool CNetConBase::Encode(google::protobuf::MessageLite* pMsg,
char* pMsgBuf, const size_t nMsgLen) const
{ {
return pMsg->SerializeToArray(pMsgBuf, (i32)nMsgLen); return pMsg->SerializeToArray(pMsgBuf, int(nMsgLen));
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -277,9 +265,10 @@ bool CNetConBase::Encode(google::protobuf::MessageLite* pMsg, byte* pMsgBuf, con
// nMsgLen - // nMsgLen -
// Output : true on success, false otherwise // Output : true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CNetConBase::Decode(google::protobuf::MessageLite* pMsg, const byte* pMsgBuf, const u32 nMsgLen) const bool CNetConBase::Decode(google::protobuf::MessageLite* pMsg,
const char* pMsgBuf, const size_t nMsgLen) const
{ {
return pMsg->ParseFromArray(pMsgBuf, (i32)nMsgLen); return pMsg->ParseFromArray(pMsgBuf, int(nMsgLen));
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -289,9 +278,18 @@ bool CNetConBase::Decode(google::protobuf::MessageLite* pMsg, const byte* pMsgBu
// nMsgLen - // nMsgLen -
// Output: true on success, false otherwise // Output: true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CNetConBase::Send(const SocketHandle_t hSocket, const byte* pMsgBuf, const u32 nMsgLen) const bool CNetConBase::Send(const SocketHandle_t hSocket, const char* pMsgBuf,
const int nMsgLen) const
{ {
const int ret = ::send(hSocket, (char*)pMsgBuf, (i32)nMsgLen, MSG_NOSIGNAL); 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);
return (ret != SOCKET_ERROR); return (ret != SOCKET_ERROR);
} }
@ -301,19 +299,19 @@ bool CNetConBase::Send(const SocketHandle_t hSocket, const byte* pMsgBuf, const
// nMaxLen - // nMaxLen -
// Output: true on success, false otherwise // Output: true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CNetConBase::Recv(ConnectedNetConsoleData_s& data, const int nMaxLen) void CNetConBase::Recv(CConnectedNetConsoleData& data, const int nMaxLen)
{ {
static char szRecvBuf[1024]; static char szRecvBuf[1024];
{////////////////////////////////////////////// {//////////////////////////////////////////////
const int nPendingLen = ::recv(data.m_hSocket, szRecvBuf, sizeof(szRecvBuf), MSG_PEEK); const int nPendingLen = ::recv(data.m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK);
if (nPendingLen == SOCKET_ERROR && m_Socket.IsSocketBlocking()) if (nPendingLen == SOCKET_ERROR && m_Socket.IsSocketBlocking())
{ {
return; return;
} }
else if (nPendingLen == 0) // Socket was closed. else if (nPendingLen == 0) // Socket was closed.
{ {
Disconnect("socket closed prematurely"); Disconnect("remote closed socket");
return; return;
} }
else if (nPendingLen < 0) else if (nPendingLen < 0)
@ -323,8 +321,8 @@ void CNetConBase::Recv(ConnectedNetConsoleData_s& data, const int nMaxLen)
} }
}////////////////////////////////////////////// }//////////////////////////////////////////////
u_long nReadLen = 0; // Find out how much we have to read. int nReadLen = 0; // Find out how much we have to read.
const int iResult = ::ioctlsocket(data.m_hSocket, FIONREAD, &nReadLen); int iResult = ::ioctlsocket(data.m_hSocket, FIONREAD, reinterpret_cast<u_long*>(&nReadLen));
if (iResult == SOCKET_ERROR) if (iResult == SOCKET_ERROR)
{ {
@ -346,10 +344,8 @@ void CNetConBase::Recv(ConnectedNetConsoleData_s& data, const int nMaxLen)
break; break;
} }
nReadLen -= static_cast<u_long>(nRecvLen); // Process what we've got. nReadLen -= nRecvLen; // Process what we've got.
ProcessBuffer(data, szRecvBuf, nRecvLen, nMaxLen);
if (!ProcessBuffer(data, reinterpret_cast<byte*>(&szRecvBuf), static_cast<u32>(nRecvLen), nMaxLen))
break;
} }
return; return;

View File

@ -1,12 +1,14 @@
#ifndef BASE_RCON_H #ifndef BASE_RCON_H
#define BASE_RCON_H #define BASE_RCON_H
#include "netcon/INetCon.h"
#include "tier1/NetAdr.h" #include "tier1/NetAdr.h"
#include "tier2/cryptutils.h" #include "tier2/cryptutils.h"
#include "tier2/socketcreator.h" #include "tier2/socketcreator.h"
#include "protobuf/message_lite.h" #include "protobuf/message_lite.h"
// Max size of the payload in the envelope frame
#define RCON_MAX_PAYLOAD_SIZE 1024*1024
class CNetConBase class CNetConBase
{ {
public: public:
@ -21,17 +23,17 @@ public:
virtual bool Connect(const char* pHostName, const int nHostPort = SOCKET_ERROR); virtual bool Connect(const char* pHostName, const int nHostPort = SOCKET_ERROR);
virtual void Disconnect(const char* szReason = nullptr) { NOTE_UNUSED(szReason); }; virtual void Disconnect(const char* szReason = nullptr) { NOTE_UNUSED(szReason); };
virtual bool ProcessBuffer(ConnectedNetConsoleData_s& data, const byte* pRecvBuf, u32 nRecvLen, const int nMaxLen = SOCKET_ERROR); virtual bool ProcessBuffer(CConnectedNetConsoleData& data, const char* pRecvBuf, int nRecvLen, const int nMaxLen = SOCKET_ERROR);
virtual bool ProcessMessage(const byte* /*pMsgBuf*/, const u32 /*nMsgLen*/) { return true; }; virtual bool ProcessMessage(const char* /*pMsgBuf*/, int /*nMsgLen*/) { return true; };
virtual bool Encrypt(CryptoContext_s& ctx, const byte* pInBuf, byte* pOutBuf, const u32 nDataLen) const; virtual bool Encrypt(CryptoContext_s& ctx, const char* pInBuf, char* pOutBuf, const size_t nDataLen) const;
virtual bool Decrypt(CryptoContext_s& ctx, const byte* pInBuf, byte* pOutBuf, const u32 nDataLen) const; virtual bool Decrypt(CryptoContext_s& ctx, const char* pInBuf, char* pOutBuf, const size_t nDataLen) const;
virtual bool Encode(google::protobuf::MessageLite* pMsg, byte* pMsgBuf, const u32 nMsgLen) const; virtual bool Encode(google::protobuf::MessageLite* pMsg, char* pMsgBuf, const size_t nMsgLen) const;
virtual bool Decode(google::protobuf::MessageLite* pMsg, const byte* pMsgBuf, const u32 nMsgLen) const; virtual bool Decode(google::protobuf::MessageLite* pMsg, const char* pMsgBuf, const size_t nMsgLen) const;
virtual bool Send(const SocketHandle_t hSocket, const byte* pMsgBuf, const u32 nMsgLen) const; virtual bool Send(const SocketHandle_t hSocket, const char* pMsgBuf, const int nMsgLen) const;
virtual void Recv(ConnectedNetConsoleData_s& data, const int nMaxLen = SOCKET_ERROR); virtual void Recv(CConnectedNetConsoleData& data, const int nMaxLen = SOCKET_ERROR);
CSocketCreator* GetSocketCreator(void) { return &m_Socket; } CSocketCreator* GetSocketCreator(void) { return &m_Socket; }
netadr_t* GetNetAddress(void) { return &m_Address; } netadr_t* GetNetAddress(void) { return &m_Address; }

View File

@ -13,9 +13,7 @@
// Input : *pBase - // Input : *pBase -
// &vecBuf - // &vecBuf -
// *pResponseMsg - // *pResponseMsg -
// nResponseMsgLen -
// *pResponseVal - // *pResponseVal -
// nResponseValLen -
// responseType - // responseType -
// nMessageId - // nMessageId -
// nMessageType - // nMessageType -
@ -23,8 +21,7 @@
// bDebug - // bDebug -
// Output : true on success, false otherwise // Output : true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool NetconServer_Serialize(const CNetConBase* pBase, vector<byte>& vecBuf, bool NetconServer_Serialize(const CNetConBase* pBase, vector<char>& vecBuf, const char* pResponseMsg, const char* pResponseVal,
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) const netcon::response_e responseType, const int nMessageId, const int nMessageType, const bool bEncrypt, const bool bDebug)
{ {
netcon::response response; netcon::response response;
@ -32,10 +29,10 @@ bool NetconServer_Serialize(const CNetConBase* pBase, vector<byte>& vecBuf,
response.set_messageid(nMessageId); response.set_messageid(nMessageId);
response.set_messagetype(nMessageType); response.set_messagetype(nMessageType);
response.set_responsetype(responseType); response.set_responsetype(responseType);
response.set_responsemsg(pResponseMsg, nResponseMsgLen); response.set_responsemsg(pResponseMsg);
response.set_responseval(pResponseVal, nResponseValLen); response.set_responseval(pResponseVal);
if (!NetconShared_PackEnvelope(pBase, vecBuf, (u32)response.ByteSizeLong(), &response, bEncrypt, bDebug)) if (!NetconShared_PackEnvelope(pBase, vecBuf, response.ByteSizeLong(), &response, bEncrypt, bDebug))
{ {
return false; return false;
} }
@ -48,25 +45,23 @@ bool NetconServer_Serialize(const CNetConBase* pBase, vector<byte>& vecBuf,
// Input : *pBase - // Input : *pBase -
// &vecBuf - // &vecBuf -
// *szReqBuf - // *szReqBuf -
// nReqMsgLen -
// *szReqVal - // *szReqVal -
// nReqValLen -
// *requestType - // *requestType -
// bEncrypt - // bEncrypt -
// bDebug - // bDebug -
// Output : true on success, false otherwise // Output : true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool NetconClient_Serialize(const CNetConBase* pBase, vector<byte>& vecBuf, const char* szReqBuf, const size_t nReqMsgLen, bool NetconClient_Serialize(const CNetConBase* pBase, vector<char>& vecBuf, const char* szReqBuf,
const char* szReqVal, const size_t nReqValLen, const netcon::request_e requestType, const bool bEncrypt, const bool bDebug) const char* szReqVal, const netcon::request_e requestType, const bool bEncrypt, const bool bDebug)
{ {
netcon::request request; netcon::request request;
request.set_messageid(-1); request.set_messageid(-1);
request.set_requesttype(requestType); request.set_requesttype(requestType);
request.set_requestmsg(szReqBuf, nReqMsgLen); request.set_requestmsg(szReqBuf);
request.set_requestval(szReqVal, nReqValLen); request.set_requestval(szReqVal);
if (!NetconShared_PackEnvelope(pBase, vecBuf, (u32)request.ByteSizeLong(), &request, bEncrypt, bDebug)) if (!NetconShared_PackEnvelope(pBase, vecBuf, request.ByteSizeLong(), &request, bEncrypt, bDebug))
{ {
return false; return false;
} }
@ -129,11 +124,11 @@ bool NetconClient_Connect(CNetConBase* pBase, const char* pHostAdr, const int nH
// bDebug - // bDebug -
// Output : true on success, false otherwise // Output : true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool NetconShared_PackEnvelope(const CNetConBase* pBase, vector<byte>& outMsgBuf, const u32 nMsgLen, bool NetconShared_PackEnvelope(const CNetConBase* pBase, vector<char>& outMsgBuf, const size_t nMsgLen,
google::protobuf::MessageLite* const inMsg, const bool bEncrypt, const bool bDebug) google::protobuf::MessageLite* inMsg, const bool bEncrypt, const bool bDebug)
{ {
byte* const encodeBuf = new byte[nMsgLen]; char* encodeBuf = new char[nMsgLen];
std::unique_ptr<byte[]> encodedContainer(encodeBuf); std::unique_ptr<char[]> encodedContainer(encodeBuf);
if (!pBase->Encode(inMsg, encodeBuf, nMsgLen)) if (!pBase->Encode(inMsg, encodeBuf, nMsgLen))
{ {
@ -148,12 +143,12 @@ bool NetconShared_PackEnvelope(const CNetConBase* pBase, vector<byte>& outMsgBuf
netcon::envelope envelope; netcon::envelope envelope;
envelope.set_encrypted(bEncrypt); envelope.set_encrypted(bEncrypt);
const byte* dataBuf = encodeBuf; const char* dataBuf = encodeBuf;
std::unique_ptr<byte[]> container; std::unique_ptr<char[]> container;
if (bEncrypt) if (bEncrypt)
{ {
byte* encryptBuf = new byte[nMsgLen]; char* encryptBuf = new char[nMsgLen];
container.reset(encryptBuf); container.reset(encryptBuf);
CryptoContext_s ctx; CryptoContext_s ctx;
@ -172,12 +167,11 @@ bool NetconShared_PackEnvelope(const CNetConBase* pBase, vector<byte>& outMsgBuf
} }
envelope.set_data(dataBuf, nMsgLen); envelope.set_data(dataBuf, nMsgLen);
const u32 envelopeSize = (u32)envelope.ByteSizeLong(); const size_t envelopeSize = envelope.ByteSizeLong();
outMsgBuf.resize(sizeof(NetConFrameHeader_s) + envelopeSize); outMsgBuf.resize(envelopeSize);
byte* const scratch = outMsgBuf.data();
if (!pBase->Encode(&envelope, &scratch[sizeof(NetConFrameHeader_s)], envelopeSize)) if (!pBase->Encode(&envelope, &outMsgBuf[0], envelopeSize))
{ {
if (bDebug) if (bDebug)
{ {
@ -187,12 +181,6 @@ bool NetconShared_PackEnvelope(const CNetConBase* pBase, vector<byte>& outMsgBuf
return false; 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; return true;
} }
@ -206,8 +194,8 @@ bool NetconShared_PackEnvelope(const CNetConBase* pBase, vector<byte>& outMsgBuf
// bDebug - // bDebug -
// Output : true on success, false otherwise // Output : true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool NetconShared_UnpackEnvelope(const CNetConBase* pBase, const byte* pMsgBuf, const u32 nMsgLen, bool NetconShared_UnpackEnvelope(const CNetConBase* pBase, const char* pMsgBuf, const size_t nMsgLen,
google::protobuf::MessageLite* const outMsg, const bool bDebug) google::protobuf::MessageLite* outMsg, const bool bDebug)
{ {
netcon::envelope envelope; netcon::envelope envelope;
@ -221,33 +209,33 @@ bool NetconShared_UnpackEnvelope(const CNetConBase* pBase, const byte* pMsgBuf,
return false; return false;
} }
const u32 msgLen = (u32)envelope.data().size(); const size_t msgLen = envelope.data().size();
if (msgLen > RCON_FRAME_MAX_SIZE) if (msgLen > RCON_MAX_PAYLOAD_SIZE)
{ {
Error(eDLL_T::ENGINE, NO_ERROR, "Data in RCON message envelope is too large (%u > %u)\n", Error(eDLL_T::ENGINE, NO_ERROR, "Data in RCON message envelope is too large (%zu > %zu)\n",
msgLen, RCON_FRAME_MAX_SIZE); msgLen, RCON_MAX_PAYLOAD_SIZE);
return false; return false;
} }
const byte* netMsg = reinterpret_cast<const byte*>(envelope.data().c_str()); const char* netMsg = envelope.data().c_str();
const byte* dataBuf = netMsg; const char* dataBuf = netMsg;
std::unique_ptr<byte[]> container; std::unique_ptr<char[]> container;
if (envelope.encrypted()) if (envelope.encrypted())
{ {
byte* decryptBuf = new byte[msgLen]; char* decryptBuf = new char[msgLen];
container.reset(decryptBuf); container.reset(decryptBuf);
const u32 ivLen = (u32)envelope.nonce().size(); const size_t ivLen = envelope.nonce().size();
if (ivLen != sizeof(CryptoIV_t)) if (ivLen != sizeof(CryptoIV_t))
{ {
if (bDebug) if (bDebug)
{ {
Error(eDLL_T::ENGINE, NO_ERROR, "Nonce in RCON message envelope is invalid (%u != %u)\n", Error(eDLL_T::ENGINE, NO_ERROR, "Nonce in RCON message envelope is invalid (%zu != %zu)\n",
ivLen, sizeof(CryptoIV_t)); ivLen, sizeof(CryptoIV_t));
} }
@ -291,7 +279,7 @@ bool NetconShared_UnpackEnvelope(const CNetConBase* pBase, const byte* pMsgBuf,
// iSocket - // iSocket -
// Output : nullptr on failure // Output : nullptr on failure
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
ConnectedNetConsoleData_s* NetconShared_GetConnData(CNetConBase* pBase, const int iSocket) CConnectedNetConsoleData* NetconShared_GetConnData(CNetConBase* pBase, const int iSocket)
{ {
CSocketCreator* pCreator = pBase->GetSocketCreator(); CSocketCreator* pCreator = pBase->GetSocketCreator();
Assert(iSocket >= 0 && (pCreator->GetAcceptedSocketCount() == 0 Assert(iSocket >= 0 && (pCreator->GetAcceptedSocketCount() == 0
@ -313,7 +301,7 @@ ConnectedNetConsoleData_s* NetconShared_GetConnData(CNetConBase* pBase, const in
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
SocketHandle_t NetconShared_GetSocketHandle(CNetConBase* pBase, const int iSocket) SocketHandle_t NetconShared_GetSocketHandle(CNetConBase* pBase, const int iSocket)
{ {
const ConnectedNetConsoleData_s* pData = NetconShared_GetConnData(pBase, iSocket); const CConnectedNetConsoleData* pData = NetconShared_GetConnData(pBase, iSocket);
if (!pData) if (!pData)
{ {
return SOCKET_ERROR; return SOCKET_ERROR;
@ -356,19 +344,19 @@ void RCON_KeyChanged_f(IConVar* pConVar, const char* pOldString, float flOldValu
RCONClient()->SetKey(RCONServer()->GetKey()); // Sync server & client keys RCONClient()->SetKey(RCONServer()->GetKey()); // Sync server & client keys
Msg(eDLL_T::ENGINE, "Installed RCON Key: %s'%s%s%s'\n", Msg(eDLL_T::ENGINE, "Installed RCON Key: %s'%s%s%s'\n",
g_svReset.c_str(), g_svGreyB.c_str(), RCONClient()->GetKey(), g_svReset.c_str()); g_svReset, g_svGreyB, RCONClient()->GetKey(), g_svReset);
#else #else
#ifdef DEDICATED #ifdef DEDICATED
RCONServer()->SetKey(pNewString); RCONServer()->SetKey(pNewString);
Msg(eDLL_T::SERVER, "Installed RCON Key: %s'%s%s%s'\n", Msg(eDLL_T::SERVER, "Installed RCON Key: %s'%s%s%s'\n",
g_svReset.c_str(), g_svGreyB.c_str(), RCONServer()->GetKey(), g_svReset.c_str()); g_svReset, g_svGreyB, RCONServer()->GetKey(), g_svReset);
#endif // DEDICATED #endif // DEDICATED
#ifdef CLIENT_DLL #ifdef CLIENT_DLL
RCONClient()->SetKey(pNewString); RCONClient()->SetKey(pNewString);
Msg(eDLL_T::CLIENT, "Installed RCON Key: %s'%s%s%s'\n", Msg(eDLL_T::CLIENT, "Installed RCON Key: %s'%s%s%s'\n",
g_svReset.c_str(), g_svGreyB.c_str(), RCONClient()->GetKey(), g_svReset.c_str()); g_svReset, g_svGreyB, RCONClient()->GetKey(), g_svReset);
#endif // CLIENT_DLL #endif // CLIENT_DLL
#endif // !DEDICATED && !CLIENT_DLL #endif // !DEDICATED && !CLIENT_DLL

View File

@ -16,18 +16,17 @@ extern void RCON_InitClientAndTrySyncKeys();
#endif // !DEDICATED #endif // !DEDICATED
#endif // _TOOLS #endif // _TOOLS
bool NetconServer_Serialize(const CNetConBase* pBase, vector<byte>& vecBuf, bool NetconServer_Serialize(const CNetConBase* pBase, vector<char>& vecBuf, const char* pResponseMsg, const char* pResponseVal,
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); const netcon::response_e responseType, const int nMessageId, const int nMessageType, const bool bEncrypt, const bool bDebug);
bool NetconClient_Serialize(const CNetConBase* pBase, vector<byte>& vecBuf, const char* szReqBuf, const size_t nReqMsgLen, bool NetconClient_Serialize(const CNetConBase* pBase, vector<char>& vecBuf, const char* szReqBuf,
const char* szReqVal, const size_t nReqValLen, const netcon::request_e requestType, const bool bEncrypt, const bool bDebug); const char* szReqVal, const netcon::request_e requestType, const bool bEncrypt, const bool bDebug);
bool NetconClient_Connect(CNetConBase* pBase, const char* pHostAdr, const int nHostPort); bool NetconClient_Connect(CNetConBase* pBase, const char* pHostAdr, const int nHostPort);
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_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 byte* pMsgBuf, const u32 nMsgLen, google::protobuf::MessageLite* const outMsg, const bool bDebug); bool NetconShared_UnpackEnvelope(const CNetConBase* pBase, const char* pMsgBuf, const size_t nMsgLen, google::protobuf::MessageLite* outMsg, const bool bDebug);
ConnectedNetConsoleData_s* NetconShared_GetConnData(CNetConBase* pBase, const int iSocket); CConnectedNetConsoleData* NetconShared_GetConnData(CNetConBase* pBase, const int iSocket);
SocketHandle_t NetconShared_GetSocketHandle(CNetConBase* pBase, const int iSocket); SocketHandle_t NetconShared_GetSocketHandle(CNetConBase* pBase, const int iSocket);
#endif // SHARED_RCON_H #endif // SHARED_RCON_H

View File

@ -1,52 +1,5 @@
#include "cliententitylist.h" #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 // Purpose: a global list of all the entities in the game. All iteration through
// entities is done through this object. // entities is done through this object.

View File

@ -59,10 +59,8 @@ private:
}; };
COMPILE_TIME_ASSERT(sizeof(CClientEntityList) == 0x3800C0); COMPILE_TIME_ASSERT(sizeof(CClientEntityList) == 0x3800C0);
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; inline IClientEntityList* g_pClientEntityList = nullptr;
extern CClientEntityList* g_clientEntityList; extern CClientEntityList* g_clientEntityList;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -75,18 +73,14 @@ class VClientEntityList : public IDetour
{ {
LogVarAdr("g_clientEntityList", g_clientEntityList); 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 virtual void GetVar(void) const
{ {
g_GameDll.FindPatternSIMD("48 8D 0D ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 44 89 0D"). g_GameDll.FindPatternSIMD("48 8D 0D ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 44 89 0D").
ResolveRelativeAddressSelf(3, 7).ResolveRelativeAddressSelf(3, 7).GetPtr(g_clientEntityList); ResolveRelativeAddressSelf(3, 7).ResolveRelativeAddressSelf(3, 7).GetPtr(g_clientEntityList);
} }
virtual void GetCon(void) const { } virtual void GetCon(void) const { }
virtual void Detour(const bool bAttach) const; virtual void Detour(const bool bAttach) const { };
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -144,7 +144,7 @@ namespace VScriptCode
else else
{ {
hiddenServerRequestMessage = Format("Request failed: %s", hiddenServerRequestMessage.c_str()); hiddenServerRequestMessage = Format("Request failed: %s", hiddenServerRequestMessage.c_str());
sq_pushstring(v, hiddenServerRequestMessage.c_str(), (SQInteger)hiddenServerRequestMessage.length()); sq_pushstring(v, hiddenServerRequestMessage.c_str(), -1);
} }
SCRIPT_CHECK_AND_RETURN(v, SQ_OK); SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
@ -157,12 +157,12 @@ namespace VScriptCode
else else
hiddenServerRequestMessage = Format("Server listing empty: %s", hiddenServerRequestMessage.c_str()); hiddenServerRequestMessage = Format("Server listing empty: %s", hiddenServerRequestMessage.c_str());
sq_pushstring(v, hiddenServerRequestMessage.c_str(), (SQInteger)hiddenServerRequestMessage.length()); sq_pushstring(v, hiddenServerRequestMessage.c_str(), -1);
} }
else else
{ {
hiddenServerRequestMessage = Format("Found server: %s", serverListing.name.c_str()); hiddenServerRequestMessage = Format("Found server: %s", serverListing.name.c_str());
sq_pushstring(v, hiddenServerRequestMessage.c_str(), (SQInteger)hiddenServerRequestMessage.length()); sq_pushstring(v, hiddenServerRequestMessage.c_str(), -1);
} }
SCRIPT_CHECK_AND_RETURN(v, SQ_OK); SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
@ -182,7 +182,7 @@ namespace VScriptCode
SCRIPT_CHECK_AND_RETURN(v, SQ_ERROR); SCRIPT_CHECK_AND_RETURN(v, SQ_ERROR);
const string& serverName = g_ServerListManager.m_vServerList[iServer].name; const string& serverName = g_ServerListManager.m_vServerList[iServer].name;
sq_pushstring(v, serverName.c_str(), (SQInteger)serverName.length()); sq_pushstring(v, serverName.c_str(), -1);
SCRIPT_CHECK_AND_RETURN(v, SQ_OK); SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
} }
@ -201,7 +201,7 @@ namespace VScriptCode
SCRIPT_CHECK_AND_RETURN(v, SQ_ERROR); SCRIPT_CHECK_AND_RETURN(v, SQ_ERROR);
const string& serverDescription = g_ServerListManager.m_vServerList[iServer].description; const string& serverDescription = g_ServerListManager.m_vServerList[iServer].description;
sq_pushstring(v, serverDescription.c_str(), (SQInteger)serverDescription.length()); sq_pushstring(v, serverDescription.c_str(), -1);
SCRIPT_CHECK_AND_RETURN(v, SQ_OK); SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
} }
@ -219,8 +219,8 @@ namespace VScriptCode
if (!Script_CheckServerIndexAndFailure(v, iServer)) if (!Script_CheckServerIndexAndFailure(v, iServer))
SCRIPT_CHECK_AND_RETURN(v, SQ_ERROR); SCRIPT_CHECK_AND_RETURN(v, SQ_ERROR);
const string& serverMapName = g_ServerListManager.m_vServerList[iServer].map; const string& svServerMapName = g_ServerListManager.m_vServerList[iServer].map;
sq_pushstring(v, serverMapName.c_str(), (SQInteger)serverMapName.length()); sq_pushstring(v, svServerMapName.c_str(), -1);
SCRIPT_CHECK_AND_RETURN(v, SQ_OK); SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
} }
@ -239,7 +239,7 @@ namespace VScriptCode
SCRIPT_CHECK_AND_RETURN(v, SQ_ERROR); SCRIPT_CHECK_AND_RETURN(v, SQ_ERROR);
const string& serverPlaylist = g_ServerListManager.m_vServerList[iServer].playlist; const string& serverPlaylist = g_ServerListManager.m_vServerList[iServer].playlist;
sq_pushstring(v, serverPlaylist.c_str(), (SQInteger)serverPlaylist.length()); sq_pushstring(v, serverPlaylist.c_str(), -1);
SCRIPT_CHECK_AND_RETURN(v, SQ_OK); SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
} }
@ -356,14 +356,14 @@ namespace VScriptCode
// set EULA version cvar to the newly fetched EULA version // set EULA version cvar to the newly fetched EULA version
eula_version->SetValue(eulaData.version); eula_version->SetValue(eulaData.version);
sq_pushstring(v, eulaData.contents.c_str(), (SQInteger)eulaData.contents.length()); sq_pushstring(v, eulaData.contents.c_str(), -1);
} }
else else
{ {
const string error = Format("Failed to load EULA Data: %s", eulaRequestMessage.c_str()); string error = Format("Failed to load EULA Data: %s", eulaRequestMessage.c_str());
Warning(eDLL_T::UI, "%s\n", error.c_str()); Warning(eDLL_T::UI, "%s\n", error.c_str());
sq_pushstring(v, error.c_str(), (SQInteger)error.length()); sq_pushstring(v, error.c_str(), -1);
} }
SCRIPT_CHECK_AND_RETURN(v, SQ_OK); SCRIPT_CHECK_AND_RETURN(v, SQ_OK);

View File

@ -120,7 +120,7 @@ private:
CTether m_tethers[2]; CTether m_tethers[2];
EHANDLE m_titanSoul; EHANDLE m_titanSoul;
Vector3D m_lastFootstepDamagePos; Vector3D m_lastFootstepDamagePos;
bool m_lastFootstepDamageOnGround; bool m_lastFoostepDamageOnGround;
char gap_1781[3]; char gap_1781[3];
int m_muzzleAttachment[2]; int m_muzzleAttachment[2];
int m_weaponHandAttachment; int m_weaponHandAttachment;

View File

@ -26,75 +26,6 @@
#define LIVEAPI_SHA512_HASH_SIZE 64 #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;
/* /*
@ -1952,16 +1883,110 @@ static bool LiveAPI_HandleCustomEvent(HSQUIRRELVM const v, const SQObject& obj,
static void LiveAPI_SendEvent(const google::protobuf::Message* const msg) static void LiveAPI_SendEvent(const google::protobuf::Message* const msg)
{ {
s_liveAPIEvent.set_event_size(msg->ByteSize()); rtech::liveapi::LiveAPIEvent envelope;
s_liveAPIEvent.mutable_gamemessage()->PackFrom(*msg);
LiveAPISystem()->LogEvent(&s_liveAPIEvent, &s_liveAPIEvent.gamemessage()); envelope.set_event_size(msg->ByteSize());
s_liveAPIEvent.Clear(); 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;
}
} }
static bool LiveAPI_HandleEventByCategory(HSQUIRRELVM const v, const SQTable* const table, const eLiveAPI_EventTypes eventType) static bool LiveAPI_HandleEventByCategory(HSQUIRRELVM const v, const SQTable* const table, const eLiveAPI_EventTypes eventType)
{ {
google::protobuf::Message* msg = nullptr; 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;
SQ_FOR_EACH_TABLE(table, i) SQ_FOR_EACH_TABLE(table, i)
{ {
@ -1970,8 +1995,15 @@ static bool LiveAPI_HandleEventByCategory(HSQUIRRELVM const v, const SQTable* co
if (sq_isnull(node.key)) if (sq_isnull(node.key))
continue; continue;
ranLoop = true;
if (!LiveAPI_CheckSwitchType(v, node.key)) if (!LiveAPI_CheckSwitchType(v, node.key))
{
Assert(msg);
delete msg;
return false; return false;
}
const SQInteger fieldNum = _integer(node.key); const SQInteger fieldNum = _integer(node.key);
const SQObjectPtr& obj = node.val; const SQObjectPtr& obj = node.val;
@ -1981,179 +2013,146 @@ static bool LiveAPI_HandleEventByCategory(HSQUIRRELVM const v, const SQTable* co
switch (eventType) switch (eventType)
{ {
case eLiveAPI_EventTypes::init: case eLiveAPI_EventTypes::init:
msg = &s_init; ret = LiveAPI_HandleInitEvent(reinterpret_cast<rtech::liveapi::Init*>(msg), eventType);
ret = LiveAPI_HandleInitEvent(&s_init, eventType);
break; break;
case eLiveAPI_EventTypes::matchSetup: case eLiveAPI_EventTypes::matchSetup:
msg = &s_matchSetup; ret = LiveAPI_HandleMatchSetup(v, obj, reinterpret_cast<rtech::liveapi::MatchSetup*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleMatchSetup(v, obj, &s_matchSetup, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::ammoUsed: case eLiveAPI_EventTypes::ammoUsed:
msg = &s_ammoUsed; ret = LiveAPI_HandleAmmoUsed(v, obj, reinterpret_cast<rtech::liveapi::AmmoUsed*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleAmmoUsed(v, obj, &s_ammoUsed, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::arenasItemDeselected: case eLiveAPI_EventTypes::arenasItemDeselected:
msg = &s_arenasItemDeselected; ret = LiveAPI_HandleInventoryChange(v, obj, reinterpret_cast<rtech::liveapi::ArenasItemDeselected*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleInventoryChange(v, obj, &s_arenasItemDeselected, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::arenasItemSelected: case eLiveAPI_EventTypes::arenasItemSelected:
msg = &s_arenasItemSelected; ret = LiveAPI_HandleInventoryChange(v, obj, reinterpret_cast<rtech::liveapi::ArenasItemSelected*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleInventoryChange(v, obj, &s_arenasItemSelected, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::bannerCollected: case eLiveAPI_EventTypes::bannerCollected:
msg = &s_bannerCollected; ret = LiveAPI_HandleBannerCollected(v, obj, reinterpret_cast<rtech::liveapi::BannerCollected*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleBannerCollected(v, obj, &s_bannerCollected, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::customEvent: case eLiveAPI_EventTypes::customEvent:
msg = &s_customEvent; ret = LiveAPI_HandleCustomEvent(v, obj, reinterpret_cast<rtech::liveapi::CustomEvent*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleCustomEvent(v, obj, &s_customEvent, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::inventoryPickUp: case eLiveAPI_EventTypes::inventoryPickUp:
msg = &s_inventoryPickUp; ret = LiveAPI_HandleInventoryChange(v, obj, reinterpret_cast<rtech::liveapi::InventoryPickUp*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleInventoryChange(v, obj, &s_inventoryPickUp, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::inventoryDrop: case eLiveAPI_EventTypes::inventoryDrop:
msg = &s_inventoryDrop; ret = LiveAPI_HandleInventoryDrop(v, obj, reinterpret_cast<rtech::liveapi::InventoryDrop*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleInventoryDrop(v, obj, &s_inventoryDrop, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::inventoryUse: case eLiveAPI_EventTypes::inventoryUse:
msg = &s_inventoryUse; ret = LiveAPI_HandleInventoryChange(v, obj, reinterpret_cast<rtech::liveapi::InventoryUse*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleInventoryChange(v, obj, &s_inventoryUse, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::gameStateChanged: case eLiveAPI_EventTypes::gameStateChanged:
msg = &s_gameStateChanged; ret = LiveAPI_HandleGameStateChanged(v, obj, reinterpret_cast<rtech::liveapi::GameStateChanged*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleGameStateChanged(v, obj, &s_gameStateChanged, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::matchStateEnd: case eLiveAPI_EventTypes::matchStateEnd:
msg = &s_matchStateEnd; ret = LiveAPI_HandleMatchStateEnd(v, obj, reinterpret_cast<rtech::liveapi::MatchStateEnd*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleMatchStateEnd(v, obj, &s_matchStateEnd, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::characterSelected: case eLiveAPI_EventTypes::characterSelected:
msg = &s_characterSelected; ret = LiveAPI_HandleSimplePlayerMessage(v, obj, reinterpret_cast<rtech::liveapi::CharacterSelected*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleSimplePlayerMessage(v, obj, &s_characterSelected, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::warpGateUsed: case eLiveAPI_EventTypes::warpGateUsed:
msg = &s_warpGateUsed; ret = LiveAPI_HandleSimplePlayerMessage(v, obj, reinterpret_cast<rtech::liveapi::WarpGateUsed*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleSimplePlayerMessage(v, obj, &s_warpGateUsed, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::wraithPortal: case eLiveAPI_EventTypes::wraithPortal:
msg = &s_wraithPortal; ret = LiveAPI_HandleSimplePlayerMessage(v, obj, reinterpret_cast<rtech::liveapi::WraithPortal*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleSimplePlayerMessage(v, obj, &s_wraithPortal, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::playerConnected: case eLiveAPI_EventTypes::playerConnected:
msg = &s_playerConnected; ret = LiveAPI_HandleSimplePlayerMessage(v, obj, reinterpret_cast<rtech::liveapi::PlayerConnected*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleSimplePlayerMessage(v, obj, &s_playerConnected, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::playerRevive: case eLiveAPI_EventTypes::playerRevive:
msg = &s_playerRevive; ret = LiveAPI_HandlePlayerRevive(v, obj, reinterpret_cast<rtech::liveapi::PlayerRevive*>(msg), eventType, fieldNum);
ret = LiveAPI_HandlePlayerRevive(v, obj, &s_playerRevive, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::playerDisconnected: case eLiveAPI_EventTypes::playerDisconnected:
msg = &s_playerDisconnected; ret = LiveAPI_HandlePlayerDisconnected(v, obj, reinterpret_cast<rtech::liveapi::PlayerDisconnected*>(msg), eventType, fieldNum);
ret = LiveAPI_HandlePlayerDisconnected(v, obj, &s_playerDisconnected, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::playerDamaged: case eLiveAPI_EventTypes::playerDamaged:
msg = &s_playerDamaged; ret = LiveAPI_HandlePlayerDamaged(v, obj, reinterpret_cast<rtech::liveapi::PlayerDamaged*>(msg), eventType, fieldNum);
ret = LiveAPI_HandlePlayerDamaged(v, obj, &s_playerDamaged, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::playerDowned: case eLiveAPI_EventTypes::playerDowned:
msg = &s_playerDowned; ret = LiveAPI_HandlePlayerDowned(v, obj, reinterpret_cast<rtech::liveapi::PlayerDowned*>(msg), eventType, fieldNum);
ret = LiveAPI_HandlePlayerDowned(v, obj, &s_playerDowned, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::playerKilled: case eLiveAPI_EventTypes::playerKilled:
msg = &s_playerKilled; ret = LiveAPI_HandlePlayerKilled(v, obj, reinterpret_cast<rtech::liveapi::PlayerKilled*>(msg), eventType, fieldNum);
ret = LiveAPI_HandlePlayerKilled(v, obj, &s_playerKilled, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::playerAssist: case eLiveAPI_EventTypes::playerAssist:
msg = &s_playerAssist; ret = LiveAPI_HandlePlayerAssist(v, obj, reinterpret_cast<rtech::liveapi::PlayerAssist*>(msg), eventType, fieldNum);
ret = LiveAPI_HandlePlayerAssist(v, obj, &s_playerAssist, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::playerRespawnTeam: case eLiveAPI_EventTypes::playerRespawnTeam:
msg = &s_playerRespawnTeam; ret = LiveAPI_HandlePlayerRespawnTeam(v, obj, reinterpret_cast<rtech::liveapi::PlayerRespawnTeam*>(msg), eventType, fieldNum);
ret = LiveAPI_HandlePlayerRespawnTeam(v, obj, &s_playerRespawnTeam, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::playerStatChanged: case eLiveAPI_EventTypes::playerStatChanged:
msg = &s_playerStatChanged; ret = LiveAPI_HandlePlayerStatChanged(v, obj, reinterpret_cast<rtech::liveapi::PlayerStatChanged*>(msg), eventType, fieldNum);
ret = LiveAPI_HandlePlayerStatChanged(v, obj, &s_playerStatChanged, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::playerUpgradeTierChanged: case eLiveAPI_EventTypes::playerUpgradeTierChanged:
msg = &s_playerUpgradeTierChanged; ret = LiveAPI_HandlePlayerUpgradeTierChanged(v, obj, reinterpret_cast<rtech::liveapi::PlayerUpgradeTierChanged*>(msg), eventType, fieldNum);
ret = LiveAPI_HandlePlayerUpgradeTierChanged(v, obj, &s_playerUpgradeTierChanged, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::legendUpgradeSelected: case eLiveAPI_EventTypes::legendUpgradeSelected:
msg = &s_legendUpgradeSelected; ret = LiveAPI_HandleLegendUpgradeSelected(v, obj, reinterpret_cast<rtech::liveapi::LegendUpgradeSelected*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleLegendUpgradeSelected(v, obj, &s_legendUpgradeSelected, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::gibraltarShieldAbsorbed: case eLiveAPI_EventTypes::gibraltarShieldAbsorbed:
msg = &s_gibraltarShieldAbsorbed; ret = LiveAPI_HandleAbilityDamaged(v, obj, reinterpret_cast<rtech::liveapi::GibraltarShieldAbsorbed*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleAbilityDamaged(v, obj, &s_gibraltarShieldAbsorbed, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::revenantForgedShadowDamaged: case eLiveAPI_EventTypes::revenantForgedShadowDamaged:
msg = &s_revenantForgedShadowDamaged; ret = LiveAPI_HandleAbilityDamaged(v, obj, reinterpret_cast<rtech::liveapi::RevenantForgedShadowDamaged*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleAbilityDamaged(v, obj, &s_revenantForgedShadowDamaged, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::ringStartClosing: case eLiveAPI_EventTypes::ringStartClosing:
msg = &s_ringStartClosing; ret = LiveAPI_HandleDeathFieldStartClosing(v, obj, reinterpret_cast<rtech::liveapi::RingStartClosing*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleDeathFieldStartClosing(v, obj, &s_ringStartClosing, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::ringFinishedClosing: case eLiveAPI_EventTypes::ringFinishedClosing:
msg = &s_ringFinishedClosing; ret = LiveAPI_HandleRingFinishedClosing(v, obj, reinterpret_cast<rtech::liveapi::RingFinishedClosing*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleRingFinishedClosing(v, obj, &s_ringFinishedClosing, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::squadEliminated: case eLiveAPI_EventTypes::squadEliminated:
msg = &s_squadEliminated; ret = LiveAPI_HandleSquadEliminated(v, obj, reinterpret_cast<rtech::liveapi::SquadEliminated*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleSquadEliminated(v, obj, &s_squadEliminated, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::ziplineUsed: case eLiveAPI_EventTypes::ziplineUsed:
msg = &s_ziplineUsed; ret = LiveAPI_HandleLinkedEntityEvent(v, obj, reinterpret_cast<rtech::liveapi::ZiplineUsed*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleLinkedEntityEvent(v, obj, &s_ziplineUsed, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::grenadeThrown: case eLiveAPI_EventTypes::grenadeThrown:
msg = &s_grenadeThrown; ret = LiveAPI_HandleLinkedEntityEvent(v, obj, reinterpret_cast<rtech::liveapi::GrenadeThrown*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleLinkedEntityEvent(v, obj, &s_grenadeThrown, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::playerAbilityUsed: case eLiveAPI_EventTypes::playerAbilityUsed:
msg = &s_playerAbilityUsed; ret = LiveAPI_HandleLinkedEntityEvent(v, obj, reinterpret_cast<rtech::liveapi::PlayerAbilityUsed*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleLinkedEntityEvent(v, obj, &s_playerAbilityUsed, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::weaponSwitched: case eLiveAPI_EventTypes::weaponSwitched:
msg = &s_weaponSwitched; ret = LiveAPI_HandleWeaponSwitchedEvent(v, obj, reinterpret_cast<rtech::liveapi::WeaponSwitched*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleWeaponSwitchedEvent(v, obj, &s_weaponSwitched, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::blackMarketAction: case eLiveAPI_EventTypes::blackMarketAction:
msg = &s_blackMarketAction; ret = LiveAPI_HandleBlackMarketActionEvent(v, obj, reinterpret_cast<rtech::liveapi::BlackMarketAction*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleBlackMarketActionEvent(v, obj, &s_blackMarketAction, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::observerSwitched: case eLiveAPI_EventTypes::observerSwitched:
msg = &s_observerSwitched; ret = LiveAPI_HandleObserverSwitched(v, obj, reinterpret_cast<rtech::liveapi::ObserverSwitched*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleObserverSwitched(v, obj, &s_observerSwitched, eventType, fieldNum);
break; break;
case eLiveAPI_EventTypes::observerAnnotation: case eLiveAPI_EventTypes::observerAnnotation:
msg = &s_observerAnnotation; ret = LiveAPI_HandleObserverAnnotation(v, obj, reinterpret_cast<rtech::liveapi::ObserverAnnotation*>(msg), eventType, fieldNum);
ret = LiveAPI_HandleObserverAnnotation(v, obj, &s_observerAnnotation, eventType, fieldNum);
break; break;
default: default:
v_SQVM_RaiseError(v, "Event type \"%d\" not found.", eventType); // LiveAPI_AllocMessage() will fail if the user provided an invalid
return false; // event type, if you reached this there is a code bug somewhere.
UNREACHABLE();
} }
if (!ret) if (!ret)
{ {
Assert(msg); Assert(msg);
delete msg;
msg->Clear();
return false; return false;
} }
} }
if (!msg) // Script bug, e.g. giving an empty table (either completely empty or filled with null) if (!ranLoop) // 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); v_SQVM_RaiseError(v, "Empty table on event type \"%d\".", eventType);
Assert(msg);
delete msg;
return false; return false;
} }
LiveAPI_SendEvent(msg); LiveAPI_SendEvent(msg);
msg->Clear(); delete msg;
return true; return true;
} }

View File

@ -240,7 +240,7 @@ namespace VScriptCode
if (!VALID_CHARSTAR(val)) if (!VALID_CHARSTAR(val))
{ {
v_SQVM_ScriptError("Empty or null class value"); v_SQVM_ScriptError("Empty or null class var");
SCRIPT_CHECK_AND_RETURN(v, SQ_ERROR); SCRIPT_CHECK_AND_RETURN(v, SQ_ERROR);
} }

View File

@ -27,7 +27,7 @@ namespace VScriptCode
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
SQRESULT GetSDKVersion(HSQUIRRELVM v) SQRESULT GetSDKVersion(HSQUIRRELVM v)
{ {
sq_pushstring(v, SDK_VERSION, sizeof(SDK_VERSION)-1); sq_pushstring(v, SDK_VERSION, -1);
SCRIPT_CHECK_AND_RETURN(v, SQ_OK); SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
} }
@ -47,7 +47,7 @@ namespace VScriptCode
{ {
const CUtlString& mapName = g_InstalledMaps[i]; const CUtlString& mapName = g_InstalledMaps[i];
sq_pushstring(v, mapName.String(), (SQInteger)mapName.Length()); sq_pushstring(v, mapName.String(), -1);
sq_arrayappend(v, -2); sq_arrayappend(v, -2);
} }
@ -65,7 +65,7 @@ namespace VScriptCode
sq_newarray(v, 0); sq_newarray(v, 0);
for (const CUtlString& it : g_vecAllPlaylists) for (const CUtlString& it : g_vecAllPlaylists)
{ {
sq_pushstring(v, it.String(), (SQInteger)it.Length()); sq_pushstring(v, it.String(), -1);
sq_arrayappend(v, -2); sq_arrayappend(v, -2);
} }

View File

@ -48,7 +48,6 @@ CBrowser::CBrowser(void)
: m_reclaimFocusOnTokenField(false) : m_reclaimFocusOnTokenField(false)
, m_queryNewListNonRecursive(false) , m_queryNewListNonRecursive(false)
, m_queryGlobalBanList(true) , m_queryGlobalBanList(true)
, m_lockedIconShaderResource(nullptr)
, m_hostMessageColor(1.00f, 1.00f, 1.00f, 1.00f) , m_hostMessageColor(1.00f, 1.00f, 1.00f, 1.00f)
, m_hiddenServerMessageColor(0.00f, 1.00f, 0.00f, 1.00f) , m_hiddenServerMessageColor(0.00f, 1.00f, 0.00f, 1.00f)
{ {
@ -58,6 +57,8 @@ CBrowser::CBrowser(void)
memset(m_serverAddressTextBuf, '\0', sizeof(m_serverAddressTextBuf)); memset(m_serverAddressTextBuf, '\0', sizeof(m_serverAddressTextBuf));
memset(m_serverNetKeyTextBuf, '\0', sizeof(m_serverNetKeyTextBuf)); memset(m_serverNetKeyTextBuf, '\0', sizeof(m_serverNetKeyTextBuf));
m_lockedIconDataResource = GetModuleResource(IDB_PNG2);
m_levelName = "mp_lobby"; m_levelName = "mp_lobby";
m_gameMode = "dev_default"; m_gameMode = "dev_default";
} }
@ -77,10 +78,7 @@ bool CBrowser::Init(void)
{ {
SetStyleVar(927.f, 524.f, -500.f, 50.f); SetStyleVar(927.f, 524.f, -500.f, 50.f);
HMODULE sdkModule = reinterpret_cast<HMODULE>(g_SDKDll.GetModuleBase()); bool ret = LoadTextureBuffer(reinterpret_cast<unsigned char*>(m_lockedIconDataResource.m_pData), int(m_lockedIconDataResource.m_nSize),
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); &m_lockedIconShaderResource, &m_lockedIconDataResource.m_nWidth, &m_lockedIconDataResource.m_nHeight);
IM_ASSERT(ret && m_lockedIconShaderResource); IM_ASSERT(ret && m_lockedIconShaderResource);
@ -193,9 +191,6 @@ void CBrowser::RunTask()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CBrowser::DrawSurface(void) bool CBrowser::DrawSurface(void)
{ {
if (!IsVisible())
return false;
if (!ImGui::Begin(m_surfaceLabel, &m_activated, ImGuiWindowFlags_None, &ResetInput)) if (!ImGui::Begin(m_surfaceLabel, &m_activated, ImGuiWindowFlags_None, &ResetInput))
{ {
ImGui::End(); ImGui::End();
@ -281,9 +276,9 @@ void CBrowser::DrawBrowserPanel(void)
const char* pszHostMap = server.map.c_str(); const char* pszHostMap = server.map.c_str();
const char* pszPlaylist = server.playlist.c_str(); const char* pszPlaylist = server.playlist.c_str();
if (m_serverBrowserTextFilter.PassFilter(pszHostName, &pszHostName[server.name.length()]) if (m_serverBrowserTextFilter.PassFilter(pszHostName)
|| m_serverBrowserTextFilter.PassFilter(pszHostMap, &pszHostMap[server.map.length()]) || m_serverBrowserTextFilter.PassFilter(pszHostMap)
|| m_serverBrowserTextFilter.PassFilter(pszPlaylist, &pszPlaylist[server.playlist.length()])) || m_serverBrowserTextFilter.PassFilter(pszPlaylist))
{ {
filteredServers.push_back(&server); filteredServers.push_back(&server);
} }
@ -297,32 +292,28 @@ void CBrowser::DrawBrowserPanel(void)
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
{ {
const NetGameServer_t* const server = filteredServers[i]; const NetGameServer_t* const server = filteredServers[i];
const ImGuiTextFlags textFlags = ImGuiTextFlags_NoWidthForLargeClippedText;
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);
ImGui::TableNextColumn(); 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::TableNextColumn();
ImGui::Text("%s", pszHostMap);
const char* const pszHostMap = server->map.c_str();
ImGui::TextEx(pszHostMap, &pszHostMap[server->map.length()], textFlags);
ImGui::TableNextColumn(); 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::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::TableNextColumn();
ImGui::Text("%d", server->port); ImGui::Text("%s", pszHostPort);
ImGui::TableNextColumn(); ImGui::TableNextColumn();
string svConnectBtn = "Connect##"; string svConnectBtn = "Connect##";
@ -818,11 +809,11 @@ void CBrowser::UpdateHostingStatus(void)
break; break;
} }
NetGameServer_t netGameServer const NetGameServer_t netGameServer
{ {
hostname->GetString(), hostname->GetString(),
hostdesc.GetString(), hostdesc.GetString(),
serverVisibility == ServerVisibility_e::HIDDEN, serverVisibility == ServerVisibility_e::PUBLIC,
g_pHostState->m_levelName, g_pHostState->m_levelName,
v_Playlists_GetCurrent(), v_Playlists_GetCurrent(),
hostip->GetString(), hostip->GetString(),
@ -851,10 +842,10 @@ void CBrowser::UpdateHostingStatus(void)
// host data on the server browser // host data on the server browser
// Input : &gameServer - // Input : &gameServer -
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CBrowser::SendHostingPostRequest(NetGameServer_t& gameServer) void CBrowser::SendHostingPostRequest(const NetGameServer_t& gameServer)
{ {
#ifndef CLIENT_DLL #ifndef CLIENT_DLL
std::thread request([&, gameServer = std::move(gameServer)] std::thread request([&, gameServer]
{ {
string hostRequestMessage; string hostRequestMessage;
string hostToken; string hostToken;
@ -864,7 +855,7 @@ void CBrowser::SendHostingPostRequest(NetGameServer_t& gameServer)
g_TaskQueue.Dispatch([&, result, hostRequestMessage, hostToken, hostIp] g_TaskQueue.Dispatch([&, result, hostRequestMessage, hostToken, hostIp]
{ {
InstallHostingDetails(result, hostRequestMessage, hostToken, hostIp); InstallHostingDetails(result, hostRequestMessage.c_str(), hostToken.c_str(), hostIp);
}, 0); }, 0);
} }
); );
@ -879,7 +870,7 @@ void CBrowser::SendHostingPostRequest(NetGameServer_t& gameServer)
// *hostToken - // *hostToken -
// &hostIp - // &hostIp -
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CBrowser::InstallHostingDetails(const bool postFailed, const string& hostMessage, const string& hostToken, const string& hostIp) void CBrowser::InstallHostingDetails(const bool postFailed, const char* const hostMessage, const char* const hostToken, const string& hostIp)
{ {
#ifndef CLIENT_DLL #ifndef CLIENT_DLL
m_hostMessage = hostMessage; m_hostMessage = hostMessage;
@ -893,10 +884,14 @@ void CBrowser::InstallHostingDetails(const bool postFailed, const string& hostMe
if (postFailed) if (postFailed)
{ {
m_hostMessageColor = ImVec4(0.00f, 1.00f, 0.00f, 1.00f); 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 = m_hostToken.empty() m_hostMessage = ssMessage.str();
? "Broadcasting"
: "Broadcasting: share the following token for clients to connect: ";
} }
else else
{ {

View File

@ -31,8 +31,8 @@ public:
void DrawHostPanel(void); void DrawHostPanel(void);
void UpdateHostingStatus(void); void UpdateHostingStatus(void);
void InstallHostingDetails(const bool postFailed, const string& hostMessage, const string& hostToken, const string& hostIp); void InstallHostingDetails(const bool postFailed, const char* const hostMessage, const char* const hostToken, const string& hostIp);
void SendHostingPostRequest(NetGameServer_t& gameServer); void SendHostingPostRequest(const NetGameServer_t& gameServer);
void ProcessCommand(const char* pszCommand) const; void ProcessCommand(const char* pszCommand) const;

View File

@ -129,6 +129,8 @@ void CConsole::RunFrame(void)
if (m_surfaceStyle == ImGuiStyle_t::MODERN) if (m_surfaceStyle == ImGuiStyle_t::MODERN)
{ {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 8.f, 10.f }); baseWindowStyleVars++; ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 8.f, 10.f }); baseWindowStyleVars++;
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_fadeAlpha); baseWindowStyleVars++;
minBaseWindowRect = ImVec2(621.f, 532.f); minBaseWindowRect = ImVec2(621.f, 532.f);
} }
else else
@ -138,9 +140,9 @@ void CConsole::RunFrame(void)
: ImVec2(618.f, 524.f); : ImVec2(618.f, 524.f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 6.f, 6.f }); baseWindowStyleVars++; 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++; ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, minBaseWindowRect); baseWindowStyleVars++;
const bool drawn = DrawSurface(); const bool drawn = DrawSurface();
@ -186,9 +188,6 @@ void CConsole::RunFrame(void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CConsole::DrawSurface(void) bool CConsole::DrawSurface(void)
{ {
if (!IsVisible())
return false;
if (!ImGui::Begin(m_surfaceLabel, &m_activated, ImGuiWindowFlags_None, &ResetInput)) if (!ImGui::Begin(m_surfaceLabel, &m_activated, ImGuiWindowFlags_None, &ResetInput))
{ {
ImGui::End(); ImGui::End();
@ -360,7 +359,7 @@ void CConsole::DrawOptionsPanel(void)
m_colorTextLogger.Copy(true); m_colorTextLogger.Copy(true);
} }
ImGui::TextEx("Console HotKey:", nullptr, ImGuiTextFlags_NoWidthForLargeClippedText); ImGui::Text("Console HotKey:");
ImGui::SameLine(); ImGui::SameLine();
int selected = g_ImGuiConfig.m_ConsoleConfig.m_nBind0; int selected = g_ImGuiConfig.m_ConsoleConfig.m_nBind0;
@ -382,7 +381,7 @@ void CConsole::DrawOptionsPanel(void)
g_ImGuiConfig.Save(); g_ImGuiConfig.Save();
} }
ImGui::TextEx("Browser HotKey:", nullptr, ImGuiTextFlags_NoWidthForLargeClippedText); ImGui::Text("Browser HotKey:");
ImGui::SameLine(); ImGui::SameLine();
selected = g_ImGuiConfig.m_BrowserConfig.m_nBind0; selected = g_ImGuiConfig.m_BrowserConfig.m_nBind0;
@ -508,7 +507,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::Image(hintRes.m_idIcon, ImVec2(float(hintRes.m_nWidth), float(hintRes.m_nHeight)));
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextEx(cvarInfo.shortdesc, nullptr, ImGuiTextFlags_NoWidthForLargeClippedText); ImGui::Text("%s", cvarInfo.shortdesc);
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -590,7 +589,7 @@ void CConsole::DrawAutoCompletePanel(void)
m_canAutoComplete = true; m_canAutoComplete = true;
m_reclaimFocus = true; m_reclaimFocus = true;
BuildSummaryText(newInputText.c_str(), newInputText.size()); BuildSummaryText(newInputText.c_str());
} }
ImGui::PopID(); ImGui::PopID();
@ -665,7 +664,7 @@ bool CConsole::RunAutoComplete(void)
{ {
const char c = m_inputTextBuf[i]; const char c = m_inputTextBuf[i];
if (c == '\0' || V_isspace(c)) if (c == '\0' || isspace(c))
{ {
break; break;
} }
@ -688,8 +687,7 @@ bool CConsole::RunAutoComplete(void)
for (int j = 0; j < iret; ++j) for (int j = 0; j < iret; ++j)
{ {
const CUtlString& cmdToAdd = commands[j]; m_vecSuggest.push_back(ConAutoCompleteSuggest_s(commands[j].String(), COMMAND_COMPLETION_MARKER));
m_vecSuggest.emplace_back(cmdToAdd.String(), cmdToAdd.Length(), COMMAND_COMPLETION_MARKER);
} }
} }
else else
@ -719,25 +717,14 @@ void CConsole::ResetAutoCompleteData(void)
m_vecSuggest.clear(); 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 // Purpose: format appends the value string
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void AppendValueString(string& targetString, const char* const toAppend) static void AppendValueString(string& targetString, const char* const toAppend)
{ {
EncaseAppendString(targetString, toAppend, " = [", "]"); targetString.append(" = ["); // Assign current value to string if its a ConVar.
targetString.append(toAppend);
targetString.append("]");
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -745,12 +732,12 @@ static void AppendValueString(string& targetString, const char* const toAppend)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void AppendDocString(string& targetString, const char* const toAppend) static void AppendDocString(string& targetString, const char* const toAppend)
{ {
if (!VALID_CHARSTAR(toAppend)) if (VALID_CHARSTAR(toAppend))
{ {
return; targetString.append(" - \"");
targetString.append(toAppend);
targetString.append("\"");
} }
EncaseAppendString(targetString, toAppend, " - \"", "\"");
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -799,7 +786,7 @@ void CConsole::CreateSuggestionsFromPartial(void)
AppendDocString(docString, commandBase->GetHelpText()); AppendDocString(docString, commandBase->GetHelpText());
AppendDocString(docString, commandBase->GetUsageText()); AppendDocString(docString, commandBase->GetUsageText());
} }
m_vecSuggest.emplace_back(commandName + docString, commandBase->GetFlags()); m_vecSuggest.push_back(ConAutoCompleteSuggest_s(commandName + docString, commandBase->GetFlags()));
} }
else else
{ {
@ -839,11 +826,11 @@ void CConsole::ProcessCommand(const char* const inputText)
// formats the number of history items instead // formats the number of history items instead
// Input : inputText - // Input : inputText -
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CConsole::BuildSummaryText(const char* const inputText, const size_t textLen) void CConsole::BuildSummaryText(const char* const inputText)
{ {
if (textLen > 0) if (*inputText)
{ {
string conVarFormatted(inputText, textLen); string conVarFormatted(inputText);
// Remove trailing space and/or semicolon before we call 'g_pCVar->FindVar(..)'. // Remove trailing space and/or semicolon before we call 'g_pCVar->FindVar(..)'.
StringRTrim(conVarFormatted, " ;", true); StringRTrim(conVarFormatted, " ;", true);
@ -924,19 +911,22 @@ void CConsole::DetermineAutoCompleteWindowRect(void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CConsole::LoadFlagIcons(void) bool CConsole::LoadFlagIcons(void)
{ {
HMODULE sdkModule = reinterpret_cast<HMODULE>(g_SDKDll.GetModuleBase());
bool ret = false; bool ret = false;
// Get all flag image resources for displaying flags. // Get all flag image resources for displaying flags.
for (int i = IDB_PNG3, k = NULL; i <= IDB_PNG32; i++, k++) for (int i = IDB_PNG3, k = NULL; i <= IDB_PNG32; i++, k++)
{ {
m_vecFlagIcons.emplace_back(GetModuleResource(sdkModule, i)); m_vecFlagIcons.push_back(MODULERESOURCE(GetModuleResource(i)));
MODULERESOURCE& rFlagIcon = m_vecFlagIcons[k]; MODULERESOURCE& rFlagIcon = m_vecFlagIcons[k];
ret = LoadTextureBuffer(reinterpret_cast<unsigned char*>(rFlagIcon.m_pData), // !TODO: Fall-back texture. 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); static_cast<int>(rFlagIcon.m_nSize), &rFlagIcon.m_idIcon, &rFlagIcon.m_nWidth, &rFlagIcon.m_nHeight);
Assert(ret, "Texture flags load failed for %i", i); if (!ret)
{
Assert(0, "Texture flags load failed for %i", i);
break;
}
} }
m_autoCompleteTexturesLoaded = ret; m_autoCompleteTexturesLoaded = ret;
@ -1033,7 +1023,7 @@ int CConsole::TextEditCallback(ImGuiInputTextCallbackData* iData)
} }
} }
BuildSummaryText(iData->Buf, iData->BufTextLen); BuildSummaryText(iData->Buf);
break; break;
} }
case ImGuiInputTextFlags_CallbackAlways: case ImGuiInputTextFlags_CallbackAlways:
@ -1098,7 +1088,7 @@ int CConsole::TextEditCallback(ImGuiInputTextCallbackData* iData)
ResetAutoCompleteData(); ResetAutoCompleteData();
} }
BuildSummaryText(iData->Buf, iData->BufTextLen); BuildSummaryText(iData->Buf);
break; break;
} }
} }
@ -1130,7 +1120,7 @@ void CConsole::HandleCommand()
m_inputTextBufModified = true; m_inputTextBufModified = true;
} }
BuildSummaryText("", 0); BuildSummaryText("");
m_reclaimFocus = true; m_reclaimFocus = true;
} }
@ -1155,7 +1145,7 @@ void CConsole::HandleSuggest()
const int vecIndex = parked ? 0 : m_suggestPos; const int vecIndex = parked ? 0 : m_suggestPos;
DetermineInputTextFromSelectedSuggestion(m_vecSuggest[vecIndex], m_selectedSuggestionText); DetermineInputTextFromSelectedSuggestion(m_vecSuggest[vecIndex], m_selectedSuggestionText);
BuildSummaryText(m_selectedSuggestionText.c_str(), m_selectedSuggestionText.size()); BuildSummaryText(m_selectedSuggestionText.c_str());
m_inputTextBufModified = true; m_inputTextBufModified = true;
m_reclaimFocus = true; m_reclaimFocus = true;
@ -1277,7 +1267,7 @@ void CConsole::ClampLogSize(void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: adds a command to the history vector; this is the only place text // Purpose: adds a command to the history vector; this is the only place text
// is added to the vector, do not call 'm_History.emplace_back' elsewhere as we // is added to the vector, do not call 'm_History.push_back' elsewhere as we
// also manage the size of the vector here !!! // also manage the size of the vector here !!!
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CConsole::AddHistory(const char* const command) void CConsole::AddHistory(const char* const command)
@ -1293,7 +1283,7 @@ void CConsole::AddHistory(const char* const command)
} }
} }
m_vecHistory.emplace_back(command); m_vecHistory.push_back(command);
ClampHistorySize(); ClampHistorySize();
} }
@ -1312,7 +1302,7 @@ const vector<string>& CConsole::GetHistory(void) const
void CConsole::ClearHistory(void) void CConsole::ClearHistory(void)
{ {
m_vecHistory.clear(); m_vecHistory.clear();
BuildSummaryText("", 0); BuildSummaryText("");
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -30,7 +30,7 @@ private:
void CreateSuggestionsFromPartial(void); void CreateSuggestionsFromPartial(void);
void ProcessCommand(const char* const inputText); void ProcessCommand(const char* const inputText);
void BuildSummaryText(const char* const inputText, const size_t textLen); void BuildSummaryText(const char* const inputText);
struct ConAutoCompleteSuggest_s; struct ConAutoCompleteSuggest_s;
void DetermineInputTextFromSelectedSuggestion(const ConAutoCompleteSuggest_s& suggest, string& svInput); void DetermineInputTextFromSelectedSuggestion(const ConAutoCompleteSuggest_s& suggest, string& svInput);
@ -83,11 +83,6 @@ private:
text = inText; text = inText;
flags = inFlags; 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 bool operator==(const string& a) const
{ {
return text.compare(a) == 0; return text.compare(a) == 0;

View File

@ -1,218 +0,0 @@
/******************************************************************************
-------------------------------------------------------------------------------
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);
}

View File

@ -1,36 +0,0 @@
#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;

View File

@ -23,8 +23,8 @@ public:
// inlines: // inlines:
inline void ToggleActive() { m_activated ^= true; } inline void ToggleActive() { m_activated ^= true; }
inline bool IsActivated() const { return m_activated; } inline bool IsActivated() { return m_activated; }
inline bool IsVisible() const { return m_fadeAlpha > 0.0f; } inline bool IsVisible() { return m_fadeAlpha > 0.0f; }
protected: protected:
const char* m_surfaceLabel; const char* m_surfaceLabel;

View File

@ -91,8 +91,6 @@ void CImguiSystem::Shutdown()
m_initialized = false; m_initialized = false;
m_hasNewFrame = false; m_hasNewFrame = false;
m_surfaceList.Purge();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -10,8 +10,6 @@ add_sources( SOURCE_GROUP "Private"
"cmaterialsystem.h" "cmaterialsystem.h"
"cshaderglue.cpp" "cshaderglue.cpp"
"cshaderglue.h" "cshaderglue.h"
"texturestreaming.cpp"
"texturestreaming.h"
) )
add_sources( SOURCE_GROUP "Public" add_sources( SOURCE_GROUP "Public"

View File

@ -5,89 +5,75 @@
#include "public/materialsystem/shader_vcs_version.h" #include "public/materialsystem/shader_vcs_version.h"
#include "public/rendersystem/schema/texture.g.h" #include "public/rendersystem/schema/texture.g.h"
#define MATERIAL_RENDER_PARAMS_COUNT 2 // the same for r2 and r5 struct MaterialDXState_t
#define MATERIAL_SAMPLER_COUNT 4
class CMaterialGlue;
enum MaterialDepthPass_e
{ {
DEPTH_SHADOW, uint32_t blendState[8];
DEPTH_PREPASS, unsigned int unkFlags;
DEPTH_VSM, unsigned __int16 depthStencilFlags;
DEPTH_SHADOW_TIGHT, unsigned __int16 rasterizerFlags;
char pad[8];
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 class CMaterialGlue : public IMaterialInternal
{ {
public: public:
inline const MaterialGlue_s* Get() const { return &material; } uint8_t pad_0008[8]; //0x0008
inline MaterialGlue_s* Get() { return &material; } uint64_t assetGuid; //0x0010
const char* name; //0x0018
private: const char* surfaceProp; //0x0020
byte reserved[8]; const char* surfaceProp2; //0x0028
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. }; //Size: 0x0130 confirmed end size.
static_assert(sizeof(CMaterialGlue) == 0x130); static_assert(sizeof(CMaterialGlue) == 0x130);
#pragma pack(pop)
#endif // !DEDICATED #endif // !DEDICATED
inline void* g_pMaterialGlueVFTable = nullptr; inline void* g_pMaterialGlueVFTable = nullptr;

View File

@ -18,7 +18,6 @@
#include "windows/id3dx.h" #include "windows/id3dx.h"
#include "gameui/imgui_system.h" #include "gameui/imgui_system.h"
#include "materialsystem/cmaterialglue.h" #include "materialsystem/cmaterialglue.h"
#include "materialsystem/texturestreaming.h"
#endif // !MATERIALSYSTEM_NODX #endif // !MATERIALSYSTEM_NODX
#include "materialsystem/cmaterialsystem.h" #include "materialsystem/cmaterialsystem.h"
@ -47,10 +46,10 @@ static bool s_useLowLatency = false;
InitReturnVal_t CMaterialSystem::Init(CMaterialSystem* thisptr) InitReturnVal_t CMaterialSystem::Init(CMaterialSystem* thisptr)
{ {
#ifdef MATERIALSYSTEM_NODX #ifdef MATERIALSYSTEM_NODX
// Only load the startup pak files, as 'common_early.rpak' has assets // Only load the 'startup.rpak' file, as 'common_early.rpak' has assets
// that references assets in 'startup.rpak'. // that references assets in 'startup.rpak'.
g_pakLoadApi->LoadAsyncAndWait("startup.rpak", AlignedMemAlloc(), 5, 0); const PakHandle_t pakHandle = g_pakLoadApi->LoadAsync("startup.rpak", AlignedMemAlloc(), 5, 0);
g_pakLoadApi->LoadAsyncAndWait("startup_sdk.rpak", AlignedMemAlloc(), 5, 0); g_pakLoadApi->WaitForAsyncLoad(pakHandle, nullptr);
// Trick: return INIT_FAILED to disable the loading of hardware // Trick: return INIT_FAILED to disable the loading of hardware
// configuration data, since we don't need it on the dedi. // configuration data, since we don't need it on the dedi.
@ -71,14 +70,7 @@ InitReturnVal_t CMaterialSystem::Init(CMaterialSystem* thisptr)
g_PCLStatsAvailable = true; g_PCLStatsAvailable = true;
} }
const InitReturnVal_t result = CMaterialSystem__Init(thisptr); return 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 #endif
} }
@ -102,6 +94,33 @@ int CMaterialSystem::Shutdown(CMaterialSystem* thisptr)
} }
#ifndef MATERIALSYSTEM_NODX #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 // Purpose: draw frame
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
@ -181,57 +200,6 @@ Vector2D CMaterialSystem::GetScreenSize(CMaterialSystem* pMatSys)
return vecScreenSize; 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 #endif // !MATERIALSYSTEM_NODX
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -247,9 +215,7 @@ void VMaterialSystem::Detour(const bool bAttach) const
DetourSetup(&CMaterialSystem__SwapBuffers, &CMaterialSystem::SwapBuffers, bAttach); DetourSetup(&CMaterialSystem__SwapBuffers, &CMaterialSystem::SwapBuffers, bAttach);
DetourSetup(&CMaterialSystem__FindMaterialEx, &CMaterialSystem::FindMaterialEx, bAttach); DetourSetup(&CMaterialSystem__FindMaterialEx, &CMaterialSystem::FindMaterialEx, bAttach);
DetourSetup(&CMaterialSystem__CreditModelTextures, &CMaterialSystem::CreditModelTextures, bAttach); DetourSetup(&v_StreamDB_Init, &StreamDB_Init, bAttach);
DetourSetup(&CMaterialSystem__UpdateStreamCamera, &CMaterialSystem::UpdateStreamCamera, bAttach);
DetourSetup(&v_DispatchDrawCall, &DispatchDrawCall, bAttach); DetourSetup(&v_DispatchDrawCall, &DispatchDrawCall, bAttach);
DetourSetup(&v_SpinPresent, &SpinPresent, bAttach); DetourSetup(&v_SpinPresent, &SpinPresent, bAttach);
#endif // !MATERIALSYSTEM_NODX #endif // !MATERIALSYSTEM_NODX

View File

@ -3,6 +3,8 @@
#include "cmaterialglue.h" #include "cmaterialglue.h"
#include "public/imaterialsystem.h" #include "public/imaterialsystem.h"
#define STREAM_DB_EXT "stbsp"
class CMaterialSystem class CMaterialSystem
{ {
public: public:
@ -15,9 +17,6 @@ public:
static void* SwapBuffers(CMaterialSystem* pMatSys); static void* SwapBuffers(CMaterialSystem* pMatSys);
static CMaterialGlue* FindMaterialEx(CMaterialSystem* pMatSys, const char* pMaterialName, uint8_t nMaterialType, int nUnk, bool bComplain); static CMaterialGlue* FindMaterialEx(CMaterialSystem* pMatSys, const char* pMaterialName, uint8_t nMaterialType, int nUnk, bool bComplain);
static Vector2D GetScreenSize(CMaterialSystem* pMatSys = nullptr); 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 #endif // !MATERIALSYSTEM_NODX
// TODO: reverse the vftable! // TODO: reverse the vftable!
@ -76,15 +75,20 @@ inline void*(*CMaterialSystem__SwapBuffers)(CMaterialSystem* pMatSys);
inline CMaterialGlue*(*CMaterialSystem__FindMaterialEx)(CMaterialSystem* pMatSys, const char* pMaterialName, uint8_t nMaterialType, int nUnk, bool bComplain); 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__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 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 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 #endif // !MATERIALSYSTEM_NODX
inline void(*v_StreamDB_Init)(const char* const pszLevelName);
#ifndef MATERIALSYSTEM_NODX #ifndef MATERIALSYSTEM_NODX
inline void** s_pRenderContext; // NOTE: This is some CMaterial instance or array. 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 #endif // !MATERIALSYSTEM_NODX
// TODO: move to materialsystem_global.h! // TODO: move to materialsystem_global.h!
@ -108,13 +112,17 @@ class VMaterialSystem : public IDetour
LogFunAdr("CMaterialSystem::SwapBuffers", CMaterialSystem__SwapBuffers); LogFunAdr("CMaterialSystem::SwapBuffers", CMaterialSystem__SwapBuffers);
LogFunAdr("CMaterialSystem::FindMaterialEx", CMaterialSystem__FindMaterialEx); LogFunAdr("CMaterialSystem::FindMaterialEx", CMaterialSystem__FindMaterialEx);
LogFunAdr("CMaterialSystem::GetScreenSize", CMaterialSystem__GetScreenSize); LogFunAdr("CMaterialSystem::GetScreenSize", CMaterialSystem__GetScreenSize);
LogFunAdr("CMaterialSystem::CreditModelTextures", CMaterialSystem__CreditModelTextures); LogFunAdr("CMaterialSystem::GetStreamOverlay", CMaterialSystem__GetStreamOverlay);
LogFunAdr("CMaterialSystem::UpdateStreamCamera", CMaterialSystem__UpdateStreamCamera); LogFunAdr("CMaterialSystem::DrawStreamOverlay", CMaterialSystem__DrawStreamOverlay);
LogFunAdr("DispatchDrawCall", v_DispatchDrawCall); LogFunAdr("DispatchDrawCall", v_DispatchDrawCall);
LogFunAdr("SpinPresent", v_SpinPresent); LogFunAdr("SpinPresent", v_SpinPresent);
#endif // !MATERIALSYSTEM_NODX #endif // !MATERIALSYSTEM_NODX
LogFunAdr("StreamDB_Init", v_StreamDB_Init);
#ifndef MATERIALSYSTEM_NODX #ifndef MATERIALSYSTEM_NODX
LogVarAdr("g_nTotalStreamingTextureMemory", g_nTotalStreamingTextureMemory);
LogVarAdr("g_nUnfreeStreamingTextureMemory", g_nUnfreeStreamingTextureMemory);
LogVarAdr("g_nUnusableStreamingTextureMemory", g_nUnusableStreamingTextureMemory);
LogVarAdr("s_pRenderContext", s_pRenderContext); LogVarAdr("s_pRenderContext", s_pRenderContext);
LogVarAdr("g_MaterialAdapterMgr", g_pMaterialAdapterMgr); LogVarAdr("g_MaterialAdapterMgr", g_pMaterialAdapterMgr);
#endif // !MATERIALSYSTEM_NODX #endif // !MATERIALSYSTEM_NODX
@ -132,17 +140,22 @@ 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("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("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("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("41 56 B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 C6 02 ??").GetPtr(CMaterialSystem__DrawStreamOverlay);
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("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); g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 8B 15 ?? ?? ?? ??").GetPtr(v_SpinPresent);
#endif // !MATERIALSYSTEM_NODX #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 virtual void GetVar(void) const
{ {
#ifndef MATERIALSYSTEM_NODX #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(v_DispatchDrawCall).FindPattern("48 8B ?? ?? ?? ?? 01").ResolveRelativeAddressSelf(0x3, 0x7).GetPtr(s_pRenderContext);
CMemory(CMaterialSystem__Disconnect).FindPattern("48 8D").ResolveRelativeAddressSelf(0x3, 0x7).GetPtr(g_pMaterialAdapterMgr); CMemory(CMaterialSystem__Disconnect).FindPattern("48 8D").ResolveRelativeAddressSelf(0x3, 0x7).GetPtr(g_pMaterialAdapterMgr);
#endif // !MATERIALSYSTEM_NODX #endif // !MATERIALSYSTEM_NODX

View File

@ -1,69 +0,0 @@
#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);
}

View File

@ -1,178 +0,0 @@
//=============================================================================//
//
// 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

View File

@ -35,7 +35,7 @@ void scanDirectoryAppend(const string& path, const string& ext, vector<string>&
do do
{ {
filelist.emplace_back(dir.name); filelist.push_back(dir.name);
} }
while (_findnext(fh, &dir) == 0); while (_findnext(fh, &dir) == 0);
_findclose(fh); _findclose(fh);
@ -53,7 +53,7 @@ void scanDirectoryAppend(const string& path, const string& ext, vector<string>&
int len = strlen(current->d_name); int len = strlen(current->d_name);
if (len > extLen && strncmp(current->d_name + len - extLen, ext.c_str(), extLen) == 0) if (len > extLen && strncmp(current->d_name + len - extLen, ext.c_str(), extLen) == 0)
{ {
filelist.emplace_back(current->d_name); filelist.push_back(current->d_name);
} }
} }
closedir(dp); closedir(dp);

View File

@ -277,7 +277,7 @@ bool sdl_init(SDL_Window*& window, SDL_Renderer*& renderer, int &width, int &hei
SDL_DisplayMode displayMode; SDL_DisplayMode displayMode;
SDL_GetCurrentDisplayMode(0, &displayMode); SDL_GetCurrentDisplayMode(0, &displayMode);
Uint32 flags = SDL_WINDOW_OPENGL | SDL_RENDERER_PRESENTVSYNC | SDL_WINDOW_RESIZABLE; Uint32 flags = SDL_WINDOW_OPENGL | SDL_RENDERER_PRESENTVSYNC;
if (presentationMode) if (presentationMode)
{ {
// Create a fullscreen window at the native resolution. // Create a fullscreen window at the native resolution.
@ -752,24 +752,6 @@ int not_main(int argc, char** argv)
} }
break; 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: case SDL_QUIT:
done = true; done = true;
break; break;

View File

@ -24,10 +24,6 @@ add_sources( SOURCE_GROUP "Engine"
"${ENGINE_SOURCE_DIR}/engine/shared/shared_rcon.h" "${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" add_sources( SOURCE_GROUP "Windows"
"${ENGINE_SOURCE_DIR}/windows/console.cpp" "${ENGINE_SOURCE_DIR}/windows/console.cpp"
"${ENGINE_SOURCE_DIR}/windows/console.h" "${ENGINE_SOURCE_DIR}/windows/console.h"

View File

@ -172,10 +172,8 @@ BOOL WINAPI CNetCon::CloseHandler(DWORD eventCode)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CNetCon::TermSetup(const bool bAnsiColor) void CNetCon::TermSetup(const bool bAnsiColor)
{ {
if (bAnsiColor)
Console_ColorInit();
SpdLog_Init(bAnsiColor); SpdLog_Init(bAnsiColor);
Console_Init(bAnsiColor);
// Handle ctrl+x or X close events, give the application time to shutdown // Handle ctrl+x or X close events, give the application time to shutdown
// properly and flush all logging buffers. // properly and flush all logging buffers.
@ -195,7 +193,7 @@ void CNetCon::TrySetKey(const char* const pKey)
if (!*pKey) if (!*pKey)
{ {
Warning(eDLL_T::CLIENT, "No key provided; using default %s'%s%s%s'\n", Warning(eDLL_T::CLIENT, "No key provided; using default %s'%s%s%s'\n",
g_svReset.c_str(), g_svGreyB.c_str(), DEFAULT_NET_ENCRYPTION_KEY, g_svReset.c_str()); g_svReset, g_svGreyB, DEFAULT_NET_ENCRYPTION_KEY, g_svReset);
SetKey(DEFAULT_NET_ENCRYPTION_KEY, true); SetKey(DEFAULT_NET_ENCRYPTION_KEY, true);
} }
@ -235,7 +233,7 @@ void CNetCon::RunInput(const string& lineInput)
return; return;
} }
vector<byte> vecMsg; vector<char> vecMsg;
const SocketHandle_t hSocket = GetSocket(); const SocketHandle_t hSocket = GetSocket();
bool bSend = false; bool bSend = false;
@ -244,27 +242,18 @@ void CNetCon::RunInput(const string& lineInput)
{ {
if (V_strcmp(cmd.Arg(0), "PASS") == 0) // Auth with RCON server. if (V_strcmp(cmd.Arg(0), "PASS") == 0) // Auth with RCON server.
{ {
const char* const pass = cmd.Arg(1); bSend = Serialize(vecMsg, cmd.Arg(1), "",
const size_t passLen = strlen(pass);
bSend = Serialize(vecMsg, pass, passLen, "", 0,
netcon::request_e::SERVERDATA_REQUEST_AUTH); netcon::request_e::SERVERDATA_REQUEST_AUTH);
} }
else // Execute command query. else // Execute command query.
{ {
const char* const request = cmd.Arg(0); bSend = Serialize(vecMsg, cmd.Arg(0), cmd.GetCommandString(),
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); netcon::request_e::SERVERDATA_REQUEST_EXECCOMMAND);
} }
} }
else // Single arg command query. else // Single arg command query.
{ {
bSend = Serialize(vecMsg, lineInput.c_str(), lineInput.length(), "", 0, netcon::request_e::SERVERDATA_REQUEST_EXECCOMMAND); bSend = Serialize(vecMsg, lineInput.c_str(), "", netcon::request_e::SERVERDATA_REQUEST_EXECCOMMAND);
} }
if (bSend) // Only send if serialization process was successful. if (bSend) // Only send if serialization process was successful.
@ -326,7 +315,7 @@ bool CNetCon::RunFrame(void)
if (IsConnected()) if (IsConnected())
{ {
ConnectedNetConsoleData_s& pData = GetSocketCreator()->GetAcceptedSocketData(0); CConnectedNetConsoleData& pData = GetSocketCreator()->GetAcceptedSocketData(0);
Recv(pData); Recv(pData);
} }
else if (GetPrompting()) else if (GetPrompting())
@ -388,7 +377,7 @@ bool CNetCon::Connect(const char* pHostName, const int nPort)
if (m_bEncryptFrames) if (m_bEncryptFrames)
{ {
Msg(eDLL_T::CLIENT, "Attempting connection to '%s' with key %s'%s%s%s'\n", Msg(eDLL_T::CLIENT, "Attempting connection to '%s' with key %s'%s%s%s'\n",
pHostName, g_svReset.c_str(), g_svGreyB.c_str(), GetKey(), g_svReset.c_str()); pHostName, g_svReset, g_svGreyB, GetKey(), g_svReset);
} }
else else
{ {
@ -424,7 +413,7 @@ void CNetCon::Disconnect(const char* szReason)
// nMsgLen - // nMsgLen -
// Output : true on success, false otherwise // Output : true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CNetCon::ProcessMessage(const byte* pMsgBuf, const u32 nMsgLen) bool CNetCon::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
{ {
netcon::response response; netcon::response response;
@ -443,10 +432,10 @@ bool CNetCon::ProcessMessage(const byte* pMsgBuf, const u32 nMsgLen)
const long i = strtol(response.responseval().c_str(), NULL, NULL); const long i = strtol(response.responseval().c_str(), NULL, NULL);
if (!i) // Means we are marked 'input only' on the rcon server. if (!i) // Means we are marked 'input only' on the rcon server.
{ {
vector<byte> vecMsg; vector<char> vecMsg;
const bool ret = Serialize(vecMsg, "", 0, "1", 1, netcon::request_e::SERVERDATA_REQUEST_SEND_CONSOLE_LOG); bool ret = Serialize(vecMsg, "", "1", netcon::request_e::SERVERDATA_REQUEST_SEND_CONSOLE_LOG);
if (ret && !Send(GetSocket(), vecMsg.data(), (u32)vecMsg.size())) if (ret && !Send(GetSocket(), vecMsg.data(), int(vecMsg.size())))
{ {
Error(eDLL_T::CLIENT, NO_ERROR, "Failed to send RCON message: (%s)\n", "SOCKET_ERROR"); Error(eDLL_T::CLIENT, NO_ERROR, "Failed to send RCON message: (%s)\n", "SOCKET_ERROR");
} }
@ -476,16 +465,14 @@ bool CNetCon::ProcessMessage(const byte* pMsgBuf, const u32 nMsgLen)
// Purpose: serializes message to vector // Purpose: serializes message to vector
// Input : &vecBuf - // Input : &vecBuf -
// *szReqBuf - // *szReqBuf -
// nReqMsgLen -
// *svReqVal - // *svReqVal -
// nReqValLen -
// requestType - // requestType -
// Output : true on success, false otherwise // Output : true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CNetCon::Serialize(vector<byte>& vecBuf, const char* szReqBuf, const size_t nReqMsgLen, bool CNetCon::Serialize(vector<char>& vecBuf, const char* szReqBuf,
const char* szReqVal, const size_t nReqValLen, const netcon::request_e requestType) const const char* szReqVal, const netcon::request_e requestType) const
{ {
return NetconClient_Serialize(this, vecBuf, szReqBuf, nReqMsgLen, szReqVal, nReqValLen, requestType, m_bEncryptFrames, true); return NetconClient_Serialize(this, vecBuf, szReqBuf, szReqVal, requestType, m_bEncryptFrames, true);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -524,23 +511,27 @@ int main(int argc, char* argv[])
bool bEnableColor = false; bool bEnableColor = false;
if (argc >= 2) for (int i = 0; i < argc; i++)
{ {
bEnableColor = V_strcmp(argv[1], "-ansicolor") == NULL; if (V_strcmp(argv[i], "-ansicolor") == NULL)
{
bEnableColor = true;
break;
}
} }
// The address and key from command line if passed in. // The address and key from command line if passed in.
const char* pAdr = nullptr; const char* pAdr = nullptr;
const char* pKey = nullptr; const char* pKey = nullptr;
if (argc >= 2 + bEnableColor) if (argc >= 2)
{ {
pAdr = argv[1 + bEnableColor]; pAdr = argv[1];
} }
if (argc >= 3 + bEnableColor) if (argc >= 3)
{ {
pKey = argv[2 + bEnableColor]; pKey = argv[2];
} }
if (!NetConsole()->Init(bEnableColor, pAdr, pKey)) if (!NetConsole()->Init(bEnableColor, pAdr, pKey))

View File

@ -35,11 +35,11 @@ public:
virtual bool Connect(const char* pHostName, const int nHostPort = SOCKET_ERROR) override; virtual bool Connect(const char* pHostName, const int nHostPort = SOCKET_ERROR) override;
virtual void Disconnect(const char* szReason = nullptr) override; virtual void Disconnect(const char* szReason = nullptr) override;
virtual bool ProcessMessage(const byte* pMsgBuf, const u32 nMsgLen) override; virtual bool ProcessMessage(const char* pMsgBuf, const int nMsgLen) override;
void TrySetKey(const char* const pKey); void TrySetKey(const char* const pKey);
bool Serialize(vector<byte>& vecBuf, const char* szReqBuf, const size_t nReqMsgLen, bool Serialize(vector<char>& vecBuf, const char* szReqBuf,
const char* szReqVal, const size_t nReqValLen, const netcon::request_e requestType) const; const char* szReqVal, const netcon::request_e requestType) const;
SocketHandle_t GetSocket(void); SocketHandle_t GetSocket(void);
bool IsInitialized(void) const; bool IsInitialized(void) const;

View File

@ -36,7 +36,7 @@ void CBanSystem::LoadList(void)
pBuf[nRead] = '\0'; // Null terminate the string buffer containing our banned list. pBuf[nRead] = '\0'; // Null terminate the string buffer containing our banned list.
rapidjson::Document document; rapidjson::Document document;
if (document.Parse(pBuf.get(), nRead).HasParseError()) if (document.Parse(pBuf.get()).HasParseError())
{ {
Warning(eDLL_T::SERVER, "%s: JSON parse error at position %zu: %s\n", Warning(eDLL_T::SERVER, "%s: JSON parse error at position %zu: %s\n",
__FUNCTION__, document.GetErrorOffset(), rapidjson::GetParseError_En(document.GetParseError())); __FUNCTION__, document.GetErrorOffset(), rapidjson::GetParseError_En(document.GetParseError()));
@ -62,7 +62,7 @@ void CBanSystem::LoadList(void)
rapidjson::Value::ConstMemberIterator entryIt; rapidjson::Value::ConstMemberIterator entryIt;
if (JSON_GetIterator(document, rapidjson::StringRef(idx, strlen(idx)), JSONFieldType_e::kObject, entryIt)) if (JSON_GetIterator(document, idx, JSONFieldType_e::kObject, entryIt))
{ {
const rapidjson::Value& entry = entryIt->value; const rapidjson::Value& entry = entryIt->value;
@ -107,7 +107,7 @@ void CBanSystem::SaveList(void) const
rapidjson::Value obj(rapidjson::kObjectType); rapidjson::Value obj(rapidjson::kObjectType);
obj.AddMember("ipAddress", rapidjson::Value(banned.m_Address.String(), banned.m_Address.Length(), allocator), allocator); obj.AddMember("ipAddress", rapidjson::Value(banned.m_Address.String(), allocator), allocator);
obj.AddMember("nucleusId", banned.m_NucleusID, allocator); obj.AddMember("nucleusId", banned.m_NucleusID, allocator);
document.AddMember(rapidjson::Value(idx, allocator), obj, 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 (strcmp(playerName, pNetChan->GetName()) == NULL) // Our wanted name?
{ {
if (shouldBan && AddEntry(pNetChan->GetAddress(true), pClient->GetNucleusID()) && !bSave) if (shouldBan && AddEntry(pNetChan->GetAddress(), pClient->GetNucleusID()) && !bSave)
bSave = true; bSave = true;
pClient->Disconnect(REP_MARK_BAD, reason); pClient->Disconnect(REP_MARK_BAD, reason);
@ -389,7 +389,7 @@ void CBanSystem::AuthorPlayerById(const char* playerHandle, const bool shouldBan
continue; continue;
} }
if (shouldBan && AddEntry(pNetChan->GetAddress(true), pClient->GetNucleusID()) && !bSave) if (shouldBan && AddEntry(pNetChan->GetAddress(), pClient->GetNucleusID()) && !bSave)
bSave = true; bSave = true;
pClient->Disconnect(REP_MARK_BAD, reason); pClient->Disconnect(REP_MARK_BAD, reason);
@ -397,12 +397,10 @@ void CBanSystem::AuthorPlayerById(const char* playerHandle, const bool shouldBan
} }
else else
{ {
const char* const chanAddr = pNetChan->GetAddress(true); if (strcmp(playerHandle, pNetChan->GetAddress()) != NULL)
if (strcmp(playerHandle, chanAddr) != NULL)
continue; continue;
if (shouldBan && AddEntry(chanAddr, pClient->GetNucleusID()) && !bSave) if (shouldBan && AddEntry(pNetChan->GetAddress(), pClient->GetNucleusID()) && !bSave)
bSave = true; bSave = true;
pClient->Disconnect(REP_MARK_BAD, reason); pClient->Disconnect(REP_MARK_BAD, reason);

View File

@ -48,8 +48,7 @@ static bool GetServerListingFromJSON(const rapidjson::Value& value, NetGameServe
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: gets a vector of hosted servers. // Purpose: gets a vector of hosted servers.
// Input : &outServerList - // Input : &outMessage -
// &outMessage -
// Output : true on success, false on failure. // Output : true on success, false on failure.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CPylon::GetServerList(vector<NetGameServer_t>& outServerList, string& outMessage) const bool CPylon::GetServerList(vector<NetGameServer_t>& outServerList, string& outMessage) const
@ -96,7 +95,7 @@ bool CPylon::GetServerList(vector<NetGameServer_t>& outServerList, string& outMe
continue; continue;
} }
outServerList.emplace_back(std::move(gameServer)); outServerList.push_back(gameServer);
} }
return true; return true;
@ -122,8 +121,8 @@ bool CPylon::GetServerByToken(NetGameServer_t& outGameServer,
requestJson.SetObject(); requestJson.SetObject();
rapidjson::Document::AllocatorType& allocator = requestJson.GetAllocator(); rapidjson::Document::AllocatorType& allocator = requestJson.GetAllocator();
requestJson.AddMember("version", rapidjson::Value(SDK_VERSION, sizeof(SDK_VERSION)-1, requestJson.GetAllocator()), allocator); requestJson.AddMember("version", rapidjson::Value(SDK_VERSION, requestJson.GetAllocator()), allocator);
requestJson.AddMember("token", rapidjson::Value(token.c_str(), token.length(), requestJson.GetAllocator()), allocator); requestJson.AddMember("token", rapidjson::Value(token.c_str(), requestJson.GetAllocator()), allocator);
rapidjson::Document responseJson; rapidjson::Document responseJson;
CURLINFO status; CURLINFO status;
@ -157,7 +156,6 @@ bool CPylon::GetServerByToken(NetGameServer_t& outGameServer,
// Purpose: Sends host server POST request. // Purpose: Sends host server POST request.
// Input : &outMessage - // Input : &outMessage -
// &outToken - // &outToken -
// &outHostIp -
// &netGameServer - // &netGameServer -
// Output : Returns true on success, false on failure. // Output : Returns true on success, false on failure.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -174,16 +172,16 @@ bool CPylon::PostServerHost(string& outMessage, string& outToken, string& outHos
rapidjson::Document::AllocatorType& allocator = requestJson.GetAllocator(); rapidjson::Document::AllocatorType& allocator = requestJson.GetAllocator();
requestJson.AddMember("name", rapidjson::Value(netGameServer.name.c_str(), netGameServer.name.length(), allocator), allocator); requestJson.AddMember("name", rapidjson::Value(netGameServer.name.c_str(), allocator), allocator);
requestJson.AddMember("description", rapidjson::Value(netGameServer.description.c_str(), netGameServer.description.length(), allocator), allocator); requestJson.AddMember("description", rapidjson::Value(netGameServer.description.c_str(), allocator), allocator);
requestJson.AddMember("hidden", netGameServer.hidden, allocator); requestJson.AddMember("hidden", netGameServer.hidden, allocator);
requestJson.AddMember("map", rapidjson::Value(netGameServer.map.c_str(), netGameServer.map.length(), allocator), allocator); requestJson.AddMember("map", rapidjson::Value(netGameServer.map.c_str(), allocator), allocator);
requestJson.AddMember("playlist", rapidjson::Value(netGameServer.playlist.c_str(), netGameServer.playlist.length(), allocator), allocator); requestJson.AddMember("playlist", rapidjson::Value(netGameServer.playlist.c_str(), allocator), allocator);
requestJson.AddMember("ip", rapidjson::Value(netGameServer.address.c_str(), netGameServer.address.length(), allocator), allocator); requestJson.AddMember("ip", rapidjson::Value(netGameServer.address.c_str(), allocator), allocator);
requestJson.AddMember("port", netGameServer.port, allocator); requestJson.AddMember("port", netGameServer.port, allocator);
requestJson.AddMember("key", rapidjson::Value(netGameServer.netKey.c_str(), netGameServer.netKey.length(), allocator), allocator); requestJson.AddMember("key", rapidjson::Value(netGameServer.netKey.c_str(), allocator), allocator);
requestJson.AddMember("checksum", netGameServer.checksum, allocator); requestJson.AddMember("checksum", netGameServer.checksum, allocator);
requestJson.AddMember("version", rapidjson::Value(netGameServer.versionId.c_str(), netGameServer.versionId.length(), allocator), allocator); requestJson.AddMember("version", rapidjson::Value(netGameServer.versionId.c_str(), allocator), allocator);
requestJson.AddMember("numPlayers", netGameServer.numPlayers, allocator); requestJson.AddMember("numPlayers", netGameServer.numPlayers, allocator);
requestJson.AddMember("maxPlayers", netGameServer.maxPlayers, allocator); requestJson.AddMember("maxPlayers", netGameServer.maxPlayers, allocator);
requestJson.AddMember("timeStamp", netGameServer.timeStamp, allocator); requestJson.AddMember("timeStamp", netGameServer.timeStamp, allocator);
@ -246,7 +244,7 @@ bool CPylon::GetBannedList(const CBanSystem::BannedList_t& inBannedVec, CBanSyst
rapidjson::Value player(rapidjson::kObjectType); rapidjson::Value player(rapidjson::kObjectType);
player.AddMember("id", banned.m_NucleusID, allocator); player.AddMember("id", banned.m_NucleusID, allocator);
player.AddMember("ip", rapidjson::Value(banned.m_Address.String(), banned.m_Address.Length(), allocator), allocator); player.AddMember("ip", rapidjson::Value(banned.m_Address.String(), allocator), allocator);
playersArray.PushBack(player, allocator); playersArray.PushBack(player, allocator);
} }
@ -298,7 +296,6 @@ bool CPylon::GetBannedList(const CBanSystem::BannedList_t& inBannedVec, CBanSyst
// Purpose: Checks if client is banned on the comp server. // Purpose: Checks if client is banned on the comp server.
// Input : &ipAddress - // Input : &ipAddress -
// nucleusId - // nucleusId -
// &personaName -
// &outReason - <- contains banned reason if any. // &outReason - <- contains banned reason if any.
// Output : True if banned, false if not banned. // Output : True if banned, false if not banned.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -480,7 +477,7 @@ bool CPylon::SendRequest(const char* endpoint, const rapidjson::Document& reques
if (status == 200) // STATUS_OK if (status == 200) // STATUS_OK
{ {
responseJson.Parse(responseBody.c_str(), responseBody.length()+1); responseJson.Parse(responseBody.c_str());
if (responseJson.HasParseError()) if (responseJson.HasParseError())
{ {
@ -620,7 +617,7 @@ void CPylon::ExtractError(const string& response, string& outMessage,
if (!response.empty()) if (!response.empty())
{ {
rapidjson::Document resultBody; rapidjson::Document resultBody;
resultBody.Parse(response.c_str(), response.length()+1); resultBody.Parse(response.c_str());
ExtractError(resultBody, outMessage, status, errorText); ExtractError(resultBody, outMessage, status, errorText);
} }

View File

@ -1,13 +0,0 @@
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/" )

View File

@ -1,34 +0,0 @@
//===========================================================================//
//
// 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);
}

View File

@ -1,28 +0,0 @@
//===========================================================================//
//
// 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

View File

@ -103,7 +103,7 @@ public:
// Utilities for convars accessed by the material system thread // Utilities for convars accessed by the material system thread
virtual bool IsMaterialThreadSetAllowed() const = 0; virtual bool IsMaterialThreadSetAllowed() const = 0;
virtual void QueueMaterialThreadSetValue(ConVar* pConVar, const char* pValue/*pValue is allowed to be null*/) = 0; virtual void QueueMaterialThreadSetValue(ConVar* pConVar, const char* pValue) = 0;
virtual void QueueMaterialThreadSetValue(ConVar* pConVar, int nValue) = 0; virtual void QueueMaterialThreadSetValue(ConVar* pConVar, int nValue) = 0;
virtual void QueueMaterialThreadSetValue(ConVar* pConVar, float flValue) = 0; virtual void QueueMaterialThreadSetValue(ConVar* pConVar, float flValue) = 0;
virtual bool HasQueuedMaterialThreadConVarSets() const = 0; virtual bool HasQueuedMaterialThreadConVarSets() const = 0;

View File

@ -1,87 +1,6 @@
#ifndef IMATERIAL_H #ifndef IMATERIAL_H
#define 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 abstract_class IMaterial
{ {
public: public:
@ -136,11 +55,7 @@ private:
virtual void stub_34() const = 0; virtual void stub_34() const = 0;
virtual void stub_35() const = 0; virtual void stub_35() const = 0;
virtual void stub_36() 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_38() const = 0;
virtual void stub_39() const = 0; virtual void stub_39() const = 0;
virtual void stub_40() const = 0; virtual void stub_40() const = 0;

View File

@ -2,7 +2,7 @@
#define IMATERIALSYSTEM_H #define IMATERIALSYSTEM_H
#define NVIDIA_VENDOR_ID 0x10DE #define NVIDIA_VENDOR_ID 0x10DE
#define AMD_VENDOR_ID 0x1002 #define AMD_VENDOR_ID 0x10EE
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Material adapter info.. // Material adapter info..

View File

@ -37,12 +37,12 @@ enum JoystickAxis_t
MAX_JOYSTICK_AXES, MAX_JOYSTICK_AXES,
}; };
enum JoystickType_t enum JoystickDeadzoneIndex_t
{ {
JOYSTICK_TYPE_NONE = 0, JOYSTICK_DEADZONE_NONE = 0,
JOYSTICK_TYPE_XBOX360, JOYSTICK_DEADZONE_XBOX360,
JOYSTICK_TYPE_XBOX1, JOYSTICK_DEADZONE_XBOX1,
JOYSTICK_TYPE_PS4 JOYSTICK_DEADZONE_OTHER
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -75,7 +75,7 @@ public:
virtual int GetButtonPressedTick( const ButtonCode_t code ) const = 0; virtual int GetButtonPressedTick( const ButtonCode_t code ) const = 0;
/// Returns the joystick deadzone index for connected hardware. /// Returns the joystick deadzone index for connected hardware.
virtual JoystickType_t GetJoystickType( ) const = 0; virtual JoystickDeadzoneIndex_t GetJoystickDeadzoneIndex( ) const = 0;
/// DoNothing; VFTable padding. /// DoNothing; VFTable padding.
virtual bool ReturnFalse( ) const = 0; virtual bool ReturnFalse( ) const = 0;

View File

@ -1,20 +0,0 @@
//===========================================================================//
//
// 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

View File

@ -1,127 +1,122 @@
#ifndef TEXTURE_G_H #ifndef TEXTURE_G_H
#define TEXTURE_G_H #define TEXTURE_G_H
#include <rtech/ipakfile.h>
#include <imaterial.h>
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Structure definitions // Structure definitions
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/*schema*/ struct TextureDesc_s /*schema*/ struct TextureDesc_t
{ {
PakGuid_t assetGuid; uint64_t m_AssetGuid;
const char* debugName; const char* m_pDebugName;
uint16 width; uint16 m_nWidth;
uint16 height; uint16 m_nHeight;
uint16 depth; uint16 m_nDepth;
uint16 imageFormat; uint16_t m_nImageFormat;
}; };
/*schema*/ struct TextureAsset_s : public TextureDesc_s /*schema*/ struct TextureHeader_t : public TextureDesc_t
{ {
uint32 dataSize; uint32_t m_nDataLength;
uint8 swizzleType; uint8_t unknown_2;
uint8 optStreamedMipLevels; uint8_t m_nOptStreamedMipCount;
uint8 arraySize; uint8_t m_nArraySize;
uint8 layerCount; uint8_t m_nLayerCount;
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_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 permanentMipLevels; uint8_t m_nPermanentMipCount;
uint8 streamedMipLevels; uint8_t m_nStreamedMipCount;
uint8 unkPerMip[13]; uint8_t unknown_4[13];
uint64 texelCount; __int64 m_nPixelCount;
uint16 streamedTextureIndex; uint8_t unknown_5[3];
uint8 loadedStreamedMipLevelCount; uint8_t m_nTotalStreamedMipCount; // Does not get set until after RTech::CreateDXTexture.
uint8 totalStreamedMipLevelCount; // Does not get set until after RTech::CreateDXTexture. uint8_t unk4[228];
uint8_t unk5[57];
int lastUsedFrame; ID3D11Texture2D* m_ppTexture;
int lastFrame; ID3D11ShaderResourceView* m_ppShaderResourceView;
uint8_t m_nTextureMipLevels;
int unknown; uint8_t m_nTextureMipLevelsStreamedOpt;
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 // Table definitions
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static inline const TextureBytesPerPixel_s s_pBytesPerPixel[] = static const pair<uint8_t, uint8_t> s_pBytesPerPixel[] =
{ {
{ u8(8u), u8(4u) }, { uint8_t(8u), uint8_t(4u) },
{ u8(8u), u8(4u) }, { uint8_t(8u), uint8_t(4u) },
{ u8(16u), u8(4u) }, { uint8_t(16u), uint8_t(4u) },
{ u8(16u), u8(4u) }, { uint8_t(16u), uint8_t(4u) },
{ u8(16u), u8(4u) }, { uint8_t(16u), uint8_t(4u) },
{ u8(16u), u8(4u) }, { uint8_t(16u), uint8_t(4u) },
{ u8(8u), u8(4u) }, { uint8_t(8u), uint8_t(4u) },
{ u8(8u), u8(4u) }, { uint8_t(8u), uint8_t(4u) },
{ u8(16u), u8(4u) }, { uint8_t(16u), uint8_t(4u) },
{ u8(16u), u8(4u) }, { uint8_t(16u), uint8_t(4u) },
{ u8(16u), u8(4u) }, { uint8_t(16u), uint8_t(4u) },
{ u8(16u), u8(4u) }, { uint8_t(16u), uint8_t(4u) },
{ u8(16u), u8(4u) }, { uint8_t(16u), uint8_t(4u) },
{ u8(16u), u8(4u) }, { uint8_t(16u), uint8_t(4u) },
{ u8(16u), u8(1u) }, { uint8_t(16u), uint8_t(1u) },
{ u8(16u), u8(1u) }, { uint8_t(16u), uint8_t(1u) },
{ u8(16u), u8(1u) }, { uint8_t(16u), uint8_t(1u) },
{ u8(12u), u8(1u) }, { uint8_t(12u), uint8_t(1u) },
{ u8(12u), u8(1u) }, { uint8_t(12u), uint8_t(1u) },
{ u8(12u), u8(1u) }, { uint8_t(12u), uint8_t(1u) },
{ u8(8u), u8(1u) }, { uint8_t(8u), uint8_t(1u) },
{ u8(8u), u8(1u) }, { uint8_t(8u), uint8_t(1u) },
{ u8(8u), u8(1u) }, { uint8_t(8u), uint8_t(1u) },
{ u8(8u), u8(1u) }, { uint8_t(8u), uint8_t(1u) },
{ u8(8u), u8(1u) }, { uint8_t(8u), uint8_t(1u) },
{ u8(8u), u8(1u) }, { uint8_t(8u), uint8_t(1u) },
{ u8(8u), u8(1u) }, { uint8_t(8u), uint8_t(1u) },
{ u8(8u), u8(1u) }, { uint8_t(8u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(2u), u8(1u) }, { uint8_t(2u), uint8_t(1u) },
{ u8(2u), u8(1u) }, { uint8_t(2u), uint8_t(1u) },
{ u8(2u), u8(1u) }, { uint8_t(2u), uint8_t(1u) },
{ u8(2u), u8(1u) }, { uint8_t(2u), uint8_t(1u) },
{ u8(2u), u8(1u) }, { uint8_t(2u), uint8_t(1u) },
{ u8(2u), u8(1u) }, { uint8_t(2u), uint8_t(1u) },
{ u8(2u), u8(1u) }, { uint8_t(2u), uint8_t(1u) },
{ u8(2u), u8(1u) }, { uint8_t(2u), uint8_t(1u) },
{ u8(2u), u8(1u) }, { uint8_t(2u), uint8_t(1u) },
{ u8(1u), u8(1u) }, { uint8_t(1u), uint8_t(1u) },
{ u8(1u), u8(1u) }, { uint8_t(1u), uint8_t(1u) },
{ u8(1u), u8(1u) }, { uint8_t(1u), uint8_t(1u) },
{ u8(1u), u8(1u) }, { uint8_t(1u), uint8_t(1u) },
{ u8(1u), u8(1u) }, { uint8_t(1u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(4u), u8(1u) }, { uint8_t(4u), uint8_t(1u) },
{ u8(2u), u8(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) }
}; };
// Map dxgi format to txtr asset format // Map dxgi format to txtr asset format
@ -197,7 +192,7 @@ inline int DxgiFormatToTxtrAsset(DXGI_FORMAT dxgi)
} }
// Map txtr asset format to dxgi format // Map txtr asset format to dxgi format
static inline const DXGI_FORMAT g_TxtrAssetToDxgiFormat[] = static const DXGI_FORMAT g_TxtrAssetToDxgiFormat[] =
{ {
DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM,
DXGI_FORMAT_BC1_UNORM_SRGB, DXGI_FORMAT_BC1_UNORM_SRGB,

View File

@ -36,11 +36,11 @@
#define PAK_MAX_TRACKED_ASSETS (PAK_MAX_LOADED_ASSETS/2) #define PAK_MAX_TRACKED_ASSETS (PAK_MAX_LOADED_ASSETS/2)
#define PAK_MAX_TRACKED_ASSETS_MASK (PAK_MAX_TRACKED_ASSETS-1) #define PAK_MAX_TRACKED_ASSETS_MASK (PAK_MAX_TRACKED_ASSETS-1)
// max amount of slabs a pak file could have // max amount of segments a pak file could have
#define PAK_MAX_SLABS 20 #define PAK_MAX_SEGMENTS 20
// max amount of buffers in which slabs get copied in // max amount of buffers in which segments get copied in
#define PAK_SLAB_BUFFER_TYPES 4 #define PAK_SEGMENT_BUFFER_TYPES 4
// max amount of streaming files that could be opened per set for a pak, so if a // 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 // 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 struct PakPageHeader_s
{ {
uint32_t slabIndex; uint32_t segmentIdx;
uint32_t pageAlignment; uint32_t pageAlignment;
uint32_t dataSize; uint32_t dataSize;
}; };
@ -203,9 +203,9 @@ struct PakAssetBinding_s
CAlignedMemAlloc* allocator; CAlignedMemAlloc* allocator;
uint32_t headerSize; unsigned int headerSize;
uint32_t structSize; // Native class size, for 'material' it would be CMaterialGlue full size. unsigned int nativeClassSize; // Native class size, for 'material' it would be CMaterialGlue full size.
uint32_t headerAlignment; unsigned int headerAlignment;
// the type of this asset bind // the type of this asset bind
// NOTE: the asset bind will be stubbed if its 'NONE' in runtime! // NOTE: the asset bind will be stubbed if its 'NONE' in runtime!
@ -229,12 +229,11 @@ struct PakAsset_s
uint16_t pageEnd; uint16_t pageEnd;
// the number of remaining dependencies that are yet to be resolved // the number of remaining dependencies that are yet to be resolved
int16_t numRemainingDependencies; uint16_t numRemainingDependencies;
uint32_t dependentsIndex; uint32_t dependentsIndex;
uint32_t usesIndex; uint32_t dependenciesIndex;
uint32_t dependentsCount; uint32_t dependentsCount;
uint32_t usesCount; uint32_t dependenciesCount;
// size of the asset's header // size of the asset's header
uint32_t headerSize; uint32_t headerSize;
@ -314,8 +313,8 @@ public:
uint32_t assetCount; uint32_t assetCount;
const char* fileName; const char* fileName;
CAlignedMemAlloc* allocator; CAlignedMemAlloc* allocator;
PakGuid_t* assetGuids; // size of the array is assetCount PakGuid_t* assetGuids; //size of the array is m_nAssetCount
void* slabBuffers[PAK_SLAB_BUFFER_TYPES]; void* segmentBuffers[PAK_SEGMENT_BUFFER_TYPES];
void* guidDestriptors; void* guidDestriptors;
FILETIME fileTime; FILETIME fileTime;
PakFile_s* pakFile; PakFile_s* pakFile;
@ -486,20 +485,20 @@ struct PakFileHeader_s
// size of the string array containing paths to external streaming files // size of the string array containing paths to external streaming files
uint16_t streamingFilesBufSize[STREAMING_SET_COUNT]; uint16_t streamingFilesBufSize[STREAMING_SET_COUNT];
// number of memory slabs in this pak in which pages get allocated to; absolute max = PAK_MAX_SLABS // number of segments in this pak; absolute max = PAK_MAX_SEGMENTS
uint16_t memSlabCount; uint16_t virtualSegmentCount;
// number of memory pages to allocate for this pak // number of memory pages to allocate for this pak
uint16_t memPageCount; uint16_t memPageCount;
uint16_t patchIndex; uint16_t patchIndex;
uint16_t alignment; uint32_t descriptorCount;
uint32_t pointerCount; // number of assets in this pak
uint32_t assetCount; // number of assets in this pak uint32_t assetCount;
uint32_t usesCount; uint32_t guidDescriptorCount;
uint32_t dependentsCount; uint32_t relationsCounts;
uint8_t unk2[0x10]; uint8_t unk2[0x10];
@ -509,28 +508,26 @@ struct PakFileHeader_s
uint8_t unk3[0x8]; uint8_t unk3[0x8];
}; static_assert(sizeof(PakFileHeader_s) == 0x80); }; static_assert(sizeof(PakFileHeader_s) == 0x80);
// slab flags // segment flags
#define SF_HEAD (0) #define SF_HEAD (0)
#define SF_CPU (1 << 0) #define SF_TEMP (1 << 0) // 0x1
#define SF_TEMP (1 << 1) #define SF_CPU (1 << 1) // 0x2
#define SF_SERVER (1 << 5) #define SF_DEV (1 << 8) // 0x80
#define SF_CLIENT (1 << 6)
#define SF_DEV (1 << 8)
struct PakSlabHeader_s struct PakSegmentHeader_s
{ {
int typeFlags; int typeFlags;
int dataAlignment; int dataAlignment;
size_t dataSize; size_t dataSize;
}; };
struct PakSlabDescriptor_s struct PakSegmentDescriptor_s
{ {
size_t assetTypeCount[PAK_MAX_TRACKED_TYPES]; size_t assetTypeCount[PAK_MAX_TRACKED_TYPES];
int64_t slabSizes[PAK_MAX_SLABS]; int64_t segmentSizes[PAK_MAX_SEGMENTS];
size_t slabSizeForType[PAK_SLAB_BUFFER_TYPES]; size_t segmentSizeForType[PAK_SEGMENT_BUFFER_TYPES];
int slabAlignmentForType[PAK_SLAB_BUFFER_TYPES]; int segmentAlignmentForType[PAK_SEGMENT_BUFFER_TYPES];
}; };
struct PakDecoder_s struct PakDecoder_s
@ -690,7 +687,7 @@ struct PakMemoryData_s
char* streamingFilePaths[STREAMING_SET_COUNT]; char* streamingFilePaths[STREAMING_SET_COUNT];
PakSlabHeader_s* slabHeaders; PakSegmentHeader_s* segmentHeaders;
PakPageHeader_s* pageHeaders; PakPageHeader_s* pageHeaders;
PakPage_u* virtualPointers; PakPage_u* virtualPointers;
@ -707,7 +704,7 @@ struct PakMemoryData_s
int someAssetCount; int someAssetCount;
int numShiftedPointers; int numShiftedPointers;
// array of sizes/offsets in the SF_HEAD slab buffer // array of sizes/offsets in the SF_HEAD segment buffer
__int64 unkAssetTypeBindingSizes[PAK_MAX_TRACKED_TYPES]; __int64 unkAssetTypeBindingSizes[PAK_MAX_TRACKED_TYPES];
const char* fileName; const char* fileName;
@ -763,7 +760,7 @@ struct PakFile_s
inline uint32_t GetPointerCount() const inline uint32_t GetPointerCount() const
{ {
return GetHeader().pointerCount; return GetHeader().descriptorCount;
} }
// --- pages --- // --- pages ---
@ -822,17 +819,17 @@ struct PakFile_s
return memoryData.memPageBuffers[ptr->index] + ptr->offset; return memoryData.memPageBuffers[ptr->index] + ptr->offset;
} }
// --- slabs --- // --- segments ---
inline uint16_t GetSlabCount() const inline uint16_t GetSegmentCount() const
{ {
return GetHeader().memSlabCount; return GetHeader().virtualSegmentCount;
} }
inline const PakSlabHeader_s* GetSlabHeader(const uint32_t i) const inline const PakSegmentHeader_s* GetSegmentHeader(const uint32_t i) const
{ {
assert(i < GetSlabCount()); assert(i < GetSegmentCount());
return &memoryData.slabHeaders[i]; return &memoryData.segmentHeaders[i];
} }
}; };

View File

@ -1,59 +0,0 @@
//=============================================================================//
//
// 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

View File

@ -3,39 +3,32 @@
class CIOStream class CIOStream
{ {
public: public:
enum class Mode_e enum Mode_t
{ {
None = 0, NONE = 0,
Read, READ = std::ios::in,
Write, WRITE = std::ios::out,
ReadWrite, // For existing files only. BINARY = std::ios::binary,
ReadWriteCreate
}; };
CIOStream(); CIOStream();
~CIOStream(); ~CIOStream();
bool Open(const char* const filePath, const Mode_e mode); bool Open(const char* const pFilePath, const int nFlags);
inline bool Open(const std::string& filePath, const Mode_e mode) { return Open(filePath.c_str(), mode); };
void Close(); void Close();
void Reset();
void Flush(); void Flush();
std::streamoff TellGet(); std::streampos TellGet();
std::streamoff TellPut(); std::streampos TellPut();
void SeekGet(const std::streamoff offset, const std::ios_base::seekdir way = std::ios::beg); void SeekGet(const std::streampos nOffset);
void SeekPut(const std::streamoff offset, const std::ios_base::seekdir way = std::ios::beg); void SeekPut(const std::streampos nOffset);
void Seek(const std::streamoff offset, const std::ios_base::seekdir way = std::ios::beg); void Seek(const std::streampos nOffset);
const std::filebuf* GetData() const; const std::filebuf* GetData() const;
const std::streamoff GetSize() const; const std::streampos GetSize() const;
bool IsReadMode() const; bool IsReadable();
bool IsWriteMode() const;
bool IsReadable() const;
bool IsWritable() const; bool IsWritable() const;
bool IsEof() const; bool IsEof() const;
@ -44,39 +37,39 @@ public:
// Purpose: reads any value from the file // Purpose: reads any value from the file
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template<typename T> template<typename T>
inline void Read(T& value) void Read(T& tValue)
{ {
if (IsReadable()) if (IsReadable())
m_stream.read(reinterpret_cast<char*>(&value), sizeof(value)); m_Stream.read(reinterpret_cast<char*>(&tValue), sizeof(tValue));
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: reads any value from the file with specified size // Purpose: reads any value from the file with specified size
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template<typename T> template<typename T>
inline void Read(T* const value, const size_t size) void Read(T* tValue, const size_t nSize)
{ {
if (IsReadable()) if (IsReadable())
m_stream.read(reinterpret_cast<char*>(value), size); m_Stream.read(reinterpret_cast<char*>(tValue), nSize);
} }
template<typename T> template<typename T>
inline void Read(T& value, const size_t size) void Read(T& tValue, const size_t nSize)
{ {
if (IsReadable()) if (IsReadable())
m_stream.read(reinterpret_cast<char*>(&value), size); m_Stream.read(reinterpret_cast<char*>(&tValue), nSize);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: reads any value from the file and returns it // Purpose: reads any value from the file and returns it
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template<typename T> template<typename T>
inline T Read() T Read()
{ {
T value{}; T value{};
if (!IsReadable()) if (!IsReadable())
return value; return value;
m_stream.read(reinterpret_cast<char*>(&value), sizeof(value)); m_Stream.read(reinterpret_cast<char*>(&value), sizeof(value));
return value; return value;
} }
bool ReadString(std::string& svOut); bool ReadString(std::string& svOut);
@ -86,40 +79,31 @@ public:
// Purpose: writes any value to the file // Purpose: writes any value to the file
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template<typename T> template<typename T>
inline void Write(const T& value) void Write(T tValue)
{ {
if (!IsWritable()) if (!IsWritable())
return; return;
const size_t count = sizeof(value); m_Stream.write(reinterpret_cast<const char*>(&tValue), sizeof(tValue));
m_nSize += sizeof(tValue);
m_stream.write(reinterpret_cast<const char*>(&value), count);
CalcAddDelta(count);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: writes any value to the file with specified size // Purpose: writes any value to the file with specified size
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template<typename T> template<typename T>
inline void Write(const T* const value, const size_t size) void Write(T* tValue, size_t nSize)
{ {
if (!IsWritable()) if (!IsWritable())
return; return;
m_stream.write(reinterpret_cast<const char*>(value), size); m_Stream.write(reinterpret_cast<const char*>(tValue), nSize);
CalcAddDelta(size); m_nSize += nSize;
} }
bool WriteString(const std::string& svInput, const bool nullterminate); bool WriteString(const std::string& svInput);
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: private:
std::fstream m_stream; // I/O stream. std::streampos m_nSize; // File size.
std::streamoff m_size; // File size. int m_nFlags; // Stream flags.
std::streamoff m_skip; // Amount skipped back. std::fstream m_Stream; // I/O stream.
std::ios_base::openmode m_flags; // Stream flags.
Mode_e m_mode; // Stream mode.
}; };

View File

@ -95,11 +95,6 @@ constexpr const char* s_ScriptAnsiColor[4] =
"\033[38;2;151;149;163mScript(X):" "\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 // Legacy Logging System
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////

View File

@ -69,9 +69,9 @@ void FourCCToString(FourCCString_t& buf, const int n);
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Bytes // Bytes
vector<uint8_t> StringToBytes(const char* const szInput, const bool bNullTerminator); vector<int> StringToBytes(const char* const szInput, const bool bNullTerminator);
pair<vector<uint8_t>, string> StringToMaskedBytes(const char* const szInput, const bool bNullTerminator); pair<vector<uint8_t>, string> StringToMaskedBytes(const char* const szInput, const bool bNullTerminator);
vector<uint16_t> PatternToBytes(const char* const szInput); vector<int> PatternToBytes(const char* const szInput);
pair<vector<uint8_t>, string> PatternToMaskedBytes(const char* const szInput); pair<vector<uint8_t>, string> PatternToMaskedBytes(const char* const szInput);
vector<int> IntToDigits(int iValue); vector<int> IntToDigits(int iValue);

View File

@ -244,7 +244,7 @@ private:
virtual void InternalSetColorValue(Color value); virtual void InternalSetColorValue(Color value);
// DoNothing in the engine, probably for tracking/debugging cvar strings in debug. // DoNothing in the engine, probably for tracking/debugging cvar strings in debug.
virtual void TrackValueChange(const char* value) { }; virtual void TrackDefaultValue(const char* value) { };
virtual bool ClampValue(float& flValue); virtual bool ClampValue(float& flValue);

View File

@ -159,12 +159,13 @@ public:
extern ConVarFlags g_ConVarFlags; extern ConVarFlags g_ConVarFlags;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
bool ConVar_ParseFlagString(const char* const pszFlags, int& nFlags, const char* const pszConVarName = "<<unspecified>>"); bool ConVar_ParseFlagString(const char* pszFlags, int& nFlags, const char* pszConVarName = "<<unspecified>>");
void ConVar_PrintDescription(ConCommandBase* pVar);
inline bool (*CCvar__Connect)(CCvar* thisptr, CreateInterfaceFn factory); inline bool (*CCvar__Connect)(CCvar* thisptr, CreateInterfaceFn factory);
inline void (*CCvar__Disconnect)(CCvar* thisptr); inline void (*CCvar__Disconnect)(CCvar* thisptr);
inline void (*v_ConVar_PrintDescription)(const ConCommandBase* const pVar); inline void (*v_ConVar_PrintDescription)(ConCommandBase* pVar);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
class VCVar : public IDetour class VCVar : public IDetour

View File

@ -1,74 +0,0 @@
//===========================================================================//
//
// 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

View File

@ -11,11 +11,11 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
enum class JSONFieldType_e enum class JSONFieldType_e
{ {
kInvalid = -1,
kNull = 0, kNull = 0,
kObject,
kBool, kBool,
kNumber,
kSint32, kSint32,
kUint32, kUint32,
@ -29,52 +29,14 @@ enum class JSONFieldType_e
kDouble, kDouble,
kLDouble, kLDouble,
kNumber,
kString, 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 // Purpose: gets the object type as string
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
inline const char* JSON_InternalTypeToString(const rapidjson::Type type) inline const char* JSON_TypeToString(const rapidjson::Type type)
{ {
switch (type) switch (type)
{ {
@ -88,40 +50,8 @@ inline const char* JSON_InternalTypeToString(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 // 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> template <class T>
inline bool JSON_IsOfType(const T& data, const JSONFieldType_e type) inline bool JSON_IsOfType(const T& data, const JSONFieldType_e type)
@ -130,8 +60,12 @@ inline bool JSON_IsOfType(const T& data, const JSONFieldType_e type)
{ {
case JSONFieldType_e::kNull: case JSONFieldType_e::kNull:
return data.IsNull(); return data.IsNull();
case JSONFieldType_e::kObject:
return data.IsObject();
case JSONFieldType_e::kBool: case JSONFieldType_e::kBool:
return data.IsBool(); return data.IsBool();
case JSONFieldType_e::kNumber:
return data.IsNumber();
case JSONFieldType_e::kSint32: case JSONFieldType_e::kSint32:
return data.IsInt(); return data.IsInt();
case JSONFieldType_e::kUint32: case JSONFieldType_e::kUint32:
@ -148,14 +82,10 @@ inline bool JSON_IsOfType(const T& data, const JSONFieldType_e type)
return data.IsDouble(); return data.IsDouble();
case JSONFieldType_e::kLDouble: case JSONFieldType_e::kLDouble:
return data.IsLosslessDouble(); return data.IsLosslessDouble();
case JSONFieldType_e::kNumber:
return data.IsNumber();
case JSONFieldType_e::kString: case JSONFieldType_e::kString:
return data.IsString(); return data.IsString();
case JSONFieldType_e::kArray: case JSONFieldType_e::kArray:
return data.IsArray(); return data.IsArray();
case JSONFieldType_e::kObject:
return data.IsObject();
default: default:
return false; return false;
} }
@ -186,16 +116,16 @@ inline JSONFieldType_e JSON_GetTypeForType()
else if constexpr (std::is_same<T, std::string>::value) else if constexpr (std::is_same<T, std::string>::value)
return JSONFieldType_e::kString; return JSONFieldType_e::kString;
else else
static_assert(std::is_same_v<T, void>, "Cannot classify data type; unsupported."); static_assert(false, "Cannot classify data type; unsupported.");
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: checks if the member exists and if its value is of type provided // Purpose: checks if the member exists and if its value is of type provided
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <class T> template <class T>
inline bool JSON_HasMemberAndIsOfType(const T& data, typename T::StringRefType member, const JSONFieldType_e type) inline bool JSON_HasMemberAndIsOfType(const T& data, const char* const member, const JSONFieldType_e type)
{ {
const T::ConstMemberIterator it = data.FindMember(rapidjson::Value(member)); const T::ConstMemberIterator it = data.FindMember(member);
if (it != data.MemberEnd()) if (it != data.MemberEnd())
{ {
@ -205,63 +135,25 @@ inline bool JSON_HasMemberAndIsOfType(const T& data, typename T::StringRefType m
return false; 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, // Purpose: checks if the member exists and if its value is of specified type,
// and sets 'out' to its value if all aforementioned conditions // and sets 'out' to its value if all aforementioned conditions
// are met // are met
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <class T, class V> template <class T, class V>
inline bool JSON_GetValue(const T& data, typename T::StringRefType member, const JSONFieldType_e type, V& out) inline bool JSON_GetValue(const T& data, const char* const member, const JSONFieldType_e type, V& out)
{ {
rapidjson::Document::ConstMemberIterator it; const T::ConstMemberIterator it = data.FindMember(member);
if (JSON_GetIterator(data, member, type, it)) if (it != data.MemberEnd())
{ {
out = it->value.Get<V>(); const rapidjson::Value& val = it->value;
return true;
if (JSON_IsOfType(val, type))
{
out = val.Get<V>();
return true;
}
} }
// Not found or didn't match specified type. // Not found or didn't match specified type.
@ -273,21 +165,26 @@ inline bool JSON_GetValue(const T& data, typename T::StringRefType member, const
// and sets 'out' to its value if all aforementioned conditions are met // and sets 'out' to its value if all aforementioned conditions are met
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <class T, class V> template <class T, class V>
inline bool JSON_GetValue(const T& data, typename T::StringRefType member, V& out) inline bool JSON_GetValue(const T& data, const char* const member, V& out)
{ {
rapidjson::Document::ConstMemberIterator it; const T::ConstMemberIterator it = data.FindMember(member);
if (JSON_GetIterator(data, member, JSON_GetTypeForType<V>(), it)) if (it != data.MemberEnd())
{ {
out = it->value.Get<V>(); const rapidjson::Value& val = it->value;
return true;
if (JSON_IsOfType(val, JSON_GetTypeForType<V>()))
{
out = val.Get<V>();
return true;
}
} }
// Not found or didn't match classified type. // Not found or didn't match classified type.
return false; return false;
} }
template <class T> template <class T>
inline bool JSON_GetValue(const T& data, typename T::StringRefType member, std::string& out) inline bool JSON_GetValue(const T& data, const char* const member, std::string& out)
{ {
const char* stringVal; const char* stringVal;
@ -306,7 +203,7 @@ inline bool JSON_GetValue(const T& data, typename T::StringRefType member, std::
// else the provided default gets returned // else the provided default gets returned
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <class T, class V> template <class T, class V>
inline V JSON_GetValueOrDefault(const T& data, typename T::StringRefType member, const V def) inline V JSON_GetValueOrDefault(const T& data, const char* const member, const V def)
{ {
V val; V val;
@ -318,25 +215,47 @@ inline V JSON_GetValueOrDefault(const T& data, typename T::StringRefType member,
return def; return def;
} }
template <class V> //-----------------------------------------------------------------------------
inline bool JSON_StringToNumber(const char* const str, const size_t len, V& num) // 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)
{ {
const char* const end = &str[len]; const T::ConstMemberIterator it = data.FindMember(member);
std::from_chars_result result;
if constexpr ((std::is_same<V, int32_t>::value) || (std::is_same<V, int64_t>::value) || if (it != data.MemberEnd())
(std::is_same<V, uint32_t>::value) || (std::is_same<V, uint64_t>::value))
{ {
result = std::from_chars(str, end, num, 0); if (JSON_IsOfType(it->value, type))
{
out = it;
return true;
}
} }
else if constexpr ((std::is_same<V, float>::value) || (std::is_same<V, double>::value))
{
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.");
return (result.ptr == end) && (result.ec == std::errc()); // 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())
{
out = it;
return true;
}
// Not found.
return false;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -353,19 +272,37 @@ inline bool JSON_ParseNumber(const T& data, V& num)
} }
else if (JSON_IsOfType(data, JSONFieldType_e::kString)) else if (JSON_IsOfType(data, JSONFieldType_e::kString))
{ {
return JSON_StringToNumber(data.GetString(), data.GetStringLength(), num); 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 false; return false;
} }
template <class T, class V> template <class T, class V>
inline bool JSON_ParseNumber(const T& data, typename T::StringRefType member, V& num) inline bool JSON_ParseNumber(const T& data, const char* const member, V& num)
{ {
rapidjson::Document::ConstMemberIterator it; rapidjson::Document::ConstMemberIterator it;
if (JSON_GetIterator(data, member, it)) if (JSON_GetIterator(data, member, it))
{ {
return JSON_ParseNumber(it->value, num); return JSON_ParseNumber(it->value, num);;
} }
return false; return false;
@ -377,7 +314,7 @@ inline bool JSON_ParseNumber(const T& data, typename T::StringRefType member, V&
// else the provided default gets returned // else the provided default gets returned
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <class T, class V> template <class T, class V>
inline V JSON_GetNumberOrDefault(const T& data, typename T::StringRefType member, V def) inline V JSON_GetNumberOrDefault(const T& data, const char* const member, V def)
{ {
V num; V num;

View File

@ -35,8 +35,8 @@ public:
SocketHandle_t GetAcceptedSocketHandle(int nIndex) const; SocketHandle_t GetAcceptedSocketHandle(int nIndex) const;
const netadr_t& GetAcceptedSocketAddress(int nIndex) const; const netadr_t& GetAcceptedSocketAddress(int nIndex) const;
ConnectedNetConsoleData_s& GetAcceptedSocketData(int nIndex); CConnectedNetConsoleData& GetAcceptedSocketData(int nIndex);
const ConnectedNetConsoleData_s& GetAcceptedSocketData(int nIndex) const; const CConnectedNetConsoleData& GetAcceptedSocketData(int nIndex) const;
public: public:
struct AcceptedSocket_t struct AcceptedSocket_t
@ -48,7 +48,7 @@ public:
SocketHandle_t m_hSocket; SocketHandle_t m_hSocket;
netadr_t m_Address; netadr_t m_Address;
ConnectedNetConsoleData_s m_Data; CConnectedNetConsoleData m_Data;
}; };
private: private:

View File

@ -53,13 +53,6 @@
0x1E3CB6: "xor rax, rax" // NULL RAX instead of mov'ing '0xDEADFEEDDEADFEED' to cache ptr in 'Pak_UpdateModelAsset()' 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()' 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 //// //// Code defects ////

View File

@ -232,13 +232,7 @@ static void ReVPK_Unpack(const CCommand& args)
return; return;
} }
CUtlString baseName; CUtlString baseName = PackedStore_GetDirBaseName(vpk.m_DirFilePath);
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. // Write the unpack log to a file.
CFmtStr1024 textFileName("%s%s%s.log", outPath, UNPACK_LOG_DIR, baseName.String()); CFmtStr1024 textFileName("%s%s%s.log", outPath, UNPACK_LOG_DIR, baseName.String());

View File

@ -42,7 +42,6 @@ add_sources( SOURCE_GROUP "LiveAPI"
add_sources( SOURCE_GROUP "Public" add_sources( SOURCE_GROUP "Public"
"${ENGINE_SOURCE_DIR}/public/rtech/iasync.h" "${ENGINE_SOURCE_DIR}/public/rtech/iasync.h"
"${ENGINE_SOURCE_DIR}/public/rtech/ipakfile.h" "${ENGINE_SOURCE_DIR}/public/rtech/ipakfile.h"
"${ENGINE_SOURCE_DIR}/public/rtech/istreamdb.h"
) )
end_sources() end_sources()

View File

@ -87,7 +87,8 @@ class V_AsyncIO : public IDetour
} }
virtual void GetVar(void) const virtual void GetVar(void) const
{ {
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"); extern void(*v_StreamDB_Init)(const char* const pszLevelName);
const CMemory streamDbBase(v_StreamDB_Init);
g_pAsyncFileSlots = streamDbBase.Offset(0x70).FindPatternSelf("4C 8D", CMemory::Direction::DOWN, 512, 1).ResolveRelativeAddress(0x3, 0x7).RCast<AsyncHandleTracker_s*>(); 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*>(); g_pAsyncFileSlotMgr = streamDbBase.Offset(0x70).FindPatternSelf("48 8D 0D", CMemory::Direction::DOWN, 512, 2).ResolveRelativeAddress(0x3, 0x7).RCast<RHashMap_MT*>();

View File

@ -8,12 +8,12 @@
#include "pakalloc.h" #include "pakalloc.h"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// aligns the slab headers for each asset type // aligns the segment headers for each asset type
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Pak_AlignSlabHeaders(PakFile_s* const pak, PakSlabDescriptor_s* const desc) void Pak_AlignSegmentHeaders(PakFile_s* const pak, PakSegmentDescriptor_s* const desc)
{ {
uint64_t headersSize = 0; uint64_t headersSize = 0;
uint32_t slabHeaderAlignment = desc->slabAlignmentForType[SF_HEAD]; uint8_t headerSegmentAlignment = static_cast<int8_t>(desc->segmentAlignmentForType[SF_HEAD]);
for (uint8_t i = 0; i < PAK_MAX_TRACKED_TYPES; ++i) for (uint8_t i = 0; i < PAK_MAX_TRACKED_TYPES; ++i)
{ {
@ -21,16 +21,19 @@ void Pak_AlignSlabHeaders(PakFile_s* const pak, PakSlabDescriptor_s* const desc)
if (desc->assetTypeCount[i]) if (desc->assetTypeCount[i])
{ {
assert(binding.headerAlignment > 0 && IsPowerOfTwo(binding.headerAlignment)); // asset header alignment really shouldn't be above 255
// if this needs raising, headerSegmentAlignment should be made wider
assert(binding.headerAlignment <= UINT8_MAX);
const size_t alignedSize = ALIGN_VALUE(headersSize, static_cast<size_t>(binding.headerAlignment)); const size_t alignedSize = ALIGN_VALUE(headersSize, static_cast<size_t>(binding.headerAlignment));
pak->memoryData.unkAssetTypeBindingSizes[i] = alignedSize; pak->memoryData.unkAssetTypeBindingSizes[i] = alignedSize;
headersSize = alignedSize + (desc->assetTypeCount[i] * binding.structSize); headersSize = alignedSize + (desc->assetTypeCount[i] * binding.nativeClassSize);
desc->slabSizeForType[SF_HEAD] = headersSize; desc->segmentSizeForType[SF_HEAD] = headersSize;
slabHeaderAlignment = Max(slabHeaderAlignment, binding.headerAlignment); headerSegmentAlignment = Max(headerSegmentAlignment, static_cast<uint8_t>(binding.headerAlignment));
desc->slabAlignmentForType[SF_HEAD] = slabHeaderAlignment; desc->segmentAlignmentForType[SF_HEAD] = headerSegmentAlignment;
} }
} }
} }
@ -38,66 +41,69 @@ void Pak_AlignSlabHeaders(PakFile_s* const pak, PakSlabDescriptor_s* const desc)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// aligns each individual non-header segment // aligns each individual non-header segment
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Pak_AlignSlabData(PakFile_s* const pak, PakSlabDescriptor_s* const desc) void Pak_AlignSegments(PakFile_s* const pak, PakSegmentDescriptor_s* const desc)
{ {
for (uint16_t i = 0; i < pak->GetSlabCount(); ++i) for (uint16_t i = 0; i < pak->GetSegmentCount(); ++i)
{ {
const PakSlabHeader_s* const slabHeader = pak->GetSlabHeader(i); const PakSegmentHeader_s* const segHeader = pak->GetSegmentHeader(i);
const uint8_t slabType = slabHeader->typeFlags & (SF_CPU | SF_TEMP);
if (slabType != SF_HEAD) // if not a header slab const uint8_t segmentType = segHeader->typeFlags & (SF_TEMP | SF_CPU);
if (segmentType != SF_HEAD) // if not a header segment
{ {
// should this be a hard error on release? // should this be a hard error on release?
// slab alignment must not be 0 and must be a power of two // segment alignment must not be 0 and must be a power of two
assert(slabHeader->dataAlignment > 0 && IsPowerOfTwo(slabHeader->dataAlignment)); assert(segHeader->dataAlignment > 0 && IsPowerOfTwo(segHeader->dataAlignment));
const size_t alignedSlabSize = ALIGN_VALUE(desc->slabSizeForType[slabType], static_cast<size_t>(slabHeader->dataAlignment));
desc->slabSizes[i] = alignedSlabSize; const size_t alignedSegmentSize = ALIGN_VALUE(desc->segmentSizeForType[segmentType], static_cast<size_t>(segHeader->dataAlignment));
desc->slabSizeForType[slabType] = alignedSlabSize + slabHeader->dataSize; //const size_t sizeAligned = ~(m_align - 1) & (m_align - 1 + segmentSizeForType[segmentType]);
// check if this slab's alignment is higher than the previous highest for this type desc->segmentSizes[i] = alignedSegmentSize;
// if so, increase the alignment to accommodate this slab desc->segmentSizeForType[segmentType] = alignedSegmentSize + segHeader->dataSize;
desc->slabAlignmentForType[slabType] = Max(desc->slabAlignmentForType[slabType], slabHeader->dataAlignment);
// 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);
} }
} }
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// copy's pages into pre-allocated and aligned slabs // copy's pages into pre-allocated and aligned segments
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Pak_CopyPagesToSlabs(PakFile_s* const pak, PakLoadedInfo_s* const loadedInfo, PakSlabDescriptor_s* const desc) void Pak_CopyPagesToSegments(PakFile_s* const pak, PakLoadedInfo_s* const loadedInfo, PakSegmentDescriptor_s* const desc)
{ {
for (uint32_t i = 0; i < pak->GetPageCount(); ++i) for (uint32_t i = 0; i < pak->GetPageCount(); ++i)
{ {
const PakPageHeader_s* const pageHeader = pak->GetPageHeader(i); const PakPageHeader_s* const pageHeader = pak->GetPageHeader(i);
const uint32_t slabIndex = pageHeader->slabIndex; const uint32_t segmentIndex = pageHeader->segmentIdx;
const PakSlabHeader_s* const slabHeader = pak->GetSlabHeader(slabIndex); const PakSegmentHeader_s* const segHeader = pak->GetSegmentHeader(segmentIndex);
const int typeFlags = slabHeader->typeFlags; const int typeFlags = segHeader->typeFlags;
// check if header page // check if header page
if ((typeFlags & (SF_CPU | SF_TEMP)) != 0) if ((typeFlags & (SF_TEMP | SF_CPU)) != 0)
{ {
// align the slab's current size to the alignment of the new page to get copied in // align the segment'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 // this ensures that the location holding the page is aligned as required
// //
// since the slab will always have alignment equal to or greater than the page, and that alignment will always be a power of 2 // 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 slab, as aligning it to its own alignment is sufficient as long as // 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
// every subsequent page does the same thing // every subsequent page does the same thing
const size_t alignedSlabSize = ALIGN_VALUE(desc->slabSizes[slabIndex], static_cast<size_t>(pageHeader->pageAlignment)); const size_t alignedSegmentSize = ALIGN_VALUE(desc->segmentSizes[segmentIndex], static_cast<size_t>(pageHeader->pageAlignment));
// get a pointer to the newly aligned location within the slab for this page // get a pointer to the newly aligned location within the segment for this page
pak->memoryData.memPageBuffers[i] = reinterpret_cast<uint8_t*>(loadedInfo->slabBuffers[typeFlags & (SF_CPU | SF_TEMP)]) + alignedSlabSize; pak->memoryData.memPageBuffers[i] = reinterpret_cast<uint8_t*>(loadedInfo->segmentBuffers[typeFlags & (SF_TEMP | SF_CPU)]) + alignedSegmentSize;
// update the slab size to reflect the new alignment and page size // update the segment size to reflect the new alignment and page size
desc->slabSizes[slabIndex] = alignedSlabSize + pak->memoryData.pageHeaders[i].dataSize; desc->segmentSizes[segmentIndex] = alignedSegmentSize + pak->memoryData.pageHeaders[i].dataSize;
} }
else else
{ {
// all headers go into one slab and are dealt with separately in Pak_ProcessPakFile // all headers go into one segment 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 // 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 // instead of just the file version
pak->memoryData.memPageBuffers[i] = reinterpret_cast<uint8_t*>(loadedInfo->slabBuffers[SF_HEAD]); pak->memoryData.memPageBuffers[i] = reinterpret_cast<uint8_t*>(loadedInfo->segmentBuffers[SF_HEAD]);
} }
} }
} }

View File

@ -2,9 +2,9 @@
#define RTECH_PAKALLOC_H #define RTECH_PAKALLOC_H
#include "rtech/ipakfile.h" #include "rtech/ipakfile.h"
extern void Pak_AlignSlabHeaders(PakFile_s* const pak, PakSlabDescriptor_s* const desc); extern void Pak_AlignSegmentHeaders(PakFile_s* const pak, PakSegmentDescriptor_s* const desc);
extern void Pak_AlignSlabData(PakFile_s* const pak, PakSlabDescriptor_s* const desc); extern void Pak_AlignSegments(PakFile_s* const pak, PakSegmentDescriptor_s* const desc);
extern void Pak_CopyPagesToSlabs(PakFile_s* const pak, PakLoadedInfo_s* const loadedInfo, PakSlabDescriptor_s* const desc); extern void Pak_CopyPagesToSegments(PakFile_s* const pak, PakLoadedInfo_s* const loadedInfo, PakSegmentDescriptor_s* const desc);
// something with sorting pages? // something with sorting pages?
inline void (*sub_140442740)(PakAsset_s** assetEntries, PakAsset_s** assetEntry, __int64 idx, PakFile_s* pak); inline void (*sub_140442740)(PakAsset_s** assetEntries, PakAsset_s** assetEntry, __int64 idx, PakFile_s* pak);

View File

@ -135,7 +135,7 @@ static const unsigned char /*141313180*/ s_defaultDecoderLUT[] =
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// checks if we have enough output buffer room to decode the data stream // checks if we have enough output buffer room to decode the data stream
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static bool Pak_HasEnoughDecodeBufferAvailable(PakDecoder_s* const decoder, const size_t outLen) bool Pak_HasEnoughDecodeBufferAvailable(PakDecoder_s* const decoder, const size_t outLen)
{ {
// make sure caller has copied all data out the ring buffer first before // make sure caller has copied all data out the ring buffer first before
// overwriting it with new decoded data // overwriting it with new decoded data
@ -146,7 +146,7 @@ static bool Pak_HasEnoughDecodeBufferAvailable(PakDecoder_s* const decoder, cons
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// checks if we have enough source data streamed to decode the next block // checks if we have enough source data streamed to decode the next block
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static bool Pak_HasEnoughStreamedDataForDecode(PakDecoder_s* const decoder, const size_t inLen) bool Pak_HasEnoughStreamedDataForDecode(PakDecoder_s* const decoder, const size_t inLen)
{ {
// the decoder needs at least this amount of input data streamed in order // 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 // to decode the rest of the pak file, as this is where reading has stopped
@ -160,7 +160,7 @@ static bool Pak_HasEnoughStreamedDataForDecode(PakDecoder_s* const decoder, cons
// gets the frame for the data in the ring buffer, the frame returned is always // 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 // ending to the end of the ring buffer, or the end of the data itself
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static PakRingBufferFrame_s Pak_DetermineRingBufferFrame(const uint64_t bufMask, const size_t seekPos, const size_t dataLen) PakRingBufferFrame_s Pak_DetermineRingBufferFrame(const uint64_t bufMask, const size_t seekPos, const size_t dataLen)
{ {
PakRingBufferFrame_s ring; PakRingBufferFrame_s ring;
ring.bufIndex = seekPos & bufMask; ring.bufIndex = seekPos & bufMask;
@ -178,7 +178,7 @@ static PakRingBufferFrame_s Pak_DetermineRingBufferFrame(const uint64_t bufMask,
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// initializes the RTech decoder // initializes the RTech decoder
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static size_t Pak_RTechDecoderInit(PakDecoder_s* const decoder, const uint8_t* const fileBuffer, 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) const uint64_t inputMask, const size_t dataSize, const size_t dataOffset, const size_t headerSize)
{ {
uint64_t frameHeader = *(_QWORD*)((inputMask & (dataOffset + headerSize)) + fileBuffer); uint64_t frameHeader = *(_QWORD*)((inputMask & (dataOffset + headerSize)) + fileBuffer);
@ -243,7 +243,7 @@ static size_t Pak_RTechDecoderInit(PakDecoder_s* const decoder, const uint8_t* c
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// decodes the RTech data stream up to available buffer or data // decodes the RTech data stream up to available buffer or data
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static bool Pak_RTechStreamDecode(PakDecoder_s* const decoder, const size_t inLen, const size_t outLen) bool Pak_RTechStreamDecode(PakDecoder_s* const decoder, const size_t inLen, const size_t outLen)
{ {
bool result; // al bool result; // al
uint64_t outBufBytePos; // r15 uint64_t outBufBytePos; // r15
@ -570,7 +570,7 @@ LABEL_69:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// initializes the ZStd decoder // initializes the ZStd decoder
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static size_t Pak_ZStdDecoderInit(PakDecoder_s* const decoder, const uint8_t* frameHeader, size_t Pak_ZStdDecoderInit(PakDecoder_s* const decoder, const uint8_t* frameHeader,
const size_t dataSize, const size_t headerSize) const size_t dataSize, const size_t headerSize)
{ {
ZSTD_DStream* const dctx = ZSTD_createDStream(); ZSTD_DStream* const dctx = ZSTD_createDStream();
@ -608,7 +608,7 @@ static size_t Pak_ZStdDecoderInit(PakDecoder_s* const decoder, const uint8_t* fr
// decodes the ZStd data stream up to available buffer or data, whichever ends // decodes the ZStd data stream up to available buffer or data, whichever ends
// first // first
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static bool Pak_ZStdStreamDecode(PakDecoder_s* const decoder, const PakRingBufferFrame_s& outFrame, const PakRingBufferFrame_s& inFrame) bool Pak_ZStdStreamDecode(PakDecoder_s* const decoder, const PakRingBufferFrame_s& outFrame, const PakRingBufferFrame_s& inFrame)
{ {
ZSTD_outBuffer outBuffer = { ZSTD_outBuffer outBuffer = {
&decoder->outputBuf[outFrame.bufIndex], &decoder->outputBuf[outFrame.bufIndex],
@ -807,7 +807,7 @@ bool Pak_DecodePakFile(const char* const inPakFile, const char* const outPakFile
CIOStream inPakStream; CIOStream inPakStream;
if (!inPakStream.Open(inPakFile, CIOStream::Mode_e::Read)) if (!inPakStream.Open(inPakFile, CIOStream::READ | CIOStream::BINARY))
{ {
Error(eDLL_T::RTECH, NO_ERROR, "%s: failed to open pak file '%s' for read!\n", Error(eDLL_T::RTECH, NO_ERROR, "%s: failed to open pak file '%s' for read!\n",
__FUNCTION__, inPakFile); __FUNCTION__, inPakFile);
@ -817,7 +817,7 @@ bool Pak_DecodePakFile(const char* const inPakFile, const char* const outPakFile
CIOStream outPakStream; CIOStream outPakStream;
if (!outPakStream.Open(outPakFile, CIOStream::Mode_e::Write)) if (!outPakStream.Open(outPakFile, CIOStream::WRITE | CIOStream::BINARY))
{ {
Error(eDLL_T::RTECH, NO_ERROR, "%s: failed to open pak file '%s' for write!\n", Error(eDLL_T::RTECH, NO_ERROR, "%s: failed to open pak file '%s' for write!\n",
__FUNCTION__, outPakFile); __FUNCTION__, outPakFile);

View File

@ -84,7 +84,7 @@ bool Pak_EncodePakFile(const char* const inPakFile, const char* const outPakFile
CIOStream inPakStream; CIOStream inPakStream;
if (!inPakStream.Open(inPakFile, CIOStream::Mode_e::Read)) if (!inPakStream.Open(inPakFile, CIOStream::READ | CIOStream::BINARY))
{ {
Error(eDLL_T::RTECH, NO_ERROR, "%s: failed to open pak file '%s' for read!\n", Error(eDLL_T::RTECH, NO_ERROR, "%s: failed to open pak file '%s' for read!\n",
__FUNCTION__, inPakFile); __FUNCTION__, inPakFile);
@ -94,7 +94,7 @@ bool Pak_EncodePakFile(const char* const inPakFile, const char* const outPakFile
CIOStream outPakStream; CIOStream outPakStream;
if (!outPakStream.Open(outPakFile, CIOStream::Mode_e::Write)) if (!outPakStream.Open(outPakFile, CIOStream::WRITE | CIOStream::BINARY))
{ {
Error(eDLL_T::RTECH, NO_ERROR, "%s: failed to open pak file '%s' for write!\n", Error(eDLL_T::RTECH, NO_ERROR, "%s: failed to open pak file '%s' for write!\n",
__FUNCTION__, outPakFile); __FUNCTION__, outPakFile);

View File

@ -49,16 +49,16 @@ static bool Pak_ResolveAssetDependency(const PakFile_s* const pak, PakGuid_t cur
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// resolve guid relations for asset // resolve guid relations for asset
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void Pak_ResolveAssetRelations(PakFile_s* const pak, const PakAsset_s* const asset) void Pak_ResolveAssetRelations(PakFile_s* const pak, const PakAsset_s* const asset)
{ {
PakPage_u* const pageDescriptors = &pak->memoryData.pageDescriptors[asset->usesIndex]; PakPage_u* const pageDescriptors = &pak->memoryData.pageDescriptors[asset->dependenciesIndex];
uint32_t* const guidDestriptors = (uint32_t*)g_pakGlobals->loadedPaks[pak->memoryData.pakId & PAK_MAX_LOADED_PAKS_MASK].guidDestriptors; uint32_t* const guidDestriptors = (uint32_t*)g_pakGlobals->loadedPaks[pak->memoryData.pakId & PAK_MAX_LOADED_PAKS_MASK].guidDestriptors;
if (pak_debugrelations.GetBool()) if (pak_debugrelations.GetBool())
Msg(eDLL_T::RTECH, "Resolving relations for asset: '0x%-16llX', dependencies: %-4u; in pak '%s'\n", Msg(eDLL_T::RTECH, "Resolving relations for asset: '0x%-16llX', dependencies: %-4u; in pak '%s'\n",
asset->guid, asset->usesCount, pak->memoryData.fileName); asset->guid, asset->dependenciesCount, pak->memoryData.fileName);
for (uint32_t i = 0; i < asset->usesCount; i++) for (uint32_t i = 0; i < asset->dependenciesCount; i++)
{ {
void** const pCurrentGuid = reinterpret_cast<void**>(pak->memoryData.memPageBuffers[pageDescriptors[i].index] + pageDescriptors[i].offset); void** const pCurrentGuid = reinterpret_cast<void**>(pak->memoryData.memPageBuffers[pageDescriptors[i].index] + pageDescriptors[i].offset);
@ -93,7 +93,7 @@ static void Pak_ResolveAssetRelations(PakFile_s* const pak, const PakAsset_s* co
"pak: '%s'\n" "pak: '%s'\n"
"asset: '0x%llX'\n" "asset: '0x%llX'\n"
"target: '0x%llX'\n", "target: '0x%llX'\n",
i, asset->usesCount, i, asset->dependenciesCount,
pak->memoryData.fileName, pak->memoryData.fileName,
asset->guid, asset->guid,
targetGuid); targetGuid);
@ -112,7 +112,7 @@ static void Pak_ResolveAssetRelations(PakFile_s* const pak, const PakAsset_s* co
} }
} }
static uint32_t Pak_ProcessRemainingPagePointers(PakFile_s* const pak) uint32_t Pak_ProcessRemainingPagePointers(PakFile_s* const pak)
{ {
uint32_t processedPointers = 0; uint32_t processedPointers = 0;
@ -134,7 +134,7 @@ static uint32_t Pak_ProcessRemainingPagePointers(PakFile_s* const pak)
return processedPointers; return processedPointers;
} }
static void Pak_RunAssetLoadingJobs(PakFile_s* const pak) void Pak_RunAssetLoadingJobs(PakFile_s* const pak)
{ {
pak->numProcessedPointers = Pak_ProcessRemainingPagePointers(pak); pak->numProcessedPointers = Pak_ProcessRemainingPagePointers(pak);
@ -167,7 +167,7 @@ static void Pak_RunAssetLoadingJobs(PakFile_s* const pak)
} }
else else
{ {
if (_InterlockedExchangeAdd16(&pakAsset->numRemainingDependencies, -1) == 1) if (_InterlockedExchangeAdd16((volatile signed __int16*)&pakAsset->numRemainingDependencies, 0xFFFFu) == 1)
Pak_ProcessAssetRelationsAndResolveDependencies(pak, pakAsset, currentAsset, assetBind); Pak_ProcessAssetRelationsAndResolveDependencies(pak, pakAsset, currentAsset, assetBind);
_InterlockedDecrement16(&g_pakGlobals->numAssetLoadJobs); _InterlockedDecrement16(&g_pakGlobals->numAssetLoadJobs);
@ -191,7 +191,7 @@ static void Pak_RunAssetLoadingJobs(PakFile_s* const pak)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// load user-requested pak files on-demand // load user-requested pak files on-demand
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static PakHandle_t Pak_LoadAsync(const char* const fileName, CAlignedMemAlloc* const allocator, const int logChannel, const bool bUnk) PakHandle_t Pak_LoadAsync(const char* const fileName, CAlignedMemAlloc* const allocator, const int logChannel, const bool bUnk)
{ {
if (!Pak_FileExists(fileName)) if (!Pak_FileExists(fileName))
{ {
@ -216,7 +216,7 @@ static PakHandle_t Pak_LoadAsync(const char* const fileName, CAlignedMemAlloc* c
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// unloads loaded pak files // unloads loaded pak files
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void Pak_UnloadAsync(const PakHandle_t handle) void Pak_UnloadAsync(const PakHandle_t handle)
{ {
const PakLoadedInfo_s* const pakInfo = Pak_GetPakInfo(handle); const PakLoadedInfo_s* const pakInfo = Pak_GetPakInfo(handle);
@ -238,8 +238,9 @@ static const int s_patchCmdToBytesToProcess[] = { CMD_INVALID, CMD_INVALID, CMD_
#undef CMD_INVALID #undef CMD_INVALID
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// loads and processes a pak file (handles decompression and patching) // loads and processes a pak file (handles decompression and patching)
// TODO: !!! FINISH REBUILD !!!
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
static bool Pak_ProcessPakFile(PakFile_s* const pak) bool Pak_ProcessPakFile(PakFile_s* const pak)
{ {
PakFileStream_s* const fileStream = &pak->fileStream; PakFileStream_s* const fileStream = &pak->fileStream;
PakMemoryData_s* const memoryData = &pak->memoryData; PakMemoryData_s* const memoryData = &pak->memoryData;
@ -521,9 +522,9 @@ static bool Pak_ProcessPakFile(PakFile_s* const pak)
return memoryData->patchSrcSize == 0; return memoryData->patchSrcSize == 0;
} }
// sets patch variables for copying the next unprocessed page into the relevant slab buffer // sets patch variables for copying the next unprocessed page into the relevant segment buffer
// if this is a header page, fetch info from the next unprocessed asset and copy over the asset's header // if this is a header page, fetch info from the next unprocessed asset and copy over the asset's header
static bool Pak_PrepareNextPageForPatching(PakLoadedInfo_s* const loadedInfo, PakFile_s* const pak) bool Pak_PrepareNextPageForPatching(PakLoadedInfo_s* const loadedInfo, PakFile_s* const pak)
{ {
Pak_RunAssetLoadingJobs(pak); Pak_RunAssetLoadingJobs(pak);
@ -541,7 +542,7 @@ static bool Pak_PrepareNextPageForPatching(PakLoadedInfo_s* const loadedInfo, Pa
: highestProcessedPageIdx - pak->GetPageCount(); : highestProcessedPageIdx - pak->GetPageCount();
const PakPageHeader_s* const nextMemPageHeader = &pak->memoryData.pageHeaders[currentPageIndex]; const PakPageHeader_s* const nextMemPageHeader = &pak->memoryData.pageHeaders[currentPageIndex];
if ((pak->memoryData.slabHeaders[nextMemPageHeader->slabIndex].typeFlags & (SF_CPU | SF_TEMP)) != 0) if ((pak->memoryData.segmentHeaders[nextMemPageHeader->segmentIdx].typeFlags & (SF_TEMP | SF_CPU)) != 0)
{ {
pak->memoryData.patchSrcSize = nextMemPageHeader->dataSize; pak->memoryData.patchSrcSize = nextMemPageHeader->dataSize;
pak->memoryData.patchDstPtr = reinterpret_cast<char*>(pak->memoryData.memPageBuffers[currentPageIndex]); pak->memoryData.patchDstPtr = reinterpret_cast<char*>(pak->memoryData.memPageBuffers[currentPageIndex]);
@ -555,13 +556,13 @@ static bool Pak_PrepareNextPageForPatching(PakLoadedInfo_s* const loadedInfo, Pa
pak->memoryData.patchSrcSize = pakAsset->headerSize; pak->memoryData.patchSrcSize = pakAsset->headerSize;
const int assetTypeIdx = pakAsset->HashTableIndexForAssetType(); const int assetTypeIdx = pakAsset->HashTableIndexForAssetType();
pak->memoryData.patchDstPtr = reinterpret_cast<char*>(loadedInfo->slabBuffers[0]) + pak->memoryData.unkAssetTypeBindingSizes[assetTypeIdx]; pak->memoryData.patchDstPtr = reinterpret_cast<char*>(loadedInfo->segmentBuffers[0]) + pak->memoryData.unkAssetTypeBindingSizes[assetTypeIdx];
pak->memoryData.unkAssetTypeBindingSizes[assetTypeIdx] += g_pakGlobals->assetBindings[assetTypeIdx].structSize; pak->memoryData.unkAssetTypeBindingSizes[assetTypeIdx] += g_pakGlobals->assetBindings[assetTypeIdx].nativeClassSize;
return true; return true;
} }
static bool Pak_ProcessAssets(PakLoadedInfo_s* const loadedInfo) bool Pak_ProcessAssets(PakLoadedInfo_s* const loadedInfo)
{ {
PakFile_s* const pak = loadedInfo->pakFile; PakFile_s* const pak = loadedInfo->pakFile;
@ -592,8 +593,8 @@ static bool Pak_ProcessAssets(PakLoadedInfo_s* const loadedInfo)
if (v4 >= pageCount) if (v4 >= pageCount)
shiftedPageIndex -= pageCount; shiftedPageIndex -= pageCount;
// if "temp_" slab // if "temp_" segment
if ((pak->memoryData.slabHeaders[pak->memoryData.pageHeaders[shiftedPageIndex].slabIndex].typeFlags & (SF_CPU | SF_TEMP)) != 0) if ((pak->memoryData.segmentHeaders[pak->memoryData.pageHeaders[shiftedPageIndex].segmentIdx].typeFlags & (SF_TEMP | SF_CPU)) != 0)
{ {
if (Pak_PrepareNextPageForPatching(loadedInfo, pak)) if (Pak_PrepareNextPageForPatching(loadedInfo, pak))
continue; continue;
@ -605,12 +606,12 @@ static bool Pak_ProcessAssets(PakLoadedInfo_s* const loadedInfo)
const uint32_t headPageOffset = asset->headPtr.offset; const uint32_t headPageOffset = asset->headPtr.offset;
char* const v8 = pak->memoryData.patchDstPtr - asset->headerSize; char* const v8 = pak->memoryData.patchDstPtr - asset->headerSize;
const uint32_t newOffsetFromSlabBufferToHeader = LODWORD(pak->memoryData.patchDstPtr) const uint32_t newOffsetFromSegmentBufferToHeader = LODWORD(pak->memoryData.patchDstPtr)
- asset->headerSize - asset->headerSize
- LODWORD(loadedInfo->slabBuffers[0]); - LODWORD(loadedInfo->segmentBuffers[0]);
asset->headPtr.offset = newOffsetFromSlabBufferToHeader; asset->headPtr.offset = newOffsetFromSegmentBufferToHeader;
const uint32_t offsetSize = newOffsetFromSlabBufferToHeader - headPageOffset; const uint32_t offsetSize = newOffsetFromSegmentBufferToHeader - headPageOffset;
for (uint32_t i = pak->memoryData.numShiftedPointers; i < pak->GetPointerCount(); pak->memoryData.numShiftedPointers = i) for (uint32_t i = pak->memoryData.numShiftedPointers; i < pak->GetPointerCount(); pak->memoryData.numShiftedPointers = i)
{ {
@ -637,9 +638,9 @@ static bool Pak_ProcessAssets(PakLoadedInfo_s* const loadedInfo)
i = pak->memoryData.numShiftedPointers + 1; i = pak->memoryData.numShiftedPointers + 1;
} }
for (uint32_t j = 0; j < asset->usesCount; ++j) for (uint32_t j = 0; j < asset->dependenciesCount; ++j)
{ {
PakPage_u* const descriptor = &pak->memoryData.pageDescriptors[asset->usesIndex + j]; PakPage_u* const descriptor = &pak->memoryData.pageDescriptors[asset->dependenciesIndex + j];
if (descriptor->index == shiftedPageIndex) if (descriptor->index == shiftedPageIndex)
descriptor->offset += offsetSize; descriptor->offset += offsetSize;
@ -654,9 +655,9 @@ static bool Pak_ProcessAssets(PakLoadedInfo_s* const loadedInfo)
pak->memoryData.patchSrcSize = v17->headerSize; pak->memoryData.patchSrcSize = v17->headerSize;
const uint8_t assetTypeIdx = v17->HashTableIndexForAssetType(); const uint8_t assetTypeIdx = v17->HashTableIndexForAssetType();
pak->memoryData.patchDstPtr = reinterpret_cast<char*>(loadedInfo->slabBuffers[0]) + pak->memoryData.unkAssetTypeBindingSizes[assetTypeIdx]; pak->memoryData.patchDstPtr = reinterpret_cast<char*>(loadedInfo->segmentBuffers[0]) + pak->memoryData.unkAssetTypeBindingSizes[assetTypeIdx];
pak->memoryData.unkAssetTypeBindingSizes[assetTypeIdx] += g_pakGlobals->assetBindings[assetTypeIdx].structSize; pak->memoryData.unkAssetTypeBindingSizes[assetTypeIdx] += g_pakGlobals->assetBindings[assetTypeIdx].nativeClassSize;
} }
else else
{ {
@ -734,7 +735,7 @@ static bool Pak_ProcessAssets(PakLoadedInfo_s* const loadedInfo)
return true; return true;
} }
static void Pak_StubInvalidAssetBinds(PakFile_s* const pak, PakSlabDescriptor_s* const desc) void Pak_StubInvalidAssetBinds(PakFile_s* const pak, PakSegmentDescriptor_s* const desc)
{ {
for (uint32_t i = 0; i < pak->GetAssetCount(); ++i) for (uint32_t i = 0; i < pak->GetAssetCount(); ++i)
{ {
@ -756,7 +757,7 @@ static void Pak_StubInvalidAssetBinds(PakFile_s* const pak, PakSlabDescriptor_s*
assetBinding->replaceAssetFunc = nullptr; assetBinding->replaceAssetFunc = nullptr;
assetBinding->allocator = AlignedMemAlloc(); assetBinding->allocator = AlignedMemAlloc();
assetBinding->headerSize = asset->headerSize; assetBinding->headerSize = asset->headerSize;
assetBinding->structSize = asset->headerSize; assetBinding->nativeClassSize = asset->headerSize;
assetBinding->headerAlignment = pak->memoryData.pageHeaders[asset->headPtr.index].pageAlignment; assetBinding->headerAlignment = pak->memoryData.pageHeaders[asset->headPtr.index].pageAlignment;
assetBinding->type = PakAssetBinding_s::STUB; assetBinding->type = PakAssetBinding_s::STUB;
} }
@ -780,16 +781,16 @@ static void Pak_StubInvalidAssetBinds(PakFile_s* const pak, PakSlabDescriptor_s*
} }
} }
static bool Pak_StartLoadingPak(PakLoadedInfo_s* const loadedInfo) bool Pak_StartLoadingPak(PakLoadedInfo_s* const loadedInfo)
{ {
PakFile_s* const pakFile = loadedInfo->pakFile; PakFile_s* const pakFile = loadedInfo->pakFile;
if (pakFile->memoryData.patchSrcSize && !Pak_ProcessPakFile(pakFile)) if (pakFile->memoryData.patchSrcSize && !Pak_ProcessPakFile(pakFile))
return false; return false;
PakSlabDescriptor_s slabDesc = {}; PakSegmentDescriptor_s pakDescriptor = {};
Pak_StubInvalidAssetBinds(pakFile, &slabDesc); Pak_StubInvalidAssetBinds(pakFile, &pakDescriptor);
const uint32_t numAssets = pakFile->GetAssetCount(); const uint32_t numAssets = pakFile->GetAssetCount();
@ -798,33 +799,33 @@ static bool Pak_StartLoadingPak(PakLoadedInfo_s* const loadedInfo)
sub_140442740(pakFile->memoryData.ppAssetEntries, &pakFile->memoryData.ppAssetEntries[numAssets], numAssets, pakFile); sub_140442740(pakFile->memoryData.ppAssetEntries, &pakFile->memoryData.ppAssetEntries[numAssets], numAssets, pakFile);
// pak must have no more than PAK_MAX_SLABS slabs as otherwise we will overrun the above "slabSizes" array // pak must have no more than PAK_MAX_SEGMENTS segments as otherwise we will overrun the above "segmentSizes" array
// and write to arbitrary locations on the stack // and write to arbitrary locations on the stack
if (pakFile->GetSlabCount() > PAK_MAX_SLABS) if (pakFile->GetSegmentCount() > PAK_MAX_SEGMENTS)
{ {
Error(eDLL_T::RTECH, EXIT_FAILURE, "Too many slabs in pakfile '%s'. Max %hu, found %hu.\n", pakFile->GetName(), PAK_MAX_SLABS, pakFile->GetSlabCount()); Error(eDLL_T::RTECH, EXIT_FAILURE, "Too many segments in pakfile '%s'. Max %i, found %i.\n", pakFile->GetName(), PAK_MAX_SEGMENTS, pakFile->GetSegmentCount());
return false; return false;
} }
Pak_AlignSlabHeaders(pakFile, &slabDesc); Pak_AlignSegmentHeaders(pakFile, &pakDescriptor);
Pak_AlignSlabData(pakFile, &slabDesc); Pak_AlignSegments(pakFile, &pakDescriptor);
// allocate slab buffers with predetermined alignments; pages will be // allocate segment buffers with predetermined alignments; pages will be
// copied into here // copied into here
for (int8_t i = 0; i < PAK_SLAB_BUFFER_TYPES; ++i) for (int8_t i = 0; i < PAK_SEGMENT_BUFFER_TYPES; ++i)
{ {
if (slabDesc.slabSizeForType[i]) if (pakDescriptor.segmentSizeForType[i])
loadedInfo->slabBuffers[i] = AlignedMemAlloc()->Alloc(slabDesc.slabSizeForType[i], slabDesc.slabAlignmentForType[i]); loadedInfo->segmentBuffers[i] = AlignedMemAlloc()->Alloc(pakDescriptor.segmentSizeForType[i], pakDescriptor.segmentAlignmentForType[i]);
} }
Pak_CopyPagesToSlabs(pakFile, loadedInfo, &slabDesc); Pak_CopyPagesToSegments(pakFile, loadedInfo, &pakDescriptor);
const PakFileHeader_s& pakHdr = pakFile->GetHeader(); const PakFileHeader_s& pakHdr = pakFile->GetHeader();
if (Pak_StreamingEnabled()) if (Pak_StreamingEnabled())
Pak_LoadStreamingData(loadedInfo); Pak_LoadStreamingData(loadedInfo);
const __int64 v106 = pakHdr.pointerCount + 2 * (pakHdr.patchIndex + pakHdr.assetCount + 4ull * pakHdr.assetCount + pakHdr.memSlabCount); const __int64 v106 = pakHdr.descriptorCount + 2 * (pakHdr.patchIndex + pakHdr.assetCount + 4ull * pakHdr.assetCount + pakHdr.virtualSegmentCount);
const __int64 patchDestOffset = pakHdr.GetTotalHeaderSize() + 2 * (pakHdr.patchIndex + 6ull * pakHdr.memPageCount + 4 * v106); const __int64 patchDestOffset = pakHdr.GetTotalHeaderSize() + 2 * (pakHdr.patchIndex + 6ull * pakHdr.memPageCount + 4 * v106);
pakFile->dword14 = 1; pakFile->dword14 = 1;

View File

@ -6,7 +6,7 @@
#include "rtech/ipakfile.h" #include "rtech/ipakfile.h"
#include "pakpatch.h" #include "pakpatch.h"
static bool PATCH_CMD_0(PakFile_s* const pak, size_t* const numAvailableBytes) bool PATCH_CMD_0(PakFile_s* const pak, size_t* const numAvailableBytes)
{ {
unsigned __int64 m_numBytesToProcess_maybe; // r9 unsigned __int64 m_numBytesToProcess_maybe; // r9
unsigned __int64 v4; // rdi unsigned __int64 v4; // rdi
@ -83,55 +83,65 @@ static bool PATCH_CMD_0(PakFile_s* const pak, size_t* const numAvailableBytes)
return pak->memoryData.numPatchBytesToProcess == 0; return pak->memoryData.numPatchBytesToProcess == 0;
} }
static bool PATCH_CMD_1(PakFile_s* const pak, size_t* const pNumBytesAvailable) bool PATCH_CMD_1(PakFile_s* const pak, size_t* const numAvailableBytes)
{ {
const size_t numBytesToProcess = pak->memoryData.numPatchBytesToProcess; unsigned __int64 m_numBytesToProcess_maybe; // r8
const size_t numBytesAvailable = *pNumBytesAvailable; size_t v3; // r9
const size_t processedPatchedDataSize = pak->memoryData.processedPatchedDataSize; uint64_t m_processedPatchedDataSize; // rax
if (*pNumBytesAvailable > numBytesToProcess) m_numBytesToProcess_maybe = pak->memoryData.numPatchBytesToProcess;
v3 = *numAvailableBytes;
m_processedPatchedDataSize = pak->memoryData.processedPatchedDataSize;
if (*numAvailableBytes > m_numBytesToProcess_maybe)
{ {
pak->memoryData.numPatchBytesToProcess = 0ull; pak->memoryData.numPatchBytesToProcess = 0i64;
pak->memoryData.processedPatchedDataSize += numBytesToProcess; pak->memoryData.processedPatchedDataSize += m_numBytesToProcess_maybe;
*pNumBytesAvailable = numBytesAvailable - numBytesToProcess; *numAvailableBytes = v3 - m_numBytesToProcess_maybe;
return true; return true;
} }
else else
{ {
pak->memoryData.processedPatchedDataSize += numBytesAvailable; pak->memoryData.processedPatchedDataSize += v3;
pak->memoryData.numPatchBytesToProcess -= numBytesAvailable; pak->memoryData.numPatchBytesToProcess -= v3;
*pNumBytesAvailable = NULL; *numAvailableBytes = NULL;
return false; return false;
} }
} }
static bool PATCH_CMD_2(PakFile_s* const pak, size_t* const pNumBytesAvailable) bool PATCH_CMD_2(PakFile_s* const pak, size_t* const numAvailableBytes)
{ {
NOTE_UNUSED(pNumBytesAvailable); NOTE_UNUSED(numAvailableBytes);
size_t numBytesToProcess = pak->memoryData.numPatchBytesToProcess; unsigned __int64 m_numBytesToProcess_maybe;
const size_t v3 = pak->memoryData.field_2A8; unsigned __int64 v3;
const char* m_patchDataPtr;
m_numBytesToProcess_maybe = pak->memoryData.numPatchBytesToProcess;
v3 = pak->memoryData.field_2A8;
if (v3) if (v3)
{ {
if (numBytesToProcess <= v3) m_patchDataPtr = pak->memoryData.patchDataPtr;
if (m_numBytesToProcess_maybe <= v3)
{ {
pak->memoryData.numPatchBytesToProcess = 0ull; pak->memoryData.numPatchBytesToProcess = 0i64;
pak->memoryData.patchDataPtr += numBytesToProcess; pak->memoryData.patchDataPtr += m_numBytesToProcess_maybe;
pak->memoryData.field_2A8 = v3 - numBytesToProcess; pak->memoryData.field_2A8 = v3 - m_numBytesToProcess_maybe;
return true; return true;
} }
pak->memoryData.field_2A8 = 0i64; pak->memoryData.field_2A8 = 0i64;
numBytesToProcess -= v3; m_numBytesToProcess_maybe -= v3;
pak->memoryData.patchDataPtr += v3; pak->memoryData.patchDataPtr += v3;
pak->memoryData.numPatchBytesToProcess = numBytesToProcess; pak->memoryData.numPatchBytesToProcess = m_numBytesToProcess_maybe;
} }
const size_t patchSrcSize = Min(numBytesToProcess, pak->memoryData.patchSrcSize); const size_t patchSrcSize = min(m_numBytesToProcess_maybe, pak->memoryData.patchSrcSize);
memcpy(pak->memoryData.patchDstPtr, pak->memoryData.patchDataPtr, patchSrcSize); memcpy(pak->memoryData.patchDstPtr, pak->memoryData.patchDataPtr, patchSrcSize);
@ -143,10 +153,13 @@ static bool PATCH_CMD_2(PakFile_s* const pak, size_t* const pNumBytesAvailable)
return pak->memoryData.numPatchBytesToProcess == 0; return pak->memoryData.numPatchBytesToProcess == 0;
} }
static bool PATCH_CMD_3(PakFile_s* const pak, size_t* const pNumBytesAvailable) bool PATCH_CMD_3(PakFile_s* const pak, size_t* const numAvailableBytes)
{ {
const size_t numBytesLeft = Min(*pNumBytesAvailable, pak->memoryData.numPatchBytesToProcess); size_t patchSrcSize = pak->memoryData.patchSrcSize;
const size_t patchSrcSize = Min(numBytesLeft, pak->memoryData.patchSrcSize);
size_t v9 = min(*numAvailableBytes, pak->memoryData.numPatchBytesToProcess);
patchSrcSize = min(v9, patchSrcSize);
memcpy(pak->memoryData.patchDstPtr, pak->memoryData.patchDataPtr, patchSrcSize); memcpy(pak->memoryData.patchDstPtr, pak->memoryData.patchDataPtr, patchSrcSize);
pak->memoryData.patchDataPtr += patchSrcSize; pak->memoryData.patchDataPtr += patchSrcSize;
@ -154,16 +167,15 @@ static bool PATCH_CMD_3(PakFile_s* const pak, size_t* const pNumBytesAvailable)
pak->memoryData.patchSrcSize -= patchSrcSize; pak->memoryData.patchSrcSize -= patchSrcSize;
pak->memoryData.patchDstPtr += patchSrcSize; pak->memoryData.patchDstPtr += patchSrcSize;
pak->memoryData.numPatchBytesToProcess -= patchSrcSize; pak->memoryData.numPatchBytesToProcess -= patchSrcSize;
*pNumBytesAvailable = *pNumBytesAvailable - patchSrcSize; *numAvailableBytes = *numAvailableBytes - patchSrcSize;
return pak->memoryData.numPatchBytesToProcess == 0; return pak->memoryData.numPatchBytesToProcess == 0;
} }
static bool PATCH_CMD_4_5(PakFile_s* const pak, size_t* const pNumBytesAvailable) bool PATCH_CMD_4_5(PakFile_s* const pak, size_t* const numAvailableBytes)
{ {
const size_t numBytesAvailable = *pNumBytesAvailable; const size_t v2 = *numAvailableBytes;
if (!v2)
if (!numBytesAvailable)
return false; return false;
*pak->memoryData.patchDstPtr = *(_BYTE*)pak->memoryData.patchDataPtr++; *pak->memoryData.patchDstPtr = *(_BYTE*)pak->memoryData.patchDataPtr++;
@ -171,29 +183,29 @@ static bool PATCH_CMD_4_5(PakFile_s* const pak, size_t* const pNumBytesAvailable
--pak->memoryData.patchSrcSize; --pak->memoryData.patchSrcSize;
++pak->memoryData.patchDstPtr; ++pak->memoryData.patchDstPtr;
pak->memoryData.patchFunc = PATCH_CMD_0; pak->memoryData.patchFunc = PATCH_CMD_0;
*pNumBytesAvailable = numBytesAvailable - 1; *numAvailableBytes = v2 - 1;
return PATCH_CMD_0(pak, pNumBytesAvailable); return PATCH_CMD_0(pak, numAvailableBytes);
} }
static bool PATCH_CMD_6(PakFile_s* const pak, size_t* const pNumBytesAvailable) bool PATCH_CMD_6(PakFile_s* const pak, size_t* const numAvailableBytes)
{ {
const size_t numBytesAvailable = *pNumBytesAvailable; const size_t v2 = *numAvailableBytes;
size_t numBytesToSkip = 2; size_t v3 = 2;
if (*pNumBytesAvailable < 2) if (*numAvailableBytes < 2)
{ {
if (!*pNumBytesAvailable) if (!*numAvailableBytes)
return false; return false;
numBytesToSkip = *pNumBytesAvailable; v3 = *numAvailableBytes;
} }
const void* const patchDataPtr = (const void*)pak->memoryData.patchDataPtr; const void* const patchDataPtr = (const void*)pak->memoryData.patchDataPtr;
const size_t patchSrcSize = pak->memoryData.patchSrcSize; const size_t patchSrcSize = pak->memoryData.patchSrcSize;
char* const patchDstPtr = pak->memoryData.patchDstPtr; char* const patchDstPtr = pak->memoryData.patchDstPtr;
if (numBytesToSkip > patchSrcSize) if (v3 > patchSrcSize)
{ {
memcpy(patchDstPtr, patchDataPtr, patchSrcSize); memcpy(patchDstPtr, patchDataPtr, patchSrcSize);
pak->memoryData.patchDataPtr += patchSrcSize; pak->memoryData.patchDataPtr += patchSrcSize;
@ -201,26 +213,26 @@ static bool PATCH_CMD_6(PakFile_s* const pak, size_t* const pNumBytesAvailable)
pak->memoryData.patchSrcSize -= patchSrcSize; pak->memoryData.patchSrcSize -= patchSrcSize;
pak->memoryData.patchDstPtr += patchSrcSize; pak->memoryData.patchDstPtr += patchSrcSize;
pak->memoryData.patchFunc = PATCH_CMD_4_5; pak->memoryData.patchFunc = PATCH_CMD_4_5;
*pNumBytesAvailable = numBytesAvailable - patchSrcSize; *numAvailableBytes = v2 - patchSrcSize;
} }
else else
{ {
memcpy(patchDstPtr, patchDataPtr, numBytesToSkip); memcpy(patchDstPtr, patchDataPtr, v3);
pak->memoryData.patchDataPtr += numBytesToSkip; pak->memoryData.patchDataPtr += v3;
pak->memoryData.processedPatchedDataSize += numBytesToSkip; pak->memoryData.processedPatchedDataSize += v3;
pak->memoryData.patchSrcSize -= numBytesToSkip; pak->memoryData.patchSrcSize -= v3;
pak->memoryData.patchDstPtr += numBytesToSkip; pak->memoryData.patchDstPtr += v3;
if (numBytesAvailable >= 2) if (v2 >= 2)
{ {
pak->memoryData.patchFunc = PATCH_CMD_0; pak->memoryData.patchFunc = PATCH_CMD_0;
*pNumBytesAvailable = numBytesAvailable - numBytesToSkip; *numAvailableBytes = v2 - v3;
return PATCH_CMD_0(pak, pNumBytesAvailable); return PATCH_CMD_0(pak, numAvailableBytes);
} }
pak->memoryData.patchFunc = PATCH_CMD_4_5; pak->memoryData.patchFunc = PATCH_CMD_4_5;
*pNumBytesAvailable = NULL; *numAvailableBytes = NULL;
} }
return false; return false;

View File

@ -22,7 +22,7 @@ static void Pak_ListPaks_f()
uint32_t numLoaded = 0; uint32_t numLoaded = 0;
for (uint16_t i = 0, n = PAK_MAX_LOADED_PAKS; i < n; ++i) for (int16_t i = 0, n = g_pakGlobals->loadedPakCount; i < n; ++i)
{ {
const PakLoadedInfo_s& info = g_pakGlobals->loadedPaks[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); const char* const pakStatus = Pak_StatusToString(info.status);
Msg(eDLL_T::RTECH, "| %04i | %-50s | %-36s | %11u |\n", info.handle, info.fileName, pakStatus, info.assetCount); Msg(eDLL_T::RTECH, "| %04i | %-50s | %-36s | %11i |\n", info.handle, info.fileName, pakStatus, info.assetCount);
numLoaded++; numLoaded++;
} }
Msg(eDLL_T::RTECH, "|------|----------------------------------------------------|--------------------------------------|-------------|\n"); Msg(eDLL_T::RTECH, "|------|----------------------------------------------------|--------------------------------------|-------------|\n");
Msg(eDLL_T::RTECH, "| %18u loaded paks. |\n", numLoaded); Msg(eDLL_T::RTECH, "| %18i loaded paks. |\n", numLoaded);
Msg(eDLL_T::RTECH, "|------|----------------------------------------------------|--------------------------------------|-------------|\n"); Msg(eDLL_T::RTECH, "|------|----------------------------------------------------|--------------------------------------|-------------|\n");
} }
@ -46,12 +46,12 @@ Pak_ListTypes_f
*/ */
static void Pak_ListTypes_f() static void Pak_ListTypes_f()
{ {
Msg(eDLL_T::RTECH, "| ext | description | version | alignment | header size | struct size |\n"); Msg(eDLL_T::RTECH, "| ext | description | version | header size | native size |\n");
Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-----------|-------------|-------------|\n"); Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-------------|-------------|\n");
uint32_t numRegistered = 0; uint32_t numRegistered = 0;
for (uint8_t i = 0; i < PAK_MAX_TRACKED_TYPES; ++i) for (int8_t i = 0; i < PAK_MAX_TRACKED_TYPES; ++i)
{ {
const PakAssetBinding_s& type = g_pakGlobals->assetBindings[i]; const PakAssetBinding_s& type = g_pakGlobals->assetBindings[i];
@ -61,14 +61,12 @@ static void Pak_ListTypes_f()
FourCCString_t assetExtension; FourCCString_t assetExtension;
FourCCToString(assetExtension, type.extension); FourCCToString(assetExtension, type.extension);
Msg(eDLL_T::RTECH, "| %-4s | %-25s | %7u | %9u | %11u | %11u |\n", Msg(eDLL_T::RTECH, "| %-4s | %-25s | %7i | %11i | %11i |\n", assetExtension, type.description, type.version, type.headerSize, type.nativeClassSize);
assetExtension, type.description, type.version, type.headerAlignment, type.headerSize, type.structSize);
numRegistered++; numRegistered++;
} }
Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-----------|-------------|-------------|\n"); Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-------------|-------------|\n");
Msg(eDLL_T::RTECH, "| %18u registered types. |\n", numRegistered); Msg(eDLL_T::RTECH, "| %18i registered types. |\n", numRegistered);
Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-----------|-------------|-------------|\n"); Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-------------|-------------|\n");
} }
/* /*

View File

@ -60,8 +60,8 @@ struct PakLoadFuncs_s
void (*HelpWithPendingRequests)(); void (*HelpWithPendingRequests)();
// lock and wait for a specific pakfile to load by pakid, and help with other // lock and wait for a specific pakfile to load by pakid, and help with other
// allocated jobs in the mean time. returns false if status is PAK_STATUS_ERROR // allocated jobs in the mean time
bool (*WaitForAsyncLoad)(const PakHandle_t handle, void(* const finishCallback)); void (*WaitForAsyncLoad)(const PakHandle_t handle, void(* const finishCallback));
// lock and wait for a specific pakfile to unload by pakid, and help with other // lock and wait for a specific pakfile to unload by pakid, and help with other
// allocated jobs in the mean time // allocated jobs in the mean time

View File

@ -263,14 +263,7 @@ PakLoadedInfo_s* Pak_GetPakInfo(const PakHandle_t pakId)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
const PakLoadedInfo_s* Pak_GetPakInfo(const char* const pakName) const PakLoadedInfo_s* Pak_GetPakInfo(const char* const pakName)
{ {
// a pak under the same name can be loaded more than once, the hotswap for (int16_t i = 0; i < g_pakGlobals->loadedPakCount; ++i)
// 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]; const PakLoadedInfo_s* const info = &g_pakGlobals->loadedPaks[i];
if (!info) if (!info)
@ -282,17 +275,11 @@ const PakLoadedInfo_s* Pak_GetPakInfo(const char* const pakName)
if (strcmp(pakName, info->fileName) != 0) if (strcmp(pakName, info->fileName) != 0)
continue; continue;
if (info->handle > highestHandle) return info;
highestHandle = info->handle;
} }
if (highestHandle == PAK_INVALID_HANDLE) DevWarning(eDLL_T::RTECH, "%s - Failed to retrieve pak info for name '%s'\n", __FUNCTION__, pakName);
{ return nullptr;
DevWarning(eDLL_T::RTECH, "%s - Failed to retrieve pak info for name '%s'\n", __FUNCTION__, pakName);
return nullptr;
}
return Pak_GetPakInfo(highestHandle);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -300,7 +287,7 @@ const PakLoadedInfo_s* Pak_GetPakInfo(const char* const pakName)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
PakPatchDataHeader_s* Pak_GetPatchDataHeader(PakFileHeader_s* const pakHeader) PakPatchDataHeader_s* Pak_GetPatchDataHeader(PakFileHeader_s* const pakHeader)
{ {
// shouldn't be called if the pak doesn't have patches! // shouldn't be called if the pak doesn1't have patches!
assert(pakHeader->patchIndex > 0); assert(pakHeader->patchIndex > 0);
return reinterpret_cast<PakPatchDataHeader_s*>(reinterpret_cast<uint8_t* const>(pakHeader) + sizeof(PakFileHeader_s)); return reinterpret_cast<PakPatchDataHeader_s*>(reinterpret_cast<uint8_t* const>(pakHeader) + sizeof(PakFileHeader_s));
} }
@ -378,7 +365,7 @@ bool Pak_UpdatePatchHeaders(uint8_t* const inBuf, const char* const outPakFile)
// unable to open patch while there should be one, we must calculate // 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 // new file sizes here, or else the runtime would fail to load them
if (!inPatch.Open(patchFile, CIOStream::Mode_e::Read)) if (!inPatch.Open(patchFile, CIOStream::READ | CIOStream::BINARY))
return false; return false;
const size_t fileSize = inPatch.GetSize(); const size_t fileSize = inPatch.GetSize();

View File

@ -104,7 +104,7 @@ void CSurface::Init()
this->m_PlaylistLabel->SetSize({ 50, 25 }); this->m_PlaylistLabel->SetSize({ 50, 25 });
this->m_PlaylistLabel->SetLocation({ 365, 53 }); this->m_PlaylistLabel->SetLocation({ 365, 53 });
this->m_PlaylistLabel->SetTabIndex(0); this->m_PlaylistLabel->SetTabIndex(0);
this->m_PlaylistLabel->SetText("Mode"); this->m_PlaylistLabel->SetText("Playlist");
this->m_PlaylistLabel->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_PlaylistLabel->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
this->m_PlaylistLabel->SetTextAlign(Drawing::ContentAlignment::TopLeft); this->m_PlaylistLabel->SetTextAlign(Drawing::ContentAlignment::TopLeft);
this->m_GameGroup->AddControl(this->m_PlaylistLabel); 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) void CSurface::AddLog(const LogType_t type, const char* const pszText)
{ {
m_LogList.emplace_back(type, pszText); m_LogList.push_back(LogList_t(type, pszText));
// Clamp the log list size, as we cannot fit more elements than // Clamp the log list size, as we cannot fit more elements than
// 8 in the console window. // 8 in the console window.

View File

@ -303,7 +303,7 @@ void CLauncher::SetupLaunchContext(const char* szConfig, const char* szGameDll,
{ {
cfgFileName.Format(GAME_CFG_PATH"%s", szConfig); cfgFileName.Format(GAME_CFG_PATH"%s", szConfig);
if (cfgFile.Open(cfgFileName.String(), CIOStream::Mode_e::Read)) if (cfgFile.Open(cfgFileName.String(), CIOStream::READ))
{ {
if (!cfgFile.ReadString(commandLine.Access(), commandLine.GetMaxLength())) if (!cfgFile.ReadString(commandLine.Access(), commandLine.GetMaxLength()))
{ {

Some files were not shown because too many files have changed in this diff Show More