mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 12:41:30 +00:00
[Base Data] Remove from shared memory and simplify (#4045)
* [Base Data] Remove from shared memory and simplify - Removes Base Data loading from shared memory and puts it into zone. - Changes type of `level` and `class` to `uint8_t` from `uint32_t` for consistency since we're renaming fields here anyway. - Renames `unk1` to `hp_regen` in `base_data` table. - Renames `unk2` to `end_regen` in `base_data` table. - These changed fields were already mapped, we just hadn't renamed them for whatever reason. - Regenerates Base Data repository. - Adds `#reload base_data` to reload base data in real time. * Cleanup * Update shareddb.h * Cleanup. * Update shareddb.cpp * Update main.cpp
This commit is contained in:
parent
b6b779723e
commit
8edf7a07e3
@ -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<BaseDataRepository::BaseData> 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<uint8_t>(Strings::ToUnsignedInt(line_data[0]));
|
||||
e.class_ = static_cast<uint8_t>(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) {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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{
|
||||
|
||||
@ -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<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.class_ = row[1] ? static_cast<uint32_t>(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<uint8_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.class_ = row[1] ? static_cast<uint8_t>(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<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.class_ = row[1] ? static_cast<uint32_t>(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<uint8_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.class_ = row[1] ? static_cast<uint8_t>(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<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.class_ = row[1] ? static_cast<uint32_t>(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<uint8_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.class_ = row[1] ? static_cast<uint8_t>(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));
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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<EQ::MemoryMappedFile>(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<char*>(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<BaseDataStruct*>(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<char*>(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<BaseDataStruct*>(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);
|
||||
|
||||
@ -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 <memory>
|
||||
|
||||
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<EQ::FixedMemoryHashSet<NPCFactionList>> faction_hash;
|
||||
std::unique_ptr<EQ::MemoryMappedFile> faction_associations_mmf;
|
||||
std::unique_ptr<EQ::FixedMemoryHashSet<FactionAssociations>> faction_associations_hash;
|
||||
std::unique_ptr<EQ::MemoryMappedFile> base_data_mmf;
|
||||
std::unique_ptr<EQ::MemoryMappedFile> spells_mmf;
|
||||
|
||||
public:
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
}
|
||||
@ -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 <string>
|
||||
#include "../common/eqemu_config.h"
|
||||
|
||||
class SharedDatabase;
|
||||
void LoadBaseData(SharedDatabase *database, const std::string &prefix);
|
||||
|
||||
#endif
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -137,6 +137,7 @@ struct Reload {
|
||||
std::vector<Reload> 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"},
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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<int>(base_data->hp_regen);
|
||||
auto base_data = zone->GetBaseData(GetLevel(), GetClass());
|
||||
if (base_data.level == GetLevel()) {
|
||||
base = static_cast<int>(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<int>(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<int>(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<int>(base_data->end_regen);
|
||||
auto base_data = zone->GetBaseData(GetLevel(), GetClass());
|
||||
if (base_data.level == GetLevel()) {
|
||||
base = static_cast<int>(base_data.end_regen);
|
||||
if (!auto_attack && base > 0)
|
||||
base += base / 2;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -1177,6 +1177,8 @@ bool Zone::Init(bool is_static) {
|
||||
|
||||
content_db.LoadGlobalLoot();
|
||||
|
||||
LoadBaseData();
|
||||
|
||||
//Load merchant data
|
||||
LoadMerchants();
|
||||
|
||||
|
||||
10
zone/zone.h
10
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<LootdropEntriesRepository::LootdropEntries> 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<LoottableEntriesRepository::LoottableEntries> m_loottable_entries = {};
|
||||
std::vector<LootdropRepository::Lootdrop> m_lootdrops = {};
|
||||
std::vector<LootdropEntriesRepository::LootdropEntries> m_lootdrop_entries = {};
|
||||
|
||||
// Base Data
|
||||
std::vector<BaseDataRepository::BaseData> m_base_data = { };
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
39
zone/zone_base_data.cpp
Normal file
39
zone/zone_base_data.cpp
Normal file
@ -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();
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user