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

Reply
 
Thread Tools Display Modes
  #1  
Old 05-01-2009, 01:48 PM
realityincarnate
Developer
 
Join Date: Dec 2007
Posts: 122
Default Augment Item Info

This creates the "Item Info" message at the bottom of augments, telling which solvent can be used to remove them. It also (incidentally) enables a couple of other pieces of item info that previously appeared in the Titanium client but not SoF.

Code:
Index: common/emu_oplist.h
===================================================================
--- common/emu_oplist.h	(revision 451)
+++ common/emu_oplist.h	(working copy)
@@ -427,3 +427,4 @@
 N(OP_ItemVerifyReply),
 N(OP_GMTrainSkillConfirm),
 N(OP_RestState),
+N(OP_AugmentInfo),
Index: common/eq_packet_structs.h
===================================================================
--- common/eq_packet_structs.h	(revision 451)
+++ common/eq_packet_structs.h	(working copy)
@@ -2037,8 +2037,8 @@
 // Use ` as a newline character in the text.
 // Variable length.
 struct BookText_Struct {
-	uint8 unknown0; //always 0xFF
-	uint8 type;             //type: 0=scroll, 1=book.. prolly others.
+	uint8 window;	// where to display the text (0xFF means new window)
+	uint8 type;             //type: 0=scroll, 1=book, 2=item info.. prolly others.
 	uint32 invslot;	// Only used in SoF and later clients.
 	char booktext[1]; // Variable Length
 };
@@ -2046,8 +2046,8 @@
 // This is just a "text file" on the server
 // or in our case, the 'name' column in our books table.
 struct BookRequest_Struct {
-	uint8 unknown0; //always 0xFF
-	uint8 type;             //type: 0=scroll, 1=book.. prolly others.
+	uint8 window;	// where to display the text (0xFF means new window)
+	uint8 type;             //type: 0=scroll, 1=book, 2=item info.. prolly others.
 	uint32 invslot;	// Only used in Sof and later clients;
 	char txtfile[20];
 };
@@ -3738,7 +3738,13 @@
 /*007*/ 				// no idea what these last three bytes represent
 };
 
+struct AugmentInfo_Struct {
+/*000*/ uint32	itemid;		// id of the solvent needed
+/*004*/ uint8	window;		// window to display the information in
+// total packet length 72, all the rest were always 00
+};
 
+
 //old structures live here:
 #include "eq_old_structs.h"
 
Index: common/patches/Client62.cpp
===================================================================
--- common/patches/Client62.cpp	(revision 451)
+++ common/patches/Client62.cpp	(working copy)
@@ -629,7 +629,7 @@
 
 	structs::BookText_Struct *eq_BookText_Struct = (structs::BookText_Struct*)in->pBuffer;
 
-	eq_BookText_Struct->unknown0 = emu_BookText_Struct->unknown0;
+	eq_BookText_Struct->window = emu_BookText_Struct->window;
 	eq_BookText_Struct->type = emu_BookText_Struct->type;
 	strcpy(eq_BookText_Struct->booktext, emu_BookText_Struct->booktext);
 
@@ -711,7 +711,7 @@
 	DECODE_LENGTH_ATLEAST(structs::BookRequest_Struct);
 	SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
 
-	IN(unknown0);
+	IN(window);
 	IN(type);
 	strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
 
Index: common/patches/Client62_structs.h
===================================================================
--- common/patches/Client62_structs.h	(revision 451)
+++ common/patches/Client62_structs.h	(working copy)
@@ -1844,16 +1844,16 @@
 // Use ` as a newline character in the text.
 // Variable length.
 struct BookText_Struct {
-	uint8 unknown0; //always 0xFF
-	uint8 type;             //type: 0=scroll, 1=book.. prolly others.
+	uint8 window;	// where to display the text (0xFF means new window)
+	uint8 type;             //type: 0=scroll, 1=book, 2=item info.. prolly others.
 	char booktext[1]; // Variable Length
 };
 // This is the request to read a book.
 // This is just a "text file" on the server
 // or in our case, the 'name' column in our books table.
 struct BookRequest_Struct {
-	uint8 unknown0; //always 0xFF
-	uint8 type;             //type: 0=scroll, 1=book.. prolly others.
+	uint8 window;	// where to display the text (0xFF means new window)
+	uint8 type;             //type: 0=scroll, 1=book, 2=item info.. prolly others.
 	char txtfile[1]; // Variable Length
 };
 
Index: common/patches/SoF.cpp
===================================================================
--- common/patches/SoF.cpp	(revision 451)
+++ common/patches/SoF.cpp	(working copy)
@@ -1513,7 +1512,9 @@
 	ENCODE_LENGTH_ATLEAST(BookText_Struct);
 	SETUP_DIRECT_ENCODE(BookText_Struct, structs::BookRequest_Struct);
 
-	eq->unknown0000 = 0xFFFFFFFF;
+	if (emu->window == 0xFF)
+		eq->window = 0xFFFFFFFF;
+	else eq->window = emu->window;
 	OUT(type);
 	OUT(invslot);
 	strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
@@ -1880,6 +1881,7 @@
 
 	IN(type);
 	IN(invslot);
+	emu->window = (uint8) eq->window;
 	strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
 
 	FINISH_DIRECT_DECODE();
Index: common/patches/SoF_structs.h
===================================================================
--- common/patches/SoF_structs.h	(revision 451)
+++ common/patches/SoF_structs.h	(working copy)
@@ -2163,17 +2163,17 @@
 // The BookRequest_Struct is used instead for both request and reply.
 //
 struct BookText_Struct {
-	uint8 unknown0; //always 0xFF
-	uint8 type;             //type: 0=scroll, 1=book.. prolly others.
+	uint8 window;	// where to display the text (0xFF means new window)
+	uint8 type;             //type: 0=scroll, 1=book, 2=item info.. prolly others.
 	char booktext[1]; // Variable Length - was 1
 };
 // This is the request to read a book.
 // This is just a "text file" on the server
 // or in our case, the 'name' column in our books table.
 struct BookRequest_Struct {
-/*0000*/	uint32 unknown0000;	// always 0xFFFFFFFF
+/*0000*/	uint32 window;		// where to display the text (0xFFFFFFFF means new window)
 /*0004*/	uint32 invslot;		// The inventory slot the book is in. Not used, but echoed in the response packet.
-/*0008*/	uint32 type;		// 0 = Scroll, 1 = Book, Possibly others
+/*0008*/	uint32 type;		// 0 = Scroll, 1 = Book, 2 = Item Info, Possibly others
 /*0012*/	uint32 unknown0012;	
 /*0016*/	uint16 unknown0016;
 /*0018*/	char txtfile[8194];
Index: common/patches/Titanium.cpp
===================================================================
--- common/patches/Titanium.cpp	(revision 451)
+++ common/patches/Titanium.cpp	(working copy)
@@ -800,7 +799,7 @@
 
 	structs::BookText_Struct *eq_BookText_Struct = (structs::BookText_Struct*)in->pBuffer;
 
-	eq_BookText_Struct->unknown0 = emu_BookText_Struct->unknown0;
+	eq_BookText_Struct->window = emu_BookText_Struct->window;
 	eq_BookText_Struct->type = emu_BookText_Struct->type;
 	strcpy(eq_BookText_Struct->booktext, emu_BookText_Struct->booktext);
 
@@ -895,7 +894,7 @@
 	DECODE_LENGTH_ATLEAST(structs::BookRequest_Struct);
 	SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
 
-	IN(unknown0);
+	IN(window);
 	IN(type);
 	strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
 
Index: common/patches/Titanium_structs.h
===================================================================
--- common/patches/Titanium_structs.h	(revision 451)
+++ common/patches/Titanium_structs.h	(working copy)
@@ -1906,16 +1906,16 @@
 // Use ` as a newline character in the text.
 // Variable length.
 struct BookText_Struct {
-	uint8 unknown0; //always 0xFF
-	uint8 type;             //type: 0=scroll, 1=book.. prolly others.
+	uint8 window;	// where to display the text (0xFF means new window)
+	uint8 type;             //type: 0=scroll, 1=book, 2=item info.. prolly others.
 	char booktext[1]; // Variable Length
 };
 // This is the request to read a book.
 // This is just a "text file" on the server
 // or in our case, the 'name' column in our books table.
 struct BookRequest_Struct {
-	uint8 unknown0; //always 0xFF
-	uint8 type;             //type: 0=scroll, 1=book.. prolly others.
+	uint8 window;	// where to display the text (0xFF means new window)
+	uint8 type;             //type: 0=scroll, 1=book, 2=item info.. prolly others.
 	char txtfile[1];	// Variable length
 };
 
Index: utils/patch_SoF.conf
===================================================================
--- utils/patch_SoF.conf	(revision 451)
+++ utils/patch_SoF.conf	(working copy)
@@ -285,6 +285,7 @@
 OP_Sacrifice=0x0x55C9			#
 OP_PopupResponse=0x028B			#
 OP_OnLevelMessage=0x0332		#
+OP_AugmentInfo=0x08f8			#RealityIncarnate 4/28/09
 
 #Looting
 OP_LootRequest=0x36E3			#Trevius 02/16/09
Index: utils/patch_Titanium.conf
===================================================================
--- utils/patch_Titanium.conf	(revision 451)
+++ utils/patch_Titanium.conf	(working copy)
@@ -272,6 +272,7 @@
 OP_Sacrifice=0x727a
 OP_KeyRing=0x68c4
 OP_ApplyPoison=0x0c2c
+OP_AugmentInfo=0x45ff		#RealityIncarnate 4/28/09
 
 #bazaar trader stuff stuff:
 #become and buy from
Index: zone/client.cpp
===================================================================
--- zone/client.cpp	(revision 451)
+++ zone/client.cpp	(working copy)
@@ -1750,7 +1751,7 @@
 		EQApplicationPacket* outapp = new EQApplicationPacket(OP_ReadBook, length + sizeof(BookText_Struct));
 
 		BookText_Struct *out = (BookText_Struct *) outapp->pBuffer;
-		out->unknown0 = book->unknown0;
+		out->window = book->window;
 		out->type = book->type;
 		out->invslot = book->invslot;
 		memcpy(out->booktext, booktxt2.c_str(), length);
Index: zone/client_packet.cpp
===================================================================
--- zone/client_packet.cpp	(revision 451)
+++ zone/client_packet.cpp	(working copy)
@@ -336,6 +336,7 @@
 	ConnectedOpcodes[OP_Barter] = &Client::Handle_OP_Barter;
 	ConnectedOpcodes[OP_VoiceMacroIn] = &Client::Handle_OP_VoiceMacroIn;
 	ConnectedOpcodes[OP_ApplyPoison] = &Client::Handle_OP_ApplyPoison;
+	ConnectedOpcodes[OP_AugmentInfo] = &Client::Handle_OP_AugmentInfo;
 }
 
 int Client::HandlePacket(const EQApplicationPacket *app)
@@ -8745,3 +8750,26 @@
 	FastQueuePacket(&outapp);
 }
 
+void Client::Handle_OP_AugmentInfo(const EQApplicationPacket *app) {
+	AugmentInfo_Struct* AugInfo = (AugmentInfo_Struct*) app->pBuffer;
+	char * outstring ("");
+	const Item_Struct * item = database.GetItem(AugInfo->itemid);
+	if (item)
+		MakeAnyLenString(&outstring, "You must use the solvent %s to remove this augment safely.", item->Name);
+	
+	int length = strlen(outstring);
+	// the same opcode is used to both send extra item info and to send book/scroll text
+	EQApplicationPacket* outapp = new EQApplicationPacket(OP_ReadBook, length + sizeof(BookText_Struct));
+
+	BookText_Struct *out = (BookText_Struct *) outapp->pBuffer;
+	out->window = AugInfo->window;
+	out->type = 2;	// type 2 equals item information
+	out->invslot = 0;	// invslot doesn't seem to matter
+	strcpy(out->booktext, outstring);
+	safe_delete_array(outstring);
+
+	FastQueuePacket(&outapp);
+	safe_delete(outapp);
+	
+}
+
Index: zone/client_packet.h
===================================================================
--- zone/client_packet.h	(revision 451)
+++ zone/client_packet.h	(working copy)
@@ -232,3 +232,4 @@
 	void Handle_OP_Barter(const EQApplicationPacket *app);
 	void Handle_OP_VoiceMacroIn(const EQApplicationPacket *app);
 	void Handle_OP_ApplyPoison(const EQApplicationPacket *app);
+	void Handle_OP_AugmentInfo(const EQApplicationPacket *app);
Reply With Quote
  #2  
Old 05-01-2009, 02:55 PM
Derision
Developer
 
Join Date: Feb 2004
Location: UK
Posts: 1,540
Default

Nice work (although I haven't had a chance to test it yet).

One thing I did notice is that in Handle_OP_AugmentInfo you FastQueue a packet and then call safe_delete to free the memory. FastQueue (unlike QueuePacket) should free the memory itself, so you shouldn't call safe_delete following FastQueue.
Reply With Quote
  #3  
Old 05-01-2009, 06:01 PM
KLS
Administrator
 
Join Date: Sep 2006
Posts: 1,348
Default

Yeah the idea by fastqueue is you basically pass ownership of the packet to the queue and it will free up all the memory after. It's a perfectly legitimate practice to use fastqueue for almost everything actually, you only really need queuepacket for when you want to send a packet more than once without recreating it (some spell and group code does this).
Reply With Quote
  #4  
Old 05-02-2009, 07:27 AM
Derision
Developer
 
Join Date: Feb 2004
Location: UK
Posts: 1,540
Default

I committed this in Rev452. Thanks again.
Reply With Quote
  #5  
Old 05-02-2009, 11:54 AM
realityincarnate
Developer
 
Join Date: Dec 2007
Posts: 122
Default

Quote:
Originally Posted by Derision View Post
One thing I did notice is that in Handle_OP_AugmentInfo you FastQueue a packet and then call safe_delete to free the memory. FastQueue (unlike QueuePacket) should free the memory itself, so you shouldn't call safe_delete following FastQueue.
Ok, I see that... now. I saw that FastQueue didn't make a copy of the data like QueuePacket did, but somehow missed that it cleared the pointer and freed the memory. Whenever there's a safe delete macro, I try to err on the side of freeing the memory.

Thanks for the info, though. The packet stream part of the code is still fairly mysterious to me, and any detail I don't have to search through functions to learn is a huge help.
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 11:19 AM.


 

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 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3