mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
new new modsystem pr (#96)
* modsystem v2 initial commit * call CModSystem::Init * clean up custom cvar value handling * add mod script compiling support * add error check to script rson loading yes this error is a duplicate but this one exits the game * fix typo * fix compile error
This commit is contained in:
parent
e8f6bf0eda
commit
bcc51460bc
@ -19,6 +19,7 @@
|
||||
#include "tier1/cvar.h"
|
||||
#include "vpc/IAppSystem.h"
|
||||
#include "vpc/keyvalues.h"
|
||||
#include "vpc/rson.h"
|
||||
#include "vpc/interfaces.h"
|
||||
#include "vstdlib/callback.h"
|
||||
#include "vstdlib/completion.h"
|
||||
@ -72,6 +73,7 @@
|
||||
#ifndef DEDICATED
|
||||
#include "engine/client/clientstate.h"
|
||||
#endif // !DEDICATED
|
||||
#include "localize/localize.h"
|
||||
#include "engine/enginetrace.h"
|
||||
#include "engine/traceinit.h"
|
||||
#include "engine/common.h"
|
||||
@ -388,6 +390,7 @@ void DetourRegister() // Register detour classes to be searched and hooked.
|
||||
// VPC
|
||||
REGISTER(VAppSystem);
|
||||
REGISTER(VKeyValues);
|
||||
REGISTER(VRSON);
|
||||
REGISTER(VFactory);
|
||||
|
||||
// VstdLib
|
||||
@ -503,6 +506,8 @@ void DetourRegister() // Register detour classes to be searched and hooked.
|
||||
REGISTER(VEngineTrace);
|
||||
REGISTER(VModelInfo);
|
||||
|
||||
REGISTER(VLocalize);
|
||||
|
||||
#ifndef DEDICATED
|
||||
REGISTER(HVideoMode_Common);
|
||||
REGISTER(VGL_RMain);
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "appframework/engine_launcher_api.h"
|
||||
#include "launcher/IApplication.h"
|
||||
#include "pluginsystem/pluginsystem.h"
|
||||
#include "pluginsystem/modsystem.h"
|
||||
#include "ebisusdk/EbisuSDK.h"
|
||||
#include "engine/cmodel_bsp.h"
|
||||
#include "engine/sys_engine.h"
|
||||
@ -106,6 +107,8 @@ bool CModAppSystemGroup::StaticCreate(CModAppSystemGroup* pModAppSystemGroup)
|
||||
//InitPluginSystem(pModAppSystemGroup);
|
||||
//CALL_PLUGIN_CALLBACKS(g_pPluginSystem->GetCreateCallbacks(), pModAppSystemGroup);
|
||||
|
||||
g_pModSystem->Init();
|
||||
|
||||
g_pDebugOverlay = g_pFactory->GetFactoryPtr(VDEBUG_OVERLAY_INTERFACE_VERSION, false).RCast<CIVDebugOverlay*>();
|
||||
#ifndef CLIENT_DLL
|
||||
g_pServerGameDLL = g_pFactory->GetFactoryPtr(INTERFACEVERSION_SERVERGAMEDLL, false).RCast<CServerGameDLL*>();
|
||||
|
33
r5dev/localize/localize.cpp
Normal file
33
r5dev/localize/localize.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "localize/localize.h"
|
||||
#include "pluginsystem/modsystem.h"
|
||||
|
||||
bool Localize_LoadLocalizationFileLists(CLocalize* thisptr)
|
||||
{
|
||||
v_CLocalize__LoadLocalizationFileLists(thisptr);
|
||||
|
||||
for (auto& mod : g_pModSystem->GetModList())
|
||||
{
|
||||
if (mod.m_iState == CModSystem::eModState::ENABLED)
|
||||
{
|
||||
for (auto& it : mod.m_vszLocalizationFiles)
|
||||
{
|
||||
v_CLocalize__AddFile(thisptr, it.c_str(), NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DevMsg(eDLL_T::ENGINE, "Loaded localization files.\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VLocalize::Attach() const
|
||||
{
|
||||
DetourAttach((LPVOID*)&v_CLocalize__LoadLocalizationFileLists, &Localize_LoadLocalizationFileLists);
|
||||
}
|
||||
|
||||
void VLocalize::Detach() const
|
||||
{
|
||||
DetourDetach((LPVOID*)&v_CLocalize__LoadLocalizationFileLists, &Localize_LoadLocalizationFileLists);
|
||||
}
|
45
r5dev/localize/localize.h
Normal file
45
r5dev/localize/localize.h
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include "tier0/threadtools.h"
|
||||
#include "tier1/utldict.h"
|
||||
|
||||
|
||||
class CLocalize
|
||||
{
|
||||
// todo
|
||||
};
|
||||
|
||||
inline CMemory p_CLocalize__AddFile;
|
||||
inline auto v_CLocalize__AddFile = p_CLocalize__AddFile.RCast<bool(__fastcall*)(CLocalize * thisptr, const char* szFileName, const char* pPathID)>();
|
||||
|
||||
inline CMemory p_CLocalize__LoadLocalizationFileLists;
|
||||
inline auto v_CLocalize__LoadLocalizationFileLists = p_CLocalize__LoadLocalizationFileLists.RCast<bool(__fastcall*)(CLocalize * thisptr)>();
|
||||
|
||||
|
||||
inline CLocalize* g_pVGuiLocalize;
|
||||
inline CLocalize* g_pLocalize;
|
||||
|
||||
void Localize_Attach();
|
||||
void Localize_Detach();
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VLocalize : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const { }
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_CLocalize__AddFile = g_GameDll.FindPatternSIMD("E8 ? ? ? ? 49 FF C4").FollowNearCallSelf();
|
||||
v_CLocalize__AddFile = p_CLocalize__AddFile.RCast<bool(__fastcall*)(CLocalize * thisptr, const char* szFileName, const char* pPathID)>();
|
||||
|
||||
p_CLocalize__LoadLocalizationFileLists = g_GameDll.FindPatternSIMD("4C 8B DC 53 48 81 EC ? ? ? ? 33 C0");
|
||||
v_CLocalize__LoadLocalizationFileLists = p_CLocalize__LoadLocalizationFileLists.RCast<bool(__fastcall*)(CLocalize * thisptr)>();
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
g_pVGuiLocalize = g_GameDll.FindPatternSIMD("48 8B 0D ? ? ? ? 48 8B 01 FF 50 40 40 38 2D ? ? ? ?").ResolveRelativeAddressSelf(0x3, 0x7).RCast<CLocalize*>();
|
||||
g_pLocalize = g_pVGuiLocalize; // these are set to the same thing in CSourceAppSystemGroup::Create
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
224
r5dev/pluginsystem/modsystem.cpp
Normal file
224
r5dev/pluginsystem/modsystem.cpp
Normal file
@ -0,0 +1,224 @@
|
||||
//=============================================================================//
|
||||
//
|
||||
// Purpose: Manage loading mods
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "core/stdafx.h"
|
||||
#include "modsystem.h"
|
||||
#include "localize/localize.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "vpc/rson.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: initialize the mod system
|
||||
// Input :
|
||||
//-----------------------------------------------------------------------------
|
||||
void CModSystem::Init()
|
||||
{
|
||||
LoadModStatusList();
|
||||
|
||||
CreateDirectories("platform\\mods");
|
||||
|
||||
for (auto& it : fs::directory_iterator("platform\\mods"))
|
||||
{
|
||||
if (!it.is_directory())
|
||||
continue;
|
||||
|
||||
fs::path basePath = it.path();
|
||||
DevMsg(eDLL_T::ENGINE, "Found mod at '%s'.\n", basePath.string().c_str());
|
||||
fs::path settingsPath = basePath / "mod.vdf";
|
||||
|
||||
if (fs::exists(settingsPath))
|
||||
{
|
||||
CModSystem::ModInstance_t modInst = CModSystem::ModInstance_t(basePath);
|
||||
if (modInst.m_iState != eModState::UNLOADED)
|
||||
m_vModList.push_back(modInst);
|
||||
}
|
||||
}
|
||||
|
||||
WriteModStatusList();
|
||||
}
|
||||
|
||||
void CModSystem::LoadModStatusList()
|
||||
{
|
||||
if (FileSystem()->FileExists("platform/mods.vdf"))
|
||||
{
|
||||
KeyValues* pModList = FileSystem()->LoadKeyValues(IFileSystem::TYPE_COMMON, "platform/mods.vdf", "GAME");
|
||||
|
||||
for (KeyValues* pSubKey = pModList->GetFirstSubKey(); pSubKey != nullptr; pSubKey = pSubKey->GetNextKey())
|
||||
{
|
||||
size_t idHash = std::hash<std::string>{}(std::string(pSubKey->GetName()));
|
||||
m_vEnabledList.emplace(idHash, pSubKey->GetBool());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CModSystem::WriteModStatusList()
|
||||
{
|
||||
KeyValues kv = KeyValues("ModList");
|
||||
KeyValues* pModListKV = kv.FindKey("ModList", true);
|
||||
|
||||
for (auto& it : m_vModList)
|
||||
{
|
||||
bool enabled = false;
|
||||
if (it.m_iState == eModState::ENABLED)
|
||||
enabled = true;
|
||||
|
||||
pModListKV->SetBool(it.m_szModID.c_str(), enabled);
|
||||
}
|
||||
|
||||
CUtlBuffer uBuf = CUtlBuffer(0i64, 0, CUtlBuffer::TEXT_BUFFER);
|
||||
|
||||
kv.RecursiveSaveToFile(uBuf, 0);
|
||||
|
||||
FileSystem()->WriteFile("platform/mods.vdf", NULL, uBuf); // NULL instead of "GAME" because otherwise for some reason the file clears itself when the process exits
|
||||
}
|
||||
|
||||
|
||||
CModSystem::ModInstance_t::ModInstance_t(const fs::path& basePath) : m_szName(std::string()), m_szModID(std::string()), m_BasePath(basePath), m_szDescription(std::string()), m_szVersion(std::string()), m_SettingsKV(nullptr), m_iState(eModState::LOADING)
|
||||
{
|
||||
std::string settingsPath = (m_BasePath / "mod.vdf").string();
|
||||
|
||||
KeyValues* pSettingsKV = FileSystem()->LoadKeyValues(IFileSystem::TYPE_COMMON, settingsPath.c_str(), "GAME");
|
||||
m_SettingsKV = pSettingsKV;
|
||||
|
||||
if (!m_SettingsKV)
|
||||
{
|
||||
SetState(eModState::UNLOADED);
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Failed to parse mod.vdf for mod at path '%s'\n", m_BasePath.string().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
// "name" "An R5Reloaded Mod"
|
||||
// [rexx]: could be optional and have id as fallback
|
||||
KeyValues* pName = pSettingsKV->FindKey("name");
|
||||
|
||||
if (!pName)
|
||||
{
|
||||
SetState(eModState::UNLOADED);
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Mod settings file '%s' was missing required 'name' field. Skipping mod...\n", settingsPath.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
m_szName = pName->GetString();
|
||||
|
||||
/////////////////////////////
|
||||
// "version" "1.0.0"
|
||||
KeyValues* pVersion = pSettingsKV->FindKey("version");
|
||||
|
||||
if (!pVersion)
|
||||
{
|
||||
SetState(eModState::UNLOADED);
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Mod settings file '%s' was missing required 'version' field. Skipping mod...\n", settingsPath.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
m_szVersion = pVersion->GetString();
|
||||
|
||||
/////////////////////////////
|
||||
// "id" "r5reloaded.TestMod"
|
||||
KeyValues* pId = pSettingsKV->FindKey("id");
|
||||
|
||||
if (!pId)
|
||||
{
|
||||
SetState(eModState::UNLOADED);
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Mod settings file '%s' was missing required 'id' field. Skipping mod...\n", settingsPath.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
m_szModID = pId->GetString();
|
||||
|
||||
/////////////////////////////
|
||||
// optional mod description field
|
||||
m_szDescription = pSettingsKV->GetString("description");
|
||||
|
||||
size_t idHash = std::hash<std::string>{}(m_szModID);
|
||||
|
||||
auto& enabledList = g_pModSystem->GetEnabledList();
|
||||
if (enabledList.count(idHash) == 0)
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "Mod does not exist in 'mods.vdf'. Enabling...\n");
|
||||
SetState(eModState::ENABLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool bEnable = enabledList[idHash];
|
||||
SetState(bEnable ? eModState::ENABLED : eModState::DISABLED);
|
||||
|
||||
DevMsg(eDLL_T::ENGINE, "Mod exists in 'mods.vdf' and is %s.\n", bEnable ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
if (m_iState != eModState::ENABLED)
|
||||
return;
|
||||
|
||||
// parse any additional info from mod.vdf
|
||||
|
||||
// add mod folder to search paths so files can be easily loaded from here
|
||||
// [rexx]: maybe this isn't ideal as the only way of finding the mod's files, as there may be name clashes in files where the engine
|
||||
// won't really care about the input file name. it may be better to, where possible, request files by file path relative to root (i.e. including platform/mods/{mod}/)
|
||||
FileSystem()->AddSearchPath(m_BasePath.string().c_str(), "GAME", SearchPathAdd_t::PATH_ADD_TO_TAIL);
|
||||
|
||||
KeyValues* pLocalizationFiles = pSettingsKV->FindKey("LocalizationFiles");
|
||||
|
||||
if (pLocalizationFiles)
|
||||
{
|
||||
for (KeyValues* pSubKey = pLocalizationFiles->GetFirstSubKey(); pSubKey != nullptr; pSubKey = pSubKey->GetNextKey())
|
||||
{
|
||||
this->m_vszLocalizationFiles.push_back(pSubKey->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
KeyValues* pConVars = pSettingsKV->FindKey("ConVars");
|
||||
|
||||
if (pConVars)
|
||||
{
|
||||
for (KeyValues* pSubKey = pConVars->GetFirstSubKey(); pSubKey != nullptr; pSubKey = pSubKey->GetNextKey())
|
||||
{
|
||||
const char* pszName = pSubKey->GetName();
|
||||
const char* pszHelpString = pSubKey->GetString("helpString");
|
||||
const char* pszFlagsString = pSubKey->GetString("flags", "NONE");
|
||||
|
||||
KeyValues* pValues = pSubKey->FindKey("Values");
|
||||
|
||||
const char* pszDefaultValue = "0";
|
||||
bool bMin = false;
|
||||
bool bMax = false;
|
||||
float fMin = 0.f;
|
||||
float fMax = 0.f;
|
||||
|
||||
if (pValues)
|
||||
{
|
||||
pszDefaultValue = pValues->GetString("default", "0");
|
||||
|
||||
// minimum cvar value
|
||||
if (pValues->FindKey("min"))
|
||||
{
|
||||
bMin = true; // has min value
|
||||
fMin = pValues->GetFloat("min", 0.f);
|
||||
}
|
||||
|
||||
// maximum cvar value
|
||||
if (pValues->FindKey("max"))
|
||||
{
|
||||
bMax = true; // has max value
|
||||
fMax = pValues->GetFloat("max", 1.f);
|
||||
}
|
||||
}
|
||||
|
||||
int flags = FCVAR_NONE;
|
||||
if (ConVar::ParseFlagString(pszFlagsString, flags, pszName))
|
||||
ConVar::StaticCreate(pszName, pszDefaultValue, flags, pszHelpString, bMin, fMin, bMax, fMax, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
std::string scriptsRsonPath = (m_BasePath / "scripts/vscripts/scripts.rson").string();
|
||||
|
||||
if (FileSystem()->FileExists(scriptsRsonPath.c_str(), "GAME"))
|
||||
m_bHasScriptCompileList = true;
|
||||
};
|
||||
|
||||
CModSystem* g_pModSystem = new CModSystem();
|
66
r5dev/pluginsystem/modsystem.h
Normal file
66
r5dev/pluginsystem/modsystem.h
Normal file
@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include "vpc/keyvalues.h"
|
||||
#include "vpc/rson.h"
|
||||
#include <filesystem/filesystem.h>
|
||||
|
||||
class CModAppSystemGroup;
|
||||
|
||||
|
||||
class CModSystem
|
||||
{
|
||||
public:
|
||||
enum eModState : int8_t
|
||||
{
|
||||
UNLOADED = -1, // loading was unsuccessful (error occurred)
|
||||
LOADING = 0, // if mod is being loaded
|
||||
DISABLED = 1, // if disabled by user
|
||||
ENABLED = 2, // if enabled by user and loaded properly
|
||||
};
|
||||
|
||||
struct ModInstance_t
|
||||
{
|
||||
ModInstance_t(const fs::path& basePath);
|
||||
|
||||
inline void SetState(eModState state) { m_iState = state; };
|
||||
|
||||
inline bool IsEnabled() { return m_iState == eModState::ENABLED; };
|
||||
|
||||
inline const fs::path& GetBasePath() { return m_BasePath; };
|
||||
|
||||
inline fs::path GetScriptCompileListPath() { return (m_BasePath / "scripts/vscripts/scripts.rson"); };
|
||||
|
||||
RSON::Node_t* LoadScriptCompileList()
|
||||
{
|
||||
return RSON::LoadFromFile(GetScriptCompileListPath().string().c_str());
|
||||
};
|
||||
|
||||
bool m_bHasScriptCompileList; // if this mod has a scripts.rson file that exists
|
||||
|
||||
string m_szName; // mod display name
|
||||
string m_szModID; // internal mod identifier
|
||||
fs::path m_BasePath; // path to folder containg all mod files
|
||||
string m_szDescription; // mod description
|
||||
string m_szVersion; // version string
|
||||
|
||||
KeyValues* m_SettingsKV;
|
||||
|
||||
eModState m_iState = eModState::UNLOADED;
|
||||
|
||||
std::vector<string> m_vszLocalizationFiles;
|
||||
};
|
||||
|
||||
void Init();
|
||||
|
||||
// load mod enabled/disabled status from file on disk
|
||||
void LoadModStatusList();
|
||||
void WriteModStatusList();
|
||||
|
||||
inline vector<ModInstance_t>& GetModList() { return m_vModList; };
|
||||
inline std::map<size_t, bool>& GetEnabledList() { return m_vEnabledList; };
|
||||
|
||||
private:
|
||||
vector<ModInstance_t> m_vModList;
|
||||
std::map<size_t, bool> m_vEnabledList;
|
||||
};
|
||||
extern CModSystem* g_pModSystem;
|
@ -413,6 +413,8 @@ public:
|
||||
void InstallChangeCallback(FnChangeCallback_t callback, bool bInvoke);
|
||||
void RemoveChangeCallback(FnChangeCallback_t callback);
|
||||
|
||||
static bool ParseFlagString(const char* pszFlags, int& nFlags, const char* pszConVarName = nullptr);
|
||||
|
||||
struct CVValue_t
|
||||
{
|
||||
char* m_pszString;
|
||||
@ -432,6 +434,38 @@ public:
|
||||
}; //Size: 0x00A0
|
||||
static_assert(sizeof(ConVar) == 0xA0);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// see iconvar.h
|
||||
static std::map<string, int> s_ConVarFlags = {
|
||||
{"NONE", FCVAR_NONE},
|
||||
{"DEVELOPMENTONLY", FCVAR_DEVELOPMENTONLY},
|
||||
{"GAMEDLL", FCVAR_GAMEDLL},
|
||||
{"CLIENTDLL", FCVAR_CLIENTDLL},
|
||||
{"HIDDEN", FCVAR_HIDDEN},
|
||||
{"PROTECTED", FCVAR_PROTECTED},
|
||||
{"SPONLY", FCVAR_SPONLY},
|
||||
{"ARCHIVE", FCVAR_ARCHIVE},
|
||||
{"NOTIFY", FCVAR_NOTIFY},
|
||||
{"USERINFO", FCVAR_USERINFO},
|
||||
{"PRINTABLEONLY", FCVAR_PRINTABLEONLY},
|
||||
{"GAMEDLL_FOR_REMOTE_CLIENTS", FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS},
|
||||
{"UNLOGGED", FCVAR_UNLOGGED},
|
||||
{"NEVER_AS_STRING", FCVAR_NEVER_AS_STRING},
|
||||
{"REPLICATED", FCVAR_REPLICATED},
|
||||
{"CHEAT", FCVAR_CHEAT},
|
||||
{"SS", FCVAR_SS},
|
||||
{"DEMO", FCVAR_DEMO},
|
||||
{"DONTRECORD", FCVAR_DONTRECORD},
|
||||
{"SS_ADDED", FCVAR_SS_ADDED},
|
||||
{"RELEASE", FCVAR_RELEASE},
|
||||
{"RELOAD_MATERIALS", FCVAR_RELOAD_MATERIALS},
|
||||
{"RELOAD_TEXTURES", FCVAR_RELOAD_TEXTURES},
|
||||
{"NOT_CONNECTED", FCVAR_NOT_CONNECTED},
|
||||
{"MATERIAL_SYSTEM_THREAD", FCVAR_MATERIAL_SYSTEM_THREAD},
|
||||
{"ARCHIVE_PLAYERPROFILE", FCVAR_ARCHIVE_PLAYERPROFILE},
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void ConVar_PrintDescription(ConCommandBase* pVar);
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "squirrel/sqapi.h"
|
||||
#include "squirrel/sqinit.h"
|
||||
#include "squirrel/sqscript.h"
|
||||
#include "pluginsystem/modsystem.h"
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: registers global constant for target context
|
||||
@ -227,9 +228,26 @@ SQInteger Script_LoadRson(const SQChar* rsonfile)
|
||||
//---------------------------------------------------------------------------------
|
||||
SQBool Script_LoadScript(HSQUIRRELVM v, const SQChar* path, const SQChar* name, SQInteger flags)
|
||||
{
|
||||
// search for mod path identifier so the mod can decide where the file is
|
||||
const char* modPath = strstr(path, MOD_SCRIPT_PATH_IDENTIFIER);
|
||||
|
||||
if (modPath)
|
||||
path = &modPath[7]; // skip "::MOD::"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
return v_Script_LoadScript(v, path, name, flags);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: parses rson data to get an array of scripts to compile
|
||||
// Input :
|
||||
//---------------------------------------------------------------------------------
|
||||
bool Script_ParseCompileListRSON(SQCONTEXT context, const char* compileListPath, RSON::Node_t* rson, char** scriptArray, int* pScriptCount, char** precompiledScriptArray, int precompiledScriptCount)
|
||||
{
|
||||
return v_Script_ParseCompileListRSON(context, compileListPath, rson, scriptArray, pScriptCount, precompiledScriptArray, precompiledScriptCount);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: Compiles and executes input code on target VM by context
|
||||
// Input : *code -
|
||||
@ -277,6 +295,128 @@ void Script_Execute(const SQChar* code, const SQCONTEXT context)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Script_SetCompilingVM(CSquirrelVM* vm, RSON::Node_t* rson)
|
||||
{
|
||||
switch (vm->GetContext())
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
case SQCONTEXT::SERVER:
|
||||
{
|
||||
v_Script_SetCompilingVM_SV(vm->GetContext(), rson);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifndef DEDICATED
|
||||
case SQCONTEXT::CLIENT:
|
||||
case SQCONTEXT::UI:
|
||||
{
|
||||
v_Script_SetCompilingVM_UICL(vm->GetContext(), rson);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void CSquirrelVM_CompileModScripts(CSquirrelVM* vm)
|
||||
{
|
||||
for (auto& mod : g_pModSystem->GetModList())
|
||||
{
|
||||
if (!mod.IsEnabled())
|
||||
continue;
|
||||
|
||||
if (!mod.m_bHasScriptCompileList)
|
||||
continue;
|
||||
|
||||
RSON::Node_t* rson = mod.LoadScriptCompileList(); // allocs parsed rson buffer
|
||||
|
||||
if (!rson)
|
||||
Error(vm->GetVM()->GetNativePrintContext(), EXIT_FAILURE, "%s: Failed to load RSON file %s\n", __FUNCTION__, mod.GetScriptCompileListPath().string().c_str());
|
||||
|
||||
const char* scriptPathArray[1024];
|
||||
int scriptCount = 0;
|
||||
|
||||
Script_SetCompilingVM(vm, rson);
|
||||
|
||||
if (Script_ParseCompileListRSON(
|
||||
vm->GetContext(),
|
||||
mod.GetScriptCompileListPath().string().c_str(),
|
||||
rson,
|
||||
(char**)scriptPathArray, &scriptCount,
|
||||
nullptr, 0))
|
||||
{
|
||||
std::vector<char*> newScriptPaths;
|
||||
for (int i = 0; i < scriptCount; ++i)
|
||||
{
|
||||
// add "::MOD::" to the start of the script path so it can be identified from Script_LoadScript later
|
||||
// this is so we can avoid script naming conflicts by removing the engine's forced directory of "scripts/vscripts/"
|
||||
// and adding the mod path to the start
|
||||
std::string scriptPath = MOD_SCRIPT_PATH_IDENTIFIER + (mod.GetBasePath() / "scripts/vscripts/" / scriptPathArray[i]).string();
|
||||
char* pszScriptPath = _strdup(scriptPath.c_str());
|
||||
|
||||
// normalise slash direction
|
||||
V_FixSlashes(pszScriptPath);
|
||||
|
||||
newScriptPaths.emplace_back(pszScriptPath);
|
||||
scriptPathArray[i] = pszScriptPath;
|
||||
}
|
||||
|
||||
switch (vm->GetVM()->GetContext())
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
case SQCONTEXT::SERVER:
|
||||
{
|
||||
v_CSquirrelVM_CompileScriptsFromArray_SV(vm, vm->GetContext(), (char**)scriptPathArray, scriptCount);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifndef DEDICATED
|
||||
case SQCONTEXT::CLIENT:
|
||||
case SQCONTEXT::UI:
|
||||
{
|
||||
v_CSquirrelVM_CompileScriptsFromArray_UICL(vm, vm->GetContext(), (char**)scriptPathArray, scriptCount);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// clean up our allocated script paths
|
||||
for (char* path : newScriptPaths)
|
||||
{
|
||||
delete path;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO[rexx]: clean up allocated RSON memory. example @ 1408B18E2
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef DEDICATED
|
||||
__int64 CSquirrelVM_CompileUICLScripts(CSquirrelVM* vm)
|
||||
{
|
||||
HSQUIRRELVM v = vm->GetVM();
|
||||
DevMsg(v->GetNativePrintContext(), (char*)"Loading and compiling script lists\n");
|
||||
|
||||
CSquirrelVM_CompileModScripts(vm);
|
||||
|
||||
return v_CSquirrelVM_CompileUICLScripts(vm);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
__int64 CSquirrelVM_CompileSVScripts(__int64 a1)
|
||||
{
|
||||
HSQUIRRELVM v = g_pServerScript->GetVM();
|
||||
|
||||
DevMsg(v->GetNativePrintContext(), (char*)"Loading and compiling script lists\n");
|
||||
|
||||
CSquirrelVM_CompileModScripts(g_pServerScript);
|
||||
|
||||
return v_CSquirrelVM_CompileSVScripts(a1);
|
||||
}
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void VSquirrelVM::Attach() const
|
||||
{
|
||||
@ -290,6 +430,7 @@ void VSquirrelVM::Attach() const
|
||||
void VSquirrelVM::Detach() const
|
||||
{
|
||||
DetourDetach((LPVOID*)&v_Script_RegisterConstant, &Script_RegisterConstant);
|
||||
|
||||
DetourDetach((LPVOID*)&v_CSquirrelVM_Init, &CSquirrelVM_Init);
|
||||
DetourDetach((LPVOID*)&v_Script_DestroySignalEntryListHead, &Script_DestroySignalEntryListHead);
|
||||
DetourDetach((LPVOID*)&v_Script_LoadRson, &Script_LoadRson);
|
||||
|
@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
#include "squirrel/sqtype.h"
|
||||
#include "squirrel/sqvm.h"
|
||||
#include "vpc/rson.h"
|
||||
|
||||
#define MOD_SCRIPT_PATH_IDENTIFIER "::MOD::"
|
||||
|
||||
struct ScriptFunctionBinding_t
|
||||
{
|
||||
@ -51,6 +54,11 @@ public:
|
||||
return m_sqVM;
|
||||
}
|
||||
|
||||
SQCONTEXT GetContext() const
|
||||
{
|
||||
return m_iContext;
|
||||
}
|
||||
|
||||
private:
|
||||
SQChar pad0[0x8];
|
||||
HSQUIRRELVM m_sqVM;
|
||||
@ -62,8 +70,7 @@ private:
|
||||
SQChar pad4[4];
|
||||
#endif
|
||||
SQInteger m_nTick;
|
||||
SQChar pad5[4];
|
||||
SQCONTEXT m_iContext;
|
||||
SQCONTEXT m_iContext; // 0x38
|
||||
#if !defined (GAMEDLL_S2) && !defined (GAMEDLL_S3)
|
||||
SQChar pad6[4];
|
||||
#endif
|
||||
@ -89,6 +96,32 @@ inline auto v_Script_LoadRson = p_Script_LoadRson.RCast<SQInteger(*)(const SQCha
|
||||
inline CMemory p_Script_LoadScript;
|
||||
inline auto v_Script_LoadScript = p_Script_LoadScript.RCast<SQBool(*)(HSQUIRRELVM v, const SQChar* path, const SQChar* name, SQInteger flags)>();
|
||||
|
||||
#ifndef DEDICATED
|
||||
inline CMemory p_CSquirrelVM_CompileUICLScripts;
|
||||
inline auto v_CSquirrelVM_CompileUICLScripts = p_CSquirrelVM_CompileUICLScripts.RCast<__int64(__fastcall*)(CSquirrelVM* vm)>();
|
||||
|
||||
inline CMemory p_CSquirrelVM_CompileScriptsFromArray_UICL;
|
||||
inline auto v_CSquirrelVM_CompileScriptsFromArray_UICL = p_CSquirrelVM_CompileScriptsFromArray_UICL.RCast<bool(__fastcall*)(CSquirrelVM* vm, SQCONTEXT context, char** scriptArray, int scriptCount)>();
|
||||
|
||||
inline CMemory p_Script_SetCompilingVM_UICL;
|
||||
inline auto v_Script_SetCompilingVM_UICL = p_Script_SetCompilingVM_UICL.RCast<void(__fastcall*)(SQCONTEXT ctx, RSON::Node_t * rson)>();
|
||||
#endif
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
inline CMemory p_CSquirrelVM_CompileSVScripts;
|
||||
inline auto v_CSquirrelVM_CompileSVScripts = p_CSquirrelVM_CompileSVScripts.RCast<__int64(__fastcall*)(__int64 a1)>();
|
||||
|
||||
inline CMemory p_CSquirrelVM_CompileScriptsFromArray_SV;
|
||||
inline auto v_CSquirrelVM_CompileScriptsFromArray_SV = p_CSquirrelVM_CompileScriptsFromArray_SV.RCast<bool(__fastcall*)(CSquirrelVM* vm, SQCONTEXT context, char** scriptArray, int scriptCount)>();
|
||||
|
||||
inline CMemory p_Script_SetCompilingVM_SV;
|
||||
inline auto v_Script_SetCompilingVM_SV = p_Script_SetCompilingVM_SV.RCast<void(__fastcall*)(SQCONTEXT ctx, RSON::Node_t * rson)>();
|
||||
#endif
|
||||
|
||||
inline CMemory p_Script_ParseCompileListRSON;
|
||||
inline auto v_Script_ParseCompileListRSON = p_Script_ParseCompileListRSON.RCast<bool(__fastcall*)(SQCONTEXT ctx, const char* compileListPath, RSON::Node_t* rson, char** scriptArray, int* pScriptCount, char** precompiledScriptArray, int precompiledScriptCount)>();
|
||||
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
inline CSquirrelVM* g_pServerScript;
|
||||
#endif // !CLIENT_DLL
|
||||
@ -110,6 +143,8 @@ CSquirrelVM* Script_GetScriptHandle(const SQCONTEXT context);
|
||||
SQInteger Script_LoadRson(const SQChar* rsonfile);
|
||||
SQBool Script_LoadScript(HSQUIRRELVM v, const SQChar* path, const SQChar* name, SQInteger flags);
|
||||
|
||||
bool Script_ParseCompileListRSON(SQCONTEXT context, const char* compileListPath, RSON::Node_t* rson, char** scriptArray, int* pScriptCount, char** precompiledScriptArray, int precompiledScriptCount);
|
||||
|
||||
void Script_Execute(const SQChar* code, const SQCONTEXT context);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -144,6 +179,35 @@ class VSquirrelVM : public IDetour
|
||||
v_Script_DestroySignalEntryListHead = p_Script_DestroySignalEntryListHead.RCast<SQBool(*)(CSquirrelVM*, HSQUIRRELVM, SQFloat)>();/*48 89 5C 24 ?? 48 89 6C 24 ?? 56 57 41 56 48 83 EC 50 44 8B 42*/
|
||||
v_Script_LoadRson = p_Script_LoadRson.RCast<SQInteger(*)(const SQChar*)>(); /*4C 8B DC 49 89 5B 08 57 48 81 EC A0 00 00 00 33*/
|
||||
v_Script_LoadScript = p_Script_LoadScript.RCast<SQBool(*)(HSQUIRRELVM, const SQChar*, const SQChar*, SQInteger)>(); /*48 8B C4 48 89 48 08 55 41 56 48 8D 68*/
|
||||
|
||||
#ifndef DEDICATED
|
||||
// cl/ui scripts.rson compiling
|
||||
p_CSquirrelVM_CompileUICLScripts = g_GameDll.FindPatternSIMD("E8 ? ? ? ? 88 05 ? ? ? ? 33 C0").FollowNearCallSelf();
|
||||
v_CSquirrelVM_CompileUICLScripts = p_CSquirrelVM_CompileUICLScripts.RCast<__int64(__fastcall*)(CSquirrelVM * vm)>();
|
||||
|
||||
p_CSquirrelVM_CompileScriptsFromArray_UICL = g_GameDll.FindPatternSIMD("E8 ? ? ? ? 44 0F B6 F0 48 85 DB").FollowNearCallSelf();
|
||||
v_CSquirrelVM_CompileScriptsFromArray_UICL = p_CSquirrelVM_CompileScriptsFromArray_UICL.RCast<bool(__fastcall*)(CSquirrelVM* vm, SQCONTEXT context, char** scriptArray, int scriptCount)>();
|
||||
|
||||
p_Script_SetCompilingVM_UICL = g_GameDll.FindString("Expected bool value for \"IsTestMap\" in \"%s\"\n").FindPatternSelf("48 89", CMemory::Direction::UP, 100);
|
||||
v_Script_SetCompilingVM_UICL = p_Script_SetCompilingVM_UICL.RCast<void(__fastcall*)(SQCONTEXT ctx, RSON::Node_t* rson)>();
|
||||
#endif
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
// sv scripts.rson compiling
|
||||
p_CSquirrelVM_CompileSVScripts = g_GameDll.FindPatternSIMD("E8 ? ? ? ? 33 DB 88 05 ? ? ? ? ").FollowNearCallSelf();
|
||||
v_CSquirrelVM_CompileSVScripts = p_CSquirrelVM_CompileSVScripts.RCast<__int64(__fastcall*)(__int64 a1)>();
|
||||
|
||||
p_CSquirrelVM_CompileScriptsFromArray_SV = g_GameDll.FindPatternSIMD("E8 ? ? ? ? 0F B6 F0 48 85 DB").FollowNearCallSelf();
|
||||
v_CSquirrelVM_CompileScriptsFromArray_SV = p_CSquirrelVM_CompileScriptsFromArray_SV.RCast<bool(__fastcall*)(CSquirrelVM* vm, SQCONTEXT context, char** scriptArray, int scriptCount)>();
|
||||
|
||||
p_Script_SetCompilingVM_SV = g_GameDll.FindString("Expected bool value for \"IsTestMap\" in \"%s\"\n", 2).FindPatternSelf("48 89", CMemory::Direction::UP, 100);
|
||||
v_Script_SetCompilingVM_SV = p_Script_SetCompilingVM_SV.RCast<void(__fastcall*)(SQCONTEXT ctx, RSON::Node_t * rson)>();
|
||||
#endif
|
||||
|
||||
p_Script_ParseCompileListRSON = g_GameDll.FindPatternSIMD("4C 89 4C 24 ? 55 41 56");
|
||||
v_Script_ParseCompileListRSON = p_Script_ParseCompileListRSON.RCast<bool(__fastcall*)(SQCONTEXT, const char*, RSON::Node_t*, char**, int*, char**, int)>();
|
||||
|
||||
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
|
@ -27,6 +27,11 @@ struct SQVM
|
||||
#endif // !GAMEDLL_S0 && !GAMEDLL_S1 && !GAMEDLL_S2
|
||||
}
|
||||
|
||||
eDLL_T GetNativePrintContext() const
|
||||
{
|
||||
return (eDLL_T)GetContext();
|
||||
}
|
||||
|
||||
SQVM* _vftable;
|
||||
_BYTE gap000[16];
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
|
||||
|
@ -1019,6 +1019,49 @@ void ConVar::RemoveChangeCallback(FnChangeCallback_t callback)
|
||||
m_pParent->m_fnChangeCallbacks.FindAndRemove(callback);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Parse input flag string into bitfield
|
||||
// Input : pszFlags -
|
||||
// nFlags -
|
||||
// pszConVarName -
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConVar::ParseFlagString(const char* pszFlags, int& nFlags, const char* pszConVarName)
|
||||
{
|
||||
int len = strlen(pszFlags);
|
||||
int flags = 0;
|
||||
|
||||
std::string sFlag = "";
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
char c = pszFlags[i];
|
||||
|
||||
if (std::isspace(c))
|
||||
continue;
|
||||
|
||||
if (c != '|')
|
||||
sFlag += c;
|
||||
|
||||
if (c == '|' || i == len - 1)
|
||||
{
|
||||
if (sFlag == "")
|
||||
continue;
|
||||
|
||||
if (s_ConVarFlags.count(sFlag) == 0)
|
||||
{
|
||||
Warning(eDLL_T::ENGINE, "%s: Attempted to parse invalid flag '%s' for convar '%s'\n", __FUNCTION__, sFlag.c_str(), pszConVarName);
|
||||
return false;
|
||||
}
|
||||
|
||||
flags |= s_ConVarFlags.at(sFlag);
|
||||
|
||||
sFlag = "";
|
||||
}
|
||||
}
|
||||
nFlags = flags;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
|
46
r5dev/vpc/rson.cpp
Normal file
46
r5dev/vpc/rson.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include "core/stdafx.h"
|
||||
#include <tier0/memstd.h>
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include <filesystem/filesystem.h>
|
||||
#include "vpc/rson.h"
|
||||
|
||||
RSON::Node_t* RSON::LoadFromBuffer(const char* pszBufferName, char* pBuffer, RSON::eFieldType rootType)
|
||||
{
|
||||
return RSON_LoadFromBuffer(pszBufferName, pBuffer, rootType, 0, NULL);
|
||||
}
|
||||
|
||||
RSON::Node_t* RSON::LoadFromFile(const char* pszFilePath)
|
||||
{
|
||||
if (FileSystem()->FileExists(pszFilePath, "GAME"))
|
||||
{
|
||||
FileHandle_t file = FileSystem()->Open(pszFilePath, "rt");
|
||||
|
||||
if (!file)
|
||||
return NULL;
|
||||
|
||||
uint32_t nFileSize = FileSystem()->Size(file);
|
||||
|
||||
char* fileBuf = MemAllocSingleton()->Alloc<char>(nFileSize + 1);
|
||||
|
||||
int nRead = FileSystem()->Read(fileBuf, nFileSize, file);
|
||||
FileSystem()->Close(file);
|
||||
|
||||
fileBuf[nRead] = '\0';
|
||||
|
||||
RSON::Node_t* node = RSON::LoadFromBuffer(pszFilePath, fileBuf, eFieldType::RSON_OBJECT);
|
||||
|
||||
MemAllocSingleton()->Free(fileBuf);
|
||||
|
||||
if (node)
|
||||
return node;
|
||||
else
|
||||
{
|
||||
// [rexx]: not sure if this should be fatal or not. ideally this should be handled appropriately
|
||||
// in the calling function
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Error loading file '%s'\n", pszFilePath);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
112
r5dev/vpc/rson.h
Normal file
112
r5dev/vpc/rson.h
Normal file
@ -0,0 +1,112 @@
|
||||
#pragma once
|
||||
#include "mathlib/color.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "public/ifilesystem.h"
|
||||
#include "filesystem/filesystem.h"
|
||||
|
||||
class RSON
|
||||
{
|
||||
public:
|
||||
enum eFieldType
|
||||
{
|
||||
RSON_NULL = 0x1,
|
||||
RSON_STRING = 0x2,
|
||||
RSON_VALUE = 0x4,
|
||||
RSON_OBJECT = 0x8,
|
||||
RSON_BOOLEAN = 0x10,
|
||||
RSON_INTEGER = 0x20,
|
||||
RSON_SIGNED_INTEGER = 0x40,
|
||||
RSON_UNSIGNED_INTEGER = 0x80,
|
||||
RSON_DOUBLE = 0x100,
|
||||
RSON_ARRAY = 0x1000,
|
||||
};
|
||||
|
||||
struct Field_t;
|
||||
|
||||
union Value_t
|
||||
{
|
||||
Field_t* pSubKey;
|
||||
char* pszString;
|
||||
__int64 integerValue;
|
||||
};
|
||||
|
||||
// used for the root node of rson tree
|
||||
struct Node_t
|
||||
{
|
||||
eFieldType m_Type;
|
||||
int m_nValueCount;
|
||||
Value_t m_Value;
|
||||
|
||||
Field_t* GetFirstSubKey()
|
||||
{
|
||||
if (m_Type & eFieldType::RSON_OBJECT)
|
||||
return m_Value.pSubKey;
|
||||
return NULL;
|
||||
};
|
||||
|
||||
// does not support finding a key in a different level of the tree
|
||||
Field_t* FindKey(const char* pszKeyName)
|
||||
{
|
||||
if ((m_Type & eFieldType::RSON_OBJECT) == 0)
|
||||
return NULL;
|
||||
|
||||
for (Field_t* pKey = GetFirstSubKey(); pKey != nullptr; pKey = pKey->GetNextKey())
|
||||
{
|
||||
if (!_stricmp(pKey->m_pszName, pszKeyName))
|
||||
return pKey;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
// used for every other field of the rson tree
|
||||
struct Field_t
|
||||
{
|
||||
char* m_pszName;
|
||||
Node_t m_Node;
|
||||
Field_t* m_pNext;
|
||||
Field_t* m_pPrev;
|
||||
|
||||
Field_t* GetNextKey() { return m_pNext; };
|
||||
Field_t* GetLastKey() { return m_pPrev; };
|
||||
|
||||
Field_t* GetFirstSubKey() { return m_Node.GetFirstSubKey(); };
|
||||
|
||||
Field_t* FindKey(const char* pszKeyName) { return m_Node.FindKey(pszKeyName); };
|
||||
|
||||
const char* GetString() { return (m_Node.m_Type == RSON_STRING) ? m_Node.m_Value.pszString : NULL; };
|
||||
};
|
||||
|
||||
public:
|
||||
static Node_t* LoadFromBuffer(const char* pszBufferName, char* pBuffer, eFieldType rootType);
|
||||
|
||||
static Node_t* LoadFromFile(const char* pszFilePath);
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline CMemory p_RSON_LoadFromBuffer;
|
||||
inline auto RSON_LoadFromBuffer = p_RSON_LoadFromBuffer.RCast<RSON::Node_t * (__fastcall*)(const char* bufName, char* buf, RSON::eFieldType rootType, __int64 a4, void* a5)>();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VRSON : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_RSON_LoadFromBuffer = g_GameDll.FindPatternSIMD("E8 ? ? ? ? 48 89 45 60 48 8B D8").FollowNearCallSelf();
|
||||
|
||||
RSON_LoadFromBuffer = p_RSON_LoadFromBuffer.RCast< RSON::Node_t * (__fastcall*)(const char* bufName, char* buf, RSON::eFieldType rootType, __int64 a4, void* a5)>();
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -79,6 +79,7 @@
|
||||
<ClCompile Include="..\launcher\IApplication.cpp" />
|
||||
<ClCompile Include="..\launcher\launcher.cpp" />
|
||||
<ClCompile Include="..\launcher\prx.cpp" />
|
||||
<ClCompile Include="..\localize\localize.cpp" />
|
||||
<ClCompile Include="..\materialsystem\cmaterialglue.cpp" />
|
||||
<ClCompile Include="..\materialsystem\cmaterialsystem.cpp" />
|
||||
<ClCompile Include="..\mathlib\adler32.cpp" />
|
||||
@ -99,6 +100,7 @@
|
||||
<ClCompile Include="..\mathlib\vmatrix.cpp" />
|
||||
<ClCompile Include="..\networksystem\listmanager.cpp" />
|
||||
<ClCompile Include="..\networksystem\pylon.cpp" />
|
||||
<ClCompile Include="..\pluginsystem\modsystem.cpp" />
|
||||
<ClCompile Include="..\pluginsystem\pluginsystem.cpp" />
|
||||
<ClCompile Include="..\protoc\cl_rcon.pb.cc">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
@ -168,6 +170,7 @@
|
||||
<ClCompile Include="..\vpc\IAppSystem.cpp" />
|
||||
<ClCompile Include="..\vpc\interfaces.cpp" />
|
||||
<ClCompile Include="..\vpc\keyvalues.cpp" />
|
||||
<ClCompile Include="..\vpc\rson.cpp" />
|
||||
<ClCompile Include="..\vphysics\physics_collide.cpp" />
|
||||
<ClCompile Include="..\vphysics\QHull.cpp" />
|
||||
<ClCompile Include="..\vpklib\packedstore.cpp" />
|
||||
@ -272,6 +275,7 @@
|
||||
<ClInclude Include="..\launcher\IApplication.h" />
|
||||
<ClInclude Include="..\launcher\launcher.h" />
|
||||
<ClInclude Include="..\launcher\prx.h" />
|
||||
<ClInclude Include="..\localize\localize.h" />
|
||||
<ClInclude Include="..\materialsystem\cmaterialglue.h" />
|
||||
<ClInclude Include="..\materialsystem\cmaterialsystem.h" />
|
||||
<ClInclude Include="..\mathlib\adler32.h" />
|
||||
@ -302,6 +306,7 @@
|
||||
<ClInclude Include="..\networksystem\pylon.h" />
|
||||
<ClInclude Include="..\networksystem\serverlisting.h" />
|
||||
<ClInclude Include="..\networksystem\sm_protocol.h" />
|
||||
<ClInclude Include="..\pluginsystem\modsystem.h" />
|
||||
<ClInclude Include="..\pluginsystem\pluginsystem.h" />
|
||||
<ClInclude Include="..\protoc\cl_rcon.pb.h" />
|
||||
<ClInclude Include="..\protoc\sig_map.pb.h" />
|
||||
@ -521,6 +526,7 @@
|
||||
<ClInclude Include="..\vpc\interfaces.h" />
|
||||
<ClInclude Include="..\vpc\keyvalues.h" />
|
||||
<ClInclude Include="..\vpc\kvleaktrace.h" />
|
||||
<ClInclude Include="..\vpc\rson.h" />
|
||||
<ClInclude Include="..\vphysics\QHull.h" />
|
||||
<ClInclude Include="..\vpklib\packedstore.h" />
|
||||
<ClInclude Include="..\vstdlib\autocompletefilelist.h" />
|
||||
|
@ -229,6 +229,9 @@
|
||||
<Filter Include="sdk\public\tier2">
|
||||
<UniqueIdentifier>{3a764173-162a-449c-952b-2db659cbad95}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="sdk\localize">
|
||||
<UniqueIdentifier>{ad59e38d-1dd1-4838-8040-6c5d9f4f660c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="sdk\engine\shared">
|
||||
<UniqueIdentifier>{bef90121-4004-47a7-b338-a41ca8078c12}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@ -675,6 +678,15 @@
|
||||
<ClCompile Include="..\tier1\lzss.cpp">
|
||||
<Filter>sdk\tier1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\pluginsystem\modsystem.cpp">
|
||||
<Filter>sdk\pluginsystem</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\vpc\rson.cpp">
|
||||
<Filter>sdk\vpc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\localize\localize.cpp">
|
||||
<Filter>sdk\localize</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\engine\staticpropmgr.cpp">
|
||||
<Filter>sdk\engine</Filter>
|
||||
</ClCompile>
|
||||
@ -1730,6 +1742,15 @@
|
||||
<ClInclude Include="..\public\tier0\memdbgoff.h">
|
||||
<Filter>sdk\public\tier0</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\pluginsystem\modsystem.h">
|
||||
<Filter>sdk\pluginsystem</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\vpc\rson.h">
|
||||
<Filter>sdk\vpc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\localize\localize.h">
|
||||
<Filter>sdk\localize</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\engine\staticpropmgr.h">
|
||||
<Filter>sdk\engine</Filter>
|
||||
</ClInclude>
|
||||
|
@ -278,6 +278,7 @@
|
||||
<ClInclude Include="..\launcher\IApplication.h" />
|
||||
<ClInclude Include="..\launcher\launcher.h" />
|
||||
<ClInclude Include="..\launcher\prx.h" />
|
||||
<ClInclude Include="..\localize\localize.h" />
|
||||
<ClInclude Include="..\materialsystem\cmaterialsystem.h" />
|
||||
<ClInclude Include="..\mathlib\adler32.h" />
|
||||
<ClInclude Include="..\mathlib\bitvec.h" />
|
||||
@ -307,6 +308,7 @@
|
||||
<ClInclude Include="..\networksystem\pylon.h" />
|
||||
<ClInclude Include="..\networksystem\serverlisting.h" />
|
||||
<ClInclude Include="..\networksystem\sm_protocol.h" />
|
||||
<ClInclude Include="..\pluginsystem\modsystem.h" />
|
||||
<ClInclude Include="..\pluginsystem\pluginsystem.h" />
|
||||
<ClInclude Include="..\protoc\cl_rcon.pb.h" />
|
||||
<ClInclude Include="..\protoc\sig_map.pb.h" />
|
||||
@ -507,6 +509,7 @@
|
||||
<ClInclude Include="..\vpc\interfaces.h" />
|
||||
<ClInclude Include="..\vpc\keyvalues.h" />
|
||||
<ClInclude Include="..\vpc\kvleaktrace.h" />
|
||||
<ClInclude Include="..\vpc\rson.h" />
|
||||
<ClInclude Include="..\vphysics\QHull.h" />
|
||||
<ClInclude Include="..\vpklib\packedstore.h" />
|
||||
<ClInclude Include="..\vstdlib\autocompletefilelist.h" />
|
||||
@ -576,6 +579,7 @@
|
||||
<ClCompile Include="..\launcher\IApplication.cpp" />
|
||||
<ClCompile Include="..\launcher\launcher.cpp" />
|
||||
<ClCompile Include="..\launcher\prx.cpp" />
|
||||
<ClCompile Include="..\localize\localize.cpp" />
|
||||
<ClCompile Include="..\materialsystem\cmaterialsystem.cpp" />
|
||||
<ClCompile Include="..\mathlib\adler32.cpp" />
|
||||
<ClCompile Include="..\mathlib\almostequal.cpp" />
|
||||
@ -595,6 +599,7 @@
|
||||
<ClCompile Include="..\mathlib\vmatrix.cpp" />
|
||||
<ClCompile Include="..\networksystem\bansystem.cpp" />
|
||||
<ClCompile Include="..\networksystem\pylon.cpp" />
|
||||
<ClCompile Include="..\pluginsystem\modsystem.cpp" />
|
||||
<ClCompile Include="..\pluginsystem\pluginsystem.cpp" />
|
||||
<ClCompile Include="..\protoc\cl_rcon.pb.cc">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
@ -657,6 +662,7 @@
|
||||
<ClCompile Include="..\vpc\IAppSystem.cpp" />
|
||||
<ClCompile Include="..\vpc\interfaces.cpp" />
|
||||
<ClCompile Include="..\vpc\keyvalues.cpp" />
|
||||
<ClCompile Include="..\vpc\rson.cpp" />
|
||||
<ClCompile Include="..\vphysics\physics_collide.cpp" />
|
||||
<ClCompile Include="..\vphysics\QHull.cpp" />
|
||||
<ClCompile Include="..\vpklib\packedstore.cpp" />
|
||||
|
@ -178,6 +178,9 @@
|
||||
<Filter Include="sdk\public\tier2">
|
||||
<UniqueIdentifier>{f6e7b39b-4032-4a7a-8a44-3aabcbe46ba5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="sdk\localize">
|
||||
<UniqueIdentifier>{a1808eb5-d397-446f-beef-33adab77733b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="sdk\engine\shared">
|
||||
<UniqueIdentifier>{4bccf09c-4f8b-4d7e-ab72-54fd8c1fb5cf}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@ -1134,6 +1137,15 @@
|
||||
<ClInclude Include="..\public\tier0\memdbgoff.h">
|
||||
<Filter>sdk\public\tier0</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\localize\localize.h">
|
||||
<Filter>sdk\localize</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\pluginsystem\modsystem.h">
|
||||
<Filter>sdk\pluginsystem</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\vpc\rson.h">
|
||||
<Filter>sdk\vpc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\engine\staticpropmgr.h">
|
||||
<Filter>sdk\engine</Filter>
|
||||
</ClInclude>
|
||||
@ -1532,6 +1544,15 @@
|
||||
<ClCompile Include="..\tier1\lzss.cpp">
|
||||
<Filter>sdk\tier1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\localize\localize.cpp">
|
||||
<Filter>sdk\localize</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\pluginsystem\modsystem.cpp">
|
||||
<Filter>sdk\pluginsystem</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\vpc\rson.cpp">
|
||||
<Filter>sdk\vpc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\engine\staticpropmgr.cpp">
|
||||
<Filter>sdk\engine</Filter>
|
||||
</ClCompile>
|
||||
|
@ -95,6 +95,7 @@
|
||||
<ClCompile Include="..\launcher\IApplication.cpp" />
|
||||
<ClCompile Include="..\launcher\launcher.cpp" />
|
||||
<ClCompile Include="..\launcher\prx.cpp" />
|
||||
<ClCompile Include="..\localize\localize.cpp" />
|
||||
<ClCompile Include="..\materialsystem\cmaterialglue.cpp" />
|
||||
<ClCompile Include="..\materialsystem\cmaterialsystem.cpp" />
|
||||
<ClCompile Include="..\materialsystem\cshaderglue.cpp" />
|
||||
@ -116,6 +117,7 @@
|
||||
<ClCompile Include="..\networksystem\bansystem.cpp" />
|
||||
<ClCompile Include="..\networksystem\listmanager.cpp" />
|
||||
<ClCompile Include="..\networksystem\pylon.cpp" />
|
||||
<ClCompile Include="..\pluginsystem\modsystem.cpp" />
|
||||
<ClCompile Include="..\pluginsystem\pluginsystem.cpp" />
|
||||
<ClCompile Include="..\protoc\cl_rcon.pb.cc">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
@ -187,6 +189,7 @@
|
||||
<ClCompile Include="..\vpc\IAppSystem.cpp" />
|
||||
<ClCompile Include="..\vpc\interfaces.cpp" />
|
||||
<ClCompile Include="..\vpc\keyvalues.cpp" />
|
||||
<ClCompile Include="..\vpc\rson.cpp" />
|
||||
<ClCompile Include="..\vphysics\physics_collide.cpp" />
|
||||
<ClCompile Include="..\vphysics\QHull.cpp" />
|
||||
<ClCompile Include="..\vpklib\packedstore.cpp" />
|
||||
@ -314,6 +317,7 @@
|
||||
<ClInclude Include="..\launcher\IApplication.h" />
|
||||
<ClInclude Include="..\launcher\launcher.h" />
|
||||
<ClInclude Include="..\launcher\prx.h" />
|
||||
<ClInclude Include="..\localize\localize.h" />
|
||||
<ClInclude Include="..\materialsystem\cmaterialglue.h" />
|
||||
<ClInclude Include="..\materialsystem\cmaterialsystem.h" />
|
||||
<ClInclude Include="..\materialsystem\cshaderglue.h" />
|
||||
@ -348,6 +352,7 @@
|
||||
<ClInclude Include="..\networksystem\serverlisting.h" />
|
||||
<ClInclude Include="..\networksystem\sm_protocol.h" />
|
||||
<ClInclude Include="..\pluginsystem\ipluginsystem.h" />
|
||||
<ClInclude Include="..\pluginsystem\modsystem.h" />
|
||||
<ClInclude Include="..\pluginsystem\pluginsystem.h" />
|
||||
<ClInclude Include="..\protoc\cl_rcon.pb.h" />
|
||||
<ClInclude Include="..\protoc\sig_map.pb.h" />
|
||||
@ -575,6 +580,7 @@
|
||||
<ClInclude Include="..\vpc\interfaces.h" />
|
||||
<ClInclude Include="..\vpc\keyvalues.h" />
|
||||
<ClInclude Include="..\vpc\kvleaktrace.h" />
|
||||
<ClInclude Include="..\vpc\rson.h" />
|
||||
<ClInclude Include="..\vphysics\QHull.h" />
|
||||
<ClInclude Include="..\vpklib\packedstore.h" />
|
||||
<ClInclude Include="..\vstdlib\autocompletefilelist.h" />
|
||||
|
@ -238,6 +238,9 @@
|
||||
<Filter Include="sdk\public\tier2">
|
||||
<UniqueIdentifier>{42a3745e-8686-4f83-97bd-cec9336b4937}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="sdk\localize">
|
||||
<UniqueIdentifier>{dd902172-603c-495a-ab31-d786cd1ddbdf}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="sdk\engine\shared">
|
||||
<UniqueIdentifier>{f3335ce8-0956-4d3c-9d12-ca2bd5646d8c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@ -741,6 +744,15 @@
|
||||
<ClCompile Include="..\tier1\lzss.cpp">
|
||||
<Filter>sdk\tier1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\pluginsystem\modsystem.cpp">
|
||||
<Filter>sdk\pluginsystem</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\vpc\rson.cpp">
|
||||
<Filter>sdk\vpc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\localize\localize.cpp">
|
||||
<Filter>sdk\localize</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\engine\staticpropmgr.cpp">
|
||||
<Filter>sdk\engine</Filter>
|
||||
</ClCompile>
|
||||
@ -1901,6 +1913,15 @@
|
||||
<ClInclude Include="..\public\tier0\memdbgoff.h">
|
||||
<Filter>sdk\public\tier0</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\pluginsystem\modsystem.h">
|
||||
<Filter>sdk\pluginsystem</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\vpc\rson.h">
|
||||
<Filter>sdk\vpc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\localize\localize.h">
|
||||
<Filter>sdk\localize</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\engine\staticpropmgr.h">
|
||||
<Filter>sdk\engine</Filter>
|
||||
</ClInclude>
|
||||
|
Loading…
x
Reference in New Issue
Block a user