From ae6bb06b5066373221e60670d316243d5f87201a Mon Sep 17 00:00:00 2001 From: iThorgrim <125808072+iThorgrim@users.noreply.github.com> Date: Wed, 19 Feb 2025 19:01:26 +0100 Subject: [PATCH] Feat(LuaEngine): Add RegisterTicketEvent and TicketMethods (#225) Co-authored-by: sudlud --- src/ElunaLuaEngine_SC.cpp | 27 +++ src/LuaEngine/Hooks.h | 10 + src/LuaEngine/LuaEngine.cpp | 11 + src/LuaEngine/LuaEngine.h | 8 + src/LuaEngine/LuaFunctions.cpp | 39 ++++ src/LuaEngine/hooks/TicketHooks.cpp | 59 +++++ src/LuaEngine/methods/GlobalMethods.h | 51 ++++ src/LuaEngine/methods/TicketMethods.h | 323 ++++++++++++++++++++++++++ 8 files changed, 528 insertions(+) create mode 100644 src/LuaEngine/hooks/TicketHooks.cpp create mode 100644 src/LuaEngine/methods/TicketMethods.h diff --git a/src/ElunaLuaEngine_SC.cpp b/src/ElunaLuaEngine_SC.cpp index 9726a52..bc3e7d8 100644 --- a/src/ElunaLuaEngine_SC.cpp +++ b/src/ElunaLuaEngine_SC.cpp @@ -1013,6 +1013,32 @@ public: } }; +class Eluna_TicketScript : public TicketScript +{ +public: + Eluna_TicketScript() : TicketScript("Eluna_TicketScript") { } + + void OnTicketCreate(GmTicket* ticket) override + { + sEluna->OnTicketCreate(ticket); + } + + void OnTicketUpdateLastChange(GmTicket* ticket) override + { + sEluna->OnTicketUpdateLastChange(ticket); + } + + void OnTicketClose(GmTicket* ticket) override + { + sEluna->OnTicketClose(ticket); + } + + void OnTicketResolve(GmTicket* ticket) override + { + sEluna->OnTicketResolve(ticket); + } +}; + // Group all custom scripts void AddSC_ElunaLuaEngine() { @@ -1033,6 +1059,7 @@ void AddSC_ElunaLuaEngine() new Eluna_PlayerScript(); new Eluna_ServerScript(); new Eluna_SpellSC(); + new Eluna_TicketScript(); new Eluna_UnitScript(); new Eluna_VehicleScript(); new Eluna_WorldObjectScript(); diff --git a/src/LuaEngine/Hooks.h b/src/LuaEngine/Hooks.h index 70e668e..7d8599c 100644 --- a/src/LuaEngine/Hooks.h +++ b/src/LuaEngine/Hooks.h @@ -86,6 +86,7 @@ namespace Hooks REGTYPE_BG, REGTYPE_MAP, REGTYPE_INSTANCE, + REGTYPE_TICKET, REGTYPE_SPELL, REGTYPE_COUNT }; @@ -368,6 +369,15 @@ namespace Hooks INSTANCE_EVENT_COUNT }; + enum TicketEvents + { + TICKET_EVENT_ON_CREATE = 1, // (event, ticket) + TICKET_EVENT_UPDATE_LAST_CHANGE = 2, // (event, ticket, message) + TICKET_EVENT_ON_CLOSE = 3, // (event, ticket) + TICKET_EVENT_ON_RESOLVE = 4, // (event, ticket) + TICKET_EVENT_COUNT + }; + enum SpellEvents { SPELL_EVENT_ON_PREPARE = 1, // (event, caster, spell) diff --git a/src/LuaEngine/LuaEngine.cpp b/src/LuaEngine/LuaEngine.cpp index 466e91a..27dfa86 100644 --- a/src/LuaEngine/LuaEngine.cpp +++ b/src/LuaEngine/LuaEngine.cpp @@ -177,6 +177,7 @@ ItemGossipBindings(NULL), PlayerGossipBindings(NULL), MapEventBindings(NULL), InstanceEventBindings(NULL), +TicketEventBindings(NULL), SpellEventBindings(NULL), CreatureUniqueBindings(NULL) @@ -270,6 +271,7 @@ void Eluna::CreateBindStores() GroupEventBindings = new BindingMap< EventKey >(L); VehicleEventBindings = new BindingMap< EventKey >(L); BGEventBindings = new BindingMap< EventKey >(L); + TicketEventBindings = new BindingMap< EventKey >(L); PacketEventBindings = new BindingMap< EntryKey >(L); CreatureEventBindings = new BindingMap< EntryKey >(L); @@ -1209,6 +1211,15 @@ int Eluna::Register(lua_State* L, uint8 regtype, uint32 entry, ObjectGuid guid, return 1; // Stack: callback } break; + case Hooks::REGTYPE_TICKET: + if (event_id < Hooks::TICKET_EVENT_COUNT) + { + auto key = EventKey((Hooks::TicketEvents)event_id); + bindingID = TicketEventBindings->Insert(key, functionRef, shots); + createCancelCallback(L, bindingID, TicketEventBindings); + return 1; // Stack: callback + } + break; case Hooks::REGTYPE_SPELL: if (event_id < Hooks::SPELL_EVENT_COUNT) { diff --git a/src/LuaEngine/LuaEngine.h b/src/LuaEngine/LuaEngine.h index ffce5e8..e582992 100644 --- a/src/LuaEngine/LuaEngine.h +++ b/src/LuaEngine/LuaEngine.h @@ -22,6 +22,7 @@ #include "ElunaUtility.h" #include "HttpManager.h" #include "EventEmitter.h" +#include "TicketMgr.h" #include #include @@ -220,6 +221,7 @@ public: BindingMap< EntryKey >* PlayerGossipBindings; BindingMap< EntryKey >* MapEventBindings; BindingMap< EntryKey >* InstanceEventBindings; + BindingMap< EventKey >* TicketEventBindings; BindingMap< EntryKey >* SpellEventBindings; BindingMap< UniqueObjectKey >* CreatureUniqueBindings; @@ -531,6 +533,12 @@ public: void OnBGCreate(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId); void OnBGDestroy(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId); + /* Ticket */ + void OnTicketCreate(GmTicket* ticket); + void OnTicketClose(GmTicket* ticket); + void OnTicketUpdateLastChange(GmTicket* ticket); + void OnTicketResolve(GmTicket* ticket); + /* Spell */ void OnSpellPrepare(Unit* caster, Spell* spell, SpellInfo const* spellInfo); void OnSpellCast(Unit* caster, Spell* spell, SpellInfo const* spellInfo, bool skipCheck); diff --git a/src/LuaEngine/LuaFunctions.cpp b/src/LuaEngine/LuaFunctions.cpp index 77cdc68..a404bf4 100644 --- a/src/LuaEngine/LuaFunctions.cpp +++ b/src/LuaEngine/LuaFunctions.cpp @@ -40,6 +40,7 @@ extern "C" #include "AchievementMethods.h" #include "ItemTemplateMethods.h" #include "RollMethods.h" +#include "TicketMethods.h" #include "SpellInfoMethods.h" // DBCStores includes @@ -65,6 +66,7 @@ luaL_Reg GlobalMethods[] = { "RegisterBGEvent", &LuaGlobalFunctions::RegisterBGEvent }, { "RegisterMapEvent", &LuaGlobalFunctions::RegisterMapEvent }, { "RegisterInstanceEvent", &LuaGlobalFunctions::RegisterInstanceEvent }, + { "RegisterTicketEvent", &LuaGlobalFunctions::RegisterTicketEvent }, { "RegisterSpellEvent", &LuaGlobalFunctions::RegisterSpellEvent }, { "ClearBattleGroundEvents", &LuaGlobalFunctions::ClearBattleGroundEvents }, @@ -83,6 +85,7 @@ luaL_Reg GlobalMethods[] = { "ClearServerEvents", &LuaGlobalFunctions::ClearServerEvents }, { "ClearMapEvents", &LuaGlobalFunctions::ClearMapEvents }, { "ClearInstanceEvents", &LuaGlobalFunctions::ClearInstanceEvents }, + { "ClearTicketEvents", &LuaGlobalFunctions::ClearTicketEvents }, { "ClearSpellEvents", &LuaGlobalFunctions::ClearSpellEvents }, // Getters @@ -1326,6 +1329,39 @@ ElunaRegister RollMethods[] = { NULL, NULL } }; +ElunaRegister TicketMethods[] = +{ + { "IsClosed", &LuaTicket::IsClosed }, + { "IsCompleted", &LuaTicket::IsCompleted }, + { "IsFromPlayer", &LuaTicket::IsFromPlayer }, + { "IsAssigned", &LuaTicket::IsAssigned }, + { "IsAssignedTo", &LuaTicket::IsAssignedTo }, + { "IsAssignedNotTo", &LuaTicket::IsAssignedNotTo }, + + { "GetId", &LuaTicket::GetId }, + { "GetPlayer", &LuaTicket::GetPlayer }, + { "GetPlayerName", &LuaTicket::GetPlayerName }, + { "GetMessage", &LuaTicket::GetMessage }, + { "GetAssignedPlayer", &LuaTicket::GetAssignedPlayer }, + { "GetAssignedToGUID", &LuaTicket::GetAssignedToGUID }, + { "GetLastModifiedTime", &LuaTicket::GetLastModifiedTime }, + { "GetResponse", &LuaTicket::GetResponse }, + { "GetChatLog", &LuaTicket::GetChatLog }, + + { "SetAssignedTo", &LuaTicket::SetAssignedTo }, + { "SetResolvedBy", &LuaTicket::SetResolvedBy }, + { "SetCompleted", &LuaTicket::SetCompleted }, + { "SetMessage", &LuaTicket::SetMessage }, + { "SetComment", &LuaTicket::SetComment }, + { "SetViewed", &LuaTicket::SetViewed }, + { "SetUnassigned", &LuaTicket::SetUnassigned }, + { "SetPosition", &LuaTicket::SetPosition }, + { "AppendResponse", &LuaTicket::AppendResponse }, + { "DeleteResponse", &LuaTicket::DeleteResponse }, + + { NULL, NULL } +}; + ElunaRegister SpellInfoMethods[] = { // Getters @@ -1650,6 +1686,9 @@ void RegisterFunctions(Eluna* E) ElunaTemplate::Register(E, "Roll"); ElunaTemplate::SetMethods(E, RollMethods); + ElunaTemplate::Register(E, "Ticket"); + ElunaTemplate::SetMethods(E, TicketMethods); + ElunaTemplate::Register(E, "SpellInfo"); ElunaTemplate::SetMethods(E, SpellInfoMethods); diff --git a/src/LuaEngine/hooks/TicketHooks.cpp b/src/LuaEngine/hooks/TicketHooks.cpp new file mode 100644 index 0000000..b09bc48 --- /dev/null +++ b/src/LuaEngine/hooks/TicketHooks.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 - 2016 Eluna Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#include "Hooks.h" +#include "HookHelpers.h" +#include "LuaEngine.h" +#include "BindingMap.h" +#include "ElunaIncludes.h" +#include "ElunaTemplate.h" + +using namespace Hooks; + +#define START_HOOK(EVENT) \ + if (!IsEnabled())\ + return;\ + auto key = EventKey(EVENT);\ + if (!TicketEventBindings->HasBindingsFor(key))\ + return;\ + LOCK_ELUNA + +#define START_HOOK(EVENT) \ + if (!IsEnabled())\ + return;\ + auto key = EventKey(EVENT);\ + if (!TicketEventBindings->HasBindingsFor(key))\ + return;\ + LOCK_ELUNA + +void Eluna::OnTicketCreate(GmTicket* ticket) +{ + START_HOOK(TICKET_EVENT_ON_CREATE); + Push(ticket); + CallAllFunctions(TicketEventBindings, key); +} + +void Eluna::OnTicketUpdateLastChange(GmTicket* ticket) +{ + START_HOOK(TICKET_EVENT_UPDATE_LAST_CHANGE); + Push(ticket); + CallAllFunctions(TicketEventBindings, key); +} + +void Eluna::OnTicketClose(GmTicket* ticket) +{ + START_HOOK(TICKET_EVENT_ON_CLOSE); + Push(ticket); + CallAllFunctions(TicketEventBindings, key); +} + +void Eluna::OnTicketResolve(GmTicket* ticket) +{ + START_HOOK(TICKET_EVENT_ON_RESOLVE); + Push(ticket); + CallAllFunctions(TicketEventBindings, key); +} + diff --git a/src/LuaEngine/methods/GlobalMethods.h b/src/LuaEngine/methods/GlobalMethods.h index f902f0d..21d32c5 100644 --- a/src/LuaEngine/methods/GlobalMethods.h +++ b/src/LuaEngine/methods/GlobalMethods.h @@ -1219,6 +1219,30 @@ namespace LuaGlobalFunctions return RegisterEntryHelper(L, Hooks::REGTYPE_GAMEOBJECT); } + /** + * Registers a [Ticket] event handler. + * + *
+     * enum TicketEvents
+     * {
+     *     TICKET_EVENT_ON_CREATE                          = 1,    // (event, player, ticket)
+     *     TICKET_EVENT_ON_UPDATE                          = 2,    // (event, player, ticket, message)
+     *     TICKET_EVENT_ON_CLOSE                           = 3,    // (event, player, ticket)
+     *     TICKET_EVENT_STATUS_UPDATE                      = 4,    // (event, player, ticket)
+     *     TICKET_EVENT_ON_RESOLVE                         = 5,    // (event, player, ticket)
+     *     TICKET_EVENT_COUNT
+     * };
+     * 
+ * + * @param uint32 event : event ID, refer to UnitEvents above + * @param function function : function to register + * @param uint32 shots = 0 : the number of times the function will be called, 0 means "always call this function" + */ + int RegisterTicketEvent(lua_State* L) + { + return RegisterEventHelper(L, Hooks::REGTYPE_TICKET); + } + /** * Registers a [Spell] event handler. * @@ -3147,6 +3171,33 @@ namespace LuaGlobalFunctions return 0; } + /** + * Unbinds event handlers for either all [Ticket] events, or one type of [Ticket] event. + * + * If `event_type` is `nil`, all [Ticket] event handlers are cleared. + * + * Otherwise, only event handlers for `event_type` are cleared. + * + * @proto () + * @proto (event_type) + * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterTicketEvent] + */ + int ClearTicketEvents(lua_State* L) + { + typedef EventKey Key; + + if (lua_isnoneornil(L, 1)) + { + Eluna::GetEluna(L)->TicketEventBindings->Clear(); + } + else + { + uint32 event_type = Eluna::CHECKVAL(L, 1); + Eluna::GetEluna(L)->TicketEventBindings->Clear(Key((Hooks::TicketEvents)event_type)); + } + return 0; + } + /** * Unbinds event handlers for either all of a [Spell]'s events, or one type of event. * diff --git a/src/LuaEngine/methods/TicketMethods.h b/src/LuaEngine/methods/TicketMethods.h new file mode 100644 index 0000000..44a5001 --- /dev/null +++ b/src/LuaEngine/methods/TicketMethods.h @@ -0,0 +1,323 @@ +/* +* Copyright (C) 2010 - 2016 Eluna Lua Engine +* This program is free software licensed under GPL version 3 +* Please see the included DOCS/LICENSE.md for more information +*/ + +#ifndef TICKETMETHODS_H +#define TICKETMETHODS_H + +/*** + * An instance of a spell, created when the spell is cast by a [Unit]. + * + * Inherits all methods from: none + */ +namespace LuaTicket +{ + /** + * Returns true if the [Ticket] is closed or false. + * + * @return bool is_closed + */ + int IsClosed(lua_State* L, GmTicket* ticket) + { + Eluna::Push(L, ticket->IsClosed()); + return 1; + } + + /** + * Returns true if the [Ticket] is completed or false. + * + * @return bool is_completed + */ + int IsCompleted(lua_State* L, GmTicket* ticket) + { + Eluna::Push(L, ticket->IsCompleted()); + return 1; + } + + /** + * Return true if this GUID is the same as the [Player] who created the [Ticket] or false. + * + * @param guid playerGuid : desired playerGuid + * + * @return bool same_guid + */ + int IsFromPlayer(lua_State* L, GmTicket* ticket) + { + ObjectGuid guid = Eluna::CHECKVAL(L, 2); + + Eluna::Push(L, ticket->IsFromPlayer(guid)); + return 1; + } + + /** + * Return true if the [Ticket] is assigned or false. + * + * @return bool is_assigned + */ + int IsAssigned(lua_State* L, GmTicket* ticket) + { + Eluna::Push(L, ticket->IsAssigned()); + return 1; + } + + /** + * Return true if the [Ticket] is assigned to the GUID or false. + * + * @param guid playerGuid : desired playerGuid + * + * @return bool is_assigned_to + */ + int IsAssignedTo(lua_State* L, GmTicket* ticket) + { + ObjectGuid guid = Eluna::CHECKVAL(L, 2); + + Eluna::Push(L, ticket->IsAssignedTo(guid)); + return 1; + } + + /** + * Return true if the [Ticket] is not assigned to the GUID or false. + * + * @param guid playerGuid : desired playerGuid + * + * @return bool is_assigned_not_to + */ + int IsAssignedNotTo(lua_State* L, GmTicket* ticket) + { + ObjectGuid guid = Eluna::CHECKVAL(L, 2); + + Eluna::Push(L, ticket->IsAssignedNotTo(guid)); + return 1; + } + + /** + * Return the [Ticket] id. + * + * @return unint32 ticket_id + */ + int GetId(lua_State* L, GmTicket* ticket) + { + Eluna::Push(L, ticket->GetId()); + return 1; + } + + /** + * Return the [Player] from the [Ticket]. + * + * @return [Player] player + */ + int GetPlayer(lua_State* L, GmTicket* ticket) + { + Eluna::Push(L, ticket->GetPlayer()); + return 1; + } + + /** + * Return the [Player] name from the [Ticket]. + * + * @return string player_name + */ + int GetPlayerName(lua_State* L, GmTicket* ticket) + { + Eluna::Push(L, ticket->GetPlayerName()); + return 1; + } + + /** + * Returns the message sent in the [Ticket]. + * + * @return string message + */ + int GetMessage(lua_State* L, GmTicket* ticket) + { + Eluna::Push(L, ticket->GetMessage()); + return 1; + } + + /** + * Returns the assigned [Player]. + * + * @return [Player] assigned_player + */ + int GetAssignedPlayer(lua_State* L, GmTicket* ticket) + { + Eluna::Push(L, ticket->GetAssignedPlayer()); + return 1; + } + + /** + * Returns the assigned guid. + * + * @return [ObjectGUID] assigned_guid + */ + int GetAssignedToGUID(lua_State* L, GmTicket* ticket) + { + Eluna::Push(L, ticket->GetAssignedToGUID()); + return 1; + } + + /** + * Returns the last modified time from the [Ticket]. + * + * @return uint64 last_modified + */ + int GetLastModifiedTime(lua_State* L, GmTicket* ticket) + { + Eluna::Push(L, ticket->GetLastModifiedTime()); + return 1; + } + + /** + * Assign the [Ticket] to a player via his GUID. + * + * @param guid playerGuid : desired playerGuid + * @param bool isAdmin : true if the guid is an Admin or false (default false) + */ + int SetAssignedTo(lua_State* L, GmTicket* ticket) + { + ObjectGuid guid = Eluna::CHECKVAL(L, 2); + bool is_admin = Eluna::CHECKVAL(L, 2, false); + ticket->SetAssignedTo(guid, is_admin); + return 0; + } + + /** + * Set [Ticket] resolved by player via his GUID. + * + * @param guid playerGuid : desired playerGuid + */ + int SetResolvedBy(lua_State* L, GmTicket* ticket) + { + ObjectGuid guid = Eluna::CHECKVAL(L, 2); + ticket->SetResolvedBy(guid); + return 0; + } + + /** + * Set [Ticket] completed. + * + */ + int SetCompleted(lua_State* /*L*/, GmTicket* ticket) + { + ticket->SetCompleted(); + return 0; + } + + /** + * Set [Ticket] message. + * + * @param string message: desired message + * + */ + int SetMessage(lua_State* L, GmTicket* ticket) + { + std::string message = Eluna::CHECKVAL(L, 2); + + ticket->SetMessage(message); + return 0; + } + + /** + * Set [Ticket] comment. + * + * @param string comment: desired comment + * + */ + int SetComment(lua_State* L, GmTicket* ticket) + { + std::string comment = Eluna::CHECKVAL(L, 2); + + ticket->SetComment(comment); + return 0; + } + + /** + * Set [Ticket] is viewed. + * + */ + int SetViewed(lua_State* /*L*/, GmTicket* ticket) + { + ticket->SetViewed(); + return 0; + } + + /** + * Set [Ticket] is unassigned. + * + */ + int SetUnassigned(lua_State* /*L*/, GmTicket* ticket) + { + ticket->SetUnassigned(); + return 0; + } + + /** + * Set the new [Ticket] creation position. + * + * @param uint32 mapId + * @param float x + * @param float y + * @param float z + * + */ + int SetPosition(lua_State* L, GmTicket* ticket) + { + uint32 mapId = Eluna::CHECKVAL(L, 2); + float x = Eluna::CHECKVAL(L, 2); + float y = Eluna::CHECKVAL(L, 2); + float z = Eluna::CHECKVAL(L, 2); + + ticket->SetPosition(mapId, x, y, z); + return 0; + } + + /** + * Adds a response to the [Ticket]. + * + * @param string response: desired response + * + */ + int AppendResponse(lua_State* L, GmTicket* ticket) + { + std::string response = Eluna::CHECKVAL(L, 2); + + ticket->AppendResponse(response); + return 0; + } + + /** + * Return the [Ticket] response. + * + * @return string response + */ + int GetResponse(lua_State* L, GmTicket* ticket) + { + Eluna::Push(L, ticket->GetResponse()); + return 1; + } + + /** + * Delete the [Ticket] response. + * + */ + int DeleteResponse(lua_State* /*L*/, GmTicket* ticket) + { + ticket->DeleteResponse(); + return 0; + } + + /** + * Return the [Ticket] chatlog. + * + * @return string chatlog + */ + int GetChatLog(lua_State* L, GmTicket* ticket) + { + Eluna::Push(L, ticket->GetChatLog()); + return 1; + } +}; +#endif +