diff --git a/common/eq_constants.h b/common/eq_constants.h index 5f8044198..5309ad162 100644 --- a/common/eq_constants.h +++ b/common/eq_constants.h @@ -727,6 +727,11 @@ namespace BuffEffectType { constexpr uint8 InverseBuff = 4; } +namespace AlternateCurrencyMode { + constexpr uint32 Update = 7; + constexpr uint32 Populate = 8; +} + typedef enum { FilterNone = 0, FilterGuildChat = 1, //0=hide, 1=show diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index 9482d4625..55c8a500e 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -5134,8 +5134,6 @@ struct GroupMakeLeader_Struct //ex for a blank crowns window you would send: //999999|1|999999|0 //any items come after in much the same way adventure merchant items do except there is no theme included -#define ALT_CURRENCY_OP_POPULATE 8 -#define ALT_CURRENCY_OP_UPDATE 7 //Server -> Client //Populates the initial Alternate Currency Window diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 4e959052b..376c82019 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -202,7 +202,7 @@ namespace RoF unsigned char *emu_buffer = in->pBuffer; uint32 opcode = *((uint32*)emu_buffer); - if (opcode == 8) { + if (opcode == AlternateCurrencyMode::Populate) { AltCurrencyPopulate_Struct *populate = (AltCurrencyPopulate_Struct*)emu_buffer; auto outapp = new EQApplicationPacket( diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 205d081f1..0ce61f27b 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -274,7 +274,7 @@ namespace RoF2 unsigned char *emu_buffer = in->pBuffer; uint32 opcode = *((uint32*)emu_buffer); - if (opcode == 8) { + if (opcode == AlternateCurrencyMode::Populate) { AltCurrencyPopulate_Struct *populate = (AltCurrencyPopulate_Struct*)emu_buffer; auto outapp = new EQApplicationPacket( diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index 7ffdfcfa9..4a40203d0 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -195,7 +195,7 @@ namespace UF unsigned char *emu_buffer = in->pBuffer; uint32 opcode = *((uint32*)emu_buffer); - if (opcode == 8) { + if (opcode == AlternateCurrencyMode::Populate) { AltCurrencyPopulate_Struct *populate = (AltCurrencyPopulate_Struct*)emu_buffer; auto outapp = new EQApplicationPacket( diff --git a/common/repositories/base/base_character_alt_currency_repository.h b/common/repositories/base/base_character_alt_currency_repository.h index 054bf0b01..7e9a64f71 100644 --- a/common/repositories/base/base_character_alt_currency_repository.h +++ b/common/repositories/base/base_character_alt_currency_repository.h @@ -6,7 +6,7 @@ * Any modifications to base repositories are to be made by the generator only * * @generator ./utils/scripts/generators/repository-generator.pl - * @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories + * @docs https://docs.eqemu.io/developer/repositories */ #ifndef EQEMU_BASE_CHARACTER_ALT_CURRENCY_REPOSITORY_H @@ -16,6 +16,7 @@ #include "../../strings.h" #include + class BaseCharacterAltCurrencyRepository { public: struct CharacterAltCurrency { @@ -112,8 +113,9 @@ public: { auto results = db.QueryDatabase( fmt::format( - "{} WHERE id = {} LIMIT 1", + "{} WHERE {} = {} LIMIT 1", BaseSelect(), + PrimaryKey(), character_alt_currency_id ) ); @@ -338,6 +340,66 @@ public: return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0); } + static std::string BaseReplace() + { + return fmt::format( + "REPLACE INTO {} ({}) ", + TableName(), + ColumnsRaw() + ); + } + + static int ReplaceOne( + Database& db, + const CharacterAltCurrency &e + ) + { + std::vector v; + + v.push_back(std::to_string(e.char_id)); + v.push_back(std::to_string(e.currency_id)); + v.push_back(std::to_string(e.amount)); + + auto results = db.QueryDatabase( + fmt::format( + "{} VALUES ({})", + BaseReplace(), + Strings::Implode(",", v) + ) + ); + + return (results.Success() ? results.RowsAffected() : 0); + } + + static int ReplaceMany( + Database& db, + const std::vector &entries + ) + { + std::vector insert_chunks; + + for (auto &e: entries) { + std::vector v; + + v.push_back(std::to_string(e.char_id)); + v.push_back(std::to_string(e.currency_id)); + v.push_back(std::to_string(e.amount)); + + insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); + } + + std::vector v; + + auto results = db.QueryDatabase( + fmt::format( + "{} VALUES {}", + BaseReplace(), + Strings::Implode(",", insert_chunks) + ) + ); + + return (results.Success() ? results.RowsAffected() : 0); + } }; #endif //EQEMU_BASE_CHARACTER_ALT_CURRENCY_REPOSITORY_H diff --git a/zone/client.cpp b/zone/client.cpp index b8bbf3619..4ce46a743 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -6564,27 +6564,33 @@ void Client::RemoveFromInstance(uint16 instance_id) void Client::SendAltCurrencies() { if (ClientVersion() >= EQ::versions::ClientVersion::SoF) { - uint32 count = zone->AlternateCurrencies.size(); - if(count == 0) { + const uint32 currency_count = zone->AlternateCurrencies.size(); + if (!currency_count) { return; } + + auto outapp = new EQApplicationPacket( + OP_AltCurrency, + sizeof(AltCurrencyPopulate_Struct) + + sizeof(AltCurrencyPopulateEntry_Struct) * currency_count + ); - auto outapp = - new EQApplicationPacket(OP_AltCurrency, sizeof(AltCurrencyPopulate_Struct) + - sizeof(AltCurrencyPopulateEntry_Struct) * count); - AltCurrencyPopulate_Struct *altc = (AltCurrencyPopulate_Struct*)outapp->pBuffer; - altc->opcode = ALT_CURRENCY_OP_POPULATE; - altc->count = count; + auto a = (AltCurrencyPopulate_Struct*) outapp->pBuffer; + + a->opcode = AlternateCurrencyMode::Populate; + a->count = currency_count; uint32 currency_id = 0; - for (const auto& alternate_currency : zone->AlternateCurrencies) { - const EQ::ItemData* item = database.GetItem(alternate_currency.item_id); - altc->entries[currency_id].currency_number = alternate_currency.id; - altc->entries[currency_id].unknown00 = 1; - altc->entries[currency_id].currency_number2 = alternate_currency.id; - altc->entries[currency_id].item_id = alternate_currency.item_id; - altc->entries[currency_id].item_icon = item ? item->Icon : 1000; - altc->entries[currency_id].stack_size = item ? item->StackSize : 1000; + for (const auto& c : zone->AlternateCurrencies) { + const auto* item = database.GetItem(c.item_id); + + a->entries[currency_id].currency_number = c.id; + a->entries[currency_id].unknown00 = 1; + a->entries[currency_id].currency_number2 = c.id; + a->entries[currency_id].item_id = c.item_id; + a->entries[currency_id].item_icon = item ? item->Icon : 1000; + a->entries[currency_id].stack_size = item ? item->StackSize : 1000; + currency_id++; } @@ -6681,11 +6687,8 @@ void Client::SendAlternateCurrencyValue(uint32 currency_id, bool send_if_null) uint32 Client::GetAlternateCurrencyValue(uint32 currency_id) const { auto iter = alternate_currency.find(currency_id); - if(iter == alternate_currency.end()) { - return 0; - } else { - return (*iter).second; - } + + return iter == alternate_currency.end() ? 0 : (*iter).second; } void Client::ProcessAlternateCurrencyQueue() { diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 91f6a2d19..96c3dc955 100755 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -34,6 +34,7 @@ #include "../common/repositories/character_currency_repository.h" #include "../common/repositories/character_alternate_abilities_repository.h" #include "../common/repositories/character_auras_repository.h" +#include "../common/repositories/character_alt_currency_repository.h" #include #include @@ -2908,27 +2909,34 @@ void ZoneDatabase::QGlobalPurge() database.QueryDatabase(query); } -void ZoneDatabase::LoadAltCurrencyValues(uint32 char_id, std::map ¤cy) { +void ZoneDatabase::LoadAltCurrencyValues(uint32 char_id, std::map ¤cy) +{ + const auto& l = CharacterAltCurrencyRepository::GetWhere( + *this, + fmt::format( + "`char_id` = {}", + char_id + ) + ); - std::string query = StringFormat("SELECT currency_id, amount " - "FROM character_alt_currency " - "WHERE char_id = '%u'", char_id); - auto results = QueryDatabase(query); - if (!results.Success()) { - return; - } - - for (auto& row = results.begin(); row != results.end(); ++row) - currency[Strings::ToInt(row[0])] = Strings::ToInt(row[1]); + if (l.empty()) { + return; + } + for (const auto& e : l) { + currency[e.currency_id] = e.amount; + } } -void ZoneDatabase::UpdateAltCurrencyValue(uint32 char_id, uint32 currency_id, uint32 value) { +void ZoneDatabase::UpdateAltCurrencyValue(uint32 char_id, uint32 currency_id, uint32 value) +{ + auto e = CharacterAltCurrencyRepository::NewEntity(); - std::string query = StringFormat("REPLACE INTO character_alt_currency (char_id, currency_id, amount) " - "VALUES('%u', '%u', '%u')", char_id, currency_id, value); - database.QueryDatabase(query); + e.char_id = char_id; + e.currency_id = currency_id; + e.amount = value; + CharacterAltCurrencyRepository::ReplaceOne(*this, e); } void ZoneDatabase::SaveBuffs(Client *client)