Zoning works but saving and player movement packets dont so it's a little limited, wear change works.

Chat is a work in progress but not yet working.
This commit is contained in:
KimLS 2024-11-19 21:06:53 -08:00
parent 2c5c28b808
commit ebb657153a
5 changed files with 173 additions and 13 deletions

View File

@ -2407,6 +2407,70 @@ namespace Larion
FINISH_ENCODE();
}
ENCODE(OP_WearChange)
{
ENCODE_LENGTH_EXACT(WearChange_Struct);
SETUP_DIRECT_ENCODE(WearChange_Struct, structs::WearChange_Struct);
OUT(spawn_id);
eq->wear_slot_id = emu->wear_slot_id;
eq->armor_id = emu->material;
eq->variation = emu->unknown06;
eq->material = emu->elite_material;
eq->new_armor_id = emu->hero_forge_model;
eq->new_armor_type = emu->unknown18;
eq->color = emu->color.Color;
FINISH_ENCODE();
}
ENCODE(OP_SpecialMesg)
{
EQApplicationPacket* in = *p;
*p = nullptr;
SerializeBuffer buf(in->size);
buf.WriteInt8(in->ReadUInt8()); // speak mode
buf.WriteInt8(in->ReadUInt8()); // journal mode
buf.WriteInt8(in->ReadUInt8()); // language
buf.WriteInt32(in->ReadUInt32()); // message type
buf.WriteInt32(in->ReadUInt32()); // target spawn id
std::string name;
in->ReadString(name); // NPC names max out at 63 chars
buf.WriteString(name);
buf.WriteInt32(in->ReadUInt32()); // loc
buf.WriteInt32(in->ReadUInt32());
buf.WriteInt32(in->ReadUInt32());
std::string old_message;
std::string new_message;
in->ReadString(old_message);
//ServerToRoF2SayLink(new_message, old_message);
buf.WriteString(new_message);
auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf);
dest->FastQueuePacket(&outapp, ack_req);
delete in;
}
ENCODE(OP_DeleteSpawn)
{
ENCODE_LENGTH_EXACT(DeleteSpawn_Struct);
SETUP_DIRECT_ENCODE(DeleteSpawn_Struct, structs::DeleteSpawn_Struct);
OUT(spawn_id);
eq->unknown04 = 1; // Observed
FINISH_ENCODE();
}
// DECODE methods
DECODE(OP_EnterWorld)
@ -2469,5 +2533,62 @@ namespace Larion
FINISH_DIRECT_DECODE();
}
DECODE(OP_WearChange)
{
DECODE_LENGTH_EXACT(structs::WearChange_Struct);
SETUP_DIRECT_DECODE(WearChange_Struct, structs::WearChange_Struct);
IN(spawn_id);
emu->wear_slot_id = eq->wear_slot_id;
emu->material = eq->armor_id;
emu->unknown06 = eq->variation;
emu->elite_material = eq->material;
emu->hero_forge_model = eq->new_armor_id;
emu->unknown18 = eq->new_armor_type;
emu->color.Color = eq->color;
FINISH_DIRECT_DECODE();
}
DECODE(OP_ChannelMessage)
{
unsigned char* __eq_buffer = __packet->pBuffer;
char* InBuffer = (char*)__eq_buffer;
char Sender[64];
char Target[64];
VARSTRUCT_DECODE_STRING(Sender, InBuffer);
VARSTRUCT_DECODE_STRING(Target, InBuffer);
//packet seems the same as rof2 with 5 more empty bytes before language
InBuffer += 9;
uint32 Language = VARSTRUCT_DECODE_TYPE(uint32, InBuffer);
uint32 Channel = VARSTRUCT_DECODE_TYPE(uint32, InBuffer);
InBuffer += 5;
uint32 Skill = VARSTRUCT_DECODE_TYPE(uint32, InBuffer);
std::string old_message = InBuffer;
std::string new_message;
//RoF2ToServerSayLink(new_message, old_message);
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
__packet->pBuffer = new unsigned char[__packet->size];
ChannelMessage_Struct* emu = (ChannelMessage_Struct*)__packet->pBuffer;
strn0cpy(emu->targetname, Target, sizeof(emu->targetname));
strn0cpy(emu->sender, Target, sizeof(emu->sender));
emu->language = Language;
emu->chan_num = Channel;
emu->skill_in_language = Skill;
strcpy(emu->message, new_message.c_str());
delete[] __eq_buffer;
}
} /*Larion*/

View File

@ -19,11 +19,16 @@ E(OP_SendZonepoints)
E(OP_RequestClientZoneChange)
E(OP_ZoneChange)
E(OP_ClientUpdate)
E(OP_WearChange)
E(OP_SpecialMesg)
E(OP_DeleteSpawn)
//list of packets we need to decode on the way in:
D(OP_EnterWorld)
D(OP_ZoneEntry)
D(OP_ZoneChange)
D(OP_ClientUpdate)
D(OP_WearChange)
D(OP_ChannelMessage)
#undef E
#undef D

View File

@ -385,6 +385,31 @@ namespace Larion {
/*176*/
};
struct WearChange_Struct {
/*000*/ uint32 spawn_id;
/*004*/ uint32 wear_slot_id;
/*008*/ uint32 armor_id;
/*012*/ uint32 variation;
/*016*/ uint32 material;
/*020*/ uint32 new_armor_id;
/*024*/ uint32 new_armor_type;
/*028*/ uint32 color;
/*032*/
};
struct ExpUpdate_Struct
{
/*000*/ uint64 exp; //This is exp % / 1000 now; eg 69250 = 69.25%
/*008*/ uint64 unknown; //unclear, I didn't see the client actually read this value but i might have missed it
};
struct DeleteSpawn_Struct
{
/*00*/ uint32 spawn_id; // Spawn ID to delete
/*04*/ uint8 unknown04; // Seen 1
/*05*/
};
#pragma pack()
}; //end namespace structs

View File

@ -105,11 +105,11 @@ OP_ExpUpdate=0x0000 #0x611d
OP_HPUpdate=0x0000 #0x775c
OP_ManaChange=0x0000 #0x0606
OP_TGB=0x0000
OP_SpecialMesg=0x0000 #0x7d93
OP_SpecialMesg=0x7d93
OP_GuildMemberList=0x0000
OP_GuildMOTD=0x0000
OP_CharInventory=0x21d6
OP_WearChange=0x0000 #0x44c0
OP_WearChange=0x44c0
OP_ClientUpdate=0x3a4b
OP_ClientReady=0x0831
OP_SetServerFilter=0x0000 #0x6b7f
@ -218,7 +218,7 @@ OP_Bug=0x0000
OP_Feedback=0x0000
OP_Report=0x0000
OP_Damage=0x0000
OP_ChannelMessage=0x0000
OP_ChannelMessage=0x6adc
OP_Assist=0x0000
OP_AssistGroup=0x0000
OP_MoveCoin=0x0000
@ -249,7 +249,7 @@ OP_XTargetOpen=0x0000
OP_XTargetOpenResponse=0x0000
OP_BuffCreate=0x0000
OP_BuffRemoveRequest=0x0000
OP_DeleteSpawn=0x0000
OP_DeleteSpawn=0x7712
OP_AutoAttack=0x0000
OP_AutoAttack2=0x0000
OP_Consume=0x0000

View File

@ -534,20 +534,29 @@ void Client::SendZoneInPackets()
if (GetLevel() >= 51)
SendAlternateAdvancementStats();
// Send exp packets
outapp = new EQApplicationPacket(OP_ExpUpdate, sizeof(ExpUpdate_Struct));
ExpUpdate_Struct* eu = (ExpUpdate_Struct*)outapp->pBuffer;
uint32 tmpxp1 = GetEXPForLevel(GetLevel() + 1);
uint32 tmpxp2 = GetEXPForLevel(GetLevel());
// Crash bug fix... Divide by zero when tmpxp1 and 2 equalled each other, most likely the error case from GetEXPForLevel() (invalid class, etc)
auto tmpxp2 = GetEXPForLevel(GetLevel() + 1);
auto tmpxp1 = GetEXPForLevel(GetLevel());
if (tmpxp1 != tmpxp2 && tmpxp1 != 0xFFFFFFFF && tmpxp2 != 0xFFFFFFFF) {
float tmpxp = (float)((float)m_pp.exp - tmpxp2) / ((float)tmpxp1 - tmpxp2);
eu->exp = (uint32)(330.0f * tmpxp);
outapp->priority = 6;
QueuePacket(outapp);
//Larion uses a more granular exp bar than other clients
if (m_ClientVersion >= EQ::versions::ClientVersion::Larion) {
eu->exp = (uint32)(100000.0f * tmpxp);
}
else {
eu->exp = (uint32)(330.0f * tmpxp);
}
FastQueuePacket(&outapp);
}
else {
eu->exp = 0;
FastQueuePacket(&outapp);
}
safe_delete(outapp);
SendAlternateAdvancementTimers();