From dced08cf97abcfe5a39cb0a6b135212e1e6e3613 Mon Sep 17 00:00:00 2001 From: Alex King <89047260+Kinglykrab@users.noreply.github.com> Date: Sat, 26 Nov 2022 11:13:46 -0500 Subject: [PATCH] [Quest API] Add Zone Flag Methods to Perl/Lua. (#2574) * [Quest API] Add Zone Flag Methods to Perl/Lua. # Perl - Add `$client->GetPEQZoneFlags()`. - Add `$client->GetZoneFlags()`. # Lua - Add `client:GetPEQZoneFlags()`. - Add `client:GetZoneFlags()`. # Notes - Allows operators to get a list of all PEQ/zone flags to be looped through or listed out easily without having to have a list of individual zone IDs to check or otherwise. * Update zoning.cpp * Repositories and cleanup. --- .../character_peqzone_flags_repository.h | 12 ++++ zone/client.h | 2 + zone/lua_client.cpp | 32 +++++++++ zone/lua_client.h | 2 + zone/perl_client.cpp | 26 +++++++ zone/zoning.cpp | 72 +++++++++---------- 6 files changed, 107 insertions(+), 39 deletions(-) diff --git a/common/repositories/character_peqzone_flags_repository.h b/common/repositories/character_peqzone_flags_repository.h index 9cd3cf80c..3295a6c8c 100644 --- a/common/repositories/character_peqzone_flags_repository.h +++ b/common/repositories/character_peqzone_flags_repository.h @@ -44,7 +44,19 @@ public: */ // Custom extended repository methods here + static int DeleteFlag(Database& db, uint32 character_id, uint32 zone_id) + { + auto results = db.QueryDatabase( + fmt::format( + "DELETE FROM {} WHERE id = {} AND zone_id = {}", + TableName(), + character_id, + zone_id + ) + ); + return (results.Success() ? results.RowsAffected() : 0); + } }; #endif //EQEMU_CHARACTER_PEQZONE_FLAGS_REPOSITORY_H diff --git a/zone/client.h b/zone/client.h index f48d55937..9de7537c7 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1029,12 +1029,14 @@ public: void DoClassAttacks(Mob *ca_target, uint16 skill = -1, bool IsRiposte=false); void ClearZoneFlag(uint32 zone_id); + inline std::set GetZoneFlags() { return zone_flags; } ; bool HasZoneFlag(uint32 zone_id) const; void LoadZoneFlags(); void SendZoneFlagInfo(Client *to) const; void SetZoneFlag(uint32 zone_id); void ClearPEQZoneFlag(uint32 zone_id); + inline std::set GetPEQZoneFlags() { return peqzone_flags; }; bool HasPEQZoneFlag(uint32 zone_id) const; void LoadPEQZoneFlags(); void SendPEQZoneFlagInfo(Client *to) const; diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 1390d4328..dda7ed50f 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -2825,6 +2825,36 @@ void Lua_Client::UpdateAdmin(bool from_database) { self->UpdateAdmin(from_database); } +luabind::object Lua_Client::GetPEQZoneFlags(lua_State* L) { + auto t = luabind::newtable(L); + if (d_) { + auto self = reinterpret_cast(d_); + auto l = self->GetPEQZoneFlags(); + auto i = 0; + for (const auto& f : l) { + t[i] = f; + i++; + } + } + + return t; +} + +luabind::object Lua_Client::GetZoneFlags(lua_State* L) { + auto t = luabind::newtable(L); + if (d_) { + auto self = reinterpret_cast(d_); + auto l = self->GetZoneFlags(); + auto i = 0; + for (const auto& f : l) { + t[i] = f; + i++; + } + } + + return t; +} + #ifdef BOTS int Lua_Client::GetBotRequiredLevel() @@ -3135,6 +3165,8 @@ luabind::scope lua_register_client() { .def("GetThirst", (int(Lua_Client::*)(void))&Lua_Client::GetThirst) .def("GetTotalSecondsPlayed", (uint32(Lua_Client::*)(void))&Lua_Client::GetTotalSecondsPlayed) .def("GetWeight", (int(Lua_Client::*)(void))&Lua_Client::GetWeight) + .def("GetPEQZoneFlags", (luabind::object(Lua_Client::*)(lua_State*))&Lua_Client::GetPEQZoneFlags) + .def("GetZoneFlags", (luabind::object(Lua_Client::*)(lua_State*))&Lua_Client::GetZoneFlags) .def("GoFish", (void(Lua_Client::*)(void))&Lua_Client::GoFish) .def("GrantAlternateAdvancementAbility", (bool(Lua_Client::*)(int, int))&Lua_Client::GrantAlternateAdvancementAbility) .def("GrantAlternateAdvancementAbility", (bool(Lua_Client::*)(int, int, bool))&Lua_Client::GrantAlternateAdvancementAbility) diff --git a/zone/lua_client.h b/zone/lua_client.h index 3ad9f1a7b..73185a291 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -448,6 +448,8 @@ public: int GetSpellDamage(); void UpdateAdmin(); void UpdateAdmin(bool from_database); + luabind::object GetPEQZoneFlags(lua_State* L); + luabind::object GetZoneFlags(lua_State* L); void ApplySpell(int spell_id); void ApplySpell(int spell_id, int duration); diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index d2be96a46..f8d199419 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -2708,6 +2708,30 @@ void Perl_Client_SetSpellDurationRaid(Client* self, int spell_id, int duration, } #endif +perl::array Perl_Client_GetPEQZoneFlags(Client* self) +{ + perl::array a; + + auto l = self->GetPEQZoneFlags(); + for (const auto& f : l) { + a.push_back(f); + } + + return a; +} + +perl::array Perl_Client_GetZoneFlags(Client* self) +{ + perl::array a; + + auto l = self->GetZoneFlags(); + for (const auto& f : l) { + a.push_back(f); + } + + return a; +} + #ifdef BOTS int Perl_Client_GetBotRequiredLevel(Client* self) @@ -3011,6 +3035,8 @@ void perl_register_client() package.add("GetThirst", &Perl_Client_GetThirst); package.add("GetTotalSecondsPlayed", &Perl_Client_GetTotalSecondsPlayed); package.add("GetWeight", &Perl_Client_GetWeight); + package.add("GetPEQZoneFlags", &Perl_Client_GetPEQZoneFlags); + package.add("GetZoneFlags", &Perl_Client_GetZoneFlags); package.add("GoFish", &Perl_Client_GoFish); package.add("GrantAlternateAdvancementAbility", (bool(*)(Client*, int, int))&Perl_Client_GrantAlternateAdvancementAbility); package.add("GrantAlternateAdvancementAbility", (bool(*)(Client*, int, int, bool))&Perl_Client_GrantAlternateAdvancementAbility); diff --git a/zone/zoning.cpp b/zone/zoning.cpp index 9025064a2..ced7eeda2 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -36,9 +36,11 @@ extern QueryServ* QServ; extern WorldServer worldserver; extern Zone* zone; -#include "../common/repositories/zone_repository.h" #include "../common/content/world_content_service.h" +#include "../common/repositories/character_peqzone_flags_repository.h" +#include "../common/repositories/zone_repository.h" + void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { #ifdef BOTS @@ -999,13 +1001,13 @@ bool Client::HasZoneFlag(uint32 zone_id) const { } void Client::LoadZoneFlags() { - std::string query = fmt::format( + const auto query = fmt::format( "SELECT zoneID from zone_flags WHERE charID = {}", CharacterID() ); auto results = database.QueryDatabase(query); - if (!results.Success()) { + if (!results.Success() || !results.RowCount()) { LogError("MySQL Error while trying to load zone flags for [{}]: [{}]", GetName(), results.ErrorMessage().c_str()); return; } @@ -1045,23 +1047,23 @@ void Client::SendZoneFlagInfo(Client *to) const { const char* zone_short_name = ZoneName(zone_id, true); if (strncmp(zone_short_name, "UNKNOWN", strlen(zone_short_name)) != 0) { std::string zone_long_name = ZoneLongName(zone_id); - char flag_name[128]; + std::string flag_name = "ERROR"; auto z = GetZone(zone_id); - if (!z) { - strcpy(flag_name, "ERROR"); + if (z) { + flag_name = z->flag_needed; } to->Message( Chat::White, fmt::format( - "Flag {} | Zone ID: {} Zone Name: {} ({}){}", + "Flag {} | Zone: {} ({}) ID: {}", flag_number, - zone_id, zone_long_name, zone_short_name, + zone_id, ( - flag_name[0] != '\0' ? + !flag_name.empty() ? fmt::format( " Flag Required: {}", flag_name @@ -1092,7 +1094,7 @@ void Client::SetZoneFlag(uint32 zone_id) { zone_flags.insert(zone_id); - std::string query = fmt::format( + const auto query = fmt::format( "INSERT INTO zone_flags (charID, zoneID) VALUES ({}, {})", CharacterID(), zone_id @@ -1111,15 +1113,8 @@ void Client::ClearPEQZoneFlag(uint32 zone_id) { peqzone_flags.erase(zone_id); - auto query = fmt::format( - "DELETE FROM character_peqzone_flags WHERE id = {} AND zone_id = {}", - CharacterID(), - zone_id - ); - auto results = database.QueryDatabase(query); - - if (!results.Success()) { - LogError("MySQL Error while trying to clear zone flag for [{}]: [{}]", GetName(), results.ErrorMessage().c_str()); + if (!CharacterPeqzoneFlagsRepository::DeleteFlag(content_db, CharacterID(), zone_id)) { + LogError("MySQL Error while trying to clear PEQZone flag for [{}]", GetName()); } } @@ -1128,21 +1123,22 @@ bool Client::HasPEQZoneFlag(uint32 zone_id) const { } void Client::LoadPEQZoneFlags() { - std::string query = fmt::format( - "SELECT zone_id from character_peqzone_flags WHERE id = {}", - CharacterID() + const auto l = CharacterPeqzoneFlagsRepository::GetWhere( + content_db, + fmt::format( + "id = {}", + CharacterID() + ) ); - auto results = database.QueryDatabase(query); - - if (!results.Success()) { - LogError("MySQL Error while trying to load zone flags for [{}]: [{}]", GetName(), results.ErrorMessage().c_str()); + if (l.empty() || !l[0].id){ + LogError("MySQL Error while trying to load PEQZone flags for [{}].", GetName()); return; } peqzone_flags.clear(); - for (auto row : results) { - peqzone_flags.insert(std::stoul(row[0])); + for (const auto& f : l) { + peqzone_flags.insert(f.zone_id); } } @@ -1177,11 +1173,11 @@ void Client::SendPEQZoneFlagInfo(Client *to) const { to->Message( Chat::White, fmt::format( - "Flag {} | Zone ID: {} Zone Name: {} ({})", + "Flag {} | Zone: {} ({}) ID: {}", flag_number, - zone_id, zone_long_name, - zone_short_name + zone_short_name, + zone_id ).c_str() ); flag_count++; @@ -1206,15 +1202,13 @@ void Client::SetPEQZoneFlag(uint32 zone_id) { peqzone_flags.insert(zone_id); - auto query = fmt::format( - "INSERT INTO character_peqzone_flags (id, zone_id) VALUES ({}, {})", - CharacterID(), - zone_id - ); - auto results = database.QueryDatabase(query); + auto f = CharacterPeqzoneFlagsRepository::NewEntity(); - if (!results.Success()) { - LogError("MySQL Error while trying to set zone flag for [{}]: [{}]", GetName(), results.ErrorMessage().c_str()); + f.id = CharacterID(); + f.zone_id = zone_id; + + if (!CharacterPeqzoneFlagsRepository::InsertOne(content_db, f).id) { + LogError("MySQL Error while trying to set zone flag for [{}]", GetName()); } }