diff --git a/common/database/database_update_manifest.cpp b/common/database/database_update_manifest.cpp index 1b2f7bc61..c5e698bf8 100644 --- a/common/database/database_update_manifest.cpp +++ b/common/database/database_update_manifest.cpp @@ -7109,6 +7109,17 @@ ALTER TABLE `npc_types` ALTER TABLE `character_data` CHANGE COLUMN `firstlogon` `ingame` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 AFTER `xtargets`, ADD COLUMN `first_login` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `xtargets`; +)", + .content_schema_update = false + }, + ManifestEntry{ + .version = 9324, + .description = "2025_05_17_keyring_index.sql", + .check = "SHOW CREATE TABLE keyring", + .condition = "missing", + .match = "idx_charid_itemid", + .sql = R"( +ALTER TABLE keyring ADD INDEX idx_charid_itemid (char_id, item_id); )", .content_schema_update = false }, diff --git a/common/version.h b/common/version.h index 7b37a2b7b..2a96adc8b 100644 --- a/common/version.h +++ b/common/version.h @@ -42,7 +42,7 @@ * Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9323 +#define CURRENT_BINARY_DATABASE_VERSION 9324 #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9054 #define CUSTOM_BINARY_DATABASE_VERSION 0 diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 5328da726..3416acef8 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1553,10 +1553,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) } if (SPDAT_RECORDS > 0) { - for (uint32 z = 0; z < EQ::spells::SPELL_GEM_COUNT; z++) { - if (m_pp.mem_spells[z] >= (uint32)SPDAT_RECORDS) - UnmemSpell(z, false); - } + UnmemSpellAll(false); database.LoadBuffs(this); uint32 max_slots = GetMaxBuffSlots(); @@ -10241,11 +10238,11 @@ void Client::Handle_OP_LoadSpellSet(const EQApplicationPacket *app) printf("Wrong size of LoadSpellSet_Struct! Expected: %zu, Got: %i\n", sizeof(LoadSpellSet_Struct), app->size); return; } - int i; - LoadSpellSet_Struct* ss = (LoadSpellSet_Struct*)app->pBuffer; - for (i = 0; i < EQ::spells::SPELL_GEM_COUNT; i++) { - if (ss->spell[i] != 0xFFFFFFFF) + LoadSpellSet_Struct *ss = (LoadSpellSet_Struct *) app->pBuffer; + for (int i = 0; i < EQ::spells::SPELL_GEM_COUNT; i++) { + if (ss->spell[i] != 0xFFFFFFFF) { UnmemSpell(i, true); + } } } diff --git a/zone/spells.cpp b/zone/spells.cpp index bca4caefa..6c2a492de 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -78,6 +78,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org) #include "../common/misc_functions.h" #include "../common/events/player_event_logs.h" #include "../common/repositories/character_corpses_repository.h" +#include "../common/repositories/character_memmed_spells_repository.h" #include "../common/repositories/spell_buckets_repository.h" #include "data_bucket.h" @@ -5953,11 +5954,30 @@ void Client::UnmemSpellBySpellID(int32 spell_id) void Client::UnmemSpellAll(bool update_client) { - for (int spell_gem = 0; spell_gem < EQ::spells::SPELL_GEM_COUNT; spell_gem++) { - if (IsValidSpell(m_pp.mem_spells[spell_gem])) { - UnmemSpell(spell_gem, update_client); + bool has_spells = false; + for (int slot = 0; slot < EQ::spells::SPELL_GEM_COUNT; slot++) { + if (IsValidSpell(m_pp.mem_spells[slot])) { + if (slot >= EQ::spells::SPELL_GEM_COUNT || slot < 0) { + return; + } + + LogSpells("Spell [{}] forgotten from slot [{}]", m_pp.mem_spells[slot], slot); + + if (update_client) { + MemorizeSpell(slot, m_pp.mem_spells[slot], memSpellForget); + } + + m_pp.mem_spells[slot] = UINT32_MAX; + has_spells = true; } } + + if (has_spells) { + CharacterMemmedSpellsRepository::DeleteWhere( + database, + fmt::format("`id` = {}", character_id) + ); + } } uint32 Client::GetSpellIDByBookSlot(int book_slot) { diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index d85d9cf63..9de9b2096 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -3027,14 +3027,14 @@ void ZoneDatabase::LoadBuffs(Client *client) void ZoneDatabase::SaveAuras(Client *c) { - CharacterAurasRepository::DeleteOne(database, c->CharacterID()); + const auto& auras = c->GetAuraMgr(); + if (!auras.count) { + return; + } std::vector v; - + CharacterAurasRepository::DeleteOne(database, c->CharacterID()); auto e = CharacterAurasRepository::NewEntity(); - - const auto& auras = c->GetAuraMgr(); - for (int slot_id = 0; slot_id < auras.count; ++slot_id) { Aura* a = auras.auras[slot_id].aura; if (a && a->AuraZones()) {