88#include < vector>
99#include < msgpack.hpp>
1010#include < sstream>
11+ #include < map>
12+ #include < stack>
1113
1214SH_DECL_HOOK2 (IGameEventManager2, FireEvent, SH_NOATTRIB, 0 , bool , IGameEvent *, bool );
1315FuncHook<decltype (Hook_CGameEventManager_Init)> TCGameEventManager_Init (Hook_CGameEventManager_Init, " CGameEventManager_Init" );
1416
1517EventManager *eventManager = nullptr ;
18+ std::stack<IGameEvent*> dupEvents;
1619
1720void Hook_CGameEventManager_Init (IGameEventManager2 *pGameEventManager)
1821{
@@ -46,6 +49,7 @@ void UnregisterEventListeners()
4649void EventManager::Initialize ()
4750{
4851 SH_ADD_HOOK (IGameEventManager2, FireEvent, g_gameEventManager, SH_MEMBER (this , &EventManager::OnFireEvent), false );
52+ SH_ADD_HOOK (IGameEventManager2, FireEvent, g_gameEventManager, SH_MEMBER (this , &EventManager::OnPostFireEvent), true );
4953
5054 for (auto it = gameEventsRegister.begin (); it != gameEventsRegister.end (); ++it)
5155 {
@@ -57,6 +61,7 @@ void EventManager::Initialize()
5761void EventManager::Shutdown ()
5862{
5963 SH_REMOVE_HOOK (IGameEventManager2, FireEvent, g_gameEventManager, SH_MEMBER (this , &EventManager::OnFireEvent), false );
64+ SH_REMOVE_HOOK (IGameEventManager2, FireEvent, g_gameEventManager, SH_MEMBER (this , &EventManager::OnPostFireEvent), true );
6065
6166 g_gameEventManager->RemoveListener (this );
6267}
@@ -102,10 +107,54 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
102107 }
103108 if (result != EventResult::Continue)
104109 {
110+ dupEvents.push (g_gameEventManager->DuplicateEvent (pEvent));
105111 g_gameEventManager->FreeEvent (pEvent);
106112 RETURN_META_VALUE (MRES_SUPERCEDE, false );
107113 }
108114 }
109115
116+ dupEvents.push (g_gameEventManager->DuplicateEvent (pEvent));
117+ RETURN_META_VALUE (MRES_IGNORED, true );
118+ }
119+
120+ bool EventManager::OnPostFireEvent (IGameEvent *pEvent, bool bDontBroadcast)
121+ {
122+ if (!pEvent)
123+ {
124+ RETURN_META_VALUE (MRES_IGNORED, false );
125+ }
126+
127+ IGameEvent* realGameEvent = dupEvents.top ();
128+
129+ std::string eventName = realGameEvent->GetName ();
130+
131+ if (gameEventsRegister.find (eventName) != gameEventsRegister.end ())
132+ {
133+ std::string prettyEventName = gameEventsRegister.at (eventName);
134+
135+ if (!setEmptyEventdata)
136+ {
137+ setEmptyEventdata = true ;
138+
139+ std::stringstream ss;
140+ std::vector<msgpack::object> eventData;
141+
142+ msgpack::pack (ss, eventData);
143+ emptyEventData = ss.str ();
144+ }
145+
146+ PluginEvent *event = new PluginEvent (" core" , realGameEvent, nullptr );
147+ EventResult result = g_pluginManager->ExecuteEvent (" core" , string_format (" OnPost%s" , prettyEventName.substr (2 ).c_str ()), emptyEventData, event);
148+ delete event;
149+
150+ if (result != EventResult::Continue) {
151+ g_gameEventManager->FreeEvent (realGameEvent);
152+ dupEvents.pop ();
153+ RETURN_META_VALUE (MRES_SUPERCEDE, false );
154+ }
155+ }
156+
157+ g_gameEventManager->FreeEvent (realGameEvent);
158+ dupEvents.pop ();
110159 RETURN_META_VALUE (MRES_IGNORED, true );
111160}
0 commit comments