mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 13:41:31 +00:00
[Character] Convert Load/Save of Character Buffs to Repositories (#3855)
* [Character] Convert Load/Save of Character Buffs to Repositories # Notes - Convert `LoadBuffs` to repositories. - `SaveBuffs` was already using repositories, cleanup logic. # Images ## Load ## Save * Update repository. * Update zonedb.cpp
This commit is contained in:
parent
f3de3e8c31
commit
164fe31fa8
@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @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_BUFFS_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_BUFFS_REPOSITORY_H
|
||||||
@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterBuffsRepository {
|
class BaseCharacterBuffsRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterBuffs {
|
struct CharacterBuffs {
|
||||||
@ -168,8 +169,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_buffs_id
|
character_buffs_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -478,6 +480,94 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
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 CharacterBuffs &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.character_id));
|
||||||
|
v.push_back(std::to_string(e.slot_id));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
v.push_back(std::to_string(e.caster_level));
|
||||||
|
v.push_back("'" + Strings::Escape(e.caster_name) + "'");
|
||||||
|
v.push_back(std::to_string(e.ticsremaining));
|
||||||
|
v.push_back(std::to_string(e.counters));
|
||||||
|
v.push_back(std::to_string(e.numhits));
|
||||||
|
v.push_back(std::to_string(e.melee_rune));
|
||||||
|
v.push_back(std::to_string(e.magic_rune));
|
||||||
|
v.push_back(std::to_string(e.persistent));
|
||||||
|
v.push_back(std::to_string(e.dot_rune));
|
||||||
|
v.push_back(std::to_string(e.caston_x));
|
||||||
|
v.push_back(std::to_string(e.caston_y));
|
||||||
|
v.push_back(std::to_string(e.caston_z));
|
||||||
|
v.push_back(std::to_string(e.ExtraDIChance));
|
||||||
|
v.push_back(std::to_string(e.instrument_mod));
|
||||||
|
|
||||||
|
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<CharacterBuffs> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.character_id));
|
||||||
|
v.push_back(std::to_string(e.slot_id));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
v.push_back(std::to_string(e.caster_level));
|
||||||
|
v.push_back("'" + Strings::Escape(e.caster_name) + "'");
|
||||||
|
v.push_back(std::to_string(e.ticsremaining));
|
||||||
|
v.push_back(std::to_string(e.counters));
|
||||||
|
v.push_back(std::to_string(e.numhits));
|
||||||
|
v.push_back(std::to_string(e.melee_rune));
|
||||||
|
v.push_back(std::to_string(e.magic_rune));
|
||||||
|
v.push_back(std::to_string(e.persistent));
|
||||||
|
v.push_back(std::to_string(e.dot_rune));
|
||||||
|
v.push_back(std::to_string(e.caston_x));
|
||||||
|
v.push_back(std::to_string(e.caston_y));
|
||||||
|
v.push_back(std::to_string(e.caston_z));
|
||||||
|
v.push_back(std::to_string(e.ExtraDIChance));
|
||||||
|
v.push_back(std::to_string(e.instrument_mod));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_BUFFS_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_BUFFS_REPOSITORY_H
|
||||||
|
|||||||
@ -1814,14 +1814,14 @@ void EntityList::DuelMessage(Mob *winner, Mob *loser, bool flee)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Client *EntityList::GetClientByName(const char *checkname)
|
Client *EntityList::GetClientByName(const char* name)
|
||||||
{
|
{
|
||||||
auto it = client_list.begin();
|
for (const auto& e : client_list) {
|
||||||
while (it != client_list.end()) {
|
if (e.second && Strings::EqualFold(e.second->GetName(), name)) {
|
||||||
if (strcasecmp(it->second->GetName(), checkname) == 0)
|
return e.second;
|
||||||
return it->second;
|
}
|
||||||
++it;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -171,7 +171,7 @@ public:
|
|||||||
return it->second;
|
return it->second;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
Client *GetClientByName(const char *name);
|
Client *GetClientByName(const char* name);
|
||||||
Client *GetClientByAccID(uint32 accid);
|
Client *GetClientByAccID(uint32 accid);
|
||||||
inline Client *GetClientByID(uint16 id)
|
inline Client *GetClientByID(uint16 id)
|
||||||
{
|
{
|
||||||
|
|||||||
218
zone/zonedb.cpp
218
zone/zonedb.cpp
@ -2930,160 +2930,150 @@ void ZoneDatabase::UpdateAltCurrencyValue(uint32 char_id, uint32 currency_id, ui
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneDatabase::SaveBuffs(Client *client) {
|
void ZoneDatabase::SaveBuffs(Client *client)
|
||||||
|
{
|
||||||
|
CharacterBuffsRepository::DeleteWhere(
|
||||||
|
database,
|
||||||
|
fmt::format(
|
||||||
|
"`character_id` = {}",
|
||||||
|
client->CharacterID()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// delete the character buffs
|
auto buffs = client->GetBuffs();
|
||||||
CharacterBuffsRepository::DeleteWhere(database, fmt::format("character_id = {}", client->CharacterID()));
|
const int max_buff_slots = client->GetMaxBuffSlots();
|
||||||
|
|
||||||
// get the character buffs
|
std::vector<CharacterBuffsRepository::CharacterBuffs> v;
|
||||||
uint32 buff_count = client->GetMaxBuffSlots();
|
|
||||||
Buffs_Struct *buffs = client->GetBuffs();
|
|
||||||
|
|
||||||
// character buffs struct
|
auto e = CharacterBuffsRepository::NewEntity();
|
||||||
auto b = CharacterBuffsRepository::NewEntity();
|
|
||||||
|
|
||||||
// vector of character buffs
|
uint32 character_buff_count = 0;
|
||||||
std::vector<CharacterBuffsRepository::CharacterBuffs> character_buffs = {};
|
|
||||||
|
|
||||||
// count the number of buffs that are valid
|
for (int slot_id = 0; slot_id < max_buff_slots; slot_id++) {
|
||||||
int character_buff_count = 0;
|
if (!IsValidSpell(buffs[slot_id].spellid)) {
|
||||||
for (int index = 0; index < buff_count; index++) {
|
|
||||||
if (!IsValidSpell(buffs[index].spellid)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
character_buff_count++;
|
character_buff_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate memory for the character buffs
|
v.reserve(character_buff_count);
|
||||||
character_buffs.reserve(character_buff_count);
|
|
||||||
|
|
||||||
for (int index = 0; index < buff_count; index++) {
|
for (int slot_id = 0; slot_id < max_buff_slots; slot_id++) {
|
||||||
if (!IsValidSpell(buffs[index].spellid)) {
|
if (!IsValidSpell(buffs[slot_id].spellid)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill in the buff struct
|
e.character_id = client->CharacterID();
|
||||||
b.character_id = client->CharacterID();
|
e.slot_id = slot_id;
|
||||||
b.slot_id = index;
|
e.spell_id = buffs[slot_id].spellid;
|
||||||
b.spell_id = buffs[index].spellid;
|
e.caster_level = buffs[slot_id].casterlevel;
|
||||||
b.caster_level = buffs[index].casterlevel;
|
e.caster_name = buffs[slot_id].caster_name;
|
||||||
b.caster_name = buffs[index].caster_name;
|
e.ticsremaining = buffs[slot_id].ticsremaining;
|
||||||
b.ticsremaining = buffs[index].ticsremaining;
|
e.counters = buffs[slot_id].counters;
|
||||||
b.counters = buffs[index].counters;
|
e.numhits = buffs[slot_id].hit_number;
|
||||||
b.numhits = buffs[index].hit_number;
|
e.melee_rune = buffs[slot_id].melee_rune;
|
||||||
b.melee_rune = buffs[index].melee_rune;
|
e.magic_rune = buffs[slot_id].magic_rune;
|
||||||
b.magic_rune = buffs[index].magic_rune;
|
e.persistent = buffs[slot_id].persistant_buff;
|
||||||
b.persistent = buffs[index].persistant_buff;
|
e.dot_rune = buffs[slot_id].dot_rune;
|
||||||
b.dot_rune = buffs[index].dot_rune;
|
e.caston_x = buffs[slot_id].caston_x;
|
||||||
b.caston_x = buffs[index].caston_x;
|
e.caston_y = buffs[slot_id].caston_y;
|
||||||
b.caston_y = buffs[index].caston_y;
|
e.caston_z = buffs[slot_id].caston_z;
|
||||||
b.caston_z = buffs[index].caston_z;
|
e.ExtraDIChance = buffs[slot_id].ExtraDIChance;
|
||||||
b.ExtraDIChance = buffs[index].ExtraDIChance;
|
e.instrument_mod = buffs[slot_id].instrument_mod;
|
||||||
b.instrument_mod = buffs[index].instrument_mod;
|
|
||||||
|
|
||||||
// add the buff to the vector
|
v.emplace_back(e);
|
||||||
character_buffs.emplace_back(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert the buffs into the database
|
if (!v.empty()) {
|
||||||
if (!character_buffs.empty()) {
|
CharacterBuffsRepository::ReplaceMany(database, v);
|
||||||
CharacterBuffsRepository::InsertMany(database, character_buffs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneDatabase::LoadBuffs(Client *client)
|
void ZoneDatabase::LoadBuffs(Client *client)
|
||||||
{
|
{
|
||||||
|
auto buffs = client->GetBuffs();
|
||||||
|
int max_buff_slots = client->GetMaxBuffSlots();
|
||||||
|
|
||||||
Buffs_Struct *buffs = client->GetBuffs();
|
for (int slot_id = 0; slot_id < max_buff_slots; ++slot_id) {
|
||||||
uint32 max_slots = client->GetMaxBuffSlots();
|
buffs[slot_id].spellid = SPELL_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
for (int index = 0; index < max_slots; ++index)
|
const auto& l = CharacterBuffsRepository::GetWhere(
|
||||||
buffs[index].spellid = SPELL_UNKNOWN;
|
*this,
|
||||||
|
fmt::format(
|
||||||
|
"`character_id` = {}",
|
||||||
|
client->CharacterID()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT spell_id, slot_id, caster_level, caster_name, ticsremaining, "
|
if (l.empty()) {
|
||||||
"counters, numhits, melee_rune, magic_rune, persistent, dot_rune, "
|
|
||||||
"caston_x, caston_y, caston_z, ExtraDIChance, instrument_mod "
|
|
||||||
"FROM `character_buffs` WHERE `character_id` = '%u'",
|
|
||||||
client->CharacterID());
|
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& row = results.begin(); row != results.end(); ++row) {
|
for (const auto& e : l) {
|
||||||
uint32 slot_id = Strings::ToUnsignedInt(row[1]);
|
if (e.slot_id >= max_buff_slots) {
|
||||||
if (slot_id >= client->GetMaxBuffSlots())
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
uint32 spell_id = Strings::ToUnsignedInt(row[0]);
|
|
||||||
if (!IsValidSpell(spell_id))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Client *caster = entity_list.GetClientByName(row[3]);
|
|
||||||
uint32 caster_level = Strings::ToInt(row[2]);
|
|
||||||
int32 ticsremaining = Strings::ToInt(row[4]);
|
|
||||||
uint32 counters = Strings::ToUnsignedInt(row[5]);
|
|
||||||
uint32 hit_number = Strings::ToUnsignedInt(row[6]);
|
|
||||||
uint32 melee_rune = Strings::ToUnsignedInt(row[7]);
|
|
||||||
uint32 magic_rune = Strings::ToUnsignedInt(row[8]);
|
|
||||||
uint8 persistent = Strings::ToUnsignedInt(row[9]);
|
|
||||||
uint32 dot_rune = Strings::ToUnsignedInt(row[10]);
|
|
||||||
int32 caston_x = Strings::ToUnsignedInt(row[11]);
|
|
||||||
int32 caston_y = Strings::ToUnsignedInt(row[12]);
|
|
||||||
int32 caston_z = Strings::ToUnsignedInt(row[13]);
|
|
||||||
int32 ExtraDIChance = Strings::ToUnsignedInt(row[14]);
|
|
||||||
uint32 instrument_mod = Strings::ToUnsignedInt(row[15]);
|
|
||||||
|
|
||||||
buffs[slot_id].spellid = spell_id;
|
|
||||||
buffs[slot_id].casterlevel = caster_level;
|
|
||||||
|
|
||||||
if (caster) {
|
|
||||||
buffs[slot_id].casterid = caster->GetID();
|
|
||||||
strcpy(buffs[slot_id].caster_name, caster->GetName());
|
|
||||||
buffs[slot_id].client = true;
|
|
||||||
} else {
|
|
||||||
buffs[slot_id].casterid = 0;
|
|
||||||
strcpy(buffs[slot_id].caster_name, "");
|
|
||||||
buffs[slot_id].client = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buffs[slot_id].ticsremaining = ticsremaining;
|
if (!IsValidSpell(e.spell_id)) {
|
||||||
buffs[slot_id].counters = counters;
|
continue;
|
||||||
buffs[slot_id].hit_number = hit_number;
|
}
|
||||||
buffs[slot_id].melee_rune = melee_rune;
|
|
||||||
buffs[slot_id].magic_rune = magic_rune;
|
Client* c = entity_list.GetClientByName(e.caster_name.c_str());
|
||||||
buffs[slot_id].persistant_buff = persistent ? true : false;
|
|
||||||
buffs[slot_id].dot_rune = dot_rune;
|
buffs[e.slot_id].spellid = e.spell_id;
|
||||||
buffs[slot_id].caston_x = caston_x;
|
buffs[e.slot_id].casterlevel = e.caster_level;
|
||||||
buffs[slot_id].caston_y = caston_y;
|
|
||||||
buffs[slot_id].caston_z = caston_z;
|
if (c) {
|
||||||
buffs[slot_id].ExtraDIChance = ExtraDIChance;
|
buffs[e.slot_id].casterid = c->GetID();
|
||||||
buffs[slot_id].RootBreakChance = 0;
|
buffs[e.slot_id].client = true;
|
||||||
buffs[slot_id].virus_spread_time = 0;
|
|
||||||
buffs[slot_id].UpdateClient = false;
|
strncpy(buffs[e.slot_id].caster_name, c->GetName(), 64);
|
||||||
buffs[slot_id].instrument_mod = instrument_mod;
|
} else {
|
||||||
|
buffs[e.slot_id].casterid = 0;
|
||||||
|
buffs[e.slot_id].client = false;
|
||||||
|
|
||||||
|
strncpy(buffs[e.slot_id].caster_name, "", 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffs[e.slot_id].ticsremaining = e.ticsremaining;
|
||||||
|
buffs[e.slot_id].counters = e.counters;
|
||||||
|
buffs[e.slot_id].hit_number = e.numhits;
|
||||||
|
buffs[e.slot_id].melee_rune = e.melee_rune;
|
||||||
|
buffs[e.slot_id].magic_rune = e.magic_rune;
|
||||||
|
buffs[e.slot_id].persistant_buff = e.persistent ? true : false;
|
||||||
|
buffs[e.slot_id].dot_rune = e.dot_rune;
|
||||||
|
buffs[e.slot_id].caston_x = e.caston_x;
|
||||||
|
buffs[e.slot_id].caston_y = e.caston_y;
|
||||||
|
buffs[e.slot_id].caston_z = e.caston_z;
|
||||||
|
buffs[e.slot_id].ExtraDIChance = e.ExtraDIChance;
|
||||||
|
buffs[e.slot_id].RootBreakChance = 0;
|
||||||
|
buffs[e.slot_id].virus_spread_time = 0;
|
||||||
|
buffs[e.slot_id].UpdateClient = false;
|
||||||
|
buffs[e.slot_id].instrument_mod = e.instrument_mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We load up to the most our client supports
|
// We load up to the most our client supports
|
||||||
max_slots = EQ::spells::StaticLookup(client->ClientVersion())->LongBuffs;
|
max_buff_slots = EQ::spells::StaticLookup(client->ClientVersion())->LongBuffs;
|
||||||
for (int index = 0; index < max_slots; ++index) {
|
|
||||||
if (!IsValidSpell(buffs[index].spellid))
|
for (int slot_id = 0; slot_id < max_buff_slots; ++slot_id) {
|
||||||
|
if (!IsValidSpell(buffs[slot_id].spellid)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (int effectIndex = 0; effectIndex < EFFECT_COUNT; ++effectIndex) {
|
if (IsEffectInSpell(buffs[slot_id].spellid, SE_Charm)) {
|
||||||
|
buffs[slot_id].spellid = SPELL_UNKNOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (spells[buffs[index].spellid].effect_id[effectIndex] == SE_Charm) {
|
if (IsEffectInSpell(buffs[slot_id].spellid, SE_Illusion)) {
|
||||||
buffs[index].spellid = SPELL_UNKNOWN;
|
if (buffs[slot_id].persistant_buff) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spells[buffs[index].spellid].effect_id[effectIndex] == SE_Illusion) {
|
buffs[slot_id].spellid = SPELL_UNKNOWN;
|
||||||
if (buffs[index].persistant_buff)
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
buffs[index].spellid = SPELL_UNKNOWN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user