diff --git a/client_files/import/main.cpp b/client_files/import/main.cpp index c1859be0e..a48ab45ee 100644 --- a/client_files/import/main.cpp +++ b/client_files/import/main.cpp @@ -27,6 +27,8 @@ #include "../../common/content/world_content_service.h" #include "../../common/zone_store.h" #include "../../common/path_manager.h" +#include "../../common/repositories/base_data_repository.h" +#include "../../common/file.h" EQEmuLogSys LogSys; WorldContentService content_service; @@ -255,50 +257,45 @@ void ImportSkillCaps(SharedDatabase *db) { fclose(f); } -void ImportBaseData(SharedDatabase *db) { +void ImportBaseData(SharedDatabase *db) +{ LogInfo("Importing Base Data"); - std::string file = fmt::format("{}/import/BaseData.txt", path.GetServerPath()); - FILE *f = fopen(file.c_str(), "r"); - if(!f) { - LogError("Unable to open {} to read, skipping.", file); - return; + const std::string& file_name = fmt::format("{}/import/BaseData.txt", path.GetServerPath()); + + const auto& file_contents = File::GetContents(file_name); + if (!file_contents.error.empty()) { + LogError("{}", file_contents.error); } - std::string delete_sql = "DELETE FROM base_data"; - db->QueryDatabase(delete_sql); + db->QueryDatabase("DELETE FROM base_data"); - char buffer[2048]; - while(fgets(buffer, 2048, f)) { - auto split = Strings::Split(buffer, '^'); + std::vector v; - if(split.size() < 10) { + auto e = BaseDataRepository::NewEntity(); + + for (const auto& line: Strings::Split(file_contents.contents, "\n")) { + const auto& line_data = Strings::Split(line, '^'); + + if (line_data.size() < 10) { continue; } - std::string sql; - int level, class_id; - double hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac; + e.level = static_cast(Strings::ToUnsignedInt(line_data[0])); + e.class_ = static_cast(Strings::ToUnsignedInt(line_data[1])); + e.hp = Strings::ToFloat(line_data[2]); + e.mana = Strings::ToFloat(line_data[3]); + e.end = Strings::ToFloat(line_data[4]); + e.hp_regen = Strings::ToFloat(line_data[5]); + e.end_regen = Strings::ToFloat(line_data[6]); + e.hp_fac = Strings::ToFloat(line_data[7]); + e.mana_fac = Strings::ToFloat(line_data[8]); + e.end_fac = Strings::ToFloat(line_data[9]); - level = Strings::ToInt(split[0].c_str()); - class_id = Strings::ToInt(split[1].c_str()); - hp = Strings::ToFloat(split[2].c_str()); - mana = Strings::ToFloat(split[3].c_str()); - end = Strings::ToFloat(split[4].c_str()); - unk1 = Strings::ToFloat(split[5].c_str()); - unk2 = Strings::ToFloat(split[6].c_str()); - hp_fac = Strings::ToFloat(split[7].c_str()); - mana_fac = Strings::ToFloat(split[8].c_str()); - end_fac = Strings::ToFloat(split[9].c_str()); - - sql = StringFormat("INSERT INTO base_data(level, class, hp, mana, end, unk1, unk2, hp_fac, " - "mana_fac, end_fac) VALUES(%d, %d, %f, %f, %f, %f, %f, %f, %f, %f)", - level, class_id, hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac); - - db->QueryDatabase(sql); + v.emplace_back(e); } - fclose(f); + BaseDataRepository::InsertMany(*db, v); } void ImportDBStrings(SharedDatabase *db) { diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index e17f79a87..3c44cc573 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -491,7 +491,6 @@ SET(repositories SET(common_headers additive_lagged_fibonacci_engine.h base_packet.h - base_data.h bodytypes.h classes.h compression.h diff --git a/common/base_data.h b/common/base_data.h deleted file mode 100644 index 4d8cf4a9f..000000000 --- a/common/base_data.h +++ /dev/null @@ -1,34 +0,0 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef __EQEMU_COMMON_BASE_DATA_H -#define __EQEMU_COMMON_BASE_DATA_H - -struct BaseDataStruct -{ - double base_hp; - double base_mana; - double base_end; - double hp_regen; - double end_regen; - double hp_factor; - double mana_factor; - double endurance_factor; -}; - -#endif diff --git a/common/database/database_update_manifest.cpp b/common/database/database_update_manifest.cpp index dec37a460..15a55ed8f 100644 --- a/common/database/database_update_manifest.cpp +++ b/common/database/database_update_manifest.cpp @@ -5253,6 +5253,21 @@ MODIFY COLUMN `name` varchar(200) CHARACTER SET latin1 COLLATE latin1_swedish_ci ALTER TABLE `ground_spawns` ADD COLUMN `fix_z` tinyint(1) UNSIGNED NOT NULL DEFAULT 1 AFTER `respawn_timer`; )" + }, + ManifestEntry{ + .version = 9258, + .description = "2024_02_04_base_data.sql", + .check = "SHOW COLUMNS FROM `base_data` LIKE `hp_regen`", + .condition = "empty", + .match = "", + .sql = R"( +ALTER TABLE `base_data` +CHANGE COLUMN `unk1` `hp_regen` double NOT NULL AFTER `end`, +CHANGE COLUMN `unk2` `end_regen` double NOT NULL AFTER `hp_regen`, +MODIFY COLUMN `level` tinyint(3) UNSIGNED NOT NULL FIRST, +MODIFY COLUMN `class` tinyint(2) UNSIGNED NOT NULL AFTER `level`; +)", + .content_schema_update = true } // -- template; copy/paste this when you need to create a new entry // ManifestEntry{ diff --git a/common/repositories/base/base_base_data_repository.h b/common/repositories/base/base_base_data_repository.h index ef75bdf31..91d9d4bc2 100644 --- a/common/repositories/base/base_base_data_repository.h +++ b/common/repositories/base/base_base_data_repository.h @@ -19,16 +19,16 @@ class BaseBaseDataRepository { public: struct BaseData { - uint32_t level; - uint32_t class_; - double hp; - double mana; - double end; - double unk1; - double unk2; - double hp_fac; - double mana_fac; - double end_fac; + uint8_t level; + uint8_t class_; + double hp; + double mana; + double end; + double hp_regen; + double end_regen; + double hp_fac; + double mana_fac; + double end_fac; }; static std::string PrimaryKey() @@ -44,8 +44,8 @@ public: "hp", "mana", "end", - "unk1", - "unk2", + "hp_regen", + "end_regen", "hp_fac", "mana_fac", "end_fac", @@ -60,8 +60,8 @@ public: "hp", "mana", "end", - "unk1", - "unk2", + "hp_regen", + "end_regen", "hp_fac", "mana_fac", "end_fac", @@ -105,16 +105,16 @@ public: { BaseData e{}; - e.level = 0; - e.class_ = 0; - e.hp = 0; - e.mana = 0; - e.end = 0; - e.unk1 = 0; - e.unk2 = 0; - e.hp_fac = 0; - e.mana_fac = 0; - e.end_fac = 0; + e.level = 0; + e.class_ = 0; + e.hp = 0; + e.mana = 0; + e.end = 0; + e.hp_regen = 0; + e.end_regen = 0; + e.hp_fac = 0; + e.mana_fac = 0; + e.end_fac = 0; return e; } @@ -151,16 +151,16 @@ public: if (results.RowCount() == 1) { BaseData e{}; - e.level = row[0] ? static_cast(strtoul(row[0], nullptr, 10)) : 0; - e.class_ = row[1] ? static_cast(strtoul(row[1], nullptr, 10)) : 0; - e.hp = row[2] ? strtod(row[2], nullptr) : 0; - e.mana = row[3] ? strtod(row[3], nullptr) : 0; - e.end = row[4] ? strtod(row[4], nullptr) : 0; - e.unk1 = row[5] ? strtod(row[5], nullptr) : 0; - e.unk2 = row[6] ? strtod(row[6], nullptr) : 0; - e.hp_fac = row[7] ? strtod(row[7], nullptr) : 0; - e.mana_fac = row[8] ? strtod(row[8], nullptr) : 0; - e.end_fac = row[9] ? strtod(row[9], nullptr) : 0; + e.level = row[0] ? static_cast(strtoul(row[0], nullptr, 10)) : 0; + e.class_ = row[1] ? static_cast(strtoul(row[1], nullptr, 10)) : 0; + e.hp = row[2] ? strtod(row[2], nullptr) : 0; + e.mana = row[3] ? strtod(row[3], nullptr) : 0; + e.end = row[4] ? strtod(row[4], nullptr) : 0; + e.hp_regen = row[5] ? strtod(row[5], nullptr) : 0; + e.end_regen = row[6] ? strtod(row[6], nullptr) : 0; + e.hp_fac = row[7] ? strtod(row[7], nullptr) : 0; + e.mana_fac = row[8] ? strtod(row[8], nullptr) : 0; + e.end_fac = row[9] ? strtod(row[9], nullptr) : 0; return e; } @@ -199,8 +199,8 @@ public: v.push_back(columns[2] + " = " + std::to_string(e.hp)); v.push_back(columns[3] + " = " + std::to_string(e.mana)); v.push_back(columns[4] + " = " + std::to_string(e.end)); - v.push_back(columns[5] + " = " + std::to_string(e.unk1)); - v.push_back(columns[6] + " = " + std::to_string(e.unk2)); + v.push_back(columns[5] + " = " + std::to_string(e.hp_regen)); + v.push_back(columns[6] + " = " + std::to_string(e.end_regen)); v.push_back(columns[7] + " = " + std::to_string(e.hp_fac)); v.push_back(columns[8] + " = " + std::to_string(e.mana_fac)); v.push_back(columns[9] + " = " + std::to_string(e.end_fac)); @@ -230,8 +230,8 @@ public: v.push_back(std::to_string(e.hp)); v.push_back(std::to_string(e.mana)); v.push_back(std::to_string(e.end)); - v.push_back(std::to_string(e.unk1)); - v.push_back(std::to_string(e.unk2)); + v.push_back(std::to_string(e.hp_regen)); + v.push_back(std::to_string(e.end_regen)); v.push_back(std::to_string(e.hp_fac)); v.push_back(std::to_string(e.mana_fac)); v.push_back(std::to_string(e.end_fac)); @@ -269,8 +269,8 @@ public: v.push_back(std::to_string(e.hp)); v.push_back(std::to_string(e.mana)); v.push_back(std::to_string(e.end)); - v.push_back(std::to_string(e.unk1)); - v.push_back(std::to_string(e.unk2)); + v.push_back(std::to_string(e.hp_regen)); + v.push_back(std::to_string(e.end_regen)); v.push_back(std::to_string(e.hp_fac)); v.push_back(std::to_string(e.mana_fac)); v.push_back(std::to_string(e.end_fac)); @@ -307,16 +307,16 @@ public: for (auto row = results.begin(); row != results.end(); ++row) { BaseData e{}; - e.level = row[0] ? static_cast(strtoul(row[0], nullptr, 10)) : 0; - e.class_ = row[1] ? static_cast(strtoul(row[1], nullptr, 10)) : 0; - e.hp = row[2] ? strtod(row[2], nullptr) : 0; - e.mana = row[3] ? strtod(row[3], nullptr) : 0; - e.end = row[4] ? strtod(row[4], nullptr) : 0; - e.unk1 = row[5] ? strtod(row[5], nullptr) : 0; - e.unk2 = row[6] ? strtod(row[6], nullptr) : 0; - e.hp_fac = row[7] ? strtod(row[7], nullptr) : 0; - e.mana_fac = row[8] ? strtod(row[8], nullptr) : 0; - e.end_fac = row[9] ? strtod(row[9], nullptr) : 0; + e.level = row[0] ? static_cast(strtoul(row[0], nullptr, 10)) : 0; + e.class_ = row[1] ? static_cast(strtoul(row[1], nullptr, 10)) : 0; + e.hp = row[2] ? strtod(row[2], nullptr) : 0; + e.mana = row[3] ? strtod(row[3], nullptr) : 0; + e.end = row[4] ? strtod(row[4], nullptr) : 0; + e.hp_regen = row[5] ? strtod(row[5], nullptr) : 0; + e.end_regen = row[6] ? strtod(row[6], nullptr) : 0; + e.hp_fac = row[7] ? strtod(row[7], nullptr) : 0; + e.mana_fac = row[8] ? strtod(row[8], nullptr) : 0; + e.end_fac = row[9] ? strtod(row[9], nullptr) : 0; all_entries.push_back(e); } @@ -341,16 +341,16 @@ public: for (auto row = results.begin(); row != results.end(); ++row) { BaseData e{}; - e.level = row[0] ? static_cast(strtoul(row[0], nullptr, 10)) : 0; - e.class_ = row[1] ? static_cast(strtoul(row[1], nullptr, 10)) : 0; - e.hp = row[2] ? strtod(row[2], nullptr) : 0; - e.mana = row[3] ? strtod(row[3], nullptr) : 0; - e.end = row[4] ? strtod(row[4], nullptr) : 0; - e.unk1 = row[5] ? strtod(row[5], nullptr) : 0; - e.unk2 = row[6] ? strtod(row[6], nullptr) : 0; - e.hp_fac = row[7] ? strtod(row[7], nullptr) : 0; - e.mana_fac = row[8] ? strtod(row[8], nullptr) : 0; - e.end_fac = row[9] ? strtod(row[9], nullptr) : 0; + e.level = row[0] ? static_cast(strtoul(row[0], nullptr, 10)) : 0; + e.class_ = row[1] ? static_cast(strtoul(row[1], nullptr, 10)) : 0; + e.hp = row[2] ? strtod(row[2], nullptr) : 0; + e.mana = row[3] ? strtod(row[3], nullptr) : 0; + e.end = row[4] ? strtod(row[4], nullptr) : 0; + e.hp_regen = row[5] ? strtod(row[5], nullptr) : 0; + e.end_regen = row[6] ? strtod(row[6], nullptr) : 0; + e.hp_fac = row[7] ? strtod(row[7], nullptr) : 0; + e.mana_fac = row[8] ? strtod(row[8], nullptr) : 0; + e.end_fac = row[9] ? strtod(row[9], nullptr) : 0; all_entries.push_back(e); } @@ -430,8 +430,8 @@ public: v.push_back(std::to_string(e.hp)); v.push_back(std::to_string(e.mana)); v.push_back(std::to_string(e.end)); - v.push_back(std::to_string(e.unk1)); - v.push_back(std::to_string(e.unk2)); + v.push_back(std::to_string(e.hp_regen)); + v.push_back(std::to_string(e.end_regen)); v.push_back(std::to_string(e.hp_fac)); v.push_back(std::to_string(e.mana_fac)); v.push_back(std::to_string(e.end_fac)); @@ -462,8 +462,8 @@ public: v.push_back(std::to_string(e.hp)); v.push_back(std::to_string(e.mana)); v.push_back(std::to_string(e.end)); - v.push_back(std::to_string(e.unk1)); - v.push_back(std::to_string(e.unk2)); + v.push_back(std::to_string(e.hp_regen)); + v.push_back(std::to_string(e.end_regen)); v.push_back(std::to_string(e.hp_fac)); v.push_back(std::to_string(e.mana_fac)); v.push_back(std::to_string(e.end_fac)); diff --git a/common/servertalk.h b/common/servertalk.h index a6e158997..3602b72b1 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -253,6 +253,7 @@ #define ServerOP_ReloadDataBucketsCache 0x4125 #define ServerOP_ReloadFactions 0x4126 #define ServerOP_ReloadLoot 0x4127 +#define ServerOP_ReloadBaseData 0x4128 #define ServerOP_CZDialogueWindow 0x4500 #define ServerOP_CZLDoNUpdate 0x4501 diff --git a/common/shareddb.cpp b/common/shareddb.cpp index fed089f0b..e5b4c3bbe 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -1974,117 +1974,6 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) { LoadDamageShieldTypes(sp, max_spells); } -int SharedDatabase::GetMaxBaseDataLevel() { - const std::string query = "SELECT MAX(level) FROM base_data"; - auto results = QueryDatabase(query); - if (!results.Success()) { - return -1; - } - - if (results.RowCount() == 0) - return -1; - - auto& row = results.begin(); - - return Strings::ToInt(row[0]); -} - -bool SharedDatabase::LoadBaseData(const std::string &prefix) { - base_data_mmf.reset(nullptr); - - try { - const auto Config = EQEmuConfig::get(); - EQ::IPCMutex mutex("base_data"); - mutex.Lock(); - - std::string file_name = fmt::format("{}/{}{}", path.GetSharedMemoryPath(), prefix, std::string("base_data")); - base_data_mmf = std::make_unique(file_name); - mutex.Unlock(); - - LogInfo("Loaded base data via shared memory"); - } catch(std::exception& ex) { - LogError("Error Loading Base Data: {}", ex.what()); - return false; - } - - return true; -} - -void SharedDatabase::LoadBaseData(void *data, int max_level) { - char *base_ptr = static_cast(data); - - const std::string query = "SELECT * FROM base_data ORDER BY level, class ASC"; - auto results = QueryDatabase(query); - if (!results.Success()) { - return; - } - - for (auto& row = results.begin(); row != results.end(); ++row) { - const int lvl = Strings::ToInt(row[0]); - const int cl = Strings::ToInt(row[1]); - - if(lvl <= 0) { - LogError("Non fatal error: base_data.level <= 0, ignoring."); - continue; - } - - if(lvl >= max_level) { - LogError("Non fatal error: base_data.level >= max_level, ignoring."); - continue; - } - - if(cl <= 0) { - LogError("Non fatal error: base_data.cl <= 0, ignoring."); - continue; - } - - if(cl > 16) { - LogError("Non fatal error: base_data.class > 16, ignoring."); - continue; - } - - BaseDataStruct *bd = reinterpret_cast(base_ptr + (((16 * (lvl - 1)) + (cl - 1)) * sizeof(BaseDataStruct))); - bd->base_hp = Strings::ToFloat(row[2]); - bd->base_mana = Strings::ToFloat(row[3]); - bd->base_end = Strings::ToFloat(row[4]); - bd->hp_regen = Strings::ToFloat(row[5]); - bd->end_regen = Strings::ToFloat(row[6]); - bd->hp_factor = Strings::ToFloat(row[7]); - bd->mana_factor = Strings::ToFloat(row[8]); - bd->endurance_factor = Strings::ToFloat(row[9]); - } -} - -const BaseDataStruct* SharedDatabase::GetBaseData(int lvl, int cl) const -{ - if(!base_data_mmf) { - return nullptr; - } - - if(lvl <= 0) { - return nullptr; - } - - if(cl <= 0) { - return nullptr; - } - - if(cl > 16) { - return nullptr; - } - - char *base_ptr = static_cast(base_data_mmf->Get()); - - const uint32 offset = ((16 * (lvl - 1)) + (cl - 1)) * sizeof(BaseDataStruct); - - if(offset >= base_data_mmf->Size()) { - return nullptr; - } - - const BaseDataStruct *bd = reinterpret_cast(base_ptr + offset); - return bd; -} - void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* message) { const std::string query = StringFormat("SELECT `inspect_message` FROM `character_inspect_messages` WHERE `id` = %u LIMIT 1", character_id); auto results = QueryDatabase(query); diff --git a/common/shareddb.h b/common/shareddb.h index 5103f5a58..e525f9aca 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -24,7 +24,6 @@ #include "database.h" #include "skills.h" #include "spdat.h" -#include "base_data.h" #include "fixed_memory_hash_set.h" #include "fixed_memory_variable_hash_set.h" #include "say_link.h" @@ -35,7 +34,6 @@ #include class EvolveInfo; -struct BaseDataStruct; struct InspectMessage_Struct; struct PlayerProfile_Struct; struct SPDat_Spell_Struct; @@ -180,14 +178,6 @@ public: uint32 GetSharedSpellsCount() { return m_shared_spells_count; } uint32 GetSpellsCount(); - /** - * basedata - */ - int GetMaxBaseDataLevel(); - bool LoadBaseData(const std::string &prefix); - void LoadBaseData(void *data, int max_level); - const BaseDataStruct *GetBaseData(int lvl, int cl) const; - std::string CreateItemLink(uint32 item_id) const { EQ::SayLinkEngine linker; @@ -206,7 +196,6 @@ protected: std::unique_ptr> faction_hash; std::unique_ptr faction_associations_mmf; std::unique_ptr> faction_associations_hash; - std::unique_ptr base_data_mmf; std::unique_ptr spells_mmf; public: diff --git a/common/version.h b/common/version.h index 28646f3f3..7bd693702 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 9257 +#define CURRENT_BINARY_DATABASE_VERSION 9258 #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9042 diff --git a/shared_memory/CMakeLists.txt b/shared_memory/CMakeLists.txt index 2fdf314c6..ba8e2f033 100644 --- a/shared_memory/CMakeLists.txt +++ b/shared_memory/CMakeLists.txt @@ -1,7 +1,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.12) SET(shared_memory_sources - base_data.cpp items.cpp main.cpp spells.cpp @@ -9,7 +8,6 @@ SET(shared_memory_sources ) SET(shared_memory_headers - base_data.h items.h spells.h skill_caps.h diff --git a/shared_memory/base_data.cpp b/shared_memory/base_data.cpp deleted file mode 100644 index f65780886..000000000 --- a/shared_memory/base_data.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "base_data.h" -#include "../common/global_define.h" -#include "../common/shareddb.h" -#include "../common/ipc_mutex.h" -#include "../common/memory_mapped_file.h" -#include "../common/eqemu_exception.h" - -void LoadBaseData(SharedDatabase *database, const std::string &prefix) { - EQ::IPCMutex mutex("base_data"); - mutex.Lock(); - int records = (database->GetMaxBaseDataLevel() + 1); - if(records == 0) { - EQ_EXCEPT("Shared Memory", "Unable to get base data from the database."); - } - - uint32 size = records * 16 * sizeof(BaseDataStruct); - - auto Config = EQEmuConfig::get(); - std::string file_name = Config->SharedMemDir + prefix + std::string("base_data"); - EQ::MemoryMappedFile mmf(file_name, size); - mmf.ZeroFile(); - - void *ptr = mmf.Get(); - database->LoadBaseData(ptr, records); - mutex.Unlock(); -} diff --git a/shared_memory/base_data.h b/shared_memory/base_data.h deleted file mode 100644 index 81cd8dd1b..000000000 --- a/shared_memory/base_data.h +++ /dev/null @@ -1,28 +0,0 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef __EQEMU_SHARED_MEMORY_BASE_DATA_H -#define __EQEMU_SHARED_MEMORY_BASE_DATA_H - -#include -#include "../common/eqemu_config.h" - -class SharedDatabase; -void LoadBaseData(SharedDatabase *database, const std::string &prefix); - -#endif diff --git a/shared_memory/main.cpp b/shared_memory/main.cpp index 12022ac21..58ebaa444 100644 --- a/shared_memory/main.cpp +++ b/shared_memory/main.cpp @@ -30,7 +30,6 @@ #include "items.h" #include "skill_caps.h" #include "spells.h" -#include "base_data.h" #include "../common/content/world_content_service.h" #include "../common/zone_store.h" #include "../common/path_manager.h" @@ -180,22 +179,15 @@ int main(int argc, char **argv) std::string hotfix_name = ""; - bool load_all = true; - bool load_items = false; - bool load_skill_caps = false; - bool load_spells = false; - bool load_bd = false; + bool load_all = true; + bool load_items = false; + bool load_loot = false; + bool load_skill_caps = false; + bool load_spells = false; if (argc > 1) { for (int i = 1; i < argc; ++i) { switch (argv[i][0]) { - case 'b': - if (strcasecmp("base_data", argv[i]) == 0) { - load_bd = true; - load_all = false; - } - break; - case 'i': if (strcasecmp("items", argv[i]) == 0) { load_items = true; @@ -263,16 +255,6 @@ int main(int argc, char **argv) } } - if (load_all || load_bd) { - LogInfo("Loading base data"); - try { - LoadBaseData(&content_db, hotfix_name); - } catch (std::exception &ex) { - LogError("{}", ex.what()); - return 1; - } - } - LogSys.CloseFileLogs(); return 0; } diff --git a/world/eqemu_api_world_data_service.cpp b/world/eqemu_api_world_data_service.cpp index ba01936ed..25d348b19 100644 --- a/world/eqemu_api_world_data_service.cpp +++ b/world/eqemu_api_world_data_service.cpp @@ -137,6 +137,7 @@ struct Reload { std::vector reload_types = { Reload{.command = "aa", .opcode = ServerOP_ReloadAAData, .desc = "Alternate Advancement"}, Reload{.command = "alternate_currencies", .opcode = ServerOP_ReloadAlternateCurrencies, .desc = "Alternate Currencies"}, + Reload{.command = "base_data", .opcode = ServerOP_ReloadBaseData, .desc = "Base Data"}, Reload{.command = "blocked_spells", .opcode = ServerOP_ReloadBlockedSpells, .desc = "Blocked Spells"}, Reload{.command = "commands", .opcode = ServerOP_ReloadCommands, .desc = "Commands"}, Reload{.command = "data_buckets_cache", .opcode = ServerOP_ReloadDataBucketsCache, .desc = "Data Buckets Cache"}, diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index 380cac6da..324ca8743 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -1385,6 +1385,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { case ServerOP_RefreshCensorship: case ServerOP_ReloadAAData: case ServerOP_ReloadAlternateCurrencies: + case ServerOP_ReloadBaseData: case ServerOP_ReloadBlockedSpells: case ServerOP_ReloadCommands: case ServerOP_ReloadDoors: diff --git a/zone/CMakeLists.txt b/zone/CMakeLists.txt index 759adf0a1..b84f5677d 100644 --- a/zone/CMakeLists.txt +++ b/zone/CMakeLists.txt @@ -160,6 +160,7 @@ SET(zone_sources zone.cpp zone_config.cpp zonedb.cpp + zone_base_data.cpp zone_event_scheduler.cpp zone_npc_factions.cpp zone_reload.cpp diff --git a/zone/client.cpp b/zone/client.cpp index 5b11803ff..fe7473ce1 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -9087,6 +9087,7 @@ void Client::ShowDevToolsMenu() */ menu_reload_one += Saylink::Silent("#reload aa", "AAs"); menu_reload_one += " | " + Saylink::Silent("#reload alternate_currencies", "Alternate Currencies"); + menu_reload_one += " | " + Saylink::Silent("#reload base_data", "Base Data"); menu_reload_one += " | " + Saylink::Silent("#reload blocked_spells", "Blocked Spells"); menu_reload_two += Saylink::Silent("#reload commands", "Commands"); @@ -11019,6 +11020,16 @@ void Client::SendReloadCommandMessages() { ).c_str() ); + auto base_data_link = Saylink::Silent("#reload base_data"); + + Message( + Chat::White, + fmt::format( + "Usage: {} - Reloads Base Data globally", + base_data_link + ).c_str() + ); + auto blocked_spells_link = Saylink::Silent("#reload blocked_spells"); Message( diff --git a/zone/client_mods.cpp b/zone/client_mods.cpp index aff88c07c..43d6a9838 100644 --- a/zone/client_mods.cpp +++ b/zone/client_mods.cpp @@ -237,9 +237,10 @@ int64 Client::CalcHPRegen(bool bCombat) item_regen += aabonuses.HPRegen; int64 base = 0; - auto base_data = database.GetBaseData(GetLevel(), GetClass()); - if (base_data) - base = static_cast(base_data->hp_regen); + auto base_data = zone->GetBaseData(GetLevel(), GetClass()); + if (base_data.level == GetLevel()) { + base = static_cast(base_data.hp_regen); + } auto level = GetLevel(); bool skip_innate = false; @@ -486,9 +487,9 @@ int64 Client::CalcBaseHP() stats += 255; } base_hp = 5; - auto base_data = database.GetBaseData(GetLevel(), GetClass()); - if (base_data) { - base_hp += base_data->base_hp + (base_data->hp_factor * stats); + auto base_data = zone->GetBaseData(GetLevel(), GetClass()); + if (base_data.level == GetLevel()) { + base_hp += base_data.hp + (base_data.hp_fac * stats); base_hp += itembonuses.heroic_max_hp; } } @@ -575,10 +576,9 @@ int64 Client::CalcBaseMana() } ConvertedWisInt = (3 * over200 - 300) / 2 + over200; } - auto base_data = database.GetBaseData(GetLevel(), GetClass()); - if (base_data) { - max_m = base_data->base_mana + - (ConvertedWisInt * base_data->mana_factor) + itembonuses.heroic_max_mana; + auto base_data = zone->GetBaseData(GetLevel(), GetClass()); + if (base_data.level == GetLevel()) { + max_m = base_data.mana + (ConvertedWisInt * base_data.mana_fac) + itembonuses.heroic_max_mana; } } else { @@ -608,10 +608,9 @@ int64 Client::CalcBaseMana() } ConvertedWisInt = (3 * over200 - 300) / 2 + over200; } - auto base_data = database.GetBaseData(GetLevel(), GetClass()); - if (base_data) { - max_m = base_data->base_mana + - (ConvertedWisInt * base_data->mana_factor) + itembonuses.heroic_max_mana; + auto base_data = zone->GetBaseData(GetLevel(), GetClass()); + if (base_data.level == GetLevel()) { + max_m = base_data.mana + (ConvertedWisInt * base_data.mana_fac) + itembonuses.heroic_max_mana; } } else { @@ -1639,9 +1638,9 @@ int64 Client::CalcBaseEndurance() else if (stats > 100.0f) { stats = 2.5f * (stats - 100.0f) + 100.0f; } - auto base_data = database.GetBaseData(GetLevel(), GetClass()); - if (base_data) { - base_end = base_data->base_end + itembonuses.heroic_max_end + (base_data->endurance_factor * static_cast(stats)); + auto base_data = zone->GetBaseData(GetLevel(), GetClass()); + if (base_data.level == GetLevel()) { + base_end = base_data.end + itembonuses.heroic_max_end + (base_data.end_fac * static_cast(stats)); } } else { @@ -1676,9 +1675,9 @@ int64 Client::CalcEnduranceRegen(bool bCombat) { int64 base = 0; if (!IsStarved()) { - auto base_data = database.GetBaseData(GetLevel(), GetClass()); - if (base_data) { - base = static_cast(base_data->end_regen); + auto base_data = zone->GetBaseData(GetLevel(), GetClass()); + if (base_data.level == GetLevel()) { + base = static_cast(base_data.end_regen); if (!auto_attack && base > 0) base += base / 2; } diff --git a/zone/gm_commands/reload.cpp b/zone/gm_commands/reload.cpp index ae1df2e06..0c0a73410 100644 --- a/zone/gm_commands/reload.cpp +++ b/zone/gm_commands/reload.cpp @@ -15,6 +15,7 @@ void command_reload(Client *c, const Seperator *sep) bool is_rq_alias = sep->arg[0] && Strings::Contains(command, "#rq"); bool is_aa = !strcasecmp(sep->arg[1], "aa"); bool is_alternate_currencies = !strcasecmp(sep->arg[1], "alternate_currencies"); + bool is_base_data = !strcasecmp(sep->arg[1], "base_data"); bool is_blocked_spells = !strcasecmp(sep->arg[1], "blocked_spells"); bool is_commands = !strcasecmp(sep->arg[1], "commands"); bool is_content_flags = !strcasecmp(sep->arg[1], "content_flags"); @@ -46,6 +47,7 @@ void command_reload(Client *c, const Seperator *sep) if ( !is_aa && !is_alternate_currencies && + !is_base_data && !is_blocked_spells && !is_commands && !is_content_flags && @@ -86,6 +88,9 @@ void command_reload(Client *c, const Seperator *sep) } else if (is_alternate_currencies) { c->Message(Chat::White, "Attempting to reload Alternate Currencies globally."); pack = new ServerPacket(ServerOP_ReloadAlternateCurrencies, 0); + } else if (is_base_data) { + c->Message(Chat::White, "Attempting to reload Base Data globally."); + pack = new ServerPacket(ServerOP_ReloadBaseData, 0); } else if (is_blocked_spells) { c->Message(Chat::White, "Attempting to reload Blocked Spells globally."); pack = new ServerPacket(ServerOP_ReloadBlockedSpells, 0); diff --git a/zone/main.cpp b/zone/main.cpp index dcbb3b7b1..6897c00c6 100644 --- a/zone/main.cpp +++ b/zone/main.cpp @@ -381,11 +381,6 @@ int main(int argc, char **argv) return 1; } - if (!database.LoadBaseData(hotfix_name)) { - LogError("Loading base data failed!"); - return 1; - } - guild_mgr.LoadGuilds(); content_db.LoadFactionData(); title_manager.LoadTitles(); diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 37b388772..2ba4c7e9f 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -1957,6 +1957,15 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } break; } + case ServerOP_ReloadBaseData: + { + if (zone && zone->IsLoaded()) { + zone->SendReloadMessage("Base Data"); + zone->ReloadBaseData(); + } + + break; + } case ServerOP_ReloadBlockedSpells: { if (zone && zone->IsLoaded()) { @@ -3525,11 +3534,6 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) if (!content_db.LoadSpells(hotfix_name, &SPDAT_RECORDS, &spells)) { LogError("Loading spells failed!"); } - - LogInfo("Loading base data"); - if (!content_db.LoadBaseData(hotfix_name)) { - LogError("Loading base data failed!"); - } break; } case ServerOP_CZClientMessageString: diff --git a/zone/zone.cpp b/zone/zone.cpp index e549264f7..a4333c461 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -1177,6 +1177,8 @@ bool Zone::Init(bool is_static) { content_db.LoadGlobalLoot(); + LoadBaseData(); + //Load merchant data LoadMerchants(); diff --git a/zone/zone.h b/zone/zone.h index 7d8b0d0b5..40ae68ce1 100755 --- a/zone/zone.h +++ b/zone/zone.h @@ -45,6 +45,7 @@ #include "../common/repositories/loottable_entries_repository.h" #include "../common/repositories/lootdrop_repository.h" #include "../common/repositories/lootdrop_entries_repository.h" +#include "../common/repositories/base_data_repository.h" struct EXPModifier { @@ -439,6 +440,12 @@ public: LootdropRepository::Lootdrop GetLootdrop(const uint32 lootdrop_id) const; std::vector GetLootdropEntries(const uint32 lootdrop_id) const; + // Base Data + inline void ClearBaseData() { m_base_data.clear(); }; + BaseDataRepository::BaseData GetBaseData(uint8 level, uint8 class_id); + void LoadBaseData(); + void ReloadBaseData(); + private: bool allow_mercs; bool can_bind; @@ -499,6 +506,9 @@ private: std::vector m_loottable_entries = {}; std::vector m_lootdrops = {}; std::vector m_lootdrop_entries = {}; + + // Base Data + std::vector m_base_data = { }; }; #endif diff --git a/zone/zone_base_data.cpp b/zone/zone_base_data.cpp new file mode 100644 index 000000000..b9b2e3756 --- /dev/null +++ b/zone/zone_base_data.cpp @@ -0,0 +1,39 @@ +#include "zone.h" + +BaseDataRepository::BaseData Zone::GetBaseData(uint8 level, uint8 class_id) +{ + for (const auto& e : m_base_data) { + if (e.level == level && e.class_ == class_id) { + return e; + } + } + + return BaseDataRepository::NewEntity(); +} + +void Zone::LoadBaseData() +{ + const auto& l = BaseDataRepository::All(content_db); + + m_base_data.reserve(l.size()); + + for (const auto& e : l) { + if (e.level < 1 || !IsPlayerClass(e.class_)) { + continue; + } + + m_base_data.emplace_back(e); + } + + LogInfo( + "Loaded [{}] Base Data Entr{}", + l.size(), + l.size() != 1 ? "ies" : "y" + ); +} + +void Zone::ReloadBaseData() +{ + ClearBaseData(); + LoadBaseData(); +}