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:
rexx 2023-05-02 19:26:49 +01:00 committed by GitHub
parent e8f6bf0eda
commit bcc51460bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 904 additions and 2 deletions

View File

@ -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);

View File

@ -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*>();

View 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
View 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;
};
///////////////////////////////////////////////////////////////////////////////

View 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();

View 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;

View File

@ -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);

View File

@ -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);

View File

@ -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
{

View File

@ -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)

View File

@ -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
View 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
View 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 { }
};
///////////////////////////////////////////////////////////////////////////////

View File

@ -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" />

View File

@ -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>

View File

@ -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" />

View File

@ -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>

View File

@ -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" />

View File

@ -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>