Thread: Mercenaries
View Single Post
  #1  
Old 04-02-2012, 07:56 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default Mercenaries

Since EQ is now F2P, I spent some time collecting data from Live for Mercenaries. There does not seem to be too many packets related to Mercs. Below is what I have figured out for mercenary packet structures. Hopefully I can get time to test some of this and maybe implement some basic handling for these packets, but I figured it would be good to post in case I don't get time to do that soon.

Mercenary Packet Structures:

Code:
// Currently unused, but may be good to have
enum MercStance
{
	MercPassive		= 1,
	MercBalanced	= 2,
	MercEfficient	= 3,
	MercReactive	= 4,
	MercAggressive	= 5,
	MercAssist		= 6,
	MercBurn		= 7,
	MercEfficient	= 8,
	MercBurnAE		= 9
};

// [OPCode: 0x27ac] On Live as of April 2 2012 [Server->Client]
struct MercenarySellList_Struct {
	int32 MercTypeCount;				// Seen 2 - Iterations of MercCategory_Struct
	MercCategory_Struct Categories[0];	// From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
	int32 MercCount;					// Seen 24 - Iterations of MercCategory_Struct
	MercenaryInfo_Struct Mercs[0];			// Data for individual mercenaries in the Merchant List
};
 
struct MercCategory_Struct {
	int32 Category;						// From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
};

// Used for Mercenary Merchant Lists and for Hired Mercenary Info Updates
struct MercenaryInfo_Struct {
	int32 MercID;					// ID unique to each type of mercenary (probably a DB id) - (if 1, do not send MercData_Struct - No merc hired)
	MercData_Struct MercData[0];	// Data for individual mercenaries - Not populated if no merc is hired
};

struct MercData_Struct {
/*0000*/	int32	MercType;				// From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
/*0004*/	int32	MercDesc;				// From dbstr_us.txt - 330020105^23^Race: Guktan<br>Type: Healer<br>Confidence: High<br>Proficiency: Apprentice, Tier V...
/*0008*/	int32	PurchaseCost;			// Purchase Cost (in gold)
/*0012*/	int32	UpkeepCost;				// Upkeep Cost (in gold)
/*0016*/	int32	Status;					// Required Account Status (Free = 0, Silver = 1, Gold = 2) at merchants - Seen 0 (suspended) or 1 (unsuspended) on hired mercs ?
/*0020*/	int32	AltCurrencyCost;		// Alternate Currency Purchase Cost? (all seen costs show N/A Bayle Mark) - Seen 0
/*0024*/	int32	AltCurrencyUpkeep;		// Alternate Currency Upkeep Cost? (all seen costs show 1 Bayle Mark) - Seen 1
/*0028*/	int32	AltCurrencyType;		// Alternate Currency Type? - 19^17^Bayle Mark^0 - Seen 19
/*0032*/	int8	MercUnk01;				// Unknown (always see 0)
/*0036*/	sint32	TimeLeft;				// Unknown (always see -1 at merchant) - Seen 900000 (15 minutes in ms for newly hired merc)
/*0040*/	int32	MerchantSlot;			// Merchant Slot? Increments, but not always by 1 - May be for Merc Window Options (Seen 5, 36, 1 for active mercs)?
/*0044*/	int32	MercUnk02;				// Unknown (always see 1)
/*0048*/	int32	StanceCount;			// Iterations of MercStance_Struct - Normally 2 to 4 seen
/*0052*/	int32	MercUnk03;				// Unknown (always 0 at merchant) - Seen on active merc: 93 a4 03 77, b8 ed 2f 26, 88 d5 8b c3, and 93 a4 ad 77
/*0056*/	int8	MercUnk04;				// Seen 1 
/*0060*/	char[0]	MercName;				// Null Terminated Mercenary Name (00 at merchants)
/*0000*/	MercStance_Struct Stances[0];	// From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012)
};

// There appears to be extra data sent in this part of the struct sometimes that is unknown (normally 0, 1, or 2)
struct MercStance_Struct {
	int32 Stance;						// From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012)
};

// [OPCode: 0x6537] On Live as of April 2 2012 [Server->Client]
// Size 12 and sent on Zone-In if no mercenary is currently hired and when merc is dismissed
// Size varies if mercenary is hired or if browsing Mercenary Merchant
struct MercDataUpdate_Struct {
/*0000*/	sint32	MercStatus;			// Seen 0 with merc and -1 with no merc hired
/*0004*/	int32	HiredCount;			// Seen 1 with 1 merc hired and 0 with no merc hired
/*0008*/	MercenaryInfo_Struct MercData[0];	// Data for individual mercenaries in the Merchant List
};

// [OPCode: 0x495d] On Live as of April 2 2012 [Server->Client] [Size: 20]
// Sent on Zone-In, or after Dismissing, Suspending or Unsuspending Mercs
struct MercenaryUpdate_Struct {
/*0000*/	int32	MercEntityID;		// Seen 0 (no merc spawned) or 615843841 and 22779137
/*0004*/	int32	UpdateInterval;	// Seen 900000 - Matches from 0x6537 packet (15 minutes in ms?)
/*0008*/	int32	MercUnk01;		// Seen 180000 - 3 minutes in milleseconds?
/*0012*/	int32	MercState;		// Seen 5 (normal) or 1 (suspended)
/*0016*/	int32	SuspendedTime;	// Seen 0 (not suspended) or c9 c2 64 4f (suspended on Sat Mar 17 11:58:49 2012) - Unix Timestamp
/*0020*/
};

// [OPCode: 0x1a79] On Live as of April 2 2012 [Client->Server] [Size: 1] - Requesting to suspend or unsuspend merc
struct SuspendMercenary_Struct {
/*0000*/	int8	SuspendMerc;	// Seen 30 (48) for suspending or unsuspending
/*0001*/
};

// [OPCode: 0x2528] On Live as of April 2 2012 [Server->Client] [Size: 4] - Response to suspend merc with timestamp
struct SuspendMercenary_Struct {
/*0000*/	int32	SuspendTime;	// Unix Timestamp - Seen a9 11 78 4f
/*0004*/
};

// MercCommand field is possibly related to MerchantSlot field in MercData_Struct (seen same values)
// [OPCode: 0x4c6c] On Live as of April 2 2012 [Client->Server] [Size: 8] - Response to suspend merc with timestamp
struct MercCommand_Struct {
/*0000*/	int32 MercCommand;	// Seen 0 (zone in with no merc or suspended), 1 (dismiss merc), 5 (normal state), 36 (zone in with merc)
/*0004*/	int32 Option;		// Seen -1 (zone in with no merc), 0 (setting to passive stance), 1 (normal or setting to balanced stance)
/*0008*/
};

These are the opcodes that appear to be directly Mercenary related:

0x6537 Server->Client - Some kinda merc info update. Much smaller with no merc
0x0327 Client->Server - Labelled OP_MercenaryDataResponse in EQExtractor2 (size 0)
0x2ef8 Client->Server - Request dismiss merc (size 0)
0x495d Server->Client - Some merc status update from server - Maybe response to 0x4c6c
0x1a79 Client->Server - Requesting to suspend merc
0x2528 Server->Client - Response to suspend merc
0x4c6c Client->Server - Some kind of merc status change request from client - Examples:
24 00 00 00 01 00 00 00 - Zoning in
01 00 00 00 01 00 00 00 - Dismiss merc
05 00 00 00 01 00 00 00 - Right after purchasing merc
05 00 00 00 00 00 00 00 - Setting merc to passive
05 00 00 00 01 00 00 00 - Setting merc back to balanced
00 00 00 00 ff ff ff ff - Zoning in with no merc
01 00 00 00 01 00 00 00 - Right after previous update of zoning in with no merc

Using Mercenary Merchant:

0x4dd9 Client->Server - Right clicking merchant request
0x27ac Server->Client - Merc merchant response
0x3887 Server->Client - After merchant response
0x5e78 Client->Server - Request to view merc info while browsing merchant?
90 01 00 00 01 00 00 00 46 22 00 00 00 6e e4 03
0x5e78 Server->Client - Server response to 0x5e78
06 00 00 00
0x528f Server->Client - Seen after purchasing merc and when camping
0x6942 Server->Client - Response after purchasing merc - Purchase approval response?

I have a ton more data than I am showing here, but I don't want to post it all until I can organize it a bit more. I will post the rest of the structs for the above lists when I have time. At least the more complex structs should be in pretty good shape from the ones I posted above. The rest are all really small (16 bytes or less).
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote