|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Development::Development Forum for development topics and for those interested in EQEMu development. (Not a support forum) |
10-13-2012, 05:45 PM
|
Administrator
|
|
Join Date: Sep 2006
Posts: 1,348
|
|
Going to chime in: I think bots are a clusterfuck and if we're implementing mercs we should implement them as a new system and not shoehorn them into the gap we've made with bots(esp since they don't work 100% the same).
|
10-13-2012, 08:02 PM
|
Developer
|
|
Join Date: Feb 2009
Location: Cincinnati, OH
Posts: 512
|
|
Maybe once Mercs are in, trunk drops support for bots, who are then maintained in the MercsAndBots branch. Seems like an acceptable solution to me.
|
|
|
|
10-15-2012, 05:07 AM
|
|
Developer
|
|
Join Date: Aug 2006
Location: USA
Posts: 5,946
|
|
Here are some more Mercenary related opcodes for SoD and UF:
SoD
Code:
OP_MercenaryDataUpdate=0x0786 #
OP_MercenaryCommand=0x167b #
OP_MercenarySuspendRequest=0x05f1 #
OP_MercenarySuspendResponse=0x57f2 #
OP_MercenaryDataUpdateRequest=0x390c #
Underfoot
Code:
OP_MercenaryDataUpdate=0x57f2 #
OP_MercenaryCommand=0x6c36 #
OP_MercenarySuspendRequest=0x3c58 #
OP_MercenarySuspendResponse=0x4b82 #
OP_MercenaryDataUpdateRequest=0x05f1 #
I will try to get some basic packet handling added for these and the code actually supporting them can be added later once more merc stuff is in place.
Also, it looks like OP_MercenaryAssign may actually just be OP_WeaponEquip1 according to the info I can find in my last collects. It is the same size packet and seems like the same struct. If we can verify this, it is one less thing to deal with for merc stuff.
Code:
// 0x7404 - OP_MercenaryAssign (Same packet as NoMercenaryHired_Struct?) [Server->Client]
struct MercenaryAssign_Struct {
/*0000*/ int32 MercEntityID; // Seen 0 (no merc spawned) or 615843841 and 22779137
/*0004*/ int32 MercUnk01; //
/*0008*/ int32 MercUnk02; //
/*0012*/
};
Code:
[OPCode: 0x7404] OP_WeaponEquip1 [Server->Client] [Size: 12]
000 | a4 59 00 00 01 00 00 00 8a 2b 00 00 | .Y.......+..
[OPCode: 0x7404] OP_WeaponEquip1 [Server->Client] [Size: 12]
000 | a4 59 00 00 00 00 00 00 dd 2a 00 00 | .Y.......*..
Last edited by trevius; 10-15-2012 at 06:00 AM..
|
|
|
|
|
|
|
10-15-2012, 07:29 AM
|
|
Developer
|
|
Join Date: Aug 2006
Location: USA
Posts: 5,946
|
|
And here are some roughed in packet handling for mercs for client_packet.cpp. These are mostly just hard set with the basic packet responses so they can be corrected later with actual functions supporting them.
Code:
ConnectedOpcodes[OP_MercenaryCommand] = &Client::Handle_OP_MercenaryCommand;
ConnectedOpcodes[OP_MercenaryDataUpdateRequest] = &Client::Handle_OP_MercenaryDataUpdateRequest;
ConnectedOpcodes[OP_MercenarySuspendRequest] = &Client::Handle_OP_MercenarySuspendRequest;
Code:
void Client::Handle_OP_MercenarySuspendRequest(const EQApplicationPacket *app)
{
if(app->size != sizeof(SuspendMercenary_Struct))
{
LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenarySuspendRequest expected %i got %i", sizeof(SuspendMercenary_Struct), app->size);
DumpPacket(app);
return;
}
SuspendMercenary_Struct* sm = (SuspendMercenary_Struct*) app->pBuffer;
uint32 merc_suspend = sm->SuspendMerc; // Seen 30 for suspending or unsuspending
DumpPacket(app);
// Handle the Command here...
// Check if the merc is suspended and if so, unsuspend, otherwise suspend it
// This response packet includes the timestamp of the suspend request
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenarySuspendResponse, sizeof(SuspendMercenaryResponse_Struct));
SuspendMercenaryResponse_Struct* smr = (SuspendMercenaryResponse_Struct*)outapp->pBuffer;
smr->SuspendTime = time(); // Unix Timestamp
DumpPacket(outapp);
FastQueuePacket(&outapp);
}
void Client::Handle_OP_MercenaryCommand(const EQApplicationPacket *app)
{
if(app->size != sizeof(MercenaryCommand_Struct))
{
LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenaryCommand expected %i got %i", sizeof(MercenaryCommand_Struct), app->size);
DumpPacket(app);
return;
}
MercenaryCommand_Struct* mc = (MercenaryCommand_Struct*) app->pBuffer;
uint32 merc_command = mc->MercCommand; // Seen 0 (zone in with no merc or suspended), 1 (dismiss merc), 5 (normal state), 36 (zone in with merc)
sint32 option = mc->Option; // Seen -1 (zone in with no merc), 0 (setting to passive stance), 1 (normal or setting to balanced stance)
DumpPacket(app);
// Handle the Command here...
// Will need a list of what every type of command is supposed to do
// Unsure if there is a server response to this packet
}
void Client::Handle_OP_MercenaryDataUpdateRequest(const EQApplicationPacket *app)
{
// The payload is 0 bytes.
if(app->size != 0)
{
LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenaryDataUpdateRequest expected 0 got %i", app->size);
DumpPacket(app);
return;
}
DumpPacket(app);
// Hard setting some stuff until it can be coded to load properly from the DB
int mercCount = 1;
int stanceCount = 2;
char mercName[32]; // This actually needs to be null terminated
strcpy(mercName, GetRandPetName());
uint32 packetSize = sizeof(MercenaryDataUpdate_Struct) + ( sizeof(MercenaryData_Struct) - 8 + sizeof(MercenaryStance_Struct) * stanceCount ) * mercCount + strlen(mercName);
// This response packet seems to be sent on zoning or camping by client request
// It is populated with owned merc data only
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataUpdate, packetSize);
MercenaryDataUpdate_Struct* mdu = (MercenaryDataUpdate_Struct*)outapp->pBuffer;
mdu->MercStatus = 0;
mdu->MercCount = mercCount;
for(int i = 0; i < mercCount; i++)
{
mdu->Mercs[i].MercID = 400;
mdu->Mercs[i].MercType = 330000100;
mdu->Mercs[i].MercSubType = 330020105;
mdu->Mercs[i].PurchaseCost = 4910;
mdu->Mercs[i].UpkeepCost = 123;
mdu->Mercs[i].Status = 0;
mdu->Mercs[i].AltCurrencyCost = 0;
mdu->Mercs[i].AltCurrencyUpkeep = 1;
mdu->Mercs[i].AltCurrencyType = 19;
mdu->Mercs[i].MercUnk01 = 0;
mdu->Mercs[i].TimeLeft = 900000;
mdu->Mercs[i].MerchantSlot = 1;
mdu->Mercs[i].MercUnk02 = 1;
mdu->Mercs[i].StanceCount = stanceCount;
mdu->Mercs[i].MercUnk03 = 519044964;
mdu->Mercs[i].MercUnk04 = 1;
strcpy(mml->Mercs[i].MercName, mercName);
for (int stanceindex = 0; stanceindex < stanceCount; stanceindex++)
{
mdu->Mercs[i].Stances[stanceindex].StanceIndex = stanceindex;
mdu->Mercs[i].Stances[stanceindex].Stance = stanceindex + 1;
}
mdu->Mercs[i].MercUnk05 = 1;
i++;
}
DumpPacket(outapp);
FastQueuePacket(&outapp);
}
I haven't tested these yet, but the basics should be there and easy to get working. I think this is the last of the handling needed for packets coming from the client. There is still plenty to do to get this stuff actually working as intended though.
|
|
|
|
|
|
|
10-16-2012, 06:23 AM
|
|
Developer
|
|
Join Date: Aug 2006
Location: USA
Posts: 5,946
|
|
I think it may need some testing, but based on my VoA merc collects, I found a couple more opcodes that appear to be mercenary related:
SoD:
Code:
OP_MercenaryDismiss=0x319a #
OP_MercenaryTimerRequest=0x184e #
Underfoot:
Code:
OP_MercenaryDismiss=0x0bd0 #
OP_MercenaryTimerRequest=0x0924 #
These are both Client->Server packets, so they will require more handling. I am pretty sure OP_MercenaryDismiss is the right opcode and names based on what I was seeing in UF while watching my log files and dismissing a merc. I am not sure about OP_MercenaryTimerRequest yet, but in my collect from Live, the OP_MercenaryTimer packet comes in right after OP_MercenaryTimerRequest on initial zone in with a merc.
All of these new packets will probably take some playing around with to figure out which are required for what and which may not be required at all (if any).
I will work on some basic handling for these as well, which can be refined later.
|
|
|
|
|
|
|
10-16-2012, 06:39 AM
|
|
Developer
|
|
Join Date: Aug 2006
Location: USA
Posts: 5,946
|
|
I think this should be the basic handling for those 2 new opcodes:
client_packet.h
Code:
void Handle_OP_MercenaryDismiss(const EQApplicationPacket *app);
void Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app);
client_packet.cpp
Code:
ConnectedOpcodes[OP_MercenaryDismiss] = &Client::Handle_OP_MercenaryDismiss;
ConnectedOpcodes[OP_MercenaryTimerRequest] = &Client::Handle_OP_MercenaryTimerRequest;
Code:
void Client::Handle_OP_MercenaryDismiss(const EQApplicationPacket *app)
{
// The payload is 0 bytes.
if(app->size != 0)
{
Message(13, "Size mismatch in OP_MercenaryDismiss expected 0 got %i", app->size);
LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenaryDismiss expected 0 got %i", app->size);
DumpPacket(app);
return;
}
DumpPacket(app);
Message(7, "Mercenary Debug: Dismiss Request Recieved.");
// Handle the dismiss here...
// Unsure if there is a server response to this packet
}
void Client::Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app)
{
// The payload is 0 bytes.
if(app->size != 0)
{
Message(13, "Size mismatch in OP_MercenaryTimerRequest expected 0 got %i", app->size);
LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenaryTimerRequest expected 0 got %i", app->size);
DumpPacket(app);
return;
}
DumpPacket(app);
Message(7, "Mercenary Debug: Timer Request received.");
// To Do: Load Mercenary Timer Data to properly populate this reply packet
// All hard set values for now
// Send Mercenary Status/Timer packet
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryTimer, sizeof(MercenaryStatus_Struct));
MercenaryStatus_Struct* mss = (MercenaryStatus_Struct*)outapp->pBuffer;
mss->MercEntityID = 1; // Seen 0 (no merc spawned) or 615843841 and 22779137
mss->UpdateInterval = 900000; // Seen 900000 - Matches from 0x6537 packet (15 minutes in ms?)
mss->MercUnk01 = 180000; // Seen 180000 - 3 minutes in milleseconds? Maybe next update interval?
mss->MercState = 5; // Seen 5 (normal) or 1 (suspended)
mss->SuspendedTime = 0; // Seen 0 (not suspended) or c9 c2 64 4f (suspended on Sat Mar 17 11:58:49 2012) - Unix Timestamp
DumpPacket(outapp);
FastQueuePacket(&outapp);
}
|
|
|
|
10-17-2012, 05:26 AM
|
|
Developer
|
|
Join Date: Aug 2006
Location: USA
Posts: 5,946
|
|
The last commit I did for Rev2234 is causing a zone crash when sending the mercenary merchant list. Simple fix is this:
client_packet.cpp in Client::Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app)
Replace:
Code:
packetSize = sizeof(MercenaryMerchantList_Struct) - 12 + mercTypeCount * 4 + ( sizeof(MercenaryListEntry_Struct) - 40 + sizeof(MercenaryStance_Struct) * mercStanceCount ) * mercCount;
With:
Code:
packetSize = sizeof(MercenaryMerchantList_Struct) + sizeof(MercenaryListEntry_Struct) * mercCount;
There are 2 spots in that function where this needs to be replaced.
I don't have access to test this right now, but will check it in the morning and commit the fix. Just noting it here for anyone following the merc branch changes.
|
10-17-2012, 12:34 PM
|
Administrator
|
|
Join Date: Sep 2006
Posts: 1,348
|
|
See this is why we need automatic packet encoding/decoding even at the application level. =/
|
|
|
|
10-19-2012, 10:09 AM
|
Developer
|
|
Join Date: Feb 2009
Location: Cincinnati, OH
Posts: 512
|
|
I did some spawn work last night. I cleaned up some code in client_packet.cpp and tried to flesh out the hiring / spawning process.
I was able to get the merc when hired added to my group. I had added some code for the merc to follow me, but it doesn't work yet. I didn't get a chance to test it out other than seeing it didn't work.
I added some code for dismiss, but it didn't seem to work either. It may have been an issue with getting the merc owner, as I had a similar issue on spawning I was able to fix. I just ran out of time to test out why.
My plan is to clean up the spawning process a little more, get my merc to follow me, get suspend/unsuspending & dismiss working tonight. A little more work needs to be done before being able to save the merc to the database (definitely not in the player profile).
The merc templates are currently being stored in the zone, so there is duplication. It could be moved to EQSharedMem to eliminate that, but to get it up and running, that's where I put them. The shared memory stuff may be beyond my pay grade, but there's plenty of time before anyone needs to worry about it. I think it's around 150kb per zone if my math is close.
If anyone has a live paid account on EQ that has mercs, I have some things I need to check on that I can't on my account. If anyone is able and willing, I'd appreciate it.
|
|
|
|
10-19-2012, 11:09 AM
|
Developer
|
|
Join Date: Feb 2009
Location: Cincinnati, OH
Posts: 512
|
|
Also, I think I have everything to put the correct stances in. Is there anything else that needs to be done besides modifying the packet size when creating it to account for the extra stances? Besides actually loading the correct stances, of course.. I'm in no hurry to add them, but wanted to check so I knew what changes would be needed. Passive and Balanced are fine for what we need to do yet.
|
|
|
|
10-20-2012, 12:23 AM
|
|
Fire Beetle
|
|
Join Date: Aug 2012
Posts: 10
|
|
Quote:
Originally Posted by bad_captain
I did some spawn work last night. I cleaned up some code in client_packet.cpp and tried to flesh out the hiring / spawning process.
I was able to get the merc when hired added to my group. I had added some code for the merc to follow me, but it doesn't work yet. I didn't get a chance to test it out other than seeing it didn't work.
I added some code for dismiss, but it didn't seem to work either. It may have been an issue with getting the merc owner, as I had a similar issue on spawning I was able to fix. I just ran out of time to test out why.
My plan is to clean up the spawning process a little more, get my merc to follow me, get suspend/unsuspending & dismiss working tonight. A little more work needs to be done before being able to save the merc to the database (definitely not in the player profile).
The merc templates are currently being stored in the zone, so there is duplication. It could be moved to EQSharedMem to eliminate that, but to get it up and running, that's where I put them. The shared memory stuff may be beyond my pay grade, but there's plenty of time before anyone needs to worry about it. I think it's around 150kb per zone if my math is close.
If anyone has a live paid account on EQ that has mercs, I have some things I need to check on that I can't on my account. If anyone is able and willing, I'd appreciate it.
|
I had mercs on my account even ended up putting in the work and getting high end tier 3 mercs so know all about them. Was also thinking of trying to help you guys out with any packet catching ya need since have guys at all levels and can solo most of the game since my mains on live are 90 druid i dual box with my 90 enchanter each with about 3000aa been awhile since I played well about VOA also have a entire guild city and a couple of houses wanted to see if I could help you guys get that data. If so let me know be glad to reactive my accounts for a month or two if it helps out.
|
|
|
|
|
|
|
10-20-2012, 08:04 AM
|
|
Developer
|
|
Join Date: Aug 2006
Location: USA
Posts: 5,946
|
|
Quote:
Originally Posted by bad_captain
Also, I think I have everything to put the correct stances in. Is there anything else that needs to be done besides modifying the packet size when creating it to account for the extra stances? Besides actually loading the correct stances, of course.. I'm in no hurry to add them, but wanted to check so I knew what changes would be needed. Passive and Balanced are fine for what we need to do yet.
|
Nothing special needs to be done to the packets for stances to be added as long as you don't exceed 5 total stances. Right now, due to the variable sized packet issues, I just have it hard coded to globally load 5 stance iterations into the packet. Then, once it is encoded, it only uses the number of iterations that are set in the stance count field. I did the same thing with merc types. I have it currently set to load 3 of them, but only use as many as are set in the merc type counts when the encode happens. Everything else gets discarded and is not populated anyway.
If we need to increase the number of merc types or stances at some point, I think we just have to adjust the related structs in eq_packet_structs.h.
|
|
|
|
10-20-2012, 10:18 AM
|
Developer
|
|
Join Date: Feb 2009
Location: Cincinnati, OH
Posts: 512
|
|
Okay, good to know.
5 stances should be okay, I believe. I'll have to check for any that might have more. Caster has the most - Passive, Balanced, Burn, and BurnAE for sure, maybe Efficient or Aggressive (I don't have them right in front of me). Healers have Passive, Balanced, Efficient and Reactive.
We will need to increase Merc Types, though. While I'm not even sure if they have any Master Mercenaries, there are a few Mercenary Merchants who have 2 races, so they will have at least 4 (6 if you include master).
I was able to get mercs to follow last night, and dismiss and suspend mostly working. Also, I fixed a couple of issues that allow the illusion packet to work (purchasing mercs from Guardian Norerd in PoK who needs to be changed to be a froglok now results in a froglok merc). I still need to add the SQL to fix the mercenary merchants, but i know him and Mercenary Mdjai in Crescent Reach work.
|
|
|
|
10-20-2012, 04:39 PM
|
Developer
|
|
Join Date: Feb 2009
Location: Cincinnati, OH
Posts: 512
|
|
I apparently made a few changes before I committed that I forgot about. One is causing a crash when hiring a merc. To fix this, add the following to the Merc constructor:
I'll add it tonight and try to fix another issue when the merc is dismissed. He's dismissed all right, but apparently his group doesn't think so. I'll get it sorted out. Good news though is that it does dismiss him.
|
|
|
|
10-20-2012, 04:42 PM
|
Developer
|
|
Join Date: Feb 2009
Location: Cincinnati, OH
Posts: 512
|
|
Quote:
Originally Posted by Devincean
I had mercs on my account even ended up putting in the work and getting high end tier 3 mercs so know all about them. Was also thinking of trying to help you guys out with any packet catching ya need since have guys at all levels and can solo most of the game since my mains on live are 90 druid i dual box with my 90 enchanter each with about 3000aa been awhile since I played well about VOA also have a entire guild city and a couple of houses wanted to see if I could help you guys get that data. If so let me know be glad to reactive my accounts for a month or two if it helps out.
|
Well, I was reminded that the test server has access to the Journeyman mercs, so I was able to get some data that way. I wouldn't want you to do that yet, and only if no one else has easy access to higher tier of mercs. I will be coming up with a list of things to work on, as well as a list of data that's needed. Hopefully this weekend.
|
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -4. The time now is 09:36 PM.
|
|
|
|
|
|
|
|
|
|
|
|
|