Thread: Mercenaries
View Single Post
  #19  
Old 10-15-2012, 07:29 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

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.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote