|  |  | 
 
  |  |  |  |  
  |  |  |  |  
  |  |  |  |  
  |  |  |  |  
  |  | 
	
		
   
   
      | Support::Windows Servers Support forum for Windows EQEMu users. |  
	
	
		
	
	
 
  |  |  |  |  
	| 
			
			 
			
				09-30-2015, 07:51 PM
			
			
			
		 |  
	| 
		
			
			| Discordant |  | 
					Join Date: Dec 2013 
						Posts: 297
					      |  |  
	| 
				  
 I reverted the bit in \client_process.cpp. 
I could use a bit of assistance with something most would consider basic.
 
I need to insert something that checks the no rent code.
 
This is as far as I got:
 
	Code: 	if (RuleB(Pets, PetLogPersistence) == false)
	{
		SetPet(0);
	}
		
	else (RuleB(Pets, PetLogPersistence) == true);
	{
		database.LoadPetInfo(this);
		/*
		This was moved before the spawn packets are sent
		in hopes that it adds more consistency...
		Remake pet
		*/
		if (m_petinfo.SpellID > 1 && !GetPet() && m_petinfo.SpellID <= SPDAT_RECORDS) {
			MakePoweredPet(m_petinfo.SpellID, spells[m_petinfo.SpellID].teleport_zone, m_petinfo.petpower, m_petinfo.Name, m_petinfo.size);
		if (GetPet() && GetPet()->IsNPC()) {
			NPC *pet = GetPet()->CastToNPC();
			pet->SetPetState(m_petinfo.Buffs, m_petinfo.Items);
			pet->CalcBonuses();
			pet->SetHP(m_petinfo.HP);
			pet->SetMana(m_petinfo.Mana);
			}
		m_petinfo.SpellID = 0;
		}
	} This is some of the no rent code:
 
	Code: void Client::RemoveNoRent(bool client_update)
bool deletenorent = database.NoRentExpired(GetName());
	if (deletenorent) { //client was offline for more than 30 minutes, delete no rent items
		if (RuleB(Inventory, TransformSummonedBags))
			DisenchantSummonedBags(false);
		RemoveNoRent(false);
	} More than hints please.
 
Thanks
			
			
			
			
				  |  
 
  |  |  |  |  
	
		
	
	
	| 
			
			 
			
				09-30-2015, 08:00 PM
			
			
			
		 |  
	| 
		
			|  | Developer |  | 
					Join Date: Apr 2012 Location: North Carolina 
						Posts: 2,815
					      |  |  
	| 
 I'm not seeing the end goal clearly defined...
 You're wanting to check a client's norent items inside of a load pets function?
 
				__________________Uleat of Bertoxxulous
 
 Compilin' Dirty
 |  
	
		
	
	
	| 
			
			 
			
				09-30-2015, 08:06 PM
			
			
			
		 |  
	| 
		
			
			| Dragon |  | 
					Join Date: Apr 2009 Location: California 
						Posts: 814
					      |  |  
	| 
 Looks like he's wanting pets to poof like No Rent items. By the code snippet above, it looks like the best thing would be to move the "if PetLogPersistance==false { SetPet(0); }" bit to just after the "RemoveNoRent(false);" line within the "if (deletenorent) { }" block. |  
	
		
	
	
	| 
			
			 
			
				09-30-2015, 08:26 PM
			
			
			
		 |  
	| 
		
			
			| Discordant |  | 
					Join Date: Dec 2013 
						Posts: 297
					      |  |  
	| 
 Thanks for the replies. 
	Quote: 
	
		| it looks like the best thing would be to move the "if PetLogPersistance==false { SetPet(0); }" bit to just after the "RemoveNoRent(false);" line within the "if (deletenorent) { }" block. |  Ah, I was thinking of going back to that. Thank you.
 
There are some basic understandings I am missing. Hopefully I'll get it soon and more will open up. |  
	
		
	
	
 
  |  |  |  |  
	| 
			
			 
			
				09-30-2015, 08:55 PM
			
			
			
		 |  
	| 
		
			
			| Discordant |  | 
					Join Date: Dec 2013 
						Posts: 297
					      |  |  
	| 
				  
 Ok. 
I added a rule check <\zone\client_packet.cpp(1677)>
 
	Code: 	if (RuleB(Pets, PetLogPersistence) == true)
	{
		database.LoadPetInfo(this);
		/*
		This was moved before the spawn packets are sent
		in hopes that it adds more consistency...
		Remake pet
		*/
		if (m_petinfo.SpellID > 1 && !GetPet() && m_petinfo.SpellID <= SPDAT_RECORDS) {
			MakePoweredPet(m_petinfo.SpellID, spells[m_petinfo.SpellID].teleport_zone, m_petinfo.petpower, m_petinfo.Name, m_petinfo.size);
			if (GetPet() && GetPet()->IsNPC()) {
				NPC *pet = GetPet()->CastToNPC();
				pet->SetPetState(m_petinfo.Buffs, m_petinfo.Items);
				pet->CalcBonuses();
				pet->SetHP(m_petinfo.HP);
				pet->SetMana(m_petinfo.Mana);
			}
			m_petinfo.SpellID = 0;
		}
	} ...and reverted this section <\zone\client_process.cpp(844)>
 
	Code: 	bool deletenorent = database.NoRentExpired(GetName());
	if (deletenorent) { //client was offline for more than 30 minutes, delete no rent items
		if (RuleB(Inventory, TransformSummonedBags))
			DisenchantSummonedBags(false);
		RemoveNoRent(false);
// added 9/30/15 no rent check (this may need fixing when introducing suspended minion)
	if (RuleB(Pets, PetLogPersistence) == false)
		{
			SetPet(0);
		}
	} 
As far as client crash from previous, I am uncertain what was causing it but, the wireless connection it had previous was not good. Getting to login server was difficult. I fixed that and logged a character with a pet (+30 minutes). I did not see the pet window but the pet was still an entry in the DB, like previous.
 
I will review what you said about this Uleat.
 
Thanks
 
EDIT: something isn't right with the norent check - I'll check back but, I've had enough for now
			
			
			
			
				  |  
 
  |  |  |  |  
	
		
	
	
 
  |  |  |  |  
	| 
			
			 
			
				09-30-2015, 10:11 PM
			
			
			
		 |  
	| 
		
			|  | Developer |  | 
					Join Date: Apr 2012 Location: North Carolina 
						Posts: 2,815
					      |  |  
	| 
 SetPet() is an inherited function from the class Mob: https://github.com/EQEmu/Server/blob.../pets.cpp#L542 
SetPet(0), when called from the Client class, is essentially doing this:
 
	Code: ((Mob*)client_inst)->SetPet(nullptr); There are no Client class-based methods performed at this level and all that is occurring is that you're setting the memory reference for the client's pet to nullptr.
 
This is ok for other mob-derived classes that don't save their pet buffs, inventories, etc... (they still clean-up as required, though)
 
But, for client, you should to handle it somewhere at the Client class level..meaning database clean-up, and deletion of any possible pet instances from memory..otherwise, 
you will end up with a memory leak (allocated..but, no longer used memory that is not released back to the system - the losses add up)
 
(If you handle the action before creating an actual in-memory reference, then you won't need to worry about the clean-up.)
				__________________Uleat of Bertoxxulous
 
 Compilin' Dirty
 |  
 
  |  |  |  |  
	
		
	
	
	| 
			
			 
			
				10-01-2015, 02:27 AM
			
			
			
		 |  
	| 
		
			
			| Discordant |  | 
					Join Date: Dec 2013 
						Posts: 297
					      |  |  
	| 
 I appreciate the explanations. I wouldn't have known if you didn't say anything about it.  I will digest this in the coming days and try to apply this if I can. |  
	
		
	
	
 
  |  |  |  |  
	| 
			
			 
			
				10-01-2015, 05:25 PM
			
			
			
		 |  
	| 
		
			
			| Discordant |  | 
					Join Date: Dec 2013 
						Posts: 297
					      |  |  
	| 
				  
 I reverted everything that was working with PetLogPersistence. The issue previous was simple and something I overlooked as I quickly wrote it in as I was out the door. 
I went back to \zone\client_process.cpp and added queries to the code.
 
The results are a little better. The entries are deleted until zoning or casting a new pet when new ones are made. I attempted to add database.SavePetInfo(this); <void ZoneDatabase::SavePetInfo(Client *client)> but the result wasn't desireable. (because of <PetInfo *petinfo = nullptr;> happening first maybe?)
 
The pet window still appears for a short time and the pet=0 entries are non-existent for the char logged 30+ minutes after initial login. (/q resets the entries - unsure if this = LD)
 
	Code: 	bool deletenorent = database.NoRentExpired(GetName());
	if (deletenorent) { //client was offline for more than 30 minutes, delete no rent items
		if (RuleB(Inventory, TransformSummonedBags))
			DisenchantSummonedBags(false);
		RemoveNoRent(false);
// added 9/30/15 no rent check (this may need fixing when introducing suspended minion - if this was an issue the queries below should fix it)
		if (!RuleB(Pets, PetLogPersistence))
		{
			SetPet(0);
			
			std::string query = StringFormat("DELETE FROM `character_pet_info` WHERE `char_id` = %u AND character_pet_info.pet = 0", CharacterID());
			auto results = database.QueryDatabase(query);
			
			query = StringFormat("DELETE FROM `character_pet_buffs` WHERE `char_id` = %u AND character_pet_info.pet = 0", CharacterID());
			results = database.QueryDatabase(query);
			
			query = StringFormat("DELETE FROM `character_pet_inventory` WHERE `char_id` = %u AND character_pet_info.pet = 0", CharacterID());
			results = database.QueryDatabase(query);						
		}
	} 
If I knew how to set these queries up in zonedb.cpp and make the connections to it from client_process, I would have. This really isn't that difficult, the concept, the web of connections. It's the syntax or C++ grammar that is the pain in the ass, the huge hindrance for me. I can figure out how the EQEmu system works just by exposure and asking questions where the answer is fairly simple, as has been mentioned.
 
Thanks
			
			
			
			
				  |  
 
  |  |  |  |  
	
		
	
	
	| 
			
			 
			
				10-01-2015, 06:49 PM
			
			
			
		 |  
	| 
		
			|  | Developer |  | 
					Join Date: Apr 2012 Location: North Carolina 
						Posts: 2,815
					      |  |  
	| 
 I wanted to see if there was an existing method to 'delete' pets from clients..but, the only one I found only deleted the inventories and buffs..so, I'm not sure where thatis handled...
 
 (I mean, when a pet dies, it is deleted, right? Otherwise, it would respawn when a client enters the world.)
 
				__________________Uleat of Bertoxxulous
 
 Compilin' Dirty
 |  
	
		
	
	
	| 
			
			 
			
				10-01-2015, 07:11 PM
			
			
			
		 |  
	| 
		
			
			| Dragon |  | 
					Join Date: Apr 2009 Location: California 
						Posts: 814
					      |  |  
	| 
 Is there just a Pet->Death()? lol |  
	
		
	
	
	| 
			
			 
			
				10-01-2015, 07:37 PM
			
			
			
		 |  
	| 
		
			|  | Developer |  | 
					Join Date: Apr 2012 Location: North Carolina 
						Posts: 2,815
					      |  |  
	| 
 Well, I followed case GETLOST: back, and SavePetInfo() .. nothing I saw removed the actual pet instance.
 I dunno? :P
 
 
 I know I'm missing something...
 
				__________________Uleat of Bertoxxulous
 
 Compilin' Dirty
 |  
	
		
	
	
	| 
			
			 
			
				10-01-2015, 07:43 PM
			
			
			
		 |  
	| 
		
			
			| Discordant |  | 
					Join Date: Dec 2013 
						Posts: 297
					      |  |  
	| 
 There is a depop in \spawn2.h and \spawn2.cpp: 
	Code: void	Depop();
void Spawn2::Depop() {
	timer.Disable();
	Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn reset, repop disabled", spawn2_id);
	npcthis = nullptr;
} I saw this while sifting through potential options.
 
There is different depop for zone. |  
	
		
	
	
 
  |  |  |  |  
	| 
			
			 
			
				10-01-2015, 08:55 PM
			
			
			
		 |  
	| 
		
			
			| Discordant |  | 
					Join Date: Dec 2013 
						Posts: 297
					      |  |  
	| 
				  
 A bit of progress, not much though. 
No entry being created like it does when zoning and using <SetPet(0);>
 
\zonedb.cpp - last 1/2 commented out, unsure what to do to make it create a new blank entry
 
When the part /* */ is uncommented it only removes `spell_id` in the DB - pet_struct maybe?
 
	Code: void ZoneDatabase::DeletePetInfo(Client *client)
{
	std::string query = StringFormat("DELETE FROM `character_pet_info` WHERE `char_id` = %u AND `pet` = 0", client->CharacterID());
	auto results = database.QueryDatabase(query);
	if (!results.Success())
		return;
	query = StringFormat("DELETE FROM `character_pet_buffs` WHERE `char_id` = %u AND `pet` = 0", client->CharacterID());
	results = database.QueryDatabase(query);
	if (!results.Success())
		return;
	query = StringFormat("DELETE FROM `character_pet_inventory` WHERE `char_id` = %u AND `pet` = 0", client->CharacterID());
	results = database.QueryDatabase(query);
	if (!results.Success())
		return;
//	PetInfo *petinfo = nullptr;
	/*
	for (int pet = 0; pet < 2; pet++) {
	PetInfo	*petinfo = client->GetPetInfo(pet);
		if (!petinfo)
			continue;
		query = StringFormat("INSERT INTO `character_pet_info` "
			"(`char_id`, `pet`, `petname`, `petpower`, `spell_id`, `hp`, `mana`, `size`) "
			"VALUES (%u, %u, '%s', %i, %u, %u, %u, %f) "
			"ON DUPLICATE KEY UPDATE `petname` = '%s', `petpower` = %i, `spell_id` = %u, "
			"`hp` = %u, `mana` = %u, `size` = %f",
			client->CharacterID(), pet, petinfo->Name, petinfo->petpower, petinfo->SpellID,
			petinfo->HP, petinfo->Mana, petinfo->size, // and now the ON DUPLICATE ENTRIES
			petinfo->Name, petinfo->petpower, petinfo->SpellID, petinfo->HP, petinfo->Mana, petinfo->size);
		results = database.QueryDatabase(query);
		if (!results.Success())
			return;
		query.clear();
		}	*/
} \client_process.cpp
 
	Code: bool deletenorent = database.NoRentExpired(GetName());
	if (deletenorent) { //client was offline for more than 30 minutes, delete no rent items
		if (RuleB(Inventory, TransformSummonedBags))
			DisenchantSummonedBags(false);
		RemoveNoRent(false);
// added 9/30/15 no rent check (this may need fixing when introducing suspended minion - if this was an issue the queries below should fix it)
		if (!RuleB(Pets, PetLogPersistence))
		{				
			SetPet(0);
			
			database.DeletePetInfo(this);			
		}
	} Thanks
			
			
			
			
				  |  
 
  |  |  |  |  
	
		
	
	
	| 
			
			 
			
				10-02-2015, 12:42 AM
			
			
			
		 |  
	| 
		
			
			| Discordant |  | 
					Join Date: Dec 2013 
						Posts: 297
					      |  |  
	| 
 Added to \client_process.cpp - it's a little smoother, adds the blank row and saves it. The client still shows the pet window momentarily. I would prefer to put <memset(&m_petinfo, 0, sizeof(struct PetInfo));> in the DeletePetInfo part and then run w/e queries are needed to fill in the blanks allowing the removal of <database.SavePetInfo(this);> below. 
I would prefer this whole process done a little earlier. Just a guess but, somewhere near <case ServerOP_SyncWorldTime:> (\zone\worldserver.cpp(744).
 
This also leaves out what Uleat said before about memory loss? which I have no clue about.
 
\client_process.cpp(841)
 
	Code: // added 9/30/15 no rent check (this may need fixing when introducing suspended minion - if this was an issue the queries below should fix it)
		if (!RuleB(Pets, PetLogPersistence))
		{
			SetPet(0);
			database.DeletePetInfo(this);
			memset(&m_petinfo, 0, sizeof(struct PetInfo));
			
			database.SavePetInfo(this);
		}
	} |  
	
		
	
	
	| 
			
			 
			
				10-02-2015, 03:06 AM
			
			
			
		 |  
	| 
		
			
			| Discordant |  | 
					Join Date: Dec 2013 
						Posts: 297
					      |  |  
	| 
 Last one for a bit: 
The two lines below SetPet, <Mob* mypet =......etc.>, gives the same resulting appearance as <SetPet(0);>. (takes a moment to depop) I am unsure if one is better than the other.
 
\client_process.cpp(841)
 
	Code: 		if (!RuleB(Pets, PetLogPersistence))
		{
			SetPet(0);
//                     or
			Mob* mypet = this->GetPet();
			mypet->CastToNPC()->Depop();
			database.DeletePetInfo(this);
			memset(&m_petinfo, 0, sizeof(struct PetInfo));
			
			database.SavePetInfo(this);
		}
	} |  
	
		
	
	
	
	
	| 
	|  Posting Rules |  
	| 
		
		You may not post new threads You may not post replies You may not post attachments You may not edit your posts 
 HTML code is Off 
 |  |  |  All times are GMT -4. The time now is 12:21 PM.
 
 |  |  
    |  |  |  |  
    |  |  |  |  
     |  |  |  |  
 |  |