It's been about a week since I started making changes to my server code. I'm very green in this aspect but, I learn quickly and understand concepts more than syntax. I also understand the implications of things. Not everything though!
I want to thank those that have given assistance if I haven't already.
My question/issue at the bottom.
I've added a few lines to <\zone\zonedb.cpp(3177)> and created a couple rules <\common\ruletypes.h(151) - RULE_CATEGORY(Pets)>.
It works as I expected.
Below is what I added:
ruletypes.h
Code:
RULE_BOOL(Pets, PetZonePersistence, true) // if true, pets will zone with players
RULE_BOOL(Pets, PetLogPersistence, true) // if false, pets will poof 30 minutes after logging character out (PetZonePersistence must be true)
zonedb.cpp
Code:
void ZoneDatabase::LoadPetInfo(Client *client)
{
// added this part 9/28/15
if (!RuleB(Pets, PetZonePersistence)) {
std::string query = StringFormat("DELETE FROM `character_pet_info` WHERE EXISTS (SELECT * FROM `character_data` WHERE character_pet_info.char_id = character_data.id AND `char_id` = %u AND character_pet_info.pet = 0)", client->CharacterID());
auto results = database.QueryDatabase(query);
if (!results.Success())
return;
query = StringFormat("DELETE FROM `character_pet_buffs` WHERE EXISTS (SELECT * FROM `character_data` WHERE character_pet_buffs.char_id = character_data.id AND `char_id` = %u AND character_pet_buffs.pet = 0)", client->CharacterID());
results = database.QueryDatabase(query);
if (!results.Success())
return;
query = StringFormat("DELETE FROM `character_pet_inventory` WHERE EXISTS (SELECT * FROM `character_data` WHERE character_pet_inventory.char_id = character_data.id AND `char_id` = %u AND character_pet_inventory.pet = 0)", client->CharacterID());
results = database.QueryDatabase(query);
if (!results.Success())
return;
}
else if (!RuleB(Pets, PetLogPersistence)) {
std::string query = StringFormat("DELETE FROM `character_pet_info` WHERE EXISTS (SELECT * FROM `character_data` WHERE character_pet_info.char_id = character_data.id AND `char_id` = %u AND(UNIX_TIMESTAMP(NOW()) - `last_login` > 1800) AND character_pet_info.pet = 0)", client->CharacterID());
auto results = database.QueryDatabase(query);
if (!results.Success())
return;
query = StringFormat("DELETE FROM `character_pet_buffs` WHERE EXISTS (SELECT * FROM `character_data` WHERE character_pet_buffs.char_id = character_data.id AND `char_id` = %u AND (UNIX_TIMESTAMP(NOW()) - `last_login` > 1800) AND character_pet_buffs.pet = 0)", client->CharacterID());
results = database.QueryDatabase(query);
if (!results.Success())
return;
query = StringFormat("DELETE FROM `character_pet_inventory` WHERE EXISTS (SELECT * FROM `character_data` WHERE character_pet_inventory.char_id = character_data.id AND `char_id` = %u AND (UNIX_TIMESTAMP(NOW()) - `last_login` > 1800) AND character_pet_inventory.pet = 0)", client->CharacterID());
results = database.QueryDatabase(query);
if (!results.Success())
return;
}
// above added 9/28/15 and a few small changes below
// Load current pet and suspended pet
PetInfo *petinfo = client->GetPetInfo(0);
PetInfo *suspended = client->GetPetInfo(1);
memset(petinfo, 0, sizeof(PetInfo));
memset(suspended, 0, sizeof(PetInfo));
std::string query = StringFormat("SELECT `pet`, `petname`, `petpower`, `spell_id`, "
"`hp`, `mana`, `size` FROM `character_pet_info` "
"WHERE `char_id` = %u",
client->CharacterID());
auto results = database.QueryDatabase(query);
if (!results.Success()) {
return;
}
My notes during the process:
Code:
Added lines to remove pet persistence after 30 minutes when logged off - `ZoneDatabase::LoadPetInfo` - \zone\zonedb.cpp(3177)
- it appears to work but, I am unsure if there is a better way
- this may also delete the entries if zoning after 30 min from `last_login` timestamp (if this timestamp is what I presume)
- it references `last_login` similar to norent although norent items are only loaded once through inventory.cpp, I think
- the solution may be to add the new lines where inventory.cpp is called for norent items
- nevermind, `last_login` appears to be an update timestamp which eliminates this as a possible issue
- create a rule for it to easily switch off for later expansions - done
ToDo: remove pet persistence between zones and create a rule for it - \zone\zonedb.cpp(3177)
- likely need an "if" statement in the same code as above; it seems to call for those lines after each zone switch
- possible solution is to simply use the added lines but, without the timestamp part and add a rule
- added more lines and rules linked to these lines
- it appears to work although I notice the rules need some time to catch up after #rules reload with these added rules
- I'm guessing it has to do with zonedb periodic updates
- issue remains on logging out and keeping pet for 30 min if `PetZonePersistence` is false - currently pets poof when logging back
- possible solution is to reference the DB `character_data` for zoneid prior to overwriting this data when logging in
- unsure the order in which the data is currently read and then overwritten
My implied question:
Code:
- issue remains on logging out and keeping pet for 30 min if `PetZonePersistence` is false
- currently pets poof when logging back
- possible solution is to reference the DB `character_data` for zoneid prior to overwriting this data when logging in
- unsure the order in which the data is currently read and then overwritten
The other issue is the running of the above queries and deleting of DB rows each time a player zones. I'd like to make this a little more efficient, if possible. (such as skipping the query if certain values don't exist, which requires another query ofc but, I seek efficiency)
I am open to suggestions.
Thanks