Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Development

Development::Development Forum for development topics and for those interested in EQEMu development. (Not a support forum)

Reply
 
Thread Tools Display Modes
  #61  
Old 11-05-2012, 10:06 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Quote:
Originally Posted by Secrets View Post
before I went crazy.
I though you were born crazy! <3 Secrets

And yeah, it is a unix timestamp. I didn't look much into that function when I stuck that in there. I was just populating fields with data. You may be right that it is returning an undesired result.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #62  
Old 11-05-2012, 10:11 AM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default

Quote:
Originally Posted by trevius View Post
I though you were born crazy! <3 Secrets

And yeah, it is a unix timestamp. I didn't look much into that function when I stuck that in there. I was just populating fields with data. You may be right that it is returning an undesired result.
I'll be committing what I learned from the disassembly soon.

In the meantime, here's a list of valid merc status update IDs. The packet is used on the client and server, whereas the client sends different data than the server packet. It's not just used for hiring as you can see below:

// [OPCode: 0x5e78 (OP_MercenaryHire?)] On Live as of April 2 2012
/*
Valid response IDs:

0 - Hire me! (Assign Merc after sending this.)
1 - Insufficient money message.
2 - Mercenary-To-Hire does not exist in the server's DB.
3 - Mercenary failed to spawn. (this actually tells us the mercenary should spawn BEFORE recieving this packet.)
4 - Mercenaries not allowed in raids.
5 - You already have a mercenary request pending
6 - You must dismiss the mercenary before hiring a new one.
7 - You must dismiss your suspended one before hiring a new one.
8 - Group is full.
9 - Error creating mercenary
10 - Replacing mercenary(?!)
11 - Your mercenary has quit! You ran out of money to pay for your mercenary!
12 - Your mercenary waived an upkeep cost of %d plat, and %d gold and your mercenary upkeep cost timer has been reset to %s. <-- these values are for GM resets of mercenaries and are generated from the client's
mercenary info. NOT from the packet.
13 - Your mercenary is about to be quit due to insufficient funds! <--- Sent before the mercenary quits, unsure of time sent before.
14 - There is no mercenary liason nearby! <-- hacking attempt check if no mercenary merchant is in the zone!
15 - You are too far away from the liason! <-- Liason exists as type in the zone, but client is too far away. (position update happened)
16 - You do not meet the requirements for that mercenary! <-- For example, if a mercenary is 'unlocked' in some way, send this if they do not have the mercenary unlock.
*/
Reply With Quote
  #63  
Old 11-05-2012, 11:10 AM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default

So, the assign packet.

It's actually a 16-byte packet that does different things depending on variable size.

I had a screenshot from when I last worked on it. Basically, there's a few fields, and you were right about the unhire struct being the same as the assign struct:
Quote:

struct MercenaryAssign_Struct {
/*0000*/ int32 MercEntityID; // Seen 0 (no merc spawned) or 615843841 and 22779137
/*0004*/ int32 MercState; // Seen 0 with no merc hired
/*0008*/ int32 MercSuspended; // Seen 1 when no merc is hired - ID unique to each type of mercenary
/*0012*/ int32 MercTimeRemaining; //UNIX Timestamp. The reason the client accepts this part of the packet missing is because SOE stupidly left no size checks. //I assume they wanted it in another packet but never removed it?
/*0016*/
};
I'm not actually sure if MercSuspended is the suspend state of the merc, it could be a list of stances from the client. It might not be. I'm not sure, I haven't observed the packet.

It's also possible the suspended state is a value from 0-4 depending on if the merc is suspended, active, dismissed or two other states? not sure.

Another thing it could be is that I have the initial hire packet and the assign packet screwed up, which would explain the merctimeremaining part being missing.

I forget what values these were but it *was* working at some point:

Reply With Quote
  #64  
Old 11-05-2012, 11:55 PM
bad_captain
Developer
 
Join Date: Feb 2009
Location: Cincinnati, OH
Posts: 512
Default

I did some debugging on the timer stuff. 0 or 1 sized didn't seem to help. I did notice that at some point it was working and tried to figure out how I did it.

I found out there is a bug where if you have a merc suspended, it allows you to purchase a new merc. That part is easily fixed, but I found out something interesting. If I suspend my merc, then purchase a new one, my timer suddenly began to work. With the help of the debug messages, I found that if I had a merc suspended (the client thinks I have one), and purchase a new one, it doesn't do a data request for the merc data, since I assume the client thinks it already knows it. Somewhere in the data response, where it requests the current merc (merchant ID = 0), there's something that causes the timer to not work.

I did notice that there are two very similar structures: MercenaryData_Struct and MercenaryListEntry_Struct. There may be a chance to combine the two, and there may be a mixup of when to use one or the other, or something. I'll check into this a little more, but I thought I would throw it out there.
Reply With Quote
  #65  
Old 11-06-2012, 04:34 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Thanks for the info, Secrets! That is some nice data for the hire packets for sure.

Quote:
Originally Posted by bad_captain View Post
I did notice that there are two very similar structures: MercenaryData_Struct and MercenaryListEntry_Struct. There may be a chance to combine the two, and there may be a mixup of when to use one or the other, or something. I'll check into this a little more, but I thought I would throw it out there.
Yeah, when I first wrote the structs, those 2 were using the same struct for their packets. The problem was that on the Live collect from VoA that I have, the MercenaryData_Struct has an extra field at the end, which I am really not too sure about. So, I split them up into 2 separate structs just to get things working. Since we actually build those packets on the fly in the patch files, the structs don't actually matter other than being a place to store the data so we can pull it when creating the packets in the path files. So, at this point, we should be able to just remove the MercenaryListEntry_Struct struct and store everything in MercenaryData_Struct instead, including the additional field. Even if that additional field isn't used, we can determine if we want to use it or not when we create the packets in the patch files.

Right now, it looks like I have that additional field at the end of the data update commented out in the encodes. I would either need a collect from SoD and UF or to have someone like Secrets to check the IDA output to figure out the correct packet struct to verify if it is correct or not. Maybe just uncommenting that so it adds the extra field would make it work, I dunno. I also don't know if that field only comes at the end of the packet, or if it can also come with every iteration of the merc data if more than one merc is owned. If it is related to owning multiple mercs, I think that was added later, so SoD and maybe UF might not have that field. At this point, it is just speculation though.

It is interesting that your timer started working when you had a merc already suspended. That sounds like the client is ignoring the merc data update response the way we are sending it. Something like that could definitely be caused by a packet struct issue, like size, which could be due to that missing field at the end (or any other peice of data). Right now, the data update struct isn't being fully populated based on what I saw on my VoA collects anyway. I know the merc name field is not yet being populated, which could also be the reason why it is failing. The variable sized packets just take a bit more work to get them sending as needed, but I am sure we can work out the rest of whatever is needed easy enough. The merc name field can probably just be changed to be 64 bytes, and we can add that to the encode with the appropriate size and null terminator. Also, if that last field in the data update only comes after the iterations for each merc data, we can't add it after "MercenaryData_Struct MercData[0]" due to the fact that 0 sized arrays have to be at the end of the struct, but we could easily just add it in during the encode by checking if we are on the last iteration and only adding it then. Either way, that doesn't matter too much at this point, until we get to the point of trying to manage more than 1 owned merc at a time.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!

Last edited by trevius; 11-06-2012 at 04:43 AM..
Reply With Quote
  #66  
Old 11-06-2012, 11:35 AM
bad_captain
Developer
 
Join Date: Feb 2009
Location: Cincinnati, OH
Posts: 512
Default

The ability to have multiple mercs came in December of last year, which was a month after VoA came out. From the December 14th 2011 patch notes:

Quote:
Mercenary Roster -
- Players can now buy extra mercenary slots on the Marketplace and keep a roster of mercenaries that they can switch between. Mercenaries operate the way they used to, except that if you purchase another mercenary, it will become active and replace the mercenary you had active before (if any). Dismissing a mercenary will cause the first remaining mercenary in your roster to become the active mercenary (though suspended). Transferring a mercenary will cause the target player's active mercenary to be suspended and the newly transferred one to become active.
- To switch mercenaries in your roster, open the Mercenary Management UI.
- Added the new command /mercswitch. With no arguments, it lists the current roster of mercenaries and displays the one that is currently active. Adding a parameter allows switching between mercenaries in the roster.
I don't think the name is needed for SoD or UF, and wasn't present until this patch. I have collects from December 7th or 8th (before the change), and then Provocating sent me caps from December 27th - 30th (after). One of the unknowns may not be needed as well, I will have to double check my packets to verify. The additional fiend at the end may have come at the same time, as I don't believe it is in my captures either. I hope to verify tonight, but things have been a little busy around work with the election.

Here's a packet from 12/5:

Code:
12/5/2011 2:56:56 AM
[OPCode: 0x0327] OP_MercenaryDataResponse [Server->Client] [Size: 82]
000 | 01 00 00 00 e4 a4 bf 07 01 00 00 00 16 07 00 00  | ................
016 | e4 a4 bf 07 29 41 c0 07 00 00 00 00 00 00 00 00  | ....)A..........
032 | 00 00 00 00 00 00 00 00 13 00 00 00 00 a0 bb 0d  | ................
048 | 00 24 00 00 00 01 00 00 00 02 00 00 00 00 00 00  | .$..............
064 | 00 01 01 00 00 00 02 00 00 00 00 00 00 00 01 00  | ................
080 | 00 00                                            | ..
The Group UpdateB packet and the two following have the merc's name.

Code:
[OPCode: 0x7139] OP_Unknown [Server->Client] [Size: 86]
000 | e1 ad 00 00 02 00 00 00 xx xx xx xx xx xx 00 00  | ........MyName..
016 | 00 00 00 xx xx xx xx xx xx 00 00 00 00 05 00 00  | ...MyName.......
032 | 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  | ................
048 | 44 69 61 73 72 69 72 31 30 32 37 39 39 00 01 00  | Diasrir102799...
064 | xx xx xx xx xx xx 00 05 00 00 00 00 00 00 00 00  | MyName..........
080 | 00 00 00 00 00 00                                | ......

Code:
12/5/2011 2:56:58 AM
[OPCode: 0x7706] OP_Unknown [Server->Client] [Size: 16]
000 | 5c 02 00 00 c2 04 00 00 44 69 61 73 72 69 72 00  | \.......Diasrir.
I haven't checked to see if those opcodes have been figured out. I just wanted to post them for reference.

Last edited by trevius; 11-06-2012 at 01:15 PM.. Reason: Changed patch notes to be quoted so the forums aren't stretched really with for code blocks.
Reply With Quote
  #67  
Old 11-06-2012, 01:15 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

I think those 2 unknowns are just normal group packets. They look pretty familiar just based on the info in them.

That 12/5/11 packet is interesting. Here is the breakdown of the packet into a struct as far as I can tell. Almost all of the fields match up with what I have seen on VoA other than the last extra field on VoA and the Status field for the new F2P membership stuff. Though, there appears to be an extra MercType field at the top of the struct, which is something I haven't seen before. Maybe if we try the struct like that, the update will work properly. I will see if I can figure out a good way to do that. I can't think of a good reason to have the MercType field redundant like that unless it is something to tell the client which is the highest type it currently has access to or something.

Code:
01 00 00 00 - 1 - MercStatus
e4 a4 bf 07 - 130000100 - MercType again ?
01 00 00 00 - 1 - MercCount
16 07 00 00 - 1814 - MercID
e4 a4 bf 07 - 130000100 - MercType
29 41 c0 07 - 130040105 - MercSubType
00 00 00 00 - 0 - PurchaseCost
00 00 00 00 - 0 - UpkeepCost
00 00 00 00 - 0 - AltCurrencyCost
00 00 00 00 - 0 - AltCurrencyUpkeep
13 00 00 00 - 19 - AltCurrencyType
00          - 0 - MercUnk01
a0 bb 0d 00 - 900000 - TimeLeft
24 00 00 00 - 36 - MerchantSlot
01 00 00 00 - 1 - MercUnk02
02 00 00 00 - 2 - StanceCount
00 00 00 00 - 0 - MercUnk03
01          - 1 - MercUnk04
01 00 00 00 - 1 - StanceIndex
02 00 00 00 - 2 - Stance
00 00 00 00 - 0 - StanceIndex
01 00 00 00 - 1 - Stance
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #68  
Old 11-06-2012, 05:22 PM
bad_captain
Developer
 
Join Date: Feb 2009
Location: Cincinnati, OH
Posts: 512
Default

I think it is the same as the initial data response, where it has the number of types to follow, the merc type, the number of mercs that follow, and then the merc. From what I've seen after hiring 5-10 mercs during that time ( I was mostly trying to get the full response packets so I didn't get as much as I'd like of later packets), the first is always 1, followed by the type. I may be wrong though. I guess I never did try hiring and not actually get to hire. Maybe one of the other fields is status?

And thanks for fixing my post. I was in a hurry to go vote before work and missed that.
Reply With Quote
  #69  
Old 11-07-2012, 08:21 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Ahh, that makes more sense. I didn't even think about it that way because the struct I have from April 2 2012 shows the following structure:

Code:
[OPCode: 0x6537] OP_MercenaryDataUpdate [Server->Client] [Size: 93]

00 00 00 00 - 0 - MercStatus
01 00 00 00 - 1 - MercCount
8f 01 00 00 - 399 - MercID
e4 66 ab 13 - 330000100 - MercType
09 b5 ab 13 - 330020105 - MercSubType
bb 00 00 00 - 187 - PurchaseCost
b2 00 00 00 - 178 - UpkeepCost
01 00 00 00 - 1 - Status
00 00 00 00 - 0 - AltCurrencyCost
01 00 00 00 - 1 - AltCurrencyUpkeep
13 00 00 00 - 19 - AltCurrencyType
00          - 0 - MercUnk01
a0 bb 0d 00 - 900000 - TimeLeft
05 00 00 00 - 5 - MerchantSlot
01 00 00 00 - 1 - MercUnk02
02 00 00 00 - 2 - StanceCount
88 d5 8b c3 - 3280721288  - MercUnk03
01          - 1 - MercUnk04
4b 65 6b 6c 65 6b 00 Keklek - MercName
00 00 00 00 - 0 - StanceIndex
01 00 00 00 - 1 - Stance
01 00 00 00 - 1 - StanceIndex
02 00 00 00 - 2 - Stance
01 00 00 00 - 1 - MercUnk05
Note the additional fields I saw are in green, and MercUnk03 also has some data in it in the VoA collect, where yours looks almost just like what they do when sent as a merchant list with no data in MercUnk03.

Maybe they used to use the same structs for merchant lists and the data updates, but changed that later in VoA since some things like the MercTypes list are unneeded.

Either way, at least both versions are in this thread as examples for that packet, which may help for comparison purposes.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #70  
Old 11-07-2012, 09:56 AM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default

I can confirm that the OP_MercenaryDataUpdate packet that we have listed is not existent in any packet handlers for Seeds of Destruction. Not sure about underfoot but the opcode we have listed is not there at all.
Reply With Quote
  #71  
Old 11-09-2012, 02:22 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default

Reply With Quote
  #72  
Old 11-09-2012, 06:59 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default

Gonna be committing the next part of the merc stuff tonight; I got the packets in order and well, a quite nice result:

Reply With Quote
  #73  
Old 11-09-2012, 09:47 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Score! Good work
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #74  
Old 11-11-2012, 05:35 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default

Mercenaries are now in an implementable state! I finished the last few bits of packet work over the last few days. We now can suspend/unsuspend, have a merc charge upkeep based on a timer, and all of these features are saving cross-zone.

I also tested in on the Underfoot client and it works just as well as titanium. The only thing that doesn't work is the auto-assist button but I assume we can implement that during the AI stuff. It's a simple button setting that the client sends to the server, and the server must send it back at some point. I could look into it, but I would rather get the AI stuff working before we go implementing an auto-assist/call target function!

bad_captain or trevius, if you would like to start work on the AI with me, that would be great. Thankfully we can just copy-paste bots for the most part. I'd like to see this go live on PEQ soon, would be nice to add this to an array of features EQEmulator has. And I can't even begin to imagine the custom server possibilities.
Reply With Quote
  #75  
Old 11-11-2012, 11:11 PM
bad_captain
Developer
 
Join Date: Feb 2009
Location: Cincinnati, OH
Posts: 512
Default

Great work, Secrets!

I took a few days off, but planned on getting back to it. I was planning on working on the database side, for getting the basic stats per level, class, proficiency, etc., naming rules, and anything else that's still needed.

A decision that still needs to be made is whether mercs use equipment (and weapons) or max & min hit values. The benefit of using weapons would seem to be less balancing that would need to be done in the database, since there wouldn't be records that would need to be updated per level, class, proficiency, and tier. That's quite a few records to have to change if melee attacks are under or over powered. On the other hand, if weapons are used, it could require more data elements that need to be edited to change the resulting damage.

As you said, much of the AI can be copied from bots and edited where needed. I'm sure the stance code for bots can be improved, but that could provide a start. I'm still working to get all spells used, and I know they differ based on the selected stance, so that data still needs to be captured completely. I think I can currently come up with basic spell sets for all of them, but more data is needed, especially for higher levels.
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 05:15 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