From 717d1b698d8129fab52836ddb4c76de30ff6b6ed Mon Sep 17 00:00:00 2001 From: Patman64 Date: Sun, 4 Jan 2015 20:30:31 -0500 Subject: [PATCH 01/10] Re-write HookMgr macros into functions and clean-up HookMgr.cpp. --- HookMgr.cpp | 2272 +++++++++++++++++++++++-------------------------- LuaEngine.cpp | 1 + LuaEngine.h | 64 +- 3 files changed, 1116 insertions(+), 1221 deletions(-) diff --git a/HookMgr.cpp b/HookMgr.cpp index 92371be..f811e83 100644 --- a/HookMgr.cpp +++ b/HookMgr.cpp @@ -28,170 +28,253 @@ struct ScriptedAI; using namespace HookMgr; /* - * Call model for EventBind: + * A hook should be written in one of the following forms: * - * // Begin the call if should - * EVENT_BEGIN(bindmap, eventid, return returnvalue); - * // push arguments - * Push(L, pPlayer); - * EVENT_EXECUTE(returnedargs); - * FOR_RET(iter) - * { - * // process returned arguments - * } - * ENDCALL(); + * A. If results will be IGNORED: + * + * // Lock out any other threads. + * ELUNA_LOCK(this); + * + * // Push extra arguments, if any. + * Push(a); + * Push(b); + * Push(c); + * + * // Call all event handlers. + * CallAllFunctions(WhateverBindings, SOME_EVENT_TYPE); + * + * + * B. If results will be USED: + * + * // Lock out any other threads. + * ELUNA_LOCK(this); + * + * // Push extra arguments, if any. + * Push(a); + * Push(b); + * Push(c); + * + * // Setup the stack and get the number of functions pushed. + * // Last argument is 3 because we did 3 Pushes. + * int n = SetupStack(WhateverBindings, SOME_EVENT_TYPE, 3); + * + * // Call each event handler in order and check results. + * while (n > 0) + * { + * // Call an event handler and decrement the function counter afterward. + * // Second-last argument is 3 because we did 3 Pushes. + * // Last argument is 2 because we want 2 results. + * int r = CallOneFunction(n--, 3, 2); + * + * // Results can be popped using `r`. + * int first = CHECKVAL(L, r + 0); + * int second = CHECKVAL(L, r + 1); + * + * // Pop the results off the stack. + * lua_pop(L, 2); + * } + * + * // Clean-up the stack. Argument is 3 because we did 3 Pushes. + * CleanUpStack(3); */ -// RET is a return statement -#define EVENT_BEGIN(BINDMAP, EVENT, RET) \ - if (!BINDMAP->HasEvents(EVENT)) \ - RET; \ - ELUNA_LOCK(this); \ - const char* _LuaBindType = this->BINDMAP->groupName; \ - uint32 _LuaEvent = EVENT; \ - int _LuaStackTop = lua_gettop(L); \ - this->BINDMAP->PushFuncRefs(L, _LuaEvent); \ - int _LuaFuncTop = lua_gettop(L); \ - int _LuaFuncCount = _LuaFuncTop-_LuaStackTop; \ - Eluna::Push(L, _LuaEvent); +/* + * Sets up the stack so that event handlers can be called. + * + * Returns the number of functions that were pushed onto the stack. + * + * Use the simpler overloads for just EventBind or EntryBind instead of this overload in hooks. + */ +template +int Eluna::SetupStack(EventBind* event_bindings, EntryBind* entry_bindings, T event_id, uint32 entry, int number_of_arguments) +{ + // Ensure that if `entry_bindings` is not NULL, a valid entry is supplied. + ASSERT(!entry_bindings || (entry_bindings && entry > 0)); + ASSERT(number_of_arguments == this->push_counter); + // Stack: [arguments] -// use LUA_MULTRET for multiple return values -// return values will be at top of stack if any -#define EVENT_EXECUTE(RETVALS) \ - int _LuaReturnValues = RETVALS; \ - int _LuaParams = lua_gettop(L) - _LuaFuncTop; \ - if (_LuaParams < 1) \ - { \ - ELUNA_LOG_ERROR("[Eluna]: Executing event %u for %s, params was %i. Report to devs", _LuaEvent, _LuaBindType, _LuaParams); \ - } \ - for (int j = _LuaFuncTop-_LuaStackTop; j > 0; --j) \ - { \ - for (int i = 0; i <= _LuaParams; ++i) \ - lua_pushvalue(L, _LuaFuncTop+i); \ - Eluna::ExecuteCall(_LuaParams, _LuaReturnValues); \ - lua_remove(L, _LuaFuncTop--); \ - } \ - for (int i = _LuaParams; i > 0; --i) \ - if (!lua_isnone(L, i)) \ - lua_remove(L, i); + Push((int)event_id); + this->push_counter = 0; + ++number_of_arguments; + // Stack: [arguments], event_id -// RET is a return statement -#define ENTRY_BEGIN(BINDMAP, ENTRY, EVENT, RET) \ - if (!BINDMAP->HasEvents(ENTRY, EVENT)) \ - RET; \ - ELUNA_LOCK(this); \ - const char* _LuaBindType = this->BINDMAP->groupName; \ - uint32 _LuaEvent = EVENT; \ - int _LuaStackTop = lua_gettop(L); \ - this->BINDMAP->PushFuncRefs(L, _LuaEvent, ENTRY); \ - int _LuaFuncTop = lua_gettop(L); \ - int _LuaFuncCount = _LuaFuncTop-_LuaStackTop; \ - Eluna::Push(L, _LuaEvent); + int arguments_top = lua_gettop(L); + int first_argument_index = arguments_top - number_of_arguments + 1; + ASSERT(arguments_top >= number_of_arguments); -#define ENTRY_EXECUTE(RETVALS) \ - int _LuaReturnValues = RETVALS; \ - int _LuaParams = lua_gettop(L) - _LuaFuncTop; \ - if (_LuaParams < 2) \ - { \ - ELUNA_LOG_ERROR("[Eluna]: Executing event %u for %s, params was %i. Report to devs", _LuaEvent, _LuaBindType, _LuaParams); \ - } \ - for (int j = _LuaFuncTop-_LuaStackTop; j > 0; --j) \ - { \ - for (int i = 0; i <= _LuaParams; ++i) \ - lua_pushvalue(L, _LuaFuncTop+i); \ - Eluna::ExecuteCall(_LuaParams, _LuaReturnValues); \ - lua_remove(L, _LuaFuncTop--); \ - } \ - for (int i = _LuaParams; i > 0; --i) \ - if (!lua_isnone(L, i)) \ - lua_remove(L, i); + lua_insert(L, first_argument_index); + // Stack: event_id, [arguments] -#define FOR_RETS(IT) \ - for (int IT = _LuaStackTop + 1; IT <= lua_gettop(L); ++IT) + if (event_bindings) + event_bindings->PushFuncRefs(L, (int)event_id); -#define ENDCALL() \ - if (lua_gettop(L) < _LuaStackTop) \ - { \ - ELUNA_LOG_ERROR("[Eluna]: Ending event %u for %s, stack top was %i and was supposed to be >= %i. Report to devs", _LuaEvent, _LuaBindType, lua_gettop(L), _LuaStackTop); \ - } \ - if (_LuaReturnValues != LUA_MULTRET && lua_gettop(L) > _LuaStackTop + _LuaFuncCount * _LuaReturnValues) \ - { \ - ELUNA_LOG_ERROR("[Eluna]: Ending event %u for %s, stack top was %i and was supposed to be between %i and %i. Report to devs", _LuaEvent, _LuaBindType, lua_gettop(L), _LuaStackTop, _LuaStackTop + _LuaFuncCount * _LuaReturnValues); \ - } \ - lua_settop(L, _LuaStackTop); \ - if (!this->event_level) \ - this->InvalidateObjects(); // Invalidate objects on outermost hook call + if (entry_bindings) + entry_bindings->PushFuncRefs(L, (int)event_id, entry); + // Stack: event_id, [arguments], [functions] + + int number_of_functions = lua_gettop(L) - arguments_top; + return number_of_functions; +} + +/* + * Call a single event handler that was put on the stack with `Setup` and removes it from the stack. + * + * The caller is responsible for keeping track of how many times this should be called. + */ +int Eluna::CallOneFunction(int number_of_functions, int number_of_arguments, int number_of_results) +{ + ++number_of_arguments; // Caller doesn't know about `event_id`. + ASSERT(number_of_functions > 0 && number_of_results >= 0); + // Stack: event_id, [arguments], [functions] + + int functions_top = lua_gettop(L); + int first_function_index = functions_top - number_of_functions + 1; + int arguments_top = first_function_index - 1; + int first_argument_index = arguments_top - number_of_arguments + 1; + + // Copy the arguments from the bottom of the stack to the top. + for (int argument_index = first_argument_index; argument_index <= arguments_top; ++argument_index) + { + lua_pushvalue(L, argument_index); + } + // Stack: event_id, [arguments], [functions], event_id, [arguments] + + ExecuteCall(number_of_arguments, number_of_results); + // Stack: event_id, [arguments], [functions - 1], [results] + + return functions_top + 1; // Return the location of the first result. +} + +/* + * Cleans up the stack, effectively undoing all Push calls and the Setup call. + */ +void Eluna::CleanUpStack(int number_of_arguments) +{ + // Stack: event_id, [arguments] + lua_pop(L, number_of_arguments + 1); // Add 1 because the caller doesn't know about `event_id`. + // Stack: (empty) +} + +/* + * Call all event handlers registered to the event ID/entry combination and ignore any results. + */ +template +void Eluna::CallAllFunctions(EventBind* event_bindings, EntryBind* entry_bindings, T event_id, uint32 entry) +{ + int number_of_arguments = this->push_counter; + // Stack: [arguments] + + int number_of_functions = SetupStack(event_bindings, entry_bindings, event_id, entry, number_of_arguments); + // Stack: event_id, [arguments], [functions] + + while (number_of_functions > 0) + { + CallOneFunction(number_of_functions, number_of_arguments, 0); + --number_of_functions; + // Stack: event_id, [arguments], [functions - 1] + } + // Stack: event_id, [arguments] + + CleanUpStack(number_of_arguments); + // Stack: (empty) +} + +/* + * Call all event handlers registered to the event ID/entry combination, + * and returns `default_value` if ALL event handlers returned `default_value`, + * otherwise returns the opposite of `default_value`. + */ +template +bool Eluna::CallAllFunctionsBool(EventBind* event_bindings, EntryBind* entry_bindings, T event_id, uint32 entry, bool default_value) +{ + bool result = default_value; + int number_of_arguments = this->push_counter; + // Stack: [arguments] + + int number_of_functions = SetupStack(event_bindings, entry_bindings, event_id, entry, number_of_arguments); + // Stack: event_id, [arguments], [functions] + + while (number_of_functions > 0) + { + int r = CallOneFunction(number_of_functions, number_of_arguments, 1); + --number_of_functions; + // Stack: event_id, [arguments], [functions - 1], result + + if (lua_isboolean(L, r) && (bool)lua_toboolean(L, r) != default_value) + result = !default_value; + + lua_pop(L, 1); + // Stack: event_id, [arguments], [functions - 1] + } + // Stack: event_id, [arguments] + + CleanUpStack(number_of_arguments); + // Stack: (empty) + return result; +} void Eluna::OnLuaStateClose() { - EVENT_BEGIN(ServerEventBindings, ELUNA_EVENT_ON_LUA_STATE_CLOSE, return); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + CallAllFunctions(ServerEventBindings, ELUNA_EVENT_ON_LUA_STATE_CLOSE); } void Eluna::OnLuaStateOpen() { - EVENT_BEGIN(ServerEventBindings, ELUNA_EVENT_ON_LUA_STATE_OPEN, return); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + CallAllFunctions(ServerEventBindings, ELUNA_EVENT_ON_LUA_STATE_OPEN); } // areatrigger bool Eluna::OnAreaTrigger(Player* pPlayer, AreaTriggerEntry const* pTrigger) { - EVENT_BEGIN(ServerEventBindings, TRIGGER_EVENT_ON_TRIGGER, return false); - Push(L, pPlayer); - Push(L, pTrigger->id); - EVENT_EXECUTE(0); - ENDCALL(); - return false; + ELUNA_LOCK(this); + Push(pPlayer); + Push(pTrigger->id); + return CallAllFunctionsBool(ServerEventBindings, TRIGGER_EVENT_ON_TRIGGER); } // weather void Eluna::OnChange(Weather* weather, WeatherState state, float grade) { - EVENT_BEGIN(ServerEventBindings, WEATHER_EVENT_ON_CHANGE, return); - Push(L, weather->GetZone()); - Push(L, state); - Push(L, grade); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(weather->GetZone()); + Push(state); + Push(grade); + CallAllFunctions(ServerEventBindings, WEATHER_EVENT_ON_CHANGE); } // Auction House void Eluna::OnAdd(AuctionHouseObject* ah) { - EVENT_BEGIN(ServerEventBindings, AUCTION_EVENT_ON_ADD, return); - Push(L, (ah)); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(ah); + CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_ADD); } void Eluna::OnRemove(AuctionHouseObject* ah) { - EVENT_BEGIN(ServerEventBindings, AUCTION_EVENT_ON_REMOVE, return); - Push(L, (ah)); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(ah); + CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_REMOVE); } void Eluna::OnSuccessful(AuctionHouseObject* ah) { - EVENT_BEGIN(ServerEventBindings, AUCTION_EVENT_ON_SUCCESSFUL, return); - Push(L, (ah)); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(ah); + CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_SUCCESSFUL); } void Eluna::OnExpire(AuctionHouseObject* ah) { - EVENT_BEGIN(ServerEventBindings, AUCTION_EVENT_ON_EXPIRE, return); - Push(L, (ah)); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(ah); + CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_EXPIRE); } // Packet bool Eluna::OnPacketSend(WorldSession* session, WorldPacket& packet) { + ELUNA_LOCK(this); bool result = true; Player* player = NULL; if (session) @@ -202,49 +285,54 @@ bool Eluna::OnPacketSend(WorldSession* session, WorldPacket& packet) } void Eluna::OnPacketSendAny(Player* player, WorldPacket& packet, bool& result) { - EVENT_BEGIN(ServerEventBindings, SERVER_EVENT_ON_PACKET_SEND, return); - Push(L, new WorldPacket(packet)); - Push(L, player); - EVENT_EXECUTE(2); - FOR_RETS(i) + ELUNA_LOCK(this); + Push(new WorldPacket(packet)); + Push(player); + int n = SetupStack(ServerEventBindings, SERVER_EVENT_ON_PACKET_SEND, 2); + + while (n > 0) { - if (lua_isnoneornil(L, i)) - continue; - if (lua_isuserdata(L, i)) - if (WorldPacket* data = CHECKOBJ(L, i, false)) - packet = *data; - if (lua_isboolean(L, i) && !CHECKVAL(L, i, true)) - { + int r = CallOneFunction(n--, 2, 2); + + if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) result = false; - break; - } + + if (lua_isuserdata(L, r + 1)) + if (WorldPacket* data = CHECKOBJ(L, r + 1, true)) + packet = *data; + + lua_pop(L, 2); } - ENDCALL(); + + CleanUpStack(2); } void Eluna::OnPacketSendOne(Player* player, WorldPacket& packet, bool& result) { - ENTRY_BEGIN(PacketEventBindings, OpcodesList(packet.GetOpcode()), PACKET_EVENT_ON_PACKET_SEND, return); - Push(L, new WorldPacket(packet)); - Push(L, player); - ENTRY_EXECUTE(2); - FOR_RETS(i) + ELUNA_LOCK(this); + Push(new WorldPacket(packet)); + Push(player); + int n = SetupStack(PacketEventBindings, PACKET_EVENT_ON_PACKET_SEND, OpcodesList(packet.GetOpcode()), 2); + + while (n > 0) { - if (lua_isnoneornil(L, i)) - continue; - if (lua_isuserdata(L, i)) - if (WorldPacket* data = CHECKOBJ(L, i, false)) - packet = *data; - if (lua_isboolean(L, i) && !CHECKVAL(L, i, true)) - { + int r = CallOneFunction(n--, 2, 2); + + if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) result = false; - break; - } + + if (lua_isuserdata(L, r + 1)) + if (WorldPacket* data = CHECKOBJ(L, r + 1, true)) + packet = *data; + + lua_pop(L, 2); } - ENDCALL(); + + CleanUpStack(2); } bool Eluna::OnPacketReceive(WorldSession* session, WorldPacket& packet) { + ELUNA_LOCK(this); bool result = true; Player* player = NULL; if (session) @@ -255,105 +343,105 @@ bool Eluna::OnPacketReceive(WorldSession* session, WorldPacket& packet) } void Eluna::OnPacketReceiveAny(Player* player, WorldPacket& packet, bool& result) { - EVENT_BEGIN(ServerEventBindings, SERVER_EVENT_ON_PACKET_RECEIVE, return); - Push(L, new WorldPacket(packet)); - Push(L, player); - EVENT_EXECUTE(2); - FOR_RETS(i) + ELUNA_LOCK(this); + Push(new WorldPacket(packet)); + Push(player); + int n = SetupStack(ServerEventBindings, SERVER_EVENT_ON_PACKET_RECEIVE, 2); + + while (n > 0) { - if (lua_isnoneornil(L, i)) - continue; - if (lua_isuserdata(L, i)) - if (WorldPacket* data = CHECKOBJ(L, i, false)) - packet = *data; - if (lua_isboolean(L, i) && !CHECKVAL(L, i, true)) - { + int r = CallOneFunction(n--, 2, 2); + + if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) result = false; - break; - } + + if (lua_isuserdata(L, r + 1)) + if (WorldPacket* data = CHECKOBJ(L, r + 1, true)) + packet = *data; + + lua_pop(L, 2); } - ENDCALL(); + + CleanUpStack(2); } void Eluna::OnPacketReceiveOne(Player* player, WorldPacket& packet, bool& result) { - ENTRY_BEGIN(PacketEventBindings, OpcodesList(packet.GetOpcode()), PACKET_EVENT_ON_PACKET_RECEIVE, return); - Push(L, new WorldPacket(packet)); - Push(L, player); - ENTRY_EXECUTE(2); - FOR_RETS(i) + ELUNA_LOCK(this); + Push(new WorldPacket(packet)); + Push(player); + int n = SetupStack(PacketEventBindings, PACKET_EVENT_ON_PACKET_RECEIVE, OpcodesList(packet.GetOpcode()), 2); + + while (n > 0) { - if (lua_isnoneornil(L, i)) - continue; - if (lua_isuserdata(L, i)) - if (WorldPacket* data = CHECKOBJ(L, i, false)) - packet = *data; - if (lua_isboolean(L, i) && !CHECKVAL(L, i, true)) - { + int r = CallOneFunction(n--, 2, 2); + + if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) result = false; - break; - } + + if (lua_isuserdata(L, r + 1)) + if (WorldPacket* data = CHECKOBJ(L, r + 1, true)) + packet = *data; + + lua_pop(L, 2); } - ENDCALL(); + + CleanUpStack(2); } // AddOns bool Eluna::OnAddonMessage(Player* sender, uint32 type, std::string& msg, Player* receiver, Guild* guild, Group* group, Channel* channel) { - EVENT_BEGIN(ServerEventBindings, ADDON_EVENT_ON_MESSAGE, return false); - Push(L, sender); - Push(L, type); + ELUNA_LOCK(this); + Push(sender); + Push(type); const char* c_msg = msg.c_str(); - Push(L, strtok((char*)c_msg, "\t")); // prefix - Push(L, strtok(NULL, "")); // msg + Push(strtok((char*)c_msg, "\t")); // prefix + Push(strtok(NULL, "")); // msg if (receiver) - Push(L, receiver); + Push(receiver); else if (guild) - Push(L, guild); + Push(guild); else if (group) - Push(L, group); + Push(group); else if (channel) - Push(L, channel->GetChannelId()); + Push(channel->GetChannelId()); else - Push(L); - EVENT_EXECUTE(0); - ENDCALL(); - return true; + Push(); + + return CallAllFunctionsBool(ServerEventBindings, ADDON_EVENT_ON_MESSAGE, true); } void Eluna::OnOpenStateChange(bool open) { - EVENT_BEGIN(ServerEventBindings, WORLD_EVENT_ON_OPEN_STATE_CHANGE, return); - Push(L, open); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(open); + CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_OPEN_STATE_CHANGE); } void Eluna::OnConfigLoad(bool reload) { - EVENT_BEGIN(ServerEventBindings, WORLD_EVENT_ON_CONFIG_LOAD, return); - Push(L, reload); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(reload); + CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_CONFIG_LOAD); } void Eluna::OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask) { - EVENT_BEGIN(ServerEventBindings, WORLD_EVENT_ON_SHUTDOWN_INIT, return); - Push(L, code); - Push(L, mask); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(code); + Push(mask); + CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_SHUTDOWN_INIT); } void Eluna::OnShutdownCancel() { - EVENT_BEGIN(ServerEventBindings, WORLD_EVENT_ON_SHUTDOWN_CANCEL, return); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_SHUTDOWN_CANCEL); } void Eluna::OnWorldUpdate(uint32 diff) { + ELUNA_LOCK(this); if (reload) { ReloadEluna(); @@ -362,84 +450,79 @@ void Eluna::OnWorldUpdate(uint32 diff) eventMgr->globalProcessor->Update(diff); - EVENT_BEGIN(ServerEventBindings, WORLD_EVENT_ON_UPDATE, return); - Push(L, diff); - EVENT_EXECUTE(0); - ENDCALL(); + Push(diff); + CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_UPDATE); } void Eluna::OnStartup() { - EVENT_BEGIN(ServerEventBindings, WORLD_EVENT_ON_STARTUP, return); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_STARTUP); } void Eluna::OnShutdown() { - EVENT_BEGIN(ServerEventBindings, WORLD_EVENT_ON_SHUTDOWN, return); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_SHUTDOWN); } void Eluna::HandleGossipSelectOption(Player* pPlayer, Item* item, uint32 sender, uint32 action, const std::string& code) { - ENTRY_BEGIN(ItemGossipBindings, item->GetEntry(), GOSSIP_EVENT_ON_SELECT, return); + ELUNA_LOCK(this); pPlayer->PlayerTalkClass->ClearMenus(); - Push(L, pPlayer); - Push(L, item); - Push(L, sender); - Push(L, action); + + Push(pPlayer); + Push(item); + Push(sender); + Push(action); if (code.empty()) - Push(L); + Push(); else - Push(L, code); - ENTRY_EXECUTE(0); - ENDCALL(); + Push(code); + + CallAllFunctions(ItemGossipBindings, GOSSIP_EVENT_ON_SELECT, item->GetEntry()); } void Eluna::HandleGossipSelectOption(Player* pPlayer, uint32 menuId, uint32 sender, uint32 action, const std::string& code) { - ENTRY_BEGIN(playerGossipBindings, menuId, GOSSIP_EVENT_ON_SELECT, return); + ELUNA_LOCK(this); pPlayer->PlayerTalkClass->ClearMenus(); - Push(L, pPlayer); // receiver - Push(L, pPlayer); // sender, just not to mess up the amount of args. - Push(L, sender); - Push(L, action); + + Push(pPlayer); // receiver + Push(pPlayer); // sender, just not to mess up the amount of args. + Push(sender); + Push(action); if (code.empty()) - Push(L); + Push(); else - Push(L, code); - ENTRY_EXECUTE(0); - ENDCALL(); + Push(code); + + CallAllFunctions(playerGossipBindings, GOSSIP_EVENT_ON_SELECT, menuId); } // item bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, Item* pTarget) { - ENTRY_BEGIN(ItemEventBindings, pTarget->GetEntry(), ITEM_EVENT_ON_DUMMY_EFFECT, return false); - Push(L, pCaster); - Push(L, spellId); - Push(L, effIndex); - Push(L, pTarget); - ENTRY_EXECUTE(0); - ENDCALL(); - return true; + ELUNA_LOCK(this); + Push(pCaster); + Push(spellId); + Push(effIndex); + Push(pTarget); + return CallAllFunctionsBool(ItemEventBindings, ITEM_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry()); } bool Eluna::OnQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest) { - ENTRY_BEGIN(ItemEventBindings, pItem->GetEntry(), ITEM_EVENT_ON_QUEST_ACCEPT, return false); - Push(L, pPlayer); - Push(L, pItem); - Push(L, pQuest); - ENTRY_EXECUTE(0); - ENDCALL(); - return true; + ELUNA_LOCK(this); + Push(pPlayer); + Push(pItem); + Push(pQuest); + return CallAllFunctionsBool(ItemEventBindings, ITEM_EVENT_ON_QUEST_ACCEPT, pItem->GetEntry()); } bool Eluna::OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) { + ELUNA_LOCK(this); ObjectGuid guid = pItem->GET_GUID(); bool castSpell = true; @@ -470,85 +553,67 @@ bool Eluna::OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) bool Eluna::OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) { - bool result = true; - ENTRY_BEGIN(ItemEventBindings, pItem->GetEntry(), ITEM_EVENT_ON_USE, return result); - Push(L, pPlayer); - Push(L, pItem); + ELUNA_LOCK(this); + Push(pPlayer); + Push(pItem); #ifndef TRINITY if (GameObject* target = targets.getGOTarget()) - Push(L, target); + Push(target); else if (Item* target = targets.getItemTarget()) - Push(L, target); + Push(target); else if (Corpse* target = pPlayer->GetMap()->GetCorpse(targets.getCorpseTargetGuid())) - Push(L, target); + Push(target); else if (Unit* target = targets.getUnitTarget()) - Push(L, target); + Push(target); else - Push(L); + Push(); #else if (GameObject* target = targets.GetGOTarget()) - Push(L, target); + Push(target); else if (Item* target = targets.GetItemTarget()) - Push(L, target); + Push(target); else if (Corpse* target = targets.GetCorpseTarget()) - Push(L, target); + Push(target); else if (Unit* target = targets.GetUnitTarget()) - Push(L, target); + Push(target); else if (WorldObject* target = targets.GetObjectTarget()) - Push(L, target); + Push(target); else - Push(L); + Push(); #endif - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, result); - } - ENDCALL(); - return result; + + return CallAllFunctionsBool(ItemEventBindings, ITEM_EVENT_ON_USE, pItem->GetEntry()); } bool Eluna::OnItemGossip(Player* pPlayer, Item* pItem, SpellCastTargets const& /*targets*/) { - bool result = true; - ENTRY_BEGIN(ItemGossipBindings, pItem->GetEntry(), GOSSIP_EVENT_ON_HELLO, return result); + ELUNA_LOCK(this); pPlayer->PlayerTalkClass->ClearMenus(); - Push(L, pPlayer); - Push(L, pItem); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, result); - } - ENDCALL(); - return result; + Push(pPlayer); + Push(pItem); + return CallAllFunctionsBool(ItemGossipBindings, GOSSIP_EVENT_ON_HELLO, pItem->GetEntry()); } bool Eluna::OnExpire(Player* pPlayer, ItemTemplate const* pProto) { - ENTRY_BEGIN(ItemEventBindings, pProto->ItemId, ITEM_EVENT_ON_EXPIRE, return false); - Push(L, pPlayer); - Push(L, pProto->ItemId); - ENTRY_EXECUTE(0); - ENDCALL(); - return true; + ELUNA_LOCK(this); + Push(pPlayer); + Push(pProto->ItemId); + return CallAllFunctionsBool(ItemEventBindings, ITEM_EVENT_ON_EXPIRE, pProto->ItemId); } bool Eluna::OnRemove(Player* pPlayer, Item* item) { - ENTRY_BEGIN(ItemEventBindings, item->GetEntry(), ITEM_EVENT_ON_REMOVE, return false); - Push(L, pPlayer); - Push(L, item); - ENTRY_EXECUTE(0); - ENDCALL(); - return true; + ELUNA_LOCK(this); + Push(pPlayer); + Push(item); + return CallAllFunctionsBool(ItemEventBindings, ITEM_EVENT_ON_REMOVE, item->GetEntry()); } // Player bool Eluna::OnCommand(Player* player, const char* text) { + ELUNA_LOCK(this); // If from console, player is NULL std::string fullcmd(text); if (!player || player->GetSession()->GetSecurity() >= SEC_ADMINISTRATOR) @@ -572,511 +637,479 @@ bool Eluna::OnCommand(Player* player, const char* text) } } - bool result = true; - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_COMMAND, return result); - Push(L, player); - Push(L, fullcmd); - EVENT_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, result); - } - ENDCALL(); - return result; + Push(player); + Push(fullcmd); + return CallAllFunctionsBool(PlayerEventBindings, PLAYER_EVENT_ON_COMMAND, true); } void Eluna::OnLootItem(Player* pPlayer, Item* pItem, uint32 count, uint64 guid) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_LOOT_ITEM, return); - Push(L, pPlayer); - Push(L, pItem); - Push(L, count); - Push(L, guid); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + Push(pItem); + Push(count); + Push(guid); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LOOT_ITEM); } void Eluna::OnLootMoney(Player* pPlayer, uint32 amount) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_LOOT_MONEY, return); - Push(L, pPlayer); - Push(L, amount); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + Push(amount); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LOOT_MONEY); } void Eluna::OnFirstLogin(Player* pPlayer) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_FIRST_LOGIN, return); - Push(L, pPlayer); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_FIRST_LOGIN); } void Eluna::OnRepop(Player* pPlayer) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_REPOP, return); - Push(L, pPlayer); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_REPOP); } void Eluna::OnResurrect(Player* pPlayer) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_RESURRECT, return); - Push(L, pPlayer); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_RESURRECT); } void Eluna::OnQuestAbandon(Player* pPlayer, uint32 questId) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_QUEST_ABANDON, return); - Push(L, pPlayer); - Push(L, questId); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + Push(questId); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_QUEST_ABANDON); } void Eluna::OnEquip(Player* pPlayer, Item* pItem, uint8 bag, uint8 slot) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_EQUIP, return); - Push(L, pPlayer); - Push(L, pItem); - Push(L, bag); - Push(L, slot); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + Push(pItem); + Push(bag); + Push(slot); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_EQUIP); } InventoryResult Eluna::OnCanUseItem(const Player* pPlayer, uint32 itemEntry) { + ELUNA_LOCK(this); InventoryResult result = EQUIP_ERR_OK; - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_CAN_USE_ITEM, return result); - Push(L, pPlayer); - Push(L, itemEntry); - EVENT_EXECUTE(1); - FOR_RETS(i) + Push(pPlayer); + Push(itemEntry); + int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_CAN_USE_ITEM, 2); + + while (n > 0) { - if (!lua_isnumber(L, i)) - continue; - uint32 res = CHECKVAL(L, i, EQUIP_ERR_OK); - if (res != EQUIP_ERR_OK) - result = (InventoryResult)res; + int r = CallOneFunction(n--, 2, 1); + + if (lua_isnumber(L, r)) + result = (InventoryResult)CHECKVAL(L, r); + + lua_pop(L, 1); } - ENDCALL(); + + CleanUpStack(2); return result; } void Eluna::OnPlayerEnterCombat(Player* pPlayer, Unit* pEnemy) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_ENTER_COMBAT, return); - Push(L, pPlayer); - Push(L, pEnemy); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + Push(pEnemy); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_ENTER_COMBAT); } void Eluna::OnPlayerLeaveCombat(Player* pPlayer) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_LEAVE_COMBAT, return); - Push(L, pPlayer); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LEAVE_COMBAT); } void Eluna::OnPVPKill(Player* pKiller, Player* pKilled) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_KILL_PLAYER, return); - Push(L, pKiller); - Push(L, pKilled); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pKiller); + Push(pKilled); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_KILL_PLAYER); } void Eluna::OnCreatureKill(Player* pKiller, Creature* pKilled) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_KILL_CREATURE, return); - Push(L, pKiller); - Push(L, pKilled); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pKiller); + Push(pKilled); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_KILL_CREATURE); } void Eluna::OnPlayerKilledByCreature(Creature* pKiller, Player* pKilled) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_KILLED_BY_CREATURE, return); - Push(L, pKiller); - Push(L, pKilled); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pKiller); + Push(pKilled); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_KILLED_BY_CREATURE); } void Eluna::OnLevelChanged(Player* pPlayer, uint8 oldLevel) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_LEVEL_CHANGE, return); - Push(L, pPlayer); - Push(L, oldLevel); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + Push(oldLevel); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LEVEL_CHANGE); } void Eluna::OnFreeTalentPointsChanged(Player* pPlayer, uint32 newPoints) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_TALENTS_CHANGE, return); - Push(L, pPlayer); - Push(L, newPoints); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + Push(newPoints); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_TALENTS_CHANGE); } void Eluna::OnTalentsReset(Player* pPlayer, bool noCost) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_TALENTS_RESET, return); - Push(L, pPlayer); - Push(L, noCost); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + Push(noCost); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_TALENTS_RESET); } void Eluna::OnMoneyChanged(Player* pPlayer, int32& amount) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_MONEY_CHANGE, return); - Push(L, pPlayer); - Push(L, amount); - EVENT_EXECUTE(1); - FOR_RETS(i) + ELUNA_LOCK(this); + Push(pPlayer); + Push(amount); + int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_MONEY_CHANGE, 2); + + while (n > 0) { - if (lua_isnumber(L, i)) - amount = CHECKVAL(L, i, amount); + int r = CallOneFunction(n--, 2, 1); + + if (lua_isnumber(L, r)) + amount = CHECKVAL(L, r); + + lua_pop(L, 1); } - ENDCALL(); + + CleanUpStack(2); } void Eluna::OnGiveXP(Player* pPlayer, uint32& amount, Unit* pVictim) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_GIVE_XP, return); - Push(L, pPlayer); - Push(L, amount); - Push(L, pVictim); - EVENT_EXECUTE(1); - FOR_RETS(i) + ELUNA_LOCK(this); + Push(pPlayer); + Push(amount); + Push(pVictim); + int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_GIVE_XP, 3); + + while (n > 0) { - if (lua_isnumber(L, i)) - amount = CHECKVAL(L, i, amount); + int r = CallOneFunction(n--, 3, 1); + + if (lua_isnumber(L, r)) + amount = CHECKVAL(L, r); + + lua_pop(L, 1); } - ENDCALL(); + + CleanUpStack(3); } void Eluna::OnReputationChange(Player* pPlayer, uint32 factionID, int32& standing, bool incremental) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_REPUTATION_CHANGE, return); - Push(L, pPlayer); - Push(L, factionID); - Push(L, standing); - Push(L, incremental); - EVENT_EXECUTE(1); - FOR_RETS(i) + ELUNA_LOCK(this); + Push(pPlayer); + Push(factionID); + Push(standing); + Push(incremental); + int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_REPUTATION_CHANGE, 4); + + while (n > 0) { - if (lua_isnumber(L, i)) - standing = CHECKVAL(L, i, standing); + int r = CallOneFunction(n--, 4, 1); + + if (lua_isnumber(L, r)) + standing = CHECKVAL(L, r); + + lua_pop(L, 1); } - ENDCALL(); + + CleanUpStack(4); } void Eluna::OnDuelRequest(Player* pTarget, Player* pChallenger) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_DUEL_REQUEST, return); - Push(L, pTarget); - Push(L, pChallenger); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pTarget); + Push(pChallenger); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_DUEL_REQUEST); } void Eluna::OnDuelStart(Player* pStarter, Player* pChallenger) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_DUEL_START, return); - Push(L, pStarter); - Push(L, pChallenger); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pStarter); + Push(pChallenger); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_DUEL_START); } void Eluna::OnDuelEnd(Player* pWinner, Player* pLoser, DuelCompleteType type) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_DUEL_END, return); - Push(L, pWinner); - Push(L, pLoser); - Push(L, type); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pWinner); + Push(pLoser); + Push(type); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_DUEL_END); } void Eluna::OnEmote(Player* pPlayer, uint32 emote) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_EMOTE, return); - Push(L, pPlayer); - Push(L, emote); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + Push(emote); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_EMOTE); } void Eluna::OnTextEmote(Player* pPlayer, uint32 textEmote, uint32 emoteNum, uint64 guid) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_TEXT_EMOTE, return); - Push(L, pPlayer); - Push(L, textEmote); - Push(L, emoteNum); - Push(L, guid); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + Push(textEmote); + Push(emoteNum); + Push(guid); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_TEXT_EMOTE); } void Eluna::OnSpellCast(Player* pPlayer, Spell* pSpell, bool skipCheck) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_SPELL_CAST, return); - Push(L, pPlayer); - Push(L, pSpell); - Push(L, skipCheck); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + Push(pSpell); + Push(skipCheck); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_SPELL_CAST); } void Eluna::OnLogin(Player* pPlayer) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_LOGIN, return); - Push(L, pPlayer); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LOGIN); } void Eluna::OnLogout(Player* pPlayer) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_LOGOUT, return); - Push(L, pPlayer); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LOGOUT); } void Eluna::OnCreate(Player* pPlayer) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_CHARACTER_CREATE, return); - Push(L, pPlayer); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_CHARACTER_CREATE); } void Eluna::OnDelete(uint32 guidlow) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_CHARACTER_DELETE, return); - Push(L, guidlow); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(guidlow); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_CHARACTER_DELETE); } void Eluna::OnSave(Player* pPlayer) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_SAVE, return); - Push(L, pPlayer); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_SAVE); } void Eluna::OnBindToInstance(Player* pPlayer, Difficulty difficulty, uint32 mapid, bool permanent) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_BIND_TO_INSTANCE, return); - Push(L, pPlayer); - Push(L, difficulty); - Push(L, mapid); - Push(L, permanent); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + Push(difficulty); + Push(mapid); + Push(permanent); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_BIND_TO_INSTANCE); } void Eluna::OnUpdateZone(Player* pPlayer, uint32 newZone, uint32 newArea) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_UPDATE_ZONE, return); - Push(L, pPlayer); - Push(L, newZone); - Push(L, newArea); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + Push(newZone); + Push(newArea); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_UPDATE_ZONE); } void Eluna::OnMapChanged(Player* player) { - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_MAP_CHANGE, return); - Push(L, player); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(player); + CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_MAP_CHANGE); } bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg) { + ELUNA_LOCK(this); if (lang == LANG_ADDON) - { - OnAddonMessage(pPlayer, type, msg, NULL, NULL, NULL, NULL); - return true; - } + return OnAddonMessage(pPlayer, type, msg, NULL, NULL, NULL, NULL); + bool result = true; - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_CHAT, return result); - Push(L, pPlayer); - Push(L, msg); - Push(L, type); - Push(L, lang); - EVENT_EXECUTE(2); - FOR_RETS(i) + Push(pPlayer); + Push(msg); + Push(type); + Push(lang); + int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_CHAT, 4); + + while (n > 0) { - if (lua_isnoneornil(L, i)) - continue; - if (lua_isstring(L, i)) - { - if (const char* c_str = CHECKVAL(L, i, NULL)) - msg = std::string(c_str); - } - else if (lua_isboolean(L, i) && !CHECKVAL(L, i, true)) - { + int r = CallOneFunction(n--, 4, 2); + + if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) result = false; - break; - } + + if (lua_isstring(L, r + 1)) + msg = std::string(lua_tostring(L, r + 1)); + + lua_pop(L, 2); } - ENDCALL(); + + CleanUpStack(4); return result; } bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Group* pGroup) { + ELUNA_LOCK(this); if (lang == LANG_ADDON) - { - OnAddonMessage(pPlayer, type, msg, NULL, NULL, pGroup, NULL); - return true; - } + return OnAddonMessage(pPlayer, type, msg, NULL, NULL, pGroup, NULL); + bool result = true; - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_GROUP_CHAT, return result); - Push(L, pPlayer); - Push(L, msg); - Push(L, type); - Push(L, lang); - Push(L, pGroup); - EVENT_EXECUTE(2); - FOR_RETS(i) + Push(pPlayer); + Push(msg); + Push(type); + Push(lang); + Push(pGroup); + int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_GROUP_CHAT, 5); + + while (n > 0) { - if (lua_isnoneornil(L, i)) - continue; - if (lua_isstring(L, i)) - { - if (const char* c_str = CHECKVAL(L, i, NULL)) - msg = std::string(c_str); - } - else if (lua_isboolean(L, i) && !CHECKVAL(L, i, true)) - { + int r = CallOneFunction(n--, 5, 2); + + if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) result = false; - break; - } + + if (lua_isstring(L, r + 1)) + msg = std::string(lua_tostring(L, r + 1)); + + lua_pop(L, 2); } - ENDCALL(); + + CleanUpStack(5); return result; } bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Guild* pGuild) { + ELUNA_LOCK(this); if (lang == LANG_ADDON) - { - OnAddonMessage(pPlayer, type, msg, NULL, pGuild, NULL, NULL); - return true; - } + return OnAddonMessage(pPlayer, type, msg, NULL, pGuild, NULL, NULL); + bool result = true; - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_GUILD_CHAT, return result); - Push(L, pPlayer); - Push(L, msg); - Push(L, type); - Push(L, lang); - Push(L, pGuild); - EVENT_EXECUTE(2); - FOR_RETS(i) + Push(pPlayer); + Push(msg); + Push(type); + Push(lang); + Push(pGuild); + int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_GUILD_CHAT, 5); + + while (n > 0) { - if (lua_isnoneornil(L, i)) - continue; - if (lua_isstring(L, i)) - { - if (const char* c_str = CHECKVAL(L, i, NULL)) - msg = std::string(c_str); - } - else if (lua_isboolean(L, i) && !CHECKVAL(L, i, true)) - { + int r = CallOneFunction(n--, 5, 2); + + if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) result = false; - break; - } + + if (lua_isstring(L, r + 1)) + msg = std::string(lua_tostring(L, r + 1)); + + lua_pop(L, 2); } - ENDCALL(); + + CleanUpStack(5); return result; } bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Channel* pChannel) { + ELUNA_LOCK(this); if (lang == LANG_ADDON) - { - OnAddonMessage(pPlayer, type, msg, NULL, NULL, NULL, pChannel); - return true; - } + return OnAddonMessage(pPlayer, type, msg, NULL, NULL, NULL, pChannel); + bool result = true; - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_CHANNEL_CHAT, return result); - Push(L, pPlayer); - Push(L, msg); - Push(L, type); - Push(L, lang); - Push(L, pChannel->GetChannelId()); - EVENT_EXECUTE(2); - FOR_RETS(i) + Push(pPlayer); + Push(msg); + Push(type); + Push(lang); + Push(pChannel->GetChannelId()); + int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_CHANNEL_CHAT, 5); + + while (n > 0) { - if (lua_isnoneornil(L, i)) - continue; - if (lua_isstring(L, i)) - { - if (const char* c_str = CHECKVAL(L, i, NULL)) - msg = std::string(c_str); - } - else if (lua_isboolean(L, i) && !CHECKVAL(L, i, true)) - { + int r = CallOneFunction(n--, 5, 2); + + if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) result = false; - break; - } + + if (lua_isstring(L, r + 1)) + msg = std::string(lua_tostring(L, r + 1)); + + lua_pop(L, 2); } - ENDCALL(); + + CleanUpStack(5); return result; } bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Player* pReceiver) { + ELUNA_LOCK(this); if (lang == LANG_ADDON) - { - OnAddonMessage(pPlayer, type, msg, pReceiver, NULL, NULL, NULL); - return true; - } + return OnAddonMessage(pPlayer, type, msg, pReceiver, NULL, NULL, NULL); + bool result = true; - EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_WHISPER, return result); - Push(L, pPlayer); - Push(L, msg); - Push(L, type); - Push(L, lang); - Push(L, pReceiver); - EVENT_EXECUTE(2); - FOR_RETS(i) + Push(pPlayer); + Push(msg); + Push(type); + Push(lang); + Push(pReceiver); + int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_WHISPER, 5); + + while (n > 0) { - if (lua_isnoneornil(L, i)) - continue; - if (lua_isstring(L, i)) - { - if (const char* c_str = CHECKVAL(L, i, NULL)) - msg = std::string(c_str); - } - else if (lua_isboolean(L, i) && !CHECKVAL(L, i, true)) - { + int r = CallOneFunction(n--, 5, 2); + + if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) result = false; - break; - } + + if (lua_isstring(L, r + 1)) + msg = std::string(lua_tostring(L, r + 1)); + + lua_pop(L, 2); } - ENDCALL(); + + CleanUpStack(5); return result; } @@ -1085,782 +1118,605 @@ bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, // Vehicle void Eluna::OnInstall(Vehicle* vehicle) { - EVENT_BEGIN(VehicleEventBindings, VEHICLE_EVENT_ON_INSTALL, return); - Push(L, vehicle); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(vehicle); + CallAllFunctions(VehicleEventBindings, VEHICLE_EVENT_ON_INSTALL); } void Eluna::OnUninstall(Vehicle* vehicle) { - EVENT_BEGIN(VehicleEventBindings, VEHICLE_EVENT_ON_UNINSTALL, return); - Push(L, vehicle); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(vehicle); + CallAllFunctions(VehicleEventBindings, VEHICLE_EVENT_ON_UNINSTALL); } void Eluna::OnInstallAccessory(Vehicle* vehicle, Creature* accessory) { - EVENT_BEGIN(VehicleEventBindings, VEHICLE_EVENT_ON_INSTALL_ACCESSORY, return); - Push(L, vehicle); - Push(L, accessory); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(vehicle); + Push(accessory); + CallAllFunctions(VehicleEventBindings, VEHICLE_EVENT_ON_INSTALL_ACCESSORY); } void Eluna::OnAddPassenger(Vehicle* vehicle, Unit* passenger, int8 seatId) { - EVENT_BEGIN(VehicleEventBindings, VEHICLE_EVENT_ON_ADD_PASSENGER, return); - Push(L, vehicle); - Push(L, passenger); - Push(L, seatId); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(vehicle); + Push(passenger); + Push(seatId); + CallAllFunctions(VehicleEventBindings, VEHICLE_EVENT_ON_ADD_PASSENGER); } void Eluna::OnRemovePassenger(Vehicle* vehicle, Unit* passenger) { - EVENT_BEGIN(VehicleEventBindings, VEHICLE_EVENT_ON_REMOVE_PASSENGER, return); - Push(L, vehicle); - Push(L, passenger); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(vehicle); + Push(passenger); + CallAllFunctions(VehicleEventBindings, VEHICLE_EVENT_ON_REMOVE_PASSENGER); } #endif #endif void Eluna::OnAddMember(Guild* guild, Player* player, uint32 plRank) { - EVENT_BEGIN(GuildEventBindings, GUILD_EVENT_ON_ADD_MEMBER, return); - Push(L, guild); - Push(L, player); - Push(L, plRank); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(guild); + Push(player); + Push(plRank); + CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_ADD_MEMBER); } void Eluna::OnRemoveMember(Guild* guild, Player* player, bool isDisbanding) { - EVENT_BEGIN(GuildEventBindings, GUILD_EVENT_ON_REMOVE_MEMBER, return); - Push(L, guild); - Push(L, player); - Push(L, isDisbanding); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(guild); + Push(player); + Push(isDisbanding); + CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_REMOVE_MEMBER); } void Eluna::OnMOTDChanged(Guild* guild, const std::string& newMotd) { - EVENT_BEGIN(GuildEventBindings, GUILD_EVENT_ON_MOTD_CHANGE, return); - Push(L, guild); - Push(L, newMotd); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(guild); + Push(newMotd); + CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_MOTD_CHANGE); } void Eluna::OnInfoChanged(Guild* guild, const std::string& newInfo) { - EVENT_BEGIN(GuildEventBindings, GUILD_EVENT_ON_INFO_CHANGE, return); - Push(L, guild); - Push(L, newInfo); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(guild); + Push(newInfo); + CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_INFO_CHANGE); } void Eluna::OnCreate(Guild* guild, Player* leader, const std::string& name) { - EVENT_BEGIN(GuildEventBindings, GUILD_EVENT_ON_CREATE, return); - Push(L, guild); - Push(L, leader); - Push(L, name); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(guild); + Push(leader); + Push(name); + CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_CREATE); } void Eluna::OnDisband(Guild* guild) { - EVENT_BEGIN(GuildEventBindings, GUILD_EVENT_ON_DISBAND, return); - Push(L, guild); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(guild); + CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_DISBAND); } void Eluna::OnMemberWitdrawMoney(Guild* guild, Player* player, uint32& amount, bool isRepair) // isRepair not a part of Mangos, implement? { - EVENT_BEGIN(GuildEventBindings, GUILD_EVENT_ON_MONEY_WITHDRAW, return); - Push(L, guild); - Push(L, player); - Push(L, amount); - Push(L, isRepair); // isRepair not a part of Mangos, implement? - EVENT_EXECUTE(1); - FOR_RETS(i) + ELUNA_LOCK(this); + Push(guild); + Push(player); + Push(amount); + Push(isRepair); // isRepair not a part of Mangos, implement? + int n = SetupStack(GuildEventBindings, GUILD_EVENT_ON_MONEY_WITHDRAW, 4); + + while (n > 0) { - if (lua_isnumber(L, i)) - amount = CHECKVAL(L, i, amount); + int r = CallOneFunction(n--, 4, 1); + + if (lua_isnumber(L, r)) + amount = CHECKVAL(L, r); + + lua_pop(L, 1); } - ENDCALL(); + + CleanUpStack(4); } void Eluna::OnMemberDepositMoney(Guild* guild, Player* player, uint32& amount) { - EVENT_BEGIN(GuildEventBindings, GUILD_EVENT_ON_MONEY_DEPOSIT, return); - Push(L, guild); - Push(L, player); - Push(L, amount); - EVENT_EXECUTE(1); - FOR_RETS(i) + ELUNA_LOCK(this); + Push(guild); + Push(player); + Push(amount); + int n = SetupStack(GuildEventBindings, GUILD_EVENT_ON_MONEY_DEPOSIT, 3); + + while (n > 0) { - if (lua_isnumber(L, i)) - amount = CHECKVAL(L, i, amount); + int r = CallOneFunction(n--, 3, 1); + + if (lua_isnumber(L, r)) + amount = CHECKVAL(L, r); + + lua_pop(L, 1); } - ENDCALL(); + + CleanUpStack(3); } void Eluna::OnItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank, uint8 srcContainer, uint8 srcSlotId, bool isDestBank, uint8 destContainer, uint8 destSlotId) { - EVENT_BEGIN(GuildEventBindings, GUILD_EVENT_ON_ITEM_MOVE, return); - Push(L, guild); - Push(L, player); - Push(L, pItem); - Push(L, isSrcBank); - Push(L, srcContainer); - Push(L, srcSlotId); - Push(L, isDestBank); - Push(L, destContainer); - Push(L, destSlotId); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(guild); + Push(player); + Push(pItem); + Push(isSrcBank); + Push(srcContainer); + Push(srcSlotId); + Push(isDestBank); + Push(destContainer); + Push(destSlotId); + CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_ITEM_MOVE); } void Eluna::OnEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank) { - EVENT_BEGIN(GuildEventBindings, GUILD_EVENT_ON_EVENT, return); - Push(L, guild); - Push(L, eventType); - Push(L, playerGuid1); - Push(L, playerGuid2); - Push(L, newRank); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(guild); + Push(eventType); + Push(playerGuid1); + Push(playerGuid2); + Push(newRank); + CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_EVENT); } void Eluna::OnBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) { - EVENT_BEGIN(GuildEventBindings, GUILD_EVENT_ON_BANK_EVENT, return); - Push(L, guild); - Push(L, eventType); - Push(L, tabId); - Push(L, playerGuid); - Push(L, itemOrMoney); - Push(L, itemStackCount); - Push(L, destTabId); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(guild); + Push(eventType); + Push(tabId); + Push(playerGuid); + Push(itemOrMoney); + Push(itemStackCount); + Push(destTabId); + CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_BANK_EVENT); } // Group void Eluna::OnAddMember(Group* group, uint64 guid) { - EVENT_BEGIN(GroupEventBindings, GROUP_EVENT_ON_MEMBER_ADD, return); - Push(L, group); - Push(L, guid); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(group); + Push(guid); + CallAllFunctions(GroupEventBindings, GROUP_EVENT_ON_MEMBER_ADD); } void Eluna::OnInviteMember(Group* group, uint64 guid) { - EVENT_BEGIN(GroupEventBindings, GROUP_EVENT_ON_MEMBER_INVITE, return); - Push(L, group); - Push(L, guid); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(group); + Push(guid); + CallAllFunctions(GroupEventBindings, GROUP_EVENT_ON_MEMBER_INVITE); } void Eluna::OnRemoveMember(Group* group, uint64 guid, uint8 method) { - EVENT_BEGIN(GroupEventBindings, GROUP_EVENT_ON_MEMBER_REMOVE, return); - Push(L, group); - Push(L, guid); - Push(L, method); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(group); + Push(guid); + Push(method); + CallAllFunctions(GroupEventBindings, GROUP_EVENT_ON_MEMBER_REMOVE); } void Eluna::OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid) { - EVENT_BEGIN(GroupEventBindings, GROUP_EVENT_ON_LEADER_CHANGE, return); - Push(L, group); - Push(L, newLeaderGuid); - Push(L, oldLeaderGuid); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(group); + Push(newLeaderGuid); + Push(oldLeaderGuid); + CallAllFunctions(GroupEventBindings, GROUP_EVENT_ON_LEADER_CHANGE); } void Eluna::OnDisband(Group* group) { - EVENT_BEGIN(GroupEventBindings, GROUP_EVENT_ON_DISBAND, return); - Push(L, group); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(group); + CallAllFunctions(GroupEventBindings, GROUP_EVENT_ON_DISBAND); } void Eluna::OnCreate(Group* group, uint64 leaderGuid, GroupType groupType) { - EVENT_BEGIN(GroupEventBindings, GROUP_EVENT_ON_CREATE, return); - Push(L, group); - Push(L, leaderGuid); - Push(L, groupType); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(group); + Push(leaderGuid); + Push(groupType); + CallAllFunctions(GroupEventBindings, GROUP_EVENT_ON_CREATE); } /* Map */ void Eluna::OnCreate(Map* map) { - EVENT_BEGIN(ServerEventBindings, MAP_EVENT_ON_CREATE, return); - Push(L, map); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(map); + CallAllFunctions(ServerEventBindings, MAP_EVENT_ON_CREATE); } void Eluna::OnDestroy(Map* map) { - EVENT_BEGIN(ServerEventBindings, MAP_EVENT_ON_DESTROY, return); - Push(L, map); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(map); + CallAllFunctions(ServerEventBindings, MAP_EVENT_ON_DESTROY); } void Eluna::OnPlayerEnter(Map* map, Player* player) { - EVENT_BEGIN(ServerEventBindings, MAP_EVENT_ON_PLAYER_ENTER, return); - Push(L, map); - Push(L, player); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(map); + Push(player); + CallAllFunctions(ServerEventBindings, MAP_EVENT_ON_PLAYER_ENTER); } void Eluna::OnPlayerLeave(Map* map, Player* player) { - EVENT_BEGIN(ServerEventBindings, MAP_EVENT_ON_PLAYER_LEAVE, return); - Push(L, map); - Push(L, player); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(map); + Push(player); + CallAllFunctions(ServerEventBindings, MAP_EVENT_ON_PLAYER_LEAVE); } void Eluna::OnUpdate(Map* map, uint32 diff) { + ELUNA_LOCK(this); // enable this for multithread // eventMgr->globalProcessor->Update(diff); - EVENT_BEGIN(ServerEventBindings, MAP_EVENT_ON_UPDATE, return); - Push(L, map); - Push(L, diff); - EVENT_EXECUTE(0); - ENDCALL(); + Push(map); + Push(diff); + CallAllFunctions(ServerEventBindings, MAP_EVENT_ON_UPDATE); } void Eluna::OnRemove(GameObject* gameobject) { - EVENT_BEGIN(ServerEventBindings, WORLD_EVENT_ON_DELETE_GAMEOBJECT, return); - Push(L, gameobject); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(gameobject); + CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_DELETE_GAMEOBJECT); } void Eluna::OnRemove(Creature* creature) { - EVENT_BEGIN(ServerEventBindings, WORLD_EVENT_ON_DELETE_CREATURE, return); - Push(L, creature); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(creature); + CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_DELETE_CREATURE); } // creature bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, Creature* pTarget) { - ENTRY_BEGIN(CreatureEventBindings, pTarget->GetEntry(), CREATURE_EVENT_ON_DUMMY_EFFECT, return false); - Push(L, pCaster); - Push(L, spellId); - Push(L, effIndex); - Push(L, pTarget); - ENTRY_EXECUTE(0); - ENDCALL(); - return true; + ELUNA_LOCK(this); + Push(pCaster); + Push(spellId); + Push(effIndex); + Push(pTarget); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry()); } bool Eluna::OnGossipHello(Player* pPlayer, Creature* pCreature) { - ENTRY_BEGIN(CreatureGossipBindings, pCreature->GetEntry(), GOSSIP_EVENT_ON_HELLO, return false); + ELUNA_LOCK(this); pPlayer->PlayerTalkClass->ClearMenus(); - Push(L, pPlayer); - Push(L, pCreature); - ENTRY_EXECUTE(0); - ENDCALL(); - return true; + Push(pPlayer); + Push(pCreature); + return CallAllFunctionsBool(CreatureGossipBindings, GOSSIP_EVENT_ON_HELLO, pCreature->GetEntry()); } bool Eluna::OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action) { - ENTRY_BEGIN(CreatureGossipBindings, pCreature->GetEntry(), GOSSIP_EVENT_ON_SELECT, return false); + ELUNA_LOCK(this); pPlayer->PlayerTalkClass->ClearMenus(); - Push(L, pPlayer); - Push(L, pCreature); - Push(L, sender); - Push(L, action); - ENTRY_EXECUTE(0); - ENDCALL(); - return true; + Push(pPlayer); + Push(pCreature); + Push(sender); + Push(action); + return CallAllFunctionsBool(CreatureGossipBindings, GOSSIP_EVENT_ON_SELECT, pCreature->GetEntry()); } bool Eluna::OnGossipSelectCode(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action, const char* code) { - ENTRY_BEGIN(CreatureGossipBindings, pCreature->GetEntry(), GOSSIP_EVENT_ON_SELECT, return false); + ELUNA_LOCK(this); pPlayer->PlayerTalkClass->ClearMenus(); - Push(L, pPlayer); - Push(L, pCreature); - Push(L, sender); - Push(L, action); - Push(L, code); - ENTRY_EXECUTE(0); - ENDCALL(); - return true; + Push(pPlayer); + Push(pCreature); + Push(sender); + Push(action); + Push(code); + return CallAllFunctionsBool(CreatureGossipBindings, GOSSIP_EVENT_ON_SELECT, pCreature->GetEntry()); } bool Eluna::OnQuestAccept(Player* pPlayer, Creature* pCreature, Quest const* pQuest) { - ENTRY_BEGIN(CreatureEventBindings, pCreature->GetEntry(), CREATURE_EVENT_ON_QUEST_ACCEPT, return false); - Push(L, pPlayer); - Push(L, pCreature); - Push(L, pQuest); - ENTRY_EXECUTE(0); - ENDCALL(); - return true; + ELUNA_LOCK(this); + Push(pPlayer); + Push(pCreature); + Push(pQuest); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_QUEST_ACCEPT, pCreature->GetEntry()); } bool Eluna::OnQuestReward(Player* pPlayer, Creature* pCreature, Quest const* pQuest, uint32 opt) { - ENTRY_BEGIN(CreatureEventBindings, pCreature->GetEntry(), CREATURE_EVENT_ON_QUEST_REWARD, return false); - Push(L, pPlayer); - Push(L, pCreature); - Push(L, pQuest); - Push(L, opt); - ENTRY_EXECUTE(0); - ENDCALL(); - return true; + ELUNA_LOCK(this); + Push(pPlayer); + Push(pCreature); + Push(pQuest); + Push(opt); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_QUEST_REWARD, pCreature->GetEntry()); } uint32 Eluna::GetDialogStatus(Player* pPlayer, Creature* pCreature) { - ENTRY_BEGIN(CreatureEventBindings, pCreature->GetEntry(), CREATURE_EVENT_ON_DIALOG_STATUS, return 0); - Push(L, pPlayer); - Push(L, pCreature); - ENTRY_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + Push(pCreature); + CallAllFunctions(CreatureEventBindings, CREATURE_EVENT_ON_DIALOG_STATUS, pCreature->GetEntry()); return DIALOG_STATUS_SCRIPTED_NO_STATUS; } void Eluna::OnAddToWorld(Creature* creature) { - ENTRY_BEGIN(CreatureEventBindings, creature->GetEntry(), CREATURE_EVENT_ON_ADD, return); - Push(L, creature); - ENTRY_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(creature); + CallAllFunctions(CreatureEventBindings, CREATURE_EVENT_ON_ADD, creature->GetEntry()); } void Eluna::OnRemoveFromWorld(Creature* creature) { - ENTRY_BEGIN(CreatureEventBindings, creature->GetEntry(), CREATURE_EVENT_ON_REMOVE, return); - Push(L, creature); - ENTRY_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(creature); + CallAllFunctions(CreatureEventBindings, CREATURE_EVENT_ON_REMOVE, creature->GetEntry()); } bool Eluna::OnSummoned(Creature* pCreature, Unit* pSummoner) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, pCreature->GetEntry(), CREATURE_EVENT_ON_SUMMONED, return false); - Push(L, pCreature); - Push(L, pSummoner); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(pCreature); + Push(pSummoner); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_SUMMONED, pCreature->GetEntry()); } bool Eluna::UpdateAI(Creature* me, const uint32 diff) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_AIUPDATE, return false); - Eluna::Push(L, me); - Eluna::Push(L, diff); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(me); + Push(diff); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_AIUPDATE, me->GetEntry()); } //Called for reaction at enter to combat if not in combat yet (enemy can be NULL) //Called at creature aggro either by MoveInLOS or Attack Start bool Eluna::EnterCombat(Creature* me, Unit* target) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_ENTER_COMBAT, return false); - Eluna::Push(L, me); - Eluna::Push(L, target); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(me); + Push(target); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_ENTER_COMBAT, me->GetEntry()); } // Called at any Damage from any attacker (before damage apply) bool Eluna::DamageTaken(Creature* me, Unit* attacker, uint32& damage) { + ELUNA_LOCK(this); bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_DAMAGE_TAKEN, return false); - Eluna::Push(L, me); - Eluna::Push(L, attacker); - Eluna::Push(L, damage); - ENTRY_EXECUTE(2); - FOR_RETS(i) + Push(me); + Push(attacker); + Push(damage); + int n = SetupStack(CreatureEventBindings, CREATURE_EVENT_ON_DAMAGE_TAKEN, me->GetEntry(), 3); + + while (n > 0) { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i); - if (lua_isnumber(L, i)) - damage = Eluna::CHECKVAL(L, i, damage); + int r = CallOneFunction(n--, 3, 2); + + if (lua_isboolean(L, r + 0) && lua_toboolean(L, r + 0)) + result = true; + + if (lua_isnumber(L, r + 1)) + damage = Eluna::CHECKVAL(L, r + 1); + + lua_pop(L, 2); } - ENDCALL(); + + CleanUpStack(3); return result; } //Called at creature death bool Eluna::JustDied(Creature* me, Unit* killer) { + ELUNA_LOCK(this); On_Reset(me); - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_DIED, return false); - Eluna::Push(L, me); - Eluna::Push(L, killer); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + Push(me); + Push(killer); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_DIED, me->GetEntry()); } //Called at creature killing another unit bool Eluna::KilledUnit(Creature* me, Unit* victim) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_TARGET_DIED, return false); - Eluna::Push(L, me); - Eluna::Push(L, victim); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(me); + Push(victim); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_TARGET_DIED, me->GetEntry()); } // Called when the creature summon successfully other creature bool Eluna::JustSummoned(Creature* me, Creature* summon) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_JUST_SUMMONED_CREATURE, return false); - Eluna::Push(L, me); - Eluna::Push(L, summon); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(me); + Push(summon); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_JUST_SUMMONED_CREATURE, me->GetEntry()); } // Called when a summoned creature is despawned bool Eluna::SummonedCreatureDespawn(Creature* me, Creature* summon) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_SUMMONED_CREATURE_DESPAWN, return false); - Eluna::Push(L, me); - Eluna::Push(L, summon); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(me); + Push(summon); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_SUMMONED_CREATURE_DESPAWN, me->GetEntry()); } //Called at waypoint reached or PointMovement end bool Eluna::MovementInform(Creature* me, uint32 type, uint32 id) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_REACH_WP, return false); - Eluna::Push(L, me); - Eluna::Push(L, type); - Eluna::Push(L, id); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(me); + Push(type); + Push(id); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_REACH_WP, me->GetEntry()); } // Called before EnterCombat even before the creature is in combat. bool Eluna::AttackStart(Creature* me, Unit* target) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_PRE_COMBAT, return false); - Eluna::Push(L, me); - Eluna::Push(L, target); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(me); + Push(target); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_PRE_COMBAT, me->GetEntry()); } // Called for reaction at stopping attack at no attackers or targets bool Eluna::EnterEvadeMode(Creature* me) { + ELUNA_LOCK(this); On_Reset(me); - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_LEAVE_COMBAT, return false); - Eluna::Push(L, me); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + Push(me); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_LEAVE_COMBAT, me->GetEntry()); } // Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc) bool Eluna::AttackedBy(Creature* me, Unit* attacker) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_ATTACKED_AT, return false); - Eluna::Push(L, me); - Eluna::Push(L, attacker); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(me); + Push(attacker); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_ATTACKED_AT, me->GetEntry()); } // Called when creature is spawned or respawned (for reseting variables) bool Eluna::JustRespawned(Creature* me) { + ELUNA_LOCK(this); On_Reset(me); - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_SPAWN, return false); - Eluna::Push(L, me); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + Push(me); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_SPAWN, me->GetEntry()); } // Called at reaching home after evade bool Eluna::JustReachedHome(Creature* me) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_REACH_HOME, return false); - Eluna::Push(L, me); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(me); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_REACH_HOME, me->GetEntry()); } // Called at text emote receive from player bool Eluna::ReceiveEmote(Creature* me, Player* player, uint32 emoteId) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_RECEIVE_EMOTE, return false); - Eluna::Push(L, me); - Eluna::Push(L, player); - Eluna::Push(L, emoteId); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(me); + Push(player); + Push(emoteId); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_RECEIVE_EMOTE, me->GetEntry()); } // called when the corpse of this creature gets removed bool Eluna::CorpseRemoved(Creature* me, uint32& respawnDelay) { + ELUNA_LOCK(this); bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_CORPSE_REMOVED, return false); - Eluna::Push(L, me); - Eluna::Push(L, respawnDelay); - ENTRY_EXECUTE(2); - FOR_RETS(i) + Push(me); + Push(respawnDelay); + int n = SetupStack(CreatureEventBindings, CREATURE_EVENT_ON_CORPSE_REMOVED, me->GetEntry(), 2); + + while (n > 0) { - if (lua_isboolean(L, i)) - result = Eluna::CHECKVAL(L, i); - if (lua_isnumber(L, i)) - respawnDelay = Eluna::CHECKVAL(L, i, respawnDelay); + int r = CallOneFunction(n--, 2, 2); + + if (lua_isboolean(L, r + 0) && lua_toboolean(L, r + 0)) + result = true; + + if (lua_isnumber(L, r + 1)) + respawnDelay = Eluna::CHECKVAL(L, r + 1); + + lua_pop(L, 2); } - ENDCALL(); + + CleanUpStack(2); return result; } bool Eluna::MoveInLineOfSight(Creature* me, Unit* who) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_MOVE_IN_LOS, return false); - Eluna::Push(L, me); - Eluna::Push(L, who); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(me); + Push(who); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_MOVE_IN_LOS, me->GetEntry()); } // Called on creature initial spawn, respawn, death, evade (leave combat) void Eluna::On_Reset(Creature* me) // Not an override, custom { - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_RESET, return); - Eluna::Push(L, me); - ENTRY_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(me); + CallAllFunctions(CreatureEventBindings, CREATURE_EVENT_ON_RESET, me->GetEntry()); } // Called when hit by a spell bool Eluna::SpellHit(Creature* me, Unit* caster, SpellInfo const* spell) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_HIT_BY_SPELL, return false); - Eluna::Push(L, me); - Eluna::Push(L, caster); - Eluna::Push(L, spell->Id); // Pass spell object? - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(me); + Push(caster); + Push(spell->Id); // Pass spell object? + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_HIT_BY_SPELL, me->GetEntry()); } // Called when spell hits a target bool Eluna::SpellHitTarget(Creature* me, Unit* target, SpellInfo const* spell) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_SPELL_HIT_TARGET, return false); - Eluna::Push(L, me); - Eluna::Push(L, target); - Eluna::Push(L, spell->Id); // Pass spell object? - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(me); + Push(target); + Push(spell->Id); // Pass spell object? + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_SPELL_HIT_TARGET, me->GetEntry()); } #ifdef TRINITY bool Eluna::SummonedCreatureDies(Creature* me, Creature* summon, Unit* killer) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_SUMMONED_CREATURE_DIED, return false); - Eluna::Push(L, me); - Eluna::Push(L, summon); - Eluna::Push(L, killer); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(me); + Push(summon); + Push(killer); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_SUMMONED_CREATURE_DIED, me->GetEntry()); } // Called when owner takes damage bool Eluna::OwnerAttackedBy(Creature* me, Unit* attacker) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_OWNER_ATTACKED_AT, return false); - Eluna::Push(L, me); - Eluna::Push(L, attacker); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(me); + Push(attacker); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_OWNER_ATTACKED_AT, me->GetEntry()); } // Called when owner attacks something bool Eluna::OwnerAttacked(Creature* me, Unit* target) { - bool result = false; - ENTRY_BEGIN(CreatureEventBindings, me->GetEntry(), CREATURE_EVENT_ON_OWNER_ATTACKED, return false); - Eluna::Push(L, me); - Eluna::Push(L, target); - ENTRY_EXECUTE(1); - FOR_RETS(i) - { - if (lua_isboolean(L, i)) - result = CHECKVAL(L, i, false); - } - ENDCALL(); - return result; + ELUNA_LOCK(this); + Push(me); + Push(target); + return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_OWNER_ATTACKED, me->GetEntry()); } #endif @@ -2060,94 +1916,80 @@ struct ElunaCreatureAI : ScriptedAI // gameobject bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, GameObject* pTarget) { - ENTRY_BEGIN(GameObjectEventBindings, pTarget->GetEntry(), GAMEOBJECT_EVENT_ON_DUMMY_EFFECT, return false); - Push(L, pCaster); - Push(L, spellId); - Push(L, effIndex); - Push(L, pTarget); - ENTRY_EXECUTE(0); - ENDCALL(); - return true; + ELUNA_LOCK(this); + Push(pCaster); + Push(spellId); + Push(effIndex); + Push(pTarget); + return CallAllFunctionsBool(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry()); } bool Eluna::OnGossipHello(Player* pPlayer, GameObject* pGameObject) { - ENTRY_BEGIN(GameObjectGossipBindings, pGameObject->GetEntry(), GOSSIP_EVENT_ON_HELLO, return false); + ELUNA_LOCK(this); pPlayer->PlayerTalkClass->ClearMenus(); - Push(L, pPlayer); - Push(L, pGameObject); - ENTRY_EXECUTE(0); - ENDCALL(); - return true; + Push(pPlayer); + Push(pGameObject); + return CallAllFunctionsBool(GameObjectGossipBindings, GOSSIP_EVENT_ON_HELLO, pGameObject->GetEntry()); } bool Eluna::OnGossipSelect(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action) { - ENTRY_BEGIN(GameObjectGossipBindings, pGameObject->GetEntry(), GOSSIP_EVENT_ON_SELECT, return false); + ELUNA_LOCK(this); pPlayer->PlayerTalkClass->ClearMenus(); - Push(L, pPlayer); - Push(L, pGameObject); - Push(L, sender); - Push(L, action); - ENTRY_EXECUTE(0); - ENDCALL(); - return true; + Push(pPlayer); + Push(pGameObject); + Push(sender); + Push(action); + return CallAllFunctionsBool(GameObjectGossipBindings, GOSSIP_EVENT_ON_SELECT, pGameObject->GetEntry()); } bool Eluna::OnGossipSelectCode(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action, const char* code) { - ENTRY_BEGIN(GameObjectGossipBindings, pGameObject->GetEntry(), GOSSIP_EVENT_ON_SELECT, return false); + ELUNA_LOCK(this); pPlayer->PlayerTalkClass->ClearMenus(); - Push(L, pPlayer); - Push(L, pGameObject); - Push(L, sender); - Push(L, action); - Push(L, code); - ENTRY_EXECUTE(0); - ENDCALL(); - return true; + Push(pPlayer); + Push(pGameObject); + Push(sender); + Push(action); + Push(code); + return CallAllFunctionsBool(GameObjectGossipBindings, GOSSIP_EVENT_ON_SELECT, pGameObject->GetEntry()); } bool Eluna::OnQuestAccept(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest) { - ENTRY_BEGIN(GameObjectEventBindings, pGameObject->GetEntry(), GAMEOBJECT_EVENT_ON_QUEST_ACCEPT, return false); - Push(L, pPlayer); - Push(L, pGameObject); - Push(L, pQuest); - ENTRY_EXECUTE(0); - ENDCALL(); - return true; + ELUNA_LOCK(this); + Push(pPlayer); + Push(pGameObject); + Push(pQuest); + return CallAllFunctionsBool(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_QUEST_ACCEPT, pGameObject->GetEntry()); } void Eluna::UpdateAI(GameObject* pGameObject, uint32 diff) { + ELUNA_LOCK(this); pGameObject->elunaEvents->Update(diff); - ENTRY_BEGIN(GameObjectEventBindings, pGameObject->GetEntry(), GAMEOBJECT_EVENT_ON_AIUPDATE, return); - Push(L, pGameObject); - Push(L, diff); - ENTRY_EXECUTE(0); - ENDCALL(); + Push(pGameObject); + Push(diff); + CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_AIUPDATE, pGameObject->GetEntry()); } bool Eluna::OnQuestReward(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest, uint32 opt) { - ENTRY_BEGIN(GameObjectEventBindings, pGameObject->GetEntry(), GAMEOBJECT_EVENT_ON_QUEST_REWARD, return false); - Push(L, pPlayer); - Push(L, pGameObject); - Push(L, pQuest); - Push(L, opt); - ENTRY_EXECUTE(0); - ENDCALL(); - return true; + ELUNA_LOCK(this); + Push(pPlayer); + Push(pGameObject); + Push(pQuest); + Push(opt); + return CallAllFunctionsBool(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_QUEST_REWARD, pGameObject->GetEntry()); } uint32 Eluna::GetDialogStatus(Player* pPlayer, GameObject* pGameObject) { - ENTRY_BEGIN(GameObjectEventBindings, pGameObject->GetEntry(), GAMEOBJECT_EVENT_ON_DIALOG_STATUS, return 0); - Push(L, pPlayer); - Push(L, pGameObject); - ENTRY_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pPlayer); + Push(pGameObject); + CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_DIALOG_STATUS, pGameObject->GetEntry()); return DIALOG_STATUS_SCRIPTED_NO_STATUS; // DIALOG_STATUS_UNDEFINED } @@ -2155,68 +1997,62 @@ uint32 Eluna::GetDialogStatus(Player* pPlayer, GameObject* pGameObject) #ifndef TBC void Eluna::OnDestroyed(GameObject* pGameObject, Player* pPlayer) { - ENTRY_BEGIN(GameObjectEventBindings, pGameObject->GetEntry(), GAMEOBJECT_EVENT_ON_DESTROYED, return); - Push(L, pGameObject); - Push(L, pPlayer); - ENTRY_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pGameObject); + Push(pPlayer); + CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_DESTROYED, pGameObject->GetEntry()); } void Eluna::OnDamaged(GameObject* pGameObject, Player* pPlayer) { - ENTRY_BEGIN(GameObjectEventBindings, pGameObject->GetEntry(), GAMEOBJECT_EVENT_ON_DAMAGED, return); - Push(L, pGameObject); - Push(L, pPlayer); - ENTRY_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pGameObject); + Push(pPlayer); + CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_DAMAGED, pGameObject->GetEntry()); } #endif #endif void Eluna::OnLootStateChanged(GameObject* pGameObject, uint32 state) { - ENTRY_BEGIN(GameObjectEventBindings, pGameObject->GetEntry(), GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE, return); - Push(L, pGameObject); - Push(L, state); - ENTRY_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pGameObject); + Push(state); + CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE, pGameObject->GetEntry()); } void Eluna::OnGameObjectStateChanged(GameObject* pGameObject, uint32 state) { - ENTRY_BEGIN(GameObjectEventBindings, pGameObject->GetEntry(), GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED, return); - Push(L, pGameObject); - Push(L, state); - ENTRY_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(pGameObject); + Push(state); + CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED, pGameObject->GetEntry()); } void Eluna::OnSpawn(GameObject* gameobject) { - ENTRY_BEGIN(GameObjectEventBindings, gameobject->GetEntry(), GAMEOBJECT_EVENT_ON_SPAWN, return); - Push(L, gameobject); - ENTRY_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(gameobject); + CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_SPAWN, gameobject->GetEntry()); } void Eluna::OnAddToWorld(GameObject* gameobject) { - ENTRY_BEGIN(GameObjectEventBindings, gameobject->GetEntry(), GAMEOBJECT_EVENT_ON_ADD, return); - Push(L, gameobject); - ENTRY_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(gameobject); + CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_ADD, gameobject->GetEntry()); } void Eluna::OnRemoveFromWorld(GameObject* gameobject) { - ENTRY_BEGIN(GameObjectEventBindings, gameobject->GetEntry(), GAMEOBJECT_EVENT_ON_REMOVE, return); - Push(L, gameobject); - ENTRY_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(gameobject); + CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_REMOVE, gameobject->GetEntry()); } CreatureAI* Eluna::GetAI(Creature* creature) { + ELUNA_LOCK(this); if (!CreatureEventBindings->HasEvents(creature->GetEntry())) return NULL; return new ElunaCreatureAI(creature); @@ -2224,41 +2060,37 @@ CreatureAI* Eluna::GetAI(Creature* creature) void Eluna::OnBGStart(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) { - EVENT_BEGIN(BGEventBindings, BG_EVENT_ON_START, return); - Push(L, bg); - Push(L, bgId); - Push(L, instanceId); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(bg); + Push(bgId); + Push(instanceId); + CallAllFunctions(BGEventBindings, BG_EVENT_ON_START); } void Eluna::OnBGEnd(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId, Team winner) { - EVENT_BEGIN(BGEventBindings, BG_EVENT_ON_END, return); - Push(L, bg); - Push(L, bgId); - Push(L, instanceId); - Push(L, winner); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(bg); + Push(bgId); + Push(instanceId); + Push(winner); + CallAllFunctions(BGEventBindings, BG_EVENT_ON_END); } void Eluna::OnBGCreate(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) { - EVENT_BEGIN(BGEventBindings, BG_EVENT_ON_CREATE, return); - Push(L, bg); - Push(L, bgId); - Push(L, instanceId); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(bg); + Push(bgId); + Push(instanceId); + CallAllFunctions(BGEventBindings, BG_EVENT_ON_CREATE); } void Eluna::OnBGDestroy(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) { - EVENT_BEGIN(BGEventBindings, BG_EVENT_ON_PRE_DESTROY, return); - Push(L, bg); - Push(L, bgId); - Push(L, instanceId); - EVENT_EXECUTE(0); - ENDCALL(); + ELUNA_LOCK(this); + Push(bg); + Push(bgId); + Push(instanceId); + CallAllFunctions(BGEventBindings, BG_EVENT_ON_PRE_DESTROY); } diff --git a/LuaEngine.cpp b/LuaEngine.cpp index 36195af..abc2451 100644 --- a/LuaEngine.cpp +++ b/LuaEngine.cpp @@ -118,6 +118,7 @@ Eluna::Eluna() : L(luaL_newstate()), event_level(0), +push_counter(0), eventMgr(NULL), diff --git a/LuaEngine.h b/LuaEngine.h index 77d40d7..28e23e5 100644 --- a/LuaEngine.h +++ b/LuaEngine.h @@ -109,6 +109,43 @@ private: Eluna(Eluna const&); Eluna& operator=(const Eluna&); + // Some helpers for hooks to call event handlers. + template int SetupStack(EventBind* event_bindings, EntryBind* entry_bindings, T event_id, uint32 entry, int number_of_arguments); + int CallOneFunction(int number_of_functions, int number_of_arguments, int number_of_results); + void CleanUpStack(int number_of_arguments); + template void CallAllFunctions(EventBind* event_bindings, EntryBind* entry_bindings, T event_id, uint32 entry); + template bool CallAllFunctionsBool(EventBind* event_bindings, EntryBind* entry_bindings, T event_id, uint32 entry, bool default_value); + + // Convenient overloads for Setup. Use these in hooks instead of original. + template int SetupStack(EventBind* event_bindings, T event_id, int number_of_arguments) + { + return SetupStack(event_bindings, (EntryBind*)NULL, event_id, 0, number_of_arguments); + } + template int SetupStack(EntryBind* entry_bindings, T event_id, uint32 entry, int number_of_arguments) + { + return SetupStack((EventBind*)NULL, entry_bindings, event_id, entry, number_of_arguments); + } + + // Convenient overloads for CallAllFunctions. Use these in hooks instead of original. + template void CallAllFunctions(EventBind* event_bindings, T event_id) + { + CallAllFunctions(event_bindings, (EntryBind*)NULL, event_id, 0); + } + template void CallAllFunctions(EntryBind* entry_bindings, T event_id, uint32 entry) + { + CallAllFunctions((EventBind*)NULL, entry_bindings, event_id, entry); + } + + // Convenient overloads for CallAllFunctionsBool. Use these in hooks instead of original. + template bool CallAllFunctionsBool(EventBind* event_bindings, T event_id, bool default_value = false) + { + return CallAllFunctionsBool(event_bindings, (EntryBind*)NULL, event_id, 0, default_value); + } + template bool CallAllFunctionsBool(EntryBind* entry_bindings, T event_id, uint32 entry, bool default_value = false) + { + return CallAllFunctionsBool((EventBind*)NULL, entry_bindings, event_id, entry, default_value); + } + public: typedef std::list ScriptList; @@ -168,7 +205,7 @@ public: void RunScripts(); void InvalidateObjects(); - // Pushes + // Static pushes, can be used by anything, including methods. static void Push(lua_State* luastate); // nil static void Push(lua_State* luastate, const long long); static void Push(lua_State* luastate, const unsigned long long); @@ -191,6 +228,31 @@ public: static void Push(lua_State* luastate, Pet const* pet); static void Push(lua_State* luastate, TempSummon const* summon); + // When a hook pushes arguments to be passed to event handlers + // this is used to keep track of how many arguments were pushed. + uint8 push_counter; + + // Non-static pushes, to be used in hooks. + // These just call the correct static version with the main thread's Lua state. + void Push() { Push(L); ++push_counter; } + void Push(const long long value) { Push(L, value); ++push_counter; } + void Push(const unsigned long long value) { Push(L, value); ++push_counter; } + void Push(const long value) { Push(L, value); ++push_counter; } + void Push(const unsigned long value) { Push(L, value); ++push_counter; } + void Push(const int value) { Push(L, value); ++push_counter; } + void Push(const unsigned int value) { Push(L, value); ++push_counter; } + void Push(const bool value) { Push(L, value); ++push_counter; } + void Push(const float value) { Push(L, value); ++push_counter; } + void Push(const double value) { Push(L, value); ++push_counter; } + void Push(const std::string& value) { Push(L, value); ++push_counter; } + void Push(const char* value) { Push(L, value); ++push_counter; } + template void Push(T const* ptr){ Push(L, ptr); ++push_counter; } + void Push(Object const* obj) { Push(L, obj); ++push_counter; } + void Push(WorldObject const* obj) { Push(L, obj); ++push_counter; } + void Push(Unit const* unit) { Push(L, unit); ++push_counter; } + void Push(Pet const* pet) { Push(L, pet); ++push_counter; } + void Push(TempSummon const* summon) { Push(L, summon); ++push_counter; } + // Checks template static T CHECKVAL(lua_State* luastate, int narg); template static T CHECKVAL(lua_State* luastate, int narg, T def) From 4349a80d8e7509e90a9f673aa5e72dacacadb5e3 Mon Sep 17 00:00:00 2001 From: Patman64 Date: Sun, 4 Jan 2015 21:38:18 -0500 Subject: [PATCH 02/10] Allow updating argument values between handler calls. This allows handlers that return values to see the returned values of previous handlers. E.g. if Handler A modifies the value from 10 to 20, Handler B will receive 20 as an argument instead of the original 10. --- HookMgr.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- LuaEngine.h | 3 ++- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/HookMgr.cpp b/HookMgr.cpp index f811e83..bbe00c3 100644 --- a/HookMgr.cpp +++ b/HookMgr.cpp @@ -116,6 +116,25 @@ int Eluna::SetupStack(EventBind* event_bindings, EntryBind* entry_bindings return number_of_functions; } +/* + * Replace one of the arguments pushed before `SetupStack` with a new value. + */ +template +void Eluna::ReplaceArgument(T value, uint8 index, uint8 number_of_arguments, uint8 number_of_results, uint8 remaining_functions) +{ + ASSERT(index <= number_of_arguments && index > 0); + // Stack: event_id, [arguments], [functions], [results] + + int first_argument_index = lua_gettop(L) - number_of_results - remaining_functions - number_of_arguments + 1; + int argument_index = first_argument_index + index - 1; + + Eluna::Push(L, value); + // Stack: event_id, [arguments], [functions], [results], value + + lua_replace(L, argument_index); + // Stack: event_id, [arguments and value], [functions], [results] +} + /* * Call a single event handler that was put on the stack with `Setup` and removes it from the stack. * @@ -795,7 +814,11 @@ void Eluna::OnMoneyChanged(Player* pPlayer, int32& amount) int r = CallOneFunction(n--, 2, 1); if (lua_isnumber(L, r)) - amount = CHECKVAL(L, r); + { + amount = CHECKVAL(L, r); + // Update the stack for subsequent calls. + ReplaceArgument(amount, 2, 2, 1, n); + } lua_pop(L, 1); } @@ -816,7 +839,11 @@ void Eluna::OnGiveXP(Player* pPlayer, uint32& amount, Unit* pVictim) int r = CallOneFunction(n--, 3, 1); if (lua_isnumber(L, r)) - amount = CHECKVAL(L, r); + { + amount = CHECKVAL(L, r); + // Update the stack for subsequent calls. + ReplaceArgument(amount, 2, 3, 1, n); + } lua_pop(L, 1); } @@ -838,7 +865,11 @@ void Eluna::OnReputationChange(Player* pPlayer, uint32 factionID, int32& standin int r = CallOneFunction(n--, 4, 1); if (lua_isnumber(L, r)) + { standing = CHECKVAL(L, r); + // Update the stack for subsequent calls. + ReplaceArgument(standing, 3, 4, 1, n); + } lua_pop(L, 1); } @@ -1221,7 +1252,11 @@ void Eluna::OnMemberWitdrawMoney(Guild* guild, Player* player, uint32& amount, b int r = CallOneFunction(n--, 4, 1); if (lua_isnumber(L, r)) + { amount = CHECKVAL(L, r); + // Update the stack for subsequent calls. + ReplaceArgument(amount, 3, 4, 1, n); + } lua_pop(L, 1); } @@ -1242,7 +1277,11 @@ void Eluna::OnMemberDepositMoney(Guild* guild, Player* player, uint32& amount) int r = CallOneFunction(n--, 3, 1); if (lua_isnumber(L, r)) + { amount = CHECKVAL(L, r); + // Update the stack for subsequent calls. + ReplaceArgument(amount, 3, 3, 1, n); + } lua_pop(L, 1); } @@ -1518,7 +1557,11 @@ bool Eluna::DamageTaken(Creature* me, Unit* attacker, uint32& damage) result = true; if (lua_isnumber(L, r + 1)) + { damage = Eluna::CHECKVAL(L, r + 1); + // Update the stack for subsequent calls. + ReplaceArgument(damage, 3, 3, 2, n); + } lua_pop(L, 2); } @@ -1645,7 +1688,11 @@ bool Eluna::CorpseRemoved(Creature* me, uint32& respawnDelay) result = true; if (lua_isnumber(L, r + 1)) + { respawnDelay = Eluna::CHECKVAL(L, r + 1); + // Update the stack for subsequent calls. + ReplaceArgument(respawnDelay, 2, 2, 2, n); + } lua_pop(L, 2); } diff --git a/LuaEngine.h b/LuaEngine.h index 28e23e5..8bb5684 100644 --- a/LuaEngine.h +++ b/LuaEngine.h @@ -111,8 +111,9 @@ private: // Some helpers for hooks to call event handlers. template int SetupStack(EventBind* event_bindings, EntryBind* entry_bindings, T event_id, uint32 entry, int number_of_arguments); - int CallOneFunction(int number_of_functions, int number_of_arguments, int number_of_results); void CleanUpStack(int number_of_arguments); + template void ReplaceArgument(T value, uint8 index, uint8 number_of_arguments, uint8 number_of_results, uint8 remaining_functions); + int CallOneFunction(int number_of_functions, int number_of_arguments, int number_of_results); template void CallAllFunctions(EventBind* event_bindings, EntryBind* entry_bindings, T event_id, uint32 entry); template bool CallAllFunctionsBool(EventBind* event_bindings, EntryBind* entry_bindings, T event_id, uint32 entry, bool default_value); From 2ff25ee2053c0de0964d7b83a3c0e5b0f172adff Mon Sep 17 00:00:00 2001 From: Patman64 Date: Sun, 4 Jan 2015 22:31:51 -0500 Subject: [PATCH 03/10] Fix getting results from event handlers. --- HookMgr.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/HookMgr.cpp b/HookMgr.cpp index bbe00c3..0013dab 100644 --- a/HookMgr.cpp +++ b/HookMgr.cpp @@ -159,9 +159,10 @@ int Eluna::CallOneFunction(int number_of_functions, int number_of_arguments, int // Stack: event_id, [arguments], [functions], event_id, [arguments] ExecuteCall(number_of_arguments, number_of_results); + --functions_top; // Stack: event_id, [arguments], [functions - 1], [results] - return functions_top + 1; // Return the location of the first result. + return functions_top + 1; // Return the location of the first result (if any exist). } /* From 0e7367e23dde45378740e21874cf7dd2bf003fa3 Mon Sep 17 00:00:00 2001 From: Rochet2 Date: Mon, 5 Jan 2015 16:37:44 +0200 Subject: [PATCH 04/10] Fix hookmgr rewrite Fix: - crash on reload - crash on error in call - a warning from type change --- HookMgr.cpp | 9 +++++---- LuaEngine.cpp | 22 +++++++++++++++++----- LuaEngine.h | 7 +------ 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/HookMgr.cpp b/HookMgr.cpp index 0013dab..61980f7 100644 --- a/HookMgr.cpp +++ b/HookMgr.cpp @@ -93,7 +93,7 @@ int Eluna::SetupStack(EventBind* event_bindings, EntryBind* entry_bindings ASSERT(number_of_arguments == this->push_counter); // Stack: [arguments] - Push((int)event_id); + Push(event_id); this->push_counter = 0; ++number_of_arguments; // Stack: [arguments], event_id @@ -143,7 +143,7 @@ void Eluna::ReplaceArgument(T value, uint8 index, uint8 number_of_arguments, uin int Eluna::CallOneFunction(int number_of_functions, int number_of_arguments, int number_of_results) { ++number_of_arguments; // Caller doesn't know about `event_id`. - ASSERT(number_of_functions > 0 && number_of_results >= 0); + ASSERT(number_of_functions > 0 && number_of_arguments > 0 && number_of_results >= 0); // Stack: event_id, [arguments], [functions] int functions_top = lua_gettop(L); @@ -208,6 +208,7 @@ template bool Eluna::CallAllFunctionsBool(EventBind* event_bindings, EntryBind* entry_bindings, T event_id, uint32 entry, bool default_value) { bool result = default_value; + // Note: number_of_arguments here does not count in eventID, which is pushed in SetupStack int number_of_arguments = this->push_counter; // Stack: [arguments] @@ -220,7 +221,7 @@ bool Eluna::CallAllFunctionsBool(EventBind* event_bindings, EntryBind* ent --number_of_functions; // Stack: event_id, [arguments], [functions - 1], result - if (lua_isboolean(L, r) && (bool)lua_toboolean(L, r) != default_value) + if (lua_isboolean(L, r) && (lua_toboolean(L, r) == 1) != default_value) result = !default_value; lua_pop(L, 1); @@ -461,13 +462,13 @@ void Eluna::OnShutdownCancel() void Eluna::OnWorldUpdate(uint32 diff) { - ELUNA_LOCK(this); if (reload) { ReloadEluna(); return; } + ELUNA_LOCK(this); eventMgr->globalProcessor->Update(diff); Push(diff); diff --git a/LuaEngine.cpp b/LuaEngine.cpp index abc2451..036bcb4 100644 --- a/LuaEngine.cpp +++ b/LuaEngine.cpp @@ -432,19 +432,31 @@ void Eluna::report(lua_State* luastate) void Eluna::ExecuteCall(int params, int res) { int top = lua_gettop(L); - int type = lua_type(L, top - params); + // Expected: function, [parameters] + ASSERT(top > params); + + // Check function type + int type = lua_type(L, top - params); if (type != LUA_TFUNCTION) { - lua_pop(L, params + 1); // Cleanup the stack. ELUNA_LOG_ERROR("[Eluna]: Cannot execute call: registered value is %s, not a function.", lua_typename(L, type)); - return; + ASSERT(false); } + // Objects are invalidated when event level hits 0 ++event_level; - if (lua_pcall(L, params, res, 0)) - report(L); + int result = lua_pcall(L, params, res, 0); --event_level; + + // lua_pcall returns 0 on success. + // On error we report errors and push nils for expected amount of returned values + if (result) + { + report(L); + for (int i = 0; i < res; ++i) + lua_pushnil(L); + } } void Eluna::Push(lua_State* luastate) diff --git a/LuaEngine.h b/LuaEngine.h index 8bb5684..bf11b34 100644 --- a/LuaEngine.h +++ b/LuaEngine.h @@ -247,12 +247,7 @@ public: void Push(const double value) { Push(L, value); ++push_counter; } void Push(const std::string& value) { Push(L, value); ++push_counter; } void Push(const char* value) { Push(L, value); ++push_counter; } - template void Push(T const* ptr){ Push(L, ptr); ++push_counter; } - void Push(Object const* obj) { Push(L, obj); ++push_counter; } - void Push(WorldObject const* obj) { Push(L, obj); ++push_counter; } - void Push(Unit const* unit) { Push(L, unit); ++push_counter; } - void Push(Pet const* pet) { Push(L, pet); ++push_counter; } - void Push(TempSummon const* summon) { Push(L, summon); ++push_counter; } + template void Push(T const* ptr){ Push(L, ptr); ++push_counter; } // Checks template static T CHECKVAL(lua_State* luastate, int narg); From 1194074fb2f87dd0054d9834d27e04660f5d3ead Mon Sep 17 00:00:00 2001 From: Patman64 Date: Mon, 5 Jan 2015 21:20:14 -0500 Subject: [PATCH 05/10] Simplify ReplaceArgument. --- HookMgr.cpp | 30 +++++++++++++++++------------- LuaEngine.h | 2 +- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/HookMgr.cpp b/HookMgr.cpp index 61980f7..33d21db 100644 --- a/HookMgr.cpp +++ b/HookMgr.cpp @@ -120,18 +120,15 @@ int Eluna::SetupStack(EventBind* event_bindings, EntryBind* entry_bindings * Replace one of the arguments pushed before `SetupStack` with a new value. */ template -void Eluna::ReplaceArgument(T value, uint8 index, uint8 number_of_arguments, uint8 number_of_results, uint8 remaining_functions) +void Eluna::ReplaceArgument(T value, uint8 index) { - ASSERT(index <= number_of_arguments && index > 0); + ASSERT(index < lua_gettop(L) && index > 0); // Stack: event_id, [arguments], [functions], [results] - int first_argument_index = lua_gettop(L) - number_of_results - remaining_functions - number_of_arguments + 1; - int argument_index = first_argument_index + index - 1; - Eluna::Push(L, value); // Stack: event_id, [arguments], [functions], [results], value - lua_replace(L, argument_index); + lua_replace(L, index + 1); // Stack: event_id, [arguments and value], [functions], [results] } @@ -809,6 +806,7 @@ void Eluna::OnMoneyChanged(Player* pPlayer, int32& amount) ELUNA_LOCK(this); Push(pPlayer); Push(amount); + int amountIndex = lua_gettop(L); int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_MONEY_CHANGE, 2); while (n > 0) @@ -819,7 +817,7 @@ void Eluna::OnMoneyChanged(Player* pPlayer, int32& amount) { amount = CHECKVAL(L, r); // Update the stack for subsequent calls. - ReplaceArgument(amount, 2, 2, 1, n); + ReplaceArgument(amount, amountIndex); } lua_pop(L, 1); @@ -834,6 +832,7 @@ void Eluna::OnGiveXP(Player* pPlayer, uint32& amount, Unit* pVictim) Push(pPlayer); Push(amount); Push(pVictim); + int amountIndex = lua_gettop(L) - 1; int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_GIVE_XP, 3); while (n > 0) @@ -844,7 +843,7 @@ void Eluna::OnGiveXP(Player* pPlayer, uint32& amount, Unit* pVictim) { amount = CHECKVAL(L, r); // Update the stack for subsequent calls. - ReplaceArgument(amount, 2, 3, 1, n); + ReplaceArgument(amount, amountIndex); } lua_pop(L, 1); @@ -860,6 +859,7 @@ void Eluna::OnReputationChange(Player* pPlayer, uint32 factionID, int32& standin Push(factionID); Push(standing); Push(incremental); + int standingIndex = lua_gettop(L) - 1; int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_REPUTATION_CHANGE, 4); while (n > 0) @@ -870,7 +870,7 @@ void Eluna::OnReputationChange(Player* pPlayer, uint32 factionID, int32& standin { standing = CHECKVAL(L, r); // Update the stack for subsequent calls. - ReplaceArgument(standing, 3, 4, 1, n); + ReplaceArgument(standing, standingIndex); } lua_pop(L, 1); @@ -1247,6 +1247,7 @@ void Eluna::OnMemberWitdrawMoney(Guild* guild, Player* player, uint32& amount, b Push(player); Push(amount); Push(isRepair); // isRepair not a part of Mangos, implement? + int amountIndex = lua_gettop(L) - 1; int n = SetupStack(GuildEventBindings, GUILD_EVENT_ON_MONEY_WITHDRAW, 4); while (n > 0) @@ -1257,7 +1258,7 @@ void Eluna::OnMemberWitdrawMoney(Guild* guild, Player* player, uint32& amount, b { amount = CHECKVAL(L, r); // Update the stack for subsequent calls. - ReplaceArgument(amount, 3, 4, 1, n); + ReplaceArgument(amount, amountIndex); } lua_pop(L, 1); @@ -1272,6 +1273,7 @@ void Eluna::OnMemberDepositMoney(Guild* guild, Player* player, uint32& amount) Push(guild); Push(player); Push(amount); + int amountIndex = lua_gettop(L); int n = SetupStack(GuildEventBindings, GUILD_EVENT_ON_MONEY_DEPOSIT, 3); while (n > 0) @@ -1282,7 +1284,7 @@ void Eluna::OnMemberDepositMoney(Guild* guild, Player* player, uint32& amount) { amount = CHECKVAL(L, r); // Update the stack for subsequent calls. - ReplaceArgument(amount, 3, 3, 1, n); + ReplaceArgument(amount, amountIndex); } lua_pop(L, 1); @@ -1549,6 +1551,7 @@ bool Eluna::DamageTaken(Creature* me, Unit* attacker, uint32& damage) Push(me); Push(attacker); Push(damage); + int damageIndex = lua_gettop(L); int n = SetupStack(CreatureEventBindings, CREATURE_EVENT_ON_DAMAGE_TAKEN, me->GetEntry(), 3); while (n > 0) @@ -1562,7 +1565,7 @@ bool Eluna::DamageTaken(Creature* me, Unit* attacker, uint32& damage) { damage = Eluna::CHECKVAL(L, r + 1); // Update the stack for subsequent calls. - ReplaceArgument(damage, 3, 3, 2, n); + ReplaceArgument(damage, damageIndex); } lua_pop(L, 2); @@ -1680,6 +1683,7 @@ bool Eluna::CorpseRemoved(Creature* me, uint32& respawnDelay) bool result = false; Push(me); Push(respawnDelay); + int respawnDelayIndex = lua_gettop(L); int n = SetupStack(CreatureEventBindings, CREATURE_EVENT_ON_CORPSE_REMOVED, me->GetEntry(), 2); while (n > 0) @@ -1693,7 +1697,7 @@ bool Eluna::CorpseRemoved(Creature* me, uint32& respawnDelay) { respawnDelay = Eluna::CHECKVAL(L, r + 1); // Update the stack for subsequent calls. - ReplaceArgument(respawnDelay, 2, 2, 2, n); + ReplaceArgument(respawnDelay, respawnDelayIndex); } lua_pop(L, 2); diff --git a/LuaEngine.h b/LuaEngine.h index bf11b34..b7b23b0 100644 --- a/LuaEngine.h +++ b/LuaEngine.h @@ -112,7 +112,7 @@ private: // Some helpers for hooks to call event handlers. template int SetupStack(EventBind* event_bindings, EntryBind* entry_bindings, T event_id, uint32 entry, int number_of_arguments); void CleanUpStack(int number_of_arguments); - template void ReplaceArgument(T value, uint8 index, uint8 number_of_arguments, uint8 number_of_results, uint8 remaining_functions); + template void ReplaceArgument(T value, uint8 index); int CallOneFunction(int number_of_functions, int number_of_arguments, int number_of_results); template void CallAllFunctions(EventBind* event_bindings, EntryBind* entry_bindings, T event_id, uint32 entry); template bool CallAllFunctionsBool(EventBind* event_bindings, EntryBind* entry_bindings, T event_id, uint32 entry, bool default_value); From 1678b3e40f6d23ca5652e073424c851ded01430e Mon Sep 17 00:00:00 2001 From: Patman64 Date: Mon, 5 Jan 2015 21:24:55 -0500 Subject: [PATCH 06/10] Invalidate ElunaObjects after hook calls. --- HookMgr.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/HookMgr.cpp b/HookMgr.cpp index 33d21db..288736a 100644 --- a/HookMgr.cpp +++ b/HookMgr.cpp @@ -168,8 +168,12 @@ int Eluna::CallOneFunction(int number_of_functions, int number_of_arguments, int void Eluna::CleanUpStack(int number_of_arguments) { // Stack: event_id, [arguments] + lua_pop(L, number_of_arguments + 1); // Add 1 because the caller doesn't know about `event_id`. // Stack: (empty) + + if (event_level == 0) + InvalidateObjects(); } /* From e2f81b7336337b110483b28ba5cd7ae10b0de71c Mon Sep 17 00:00:00 2001 From: Patman64 Date: Mon, 5 Jan 2015 22:20:52 -0500 Subject: [PATCH 07/10] Make the Eluna mutex static. It was previously unsafe to reload Eluna because it had to be reloaded with the mutex unlocked. This is because the mutex's lifespan was shorter than the Eluna instance it was guarding. --- HookMgr.cpp | 2 +- LuaEngine.cpp | 1 + LuaEngine.h | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/HookMgr.cpp b/HookMgr.cpp index 288736a..fe837d5 100644 --- a/HookMgr.cpp +++ b/HookMgr.cpp @@ -463,13 +463,13 @@ void Eluna::OnShutdownCancel() void Eluna::OnWorldUpdate(uint32 diff) { + ELUNA_LOCK(this); if (reload) { ReloadEluna(); return; } - ELUNA_LOCK(this); eventMgr->globalProcessor->Update(diff); Push(diff); diff --git a/LuaEngine.cpp b/LuaEngine.cpp index 036bcb4..f1ec9c9 100644 --- a/LuaEngine.cpp +++ b/LuaEngine.cpp @@ -36,6 +36,7 @@ std::string Eluna::lua_requirepath; Eluna* Eluna::GEluna = NULL; bool Eluna::reload = false; bool Eluna::initialized = false; +Eluna::LockType Eluna::lock; extern void RegisterFunctions(Eluna* E); diff --git a/LuaEngine.h b/LuaEngine.h index b7b23b0..f9e603b 100644 --- a/LuaEngine.h +++ b/LuaEngine.h @@ -159,10 +159,10 @@ public: typedef std::lock_guard ElunaGuard; #else typedef ACE_Recursive_Thread_Mutex LockType; - typedef ACE_Guard ElunaGuard; + typedef ACE_Guard Guard; #endif - LockType elunaLock; + static LockType lock; lua_State* L; uint32 event_level; @@ -459,5 +459,5 @@ template<> WorldObject* Eluna::CHECKOBJ(lua_State* L, int narg, boo template<> ElunaObject* Eluna::CHECKOBJ(lua_State* L, int narg, bool error); #define sEluna Eluna::GEluna -#define ELUNA_LOCK(E) Eluna::ElunaGuard elunaGuard((E)->elunaLock); +#define ELUNA_LOCK(E) Eluna::Guard __guard(Eluna::lock); #endif From 15f161fa1e8b18ed4d4aaa65a4daa6f146dc0ce4 Mon Sep 17 00:00:00 2001 From: Patman64 Date: Mon, 5 Jan 2015 22:52:46 -0500 Subject: [PATCH 08/10] Clean-up Eluna lock macro. --- ElunaEventMgr.cpp | 2 +- HookMgr.cpp | 306 +++++++++++++++++++++++----------------------- LuaEngine.h | 2 +- 3 files changed, 155 insertions(+), 155 deletions(-) diff --git a/ElunaEventMgr.cpp b/ElunaEventMgr.cpp index 48c4ca3..b640e2f 100644 --- a/ElunaEventMgr.cpp +++ b/ElunaEventMgr.cpp @@ -26,7 +26,7 @@ LuaEvent::~LuaEvent() void LuaEvent::Execute() { - ELUNA_LOCK(*events->E); + LOCK_ELUNA; // In multithread get map from object and the map's lua state lua_rawgeti((*events->E)->L, LUA_REGISTRYINDEX, funcRef); Eluna::Push((*events->E)->L, funcRef); diff --git a/HookMgr.cpp b/HookMgr.cpp index fe837d5..4d9e8e1 100644 --- a/HookMgr.cpp +++ b/HookMgr.cpp @@ -33,7 +33,7 @@ using namespace HookMgr; * A. If results will be IGNORED: * * // Lock out any other threads. - * ELUNA_LOCK(this); + * LOCK_ELUNA; * * // Push extra arguments, if any. * Push(a); @@ -47,7 +47,7 @@ using namespace HookMgr; * B. If results will be USED: * * // Lock out any other threads. - * ELUNA_LOCK(this); + * LOCK_ELUNA; * * // Push extra arguments, if any. * Push(a); @@ -237,20 +237,20 @@ bool Eluna::CallAllFunctionsBool(EventBind* event_bindings, EntryBind* ent void Eluna::OnLuaStateClose() { - ELUNA_LOCK(this); + LOCK_ELUNA; CallAllFunctions(ServerEventBindings, ELUNA_EVENT_ON_LUA_STATE_CLOSE); } void Eluna::OnLuaStateOpen() { - ELUNA_LOCK(this); + LOCK_ELUNA; CallAllFunctions(ServerEventBindings, ELUNA_EVENT_ON_LUA_STATE_OPEN); } // areatrigger bool Eluna::OnAreaTrigger(Player* pPlayer, AreaTriggerEntry const* pTrigger) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(pTrigger->id); return CallAllFunctionsBool(ServerEventBindings, TRIGGER_EVENT_ON_TRIGGER); @@ -258,7 +258,7 @@ bool Eluna::OnAreaTrigger(Player* pPlayer, AreaTriggerEntry const* pTrigger) // weather void Eluna::OnChange(Weather* weather, WeatherState state, float grade) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(weather->GetZone()); Push(state); Push(grade); @@ -267,28 +267,28 @@ void Eluna::OnChange(Weather* weather, WeatherState state, float grade) // Auction House void Eluna::OnAdd(AuctionHouseObject* ah) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(ah); CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_ADD); } void Eluna::OnRemove(AuctionHouseObject* ah) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(ah); CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_REMOVE); } void Eluna::OnSuccessful(AuctionHouseObject* ah) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(ah); CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_SUCCESSFUL); } void Eluna::OnExpire(AuctionHouseObject* ah) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(ah); CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_EXPIRE); } @@ -296,7 +296,7 @@ void Eluna::OnExpire(AuctionHouseObject* ah) // Packet bool Eluna::OnPacketSend(WorldSession* session, WorldPacket& packet) { - ELUNA_LOCK(this); + LOCK_ELUNA; bool result = true; Player* player = NULL; if (session) @@ -307,7 +307,7 @@ bool Eluna::OnPacketSend(WorldSession* session, WorldPacket& packet) } void Eluna::OnPacketSendAny(Player* player, WorldPacket& packet, bool& result) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(new WorldPacket(packet)); Push(player); int n = SetupStack(ServerEventBindings, SERVER_EVENT_ON_PACKET_SEND, 2); @@ -330,7 +330,7 @@ void Eluna::OnPacketSendAny(Player* player, WorldPacket& packet, bool& result) } void Eluna::OnPacketSendOne(Player* player, WorldPacket& packet, bool& result) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(new WorldPacket(packet)); Push(player); int n = SetupStack(PacketEventBindings, PACKET_EVENT_ON_PACKET_SEND, OpcodesList(packet.GetOpcode()), 2); @@ -354,7 +354,7 @@ void Eluna::OnPacketSendOne(Player* player, WorldPacket& packet, bool& result) bool Eluna::OnPacketReceive(WorldSession* session, WorldPacket& packet) { - ELUNA_LOCK(this); + LOCK_ELUNA; bool result = true; Player* player = NULL; if (session) @@ -365,7 +365,7 @@ bool Eluna::OnPacketReceive(WorldSession* session, WorldPacket& packet) } void Eluna::OnPacketReceiveAny(Player* player, WorldPacket& packet, bool& result) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(new WorldPacket(packet)); Push(player); int n = SetupStack(ServerEventBindings, SERVER_EVENT_ON_PACKET_RECEIVE, 2); @@ -388,7 +388,7 @@ void Eluna::OnPacketReceiveAny(Player* player, WorldPacket& packet, bool& result } void Eluna::OnPacketReceiveOne(Player* player, WorldPacket& packet, bool& result) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(new WorldPacket(packet)); Push(player); int n = SetupStack(PacketEventBindings, PACKET_EVENT_ON_PACKET_RECEIVE, OpcodesList(packet.GetOpcode()), 2); @@ -413,7 +413,7 @@ void Eluna::OnPacketReceiveOne(Player* player, WorldPacket& packet, bool& result // AddOns bool Eluna::OnAddonMessage(Player* sender, uint32 type, std::string& msg, Player* receiver, Guild* guild, Group* group, Channel* channel) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(sender); Push(type); const char* c_msg = msg.c_str(); @@ -435,21 +435,21 @@ bool Eluna::OnAddonMessage(Player* sender, uint32 type, std::string& msg, Player void Eluna::OnOpenStateChange(bool open) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(open); CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_OPEN_STATE_CHANGE); } void Eluna::OnConfigLoad(bool reload) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(reload); CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_CONFIG_LOAD); } void Eluna::OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(code); Push(mask); CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_SHUTDOWN_INIT); @@ -457,13 +457,13 @@ void Eluna::OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask) void Eluna::OnShutdownCancel() { - ELUNA_LOCK(this); + LOCK_ELUNA; CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_SHUTDOWN_CANCEL); } void Eluna::OnWorldUpdate(uint32 diff) { - ELUNA_LOCK(this); + LOCK_ELUNA; if (reload) { ReloadEluna(); @@ -478,19 +478,19 @@ void Eluna::OnWorldUpdate(uint32 diff) void Eluna::OnStartup() { - ELUNA_LOCK(this); + LOCK_ELUNA; CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_STARTUP); } void Eluna::OnShutdown() { - ELUNA_LOCK(this); + LOCK_ELUNA; CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_SHUTDOWN); } void Eluna::HandleGossipSelectOption(Player* pPlayer, Item* item, uint32 sender, uint32 action, const std::string& code) { - ELUNA_LOCK(this); + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); Push(pPlayer); @@ -507,7 +507,7 @@ void Eluna::HandleGossipSelectOption(Player* pPlayer, Item* item, uint32 sender, void Eluna::HandleGossipSelectOption(Player* pPlayer, uint32 menuId, uint32 sender, uint32 action, const std::string& code) { - ELUNA_LOCK(this); + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); Push(pPlayer); // receiver @@ -525,7 +525,7 @@ void Eluna::HandleGossipSelectOption(Player* pPlayer, uint32 menuId, uint32 send // item bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, Item* pTarget) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pCaster); Push(spellId); Push(effIndex); @@ -535,7 +535,7 @@ bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, bool Eluna::OnQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(pItem); Push(pQuest); @@ -544,7 +544,7 @@ bool Eluna::OnQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest) bool Eluna::OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) { - ELUNA_LOCK(this); + LOCK_ELUNA; ObjectGuid guid = pItem->GET_GUID(); bool castSpell = true; @@ -575,7 +575,7 @@ bool Eluna::OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) bool Eluna::OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(pItem); #ifndef TRINITY @@ -609,7 +609,7 @@ bool Eluna::OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targ bool Eluna::OnItemGossip(Player* pPlayer, Item* pItem, SpellCastTargets const& /*targets*/) { - ELUNA_LOCK(this); + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); Push(pPlayer); Push(pItem); @@ -618,7 +618,7 @@ bool Eluna::OnItemGossip(Player* pPlayer, Item* pItem, SpellCastTargets const& / bool Eluna::OnExpire(Player* pPlayer, ItemTemplate const* pProto) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(pProto->ItemId); return CallAllFunctionsBool(ItemEventBindings, ITEM_EVENT_ON_EXPIRE, pProto->ItemId); @@ -626,7 +626,7 @@ bool Eluna::OnExpire(Player* pPlayer, ItemTemplate const* pProto) bool Eluna::OnRemove(Player* pPlayer, Item* item) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(item); return CallAllFunctionsBool(ItemEventBindings, ITEM_EVENT_ON_REMOVE, item->GetEntry()); @@ -635,7 +635,7 @@ bool Eluna::OnRemove(Player* pPlayer, Item* item) // Player bool Eluna::OnCommand(Player* player, const char* text) { - ELUNA_LOCK(this); + LOCK_ELUNA; // If from console, player is NULL std::string fullcmd(text); if (!player || player->GetSession()->GetSecurity() >= SEC_ADMINISTRATOR) @@ -666,7 +666,7 @@ bool Eluna::OnCommand(Player* player, const char* text) void Eluna::OnLootItem(Player* pPlayer, Item* pItem, uint32 count, uint64 guid) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(pItem); Push(count); @@ -676,7 +676,7 @@ void Eluna::OnLootItem(Player* pPlayer, Item* pItem, uint32 count, uint64 guid) void Eluna::OnLootMoney(Player* pPlayer, uint32 amount) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(amount); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LOOT_MONEY); @@ -684,28 +684,28 @@ void Eluna::OnLootMoney(Player* pPlayer, uint32 amount) void Eluna::OnFirstLogin(Player* pPlayer) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_FIRST_LOGIN); } void Eluna::OnRepop(Player* pPlayer) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_REPOP); } void Eluna::OnResurrect(Player* pPlayer) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_RESURRECT); } void Eluna::OnQuestAbandon(Player* pPlayer, uint32 questId) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(questId); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_QUEST_ABANDON); @@ -713,7 +713,7 @@ void Eluna::OnQuestAbandon(Player* pPlayer, uint32 questId) void Eluna::OnEquip(Player* pPlayer, Item* pItem, uint8 bag, uint8 slot) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(pItem); Push(bag); @@ -723,7 +723,7 @@ void Eluna::OnEquip(Player* pPlayer, Item* pItem, uint8 bag, uint8 slot) InventoryResult Eluna::OnCanUseItem(const Player* pPlayer, uint32 itemEntry) { - ELUNA_LOCK(this); + LOCK_ELUNA; InventoryResult result = EQUIP_ERR_OK; Push(pPlayer); Push(itemEntry); @@ -744,7 +744,7 @@ InventoryResult Eluna::OnCanUseItem(const Player* pPlayer, uint32 itemEntry) } void Eluna::OnPlayerEnterCombat(Player* pPlayer, Unit* pEnemy) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(pEnemy); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_ENTER_COMBAT); @@ -752,14 +752,14 @@ void Eluna::OnPlayerEnterCombat(Player* pPlayer, Unit* pEnemy) void Eluna::OnPlayerLeaveCombat(Player* pPlayer) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LEAVE_COMBAT); } void Eluna::OnPVPKill(Player* pKiller, Player* pKilled) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pKiller); Push(pKilled); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_KILL_PLAYER); @@ -767,7 +767,7 @@ void Eluna::OnPVPKill(Player* pKiller, Player* pKilled) void Eluna::OnCreatureKill(Player* pKiller, Creature* pKilled) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pKiller); Push(pKilled); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_KILL_CREATURE); @@ -775,7 +775,7 @@ void Eluna::OnCreatureKill(Player* pKiller, Creature* pKilled) void Eluna::OnPlayerKilledByCreature(Creature* pKiller, Player* pKilled) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pKiller); Push(pKilled); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_KILLED_BY_CREATURE); @@ -783,7 +783,7 @@ void Eluna::OnPlayerKilledByCreature(Creature* pKiller, Player* pKilled) void Eluna::OnLevelChanged(Player* pPlayer, uint8 oldLevel) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(oldLevel); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LEVEL_CHANGE); @@ -791,7 +791,7 @@ void Eluna::OnLevelChanged(Player* pPlayer, uint8 oldLevel) void Eluna::OnFreeTalentPointsChanged(Player* pPlayer, uint32 newPoints) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(newPoints); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_TALENTS_CHANGE); @@ -799,7 +799,7 @@ void Eluna::OnFreeTalentPointsChanged(Player* pPlayer, uint32 newPoints) void Eluna::OnTalentsReset(Player* pPlayer, bool noCost) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(noCost); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_TALENTS_RESET); @@ -807,7 +807,7 @@ void Eluna::OnTalentsReset(Player* pPlayer, bool noCost) void Eluna::OnMoneyChanged(Player* pPlayer, int32& amount) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(amount); int amountIndex = lua_gettop(L); @@ -832,7 +832,7 @@ void Eluna::OnMoneyChanged(Player* pPlayer, int32& amount) void Eluna::OnGiveXP(Player* pPlayer, uint32& amount, Unit* pVictim) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(amount); Push(pVictim); @@ -858,7 +858,7 @@ void Eluna::OnGiveXP(Player* pPlayer, uint32& amount, Unit* pVictim) void Eluna::OnReputationChange(Player* pPlayer, uint32 factionID, int32& standing, bool incremental) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(factionID); Push(standing); @@ -885,7 +885,7 @@ void Eluna::OnReputationChange(Player* pPlayer, uint32 factionID, int32& standin void Eluna::OnDuelRequest(Player* pTarget, Player* pChallenger) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pTarget); Push(pChallenger); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_DUEL_REQUEST); @@ -893,7 +893,7 @@ void Eluna::OnDuelRequest(Player* pTarget, Player* pChallenger) void Eluna::OnDuelStart(Player* pStarter, Player* pChallenger) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pStarter); Push(pChallenger); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_DUEL_START); @@ -901,7 +901,7 @@ void Eluna::OnDuelStart(Player* pStarter, Player* pChallenger) void Eluna::OnDuelEnd(Player* pWinner, Player* pLoser, DuelCompleteType type) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pWinner); Push(pLoser); Push(type); @@ -910,7 +910,7 @@ void Eluna::OnDuelEnd(Player* pWinner, Player* pLoser, DuelCompleteType type) void Eluna::OnEmote(Player* pPlayer, uint32 emote) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(emote); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_EMOTE); @@ -918,7 +918,7 @@ void Eluna::OnEmote(Player* pPlayer, uint32 emote) void Eluna::OnTextEmote(Player* pPlayer, uint32 textEmote, uint32 emoteNum, uint64 guid) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(textEmote); Push(emoteNum); @@ -928,7 +928,7 @@ void Eluna::OnTextEmote(Player* pPlayer, uint32 textEmote, uint32 emoteNum, uint void Eluna::OnSpellCast(Player* pPlayer, Spell* pSpell, bool skipCheck) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(pSpell); Push(skipCheck); @@ -937,42 +937,42 @@ void Eluna::OnSpellCast(Player* pPlayer, Spell* pSpell, bool skipCheck) void Eluna::OnLogin(Player* pPlayer) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LOGIN); } void Eluna::OnLogout(Player* pPlayer) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LOGOUT); } void Eluna::OnCreate(Player* pPlayer) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_CHARACTER_CREATE); } void Eluna::OnDelete(uint32 guidlow) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(guidlow); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_CHARACTER_DELETE); } void Eluna::OnSave(Player* pPlayer) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_SAVE); } void Eluna::OnBindToInstance(Player* pPlayer, Difficulty difficulty, uint32 mapid, bool permanent) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(difficulty); Push(mapid); @@ -982,7 +982,7 @@ void Eluna::OnBindToInstance(Player* pPlayer, Difficulty difficulty, uint32 mapi void Eluna::OnUpdateZone(Player* pPlayer, uint32 newZone, uint32 newArea) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(newZone); Push(newArea); @@ -991,14 +991,14 @@ void Eluna::OnUpdateZone(Player* pPlayer, uint32 newZone, uint32 newArea) void Eluna::OnMapChanged(Player* player) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(player); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_MAP_CHANGE); } bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg) { - ELUNA_LOCK(this); + LOCK_ELUNA; if (lang == LANG_ADDON) return OnAddonMessage(pPlayer, type, msg, NULL, NULL, NULL, NULL); @@ -1028,7 +1028,7 @@ bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg) bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Group* pGroup) { - ELUNA_LOCK(this); + LOCK_ELUNA; if (lang == LANG_ADDON) return OnAddonMessage(pPlayer, type, msg, NULL, NULL, pGroup, NULL); @@ -1059,7 +1059,7 @@ bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Guild* pGuild) { - ELUNA_LOCK(this); + LOCK_ELUNA; if (lang == LANG_ADDON) return OnAddonMessage(pPlayer, type, msg, NULL, pGuild, NULL, NULL); @@ -1090,7 +1090,7 @@ bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Channel* pChannel) { - ELUNA_LOCK(this); + LOCK_ELUNA; if (lang == LANG_ADDON) return OnAddonMessage(pPlayer, type, msg, NULL, NULL, NULL, pChannel); @@ -1121,7 +1121,7 @@ bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Player* pReceiver) { - ELUNA_LOCK(this); + LOCK_ELUNA; if (lang == LANG_ADDON) return OnAddonMessage(pPlayer, type, msg, pReceiver, NULL, NULL, NULL); @@ -1155,21 +1155,21 @@ bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, // Vehicle void Eluna::OnInstall(Vehicle* vehicle) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(vehicle); CallAllFunctions(VehicleEventBindings, VEHICLE_EVENT_ON_INSTALL); } void Eluna::OnUninstall(Vehicle* vehicle) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(vehicle); CallAllFunctions(VehicleEventBindings, VEHICLE_EVENT_ON_UNINSTALL); } void Eluna::OnInstallAccessory(Vehicle* vehicle, Creature* accessory) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(vehicle); Push(accessory); CallAllFunctions(VehicleEventBindings, VEHICLE_EVENT_ON_INSTALL_ACCESSORY); @@ -1177,7 +1177,7 @@ void Eluna::OnInstallAccessory(Vehicle* vehicle, Creature* accessory) void Eluna::OnAddPassenger(Vehicle* vehicle, Unit* passenger, int8 seatId) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(vehicle); Push(passenger); Push(seatId); @@ -1186,7 +1186,7 @@ void Eluna::OnAddPassenger(Vehicle* vehicle, Unit* passenger, int8 seatId) void Eluna::OnRemovePassenger(Vehicle* vehicle, Unit* passenger) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(vehicle); Push(passenger); CallAllFunctions(VehicleEventBindings, VEHICLE_EVENT_ON_REMOVE_PASSENGER); @@ -1196,7 +1196,7 @@ void Eluna::OnRemovePassenger(Vehicle* vehicle, Unit* passenger) void Eluna::OnAddMember(Guild* guild, Player* player, uint32 plRank) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(guild); Push(player); Push(plRank); @@ -1205,7 +1205,7 @@ void Eluna::OnAddMember(Guild* guild, Player* player, uint32 plRank) void Eluna::OnRemoveMember(Guild* guild, Player* player, bool isDisbanding) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(guild); Push(player); Push(isDisbanding); @@ -1214,7 +1214,7 @@ void Eluna::OnRemoveMember(Guild* guild, Player* player, bool isDisbanding) void Eluna::OnMOTDChanged(Guild* guild, const std::string& newMotd) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(guild); Push(newMotd); CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_MOTD_CHANGE); @@ -1222,7 +1222,7 @@ void Eluna::OnMOTDChanged(Guild* guild, const std::string& newMotd) void Eluna::OnInfoChanged(Guild* guild, const std::string& newInfo) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(guild); Push(newInfo); CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_INFO_CHANGE); @@ -1230,7 +1230,7 @@ void Eluna::OnInfoChanged(Guild* guild, const std::string& newInfo) void Eluna::OnCreate(Guild* guild, Player* leader, const std::string& name) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(guild); Push(leader); Push(name); @@ -1239,14 +1239,14 @@ void Eluna::OnCreate(Guild* guild, Player* leader, const std::string& name) void Eluna::OnDisband(Guild* guild) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(guild); CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_DISBAND); } void Eluna::OnMemberWitdrawMoney(Guild* guild, Player* player, uint32& amount, bool isRepair) // isRepair not a part of Mangos, implement? { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(guild); Push(player); Push(amount); @@ -1273,7 +1273,7 @@ void Eluna::OnMemberWitdrawMoney(Guild* guild, Player* player, uint32& amount, b void Eluna::OnMemberDepositMoney(Guild* guild, Player* player, uint32& amount) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(guild); Push(player); Push(amount); @@ -1300,7 +1300,7 @@ void Eluna::OnMemberDepositMoney(Guild* guild, Player* player, uint32& amount) void Eluna::OnItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank, uint8 srcContainer, uint8 srcSlotId, bool isDestBank, uint8 destContainer, uint8 destSlotId) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(guild); Push(player); Push(pItem); @@ -1315,7 +1315,7 @@ void Eluna::OnItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank void Eluna::OnEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(guild); Push(eventType); Push(playerGuid1); @@ -1326,7 +1326,7 @@ void Eluna::OnEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 pl void Eluna::OnBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(guild); Push(eventType); Push(tabId); @@ -1339,7 +1339,7 @@ void Eluna::OnBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uint32 playe // Group void Eluna::OnAddMember(Group* group, uint64 guid) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(group); Push(guid); CallAllFunctions(GroupEventBindings, GROUP_EVENT_ON_MEMBER_ADD); @@ -1347,7 +1347,7 @@ void Eluna::OnAddMember(Group* group, uint64 guid) void Eluna::OnInviteMember(Group* group, uint64 guid) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(group); Push(guid); CallAllFunctions(GroupEventBindings, GROUP_EVENT_ON_MEMBER_INVITE); @@ -1355,7 +1355,7 @@ void Eluna::OnInviteMember(Group* group, uint64 guid) void Eluna::OnRemoveMember(Group* group, uint64 guid, uint8 method) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(group); Push(guid); Push(method); @@ -1364,7 +1364,7 @@ void Eluna::OnRemoveMember(Group* group, uint64 guid, uint8 method) void Eluna::OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(group); Push(newLeaderGuid); Push(oldLeaderGuid); @@ -1373,14 +1373,14 @@ void Eluna::OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderG void Eluna::OnDisband(Group* group) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(group); CallAllFunctions(GroupEventBindings, GROUP_EVENT_ON_DISBAND); } void Eluna::OnCreate(Group* group, uint64 leaderGuid, GroupType groupType) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(group); Push(leaderGuid); Push(groupType); @@ -1390,33 +1390,33 @@ void Eluna::OnCreate(Group* group, uint64 leaderGuid, GroupType groupType) /* Map */ void Eluna::OnCreate(Map* map) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(map); CallAllFunctions(ServerEventBindings, MAP_EVENT_ON_CREATE); } void Eluna::OnDestroy(Map* map) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(map); CallAllFunctions(ServerEventBindings, MAP_EVENT_ON_DESTROY); } void Eluna::OnPlayerEnter(Map* map, Player* player) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(map); Push(player); CallAllFunctions(ServerEventBindings, MAP_EVENT_ON_PLAYER_ENTER); } void Eluna::OnPlayerLeave(Map* map, Player* player) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(map); Push(player); CallAllFunctions(ServerEventBindings, MAP_EVENT_ON_PLAYER_LEAVE); } void Eluna::OnUpdate(Map* map, uint32 diff) { - ELUNA_LOCK(this); + LOCK_ELUNA; // enable this for multithread // eventMgr->globalProcessor->Update(diff); Push(map); @@ -1425,13 +1425,13 @@ void Eluna::OnUpdate(Map* map, uint32 diff) } void Eluna::OnRemove(GameObject* gameobject) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(gameobject); CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_DELETE_GAMEOBJECT); } void Eluna::OnRemove(Creature* creature) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(creature); CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_DELETE_CREATURE); } @@ -1439,7 +1439,7 @@ void Eluna::OnRemove(Creature* creature) // creature bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, Creature* pTarget) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pCaster); Push(spellId); Push(effIndex); @@ -1449,7 +1449,7 @@ bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, bool Eluna::OnGossipHello(Player* pPlayer, Creature* pCreature) { - ELUNA_LOCK(this); + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); Push(pPlayer); Push(pCreature); @@ -1458,7 +1458,7 @@ bool Eluna::OnGossipHello(Player* pPlayer, Creature* pCreature) bool Eluna::OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action) { - ELUNA_LOCK(this); + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); Push(pPlayer); Push(pCreature); @@ -1469,7 +1469,7 @@ bool Eluna::OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 sender, bool Eluna::OnGossipSelectCode(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action, const char* code) { - ELUNA_LOCK(this); + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); Push(pPlayer); Push(pCreature); @@ -1481,7 +1481,7 @@ bool Eluna::OnGossipSelectCode(Player* pPlayer, Creature* pCreature, uint32 send bool Eluna::OnQuestAccept(Player* pPlayer, Creature* pCreature, Quest const* pQuest) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(pCreature); Push(pQuest); @@ -1490,7 +1490,7 @@ bool Eluna::OnQuestAccept(Player* pPlayer, Creature* pCreature, Quest const* pQu bool Eluna::OnQuestReward(Player* pPlayer, Creature* pCreature, Quest const* pQuest, uint32 opt) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(pCreature); Push(pQuest); @@ -1500,7 +1500,7 @@ bool Eluna::OnQuestReward(Player* pPlayer, Creature* pCreature, Quest const* pQu uint32 Eluna::GetDialogStatus(Player* pPlayer, Creature* pCreature) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(pCreature); CallAllFunctions(CreatureEventBindings, CREATURE_EVENT_ON_DIALOG_STATUS, pCreature->GetEntry()); @@ -1509,21 +1509,21 @@ uint32 Eluna::GetDialogStatus(Player* pPlayer, Creature* pCreature) void Eluna::OnAddToWorld(Creature* creature) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(creature); CallAllFunctions(CreatureEventBindings, CREATURE_EVENT_ON_ADD, creature->GetEntry()); } void Eluna::OnRemoveFromWorld(Creature* creature) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(creature); CallAllFunctions(CreatureEventBindings, CREATURE_EVENT_ON_REMOVE, creature->GetEntry()); } bool Eluna::OnSummoned(Creature* pCreature, Unit* pSummoner) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pCreature); Push(pSummoner); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_SUMMONED, pCreature->GetEntry()); @@ -1531,7 +1531,7 @@ bool Eluna::OnSummoned(Creature* pCreature, Unit* pSummoner) bool Eluna::UpdateAI(Creature* me, const uint32 diff) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); Push(diff); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_AIUPDATE, me->GetEntry()); @@ -1541,7 +1541,7 @@ bool Eluna::UpdateAI(Creature* me, const uint32 diff) //Called at creature aggro either by MoveInLOS or Attack Start bool Eluna::EnterCombat(Creature* me, Unit* target) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); Push(target); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_ENTER_COMBAT, me->GetEntry()); @@ -1550,7 +1550,7 @@ bool Eluna::EnterCombat(Creature* me, Unit* target) // Called at any Damage from any attacker (before damage apply) bool Eluna::DamageTaken(Creature* me, Unit* attacker, uint32& damage) { - ELUNA_LOCK(this); + LOCK_ELUNA; bool result = false; Push(me); Push(attacker); @@ -1582,7 +1582,7 @@ bool Eluna::DamageTaken(Creature* me, Unit* attacker, uint32& damage) //Called at creature death bool Eluna::JustDied(Creature* me, Unit* killer) { - ELUNA_LOCK(this); + LOCK_ELUNA; On_Reset(me); Push(me); Push(killer); @@ -1592,7 +1592,7 @@ bool Eluna::JustDied(Creature* me, Unit* killer) //Called at creature killing another unit bool Eluna::KilledUnit(Creature* me, Unit* victim) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); Push(victim); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_TARGET_DIED, me->GetEntry()); @@ -1601,7 +1601,7 @@ bool Eluna::KilledUnit(Creature* me, Unit* victim) // Called when the creature summon successfully other creature bool Eluna::JustSummoned(Creature* me, Creature* summon) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); Push(summon); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_JUST_SUMMONED_CREATURE, me->GetEntry()); @@ -1610,7 +1610,7 @@ bool Eluna::JustSummoned(Creature* me, Creature* summon) // Called when a summoned creature is despawned bool Eluna::SummonedCreatureDespawn(Creature* me, Creature* summon) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); Push(summon); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_SUMMONED_CREATURE_DESPAWN, me->GetEntry()); @@ -1619,7 +1619,7 @@ bool Eluna::SummonedCreatureDespawn(Creature* me, Creature* summon) //Called at waypoint reached or PointMovement end bool Eluna::MovementInform(Creature* me, uint32 type, uint32 id) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); Push(type); Push(id); @@ -1629,7 +1629,7 @@ bool Eluna::MovementInform(Creature* me, uint32 type, uint32 id) // Called before EnterCombat even before the creature is in combat. bool Eluna::AttackStart(Creature* me, Unit* target) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); Push(target); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_PRE_COMBAT, me->GetEntry()); @@ -1638,7 +1638,7 @@ bool Eluna::AttackStart(Creature* me, Unit* target) // Called for reaction at stopping attack at no attackers or targets bool Eluna::EnterEvadeMode(Creature* me) { - ELUNA_LOCK(this); + LOCK_ELUNA; On_Reset(me); Push(me); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_LEAVE_COMBAT, me->GetEntry()); @@ -1647,7 +1647,7 @@ bool Eluna::EnterEvadeMode(Creature* me) // Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc) bool Eluna::AttackedBy(Creature* me, Unit* attacker) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); Push(attacker); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_ATTACKED_AT, me->GetEntry()); @@ -1656,7 +1656,7 @@ bool Eluna::AttackedBy(Creature* me, Unit* attacker) // Called when creature is spawned or respawned (for reseting variables) bool Eluna::JustRespawned(Creature* me) { - ELUNA_LOCK(this); + LOCK_ELUNA; On_Reset(me); Push(me); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_SPAWN, me->GetEntry()); @@ -1665,7 +1665,7 @@ bool Eluna::JustRespawned(Creature* me) // Called at reaching home after evade bool Eluna::JustReachedHome(Creature* me) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_REACH_HOME, me->GetEntry()); } @@ -1673,7 +1673,7 @@ bool Eluna::JustReachedHome(Creature* me) // Called at text emote receive from player bool Eluna::ReceiveEmote(Creature* me, Player* player, uint32 emoteId) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); Push(player); Push(emoteId); @@ -1683,7 +1683,7 @@ bool Eluna::ReceiveEmote(Creature* me, Player* player, uint32 emoteId) // called when the corpse of this creature gets removed bool Eluna::CorpseRemoved(Creature* me, uint32& respawnDelay) { - ELUNA_LOCK(this); + LOCK_ELUNA; bool result = false; Push(me); Push(respawnDelay); @@ -1713,7 +1713,7 @@ bool Eluna::CorpseRemoved(Creature* me, uint32& respawnDelay) bool Eluna::MoveInLineOfSight(Creature* me, Unit* who) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); Push(who); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_MOVE_IN_LOS, me->GetEntry()); @@ -1722,7 +1722,7 @@ bool Eluna::MoveInLineOfSight(Creature* me, Unit* who) // Called on creature initial spawn, respawn, death, evade (leave combat) void Eluna::On_Reset(Creature* me) // Not an override, custom { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); CallAllFunctions(CreatureEventBindings, CREATURE_EVENT_ON_RESET, me->GetEntry()); } @@ -1730,7 +1730,7 @@ void Eluna::On_Reset(Creature* me) // Not an override, custom // Called when hit by a spell bool Eluna::SpellHit(Creature* me, Unit* caster, SpellInfo const* spell) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); Push(caster); Push(spell->Id); // Pass spell object? @@ -1740,7 +1740,7 @@ bool Eluna::SpellHit(Creature* me, Unit* caster, SpellInfo const* spell) // Called when spell hits a target bool Eluna::SpellHitTarget(Creature* me, Unit* target, SpellInfo const* spell) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); Push(target); Push(spell->Id); // Pass spell object? @@ -1751,7 +1751,7 @@ bool Eluna::SpellHitTarget(Creature* me, Unit* target, SpellInfo const* spell) bool Eluna::SummonedCreatureDies(Creature* me, Creature* summon, Unit* killer) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); Push(summon); Push(killer); @@ -1761,7 +1761,7 @@ bool Eluna::SummonedCreatureDies(Creature* me, Creature* summon, Unit* killer) // Called when owner takes damage bool Eluna::OwnerAttackedBy(Creature* me, Unit* attacker) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); Push(attacker); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_OWNER_ATTACKED_AT, me->GetEntry()); @@ -1770,7 +1770,7 @@ bool Eluna::OwnerAttackedBy(Creature* me, Unit* attacker) // Called when owner attacks something bool Eluna::OwnerAttacked(Creature* me, Unit* target) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(me); Push(target); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_OWNER_ATTACKED, me->GetEntry()); @@ -1973,7 +1973,7 @@ struct ElunaCreatureAI : ScriptedAI // gameobject bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, GameObject* pTarget) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pCaster); Push(spellId); Push(effIndex); @@ -1983,7 +1983,7 @@ bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, bool Eluna::OnGossipHello(Player* pPlayer, GameObject* pGameObject) { - ELUNA_LOCK(this); + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); Push(pPlayer); Push(pGameObject); @@ -1992,7 +1992,7 @@ bool Eluna::OnGossipHello(Player* pPlayer, GameObject* pGameObject) bool Eluna::OnGossipSelect(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action) { - ELUNA_LOCK(this); + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); Push(pPlayer); Push(pGameObject); @@ -2003,7 +2003,7 @@ bool Eluna::OnGossipSelect(Player* pPlayer, GameObject* pGameObject, uint32 send bool Eluna::OnGossipSelectCode(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action, const char* code) { - ELUNA_LOCK(this); + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); Push(pPlayer); Push(pGameObject); @@ -2015,7 +2015,7 @@ bool Eluna::OnGossipSelectCode(Player* pPlayer, GameObject* pGameObject, uint32 bool Eluna::OnQuestAccept(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(pGameObject); Push(pQuest); @@ -2024,7 +2024,7 @@ bool Eluna::OnQuestAccept(Player* pPlayer, GameObject* pGameObject, Quest const* void Eluna::UpdateAI(GameObject* pGameObject, uint32 diff) { - ELUNA_LOCK(this); + LOCK_ELUNA; pGameObject->elunaEvents->Update(diff); Push(pGameObject); Push(diff); @@ -2033,7 +2033,7 @@ void Eluna::UpdateAI(GameObject* pGameObject, uint32 diff) bool Eluna::OnQuestReward(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest, uint32 opt) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(pGameObject); Push(pQuest); @@ -2043,7 +2043,7 @@ bool Eluna::OnQuestReward(Player* pPlayer, GameObject* pGameObject, Quest const* uint32 Eluna::GetDialogStatus(Player* pPlayer, GameObject* pGameObject) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pPlayer); Push(pGameObject); CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_DIALOG_STATUS, pGameObject->GetEntry()); @@ -2054,7 +2054,7 @@ uint32 Eluna::GetDialogStatus(Player* pPlayer, GameObject* pGameObject) #ifndef TBC void Eluna::OnDestroyed(GameObject* pGameObject, Player* pPlayer) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pGameObject); Push(pPlayer); CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_DESTROYED, pGameObject->GetEntry()); @@ -2062,7 +2062,7 @@ void Eluna::OnDestroyed(GameObject* pGameObject, Player* pPlayer) void Eluna::OnDamaged(GameObject* pGameObject, Player* pPlayer) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pGameObject); Push(pPlayer); CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_DAMAGED, pGameObject->GetEntry()); @@ -2072,7 +2072,7 @@ void Eluna::OnDamaged(GameObject* pGameObject, Player* pPlayer) void Eluna::OnLootStateChanged(GameObject* pGameObject, uint32 state) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pGameObject); Push(state); CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE, pGameObject->GetEntry()); @@ -2080,7 +2080,7 @@ void Eluna::OnLootStateChanged(GameObject* pGameObject, uint32 state) void Eluna::OnGameObjectStateChanged(GameObject* pGameObject, uint32 state) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(pGameObject); Push(state); CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED, pGameObject->GetEntry()); @@ -2088,28 +2088,28 @@ void Eluna::OnGameObjectStateChanged(GameObject* pGameObject, uint32 state) void Eluna::OnSpawn(GameObject* gameobject) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(gameobject); CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_SPAWN, gameobject->GetEntry()); } void Eluna::OnAddToWorld(GameObject* gameobject) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(gameobject); CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_ADD, gameobject->GetEntry()); } void Eluna::OnRemoveFromWorld(GameObject* gameobject) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(gameobject); CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_REMOVE, gameobject->GetEntry()); } CreatureAI* Eluna::GetAI(Creature* creature) { - ELUNA_LOCK(this); + LOCK_ELUNA; if (!CreatureEventBindings->HasEvents(creature->GetEntry())) return NULL; return new ElunaCreatureAI(creature); @@ -2117,7 +2117,7 @@ CreatureAI* Eluna::GetAI(Creature* creature) void Eluna::OnBGStart(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(bg); Push(bgId); Push(instanceId); @@ -2126,7 +2126,7 @@ void Eluna::OnBGStart(BattleGround* bg, BattleGroundTypeId bgId, uint32 instance void Eluna::OnBGEnd(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId, Team winner) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(bg); Push(bgId); Push(instanceId); @@ -2136,7 +2136,7 @@ void Eluna::OnBGEnd(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId void Eluna::OnBGCreate(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(bg); Push(bgId); Push(instanceId); @@ -2145,7 +2145,7 @@ void Eluna::OnBGCreate(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanc void Eluna::OnBGDestroy(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) { - ELUNA_LOCK(this); + LOCK_ELUNA; Push(bg); Push(bgId); Push(instanceId); diff --git a/LuaEngine.h b/LuaEngine.h index f9e603b..92d4716 100644 --- a/LuaEngine.h +++ b/LuaEngine.h @@ -459,5 +459,5 @@ template<> WorldObject* Eluna::CHECKOBJ(lua_State* L, int narg, boo template<> ElunaObject* Eluna::CHECKOBJ(lua_State* L, int narg, bool error); #define sEluna Eluna::GEluna -#define ELUNA_LOCK(E) Eluna::Guard __guard(Eluna::lock); +#define LOCK_ELUNA Eluna::Guard __guard(Eluna::lock) #endif From 6371728547dc9906604464f48f1f11ef21e5d5c0 Mon Sep 17 00:00:00 2001 From: Patman64 Date: Mon, 5 Jan 2015 23:48:18 -0500 Subject: [PATCH 09/10] Return from hooks early if no bindings exist. Also add locking to the bindings to allow for thread-safe checking if bindings exist. --- ElunaBinding.h | 30 ++- HookMgr.cpp | 482 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 489 insertions(+), 23 deletions(-) diff --git a/ElunaBinding.h b/ElunaBinding.h index 831e1f4..5d3c0f6 100644 --- a/ElunaBinding.h +++ b/ElunaBinding.h @@ -61,7 +61,7 @@ public: }; template -class EventBind : public ElunaBind +class EventBind : public ElunaBind, public ElunaUtil::RWLockable { public: EventBind(const char* bindGroupName, Eluna& _E) : ElunaBind(bindGroupName, _E) @@ -71,6 +71,8 @@ public: // unregisters all registered functions and clears all registered events from the bind std::maps (reset) void Clear() override { + WriteGuard guard(GetLock()); + for (EventToFunctionsMap::iterator itr = Bindings.begin(); itr != Bindings.end(); ++itr) { FunctionRefVector& funcrefvec = itr->second; @@ -83,6 +85,8 @@ public: void Clear(uint32 event_id) { + WriteGuard guard(GetLock()); + for (FunctionRefVector::iterator itr = Bindings[event_id].begin(); itr != Bindings[event_id].end(); ++itr) delete *itr; Bindings[event_id].clear(); @@ -91,6 +95,8 @@ public: // Pushes the function references and updates the counters on the binds and erases them if the counter would reach 0 void PushFuncRefs(lua_State* L, int event_id) { + WriteGuard guard(GetLock()); + for (FunctionRefVector::iterator it = Bindings[event_id].begin(); it != Bindings[event_id].end();) { FunctionRefVector::iterator it_old = it++; @@ -115,12 +121,15 @@ public: void Insert(int eventId, int funcRef, uint32 shots) // Inserts a new registered event { + WriteGuard guard(GetLock()); Bindings[eventId].push_back(new Binding(E, funcRef, shots)); } // Checks if there are events for ID - bool HasEvents(T eventId) const + bool HasEvents(T eventId) { + ReadGuard guard(GetLock()); + if (Bindings.empty()) return false; if (Bindings.find(eventId) == Bindings.end()) @@ -132,7 +141,7 @@ public: }; template -class EntryBind : public ElunaBind +class EntryBind : public ElunaBind, public ElunaUtil::RWLockable { public: typedef UNORDERED_MAP EntryToEventsMap; @@ -144,6 +153,8 @@ public: // unregisters all registered functions and clears all registered events from the bindmap void Clear() override { + WriteGuard guard(GetLock()); + for (EntryToEventsMap::iterator itr = Bindings.begin(); itr != Bindings.end(); ++itr) { EventToFunctionsMap& funcmap = itr->second; @@ -161,6 +172,8 @@ public: void Clear(uint32 entry, uint32 event_id) { + WriteGuard guard(GetLock()); + for (FunctionRefVector::iterator itr = Bindings[entry][event_id].begin(); itr != Bindings[entry][event_id].end(); ++itr) delete *itr; Bindings[entry][event_id].clear(); @@ -169,6 +182,8 @@ public: // Pushes the function references and updates the counters on the binds and erases them if the counter would reach 0 void PushFuncRefs(lua_State* L, int event_id, uint32 entry) { + WriteGuard guard(GetLock()); + for (FunctionRefVector::iterator it = Bindings[entry][event_id].begin(); it != Bindings[entry][event_id].end();) { FunctionRefVector::iterator it_old = it++; @@ -196,12 +211,15 @@ public: void Insert(uint32 entryId, int eventId, int funcRef, uint32 shots) // Inserts a new registered event { + WriteGuard guard(GetLock()); Bindings[entryId][eventId].push_back(new Binding(E, funcRef, shots)); } // Returns true if the entry has registered binds - bool HasEvents(uint32 entryId, int eventId) const + bool HasEvents(T eventId, uint32 entryId) { + ReadGuard guard(GetLock()); + if (Bindings.empty()) return false; @@ -212,8 +230,10 @@ public: return itr->second.find(eventId) != itr->second.end(); } - bool HasEvents(uint32 entryId) const + bool HasEvents(uint32 entryId) { + ReadGuard guard(GetLock()); + if (Bindings.empty()) return false; diff --git a/HookMgr.cpp b/HookMgr.cpp index 4d9e8e1..6084275 100644 --- a/HookMgr.cpp +++ b/HookMgr.cpp @@ -1,8 +1,8 @@ /* -* Copyright (C) 2010 - 2015 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ + * Copyright (C) 2010 - 2015 Eluna Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ #include "HookMgr.h" #include "LuaEngine.h" @@ -32,6 +32,10 @@ using namespace HookMgr; * * A. If results will be IGNORED: * + * // Return early if there are no bindings. + * if (!WhateverBindings->HasEvents(SOME_EVENT_TYPE)) + * return; + * * // Lock out any other threads. * LOCK_ELUNA; * @@ -46,6 +50,10 @@ using namespace HookMgr; * * B. If results will be USED: * + * // Return early if there are no bindings. + * if (!WhateverBindings->HasEvents(SOME_EVENT_TYPE)) + * return; + * * // Lock out any other threads. * LOCK_ELUNA; * @@ -237,12 +245,18 @@ bool Eluna::CallAllFunctionsBool(EventBind* event_bindings, EntryBind* ent void Eluna::OnLuaStateClose() { + if (!ServerEventBindings->HasEvents(ELUNA_EVENT_ON_LUA_STATE_CLOSE)) + return; + LOCK_ELUNA; CallAllFunctions(ServerEventBindings, ELUNA_EVENT_ON_LUA_STATE_CLOSE); } void Eluna::OnLuaStateOpen() { + if (!ServerEventBindings->HasEvents(ELUNA_EVENT_ON_LUA_STATE_OPEN)) + return; + LOCK_ELUNA; CallAllFunctions(ServerEventBindings, ELUNA_EVENT_ON_LUA_STATE_OPEN); } @@ -250,6 +264,9 @@ void Eluna::OnLuaStateOpen() // areatrigger bool Eluna::OnAreaTrigger(Player* pPlayer, AreaTriggerEntry const* pTrigger) { + if (!ServerEventBindings->HasEvents(TRIGGER_EVENT_ON_TRIGGER)) + return false; + LOCK_ELUNA; Push(pPlayer); Push(pTrigger->id); @@ -258,6 +275,9 @@ bool Eluna::OnAreaTrigger(Player* pPlayer, AreaTriggerEntry const* pTrigger) // weather void Eluna::OnChange(Weather* weather, WeatherState state, float grade) { + if (!ServerEventBindings->HasEvents(WEATHER_EVENT_ON_CHANGE)) + return; + LOCK_ELUNA; Push(weather->GetZone()); Push(state); @@ -267,6 +287,9 @@ void Eluna::OnChange(Weather* weather, WeatherState state, float grade) // Auction House void Eluna::OnAdd(AuctionHouseObject* ah) { + if (!ServerEventBindings->HasEvents(AUCTION_EVENT_ON_ADD)) + return; + LOCK_ELUNA; Push(ah); CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_ADD); @@ -274,6 +297,9 @@ void Eluna::OnAdd(AuctionHouseObject* ah) void Eluna::OnRemove(AuctionHouseObject* ah) { + if (!ServerEventBindings->HasEvents(AUCTION_EVENT_ON_REMOVE)) + return; + LOCK_ELUNA; Push(ah); CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_REMOVE); @@ -281,6 +307,9 @@ void Eluna::OnRemove(AuctionHouseObject* ah) void Eluna::OnSuccessful(AuctionHouseObject* ah) { + if (!ServerEventBindings->HasEvents(AUCTION_EVENT_ON_SUCCESSFUL)) + return; + LOCK_ELUNA; Push(ah); CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_SUCCESSFUL); @@ -288,6 +317,9 @@ void Eluna::OnSuccessful(AuctionHouseObject* ah) void Eluna::OnExpire(AuctionHouseObject* ah) { + if (!ServerEventBindings->HasEvents(AUCTION_EVENT_ON_EXPIRE)) + return; + LOCK_ELUNA; Push(ah); CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_EXPIRE); @@ -296,7 +328,6 @@ void Eluna::OnExpire(AuctionHouseObject* ah) // Packet bool Eluna::OnPacketSend(WorldSession* session, WorldPacket& packet) { - LOCK_ELUNA; bool result = true; Player* player = NULL; if (session) @@ -307,6 +338,9 @@ bool Eluna::OnPacketSend(WorldSession* session, WorldPacket& packet) } void Eluna::OnPacketSendAny(Player* player, WorldPacket& packet, bool& result) { + if (!ServerEventBindings->HasEvents(SERVER_EVENT_ON_PACKET_SEND)) + return; + LOCK_ELUNA; Push(new WorldPacket(packet)); Push(player); @@ -330,6 +364,9 @@ void Eluna::OnPacketSendAny(Player* player, WorldPacket& packet, bool& result) } void Eluna::OnPacketSendOne(Player* player, WorldPacket& packet, bool& result) { + if (!PacketEventBindings->HasEvents(PACKET_EVENT_ON_PACKET_SEND, packet.GetOpcode())) + return; + LOCK_ELUNA; Push(new WorldPacket(packet)); Push(player); @@ -354,7 +391,6 @@ void Eluna::OnPacketSendOne(Player* player, WorldPacket& packet, bool& result) bool Eluna::OnPacketReceive(WorldSession* session, WorldPacket& packet) { - LOCK_ELUNA; bool result = true; Player* player = NULL; if (session) @@ -365,6 +401,9 @@ bool Eluna::OnPacketReceive(WorldSession* session, WorldPacket& packet) } void Eluna::OnPacketReceiveAny(Player* player, WorldPacket& packet, bool& result) { + if (!ServerEventBindings->HasEvents(SERVER_EVENT_ON_PACKET_RECEIVE)) + return; + LOCK_ELUNA; Push(new WorldPacket(packet)); Push(player); @@ -388,10 +427,13 @@ void Eluna::OnPacketReceiveAny(Player* player, WorldPacket& packet, bool& result } void Eluna::OnPacketReceiveOne(Player* player, WorldPacket& packet, bool& result) { + if (!PacketEventBindings->HasEvents(PACKET_EVENT_ON_PACKET_RECEIVE, packet.GetOpcode())) + return; + LOCK_ELUNA; Push(new WorldPacket(packet)); Push(player); - int n = SetupStack(PacketEventBindings, PACKET_EVENT_ON_PACKET_RECEIVE, OpcodesList(packet.GetOpcode()), 2); + int n = SetupStack(PacketEventBindings, PACKET_EVENT_ON_PACKET_RECEIVE, OpcodesList(), 2); while (n > 0) { @@ -413,6 +455,9 @@ void Eluna::OnPacketReceiveOne(Player* player, WorldPacket& packet, bool& result // AddOns bool Eluna::OnAddonMessage(Player* sender, uint32 type, std::string& msg, Player* receiver, Guild* guild, Group* group, Channel* channel) { + if (!ServerEventBindings->HasEvents(ADDON_EVENT_ON_MESSAGE)) + return true; + LOCK_ELUNA; Push(sender); Push(type); @@ -435,6 +480,9 @@ bool Eluna::OnAddonMessage(Player* sender, uint32 type, std::string& msg, Player void Eluna::OnOpenStateChange(bool open) { + if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_OPEN_STATE_CHANGE)) + return; + LOCK_ELUNA; Push(open); CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_OPEN_STATE_CHANGE); @@ -442,6 +490,9 @@ void Eluna::OnOpenStateChange(bool open) void Eluna::OnConfigLoad(bool reload) { + if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_CONFIG_LOAD)) + return; + LOCK_ELUNA; Push(reload); CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_CONFIG_LOAD); @@ -449,6 +500,9 @@ void Eluna::OnConfigLoad(bool reload) void Eluna::OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask) { + if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_SHUTDOWN_INIT)) + return; + LOCK_ELUNA; Push(code); Push(mask); @@ -457,6 +511,9 @@ void Eluna::OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask) void Eluna::OnShutdownCancel() { + if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_SHUTDOWN_CANCEL)) + return; + LOCK_ELUNA; CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_SHUTDOWN_CANCEL); } @@ -464,6 +521,7 @@ void Eluna::OnShutdownCancel() void Eluna::OnWorldUpdate(uint32 diff) { LOCK_ELUNA; + if (reload) { ReloadEluna(); @@ -472,24 +530,36 @@ void Eluna::OnWorldUpdate(uint32 diff) eventMgr->globalProcessor->Update(diff); + if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_UPDATE)) + return; + Push(diff); CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_UPDATE); } void Eluna::OnStartup() { + if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_STARTUP)) + return; + LOCK_ELUNA; CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_STARTUP); } void Eluna::OnShutdown() { + if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_SHUTDOWN)) + return; + LOCK_ELUNA; CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_SHUTDOWN); } void Eluna::HandleGossipSelectOption(Player* pPlayer, Item* item, uint32 sender, uint32 action, const std::string& code) { + if (!ItemGossipBindings->HasEvents(GOSSIP_EVENT_ON_SELECT, item->GetEntry())) + return; + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); @@ -507,6 +577,9 @@ void Eluna::HandleGossipSelectOption(Player* pPlayer, Item* item, uint32 sender, void Eluna::HandleGossipSelectOption(Player* pPlayer, uint32 menuId, uint32 sender, uint32 action, const std::string& code) { + if (!playerGossipBindings->HasEvents(GOSSIP_EVENT_ON_SELECT, menuId)) + return; + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); @@ -525,6 +598,9 @@ void Eluna::HandleGossipSelectOption(Player* pPlayer, uint32 menuId, uint32 send // item bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, Item* pTarget) { + if (!ItemEventBindings->HasEvents(ITEM_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry())) + return false; + LOCK_ELUNA; Push(pCaster); Push(spellId); @@ -535,6 +611,9 @@ bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, bool Eluna::OnQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest) { + if (!ItemEventBindings->HasEvents(ITEM_EVENT_ON_QUEST_ACCEPT, pItem->GetEntry())) + return false; + LOCK_ELUNA; Push(pPlayer); Push(pItem); @@ -544,7 +623,6 @@ bool Eluna::OnQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest) bool Eluna::OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) { - LOCK_ELUNA; ObjectGuid guid = pItem->GET_GUID(); bool castSpell = true; @@ -575,6 +653,9 @@ bool Eluna::OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) bool Eluna::OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) { + if (!ItemEventBindings->HasEvents(ITEM_EVENT_ON_USE, pItem->GetEntry())) + return false; + LOCK_ELUNA; Push(pPlayer); Push(pItem); @@ -609,6 +690,9 @@ bool Eluna::OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targ bool Eluna::OnItemGossip(Player* pPlayer, Item* pItem, SpellCastTargets const& /*targets*/) { + if (!ItemGossipBindings->HasEvents(GOSSIP_EVENT_ON_HELLO, pItem->GetEntry())) + return false; + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); Push(pPlayer); @@ -618,6 +702,9 @@ bool Eluna::OnItemGossip(Player* pPlayer, Item* pItem, SpellCastTargets const& / bool Eluna::OnExpire(Player* pPlayer, ItemTemplate const* pProto) { + if (!ItemEventBindings->HasEvents(ITEM_EVENT_ON_EXPIRE, pProto->ItemId)) + return false; + LOCK_ELUNA; Push(pPlayer); Push(pProto->ItemId); @@ -626,6 +713,9 @@ bool Eluna::OnExpire(Player* pPlayer, ItemTemplate const* pProto) bool Eluna::OnRemove(Player* pPlayer, Item* item) { + if (!ItemEventBindings->HasEvents(ITEM_EVENT_ON_REMOVE, item->GetEntry())) + return false; + LOCK_ELUNA; Push(pPlayer); Push(item); @@ -635,7 +725,6 @@ bool Eluna::OnRemove(Player* pPlayer, Item* item) // Player bool Eluna::OnCommand(Player* player, const char* text) { - LOCK_ELUNA; // If from console, player is NULL std::string fullcmd(text); if (!player || player->GetSession()->GetSecurity() >= SEC_ADMINISTRATOR) @@ -659,6 +748,10 @@ bool Eluna::OnCommand(Player* player, const char* text) } } + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_COMMAND)) + return true; + + LOCK_ELUNA; Push(player); Push(fullcmd); return CallAllFunctionsBool(PlayerEventBindings, PLAYER_EVENT_ON_COMMAND, true); @@ -666,6 +759,9 @@ bool Eluna::OnCommand(Player* player, const char* text) void Eluna::OnLootItem(Player* pPlayer, Item* pItem, uint32 count, uint64 guid) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_LOOT_ITEM)) + return; + LOCK_ELUNA; Push(pPlayer); Push(pItem); @@ -676,6 +772,9 @@ void Eluna::OnLootItem(Player* pPlayer, Item* pItem, uint32 count, uint64 guid) void Eluna::OnLootMoney(Player* pPlayer, uint32 amount) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_LOOT_MONEY)) + return; + LOCK_ELUNA; Push(pPlayer); Push(amount); @@ -684,6 +783,9 @@ void Eluna::OnLootMoney(Player* pPlayer, uint32 amount) void Eluna::OnFirstLogin(Player* pPlayer) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_FIRST_LOGIN)) + return; + LOCK_ELUNA; Push(pPlayer); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_FIRST_LOGIN); @@ -691,6 +793,9 @@ void Eluna::OnFirstLogin(Player* pPlayer) void Eluna::OnRepop(Player* pPlayer) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_REPOP)) + return; + LOCK_ELUNA; Push(pPlayer); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_REPOP); @@ -698,6 +803,9 @@ void Eluna::OnRepop(Player* pPlayer) void Eluna::OnResurrect(Player* pPlayer) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_RESURRECT)) + return; + LOCK_ELUNA; Push(pPlayer); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_RESURRECT); @@ -705,6 +813,9 @@ void Eluna::OnResurrect(Player* pPlayer) void Eluna::OnQuestAbandon(Player* pPlayer, uint32 questId) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_QUEST_ABANDON)) + return; + LOCK_ELUNA; Push(pPlayer); Push(questId); @@ -713,6 +824,9 @@ void Eluna::OnQuestAbandon(Player* pPlayer, uint32 questId) void Eluna::OnEquip(Player* pPlayer, Item* pItem, uint8 bag, uint8 slot) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_EQUIP)) + return; + LOCK_ELUNA; Push(pPlayer); Push(pItem); @@ -723,6 +837,9 @@ void Eluna::OnEquip(Player* pPlayer, Item* pItem, uint8 bag, uint8 slot) InventoryResult Eluna::OnCanUseItem(const Player* pPlayer, uint32 itemEntry) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_CAN_USE_ITEM)) + return EQUIP_ERR_OK; + LOCK_ELUNA; InventoryResult result = EQUIP_ERR_OK; Push(pPlayer); @@ -744,6 +861,9 @@ InventoryResult Eluna::OnCanUseItem(const Player* pPlayer, uint32 itemEntry) } void Eluna::OnPlayerEnterCombat(Player* pPlayer, Unit* pEnemy) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_ENTER_COMBAT)) + return; + LOCK_ELUNA; Push(pPlayer); Push(pEnemy); @@ -752,6 +872,9 @@ void Eluna::OnPlayerEnterCombat(Player* pPlayer, Unit* pEnemy) void Eluna::OnPlayerLeaveCombat(Player* pPlayer) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_LEAVE_COMBAT)) + return; + LOCK_ELUNA; Push(pPlayer); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LEAVE_COMBAT); @@ -759,6 +882,9 @@ void Eluna::OnPlayerLeaveCombat(Player* pPlayer) void Eluna::OnPVPKill(Player* pKiller, Player* pKilled) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_KILL_PLAYER)) + return; + LOCK_ELUNA; Push(pKiller); Push(pKilled); @@ -767,6 +893,9 @@ void Eluna::OnPVPKill(Player* pKiller, Player* pKilled) void Eluna::OnCreatureKill(Player* pKiller, Creature* pKilled) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_KILL_CREATURE)) + return; + LOCK_ELUNA; Push(pKiller); Push(pKilled); @@ -775,6 +904,9 @@ void Eluna::OnCreatureKill(Player* pKiller, Creature* pKilled) void Eluna::OnPlayerKilledByCreature(Creature* pKiller, Player* pKilled) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_KILLED_BY_CREATURE)) + return; + LOCK_ELUNA; Push(pKiller); Push(pKilled); @@ -783,6 +915,9 @@ void Eluna::OnPlayerKilledByCreature(Creature* pKiller, Player* pKilled) void Eluna::OnLevelChanged(Player* pPlayer, uint8 oldLevel) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_LEVEL_CHANGE)) + return; + LOCK_ELUNA; Push(pPlayer); Push(oldLevel); @@ -791,6 +926,9 @@ void Eluna::OnLevelChanged(Player* pPlayer, uint8 oldLevel) void Eluna::OnFreeTalentPointsChanged(Player* pPlayer, uint32 newPoints) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_TALENTS_CHANGE)) + return; + LOCK_ELUNA; Push(pPlayer); Push(newPoints); @@ -799,6 +937,9 @@ void Eluna::OnFreeTalentPointsChanged(Player* pPlayer, uint32 newPoints) void Eluna::OnTalentsReset(Player* pPlayer, bool noCost) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_TALENTS_RESET)) + return; + LOCK_ELUNA; Push(pPlayer); Push(noCost); @@ -807,6 +948,9 @@ void Eluna::OnTalentsReset(Player* pPlayer, bool noCost) void Eluna::OnMoneyChanged(Player* pPlayer, int32& amount) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_MONEY_CHANGE)) + return; + LOCK_ELUNA; Push(pPlayer); Push(amount); @@ -832,6 +976,9 @@ void Eluna::OnMoneyChanged(Player* pPlayer, int32& amount) void Eluna::OnGiveXP(Player* pPlayer, uint32& amount, Unit* pVictim) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_GIVE_XP)) + return; + LOCK_ELUNA; Push(pPlayer); Push(amount); @@ -858,6 +1005,9 @@ void Eluna::OnGiveXP(Player* pPlayer, uint32& amount, Unit* pVictim) void Eluna::OnReputationChange(Player* pPlayer, uint32 factionID, int32& standing, bool incremental) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_REPUTATION_CHANGE)) + return; + LOCK_ELUNA; Push(pPlayer); Push(factionID); @@ -885,6 +1035,9 @@ void Eluna::OnReputationChange(Player* pPlayer, uint32 factionID, int32& standin void Eluna::OnDuelRequest(Player* pTarget, Player* pChallenger) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_DUEL_REQUEST)) + return; + LOCK_ELUNA; Push(pTarget); Push(pChallenger); @@ -893,6 +1046,9 @@ void Eluna::OnDuelRequest(Player* pTarget, Player* pChallenger) void Eluna::OnDuelStart(Player* pStarter, Player* pChallenger) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_DUEL_START)) + return; + LOCK_ELUNA; Push(pStarter); Push(pChallenger); @@ -901,6 +1057,9 @@ void Eluna::OnDuelStart(Player* pStarter, Player* pChallenger) void Eluna::OnDuelEnd(Player* pWinner, Player* pLoser, DuelCompleteType type) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_DUEL_END)) + return; + LOCK_ELUNA; Push(pWinner); Push(pLoser); @@ -910,6 +1069,9 @@ void Eluna::OnDuelEnd(Player* pWinner, Player* pLoser, DuelCompleteType type) void Eluna::OnEmote(Player* pPlayer, uint32 emote) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_EMOTE)) + return; + LOCK_ELUNA; Push(pPlayer); Push(emote); @@ -918,6 +1080,9 @@ void Eluna::OnEmote(Player* pPlayer, uint32 emote) void Eluna::OnTextEmote(Player* pPlayer, uint32 textEmote, uint32 emoteNum, uint64 guid) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_TEXT_EMOTE)) + return; + LOCK_ELUNA; Push(pPlayer); Push(textEmote); @@ -928,6 +1093,9 @@ void Eluna::OnTextEmote(Player* pPlayer, uint32 textEmote, uint32 emoteNum, uint void Eluna::OnSpellCast(Player* pPlayer, Spell* pSpell, bool skipCheck) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_SPELL_CAST)) + return; + LOCK_ELUNA; Push(pPlayer); Push(pSpell); @@ -937,6 +1105,9 @@ void Eluna::OnSpellCast(Player* pPlayer, Spell* pSpell, bool skipCheck) void Eluna::OnLogin(Player* pPlayer) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_LOGIN)) + return; + LOCK_ELUNA; Push(pPlayer); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LOGIN); @@ -944,6 +1115,9 @@ void Eluna::OnLogin(Player* pPlayer) void Eluna::OnLogout(Player* pPlayer) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_LOGOUT)) + return; + LOCK_ELUNA; Push(pPlayer); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LOGOUT); @@ -951,6 +1125,9 @@ void Eluna::OnLogout(Player* pPlayer) void Eluna::OnCreate(Player* pPlayer) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_CHARACTER_CREATE)) + return; + LOCK_ELUNA; Push(pPlayer); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_CHARACTER_CREATE); @@ -958,6 +1135,9 @@ void Eluna::OnCreate(Player* pPlayer) void Eluna::OnDelete(uint32 guidlow) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_CHARACTER_DELETE)) + return; + LOCK_ELUNA; Push(guidlow); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_CHARACTER_DELETE); @@ -965,6 +1145,9 @@ void Eluna::OnDelete(uint32 guidlow) void Eluna::OnSave(Player* pPlayer) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_SAVE)) + return; + LOCK_ELUNA; Push(pPlayer); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_SAVE); @@ -972,6 +1155,9 @@ void Eluna::OnSave(Player* pPlayer) void Eluna::OnBindToInstance(Player* pPlayer, Difficulty difficulty, uint32 mapid, bool permanent) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_BIND_TO_INSTANCE)) + return; + LOCK_ELUNA; Push(pPlayer); Push(difficulty); @@ -982,6 +1168,9 @@ void Eluna::OnBindToInstance(Player* pPlayer, Difficulty difficulty, uint32 mapi void Eluna::OnUpdateZone(Player* pPlayer, uint32 newZone, uint32 newArea) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_UPDATE_ZONE)) + return; + LOCK_ELUNA; Push(pPlayer); Push(newZone); @@ -991,6 +1180,9 @@ void Eluna::OnUpdateZone(Player* pPlayer, uint32 newZone, uint32 newArea) void Eluna::OnMapChanged(Player* player) { + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_MAP_CHANGE)) + return; + LOCK_ELUNA; Push(player); CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_MAP_CHANGE); @@ -998,10 +1190,13 @@ void Eluna::OnMapChanged(Player* player) bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg) { - LOCK_ELUNA; + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_CHAT)) + return true; + if (lang == LANG_ADDON) return OnAddonMessage(pPlayer, type, msg, NULL, NULL, NULL, NULL); + LOCK_ELUNA; bool result = true; Push(pPlayer); Push(msg); @@ -1028,10 +1223,13 @@ bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg) bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Group* pGroup) { - LOCK_ELUNA; + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_GROUP_CHAT)) + return true; + if (lang == LANG_ADDON) return OnAddonMessage(pPlayer, type, msg, NULL, NULL, pGroup, NULL); + LOCK_ELUNA; bool result = true; Push(pPlayer); Push(msg); @@ -1059,10 +1257,13 @@ bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Guild* pGuild) { - LOCK_ELUNA; + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_GUILD_CHAT)) + return true; + if (lang == LANG_ADDON) return OnAddonMessage(pPlayer, type, msg, NULL, pGuild, NULL, NULL); + LOCK_ELUNA; bool result = true; Push(pPlayer); Push(msg); @@ -1090,10 +1291,13 @@ bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Channel* pChannel) { - LOCK_ELUNA; + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_CHANNEL_CHAT)) + return true; + if (lang == LANG_ADDON) return OnAddonMessage(pPlayer, type, msg, NULL, NULL, NULL, pChannel); + LOCK_ELUNA; bool result = true; Push(pPlayer); Push(msg); @@ -1121,10 +1325,13 @@ bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Player* pReceiver) { - LOCK_ELUNA; + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_WHISPER)) + return true; + if (lang == LANG_ADDON) return OnAddonMessage(pPlayer, type, msg, pReceiver, NULL, NULL, NULL); + LOCK_ELUNA; bool result = true; Push(pPlayer); Push(msg); @@ -1155,6 +1362,9 @@ bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, // Vehicle void Eluna::OnInstall(Vehicle* vehicle) { + if (!VehicleEventBindings->HasEvents(VEHICLE_EVENT_ON_INSTALL)) + return; + LOCK_ELUNA; Push(vehicle); CallAllFunctions(VehicleEventBindings, VEHICLE_EVENT_ON_INSTALL); @@ -1162,6 +1372,9 @@ void Eluna::OnInstall(Vehicle* vehicle) void Eluna::OnUninstall(Vehicle* vehicle) { + if (!VehicleEventBindings->HasEvents(VEHICLE_EVENT_ON_UNINSTALL)) + return; + LOCK_ELUNA; Push(vehicle); CallAllFunctions(VehicleEventBindings, VEHICLE_EVENT_ON_UNINSTALL); @@ -1169,6 +1382,9 @@ void Eluna::OnUninstall(Vehicle* vehicle) void Eluna::OnInstallAccessory(Vehicle* vehicle, Creature* accessory) { + if (!VehicleEventBindings->HasEvents(VEHICLE_EVENT_ON_INSTALL_ACCESSORY)) + return; + LOCK_ELUNA; Push(vehicle); Push(accessory); @@ -1177,6 +1393,9 @@ void Eluna::OnInstallAccessory(Vehicle* vehicle, Creature* accessory) void Eluna::OnAddPassenger(Vehicle* vehicle, Unit* passenger, int8 seatId) { + if (!VehicleEventBindings->HasEvents(VEHICLE_EVENT_ON_ADD_PASSENGER)) + return; + LOCK_ELUNA; Push(vehicle); Push(passenger); @@ -1186,6 +1405,9 @@ void Eluna::OnAddPassenger(Vehicle* vehicle, Unit* passenger, int8 seatId) void Eluna::OnRemovePassenger(Vehicle* vehicle, Unit* passenger) { + if (!VehicleEventBindings->HasEvents(VEHICLE_EVENT_ON_REMOVE_PASSENGER)) + return; + LOCK_ELUNA; Push(vehicle); Push(passenger); @@ -1196,6 +1418,9 @@ void Eluna::OnRemovePassenger(Vehicle* vehicle, Unit* passenger) void Eluna::OnAddMember(Guild* guild, Player* player, uint32 plRank) { + if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_ADD_MEMBER)) + return; + LOCK_ELUNA; Push(guild); Push(player); @@ -1205,6 +1430,9 @@ void Eluna::OnAddMember(Guild* guild, Player* player, uint32 plRank) void Eluna::OnRemoveMember(Guild* guild, Player* player, bool isDisbanding) { + if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_REMOVE_MEMBER)) + return; + LOCK_ELUNA; Push(guild); Push(player); @@ -1214,6 +1442,9 @@ void Eluna::OnRemoveMember(Guild* guild, Player* player, bool isDisbanding) void Eluna::OnMOTDChanged(Guild* guild, const std::string& newMotd) { + if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_MOTD_CHANGE)) + return; + LOCK_ELUNA; Push(guild); Push(newMotd); @@ -1222,6 +1453,9 @@ void Eluna::OnMOTDChanged(Guild* guild, const std::string& newMotd) void Eluna::OnInfoChanged(Guild* guild, const std::string& newInfo) { + if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_INFO_CHANGE)) + return; + LOCK_ELUNA; Push(guild); Push(newInfo); @@ -1230,6 +1464,9 @@ void Eluna::OnInfoChanged(Guild* guild, const std::string& newInfo) void Eluna::OnCreate(Guild* guild, Player* leader, const std::string& name) { + if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_CREATE)) + return; + LOCK_ELUNA; Push(guild); Push(leader); @@ -1239,6 +1476,9 @@ void Eluna::OnCreate(Guild* guild, Player* leader, const std::string& name) void Eluna::OnDisband(Guild* guild) { + if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_DISBAND)) + return; + LOCK_ELUNA; Push(guild); CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_DISBAND); @@ -1246,6 +1486,9 @@ void Eluna::OnDisband(Guild* guild) void Eluna::OnMemberWitdrawMoney(Guild* guild, Player* player, uint32& amount, bool isRepair) // isRepair not a part of Mangos, implement? { + if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_MONEY_WITHDRAW)) + return; + LOCK_ELUNA; Push(guild); Push(player); @@ -1273,6 +1516,9 @@ void Eluna::OnMemberWitdrawMoney(Guild* guild, Player* player, uint32& amount, b void Eluna::OnMemberDepositMoney(Guild* guild, Player* player, uint32& amount) { + if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_MONEY_DEPOSIT)) + return; + LOCK_ELUNA; Push(guild); Push(player); @@ -1300,6 +1546,9 @@ void Eluna::OnMemberDepositMoney(Guild* guild, Player* player, uint32& amount) void Eluna::OnItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank, uint8 srcContainer, uint8 srcSlotId, bool isDestBank, uint8 destContainer, uint8 destSlotId) { + if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_ITEM_MOVE)) + return; + LOCK_ELUNA; Push(guild); Push(player); @@ -1315,6 +1564,9 @@ void Eluna::OnItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank void Eluna::OnEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank) { + if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_EVENT)) + return; + LOCK_ELUNA; Push(guild); Push(eventType); @@ -1326,6 +1578,9 @@ void Eluna::OnEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 pl void Eluna::OnBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) { + if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_BANK_EVENT)) + return; + LOCK_ELUNA; Push(guild); Push(eventType); @@ -1339,6 +1594,9 @@ void Eluna::OnBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uint32 playe // Group void Eluna::OnAddMember(Group* group, uint64 guid) { + if (!GroupEventBindings->HasEvents(GROUP_EVENT_ON_MEMBER_ADD)) + return; + LOCK_ELUNA; Push(group); Push(guid); @@ -1347,6 +1605,9 @@ void Eluna::OnAddMember(Group* group, uint64 guid) void Eluna::OnInviteMember(Group* group, uint64 guid) { + if (!GroupEventBindings->HasEvents(GROUP_EVENT_ON_MEMBER_INVITE)) + return; + LOCK_ELUNA; Push(group); Push(guid); @@ -1355,6 +1616,9 @@ void Eluna::OnInviteMember(Group* group, uint64 guid) void Eluna::OnRemoveMember(Group* group, uint64 guid, uint8 method) { + if (!GroupEventBindings->HasEvents(GROUP_EVENT_ON_MEMBER_REMOVE)) + return; + LOCK_ELUNA; Push(group); Push(guid); @@ -1364,6 +1628,9 @@ void Eluna::OnRemoveMember(Group* group, uint64 guid, uint8 method) void Eluna::OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid) { + if (!GroupEventBindings->HasEvents(GROUP_EVENT_ON_LEADER_CHANGE)) + return; + LOCK_ELUNA; Push(group); Push(newLeaderGuid); @@ -1373,6 +1640,9 @@ void Eluna::OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderG void Eluna::OnDisband(Group* group) { + if (!GroupEventBindings->HasEvents(GROUP_EVENT_ON_DISBAND)) + return; + LOCK_ELUNA; Push(group); CallAllFunctions(GroupEventBindings, GROUP_EVENT_ON_DISBAND); @@ -1380,6 +1650,9 @@ void Eluna::OnDisband(Group* group) void Eluna::OnCreate(Group* group, uint64 leaderGuid, GroupType groupType) { + if (!GroupEventBindings->HasEvents(GROUP_EVENT_ON_CREATE)) + return; + LOCK_ELUNA; Push(group); Push(leaderGuid); @@ -1390,18 +1663,27 @@ void Eluna::OnCreate(Group* group, uint64 leaderGuid, GroupType groupType) /* Map */ void Eluna::OnCreate(Map* map) { + if (!ServerEventBindings->HasEvents(MAP_EVENT_ON_CREATE)) + return; + LOCK_ELUNA; Push(map); CallAllFunctions(ServerEventBindings, MAP_EVENT_ON_CREATE); } void Eluna::OnDestroy(Map* map) { + if (!ServerEventBindings->HasEvents(MAP_EVENT_ON_DESTROY)) + return; + LOCK_ELUNA; Push(map); CallAllFunctions(ServerEventBindings, MAP_EVENT_ON_DESTROY); } void Eluna::OnPlayerEnter(Map* map, Player* player) { + if (!ServerEventBindings->HasEvents(MAP_EVENT_ON_PLAYER_ENTER)) + return; + LOCK_ELUNA; Push(map); Push(player); @@ -1409,6 +1691,9 @@ void Eluna::OnPlayerEnter(Map* map, Player* player) } void Eluna::OnPlayerLeave(Map* map, Player* player) { + if (!ServerEventBindings->HasEvents(MAP_EVENT_ON_PLAYER_LEAVE)) + return; + LOCK_ELUNA; Push(map); Push(player); @@ -1416,6 +1701,9 @@ void Eluna::OnPlayerLeave(Map* map, Player* player) } void Eluna::OnUpdate(Map* map, uint32 diff) { + if (!ServerEventBindings->HasEvents(MAP_EVENT_ON_UPDATE)) + return; + LOCK_ELUNA; // enable this for multithread // eventMgr->globalProcessor->Update(diff); @@ -1425,12 +1713,18 @@ void Eluna::OnUpdate(Map* map, uint32 diff) } void Eluna::OnRemove(GameObject* gameobject) { + if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_DELETE_GAMEOBJECT)) + return; + LOCK_ELUNA; Push(gameobject); CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_DELETE_GAMEOBJECT); } void Eluna::OnRemove(Creature* creature) { + if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_DELETE_CREATURE)) + return; + LOCK_ELUNA; Push(creature); CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_DELETE_CREATURE); @@ -1439,6 +1733,9 @@ void Eluna::OnRemove(Creature* creature) // creature bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, Creature* pTarget) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry())) + return false; + LOCK_ELUNA; Push(pCaster); Push(spellId); @@ -1449,6 +1746,9 @@ bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, bool Eluna::OnGossipHello(Player* pPlayer, Creature* pCreature) { + if (!CreatureGossipBindings->HasEvents(GOSSIP_EVENT_ON_HELLO, pCreature->GetEntry())) + return false; + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); Push(pPlayer); @@ -1458,6 +1758,9 @@ bool Eluna::OnGossipHello(Player* pPlayer, Creature* pCreature) bool Eluna::OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action) { + if (!CreatureGossipBindings->HasEvents(GOSSIP_EVENT_ON_SELECT, pCreature->GetEntry())) + return false; + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); Push(pPlayer); @@ -1469,6 +1772,9 @@ bool Eluna::OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 sender, bool Eluna::OnGossipSelectCode(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action, const char* code) { + if (!CreatureGossipBindings->HasEvents(GOSSIP_EVENT_ON_SELECT, pCreature->GetEntry())) + return false; + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); Push(pPlayer); @@ -1481,6 +1787,9 @@ bool Eluna::OnGossipSelectCode(Player* pPlayer, Creature* pCreature, uint32 send bool Eluna::OnQuestAccept(Player* pPlayer, Creature* pCreature, Quest const* pQuest) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_QUEST_ACCEPT, pCreature->GetEntry())) + return false; + LOCK_ELUNA; Push(pPlayer); Push(pCreature); @@ -1490,6 +1799,9 @@ bool Eluna::OnQuestAccept(Player* pPlayer, Creature* pCreature, Quest const* pQu bool Eluna::OnQuestReward(Player* pPlayer, Creature* pCreature, Quest const* pQuest, uint32 opt) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_QUEST_REWARD, pCreature->GetEntry())) + return false; + LOCK_ELUNA; Push(pPlayer); Push(pCreature); @@ -1500,6 +1812,9 @@ bool Eluna::OnQuestReward(Player* pPlayer, Creature* pCreature, Quest const* pQu uint32 Eluna::GetDialogStatus(Player* pPlayer, Creature* pCreature) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_DIALOG_STATUS, pCreature->GetEntry())) + return DIALOG_STATUS_SCRIPTED_NO_STATUS; + LOCK_ELUNA; Push(pPlayer); Push(pCreature); @@ -1509,6 +1824,9 @@ uint32 Eluna::GetDialogStatus(Player* pPlayer, Creature* pCreature) void Eluna::OnAddToWorld(Creature* creature) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_ADD, creature->GetEntry())) + return; + LOCK_ELUNA; Push(creature); CallAllFunctions(CreatureEventBindings, CREATURE_EVENT_ON_ADD, creature->GetEntry()); @@ -1516,6 +1834,9 @@ void Eluna::OnAddToWorld(Creature* creature) void Eluna::OnRemoveFromWorld(Creature* creature) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_REMOVE, creature->GetEntry())) + return; + LOCK_ELUNA; Push(creature); CallAllFunctions(CreatureEventBindings, CREATURE_EVENT_ON_REMOVE, creature->GetEntry()); @@ -1523,6 +1844,9 @@ void Eluna::OnRemoveFromWorld(Creature* creature) bool Eluna::OnSummoned(Creature* pCreature, Unit* pSummoner) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_SUMMONED, pCreature->GetEntry())) + return false; + LOCK_ELUNA; Push(pCreature); Push(pSummoner); @@ -1531,6 +1855,9 @@ bool Eluna::OnSummoned(Creature* pCreature, Unit* pSummoner) bool Eluna::UpdateAI(Creature* me, const uint32 diff) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_AIUPDATE, me->GetEntry())) + return false; + LOCK_ELUNA; Push(me); Push(diff); @@ -1541,6 +1868,9 @@ bool Eluna::UpdateAI(Creature* me, const uint32 diff) //Called at creature aggro either by MoveInLOS or Attack Start bool Eluna::EnterCombat(Creature* me, Unit* target) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_ENTER_COMBAT, me->GetEntry())) + return false; + LOCK_ELUNA; Push(me); Push(target); @@ -1550,6 +1880,9 @@ bool Eluna::EnterCombat(Creature* me, Unit* target) // Called at any Damage from any attacker (before damage apply) bool Eluna::DamageTaken(Creature* me, Unit* attacker, uint32& damage) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_DAMAGE_TAKEN, me->GetEntry())) + return false; + LOCK_ELUNA; bool result = false; Push(me); @@ -1582,8 +1915,11 @@ bool Eluna::DamageTaken(Creature* me, Unit* attacker, uint32& damage) //Called at creature death bool Eluna::JustDied(Creature* me, Unit* killer) { - LOCK_ELUNA; + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_DIED, me->GetEntry())) + return false; + On_Reset(me); + LOCK_ELUNA; Push(me); Push(killer); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_DIED, me->GetEntry()); @@ -1592,6 +1928,9 @@ bool Eluna::JustDied(Creature* me, Unit* killer) //Called at creature killing another unit bool Eluna::KilledUnit(Creature* me, Unit* victim) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_TARGET_DIED, me->GetEntry())) + return false; + LOCK_ELUNA; Push(me); Push(victim); @@ -1601,6 +1940,9 @@ bool Eluna::KilledUnit(Creature* me, Unit* victim) // Called when the creature summon successfully other creature bool Eluna::JustSummoned(Creature* me, Creature* summon) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_JUST_SUMMONED_CREATURE, me->GetEntry())) + return false; + LOCK_ELUNA; Push(me); Push(summon); @@ -1610,6 +1952,9 @@ bool Eluna::JustSummoned(Creature* me, Creature* summon) // Called when a summoned creature is despawned bool Eluna::SummonedCreatureDespawn(Creature* me, Creature* summon) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_SUMMONED_CREATURE_DESPAWN, me->GetEntry())) + return false; + LOCK_ELUNA; Push(me); Push(summon); @@ -1619,6 +1964,9 @@ bool Eluna::SummonedCreatureDespawn(Creature* me, Creature* summon) //Called at waypoint reached or PointMovement end bool Eluna::MovementInform(Creature* me, uint32 type, uint32 id) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_REACH_WP, me->GetEntry())) + return false; + LOCK_ELUNA; Push(me); Push(type); @@ -1629,6 +1977,9 @@ bool Eluna::MovementInform(Creature* me, uint32 type, uint32 id) // Called before EnterCombat even before the creature is in combat. bool Eluna::AttackStart(Creature* me, Unit* target) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_PRE_COMBAT, me->GetEntry())) + return false; + LOCK_ELUNA; Push(me); Push(target); @@ -1638,8 +1989,11 @@ bool Eluna::AttackStart(Creature* me, Unit* target) // Called for reaction at stopping attack at no attackers or targets bool Eluna::EnterEvadeMode(Creature* me) { - LOCK_ELUNA; + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_LEAVE_COMBAT, me->GetEntry())) + return false; + On_Reset(me); + LOCK_ELUNA; Push(me); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_LEAVE_COMBAT, me->GetEntry()); } @@ -1647,6 +2001,9 @@ bool Eluna::EnterEvadeMode(Creature* me) // Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc) bool Eluna::AttackedBy(Creature* me, Unit* attacker) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_ATTACKED_AT, me->GetEntry())) + return false; + LOCK_ELUNA; Push(me); Push(attacker); @@ -1656,8 +2013,11 @@ bool Eluna::AttackedBy(Creature* me, Unit* attacker) // Called when creature is spawned or respawned (for reseting variables) bool Eluna::JustRespawned(Creature* me) { - LOCK_ELUNA; + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_SPAWN, me->GetEntry())) + return false; + On_Reset(me); + LOCK_ELUNA; Push(me); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_SPAWN, me->GetEntry()); } @@ -1665,6 +2025,9 @@ bool Eluna::JustRespawned(Creature* me) // Called at reaching home after evade bool Eluna::JustReachedHome(Creature* me) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_REACH_HOME, me->GetEntry())) + return false; + LOCK_ELUNA; Push(me); return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_REACH_HOME, me->GetEntry()); @@ -1673,6 +2036,9 @@ bool Eluna::JustReachedHome(Creature* me) // Called at text emote receive from player bool Eluna::ReceiveEmote(Creature* me, Player* player, uint32 emoteId) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_RECEIVE_EMOTE, me->GetEntry())) + return false; + LOCK_ELUNA; Push(me); Push(player); @@ -1683,6 +2049,9 @@ bool Eluna::ReceiveEmote(Creature* me, Player* player, uint32 emoteId) // called when the corpse of this creature gets removed bool Eluna::CorpseRemoved(Creature* me, uint32& respawnDelay) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_CORPSE_REMOVED, me->GetEntry())) + return false; + LOCK_ELUNA; bool result = false; Push(me); @@ -1713,6 +2082,9 @@ bool Eluna::CorpseRemoved(Creature* me, uint32& respawnDelay) bool Eluna::MoveInLineOfSight(Creature* me, Unit* who) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_MOVE_IN_LOS, me->GetEntry())) + return false; + LOCK_ELUNA; Push(me); Push(who); @@ -1722,6 +2094,9 @@ bool Eluna::MoveInLineOfSight(Creature* me, Unit* who) // Called on creature initial spawn, respawn, death, evade (leave combat) void Eluna::On_Reset(Creature* me) // Not an override, custom { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_RESET, me->GetEntry())) + return; + LOCK_ELUNA; Push(me); CallAllFunctions(CreatureEventBindings, CREATURE_EVENT_ON_RESET, me->GetEntry()); @@ -1730,6 +2105,9 @@ void Eluna::On_Reset(Creature* me) // Not an override, custom // Called when hit by a spell bool Eluna::SpellHit(Creature* me, Unit* caster, SpellInfo const* spell) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_HIT_BY_SPELL, me->GetEntry())) + return false; + LOCK_ELUNA; Push(me); Push(caster); @@ -1740,6 +2118,9 @@ bool Eluna::SpellHit(Creature* me, Unit* caster, SpellInfo const* spell) // Called when spell hits a target bool Eluna::SpellHitTarget(Creature* me, Unit* target, SpellInfo const* spell) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_SPELL_HIT_TARGET, me->GetEntry())) + return false; + LOCK_ELUNA; Push(me); Push(target); @@ -1751,6 +2132,9 @@ bool Eluna::SpellHitTarget(Creature* me, Unit* target, SpellInfo const* spell) bool Eluna::SummonedCreatureDies(Creature* me, Creature* summon, Unit* killer) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_SUMMONED_CREATURE_DIED, me->GetEntry())) + return false; + LOCK_ELUNA; Push(me); Push(summon); @@ -1761,6 +2145,9 @@ bool Eluna::SummonedCreatureDies(Creature* me, Creature* summon, Unit* killer) // Called when owner takes damage bool Eluna::OwnerAttackedBy(Creature* me, Unit* attacker) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_OWNER_ATTACKED_AT, me->GetEntry())) + return false; + LOCK_ELUNA; Push(me); Push(attacker); @@ -1770,6 +2157,9 @@ bool Eluna::OwnerAttackedBy(Creature* me, Unit* attacker) // Called when owner attacks something bool Eluna::OwnerAttacked(Creature* me, Unit* target) { + if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_OWNER_ATTACKED, me->GetEntry())) + return false; + LOCK_ELUNA; Push(me); Push(target); @@ -1973,6 +2363,9 @@ struct ElunaCreatureAI : ScriptedAI // gameobject bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, GameObject* pTarget) { + if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry())) + return false; + LOCK_ELUNA; Push(pCaster); Push(spellId); @@ -1983,6 +2376,9 @@ bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, bool Eluna::OnGossipHello(Player* pPlayer, GameObject* pGameObject) { + if (!GameObjectGossipBindings->HasEvents(GOSSIP_EVENT_ON_HELLO, pGameObject->GetEntry())) + return false; + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); Push(pPlayer); @@ -1992,6 +2388,9 @@ bool Eluna::OnGossipHello(Player* pPlayer, GameObject* pGameObject) bool Eluna::OnGossipSelect(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action) { + if (!GameObjectGossipBindings->HasEvents(GOSSIP_EVENT_ON_SELECT, pGameObject->GetEntry())) + return false; + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); Push(pPlayer); @@ -2003,6 +2402,9 @@ bool Eluna::OnGossipSelect(Player* pPlayer, GameObject* pGameObject, uint32 send bool Eluna::OnGossipSelectCode(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action, const char* code) { + if (!GameObjectGossipBindings->HasEvents(GOSSIP_EVENT_ON_SELECT, pGameObject->GetEntry())) + return false; + LOCK_ELUNA; pPlayer->PlayerTalkClass->ClearMenus(); Push(pPlayer); @@ -2015,6 +2417,9 @@ bool Eluna::OnGossipSelectCode(Player* pPlayer, GameObject* pGameObject, uint32 bool Eluna::OnQuestAccept(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest) { + if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_QUEST_ACCEPT, pGameObject->GetEntry())) + return false; + LOCK_ELUNA; Push(pPlayer); Push(pGameObject); @@ -2024,6 +2429,9 @@ bool Eluna::OnQuestAccept(Player* pPlayer, GameObject* pGameObject, Quest const* void Eluna::UpdateAI(GameObject* pGameObject, uint32 diff) { + if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_AIUPDATE, pGameObject->GetEntry())) + return; + LOCK_ELUNA; pGameObject->elunaEvents->Update(diff); Push(pGameObject); @@ -2033,6 +2441,9 @@ void Eluna::UpdateAI(GameObject* pGameObject, uint32 diff) bool Eluna::OnQuestReward(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest, uint32 opt) { + if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_QUEST_REWARD, pGameObject->GetEntry())) + return false; + LOCK_ELUNA; Push(pPlayer); Push(pGameObject); @@ -2043,6 +2454,9 @@ bool Eluna::OnQuestReward(Player* pPlayer, GameObject* pGameObject, Quest const* uint32 Eluna::GetDialogStatus(Player* pPlayer, GameObject* pGameObject) { + if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_DIALOG_STATUS, pGameObject->GetEntry())) + return DIALOG_STATUS_SCRIPTED_NO_STATUS; + LOCK_ELUNA; Push(pPlayer); Push(pGameObject); @@ -2054,6 +2468,9 @@ uint32 Eluna::GetDialogStatus(Player* pPlayer, GameObject* pGameObject) #ifndef TBC void Eluna::OnDestroyed(GameObject* pGameObject, Player* pPlayer) { + if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_DESTROYED, pGameObject->GetEntry())) + return; + LOCK_ELUNA; Push(pGameObject); Push(pPlayer); @@ -2062,6 +2479,9 @@ void Eluna::OnDestroyed(GameObject* pGameObject, Player* pPlayer) void Eluna::OnDamaged(GameObject* pGameObject, Player* pPlayer) { + if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_DAMAGED, pGameObject->GetEntry())) + return; + LOCK_ELUNA; Push(pGameObject); Push(pPlayer); @@ -2072,6 +2492,9 @@ void Eluna::OnDamaged(GameObject* pGameObject, Player* pPlayer) void Eluna::OnLootStateChanged(GameObject* pGameObject, uint32 state) { + if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE, pGameObject->GetEntry())) + return; + LOCK_ELUNA; Push(pGameObject); Push(state); @@ -2080,6 +2503,9 @@ void Eluna::OnLootStateChanged(GameObject* pGameObject, uint32 state) void Eluna::OnGameObjectStateChanged(GameObject* pGameObject, uint32 state) { + if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED, pGameObject->GetEntry())) + return; + LOCK_ELUNA; Push(pGameObject); Push(state); @@ -2088,6 +2514,9 @@ void Eluna::OnGameObjectStateChanged(GameObject* pGameObject, uint32 state) void Eluna::OnSpawn(GameObject* gameobject) { + if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_SPAWN, gameobject->GetEntry())) + return; + LOCK_ELUNA; Push(gameobject); CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_SPAWN, gameobject->GetEntry()); @@ -2095,6 +2524,9 @@ void Eluna::OnSpawn(GameObject* gameobject) void Eluna::OnAddToWorld(GameObject* gameobject) { + if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_ADD, gameobject->GetEntry())) + return; + LOCK_ELUNA; Push(gameobject); CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_ADD, gameobject->GetEntry()); @@ -2102,6 +2534,9 @@ void Eluna::OnAddToWorld(GameObject* gameobject) void Eluna::OnRemoveFromWorld(GameObject* gameobject) { + if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_REMOVE, gameobject->GetEntry())) + return; + LOCK_ELUNA; Push(gameobject); CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_REMOVE, gameobject->GetEntry()); @@ -2109,7 +2544,6 @@ void Eluna::OnRemoveFromWorld(GameObject* gameobject) CreatureAI* Eluna::GetAI(Creature* creature) { - LOCK_ELUNA; if (!CreatureEventBindings->HasEvents(creature->GetEntry())) return NULL; return new ElunaCreatureAI(creature); @@ -2117,6 +2551,9 @@ CreatureAI* Eluna::GetAI(Creature* creature) void Eluna::OnBGStart(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) { + if (!BGEventBindings->HasEvents(BG_EVENT_ON_START)) + return; + LOCK_ELUNA; Push(bg); Push(bgId); @@ -2126,6 +2563,9 @@ void Eluna::OnBGStart(BattleGround* bg, BattleGroundTypeId bgId, uint32 instance void Eluna::OnBGEnd(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId, Team winner) { + if (!BGEventBindings->HasEvents(BG_EVENT_ON_END)) + return; + LOCK_ELUNA; Push(bg); Push(bgId); @@ -2136,6 +2576,9 @@ void Eluna::OnBGEnd(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId void Eluna::OnBGCreate(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) { + if (!BGEventBindings->HasEvents(BG_EVENT_ON_CREATE)) + return; + LOCK_ELUNA; Push(bg); Push(bgId); @@ -2145,6 +2588,9 @@ void Eluna::OnBGCreate(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanc void Eluna::OnBGDestroy(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) { + if (!BGEventBindings->HasEvents(BG_EVENT_ON_PRE_DESTROY)) + return; + LOCK_ELUNA; Push(bg); Push(bgId); From 5e7b0ee0f7f3ec950c9e98677a47c88a0c5da9ba Mon Sep 17 00:00:00 2001 From: Rochet2 Date: Tue, 6 Jan 2015 12:43:53 +0200 Subject: [PATCH 10/10] Fix TC build, analysis warnings and triggering addon message hooks --- ElunaBinding.h | 6 +++--- ElunaEventMgr.cpp | 10 +++++----- ElunaUtility.h | 4 ++-- HookMgr.cpp | 30 +++++++++++++++--------------- LuaEngine.cpp | 4 ++-- LuaEngine.h | 2 +- 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/ElunaBinding.h b/ElunaBinding.h index 5d3c0f6..d65a94e 100644 --- a/ElunaBinding.h +++ b/ElunaBinding.h @@ -17,7 +17,7 @@ extern "C" #include "lauxlib.h" }; -class ElunaBind +class ElunaBind : public ElunaUtil::RWLockable { public: struct Binding @@ -61,7 +61,7 @@ public: }; template -class EventBind : public ElunaBind, public ElunaUtil::RWLockable +class EventBind : public ElunaBind { public: EventBind(const char* bindGroupName, Eluna& _E) : ElunaBind(bindGroupName, _E) @@ -141,7 +141,7 @@ public: }; template -class EntryBind : public ElunaBind, public ElunaUtil::RWLockable +class EntryBind : public ElunaBind { public: typedef UNORDERED_MAP EntryToEventsMap; diff --git a/ElunaEventMgr.cpp b/ElunaEventMgr.cpp index b640e2f..cc765c9 100644 --- a/ElunaEventMgr.cpp +++ b/ElunaEventMgr.cpp @@ -45,7 +45,7 @@ ElunaEventProcessor::ElunaEventProcessor(Eluna** _E, WorldObject* _obj) : m_time { if (obj) { - EventMgr::WriteGuard lock((*E)->eventMgr->GetLock()); + EventMgr::WriteGuard guard((*E)->eventMgr->GetLock()); (*E)->eventMgr->processors.insert(this); } } @@ -56,7 +56,7 @@ ElunaEventProcessor::~ElunaEventProcessor() if (obj && Eluna::initialized) { - EventMgr::WriteGuard lock((*E)->eventMgr->GetLock()); + EventMgr::WriteGuard guard((*E)->eventMgr->GetLock()); (*E)->eventMgr->processors.erase(this); } } @@ -133,7 +133,7 @@ EventMgr::EventMgr(Eluna** _E) : globalProcessor(new ElunaEventProcessor(_E, NUL EventMgr::~EventMgr() { { - ReadGuard lock(GetLock()); + ReadGuard guard(GetLock()); if (!processors.empty()) for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors (*it)->RemoveEvents_internal(); @@ -145,7 +145,7 @@ EventMgr::~EventMgr() void EventMgr::RemoveEvents() { - ReadGuard lock(GetLock()); + ReadGuard guard(GetLock()); if (!processors.empty()) for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors (*it)->RemoveEvents(); @@ -154,7 +154,7 @@ void EventMgr::RemoveEvents() void EventMgr::RemoveEvent(int eventId) { - ReadGuard lock(GetLock()); + ReadGuard guard(GetLock()); if (!processors.empty()) for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors (*it)->RemoveEvent(eventId); diff --git a/ElunaUtility.h b/ElunaUtility.h index b56ade6..1ca5b29 100644 --- a/ElunaUtility.h +++ b/ElunaUtility.h @@ -119,9 +119,9 @@ namespace ElunaUtil /* * Usage: * Inherit this class, then when needing lock, use - * ReadGuard lock(_lock); + * ReadGuard guard(GetLock()); * or - * WriteGuard lock(_lock); + * WriteGuard guard(GetLock()); * * The lock is automatically released at end of scope */ diff --git a/HookMgr.cpp b/HookMgr.cpp index 6084275..b6ce2f2 100644 --- a/HookMgr.cpp +++ b/HookMgr.cpp @@ -1190,12 +1190,12 @@ void Eluna::OnMapChanged(Player* player) bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg) { - if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_CHAT)) - return true; - if (lang == LANG_ADDON) return OnAddonMessage(pPlayer, type, msg, NULL, NULL, NULL, NULL); + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_CHAT)) + return true; + LOCK_ELUNA; bool result = true; Push(pPlayer); @@ -1223,12 +1223,12 @@ bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg) bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Group* pGroup) { - if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_GROUP_CHAT)) - return true; - if (lang == LANG_ADDON) return OnAddonMessage(pPlayer, type, msg, NULL, NULL, pGroup, NULL); + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_GROUP_CHAT)) + return true; + LOCK_ELUNA; bool result = true; Push(pPlayer); @@ -1257,12 +1257,12 @@ bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Guild* pGuild) { - if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_GUILD_CHAT)) - return true; - if (lang == LANG_ADDON) return OnAddonMessage(pPlayer, type, msg, NULL, pGuild, NULL, NULL); + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_GUILD_CHAT)) + return true; + LOCK_ELUNA; bool result = true; Push(pPlayer); @@ -1291,12 +1291,12 @@ bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Channel* pChannel) { - if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_CHANNEL_CHAT)) - return true; - if (lang == LANG_ADDON) return OnAddonMessage(pPlayer, type, msg, NULL, NULL, NULL, pChannel); + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_CHANNEL_CHAT)) + return true; + LOCK_ELUNA; bool result = true; Push(pPlayer); @@ -1325,12 +1325,12 @@ bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Player* pReceiver) { - if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_WHISPER)) - return true; - if (lang == LANG_ADDON) return OnAddonMessage(pPlayer, type, msg, pReceiver, NULL, NULL, NULL); + if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_WHISPER)) + return true; + LOCK_ELUNA; bool result = true; Push(pPlayer); diff --git a/LuaEngine.cpp b/LuaEngine.cpp index f1ec9c9..29a7f9b 100644 --- a/LuaEngine.cpp +++ b/LuaEngine.cpp @@ -89,13 +89,13 @@ void Eluna::ReloadEluna() EventMgr::ProcessorSet oldProcessors; { - EventMgr::ReadGuard lock(sEluna->eventMgr->GetLock()); + EventMgr::ReadGuard guard(sEluna->eventMgr->GetLock()); oldProcessors = sEluna->eventMgr->processors; } Uninitialize(); Initialize(); { - EventMgr::WriteGuard lock(sEluna->eventMgr->GetLock()); + EventMgr::WriteGuard guard(sEluna->eventMgr->GetLock()); sEluna->eventMgr->processors.insert(oldProcessors.begin(), oldProcessors.end()); } diff --git a/LuaEngine.h b/LuaEngine.h index 92d4716..2b3ef7f 100644 --- a/LuaEngine.h +++ b/LuaEngine.h @@ -156,7 +156,7 @@ public: #ifdef TRINITY typedef std::recursive_mutex LockType; - typedef std::lock_guard ElunaGuard; + typedef std::lock_guard Guard; #else typedef ACE_Recursive_Thread_Mutex LockType; typedef ACE_Guard Guard;