Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Server Code Submissions

Reply
 
Thread Tools Display Modes
  #1  
Old 01-02-2011, 06:16 PM
l0stmancd
Fire Beetle
 
Join Date: Apr 2005
Posts: 23
Default

Hi Trevius,

I see what you mean by the bagtype change. Just started working on it here. Changing the bagtype to 53 has given a lot of things by default but there still needs to be a code change. Looking into this now.

Thanks!
Reply With Quote
  #2  
Old 01-02-2011, 08:20 PM
l0stmancd
Fire Beetle
 
Join Date: Apr 2005
Posts: 23
Default

This is actually a pretty clean change. Still working through it but I think the only really odd part is in the slot numbering. The client is sending slots for the "container" that appear to be shifted. IE: Sending slot 30 for container slot 8 in inventory (29). Consistent in SoD inventory, havent tested bank yet...

Will see if we are handling this in a consistent way in the code already...
Reply With Quote
  #3  
Old 01-03-2011, 03:38 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

It is normal for all SoF+ clients to send shifted slot IDs for all slots over slot 21, since Power Source replaced the Titanium Ammo slot and bumped them all up by 1. This is all handled directly in the <patch>.cpp files near the top such as in this file for SoD:

http://code.google.com/p/projecteqem...atches/SoD.cpp

I made slot converting functions that adjusts Titanium slots to later clients slots and visa versa.

So, even though you see it sending slot 30 (cursor slot in Titanium), when it is in slot 29, it is actually converted back to slot 29 before it is actually handled in any way.

If something is making it into the handling without being converted, it is most likely due to us missing an encode/decode in that .cpp file for that particular packet type. It is pretty easy to add encodes/decodes if needed, we just need to know which packet it is that isn't in there already.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #4  
Old 01-03-2011, 04:06 AM
l0stmancd
Fire Beetle
 
Join Date: Apr 2005
Posts: 23
Default

Hey folks,

Rewrote the code submission based on Trevius's recommendation. Turns out it was a fairly simple change with a -lot- less code than before.

The only "interesting" part of it was that I had to add decode functions to the expansion patch files to allow us to shift the slot numbers to the titanium slot numbers. This is done following the same logic as the tradeskill decode functions for the same reason. As I mentioned above, the slot numbers were incorrect between Titanium and SoD due to them using different slightly different slot numbers.

Tested this with ItemID 66180 and also a custom container I created for it - works fine.

Tests ran:
1. Validated that I could still augment slots without issue in aug pool.
2. Validated that I could still remove augments without issue in aug pool.
3. Validated that I could still delete augments without issue in aug pool..
4. Validated that I could agument slots with bags of type 53.
5. Validated that I could remove augments with bags of type 53 (and select which one to remove).
6. Validate that I could delete augments with bags of type 53 (and select which one to remove).
7. Validated that after a successful augmentation, deaugmentation, or augment deletion that the items in your tradeskill container are wiped and the new items are still pushed onto your cursor.
8. Validated all of the above on both Titanium and SoD clients.
9. Validated that items are not lost on zone crash.

You can use the following item ids to test this: 69312, 60332, 47013, 66180

No new logic was added - for the most part this is using the exact same logic that the augmentation pool is using.

Hah - just noticed you responded to my statement - yeah, was testing other things before posting it. Thanks man...

Code:
Index: common/patches/HoT.cpp
===================================================================
--- common/patches/HoT.cpp	(revision 1798)
+++ common/patches/HoT.cpp	(working copy)
@@ -3105,6 +3105,16 @@
 	FINISH_DIRECT_DECODE();
 }
 
+DECODE(OP_AugmentItem) {
+	DECODE_LENGTH_EXACT(structs::AugmentItem_Struct);
+	SETUP_DIRECT_DECODE(AugmentItem_Struct, structs::AugmentItem_Struct);
+
+	emu->container_slot = HoTToTitaniumSlot(eq->container_slot);
+	emu->augment_slot = eq->augment_slot;
+
+	FINISH_DIRECT_DECODE();
+}
+
 DECODE(OP_TradeSkillCombine) {
 	DECODE_LENGTH_EXACT(structs::NewCombine_Struct);
 	SETUP_DIRECT_DECODE(NewCombine_Struct, structs::NewCombine_Struct);
Index: common/patches/HoT_ops.h
===================================================================
--- common/patches/HoT_ops.h	(revision 1798)
+++ common/patches/HoT_ops.h	(working copy)
@@ -114,5 +114,6 @@
 D(OP_ChannelMessage)
 D(OP_DeleteItem)
 D(OP_ZoneChange)
+D(OP_AugmentItem)
 #undef E
 #undef D
Index: common/patches/SoD.cpp
===================================================================
--- common/patches/SoD.cpp	(revision 1798)
+++ common/patches/SoD.cpp	(working copy)
@@ -2771,6 +2771,16 @@
 	FINISH_DIRECT_DECODE();
 }
 
+DECODE(OP_AugmentItem) {
+	DECODE_LENGTH_EXACT(structs::AugmentItem_Struct);
+	SETUP_DIRECT_DECODE(AugmentItem_Struct, structs::AugmentItem_Struct);
+
+	emu->container_slot = SoDToTitaniumSlot(eq->container_slot);
+	emu->augment_slot = eq->augment_slot;
+
+	FINISH_DIRECT_DECODE();
+}
+
 DECODE(OP_TradeSkillCombine) {
 	DECODE_LENGTH_EXACT(structs::NewCombine_Struct);
 	SETUP_DIRECT_DECODE(NewCombine_Struct, structs::NewCombine_Struct);
Index: common/patches/SoD_ops.h
===================================================================
--- common/patches/SoD_ops.h	(revision 1798)
+++ common/patches/SoD_ops.h	(working copy)
@@ -104,5 +104,6 @@
 D(OP_LoadSpellSet)
 D(OP_ApplyPoison)
 D(OP_DeleteItem)
+D(OP_AugmentItem)
 #undef E
 #undef D
Index: common/patches/SoF.cpp
===================================================================
--- common/patches/SoF.cpp	(revision 1798)
+++ common/patches/SoF.cpp	(working copy)
@@ -2269,6 +2269,16 @@
 	FINISH_DIRECT_DECODE();
 }
 
+DECODE(OP_AugmentItem) {
+	DECODE_LENGTH_EXACT(structs::AugmentItem_Struct);
+	SETUP_DIRECT_DECODE(AugmentItem_Struct, structs::AugmentItem_Struct);
+
+	emu->container_slot = SoFToTitaniumSlot(eq->container_slot);
+	emu->augment_slot = eq->augment_slot;
+
+	FINISH_DIRECT_DECODE();
+}
+
 DECODE(OP_TradeSkillCombine) {
 	DECODE_LENGTH_EXACT(structs::NewCombine_Struct);
 	SETUP_DIRECT_DECODE(NewCombine_Struct, structs::NewCombine_Struct);
Index: common/patches/SoF_ops.h
===================================================================
--- common/patches/SoF_ops.h	(revision 1798)
+++ common/patches/SoF_ops.h	(working copy)
@@ -88,5 +88,6 @@
 D(OP_InspectAnswer)
 D(OP_ApplyPoison)
 D(OP_DeleteItem)
+D(OP_AugmentItem)
 #undef E
 #undef D
Index: common/patches/Underfoot.cpp
===================================================================
--- common/patches/Underfoot.cpp	(revision 1798)
+++ common/patches/Underfoot.cpp	(working copy)
@@ -3000,6 +3000,16 @@
 	FINISH_DIRECT_DECODE();
 }
 
+DECODE(OP_AugmentItem) {
+	DECODE_LENGTH_EXACT(structs::AugmentItem_Struct);
+	SETUP_DIRECT_DECODE(AugmentItem_Struct, structs::AugmentItem_Struct);
+
+	emu->container_slot = UnderfootToTitaniumSlot(eq->container_slot);
+	emu->augment_slot = eq->augment_slot;
+
+	FINISH_DIRECT_DECODE();
+}
+
 DECODE(OP_TradeSkillCombine) {
 	DECODE_LENGTH_EXACT(structs::NewCombine_Struct);
 	SETUP_DIRECT_DECODE(NewCombine_Struct, structs::NewCombine_Struct);
Index: common/patches/Underfoot_ops.h
===================================================================
--- common/patches/Underfoot_ops.h	(revision 1798)
+++ common/patches/Underfoot_ops.h	(working copy)
@@ -113,5 +113,6 @@
 D(OP_ChannelMessage)
 D(OP_DeleteItem)
 D(OP_PetCommands)
+D(OP_AugmentItem)
 #undef E
 #undef D
Index: zone/tradeskills.cpp
===================================================================
--- zone/tradeskills.cpp	(revision 1798)
+++ zone/tradeskills.cpp	(working copy)
@@ -45,16 +45,48 @@
 		LogFile->write(EQEMuLog::Error, "Client or AugmentItem_Struct not set in Object::HandleAugmentation");
 		return;
 	}
+	
+	ItemInst* container = NULL;
 
-	if(!worldo)
-	{
+	if (worldo) {
+		container = worldo->m_inst;
+	} 
+	else {
+		// Check to see if they have an inventory container type 53 that is used for this.
+		Inventory& user_inv = user->GetInv();
+		ItemInst* inst = NULL;
+		
+		inst = user_inv.GetItem(in_augment->container_slot);
+		if (inst) {
+			const Item_Struct* item = inst->GetItem();
+			if (item && inst->IsType(ItemClassContainer) && item->BagType == 53) {
+				// We have found an appropriate inventory augmentation sealer
+				container = inst;
+
+				// Verify that no more than two items are in container to guarantee no inadvertant wipes.
+				uint8 itemsFound = 0;
+				for (uint8 i=0; i<10; i++){
+					const ItemInst* inst = container->GetItem(i);
+					if (inst) {
+						itemsFound++;
+					}
+				}
+
+				if (itemsFound != 2) {
+					user->Message(13, "Error:  Too many/few items in augmentation container.");
+					return;
+				}
+			}
+		}
+	}
+
+	if(!container) {
 		LogFile->write(EQEMuLog::Error, "Player tried to augment an item without a world object set.");
 		return;
 	}
 	
 	ItemInst *tobe_auged, *auged_with = NULL;
 	sint8 slot=-1;
-	ItemInst* container = worldo->m_inst;
 
 	if (!container) {
 		user->Message(13, "Error: This item is not a container!");
@@ -78,18 +110,14 @@
 		}
 	}
 
+	bool deleteItems = false;
+
 	// Adding augment
 	if (in_augment->augment_slot == -1) {
 		if (((slot=tobe_auged->AvailableAugmentSlot(auged_with->GetAugmentType()))!=-1) && (tobe_auged->AvailableWearSlot(auged_with->GetItem()->Slots))) {
 			tobe_auged->PutAugment(slot,*auged_with);
 			user->PushItemOnCursor(*tobe_auged,true);
-			container->Clear();
-			EQApplicationPacket* outapp = new EQApplicationPacket(OP_ClearObject, sizeof(ClearObject_Struct));
-			ClearObject_Struct *cos = (ClearObject_Struct *)outapp->pBuffer;
-			cos->Clear = 1;
-			user->QueuePacket(outapp);
-			safe_delete(outapp);
-			database.DeleteWorldContainer(worldo->m_id, zone->GetZoneID());
+			deleteItems = true;
 		} else {
 			user->Message(13, "Error: No available slot for augment");
 		}
@@ -104,14 +132,31 @@
 		user->PushItemOnCursor(*tobe_auged,true);
 		if (old_aug)
 			user->PushItemOnCursor(*old_aug,true);
-		container->Clear();
-		EQApplicationPacket* outapp = new EQApplicationPacket(OP_ClearObject, sizeof(ClearObject_Struct));
-		ClearObject_Struct *cos = (ClearObject_Struct *)outapp->pBuffer;
-		cos->Clear = 1;
-		user->QueuePacket(outapp);
-		safe_delete(outapp);
-		database.DeleteWorldContainer(worldo->m_id, zone->GetZoneID());
+		deleteItems = true;
 	}
+
+	if (deleteItems) {
+		if (worldo) {
+			container->Clear();
+			EQApplicationPacket* outapp = new EQApplicationPacket(OP_ClearObject, sizeof(ClearObject_Struct));
+			ClearObject_Struct *cos = (ClearObject_Struct *)outapp->pBuffer;
+			cos->Clear = 1;
+			user->QueuePacket(outapp);
+			safe_delete(outapp);
+			database.DeleteWorldContainer(worldo->m_id, zone->GetZoneID());
+		}
+		else {
+			// Delete items in our inventory container... 
+			for (uint8 i=0; i<10; i++){
+				const ItemInst* inst = container->GetItem(i);
+				if (inst) {
+					user->DeleteItemInInventory(Inventory::CalcSlotId(in_augment->container_slot,i),0,true);
+				}
+			}
+			// Explicitly mark container as cleared.
+			container->Clear();
+		}
+	}
 }
 
 // Perform tradeskill combine
Reply With Quote
  #5  
Old 01-03-2011, 05:01 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Excellent work! That looks much better to me

Unless anyone sees issues with this last submission, I will get it committed as soon as I have a chance.

I will be making use of it right away as well, so it should get some good testing fairly quickly. Currently, I have a custom collapsible aug pool item that I have cast a spell and spawn an aug pool on the spot. It works well enough, but is a bit of a pain since it requires code in all zones player.pl to make sure the aug pool gets removed when the zone is emptied. It also causes aug pools to become permanent in zones that crash or if the server is shut down with one in a zone. Your new aug container will be a MUCH better permanent solution. Not only does it mean portable augmenting, but means 100% (or close) safe aug combines without item loss.

Sorry I had to give you so much hassle with the original code submission, but I think it resulted in a great solution in the end
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #6  
Old 01-03-2011, 06:19 AM
Akkadius's Avatar
Akkadius
Administrator
 
Join Date: Feb 2009
Location: MN
Posts: 2,072
Default

Quote:
Originally Posted by trevius View Post
Excellent work! That looks much better to me

Unless anyone sees issues with this last submission, I will get it committed as soon as I have a chance.

I will be making use of it right away as well, so it should get some good testing fairly quickly. Currently, I have a custom collapsible aug pool item that I have cast a spell and spawn an aug pool on the spot. It works well enough, but is a bit of a pain since it requires code in all zones player.pl to make sure the aug pool gets removed when the zone is emptied. It also causes aug pools to become permanent in zones that crash or if the server is shut down with one in a zone. Your new aug container will be a MUCH better permanent solution. Not only does it mean portable augmenting, but means 100% (or close) safe aug combines without item loss.

Sorry I had to give you so much hassle with the original code submission, but I think it resulted in a great solution in the end
Why don't you have all of your player.pl's reference a plugin/sub routine for each player.pl subroutine so you don't have to go back through all of those files to make any global changes like that again.
Reply With Quote
  #7  
Old 01-03-2011, 09:36 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Quote:
Originally Posted by Akkadius View Post
Why don't you have all of your player.pl's reference a plugin/sub routine for each player.pl subroutine so you don't have to go back through all of those files to make any global changes like that again.
Not to derail the thread too much, but:

Yeah, that would be a decent solution for that type of thing. I could have done that easy enough with plugins or using require(). I just don't like the idea of having to have special player.pl stuff global in every zone. If something needs to be global like that, I normally try to find a better solution for it. In the case of the custom aug pool stuff I made, I only added it to a few key zones as a temporary solution until I had a better one. If something has to go in every zone's player.pl, that would mean I would really need to do it in every single current and future zone in the quests folder. I am sure I could get away with just doing it for our own custom zones, but again, I don't want to have to manage all player.pls like that in any way. There is always another solution!

Anyway, I am hoping to get this running on Storm Haven today and will leave it in for testing so it can be committed maybe tonight.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #8  
Old 01-03-2011, 01:13 PM
l0stmancd
Fire Beetle
 
Join Date: Apr 2005
Posts: 23
Default

Quote:
Originally Posted by trevius View Post
Sorry I had to give you so much hassle with the original code submission, but I think it resulted in a great solution in the end
Don't worry about it in the slightest. You took the time to review, found a few issues, and suggested a better way that works perfectly.

Appreciate the help Trevius.
Reply With Quote
  #9  
Old 01-09-2011, 02:03 PM
l0stmancd
Fire Beetle
 
Join Date: Apr 2005
Posts: 23
Default

Appears to be a small defect here - as we are using the same path as the augmentation container, we are first pushing the item to the client then deleting the item (in the container) from the client.

This can cause issues if you have a lag spike and both updates do not happen almost simultaneously.

Looks like it is limited to just deleting one of the lore items and making the other invisible until the client logs off or zones - an annoyance but does not appear to cause any item deletion. Posting a fix for this now.
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 06:13 PM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3