| 
   | 
   | 
  
 
    | 
    | 
    | 
  
 
    | 
   | 
    | 
  
 
    | 
   | 
    | 
  
 
    | 
   | 
    | 
  
 
   | 
  
	
		
   
   
      | 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 that 
is 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 02:49 AM. 
 
		 
	 
 
 
     | 
     | 
    
   
      | 
     | 
      | 
    
   
     | 
      | 
     | 
    
   
       | 
      | 
       | 
     
    
    
  | 
   |