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
6 changes: 5 additions & 1 deletion BindingMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ extern "C"
#include "lauxlib.h"
};

class BaseBindingMap {
public:
virtual ~BaseBindingMap() = default;
};

/*
* A set of bindings from keys of type `K` to Lua references.
*/
template<typename K>
class BindingMap
class BindingMap : public BaseBindingMap
{
private:
lua_State* L;
Expand Down
325 changes: 112 additions & 213 deletions LuaEngine.cpp

Large diffs are not rendered by default.

50 changes: 25 additions & 25 deletions LuaEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ typedef VehicleInfo Vehicle;
struct lua_State;
class EventMgr;
class ElunaObject;
class BaseBindingMap;
template<typename T> class ElunaTemplate;

template<typename K> class BindingMap;
Expand Down Expand Up @@ -150,8 +151,6 @@ enum MethodFlags : uint32
class ELUNA_GAME_API Eluna
{
public:
typedef std::list<LuaScript> ScriptList;
typedef std::recursive_mutex LockType;

void ReloadEluna() { reload = true; }
bool ExecuteCall(int params, int res);
Expand Down Expand Up @@ -183,6 +182,14 @@ class ELUNA_GAME_API Eluna
// Map from map ID -> Lua table ref
std::unordered_map<uint32, int> continentDataRefs;

std::unordered_map<std::underlying_type_t<Hooks::RegisterTypes>, std::unique_ptr<BaseBindingMap>> bindingMaps;

template<typename T>
void CreateBinding(Hooks::RegisterTypes type)
{
bindingMaps[std::underlying_type_t<Hooks::RegisterTypes>(type)] = std::make_unique<BindingMap<T>>(L);
}

void OpenLua();
void CloseLua();
void DestroyBindStores();
Expand Down Expand Up @@ -240,34 +247,13 @@ class ELUNA_GAME_API Eluna
public:

lua_State* L;
EventMgr* eventMgr;
std::unique_ptr<EventMgr> eventMgr;

#if defined ELUNA_TRINITY
QueryCallbackProcessor queryProcessor;
QueryCallbackProcessor& GetQueryProcessor() { return queryProcessor; }
#endif

BindingMap< EventKey<Hooks::ServerEvents> >* ServerEventBindings;
BindingMap< EventKey<Hooks::PlayerEvents> >* PlayerEventBindings;
BindingMap< EventKey<Hooks::GuildEvents> >* GuildEventBindings;
BindingMap< EventKey<Hooks::GroupEvents> >* GroupEventBindings;
BindingMap< EventKey<Hooks::VehicleEvents> >* VehicleEventBindings;
BindingMap< EventKey<Hooks::BGEvents> >* BGEventBindings;

BindingMap< EntryKey<Hooks::PacketEvents> >* PacketEventBindings;
BindingMap< EntryKey<Hooks::CreatureEvents> >* CreatureEventBindings;
BindingMap< EntryKey<Hooks::GossipEvents> >* CreatureGossipBindings;
BindingMap< EntryKey<Hooks::GameObjectEvents> >* GameObjectEventBindings;
BindingMap< EntryKey<Hooks::GossipEvents> >* GameObjectGossipBindings;
BindingMap< EntryKey<Hooks::SpellEvents> >* SpellEventBindings;
BindingMap< EntryKey<Hooks::ItemEvents> >* ItemEventBindings;
BindingMap< EntryKey<Hooks::GossipEvents> >* ItemGossipBindings;
BindingMap< EntryKey<Hooks::GossipEvents> >* PlayerGossipBindings;
BindingMap< EntryKey<Hooks::InstanceEvents> >* MapEventBindings;
BindingMap< EntryKey<Hooks::InstanceEvents> >* InstanceEventBindings;

BindingMap< UniqueObjectKey<Hooks::CreatureEvents> >* CreatureUniqueBindings;

static int StackTrace(lua_State* _L);
static void Report(lua_State* _L);

Expand Down Expand Up @@ -337,7 +323,7 @@ class ELUNA_GAME_API Eluna
#if !defined TRACKABLE_PTR_NAMESPACE
uint64 GetCallstackId() const { return callstackid; }
#endif
int Register(uint8 reg, uint32 entry, ObjectGuid guid, uint32 instanceId, uint32 event_id, int functionRef, uint32 shots);
int Register(std::underlying_type_t<Hooks::RegisterTypes> regtype, uint32 entry, ObjectGuid guid, uint32 instanceId, uint32 event_id, int functionRef, uint32 shots);
void UpdateEluna(uint32 diff);

// Checks
Expand Down Expand Up @@ -374,6 +360,20 @@ class ELUNA_GAME_API Eluna
return 0;
}

template<typename T>
BindingMap<T>* GetBinding(std::underlying_type_t<Hooks::RegisterTypes> type)
{
auto it = bindingMaps.find(type);
if (it == bindingMaps.end()) return nullptr;
return dynamic_cast<BindingMap<T>*>(it->second.get());
}

template<typename T>
BindingMap<T>* GetBinding(Hooks::RegisterTypes type)
{
return GetBinding<T>(static_cast<std::underlying_type_t<Hooks::RegisterTypes>>(type));
}

Eluna(Map * map);
~Eluna();

Expand Down
11 changes: 6 additions & 5 deletions hooks/BattleGroundHooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
using namespace Hooks;

#define START_HOOK(EVENT) \
auto binding = GetBinding<EventKey<BGEvents>>(REGTYPE_BG);\
auto key = EventKey<BGEvents>(EVENT);\
if (!BGEventBindings->HasBindingsFor(key))\
if (!binding->HasBindingsFor(key))\
return;

void Eluna::OnBGStart(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId)
Expand All @@ -23,7 +24,7 @@ void Eluna::OnBGStart(BattleGround* bg, BattleGroundTypeId bgId, uint32 instance
HookPush(bg);
HookPush(bgId);
HookPush(instanceId);
CallAllFunctions(BGEventBindings, key);
CallAllFunctions(binding, key);
}

void Eluna::OnBGEnd(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId, Team winner)
Expand All @@ -33,7 +34,7 @@ void Eluna::OnBGEnd(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId
HookPush(bgId);
HookPush(instanceId);
HookPush(winner);
CallAllFunctions(BGEventBindings, key);
CallAllFunctions(binding, key);
}

void Eluna::OnBGCreate(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId)
Expand All @@ -42,7 +43,7 @@ void Eluna::OnBGCreate(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanc
HookPush(bg);
HookPush(bgId);
HookPush(instanceId);
CallAllFunctions(BGEventBindings, key);
CallAllFunctions(binding, key);
}

void Eluna::OnBGDestroy(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId)
Expand All @@ -51,5 +52,5 @@ void Eluna::OnBGDestroy(BattleGround* bg, BattleGroundTypeId bgId, uint32 instan
HookPush(bg);
HookPush(bgId);
HookPush(instanceId);
CallAllFunctions(BGEventBindings, key);
CallAllFunctions(binding, key);
}
4 changes: 4 additions & 0 deletions hooks/CreatureHooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@
using namespace Hooks;

#define START_HOOK(EVENT, CREATURE) \
auto CreatureEventBindings = GetBinding<EntryKey<CreatureEvents>>(REGTYPE_CREATURE);\
auto CreatureUniqueBindings = GetBinding<UniqueObjectKey<CreatureEvents>>(REGTYPE_CREATURE_UNIQUE);\
auto entry_key = EntryKey<CreatureEvents>(EVENT, CREATURE->GetEntry());\
auto unique_key = UniqueObjectKey<CreatureEvents>(EVENT, CREATURE->GET_GUID(), CREATURE->GetInstanceId());\
if (!CreatureEventBindings->HasBindingsFor(entry_key))\
if (!CreatureUniqueBindings->HasBindingsFor(unique_key))\
return;

#define START_HOOK_WITH_RETVAL(EVENT, CREATURE, RETVAL) \
auto CreatureEventBindings = GetBinding<EntryKey<CreatureEvents>>(REGTYPE_CREATURE);\
auto CreatureUniqueBindings = GetBinding<UniqueObjectKey<CreatureEvents>>(REGTYPE_CREATURE_UNIQUE);\
auto entry_key = EntryKey<CreatureEvents>(EVENT, CREATURE->GetEntry());\
auto unique_key = UniqueObjectKey<CreatureEvents>(EVENT, CREATURE->GET_GUID(), CREATURE->GetInstanceId());\
if (!CreatureEventBindings->HasBindingsFor(entry_key))\
Expand Down
32 changes: 17 additions & 15 deletions hooks/GameObjectHooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
using namespace Hooks;

#define START_HOOK(EVENT, ENTRY) \
auto binding = GetBinding<EntryKey<GameObjectEvents>>(REGTYPE_GAMEOBJECT);\
auto key = EntryKey<GameObjectEvents>(EVENT, ENTRY);\
if (!GameObjectEventBindings->HasBindingsFor(key))\
if (!binding->HasBindingsFor(key))\
return;

#define START_HOOK_WITH_RETVAL(EVENT, ENTRY, RETVAL) \
auto binding = GetBinding<EntryKey<GameObjectEvents>>(REGTYPE_GAMEOBJECT);\
auto key = EntryKey<GameObjectEvents>(EVENT, ENTRY);\
if (!GameObjectEventBindings->HasBindingsFor(key))\
if (!binding->HasBindingsFor(key))\
return RETVAL;

void Eluna::OnDummyEffect(WorldObject* pCaster, uint32 spellId, SpellEffIndex effIndex, GameObject* pTarget)
Expand All @@ -31,15 +33,15 @@ void Eluna::OnDummyEffect(WorldObject* pCaster, uint32 spellId, SpellEffIndex ef
HookPush(spellId);
HookPush(effIndex);
HookPush(pTarget);
CallAllFunctions(GameObjectEventBindings, key);
CallAllFunctions(binding, key);
}

void Eluna::UpdateAI(GameObject* pGameObject, uint32 diff)
{
START_HOOK(GAMEOBJECT_EVENT_ON_AIUPDATE, pGameObject->GetEntry());
HookPush(pGameObject);
HookPush(diff);
CallAllFunctions(GameObjectEventBindings, key);
CallAllFunctions(binding, key);
}

bool Eluna::OnQuestAccept(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest)
Expand All @@ -48,7 +50,7 @@ bool Eluna::OnQuestAccept(Player* pPlayer, GameObject* pGameObject, Quest const*
HookPush(pPlayer);
HookPush(pGameObject);
HookPush(pQuest);
return CallAllFunctionsBool(GameObjectEventBindings, key);
return CallAllFunctionsBool(binding, key);
}

bool Eluna::OnQuestReward(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest, uint32 opt)
Expand All @@ -58,15 +60,15 @@ bool Eluna::OnQuestReward(Player* pPlayer, GameObject* pGameObject, Quest const*
HookPush(pGameObject);
HookPush(pQuest);
HookPush(opt);
return CallAllFunctionsBool(GameObjectEventBindings, key);
return CallAllFunctionsBool(binding, key);
}

void Eluna::GetDialogStatus(const Player* pPlayer, const GameObject* pGameObject)
{
START_HOOK(GAMEOBJECT_EVENT_ON_DIALOG_STATUS, pGameObject->GetEntry());
HookPush(pPlayer);
HookPush(pGameObject);
CallAllFunctions(GameObjectEventBindings, key);
CallAllFunctions(binding, key);
}

#if ELUNA_EXPANSION >= EXP_WOTLK
Expand All @@ -75,15 +77,15 @@ void Eluna::OnDestroyed(GameObject* pGameObject, WorldObject* attacker)
START_HOOK(GAMEOBJECT_EVENT_ON_DESTROYED, pGameObject->GetEntry());
HookPush(pGameObject);
HookPush(attacker);
CallAllFunctions(GameObjectEventBindings, key);
CallAllFunctions(binding, key);
}

void Eluna::OnDamaged(GameObject* pGameObject, WorldObject* attacker)
{
START_HOOK(GAMEOBJECT_EVENT_ON_DAMAGED, pGameObject->GetEntry());
HookPush(pGameObject);
HookPush(attacker);
CallAllFunctions(GameObjectEventBindings, key);
CallAllFunctions(binding, key);
}
#endif

Expand All @@ -92,42 +94,42 @@ void Eluna::OnLootStateChanged(GameObject* pGameObject, uint32 state)
START_HOOK(GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE, pGameObject->GetEntry());
HookPush(pGameObject);
HookPush(state);
CallAllFunctions(GameObjectEventBindings, key);
CallAllFunctions(binding, key);
}

void Eluna::OnGameObjectStateChanged(GameObject* pGameObject, uint32 state)
{
START_HOOK(GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED, pGameObject->GetEntry());
HookPush(pGameObject);
HookPush(state);
CallAllFunctions(GameObjectEventBindings, key);
CallAllFunctions(binding, key);
}

void Eluna::OnSpawn(GameObject* pGameObject)
{
START_HOOK(GAMEOBJECT_EVENT_ON_SPAWN, pGameObject->GetEntry());
HookPush(pGameObject);
CallAllFunctions(GameObjectEventBindings, key);
CallAllFunctions(binding, key);
}

void Eluna::OnAddToWorld(GameObject* pGameObject)
{
START_HOOK(GAMEOBJECT_EVENT_ON_ADD, pGameObject->GetEntry());
HookPush(pGameObject);
CallAllFunctions(GameObjectEventBindings, key);
CallAllFunctions(binding, key);
}

void Eluna::OnRemoveFromWorld(GameObject* pGameObject)
{
START_HOOK(GAMEOBJECT_EVENT_ON_REMOVE, pGameObject->GetEntry());
HookPush(pGameObject);
CallAllFunctions(GameObjectEventBindings, key);
CallAllFunctions(binding, key);
}

bool Eluna::OnGameObjectUse(Player* pPlayer, GameObject* pGameObject)
{
START_HOOK_WITH_RETVAL(GAMEOBJECT_EVENT_ON_USE, pGameObject->GetEntry(), false);
HookPush(pGameObject);
HookPush(pPlayer);
return CallAllFunctionsBool(GameObjectEventBindings, key);
return CallAllFunctionsBool(binding, key);
}
Loading