diff --git a/src/Event/MpEvent.h b/src/Event/MpEvent.h index b1bdbbc..eaf42ad 100644 --- a/src/Event/MpEvent.h +++ b/src/Event/MpEvent.h @@ -14,6 +14,7 @@ enum class MpEvent UpgradeAdvancement, // Upgrades a player advancement 1 level ResetAdvancement, // Resets a player Advancement back to 0 ResetAllAdvancements, // Resets all player advancements + GetPlayerRank, // Get the rank requirements for an advancement to the next levels GetAdvancementRank // Get the details about the rank of a specific advancement (cost, bonus, etc) }; @@ -24,6 +25,7 @@ enum class MpClientEvent UpgradeAdvancement, ResetAdvancement, ResetAllAdvancements, + GetPlayerRank, GetAdvancementRank }; @@ -32,6 +34,7 @@ inline std::unordered_map MpEventMap = {{ {"UpgradeAdvancement", MpEvent::UpgradeAdvancement}, {"ResetAdvancement", MpEvent::ResetAdvancement}, {"ResetAllAdvancements", MpEvent::ResetAllAdvancements}, + {"GetPlayerRank", MpEvent::GetPlayerRank}, {"GetAdvancementRank", MpEvent::ResetAllAdvancements} }}; @@ -40,6 +43,7 @@ inline std::unordered_map MpClientEventNames = {MpClientEvent::UpgradeAdvancement, "UpgradeAdvancement"}, {MpClientEvent::ResetAdvancement, "ResetAdvancement"}, {MpClientEvent::ResetAllAdvancements, "ResetAllAdvancements"}, + {MpClientEvent::GetPlayerRank, "GetPlayerRank"}, {MpClientEvent::GetAdvancementRank, "GetAdvancementRank"} }}; diff --git a/src/Event/MpEventHandlers.cpp b/src/Event/MpEventHandlers.cpp index 3b33e98..3063e3f 100644 --- a/src/Event/MpEventHandlers.cpp +++ b/src/Event/MpEventHandlers.cpp @@ -1,6 +1,6 @@ #include "MpEvent.h" #include "MpLogger.h" -#include "AdvancementMgr.h" +#include "../AdvancementMgr.h" #include "MpEventProcessor.h" #include "MpClientDispatcher.h" #include "Player.h" @@ -15,13 +15,12 @@ /** * Handles Updates to a players advancement system * Event format - * p|playerGuid|UpgradeAdvancement|advancementId|rank|diceSpent|bonus */ enum class MP_EVENT_CODE { SUCCESS = 0, - // API Errors + // Message Errors INVALID_EVENT = 100, INVALID_ARGUMENT_SIZE = 201, INVALID_ARGUMENT = 202, @@ -30,8 +29,26 @@ enum class MP_EVENT_CODE // Game Response Codes FAILED_UPGRADE_ADV = 300, + // Unknown Error + UNKNOWN_ERROR = 400, + NO_HANDLER = 401 + }; +std::string EventCodeToString(MP_EVENT_CODE code) +{ + switch(code) { + case MP_EVENT_CODE::SUCCESS: return "Success"; + case MP_EVENT_CODE::INVALID_EVENT: return "Invalid event"; + case MP_EVENT_CODE::INVALID_ARGUMENT_SIZE: return "Invalid argument size"; + case MP_EVENT_CODE::INVALID_ARGUMENT: return "Invalid argument"; + case MP_EVENT_CODE::INVALID_ARGUMENT_TYPE: return "Invalid argument type"; + case MP_EVENT_CODE::FAILED_UPGRADE_ADV: return "Failed to upgrade advancement"; + case MP_EVENT_CODE::NO_HANDLER: return "No handler for event"; + default: return "Unknown error"; + } +} + // Send an error event to the client bool SendEventError(Player* player, const std::string& method, MP_EVENT_CODE code, std::string message) { @@ -41,6 +58,11 @@ bool SendEventError(Player* player, const std::string& method, MP_EVENT_CODE cod return false; } +/** + * Upgrade a Player Advancement + * Message Format: + * p|playerGuid|UpgradeAdvancement|advancementId|diceLevel|itemEntry1|itemEntry2|itemEntry3 + */ class UpdateAdvancements : public MpEventInterface { public: @@ -49,7 +71,7 @@ class UpdateAdvancements : public MpEventInterface return "UpgradeAdvancement"; } - bool Execute(Player* player, std::vector& args) + bool Execute(Player* player, std::vector& args) override { // Store the event data to send back to the client for parsing std::vector eventData; @@ -83,16 +105,25 @@ class UpdateAdvancements : public MpEventInterface uint32 itemEntry2 = std::stoi(args[3]); uint32 itemEntry3 = std::stoi(args[4]); - // Upgrade the advancement for the player! + uint32 increase; try { - if(! sAdvancementMgr->UpgradeAdvancement(player, static_cast(advancementId), diceLevel, itemEntry1, itemEntry2, itemEntry3)) { + increase = sAdvancementMgr->UpgradeAdvancement(player, static_cast(advancementId), diceLevel, itemEntry1, itemEntry2, itemEntry3); + if( increase == 0) { return SendEventError(player, EventName(),MP_EVENT_CODE::INVALID_ARGUMENT, "Failed to upgrade advancement invalid request see error logs for player " + player->GetName()); } } catch(const std::exception& e) { return SendEventError(player, EventName(),MP_EVENT_CODE::FAILED_UPGRADE_ADV, "Failed to upgrade: " + std::string(e.what()) + " for player " + player->GetName()); } - eventData = {"0", "success"}; + MpPlayerRank* playerRank = sAdvancementMgr->GetPlayerAdvancementRank(player, static_cast(advancementId)); + + // Format the success event data for client increase|newrank|bonus + eventData = { + EventCodeToString(MP_EVENT_CODE::SUCCESS), + std::to_string(increase), + std::to_string(playerRank->rank), + std::to_string(playerRank->bonus) + }; // Send response back to the client sMpClientDispatcher->Dispatch(MpClientEvent::UpgradeAdvancement, player, eventData); @@ -101,15 +132,24 @@ class UpdateAdvancements : public MpEventInterface } }; -class GetAdvancementRank : public MpEventInterface +/** + * @brief Event is used to get the rank requirements for an advancement to the next levels + * + * Message Format: + * p|playerGuid|GetPlayerRank|advancementId + * + * Returns: + * p|playerGuid|GetPlayerRank|rank|bonus|spentDice + */ +class GetPlayerRank : public MpEventInterface { public: const std::string EventName() const override { - return "GetAdvancementRank"; + return "GetPlayerRank"; } - bool Execute(Player* player, std::vector& args) + bool Execute(Player* player, std::vector& args) override { // Store the event data to send back to the client for parsing std::vector eventData; @@ -129,22 +169,89 @@ class GetAdvancementRank : public MpEventInterface return SendEventError(player, EventName(),MP_EVENT_CODE::INVALID_ARGUMENT, "Invalid advancement id " + args[0] + " max is " + std::to_string(MpAdvancements::MP_ADV_MAX)); } - MpAdvancementRank* rank = sAdvancementMgr->GetAdvancementRank(1, static_cast(advancementId)); - if(!rank) { + MpPlayerRank* playerRank = sAdvancementMgr->GetPlayerAdvancementRank(player, static_cast(advancementId)); + if(!playerRank) { return SendEventError(player, EventName(),MP_EVENT_CODE::INVALID_ARGUMENT, "Failed to get advancement rank for player " + player->GetName()); } - eventData = {std::to_string(rank->rank), std::to_string(rank->advancementId)}; + eventData = { + EventCodeToString(MP_EVENT_CODE::SUCCESS), + std::to_string(playerRank->rank), + std::to_string(playerRank->bonus), + std::to_string(playerRank->diceSpent) + }; + + // Send response back to the client + sMpClientDispatcher->Dispatch(MpClientEvent::GetPlayerRank, player, eventData); + + return true; + } +}; + +/** + * @brief Event is used to get the rank requirements for an advancement to the next levels + * + * Message Format: + * p|playerGuid|GetAdvancmentRank|advancementId|rank + * + * Returns: + * p|playerGuid|GetAdvancementRank|advancementId|rank|min1|max1|min2|max2|min3|max3|itemEntry1|itemEntryCost1|itemEntry2|itemEntryCost2|itemEntry3|itemEntryCost3 + */ +class GetAdvancementRank : public MpEventInterface { + public: + const std::string EventName() const override + { + return "GetAdvancementRank"; + } + + bool Execute(Player* player, std::vector& args) override + { + if(args.size() != 3) { + return SendEventError(player, EventName(),MP_EVENT_CODE::INVALID_ARGUMENT_SIZE, "Invalid number of arguments expected 3, found " + std::to_string(args.size())); + } + + uint32 advancementId = std::stoi(args[0]); + if(advancementId >= MpAdvancements::MP_ADV_MAX) { + return SendEventError(player, EventName(),MP_EVENT_CODE::INVALID_ARGUMENT, "Invalid advancement id " + args[0] + " max is " + std::to_string(MpAdvancements::MP_ADV_MAX)); + } + + uint32 rank = std::stoi(args[1]); + if(rank == 0) { + return SendEventError(player, EventName(),MP_EVENT_CODE::INVALID_ARGUMENT, "Invalid rank " + args[1] + " can not be empty"); + } + + MpAdvancementRank* advRank = sAdvancementMgr->GetAdvancementRank(rank, static_cast(advancementId)); + if(!advRank) { + return SendEventError(player, EventName(),MP_EVENT_CODE::INVALID_ARGUMENT, "Failed to get advancement rank for player " + player->GetName()); + } + + std::vector eventData = { + EventCodeToString(MP_EVENT_CODE::SUCCESS), + std::to_string(advRank->advancementId), + std::to_string(advRank->rank), + std::to_string(advRank->lowRange.first), + std::to_string(advRank->lowRange.second), + std::to_string(advRank->midRange.first), + std::to_string(advRank->midRange.second), + std::to_string(advRank->highRange.first), + std::to_string(advRank->highRange.second), + std::to_string(advRank->material1.first), + std::to_string(advRank->material1.second), + std::to_string(advRank->material2.first), + std::to_string(advRank->material2.second), + std::to_string(advRank->material3.first), + std::to_string(advRank->material3.second) + }; // Send response back to the client sMpClientDispatcher->Dispatch(MpClientEvent::GetAdvancementRank, player, eventData); - return true; } }; void MP_Register_EventHandlers() { - auto updateAdvancements = std::make_shared(); - sMpEventProcessor->RegisterHandler(MpEvent::UpgradeAdvancement, updateAdvancements); + sMpEventProcessor->RegisterHandler(MpEvent::UpgradeAdvancement, std::make_shared()); + sMpEventProcessor->RegisterHandler(MpEvent::GetPlayerRank, std::make_shared()); + sMpEventProcessor->RegisterHandler(MpEvent::GetAdvancementRank, std::make_shared()); } diff --git a/src/Event/MpEventProcessor.cpp b/src/Event/MpEventProcessor.cpp index 213a170..440df99 100644 --- a/src/Event/MpEventProcessor.cpp +++ b/src/Event/MpEventProcessor.cpp @@ -2,6 +2,7 @@ #include "MpEventProcessor.h" #include "MythicPlus.h" #include "MpLogger.h" +#include "MpClientDispatcher.h" #include "Player.h" #include @@ -65,6 +66,10 @@ void MpEventProcessor::RegisterHandler(MpEvent event, std::shared_ptr& args) { if(!_eventHandlers.contains(event)) { + + // Send a client message back also to the player + std::vector clientError = { std::to_string(static_cast(event)), "No handler registered for event: " + std::to_string(static_cast(event)) }; + sMpClientDispatcher->Dispatch(MpClientEvent::Error, player, clientError); MpLogger::warn("No handler registered for event: {}", event); return false; }