From bdba6bd9bd7bfb074369faa97d22df4307bac310 Mon Sep 17 00:00:00 2001 From: Rochet2 Date: Fri, 13 Feb 2015 21:29:02 +0200 Subject: [PATCH 1/5] Eluna fix cppcheck warnings and errors --- LuaEngine.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/LuaEngine.cpp b/LuaEngine.cpp index c9cefcc..eac6eaa 100644 --- a/LuaEngine.cpp +++ b/LuaEngine.cpp @@ -343,7 +343,7 @@ void Eluna::GetScripts(std::string path) continue; #endif #ifdef UNIX - const char* name = dir_iter->path().filename().generic_string().c_str(); + std::string name = dir_iter->path().filename().generic_string().c_str(); if (name != ".." || name != "." || name[0] == '.') continue; #endif @@ -391,7 +391,7 @@ void Eluna::GetScripts(std::string path) continue; #endif #ifdef UNIX - const char* name = directory->d_name.c_str(); + std::string name = directory->d_name.c_str(); if (name != ".." || name != "." || name[0] == '.') continue; #endif @@ -755,13 +755,13 @@ static int CheckIntegerRange(lua_State* luastate, int narg, int min, int max) static unsigned int CheckUnsignedRange(lua_State* luastate, int narg, unsigned int max) { double value = luaL_checknumber(luastate, narg); - char error_buffer[64]; if (value < 0) return luaL_argerror(luastate, narg, "value must be greater than or equal to 0"); if (value > max) { + char error_buffer[64]; snprintf(error_buffer, 64, "value must be less than or equal to %u", max); return luaL_argerror(luastate, narg, error_buffer); } From 849651d4c0cc896a48fefd6533d46fba56d3f85c Mon Sep 17 00:00:00 2001 From: Rochet2 Date: Fri, 13 Feb 2015 22:27:06 +0200 Subject: [PATCH 2/5] Change player access from sessions to players --- GlobalMethods.h | 27 +++++++++++++++------------ GuildMethods.h | 19 +++++++++++-------- MapMethods.h | 2 +- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/GlobalMethods.h b/GlobalMethods.h index 6993669..a5db2eb 100644 --- a/GlobalMethods.h +++ b/GlobalMethods.h @@ -149,21 +149,24 @@ namespace LuaGlobalFunctions int tbl = lua_gettop(L); uint32 i = 0; - SessionMap const& sessions = eWorld->GetAllSessions(); - for (SessionMap::const_iterator it = sessions.begin(); it != sessions.end(); ++it) { - if (Player* player = it->second->GetPlayer()) + HashMapHolder::ReadGuard g(HashMapHolder::GetLock()); + HashMapHolder::MapType& m = eObjectAccessor->GetPlayers(); + for (HashMapHolder::MapType::iterator it = m.begin(); it != m.end(); ++it) { -#ifndef TRINITY - if ((team == TEAM_NEUTRAL || player->GetTeamId() == team) && (!onlyGM || player->isGameMaster())) -#else - if ((team == TEAM_NEUTRAL || player->GetTeamId() == team) && (!onlyGM || player->IsGameMaster())) -#endif + if (Player* player = it->second) { - ++i; - Eluna::Push(L, i); - Eluna::Push(L, player); - lua_settable(L, tbl); +#ifndef TRINITY + if ((team == TEAM_NEUTRAL || player->GetTeamId() == team) && (!onlyGM || player->isGameMaster())) +#else + if ((team == TEAM_NEUTRAL || player->GetTeamId() == team) && (!onlyGM || player->IsGameMaster())) +#endif + { + ++i; + Eluna::Push(L, i); + Eluna::Push(L, player); + lua_settable(L, tbl); + } } } } diff --git a/GuildMethods.h b/GuildMethods.h index c9305f7..e152d28 100644 --- a/GuildMethods.h +++ b/GuildMethods.h @@ -21,17 +21,20 @@ namespace LuaGuild int tbl = lua_gettop(L); uint32 i = 0; - SessionMap const& sessions = eWorld->GetAllSessions(); - for (SessionMap::const_iterator it = sessions.begin(); it != sessions.end(); ++it) { - if (Player* player = it->second->GetPlayer()) + HashMapHolder::ReadGuard g(HashMapHolder::GetLock()); + HashMapHolder::MapType& m = eObjectAccessor->GetPlayers(); + for (HashMapHolder::MapType::iterator it = m.begin(); it != m.end(); ++it) { - if (player->GetSession() && (player->GetGuildId() == guild->GetId())) + if (Player* player = it->second) { - ++i; - Eluna::Push(L, i); - Eluna::Push(L, player); - lua_settable(L, tbl); + if (player->GetSession() && (player->GetGuildId() == guild->GetId())) + { + ++i; + Eluna::Push(L, i); + Eluna::Push(L, player); + lua_settable(L, tbl); + } } } } diff --git a/MapMethods.h b/MapMethods.h index b0a1e83..b1d27e0 100644 --- a/MapMethods.h +++ b/MapMethods.h @@ -259,7 +259,7 @@ namespace LuaMap uint32 weatherType = Eluna::CHECKVAL(L, 3); float grade = Eluna::CHECKVAL(L, 4); -#if (defined(CMANGOS) && defined(WOTLK)) +#if ((defined(CMANGOS) || defined(MANGOS)) && defined(WOTLK)) if (Weather::IsValidWeatherType(weatherType)) map->SetWeather(zoneId, (WeatherType)weatherType, grade, false); #else From 1b9a2ae01868ebf619aa5103bbc6f71679f8aabd Mon Sep 17 00:00:00 2001 From: Rochet2 Date: Sat, 14 Feb 2015 00:31:08 +0200 Subject: [PATCH 3/5] MangosTwo change fixes --- GlobalMethods.h | 8 ++++++-- GuildMethods.h | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/GlobalMethods.h b/GlobalMethods.h index a5db2eb..d269c95 100644 --- a/GlobalMethods.h +++ b/GlobalMethods.h @@ -150,9 +150,13 @@ namespace LuaGlobalFunctions uint32 i = 0; { +#ifdef TRINITY + boost::shared_lock lock(*HashMapHolder::GetLock()); +#else HashMapHolder::ReadGuard g(HashMapHolder::GetLock()); - HashMapHolder::MapType& m = eObjectAccessor->GetPlayers(); - for (HashMapHolder::MapType::iterator it = m.begin(); it != m.end(); ++it) +#endif + const HashMapHolder::MapType& m = eObjectAccessor->GetPlayers(); + for (HashMapHolder::MapType::const_iterator it = m.begin(); it != m.end(); ++it) { if (Player* player = it->second) { diff --git a/GuildMethods.h b/GuildMethods.h index e152d28..5bc5fd6 100644 --- a/GuildMethods.h +++ b/GuildMethods.h @@ -22,9 +22,13 @@ namespace LuaGuild uint32 i = 0; { +#ifdef TRINITY + boost::shared_lock lock(*HashMapHolder::GetLock()); +#else HashMapHolder::ReadGuard g(HashMapHolder::GetLock()); - HashMapHolder::MapType& m = eObjectAccessor->GetPlayers(); - for (HashMapHolder::MapType::iterator it = m.begin(); it != m.end(); ++it) +#endif + const HashMapHolder::MapType& m = eObjectAccessor->GetPlayers(); + for (HashMapHolder::MapType::const_iterator it = m.begin(); it != m.end(); ++it) { if (Player* player = it->second) { From 4e787924e279eec6609d2a39c3ff0e7c44ae290c Mon Sep 17 00:00:00 2001 From: Rochet2 Date: Sun, 15 Feb 2015 00:16:22 +0200 Subject: [PATCH 4/5] Change AH hooks to work with TC --- ElunaIncludes.h | 2 ++ Hooks.h | 8 +++--- LuaEngine.h | 9 +++--- ServerHooks.cpp | 75 +++++++++++++++++++++++++++++++++++++++---------- 4 files changed, 71 insertions(+), 23 deletions(-) diff --git a/ElunaIncludes.h b/ElunaIncludes.h index eed76b6..8829006 100644 --- a/ElunaIncludes.h +++ b/ElunaIncludes.h @@ -87,6 +87,7 @@ typedef Opcodes OpcodesList; #define eGuildMgr (sGuildMgr) #define eObjectMgr (sObjectMgr) #define eAccountMgr (sAccountMgr) +#define eAuctionMgr (sAuctionMgr) #define eObjectAccessor (sObjectAccessor) #define REGEN_TIME_FULL typedef ThreatContainer::StorageType ThreatList; @@ -103,6 +104,7 @@ typedef ThreatContainer::StorageType ThreatList; #define eGuildMgr (&sGuildMgr) #define eObjectMgr (&sObjectMgr) #define eAccountMgr (&sAccountMgr) +#define eAuctionMgr (&sAuctionMgr) #define eObjectAccessor (&sObjectAccessor) #define SERVER_MSG_STRING SERVER_MSG_CUSTOM #define TOTAL_LOCALES MAX_LOCALE diff --git a/Hooks.h b/Hooks.h index 279ddd2..e7b7609 100644 --- a/Hooks.h +++ b/Hooks.h @@ -136,10 +136,10 @@ namespace Hooks WEATHER_EVENT_ON_CHANGE = 25, // (event, zoneId, state, grade) // Auction house - AUCTION_EVENT_ON_ADD = 26, // (event, auctionHouseEntry, player, item, bid, buyout, etime) - AUCTION_EVENT_ON_REMOVE = 27, // (event, auctionHouseEntry, player, item) - AUCTION_EVENT_ON_SUCCESSFUL = 28, // (event, auctionHouseEntry) // Not Implemented - AUCTION_EVENT_ON_EXPIRE = 29, // (event, auctionHouseEntry) // Not Implemented + AUCTION_EVENT_ON_ADD = 26, // (event, auctionId, owner, item, expireTime, buyout, startBid, currentBid, bidderGUIDLow) + AUCTION_EVENT_ON_REMOVE = 27, // (event, auctionId, owner, item, expireTime, buyout, startBid, currentBid, bidderGUIDLow) + AUCTION_EVENT_ON_SUCCESSFUL = 28, // (event, auctionId, owner, item, expireTime, buyout, startBid, currentBid, bidderGUIDLow) + AUCTION_EVENT_ON_EXPIRE = 29, // (event, auctionId, owner, item, expireTime, buyout, startBid, currentBid, bidderGUIDLow) // AddOns ADDON_EVENT_ON_MESSAGE = 30, // (event, sender, type, prefix, msg, target) - target can be nil/whisper_target/guild/group/channel. Can return false diff --git a/LuaEngine.h b/LuaEngine.h index 83a6cb2..98371f2 100644 --- a/LuaEngine.h +++ b/LuaEngine.h @@ -41,6 +41,7 @@ typedef int Difficulty; struct AreaTriggerEntry; class AuctionHouseObject; +struct AuctionEntry; #ifdef TRINITY class Battleground; typedef Battleground BattleGround; @@ -442,10 +443,10 @@ public: void OnChange(Weather* weather, uint32 zone, WeatherState state, float grade); /* Auction House */ - void OnAdd(AuctionHouseEntry const* auctionHouseEntry, Player* pPlayer, Item* pItem, uint32 bid, uint32 buyout, uint32 etime); - void OnRemove(AuctionHouseEntry const* auctionHouseEntry, Player* pPlayer, Item* pItem); - void OnSuccessful(AuctionHouseEntry const* auctionHouseEntry); - void OnExpire(AuctionHouseEntry const* auctionHouseEntry); + void OnAdd(AuctionHouseObject* ah, AuctionEntry* entry); + void OnRemove(AuctionHouseObject* ah, AuctionEntry* entry); + void OnSuccessful(AuctionHouseObject* ah, AuctionEntry* entry); + void OnExpire(AuctionHouseObject* ah, AuctionEntry* entry); /* Guild */ void OnAddMember(Guild* guild, Player* player, uint32 plRank); diff --git a/ServerHooks.cpp b/ServerHooks.cpp index 0de14b8..7f11656 100644 --- a/ServerHooks.cpp +++ b/ServerHooks.cpp @@ -82,50 +82,95 @@ void Eluna::OnChange(Weather* weather, uint32 zone, WeatherState state, float gr } // Auction House -void Eluna::OnAdd(AuctionHouseEntry const* auctionHouseEntry, Player* pPlayer, Item* pItem, uint32 bid, uint32 buyout, uint32 etime) +void Eluna::OnAdd(AuctionHouseObject* /*ah*/, AuctionEntry* entry) { if (!ServerEventBindings->HasEvents(AUCTION_EVENT_ON_ADD)) return; + Player* owner = eObjectAccessor->FindPlayer(MAKE_NEW_GUID(entry->owner, 0, HIGHGUID_PLAYER)); + Item* item = eAuctionMgr->GetAItem(entry->itemGUIDLow); + + if (!owner || !item) + return; + LOCK_ELUNA; - Push(auctionHouseEntry); - Push(pPlayer); - Push(pItem); - Push(bid); - Push(buyout); - Push(etime); + Push(entry->Id); + Push(owner); + Push(item); + Push(entry->expire_time); + Push(entry->buyout); + Push(entry->startbid); + Push(entry->bid); + Push(entry->bidder); CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_ADD); } -void Eluna::OnRemove(AuctionHouseEntry const* auctionHouseEntry, Player* pPlayer, Item* pItem) +void Eluna::OnRemove(AuctionHouseObject* /*ah*/, AuctionEntry* entry) { if (!ServerEventBindings->HasEvents(AUCTION_EVENT_ON_REMOVE)) return; + Player* owner = eObjectAccessor->FindPlayer(MAKE_NEW_GUID(entry->owner, 0, HIGHGUID_PLAYER)); + Item* item = eAuctionMgr->GetAItem(entry->itemGUIDLow); + + if (!owner || !item) + return; + LOCK_ELUNA; - Push(auctionHouseEntry); - Push(pPlayer); - Push(pItem); + Push(entry->Id); + Push(owner); + Push(item); + Push(entry->expire_time); + Push(entry->buyout); + Push(entry->startbid); + Push(entry->bid); + Push(entry->bidder); CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_REMOVE); } -void Eluna::OnSuccessful(AuctionHouseEntry const* auctionHouseEntry) +void Eluna::OnSuccessful(AuctionHouseObject* /*ah*/, AuctionEntry* entry) { if (!ServerEventBindings->HasEvents(AUCTION_EVENT_ON_SUCCESSFUL)) return; + Player* owner = eObjectAccessor->FindPlayer(MAKE_NEW_GUID(entry->owner, 0, HIGHGUID_PLAYER)); + Item* item = eAuctionMgr->GetAItem(entry->itemGUIDLow); + + if (!owner || !item) + return; + LOCK_ELUNA; - Push(auctionHouseEntry); + Push(entry->Id); + Push(owner); + Push(item); + Push(entry->expire_time); + Push(entry->buyout); + Push(entry->startbid); + Push(entry->bid); + Push(entry->bidder); CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_SUCCESSFUL); } -void Eluna::OnExpire(AuctionHouseEntry const* auctionHouseEntry) +void Eluna::OnExpire(AuctionHouseObject* /*ah*/, AuctionEntry* entry) { if (!ServerEventBindings->HasEvents(AUCTION_EVENT_ON_EXPIRE)) return; + Player* owner = eObjectAccessor->FindPlayer(MAKE_NEW_GUID(entry->owner, 0, HIGHGUID_PLAYER)); + Item* item = eAuctionMgr->GetAItem(entry->itemGUIDLow); + + if (!owner || !item) + return; + LOCK_ELUNA; - Push(auctionHouseEntry); + Push(entry->Id); + Push(owner); + Push(item); + Push(entry->expire_time); + Push(entry->buyout); + Push(entry->startbid); + Push(entry->bid); + Push(entry->bidder); CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_EXPIRE); } From 6b5fed561c848ffc747687d0f57a99ddf4cabd03 Mon Sep 17 00:00:00 2001 From: Rochet2 Date: Sun, 15 Feb 2015 02:08:23 +0200 Subject: [PATCH 5/5] Eluna fix problem with reloading timed events --- ElunaEventMgr.cpp | 37 +++++++++++++++++++++++-------------- ElunaEventMgr.h | 30 ++++++++++++++++++++++-------- GlobalMethods.h | 8 ++++---- LuaEngine.cpp | 2 +- WorldObjectMethods.h | 4 ++-- 5 files changed, 52 insertions(+), 29 deletions(-) diff --git a/ElunaEventMgr.cpp b/ElunaEventMgr.cpp index 266b9d9..fe364b7 100644 --- a/ElunaEventMgr.cpp +++ b/ElunaEventMgr.cpp @@ -41,9 +41,11 @@ void ElunaEventProcessor::Update(uint32 diff) { LuaEvent* luaEvent = it->second; eventList.erase(it); - eventMap.erase(luaEvent->funcRef); - if (!luaEvent->abort) + if (luaEvent->state != LUAEVENT_STATE_ERASE) + eventMap.erase(luaEvent->funcRef); + + if (luaEvent->state == LUAEVENT_STATE_RUN) { bool remove = luaEvent->repeats == 1; if (!remove) @@ -61,10 +63,12 @@ void ElunaEventProcessor::Update(uint32 diff) } } -void ElunaEventProcessor::RemoveEvents() +void ElunaEventProcessor::SetStates(LuaEventState state) { for (EventList::iterator it = eventList.begin(); it != eventList.end(); ++it) - it->second->abort = true; + it->second->SetState(state); + if (state == LUAEVENT_STATE_ERASE) + eventMap.clear(); } void ElunaEventProcessor::RemoveEvents_internal() @@ -83,10 +87,12 @@ void ElunaEventProcessor::RemoveEvents_internal() eventMap.clear(); } -void ElunaEventProcessor::RemoveEvent(int eventId) +void ElunaEventProcessor::SetState(int eventId, LuaEventState state) { if (eventMap.find(eventId) != eventMap.end()) - eventMap[eventId]->abort = true; + eventMap[eventId]->SetState(state); + if (state == LUAEVENT_STATE_ERASE) + eventMap.erase(eventId); } void ElunaEventProcessor::AddEvent(LuaEvent* luaEvent) @@ -102,8 +108,11 @@ void ElunaEventProcessor::AddEvent(int funcRef, uint32 delay, uint32 repeats) void ElunaEventProcessor::RemoveEvent(LuaEvent* luaEvent) { - // Free lua function ref - luaL_unref((*E)->L, LUA_REGISTRYINDEX, luaEvent->funcRef); + if (luaEvent->state != LUAEVENT_STATE_ERASE && Eluna::IsInitialized()) + { + // Free lua function ref + luaL_unref((*E)->L, LUA_REGISTRYINDEX, luaEvent->funcRef); + } delete luaEvent; } @@ -124,20 +133,20 @@ EventMgr::~EventMgr() globalProcessor = NULL; } -void EventMgr::RemoveEvents() +void EventMgr::SetStates(LuaEventState state) { ReadGuard guard(GetLock()); if (!processors.empty()) for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors - (*it)->RemoveEvents(); - globalProcessor->RemoveEvents(); + (*it)->SetStates(state); + globalProcessor->SetStates(state); } -void EventMgr::RemoveEvent(int eventId) +void EventMgr::SetState(int eventId, LuaEventState state) { ReadGuard guard(GetLock()); if (!processors.empty()) for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors - (*it)->RemoveEvent(eventId); - globalProcessor->RemoveEvent(eventId); + (*it)->SetState(eventId, state); + globalProcessor->SetState(eventId, state); } diff --git a/ElunaEventMgr.h b/ElunaEventMgr.h index 01771f5..ecf879e 100644 --- a/ElunaEventMgr.h +++ b/ElunaEventMgr.h @@ -22,16 +22,30 @@ class EventMgr; class ElunaEventProcessor; class WorldObject; +enum LuaEventState +{ + LUAEVENT_STATE_RUN, // On next call run the function normally + LUAEVENT_STATE_ABORT, // On next call unregisters reffed function and erases the data + LUAEVENT_STATE_ERASE, // On next call just erases the data +}; + struct LuaEvent { LuaEvent(int _funcRef, uint32 _delay, uint32 _repeats) : - delay(_delay), repeats(_repeats), funcRef(_funcRef), abort(false) + delay(_delay), repeats(_repeats), funcRef(_funcRef), state(LUAEVENT_STATE_RUN) { } + + void SetState(LuaEventState _state) + { + if (state != LUAEVENT_STATE_ERASE) + state = _state; + } + uint32 delay; // Delay between event calls uint32 repeats; // Amount of repeats to make, 0 for infinite int funcRef; // Lua function reference ID, also used as event ID - bool abort; // True if aborted and should not execute anymore + LuaEventState state; // State for next call }; class ElunaEventProcessor @@ -47,9 +61,9 @@ public: void Update(uint32 diff); // removes all timed events on next tick or at tick end - void RemoveEvents(); + void SetStates(LuaEventState state); // set the event to be removed when executing - void RemoveEvent(int eventId); + void SetState(int eventId, LuaEventState state); void AddEvent(int funcRef, uint32 delay, uint32 repeats); EventMap eventMap; @@ -74,13 +88,13 @@ public: EventMgr(Eluna** _E); ~EventMgr(); - // Remove all timed events + // Set the state of all timed events // Execute only in safe env - void RemoveEvents(); + void SetStates(LuaEventState state); - // Removes the eventId from all events + // Sets the eventId's state in all processors // Execute only in safe env - void RemoveEvent(int eventId); + void SetState(int eventId, LuaEventState state); }; #endif diff --git a/GlobalMethods.h b/GlobalMethods.h index d269c95..2119cc9 100644 --- a/GlobalMethods.h +++ b/GlobalMethods.h @@ -1251,9 +1251,9 @@ namespace LuaGlobalFunctions // not thread safe if (all_Events) - E->eventMgr->RemoveEvent(eventId); + E->eventMgr->SetState(eventId, LUAEVENT_STATE_ABORT); else - E->eventMgr->globalProcessor->RemoveEvent(eventId); + E->eventMgr->globalProcessor->SetState(eventId, LUAEVENT_STATE_ABORT); return 0; } @@ -1268,9 +1268,9 @@ namespace LuaGlobalFunctions // not thread safe if (all_Events) - E->eventMgr->RemoveEvents(); + E->eventMgr->SetStates(LUAEVENT_STATE_ABORT); else - E->eventMgr->globalProcessor->RemoveEvents(); + E->eventMgr->globalProcessor->SetStates(LUAEVENT_STATE_ABORT); return 0; } diff --git a/LuaEngine.cpp b/LuaEngine.cpp index eac6eaa..ad7a75f 100644 --- a/LuaEngine.cpp +++ b/LuaEngine.cpp @@ -101,7 +101,7 @@ void Eluna::_ReloadEluna() eWorld->SendServerMessage(SERVER_MSG_STRING, "Reloading Eluna..."); // Remove all timed events - sEluna->eventMgr->RemoveEvents(); + sEluna->eventMgr->SetStates(LUAEVENT_STATE_ERASE); // Close lua sEluna->CloseLua(); diff --git a/WorldObjectMethods.h b/WorldObjectMethods.h index 4786583..ffe3bc1 100644 --- a/WorldObjectMethods.h +++ b/WorldObjectMethods.h @@ -645,7 +645,7 @@ namespace LuaWorldObject int RemoveEventById(Eluna* /*E*/, lua_State* L, WorldObject* obj) { int eventId = Eluna::CHECKVAL(L, 2); - obj->elunaEvents->RemoveEvent(eventId); + obj->elunaEvents->SetState(eventId, LUAEVENT_STATE_ABORT); return 0; } @@ -655,7 +655,7 @@ namespace LuaWorldObject */ int RemoveEvents(Eluna* /*E*/, lua_State* /*L*/, WorldObject* obj) { - obj->elunaEvents->RemoveEvents(); + obj->elunaEvents->SetStates(LUAEVENT_STATE_ABORT); return 0; }