Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CS2Fixes.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@
<ClInclude Include="src\cs2_sdk\schema.h" />
<ClInclude Include="src\cs2_sdk\entityio.h" />
<ClInclude Include="src\cs2_sdk\cchecktransmitinfo.h" />
<ClInclude Include="src\cs2_sdk\map.h" />
<ClInclude Include="src\ctimer.h" />
<ClInclude Include="src\customio.h" />
<ClInclude Include="src\detours.h" />
Expand Down Expand Up @@ -317,6 +318,7 @@
<ClInclude Include="src\utils\version_gen_placeholder.h" />
<ClInclude Include="src\utils\hud_manager.h" />
<ClInclude Include="src\utils\utils.h" />
<ClInclude Include="src\utils\khook_helpers.h" />
<ClInclude Include="src\utils\sighook.h" />
<ClInclude Include="src\utils\weapon.h" />
<!--- CS2ModServer - Headers -->
Expand Down
5 changes: 4 additions & 1 deletion CS2Fixes.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,9 @@
<ClInclude Include="src\cs2_sdk\cchecktransmitinfo.h">
<Filter>Header Files\cs2_sdk</Filter>
</ClInclude>
<ClInclude Include="src\cs2_sdk\map.h">
<Filter>Header Files\cs2_sdk</Filter>
</ClInclude>
<ClInclude Include="src\entwatch.h">
<Filter>Header Files</Filter>
</ClInclude>
Expand Down Expand Up @@ -451,7 +454,7 @@
<ClInclude Include="src\utils\utils.h">
<Filter>Header Files\utils</Filter>
</ClInclude>
<ClInclude Include="src\utils\sighook.h">
<ClInclude Include="src\utils\khook_helpers.h">
<Filter>Header Files\utils</Filter>
</ClInclude>
<ClInclude Include="src\cs2_sdk\entity\cpointorient.h">
Expand Down
7 changes: 7 additions & 0 deletions gamedata/cs2fixes.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,13 @@
"library": "server",
"windows": "48 83 EC ? 4C 8B C2 48 8D 0D ? ? ? ? 48 8D 54 24 ? FF",
"linux": "55 48 89 F2 48 8D 35 ? ? ? ? 48 89 E5 48 83 EC"
},
// "CWorldRendererMgr::CreateWorld_Internal( %s ): Blocking load because marked for deletion during load"
"CWorldRendererMgr_CreateWorld_Internal":
{
"library": "worldrenderer",
"windows": "48 89 5C 24 ? 48 89 54 24 ? 55 56 57 48 81 EC",
"linux": "55 48 89 E5 41 56 41 55 41 54 49 89 FC 53 48 89 F3 48 83 EC ? F6 46"
}
},
"Offsets":
Expand Down
7 changes: 4 additions & 3 deletions src/addresses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@

#include "tier0/memdbgon.h"

#define RESOLVE_SIG(name, variable) \
#define RESOLVE_SIG(name, variable) \
variable = (decltype(variable))g_GameConfig->ResolveSignature(name); \
if (!variable) \
return false; \
if (!variable) \
return false; \
Message("Found %s at 0x%p\n", name, variable);

#define RESOLVE_SF(scriptDesc, funcName, variable) \
Expand All @@ -51,6 +51,7 @@ bool addresses::Initialize()
modules::networksystem = new CModule(ROOTBIN, "networksystem");
modules::vphysics2 = new CModule(ROOTBIN, "vphysics2");
modules::matchmaking = new CModule(GAMEBIN, "matchmaking");
modules::worldrenderer = new CModule(ROOTBIN, "worldrenderer");
modules::client = nullptr;

if (!CommandLine()->HasParm("-dedicated"))
Expand Down
1 change: 1 addition & 0 deletions src/addresses.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ namespace modules
inline CModule* networksystem;
inline CModule* vphysics2;
inline CModule* matchmaking;
inline CModule* worldrenderer;
#ifdef _WIN32
inline CModule* hammer;
#endif
Expand Down
61 changes: 45 additions & 16 deletions src/cfgparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,19 @@

CCfgParser* g_pCfgParser = nullptr;

CON_COMMAND_F(exec_custom, "<cfgpath> - Execute a cfg through the custom cfg parser", FCVAR_SPONLY | FCVAR_LINKED_CONCOMMAND)
void CCfgParser::PreLevelLoad(const char* pszMapName)
{
if (args.ArgC() < 2)
{
Message("Usage: exec_custom <cfgpath>\n");
return;
}

g_pCfgParser->ParseCfg(args[1]);
// Make sure convars are set before map load, currently used by map migrations
ExecuteConfigs(pszMapName);
}

void CCfgParser::ApplyGameSettings(const char* pszMapName)
{
// Execute again for good measure, because this is when configs would normally execute
ExecuteConfigs(pszMapName);
}

void CCfgParser::ExecuteConfigs(const char* pszMapName)
{
// Run plugin cfg
g_pCfgParser->ParseCfg("cs2fixes/cs2fixes");
Expand All @@ -47,10 +48,9 @@ void CCfgParser::ApplyGameSettings(const char* pszMapName)
return;

// Run map cfg (if present)
// We call ParseCfg indirectly through exec_custom, so any commands within the map cfg will be added to the command buffer after nested executes in previous configs
char cmd[MAX_PATH];
V_snprintf(cmd, sizeof(cmd), "exec_custom cs2fixes/maps/%s", pszMapName);
g_pEngineServer2->ServerCommand(cmd);
char szCfgPath[MAX_PATH];
V_snprintf(szCfgPath, sizeof(szCfgPath), "cs2fixes/maps/%s", pszMapName);
ParseCfg(szCfgPath);
}

void CCfgParser::ParseCfg(const char* pszCfgPath)
Expand All @@ -71,10 +71,39 @@ void CCfgParser::ParseCfg(const char* pszCfgPath)

while (std::getline(cfgFile, strCommand))
{
if (!strCommand.empty() && strCommand.back() == '\r')
strCommand.pop_back();
CCommand args;

if (!args.Tokenize(strCommand.c_str()) || !args.ArgC())
continue;

if (!V_strcasecmp(args[0], "exec_custom"))
{
if (args.ArgC() < 2)
Message("Usage: exec_custom <cfgpath>\n");
else
ParseCfg(args[1]);

continue;
}

ConCommandRef command(args[0], true);
ConVarRefAbstract convar(args[0], true);

if (command.IsValidRef())
{
CCommandContext context(CT_FIRST_SPLITSCREEN_CLIENT, -1);
command.Dispatch(context, args);
continue;
}

if (convar.IsValidRef())
{
if (args.ArgC() > 1 && !convar.SetString(args[1]))
Message("Failed to execute \"%s %s\"\n", args[0], args[1]);

continue;
}

if (!strCommand.empty())
g_pEngineServer2->ServerCommand(strCommand.c_str());
Message("Unknown command \"%s\"\n", args[0]);
}
}
2 changes: 2 additions & 0 deletions src/cfgparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
class CCfgParser
{
public:
void PreLevelLoad(const char* pszMapName);
void ApplyGameSettings(const char* pszMapName);
void ExecuteConfigs(const char* pszMapName);
void ParseCfg(const char* pszCfgPath);
};

Expand Down
7 changes: 6 additions & 1 deletion src/commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1194,7 +1194,12 @@ CON_COMMAND_CHAT(uitest, "<xml path> (<text>) - Spawn UI panel")
if (args.ArgC() > 2)
hLayout->SetDialogVariableString("MyLabel", "CustomText", args[2], player);

hLayout->AddClickCallback([](CCSPlayerController* pController, CCSCustomHudLayout* pHud, std::string sButtonId) {
hLayout->SetDisconnectCallback([](CCSCustomHudLayout* pHud, int slot) {
CCSCustomHudLayout::DefaultOnDisconnect(pHud, slot);
Message("Custom disconnect callback called\n");
});

hLayout->SetClickCallback([](CCSPlayerController* pController, CCSCustomHudLayout* pHud, std::string sButtonId) {
ClientPrintAll(HUD_PRINTTALK, CHAT_PREFIX "%s clicked %s on %s\n", pController->GetPlayerName().c_str(), sButtonId.c_str(), pHud->GetName());

if (sButtonId == "dismiss_button")
Expand Down
124 changes: 106 additions & 18 deletions src/cs2_sdk/entity/customhudlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include "customhudlayout.h"
#include "entity.h"

std::unordered_map<int, CustomHudClickCallback_t> g_mapClickCallbacks;
std::unordered_map<int, CustomHudLayoutCallbacks_t> CCSCustomHudLayout::sm_mapCustomLayoutCallbacks;

CCSCustomHudLayout* CCSCustomHudLayout::Create(std::string sLayout, std::string sTargetName)
{
Expand All @@ -37,34 +37,67 @@ CCSCustomHudLayout* CCSCustomHudLayout::Create(std::string sLayout, std::string
pKeyValues->SetString("targetname", sTargetName.c_str());

pLayout->DispatchSpawn(pKeyValues);
pLayout->SetDisconnectCallback(&DefaultOnDisconnect);

return pLayout;
}

void CCSCustomHudLayout::ClearClickCallbacks()
void CCSCustomHudLayout::ClearCallbacks()
{
g_mapClickCallbacks.clear();
sm_mapCustomLayoutCallbacks.clear();
}

void CCSCustomHudLayout::OnClick(CCSPlayerController* pController, const std::string& sButtonId)
{
if (auto it = g_mapClickCallbacks.find(GetHandle().ToInt()); it != g_mapClickCallbacks.end())
it->second(pController, this, sButtonId);
if (auto it = sm_mapCustomLayoutCallbacks.find(GetHandle().ToInt()); it != sm_mapCustomLayoutCallbacks.end())
it->second.m_OnClick(pController, this, sButtonId);
}

void CCSCustomHudLayout::OnClientDisconnect(int slot)
{
auto iterator = sm_mapCustomLayoutCallbacks.begin();

while (iterator != sm_mapCustomLayoutCallbacks.end())
{
auto pLayout = CHandle<CCSCustomHudLayout>(iterator->first).Get();

if (!pLayout)
{
iterator = sm_mapCustomLayoutCallbacks.erase(iterator);
continue;
}

iterator->second.m_OnDisconnect(pLayout, slot);
iterator++;
}
}

void CCSCustomHudLayout::DefaultOnDisconnect(CCSCustomHudLayout* pLayout, int slot)
{
pLayout->ClearClasses(slot);
pLayout->ClearDialogVariables(slot);
pLayout->SetInputCaptureEnabled(false, slot);
}

void CCSCustomHudLayout::OnEntityDeleted()
{
g_mapClickCallbacks.erase(GetHandle().ToInt());
sm_mapCustomLayoutCallbacks.erase(GetHandle().ToInt());
}

CCSCustomHudLayoutState& CCSCustomHudLayout::GetLayoutState(CCSPlayerController* pController)
CCSCustomHudLayoutState& CCSCustomHudLayout::GetLayoutState(int nSlot)
{
if (!pController)
if (nSlot < 0 || nSlot >= 64)
return *m_globalLayoutState;

return *(CCSCustomHudLayoutState*)m_vecPlayerLayoutStates.GetManipulator()(SCHEMA_COLLECTION_MANIPULATOR_ACTION_GET_ELEMENT, m_vecPlayerLayoutStates, pController->GetPlayerSlot(), 0);
return *(CCSCustomHudLayoutState*)m_vecPlayerLayoutStates.GetManipulator()(SCHEMA_COLLECTION_MANIPULATOR_ACTION_GET_ELEMENT, m_vecPlayerLayoutStates, nSlot, 0);
}

void CCSCustomHudLayout::SetHasClass(std::string sPanelId, std::string sClassName, bool bHasClass, CCSPlayerController* pController)
CCSCustomHudLayoutState& CCSCustomHudLayout::GetLayoutState(CCSPlayerController* pController)
{
return pController ? GetLayoutState(pController->GetPlayerSlot()) : *m_globalLayoutState;
}

void CCSCustomHudLayout::SetHasClass(std::string sPanelId, std::string sClassName, bool bHasClass, int nSlot)
{
auto panelIndex = m_vecPanelIds->Find(sPanelId.c_str());

Expand All @@ -76,7 +109,7 @@ void CCSCustomHudLayout::SetHasClass(std::string sPanelId, std::string sClassNam
if (classIndex == -1)
classIndex = m_vecClassNames->AddToTail(sClassName.c_str());

auto& layoutState = GetLayoutState(pController);
auto& layoutState = GetLayoutState(nSlot);

HUDPanelHasClass_t hasClass(panelIndex, classIndex, bHasClass);

Expand All @@ -86,11 +119,14 @@ void CCSCustomHudLayout::SetHasClass(std::string sPanelId, std::string sClassNam
layoutState.m_vecHasClasses->AddToTail(hasClass);
else
layoutState.m_vecHasClasses->Element(hasClassIndex).m_eClassStatus = hasClass.m_eClassStatus;
}

layoutState.m_vecHasClasses.NetworkStateChanged();
void CCSCustomHudLayout::SetHasClass(std::string sPanelId, std::string sClassName, bool bHasClass, CCSPlayerController* pController)
{
SetHasClass(sPanelId, sClassName, bHasClass, pController ? pController->GetPlayerSlot() : -1);
}

void CCSCustomHudLayout::SetDialogVariableString(std::string sPanelId, std::string sVariableName, std::string sValue, CCSPlayerController* pController)
void CCSCustomHudLayout::SetDialogVariableString(std::string sPanelId, std::string sVariableName, std::string sValue, int nSlot)
{
auto panelIndex = m_vecPanelIds->Find(sPanelId.c_str());

Expand All @@ -102,31 +138,83 @@ void CCSCustomHudLayout::SetDialogVariableString(std::string sPanelId, std::stri
if (variableIndex == -1)
variableIndex = m_vecDialogVariableNames->AddToTail(sVariableName.c_str());

auto& layoutState = GetLayoutState(pController);
auto& layoutState = GetLayoutState(nSlot);

HUDPanelDialogVariableString_t dialogVariable(panelIndex, variableIndex, sValue.c_str(), true);

auto dialogVariableIndex = layoutState.m_vecDialogVariableStrings->Find(dialogVariable);

if (dialogVariableIndex == -1)
{
layoutState.m_vecDialogVariableStrings->AddToTail(dialogVariable);
}
else
{
layoutState.m_vecDialogVariableStrings->Element(dialogVariableIndex).m_sValue = sValue.c_str();
layoutState.m_vecDialogVariableStrings->Element(dialogVariableIndex).m_bIsSet = true;
}
}

layoutState.m_vecDialogVariableStrings.NetworkStateChanged();
void CCSCustomHudLayout::SetDialogVariableString(std::string sPanelId, std::string sVariableName, std::string sValue, CCSPlayerController* pController)
{
SetDialogVariableString(sPanelId, sVariableName, sValue, pController ? pController->GetPlayerSlot() : -1);
}

void CCSCustomHudLayout::ClearClasses(int nSlot)
{
auto& layoutState = GetLayoutState(nSlot);

for (int i = 0; i < layoutState.m_vecHasClasses->Count(); i++)
{
if (layoutState.m_vecHasClasses->Element(i).m_eClassStatus == k_eHudPanelClassStatus_Undefined)
continue;

auto pClass = (HUDPanelHasClass_t*)layoutState.m_vecHasClasses.GetManipulator()(SCHEMA_COLLECTION_MANIPULATOR_ACTION_GET_ELEMENT, layoutState.m_vecHasClasses, i, 0);
pClass->m_eClassStatus = k_eHudPanelClassStatus_Undefined;
}
}

void CCSCustomHudLayout::ClearDialogVariables(int nSlot)
{
auto& layoutState = GetLayoutState(nSlot);

for (int i = 0; i < layoutState.m_vecDialogVariableStrings->Count(); i++)
{
if (!layoutState.m_vecDialogVariableStrings->Element(i).m_bIsSet)
continue;

auto pString = (HUDPanelDialogVariableString_t*)layoutState.m_vecDialogVariableStrings.GetManipulator()(SCHEMA_COLLECTION_MANIPULATOR_ACTION_GET_ELEMENT, layoutState.m_vecDialogVariableStrings, i, 0);
pString->m_bIsSet = false;
pString->m_sValue = "";
}
}

void CCSCustomHudLayout::SetInputCaptureEnabled(bool bEnable, int nSlot)
{
GetLayoutState(nSlot).m_bInputCaptureEnabled = bEnable;
}

void CCSCustomHudLayout::SetInputCaptureEnabled(bool bEnable, CCSPlayerController* pController)
{
GetLayoutState(pController).m_bInputCaptureEnabled = bEnable;
SetInputCaptureEnabled(bEnable, pController ? pController->GetPlayerSlot() : -1);
}

bool CCSCustomHudLayout::IsInputCaptureEnabled(int nSlot)
{
return GetLayoutState(nSlot).m_bInputCaptureEnabled;
}

bool CCSCustomHudLayout::IsInputCaptureEnabled(CCSPlayerController* pController)
{
return GetLayoutState(pController).m_bInputCaptureEnabled;
}

void CCSCustomHudLayout::AddClickCallback(CustomHudClickCallback_t callback)
void CCSCustomHudLayout::SetClickCallback(CustomHudClickCallback_t callback)
{
sm_mapCustomLayoutCallbacks[GetHandle().ToInt()].m_OnClick = callback;
}

void CCSCustomHudLayout::SetDisconnectCallback(CustomHudDisconnectCallback_t callback)
{
g_mapClickCallbacks.insert({GetHandle().ToInt(), callback});
sm_mapCustomLayoutCallbacks[GetHandle().ToInt()].m_OnDisconnect = callback;
}
Loading
Loading