View Single Post
  #7  
Old 11-02-2012, 06:13 PM
Uleat's Avatar
Uleat
Developer
 
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
Default Reference Post for ResyncInventory()

Code:
Slot Criteria for ResyncInventory(): (Translated to EQEmulator Titanium-based Definitions - Current as of post revision)
(These values were tested with a SoF client on a Windows 32-bit 'ReleaseBots' build -U)

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|SLOT GROUP:		|SLOT RANGE:		|UPDATE METHOD:	|DELETE METHOD:	|(NOTES:)														     |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|PERSONAL		|0 - 21 (& 9999)	|REG			|REG			|(U:REG & D:REG work properly, including 9999 for SoF+ clients)						     |
|CURSOR			|30			|REG			|REG			|(U:REG & D:REG work properly)										     |
|INVENTORY		|22 - 29		|REG			|REG			|(U:REG & D:REG work properly)										     |
|INVENTORY BAG		|251 - 330		|REG			|ALT			|(U:REG & D:REG work properly)										     |
|CURSOR BAG		|331 - 340		|REG			|ALT			|(U:REG & D:REG work properly)										     |
|TRIBUTE		|400 - 404		|UNK			|UNK			|(unverified if U:REG works properly, D:REG crashes client)						     |
|BANK			|2000 - 2015 (2023)	|REG			|HCK			|(U:REG works properly, D:REG crashes client, D:HCK allows deletion with spam, through 2023 for SoF+ clients)|
|BANK BAG		|2031 - 2190 (2270)	|REG			|ALT			|(U:REG works properly, D:REG crashes client, D:HCK allows deletion with spam, through 2270 for SoF+ clients)|
|SHARED BANK		|2500 - 2501		|REG			|UNK			|(U:REG works properly, D:REG crashes client, D:HCK not effective)					     |
|SHARED BANK BAG	|2531 - 2550		|REG			|ALT			|(U:REG works properly, D:REG crashes client, D:HCK not effective)					     |
|TRADER			|3000 - 3007		|UNK			|UNK			|(need testing results)											     |
|TRADER BAG		|3100 - 3179		|UNK			|UNK			|(need testing results)											     |
|WORLD CONTAINER	|4000 - 4009		|UNK			|UNK			|(need testing results)											     |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

UPDATE METHOD DEFINITIONS:
	Regular(REG):	{ const ItemInst* slot_inst = m_inv[slot_id];
			  SendItemPacket(slot_id, slot_inst, ItemPacketTrade); }

	Alternate(ALT):	No satisfactory method has been found.

	Unknown(UNK):	Is an untested process, results cannot be verified, or client does not update screen item

DELETE METHOD DEFINITIONS:
	Regular(REG):	{ const Item_Struct* token_item = database.GetItem(22292);		// any non-lore item 'should' work..this one is tested
			  ItemInst* token_inst = database.CreateItem(token_item, 1);
					  
			  SendItemPacket(slot_id, token_inst, ItemPacketTrade);			// to eliminate empty slot spam, trade something to it first

			  EQApplicationPacket* outapp		= new EQApplicationPacket(OP_DeleteItem, sizeof(DeleteItem_Struct));
			  DeleteItem_Struct* delete_slot	= (DeleteItem_Struct*)outapp->pBuffer;
			  delete_slot->from_slot			= slot_id;
			  delete_slot->to_slot				= 0xFFFFFFFF;
			  delete_slot->number_in_stack		= 0xFFFFFFFF;
					  
			  QueuePacket(outapp);
			  safe_delete(outapp); }	
	
	Alternate(ALT):	Alternate method for addressing ALL non-broken bag slots appears to be best method for updating bags..When parent slot is
			overwritten with non-container, client will automatically update contents. Then, a simple re-send of parent and occupied
			slots will correct the de-sync.
	
	Hack(HCK):	(This is a hack method to trick the client into doing what we can't make it do normally.)
					
			{ const Item_Struct* token_item = database.GetItem(1041);		// any lore item 'should' work..this one is tested
			  ItemInst* token_inst = database.CreateItem(token_item, 1);
					  
			  SendItemPacket(slot_id, token_inst, ItemPacketTrade);			// must be ItemPacketTrade
			  (send to every bank and bank bag slot that is empty)
					  
			  SendItemPacket(SLOT_CURSOR, token_inst, ItemPacketTrade);		// with the last on cursor, client deletes and spams all others
			  (now use REG method above to delete the cursor) }
					
	Unknown(UNK):	Is an untested process, results cannot be verified, or client does not update screen item.


DESCRIPTION:
	The purpose of this method is to correct as many client-server desyncronizations in-game as possible. It should eliminate the need for item
	deletions due to desync's, and Kick()'s can be disabled when a player performs an action that is known to cause this condition, unless an
	automatic banning process is in effect.

	Whenever a MoveItem request is received, it is processed by Client::SwapItem(). When this action fails, the ResyncInventory() method is
	called. It can also be called manually by the use of #resyncinv (a self-only command) if a player suspects an issue.

	Currently, this method cannot correct every case of a desyncronization. Some ranges are also not addressable due to the way the client handles
	certain slots. The Delete: HCK method above is a work-around to provide some solution, though it comes with undesired side-effects. This method
	is coded to try to minimize these side-effects. (3rd-party software users may not receive the resync's full benefits.)

	The workload is spread across multiple callbacks. This keeps the client active while the resync is updating and helps to eliminate errors due
	to client overload. It also allows subsequent triggers to activate properly by interrupting the current process instead of just buffering the
	request and performing an entire new cycle. The number of concurrent calls is limited to three at the moment. Once a fourth request is issued,
	the process is stopped and the client is kicked to resolve the issue.

	Due to reasons unknown, the bank slots cannot be directly deleted. The hack method employed does not correct shared bank slots due to the fact
	that they allow duplicate lore items. When trying to use the normal delete method on these slots, the client responds by crashing..an undesired
	effect. Changing pBuffer->number_in_stack to a 16-bit -1 (0xFFFF) alleviates the client crash, but serves no purpose as the action still does
	not process correctly. Using OP_MoveItem also crashes the client on these slots regardless of value. It's possible that the client can just no
	longer handle this request. (I've tested all 16-bit values of number_in_stack in these to_slot ranges: 0xFFF0 - 0x0004, 0x7FFC - 0x8003)

	When updating the bank slots, a lore item is sent to each empty one, and then to the cursor. This triggers an action in the client to delete all
	duplicate lore items. This will clear only the bank slots and any empty slots in the corresponding bags. The alternate method that I discovered
	and implemented recently, is actually more efficient as it corrects ALL bag contents without the additional deletion process. Only the parent
	bank or shared banks slots remain an issue. IF any of these slots are unoccupied, the client will still receive a 'deleting lore item from bank'
	message around the 85% mark. This is far less than the previous way, which would send them for not only bank and shared bank slots, but also for
	all empty bank and shared bank bag slots. These messages can be minimized/eliminated by ensuring that all bank/shared bank slots are occupied.

	Until all of the bugs can be tracked down and fixed, zoning or re-logging are the only 100% ways to assure server-client syncronization. This
	method only serves as an intermediate solution.


TODO:
	1) Find and/or verify all client limits (SoF: 1 active, 36-depth list (37 total); server cursor depths: {0..36} )
	2) Adjust 'delay_modifier' before 'ri_CallBackDelay' in incremental steps. The whole process probably needs tweaking for 'live' servers
	   (If you get 'CLIENT MOVE ITEM FAIL' errors, adjust the 'delay_modifier' up and retest. Continue to do this until client messages disappear)
	3) Consider making 'delay_modifier' into rule, but only if it needs to be tweaked frequently
__________________
Uleat of Bertoxxulous

Compilin' Dirty
Reply With Quote