View Single Post
  #34  
Old 09-29-2015, 02:52 AM
AdrianD
Discordant
 
Join Date: Dec 2013
Posts: 297
Default

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
Reply With Quote