Skip to content

Commit ba74d1d

Browse files
committed
fix(events): EventResult Handled not being considered & Event Object Lifetime
1 parent 6393260 commit ba74d1d

File tree

10 files changed

+61
-35
lines changed

10 files changed

+61
-35
lines changed

src/core/entrypoint.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,19 +246,21 @@ bool SwiftlyS2::Unload(char* error, size_t maxlen)
246246

247247
bool OnClientCommand(int playerid, std::string command)
248248
{
249-
ClassData data({ { "plugin_name", std::string("core") } }, "Event", nullptr);
250-
g_pluginManager.ExecuteEvent("core", "OnClientCommand", { playerid, command }, &data);
249+
ClassData* data = new ClassData({ { "plugin_name", std::string("core") } }, "Event", nullptr);
250+
g_pluginManager.ExecuteEvent("core", "OnClientCommand", { playerid, command }, data);
251251

252252
bool response = true;
253253
try
254254
{
255-
response = std::any_cast<bool>(data.GetAnyData("event_return"));
255+
response = std::any_cast<bool>(data->GetAnyData("event_return"));
256256
}
257257
catch (std::bad_any_cast& e)
258258
{
259259
response = true;
260260
}
261261

262+
delete data;
263+
262264
return response;
263265
}
264266

src/entities/system.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,9 @@ void EntitySystem::AcceptInput(void* entity, std::string input, void* activator,
6464
{
6565
variant_t variantValue = variant_t(value.c_str());
6666
g_GameData.FetchSignature<CEntityInstance_AcceptInput>("CEntityInstance_AcceptInput")(entity, input.c_str(), activator, caller, &variantValue, outputID);
67+
}
68+
69+
bool EntitySystem::IsValidEntity(void* entity)
70+
{
71+
return entity != nullptr;
6772
}

src/entities/system.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class EntitySystem
2929
void Despawn(void* entity);
3030
void* CreateByName(const char* name);
3131
void AcceptInput(void* entity, std::string input, void* activator, void* caller, std::string value, int outputID);
32+
33+
bool IsValidEntity(void* entity);
3234
};
3335

3436
class CEntityListener : public IEntityListener

src/network/usermessages/usermessages.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ bool UserMessages::FilterMessage(const CNetMessage* cMsg, INetChannel* netchan)
3131
if (!client) RETURN_META_VALUE(MRES_IGNORED, true);
3232

3333
UserMessage um(cMsg->GetNetMessage(), const_cast<CNetMessage*>(cMsg), (uint64_t*)0);
34-
ClassData umobj({ { "um_ptr", &um } }, "UserMessage", nullptr);
35-
auto result = g_pluginManager.ExecuteEvent("core", "OnUserMessageReceive", { client->GetPlayerSlot().Get(), &umobj }, {});
34+
ClassData* umobj = new ClassData({ { "um_ptr", &um } }, "UserMessage", nullptr);
35+
auto result = g_pluginManager.ExecuteEvent("core", "OnUserMessageReceive", { client->GetPlayerSlot().Get(), umobj }, {});
36+
delete umobj;
3637
if (result != EventResult::Continue)
3738
RETURN_META_VALUE(MRES_SUPERCEDE, true);
3839

@@ -50,8 +51,12 @@ void UserMessages::Destroy()
5051
void UserMessages::PostEvent(CSplitScreenSlot nSlot, bool bLocalOnly, int nClientCount, const uint64* clients, INetworkMessageInternal* pEvent, const CNetMessage* pData, unsigned long nSize, NetChannelBufType_t bufType)
5152
{
5253
UserMessage um(pEvent, const_cast<CNetMessage*>(pData), (uint64_t*)(const_cast<uint64*>(clients)));
53-
ClassData umobj({ { "um_ptr", &um } }, "UserMessage", nullptr);
54+
ClassData* umobj = new ClassData({ { "um_ptr", &um } }, "UserMessage", nullptr);
5455

55-
if (g_pluginManager.ExecuteEvent("core", "OnUserMessageSend", { &umobj, bufType == BUF_RELIABLE }, {}) == EventResult::Stop)
56+
if (g_pluginManager.ExecuteEvent("core", "OnUserMessageSend", { umobj, bufType == BUF_RELIABLE }, {}) == EventResult::Stop) {
57+
delete umobj;
5658
RETURN_META(MRES_SUPERCEDE);
59+
}
60+
61+
delete umobj;
5762
}

src/plugins/manager.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,9 @@ std::string PluginsManager::GetPluginBasePath(std::string plugin_name)
216216

217217
EXT_API int swiftly_TriggerEvent(const char* ext_name, const char* evName, void* args, void* eventReturn)
218218
{
219-
ClassData data({ { "plugin_name", std::string(ext_name) } }, "Event", nullptr);
220-
auto result = g_pluginManager.ExecuteEvent(ext_name, evName, *(std::vector<std::any>*)args, &data);
221-
*reinterpret_cast<std::any*>(eventReturn) = data.GetAnyData("event_return");
222-
219+
ClassData* data = new ClassData({ { "plugin_name", std::string(ext_name) } }, "Event", nullptr);
220+
auto result = g_pluginManager.ExecuteEvent(ext_name, evName, *(std::vector<std::any>*)args, data);
221+
*reinterpret_cast<std::any*>(eventReturn) = data->GetAnyData("event_return");
222+
delete data;
223223
return (int)result;
224224
}

src/plugins/object.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ EventResult PluginObject::TriggerEvent(std::string invokedBy, std::string eventN
7777
if (value.isNumber())
7878
{
7979
int result = value.cast<int>();
80-
if (result < (int)EventResult::Continue || result >(int)EventResult::Stop)
80+
if (result < (int)EventResult::Continue || result >(int)EventResult::Handled)
8181
response = EventResult::Continue;
8282
else
8383
response = (EventResult)result;

src/scripting/engine/gameevents.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,19 @@ FunctionHook CCSPlayerPawnBase_PostThink("CCSPlayerPawnBase_PostThink", dyno::Ca
2929

3030
bool OnClientChat(int playerid, std::string text, bool teamonly)
3131
{
32-
ClassData data({ { "plugin_name", std::string("core") } }, "Event", nullptr);
33-
g_pluginManager.ExecuteEvent("core", "OnClientChat", { playerid, text, teamonly }, &data);
32+
ClassData* data = new ClassData({ { "plugin_name", std::string("core") } }, "Event", nullptr);
33+
g_pluginManager.ExecuteEvent("core", "OnClientChat", { playerid, text, teamonly }, data);
3434

3535
bool response = true;
3636
try
3737
{
38-
response = std::any_cast<bool>(data.GetAnyData("event_return"));
38+
response = std::any_cast<bool>(data->GetAnyData("event_return"));
3939
}
4040
catch (std::bad_any_cast& e)
4141
{
4242
response = true;
4343
}
44+
delete data;
4445

4546
return response;
4647
}
@@ -52,18 +53,19 @@ void OnClientConvarQuery(int playerid, std::string convar_name, std::string conv
5253

5354
dyno::ReturnAction Hook_CGameRules_TerminateRound(dyno::CallbackType type, dyno::IHook& hook)
5455
{
55-
ClassData data({ { "plugin_name", std::string("core") } }, "Event", nullptr);
56-
g_pluginManager.ExecuteEvent("core", "OnTerminateRound", std::vector<std::any>{ hook.getArgument<float>(1), hook.getArgument<uint32_t>(2) }, & data);
56+
ClassData* data = new ClassData({ { "plugin_name", std::string("core") } }, "Event", nullptr);
57+
g_pluginManager.ExecuteEvent("core", "OnTerminateRound", std::vector<std::any>{ hook.getArgument<float>(1), hook.getArgument<uint32_t>(2) }, data);
5758

5859
bool response = true;
5960
try
6061
{
61-
response = std::any_cast<bool>(data.GetAnyData("event_return"));
62+
response = std::any_cast<bool>(data->GetAnyData("event_return"));
6263
}
6364
catch (std::bad_any_cast& e)
6465
{
6566
response = true;
6667
}
68+
delete data;
6769

6870
if (!response) return dyno::ReturnAction::Supercede;
6971

@@ -74,17 +76,17 @@ FunctionHook CGameRules_TerminateRound("CGameRules_TerminateRound", dyno::Callba
7476

7577
dyno::ReturnAction Hook_CEntityIdentity_AcceptInput(dyno::CallbackType type, dyno::IHook& hook)
7678
{
77-
ClassData data({ { "plugin_name", std::string("core") } }, "Event", nullptr);
79+
ClassData* data = new ClassData({ { "plugin_name", std::string("core") } }, "Event", nullptr);
7880
ClassData* ThisPlayer = new ClassData({ { "class_name", std::string("CEntityInstance") }, { "class_ptr", (void*)(hook.getArgument<CEntityIdentity*>(0)->m_pInstance) } }, "SDKClass", nullptr);
7981
ClassData* Activator = new ClassData({ { "class_name", std::string("CEntityInstance") }, { "class_ptr", (void*)(hook.getArgument<CEntityInstance*>(2)) } }, "SDKClass", nullptr);
8082
ClassData* Caller = new ClassData({ { "class_name", std::string("CEntityInstance") }, { "class_ptr", (void*)(hook.getArgument<CEntityInstance*>(3)) } }, "SDKClass", nullptr);
8183

82-
g_pluginManager.ExecuteEvent("core", "OnEntityAcceptInput", { ThisPlayer, hook.getArgument<CUtlSymbolLarge*>(1)->String(), Activator, Caller, hook.getArgument<variant_t*>(4)->ToString(), hook.getArgument<int>(5) }, &data);
84+
g_pluginManager.ExecuteEvent("core", "OnEntityAcceptInput", { ThisPlayer, hook.getArgument<CUtlSymbolLarge*>(1)->String(), Activator, Caller, hook.getArgument<variant_t*>(4)->ToString(), hook.getArgument<int>(5) }, data);
8385

8486
bool response = true;
8587
try
8688
{
87-
response = std::any_cast<bool>(data.GetAnyData("event_return"));
89+
response = std::any_cast<bool>(data->GetAnyData("event_return"));
8890
}
8991
catch (std::bad_any_cast& e)
9092
{
@@ -94,6 +96,7 @@ dyno::ReturnAction Hook_CEntityIdentity_AcceptInput(dyno::CallbackType type, dyn
9496
delete ThisPlayer;
9597
delete Activator;
9698
delete Caller;
99+
delete data;
97100

98101
if (!response) return dyno::ReturnAction::Supercede;
99102

@@ -120,17 +123,17 @@ dyno::ReturnAction Hook_CBaseEntity_TakeDamage(dyno::CallbackType type, dyno::IH
120123
if (attackerController) attackerid = attackerController.GetEntryIndex() - 1;
121124
}
122125

123-
ClassData data({ { "plugin_name", std::string("core") } }, "Event", nullptr);
126+
ClassData* data = new ClassData({ { "plugin_name", std::string("core") } }, "Event", nullptr);
124127
ClassData* damageinfo = new ClassData({ { "class_name", std::string("CTakeDamageInfo") }, { "class_ptr", (void*)info } }, "SDKClass", nullptr);
125128
ClassData* Inflictor = new ClassData({ { "class_name", std::string("CBaseEntity") }, { "class_ptr", (void*)(info->m_hInflictor.Get()) } }, "SDKClass", nullptr);
126129
ClassData* Ability = new ClassData({ { "class_name", std::string("CBaseEntity") }, { "class_ptr", (void*)(info->m_hAbility.Get()) } }, "SDKClass", nullptr);
127130

128-
g_pluginManager.ExecuteEvent("core", "OnPlayerDamage", { playerid, attackerid, damageinfo, Inflictor, Ability }, &data);
131+
g_pluginManager.ExecuteEvent("core", "OnPlayerDamage", { playerid, attackerid, damageinfo, Inflictor, Ability }, data);
129132

130133
bool response = true;
131134
try
132135
{
133-
response = std::any_cast<bool>(data.GetAnyData("event_return"));
136+
response = std::any_cast<bool>(data->GetAnyData("event_return"));
134137
}
135138
catch (std::bad_any_cast& e)
136139
{
@@ -140,6 +143,7 @@ dyno::ReturnAction Hook_CBaseEntity_TakeDamage(dyno::CallbackType type, dyno::IH
140143
delete damageinfo;
141144
delete Inflictor;
142145
delete Ability;
146+
delete data;
143147

144148
if (!response) return dyno::ReturnAction::Supercede;
145149

src/scripting/memory/hooks.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,16 @@ dyno::ReturnAction HookCallback(dyno::CallbackType type, dyno::IHook& hook) {
7272
if (hooksList.find(hptr) == hooksList.end())
7373
return dyno::ReturnAction::Ignored;
7474

75-
ClassData ev({ { "plugin_name", std::string("core") }, { "hook_ptr", hptr } }, "Event", nullptr);
75+
ClassData* ev = new ClassData({ { "plugin_name", std::string("core") }, { "hook_ptr", hptr } }, "Event", nullptr);
7676
for (auto hk : hooksList[hptr])
7777
{
78-
if (g_pluginManager.ExecuteEvent("core", "hook:" + callbackType + ":" + hk.id, {}, &ev) != EventResult::Continue) {
78+
if (g_pluginManager.ExecuteEvent("core", "hook:" + callbackType + ":" + hk.id, {}, ev) != EventResult::Continue) {
79+
delete ev;
7980
return dyno::ReturnAction::Supercede;
8081
}
8182
}
8283

84+
delete ev;
8385
return dyno::ReturnAction::Ignored;
8486
}
8587

@@ -109,7 +111,7 @@ dyno::ReturnAction Hook_FireOutputInternal(dyno::CallbackType type, dyno::IHook&
109111

110112
if (hookIds.size() > 0)
111113
{
112-
ClassData ev({ { "plugin_name", std::string("core") } }, "Event", nullptr);
114+
ClassData* ev = new ClassData({ { "plugin_name", std::string("core") } }, "Event", nullptr);
113115

114116
ClassData* entIOOutput = new ClassData({ { "class_name", std::string("CEntityIOOutput") }, { "class_ptr", (void*)pThis } }, "SDKClass", nullptr);
115117
ClassData* Activator = new ClassData({ { "class_name", std::string("CEntityInstance") }, { "class_ptr", (void*)pActivator } }, "SDKClass", nullptr);
@@ -123,16 +125,21 @@ dyno::ReturnAction Hook_FireOutputInternal(dyno::CallbackType type, dyno::IHook&
123125
Activator,
124126
Caller,
125127
delay
126-
}, &ev);
128+
}, ev);
127129
if (result != EventResult::Continue)
128130
{
131+
delete entIOOutput;
132+
delete Activator;
133+
delete Caller;
134+
delete ev;
129135
return dyno::ReturnAction::Supercede;
130136
}
131137
}
132138

133139
delete entIOOutput;
134140
delete Activator;
135141
delete Caller;
142+
delete ev;
136143
}
137144

138145
return dyno::ReturnAction::Ignored;

src/scripting/sdk/schema.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ void SchemaCallback(PluginObject plugin, EContext* ctx) {
100100
});
101101

102102
ADD_CLASS_FUNCTION("SDKClass", "IsValid", [](FunctionContext* context, ClassData* data) -> void {
103-
context->SetReturn(data->GetData<void*>("class_ptr") != nullptr);
103+
context->SetReturn(g_entSystem.IsValidEntity(data->GetData<void*>("class_ptr")));
104104
});
105105

106106
ADD_CLASS_FUNCTION("SDKClass", "ToPtr", [](FunctionContext* context, ClassData* data) -> void {
@@ -311,7 +311,7 @@ void SchemaCallback(PluginObject plugin, EContext* ctx) {
311311
uint64_t path = ((uint64_t)hash_32_fnv1a_const(className.c_str()) << 32 | hash_32_fnv1a_const(fieldName.c_str()));
312312

313313
void* instance = data->GetData<void*>("class_ptr");
314-
if (!instance) {
314+
if (!g_entSystem.IsValidEntity(instance)) {
315315
ReportPreventionIncident("Schema / SDK", string_format("Tried to get member '%s::%s' but the entity is invalid.", className.c_str(), fieldName.c_str()));
316316
return context->StopExecution();
317317
}
@@ -322,7 +322,7 @@ void SchemaCallback(PluginObject plugin, EContext* ctx) {
322322
std::string fieldName = explode(context->GetFunctionKey(), " ").back();
323323

324324
void* instance = data->GetData<void*>("class_ptr");
325-
if (!instance) {
325+
if (!g_entSystem.IsValidEntity(instance)) {
326326
ReportPreventionIncident("Schema / SDK", string_format("Tried to set member '%s::%s' but the entity is invalid.", className.c_str(), fieldName.c_str()));
327327
return context->StopExecution();
328328
}
@@ -339,7 +339,7 @@ void SchemaCallback(PluginObject plugin, EContext* ctx) {
339339
uint64_t path = ((uint64_t)hash_32_fnv1a_const(className.c_str()) << 32 | hash_32_fnv1a_const(function_name.c_str()));
340340
if (classFuncs.find(path) != classFuncs.end()) {
341341
void* instance = data->GetData<void*>("class_ptr");
342-
if (!instance) {
342+
if (!g_entSystem.IsValidEntity(instance)) {
343343
ReportPreventionIncident("Schema / SDK", string_format("Tried to call function '%s::%s' but the entity is invalid.", className.c_str(), function_name.c_str()));
344344
return context->StopExecution();
345345
}

src/server/player/manager.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,18 +117,19 @@ bool PlayerManager::ClientConnect(CPlayerSlot slot, const char* pszName, uint64
117117
Player* player = new Player(false, slot.Get(), pszName, xuid, ip_address);
118118
RegisterPlayer(slot, player);
119119

120-
ClassData data({ { "plugin_name", std::string("core") } }, "Event", nullptr);
121-
g_pluginManager.ExecuteEvent("core", "OnClientConnect", { slot.Get() }, &data);
120+
ClassData* data = new ClassData({ { "plugin_name", std::string("core") } }, "Event", nullptr);
121+
g_pluginManager.ExecuteEvent("core", "OnClientConnect", { slot.Get() }, data);
122122

123123
bool response = true;
124124
try
125125
{
126-
response = std::any_cast<bool>(data.GetAnyData("event_return"));
126+
response = std::any_cast<bool>(data->GetAnyData("event_return"));
127127
}
128128
catch (std::bad_any_cast& e)
129129
{
130130
response = true;
131131
}
132+
delete data;
132133

133134
RETURN_META_VALUE(MRES_IGNORED, response);
134135
}

0 commit comments

Comments
 (0)