mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 22:58:34 +00:00
Merge branch 'master' of https://github.com/EQEmu/Server
This commit is contained in:
@@ -149,6 +149,8 @@ public:
|
||||
static const uint32 BANDOLIER_SIZE = Titanium::consts::BANDOLIER_SIZE; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = Titanium::consts::POTION_BELT_SIZE;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 56;
|
||||
|
||||
// legacy-related functions
|
||||
//static int ServerToPerlSlot(int slot); // encode
|
||||
//static int PerlToServerSlot(int slot); // decode
|
||||
|
||||
@@ -5269,6 +5269,23 @@ struct ClientMarqueeMessage_Struct {
|
||||
|
||||
typedef std::list<ServerLootItem_Struct*> ItemList;
|
||||
|
||||
struct TextLinkBody_Struct {
|
||||
// Current server mask: EQClientRoF2
|
||||
uint8 unknown_1; /* %1X */
|
||||
uint32 item_id; /* %05X */
|
||||
uint32 augment_1; /* %05X */
|
||||
uint32 augment_2; /* %05X */
|
||||
uint32 augment_3; /* %05X */
|
||||
uint32 augment_4; /* %05X */
|
||||
uint32 augment_5; /* %05X */
|
||||
uint32 augment_6; /* %05X */
|
||||
uint8 is_evolving; /* %1X */
|
||||
uint32 evolve_group; /* %05X */
|
||||
uint8 evolve_level; /* %02X */
|
||||
uint32 ornament_icon; /* %05X */
|
||||
int hash; /* %08X */
|
||||
};
|
||||
|
||||
// Restore structure packing to default
|
||||
#pragma pack()
|
||||
|
||||
|
||||
+135
-45
@@ -33,6 +33,12 @@ namespace RoF
|
||||
static inline uint32 RoFToServerMainInvSlot(structs::MainInvItemSlotStruct RoFSlot);
|
||||
static inline uint32 RoFToServerCorpseSlot(uint32 RoFCorpse);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToRoFTextLink(std::string& rofTextLink, const std::string& serverTextLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void RoFToServerTextLink(std::string& serverTextLink, const std::string& rofTextLink);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@@ -488,7 +494,13 @@ namespace RoF
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToRoFTextLink(new_message, old_message);
|
||||
|
||||
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||
in->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
|
||||
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
@@ -501,7 +513,7 @@ namespace RoF
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->skill_in_language);
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->message);
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
@@ -3096,6 +3108,44 @@ namespace RoF
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SpecialMesg)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
ServerToRoFTextLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = 25 + strlen(emu->sayer) + new_message.length();
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_Stun)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Stun_Struct);
|
||||
@@ -4041,7 +4091,13 @@ namespace RoF
|
||||
|
||||
uint32 Skill = VARSTRUCT_DECODE_TYPE(uint32, InBuffer);
|
||||
|
||||
__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||
std::string old_message = InBuffer;
|
||||
std::string new_message;
|
||||
RoFToServerTextLink(new_message, old_message);
|
||||
|
||||
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
ChannelMessage_Struct *emu = (ChannelMessage_Struct *)__packet->pBuffer;
|
||||
|
||||
@@ -4050,7 +4106,7 @@ namespace RoF
|
||||
emu->language = Language;
|
||||
emu->chan_num = Channel;
|
||||
emu->skill_in_language = Skill;
|
||||
strcpy(emu->message, InBuffer);
|
||||
strcpy(emu->message, new_message.c_str());
|
||||
|
||||
delete[] __eq_buffer;
|
||||
}
|
||||
@@ -4456,47 +4512,8 @@ namespace RoF
|
||||
DECODE_LENGTH_EXACT(structs::PetCommand_Struct);
|
||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||
|
||||
switch (eq->command)
|
||||
{
|
||||
case 0x00:
|
||||
emu->command = 0x04; // Health
|
||||
break;
|
||||
case 0x01:
|
||||
emu->command = 0x10; // Leader
|
||||
break;
|
||||
case 0x02:
|
||||
emu->command = 0x07; // Attack
|
||||
break;
|
||||
case 0x04:
|
||||
emu->command = 0x08; // Follow
|
||||
break;
|
||||
case 0x05:
|
||||
emu->command = 0x05; // Guard
|
||||
break;
|
||||
case 0x06:
|
||||
emu->command = 0x09; // Sit. Needs work. This appears to be a toggle between Sit/Stand now.
|
||||
break;
|
||||
case 0x0c:
|
||||
emu->command = 0x0b; // Taunt
|
||||
break;
|
||||
case 0x0f:
|
||||
emu->command = 0x0c; // Hold
|
||||
break;
|
||||
case 0x10:
|
||||
emu->command = 0x1b; // Hold on
|
||||
break;
|
||||
case 0x11:
|
||||
emu->command = 0x1c; // Hold off
|
||||
break;
|
||||
case 0x1c:
|
||||
emu->command = 0x01; // Back
|
||||
break;
|
||||
case 0x1d:
|
||||
emu->command = 0x02; // Leave/Go Away
|
||||
break;
|
||||
default:
|
||||
emu->command = eq->command;
|
||||
}
|
||||
IN(command);
|
||||
emu->unknown = eq->unknown04;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@@ -5627,5 +5644,78 @@ namespace RoF
|
||||
{
|
||||
return (RoFCorpse - 1);
|
||||
}
|
||||
|
||||
static inline void ServerToRoFTextLink(std::string& rofTextLink, const std::string& serverTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find(delimiter) == std::string::npos)) {
|
||||
rofTextLink = serverTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// RoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (55)
|
||||
// Diff: ^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 41).c_str());
|
||||
|
||||
if (segments[segment_iter].substr(41, 1) == "0")
|
||||
new_segment.append(segments[segment_iter].substr(42, 1).c_str());
|
||||
else
|
||||
new_segment.append("F");
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(43).c_str());
|
||||
|
||||
rofTextLink.push_back(delimiter);
|
||||
rofTextLink.append(new_segment.c_str());
|
||||
rofTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
rofTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void RoFToServerTextLink(std::string& serverTextLink, const std::string& rofTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (rofTextLink.find(delimiter) == std::string::npos)) {
|
||||
serverTextLink = rofTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(rofTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 42 47 (Source)
|
||||
// RoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (55)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 41).c_str());
|
||||
new_segment.append("0");
|
||||
new_segment.append(segments[segment_iter].substr(41).c_str());
|
||||
|
||||
serverTextLink.push_back(delimiter);
|
||||
serverTextLink.append(new_segment.c_str());
|
||||
serverTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// end namespace RoF
|
||||
|
||||
+126
-45
@@ -33,6 +33,12 @@ namespace RoF2
|
||||
static inline uint32 RoF2ToServerMainInvSlot(structs::MainInvItemSlotStruct RoF2Slot);
|
||||
static inline uint32 RoF2ToServerCorpseSlot(uint32 RoF2Corpse);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToRoF2TextLink(std::string& rof2TextLink, const std::string& serverTextLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void RoF2ToServerTextLink(std::string& serverTextLink, const std::string& rof2TextLink);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@@ -554,7 +560,13 @@ namespace RoF2
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToRoF2TextLink(new_message, old_message);
|
||||
|
||||
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||
in->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
|
||||
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
@@ -567,7 +579,7 @@ namespace RoF2
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->skill_in_language);
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->message);
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
@@ -3162,6 +3174,44 @@ namespace RoF2
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SpecialMesg)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
ServerToRoF2TextLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = 25 + strlen(emu->sayer) + new_message.length();
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_Stun)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Stun_Struct);
|
||||
@@ -4113,7 +4163,13 @@ namespace RoF2
|
||||
|
||||
uint32 Skill = VARSTRUCT_DECODE_TYPE(uint32, InBuffer);
|
||||
|
||||
__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||
std::string old_message = InBuffer;
|
||||
std::string new_message;
|
||||
RoF2ToServerTextLink(new_message, old_message);
|
||||
|
||||
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
ChannelMessage_Struct *emu = (ChannelMessage_Struct *)__packet->pBuffer;
|
||||
|
||||
@@ -4122,7 +4178,7 @@ namespace RoF2
|
||||
emu->language = Language;
|
||||
emu->chan_num = Channel;
|
||||
emu->skill_in_language = Skill;
|
||||
strcpy(emu->message, InBuffer);
|
||||
strcpy(emu->message, new_message.c_str());
|
||||
|
||||
delete[] __eq_buffer;
|
||||
}
|
||||
@@ -4527,47 +4583,8 @@ namespace RoF2
|
||||
DECODE_LENGTH_EXACT(structs::PetCommand_Struct);
|
||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||
|
||||
switch (eq->command)
|
||||
{
|
||||
case 0x00:
|
||||
emu->command = 0x04; // Health
|
||||
break;
|
||||
case 0x01:
|
||||
emu->command = 0x10; // Leader
|
||||
break;
|
||||
case 0x02:
|
||||
emu->command = 0x07; // Attack
|
||||
break;
|
||||
case 0x04:
|
||||
emu->command = 0x08; // Follow
|
||||
break;
|
||||
case 0x05:
|
||||
emu->command = 0x05; // Guard
|
||||
break;
|
||||
case 0x06:
|
||||
emu->command = 0x09; // Sit. Needs work. This appears to be a toggle between Sit/Stand now.
|
||||
break;
|
||||
case 0x0c:
|
||||
emu->command = 0x0b; // Taunt
|
||||
break;
|
||||
case 0x0f:
|
||||
emu->command = 0x0c; // Hold
|
||||
break;
|
||||
case 0x10:
|
||||
emu->command = 0x1b; // Hold on
|
||||
break;
|
||||
case 0x11:
|
||||
emu->command = 0x1c; // Hold off
|
||||
break;
|
||||
case 0x1c:
|
||||
emu->command = 0x01; // Back
|
||||
break;
|
||||
case 0x1d:
|
||||
emu->command = 0x02; // Leave/Go Away
|
||||
break;
|
||||
default:
|
||||
emu->command = eq->command;
|
||||
}
|
||||
IN(command);
|
||||
emu->unknown = eq->unknown04;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@@ -5722,5 +5739,69 @@ namespace RoF2
|
||||
{
|
||||
return (RoF2Corpse + EmuConstants::CORPSE_BEGIN - 1);
|
||||
}
|
||||
|
||||
static inline void ServerToRoF2TextLink(std::string& rof2TextLink, const std::string& serverTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find(delimiter) == std::string::npos)) {
|
||||
rof2TextLink = serverTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff:
|
||||
|
||||
new_segment.append(segments[segment_iter]);
|
||||
|
||||
rof2TextLink.push_back(delimiter);
|
||||
rof2TextLink.append(new_segment.c_str());
|
||||
rof2TextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
rof2TextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void RoF2ToServerTextLink(std::string& serverTextLink, const std::string& rof2TextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (rof2TextLink.find(delimiter) == std::string::npos)) {
|
||||
serverTextLink = rof2TextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(rof2TextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff:
|
||||
|
||||
new_segment.append(segments[segment_iter]);
|
||||
|
||||
serverTextLink.push_back(delimiter);
|
||||
serverTextLink.append(new_segment.c_str());
|
||||
serverTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// end namespace RoF2
|
||||
|
||||
@@ -181,6 +181,8 @@ namespace RoF2 {
|
||||
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 5;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 56;
|
||||
}
|
||||
|
||||
namespace limits {
|
||||
|
||||
@@ -95,6 +95,7 @@ E(OP_SkillUpdate)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnAppearance)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_SpecialMesg)
|
||||
E(OP_Stun)
|
||||
E(OP_TargetBuffs)
|
||||
E(OP_TaskDescription)
|
||||
|
||||
@@ -180,6 +180,8 @@ namespace RoF {
|
||||
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 5;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 55;
|
||||
}
|
||||
|
||||
namespace limits {
|
||||
|
||||
@@ -84,6 +84,7 @@ E(OP_SkillUpdate)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnAppearance)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_SpecialMesg)
|
||||
E(OP_Stun)
|
||||
E(OP_TargetBuffs)
|
||||
E(OP_TaskDescription)
|
||||
|
||||
@@ -31,6 +31,12 @@ namespace SoD
|
||||
static inline uint32 SoDToServerSlot(uint32 SoDSlot);
|
||||
static inline uint32 SoDToServerCorpseSlot(uint32 SoDCorpse);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToSoDTextLink(std::string& sodTextLink, const std::string& serverTextLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void SoDToServerTextLink(std::string& serverTextLink, const std::string& sodTextLink);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@@ -296,6 +302,35 @@ namespace SoD
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ChannelMessage)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
ChannelMessage_Struct *emu = (ChannelMessage_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToSoDTextLink(new_message, old_message);
|
||||
|
||||
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
memcpy(OutBuffer, __emu_buffer, sizeof(ChannelMessage_Struct));
|
||||
|
||||
OutBuffer += sizeof(ChannelMessage_Struct);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_CharInventory)
|
||||
{
|
||||
//consume the packet
|
||||
@@ -1963,6 +1998,44 @@ namespace SoD
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SpecialMesg)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
ServerToSoDTextLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = 25 + strlen(emu->sayer) + new_message.length();
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_Stun)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Stun_Struct);
|
||||
@@ -2729,6 +2802,25 @@ namespace SoD
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ChannelMessage)
|
||||
{
|
||||
unsigned char *__eq_buffer = __packet->pBuffer;
|
||||
|
||||
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
|
||||
std::string new_message;
|
||||
SoDToServerTextLink(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;
|
||||
|
||||
memcpy(emu, __eq_buffer, sizeof(ChannelMessage_Struct));
|
||||
strcpy(emu->message, new_message.c_str());
|
||||
|
||||
delete[] __eq_buffer;
|
||||
}
|
||||
|
||||
DECODE(OP_CharacterCreate)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::CharCreate_Struct);
|
||||
@@ -3007,6 +3099,89 @@ namespace SoD
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_PetCommands)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::PetCommand_Struct);
|
||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||
|
||||
switch (eq->command)
|
||||
{
|
||||
case 0x04:
|
||||
emu->command = 0x00; // /pet health
|
||||
break;
|
||||
case 0x10:
|
||||
emu->command = 0x01; // /pet leader
|
||||
break;
|
||||
case 0x07:
|
||||
emu->command = 0x02; // /pet attack or Pet Window
|
||||
break;
|
||||
case 0x03: // Case Guessed
|
||||
emu->command = 0x03; // /pet qattack
|
||||
case 0x08:
|
||||
emu->command = 0x04; // /pet follow or Pet Window
|
||||
break;
|
||||
case 0x05:
|
||||
emu->command = 0x05; // /pet guard or Pet Window
|
||||
break;
|
||||
case 0x09:
|
||||
emu->command = 0x07; // /pet sit or Pet Window
|
||||
break;
|
||||
case 0x0a:
|
||||
emu->command = 0x08; // /pet stand or Pet Window
|
||||
break;
|
||||
case 0x06:
|
||||
emu->command = 0x1e; // /pet guard me
|
||||
break;
|
||||
case 0x0f: // Case Made Up
|
||||
emu->command = 0x09; // /pet stop
|
||||
break;
|
||||
case 0x0b:
|
||||
emu->command = 0x0d; // /pet taunt or Pet Window
|
||||
break;
|
||||
case 0x0e:
|
||||
emu->command = 0x0e; // /pet notaunt or Pet Window
|
||||
break;
|
||||
case 0x0c:
|
||||
emu->command = 0x0f; // /pet hold
|
||||
break;
|
||||
case 0x1b:
|
||||
emu->command = 0x10; // /pet hold on
|
||||
break;
|
||||
case 0x1c:
|
||||
emu->command = 0x11; // /pet hold off
|
||||
break;
|
||||
case 0x11:
|
||||
emu->command = 0x12; // Slumber?
|
||||
break;
|
||||
case 0x12:
|
||||
emu->command = 0x15; // /pet no cast
|
||||
break;
|
||||
case 0x0d: // Case Made Up
|
||||
emu->command = 0x16; // Pet Window No Cast
|
||||
break;
|
||||
case 0x13:
|
||||
emu->command = 0x18; // /pet focus
|
||||
break;
|
||||
case 0x19:
|
||||
emu->command = 0x19; // /pet focus on
|
||||
break;
|
||||
case 0x1a:
|
||||
emu->command = 0x1a; // /pet focus off
|
||||
break;
|
||||
case 0x01:
|
||||
emu->command = 0x1c; // /pet back off
|
||||
break;
|
||||
case 0x02:
|
||||
emu->command = 0x1d; // /pet get lost
|
||||
break;
|
||||
default:
|
||||
emu->command = eq->command;
|
||||
}
|
||||
OUT(unknown);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_RaidInvite)
|
||||
{
|
||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||
@@ -3683,5 +3858,81 @@ namespace SoD
|
||||
//uint32 ServerCorpse;
|
||||
return (SoDCorpse - 1);
|
||||
}
|
||||
|
||||
static inline void ServerToSoDTextLink(std::string& sodTextLink, const std::string& serverTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find(delimiter) == std::string::npos)) {
|
||||
sodTextLink = serverTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 31).c_str());
|
||||
new_segment.append(segments[segment_iter].substr(36, 5).c_str());
|
||||
|
||||
if (segments[segment_iter].substr(41, 1) == "0")
|
||||
new_segment.append(segments[segment_iter].substr(42, 1).c_str());
|
||||
else
|
||||
new_segment.append("F");
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(43).c_str());
|
||||
|
||||
sodTextLink.push_back(delimiter);
|
||||
sodTextLink.append(new_segment.c_str());
|
||||
sodTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
sodTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SoDToServerTextLink(std::string& serverTextLink, const std::string& sodTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (sodTextLink.find(delimiter) == std::string::npos)) {
|
||||
serverTextLink = sodTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(sodTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 32 36 37 42 (Source)
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 31).c_str());
|
||||
new_segment.append("00000");
|
||||
new_segment.append(segments[segment_iter].substr(31, 5).c_str());
|
||||
new_segment.append("0");
|
||||
new_segment.append(segments[segment_iter].substr(36).c_str());
|
||||
|
||||
serverTextLink.push_back(delimiter);
|
||||
serverTextLink.append(new_segment.c_str());
|
||||
serverTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// end namespace SoD
|
||||
|
||||
@@ -177,6 +177,8 @@ namespace SoD {
|
||||
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 5;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 50;
|
||||
}
|
||||
|
||||
namespace limits {
|
||||
|
||||
@@ -8,6 +8,7 @@ E(OP_Barter)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_Buff)
|
||||
E(OP_CancelTrade)
|
||||
E(OP_ChannelMessage)
|
||||
E(OP_CharInventory)
|
||||
E(OP_ClientUpdate)
|
||||
E(OP_Consider)
|
||||
@@ -57,6 +58,7 @@ E(OP_ShopPlayerBuy)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_SpecialMesg)
|
||||
E(OP_Stun)
|
||||
E(OP_TargetBuffs)
|
||||
E(OP_Track)
|
||||
@@ -81,6 +83,7 @@ D(OP_BazaarSearch)
|
||||
D(OP_Buff)
|
||||
D(OP_Bug)
|
||||
D(OP_CastSpell)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_ClientUpdate)
|
||||
D(OP_Consider)
|
||||
@@ -101,6 +104,7 @@ D(OP_ItemVerifyRequest)
|
||||
D(OP_LoadSpellSet)
|
||||
D(OP_LootItem)
|
||||
D(OP_MoveItem)
|
||||
D(OP_PetCommands)
|
||||
D(OP_RaidInvite)
|
||||
D(OP_ReadBook)
|
||||
D(OP_Save)
|
||||
|
||||
@@ -4409,7 +4409,6 @@ struct MercenaryAssign_Struct {
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
|
||||
}; //end namespace structs
|
||||
}; //end namespace SoD
|
||||
|
||||
|
||||
@@ -31,6 +31,12 @@ namespace SoF
|
||||
static inline uint32 SoFToServerSlot(uint32 SoFSlot);
|
||||
static inline uint32 SoFToServerCorpseSlot(uint32 SoFCorpse);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToSoFTextLink(std::string& sofTextLink, const std::string& serverTextLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void SoFToServerTextLink(std::string& serverTextLink, const std::string& sofTextLink);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@@ -278,6 +284,35 @@ namespace SoF
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ChannelMessage)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
ChannelMessage_Struct *emu = (ChannelMessage_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToSoFTextLink(new_message, old_message);
|
||||
|
||||
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
memcpy(OutBuffer, __emu_buffer, sizeof(ChannelMessage_Struct));
|
||||
|
||||
OutBuffer += sizeof(ChannelMessage_Struct);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_CharInventory)
|
||||
{
|
||||
//consume the packet
|
||||
@@ -1609,6 +1644,44 @@ namespace SoF
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SpecialMesg)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
ServerToSoFTextLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = 25 + strlen(emu->sayer) + new_message.length();
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_Stun)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Stun_Struct);
|
||||
@@ -2129,6 +2202,25 @@ namespace SoF
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ChannelMessage)
|
||||
{
|
||||
unsigned char *__eq_buffer = __packet->pBuffer;
|
||||
|
||||
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
|
||||
std::string new_message;
|
||||
SoFToServerTextLink(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;
|
||||
|
||||
memcpy(emu, __eq_buffer, sizeof(ChannelMessage_Struct));
|
||||
strcpy(emu->message, new_message.c_str());
|
||||
|
||||
delete[] __eq_buffer;
|
||||
}
|
||||
|
||||
DECODE(OP_CharacterCreate)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::CharCreate_Struct);
|
||||
@@ -2345,6 +2437,89 @@ namespace SoF
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_PetCommands)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::PetCommand_Struct);
|
||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||
|
||||
switch (eq->command)
|
||||
{
|
||||
case 0x04:
|
||||
emu->command = 0x00; // /pet health
|
||||
break;
|
||||
case 0x10:
|
||||
emu->command = 0x01; // /pet leader
|
||||
break;
|
||||
case 0x07:
|
||||
emu->command = 0x02; // /pet attack or Pet Window
|
||||
break;
|
||||
case 0x03: // Case Guessed
|
||||
emu->command = 0x03; // /pet qattack
|
||||
case 0x08:
|
||||
emu->command = 0x04; // /pet follow or Pet Window
|
||||
break;
|
||||
case 0x05:
|
||||
emu->command = 0x05; // /pet guard or Pet Window
|
||||
break;
|
||||
case 0x09:
|
||||
emu->command = 0x07; // /pet sit or Pet Window
|
||||
break;
|
||||
case 0x0a:
|
||||
emu->command = 0x08; // /pet stand or Pet Window
|
||||
break;
|
||||
case 0x06:
|
||||
emu->command = 0x1e; // /pet guard me
|
||||
break;
|
||||
case 0x0f: // Case Made Up
|
||||
emu->command = 0x09; // Stop?
|
||||
break;
|
||||
case 0x0b:
|
||||
emu->command = 0x0d; // /pet taunt or Pet Window
|
||||
break;
|
||||
case 0x0e:
|
||||
emu->command = 0x0e; // /pet notaunt or Pet Window
|
||||
break;
|
||||
case 0x0c:
|
||||
emu->command = 0x0f; // /pet hold
|
||||
break;
|
||||
case 0x1b:
|
||||
emu->command = 0x10; // /pet hold on
|
||||
break;
|
||||
case 0x1c:
|
||||
emu->command = 0x11; // /pet hold off
|
||||
break;
|
||||
case 0x11:
|
||||
emu->command = 0x12; // Slumber?
|
||||
break;
|
||||
case 0x12:
|
||||
emu->command = 0x15; // /pet no cast
|
||||
break;
|
||||
case 0x0d: // Case Made Up
|
||||
emu->command = 0x16; // Pet Window No Cast
|
||||
break;
|
||||
case 0x13:
|
||||
emu->command = 0x18; // /pet focus
|
||||
break;
|
||||
case 0x19:
|
||||
emu->command = 0x19; // /pet focus on
|
||||
break;
|
||||
case 0x1a:
|
||||
emu->command = 0x1a; // /pet focus off
|
||||
break;
|
||||
case 0x01:
|
||||
emu->command = 0x1c; // /pet back off
|
||||
break;
|
||||
case 0x02:
|
||||
emu->command = 0x1d; // /pet get lost
|
||||
break;
|
||||
default:
|
||||
emu->command = eq->command;
|
||||
}
|
||||
OUT(unknown);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_RaidInvite)
|
||||
{
|
||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||
@@ -3005,5 +3180,81 @@ namespace SoF
|
||||
//uint32 ServerCorpse;
|
||||
return (SoFCorpse - 1);
|
||||
}
|
||||
|
||||
static inline void ServerToSoFTextLink(std::string& sofTextLink, const std::string& serverTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find(delimiter) == std::string::npos)) {
|
||||
sofTextLink = serverTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 31).c_str());
|
||||
new_segment.append(segments[segment_iter].substr(36, 5).c_str());
|
||||
|
||||
if (segments[segment_iter].substr(41, 1) == "0")
|
||||
new_segment.append(segments[segment_iter].substr(42, 1).c_str());
|
||||
else
|
||||
new_segment.append("F");
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(43).c_str());
|
||||
|
||||
sofTextLink.push_back(delimiter);
|
||||
sofTextLink.append(new_segment.c_str());
|
||||
sofTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
sofTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SoFToServerTextLink(std::string& serverTextLink, const std::string& sofTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (sofTextLink.find(delimiter) == std::string::npos)) {
|
||||
serverTextLink = sofTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(sofTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 32 36 37 42 (Source)
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 31).c_str());
|
||||
new_segment.append("00000");
|
||||
new_segment.append(segments[segment_iter].substr(31, 5).c_str());
|
||||
new_segment.append("0");
|
||||
new_segment.append(segments[segment_iter].substr(36).c_str());
|
||||
|
||||
serverTextLink.push_back(delimiter);
|
||||
serverTextLink.append(new_segment.c_str());
|
||||
serverTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// end namespace SoF
|
||||
|
||||
@@ -177,6 +177,8 @@ namespace SoF {
|
||||
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 5;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 50;
|
||||
}
|
||||
|
||||
namespace limits {
|
||||
|
||||
@@ -8,6 +8,7 @@ E(OP_BazaarSearch)
|
||||
E(OP_BecomeTrader)
|
||||
E(OP_Buff)
|
||||
E(OP_CancelTrade)
|
||||
E(OP_ChannelMessage)
|
||||
E(OP_CharInventory)
|
||||
E(OP_ClientUpdate)
|
||||
E(OP_Consider)
|
||||
@@ -50,6 +51,7 @@ E(OP_SendZonepoints)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_SpecialMesg)
|
||||
E(OP_Stun)
|
||||
E(OP_Track)
|
||||
E(OP_Trader)
|
||||
@@ -70,6 +72,7 @@ D(OP_AugmentInfo)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_Buff)
|
||||
D(OP_CastSpell)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_ClientUpdate)
|
||||
D(OP_Consider)
|
||||
@@ -85,6 +88,7 @@ D(OP_ItemLinkClick)
|
||||
D(OP_ItemVerifyRequest)
|
||||
D(OP_LootItem)
|
||||
D(OP_MoveItem)
|
||||
D(OP_PetCommands)
|
||||
D(OP_RaidInvite)
|
||||
D(OP_ReadBook)
|
||||
D(OP_Save)
|
||||
|
||||
@@ -4115,18 +4115,7 @@ struct AltCurrencySellItem_Struct {
|
||||
/*010*/ uint32 cost;
|
||||
};
|
||||
|
||||
|
||||
}; //end namespace structs
|
||||
}; //end namespace SoF
|
||||
|
||||
#endif /*SoF_STRUCTS_H_*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "../races.h"
|
||||
|
||||
#include "../eq_packet_structs.h"
|
||||
#include "../misc_functions.h"
|
||||
#include "../string_util.h"
|
||||
#include "../item.h"
|
||||
#include "titanium_structs.h"
|
||||
@@ -28,6 +29,12 @@ namespace Titanium
|
||||
static inline uint32 TitaniumToServerSlot(int16 TitaniumSlot);
|
||||
static inline uint32 TitaniumToServerCorpseSlot(int16 TitaniumCorpse);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToTitaniumTextLink(std::string& titaniumTextLink, const std::string& serverTextLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void TitaniumToServerTextLink(std::string& serverTextLink, const std::string& titaniumTextLink);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@@ -220,6 +227,35 @@ namespace Titanium
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ChannelMessage)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
ChannelMessage_Struct *emu = (ChannelMessage_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToTitaniumTextLink(new_message, old_message);
|
||||
|
||||
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
memcpy(OutBuffer, __emu_buffer, sizeof(ChannelMessage_Struct));
|
||||
|
||||
OutBuffer += sizeof(ChannelMessage_Struct);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_CharInventory)
|
||||
{
|
||||
//consume the packet
|
||||
@@ -1070,6 +1106,44 @@ namespace Titanium
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SpecialMesg)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
ServerToTitaniumTextLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = 25 + strlen(emu->sayer) + new_message.length();
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_Track)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
@@ -1371,6 +1445,25 @@ namespace Titanium
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ChannelMessage)
|
||||
{
|
||||
unsigned char *__eq_buffer = __packet->pBuffer;
|
||||
|
||||
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
|
||||
std::string new_message;
|
||||
TitaniumToServerTextLink(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;
|
||||
|
||||
memcpy(emu, __eq_buffer, sizeof(ChannelMessage_Struct));
|
||||
strcpy(emu->message, new_message.c_str());
|
||||
|
||||
delete[] __eq_buffer;
|
||||
}
|
||||
|
||||
DECODE(OP_CharacterCreate)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::CharCreate_Struct);
|
||||
@@ -1538,6 +1631,89 @@ namespace Titanium
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_PetCommands)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::PetCommand_Struct);
|
||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||
|
||||
switch (eq->command)
|
||||
{
|
||||
case 0x04:
|
||||
emu->command = 0x00; // /pet health
|
||||
break;
|
||||
case 0x10:
|
||||
emu->command = 0x01; // /pet leader
|
||||
break;
|
||||
case 0x07:
|
||||
emu->command = 0x02; // /pet attack or Pet Window
|
||||
break;
|
||||
case 0x03: // Case Guessed
|
||||
emu->command = 0x03; // /pet qattack
|
||||
case 0x08:
|
||||
emu->command = 0x04; // /pet follow or Pet Window
|
||||
break;
|
||||
case 0x05:
|
||||
emu->command = 0x05; // /pet guard or Pet Window
|
||||
break;
|
||||
case 0x09:
|
||||
emu->command = 0x07; // /pet sit or Pet Window
|
||||
break;
|
||||
case 0x0a:
|
||||
emu->command = 0x08; // /pet stand or Pet Window
|
||||
break;
|
||||
case 0x06:
|
||||
emu->command = 0x1e; // /pet guard me
|
||||
break;
|
||||
case 0x0f: // Case Made Up
|
||||
emu->command = 0x09; // Stop?
|
||||
break;
|
||||
case 0x0b:
|
||||
emu->command = 0x0d; // /pet taunt or Pet Window
|
||||
break;
|
||||
case 0x0e:
|
||||
emu->command = 0x0e; // /pet notaunt or Pet Window
|
||||
break;
|
||||
case 0x0c:
|
||||
emu->command = 0x0f; // /pet hold
|
||||
break;
|
||||
case 0x1b:
|
||||
emu->command = 0x10; // /pet hold on
|
||||
break;
|
||||
case 0x1c:
|
||||
emu->command = 0x11; // /pet hold off
|
||||
break;
|
||||
case 0x11:
|
||||
emu->command = 0x12; // Slumber?
|
||||
break;
|
||||
case 0x12:
|
||||
emu->command = 0x15; // /pet no cast
|
||||
break;
|
||||
case 0x0d: // Case Made Up
|
||||
emu->command = 0x16; // Pet Window No Cast
|
||||
break;
|
||||
case 0x13:
|
||||
emu->command = 0x18; // /pet focus
|
||||
break;
|
||||
case 0x19:
|
||||
emu->command = 0x19; // /pet focus on
|
||||
break;
|
||||
case 0x1a:
|
||||
emu->command = 0x1a; // /pet focus off
|
||||
break;
|
||||
case 0x01:
|
||||
emu->command = 0x1c; // /pet back off
|
||||
break;
|
||||
case 0x02:
|
||||
emu->command = 0x1d; // /pet get lost
|
||||
break;
|
||||
default:
|
||||
emu->command = eq->command;
|
||||
}
|
||||
OUT(unknown);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ReadBook)
|
||||
{
|
||||
// no apparent slot translation needed -U
|
||||
@@ -1763,5 +1939,83 @@ namespace Titanium
|
||||
//uint32 ServerCorpse;
|
||||
return TitaniumCorpse;
|
||||
}
|
||||
|
||||
static inline void ServerToTitaniumTextLink(std::string& titaniumTextLink, const std::string& serverTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find(delimiter) == std::string::npos)) {
|
||||
titaniumTextLink = serverTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// 6.2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXXXXX (45)
|
||||
// Diff: ^^^^^ ^ ^^^^^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 31).c_str());
|
||||
new_segment.append(segments[segment_iter].substr(36, 5).c_str());
|
||||
|
||||
if (segments[segment_iter].substr(41, 1) == "0")
|
||||
new_segment.append(segments[segment_iter].substr(42, 1).c_str());
|
||||
else
|
||||
new_segment.append("F");
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(48).c_str());
|
||||
|
||||
titaniumTextLink.push_back(delimiter);
|
||||
titaniumTextLink.append(new_segment.c_str());
|
||||
titaniumTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
titaniumTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void TitaniumToServerTextLink(std::string& serverTextLink, const std::string& titaniumTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (titaniumTextLink.find(delimiter) == std::string::npos)) {
|
||||
serverTextLink = titaniumTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(titaniumTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 32 36 37 (Source)
|
||||
// 6.2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXXXXX (45)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^^^^^ ^ ^^^^^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 31).c_str());
|
||||
new_segment.append("00000");
|
||||
new_segment.append(segments[segment_iter].substr(31, 5).c_str());
|
||||
new_segment.append("0");
|
||||
new_segment.append(segments[segment_iter].substr(36, 1).c_str());
|
||||
new_segment.append("00000");
|
||||
new_segment.append(segments[segment_iter].substr(37).c_str());
|
||||
|
||||
serverTextLink.push_back(delimiter);
|
||||
serverTextLink.append(new_segment.c_str());
|
||||
serverTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// end namespace Titanium
|
||||
|
||||
@@ -176,6 +176,8 @@ namespace Titanium {
|
||||
static const uint32 BANDOLIERS_COUNT = 4; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 4;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 45;
|
||||
}
|
||||
|
||||
namespace limits {
|
||||
|
||||
@@ -4,6 +4,7 @@ E(OP_AdventureMerchantSell)
|
||||
E(OP_ApplyPoison)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_BecomeTrader)
|
||||
E(OP_ChannelMessage)
|
||||
E(OP_CharInventory)
|
||||
E(OP_DeleteCharge)
|
||||
E(OP_DeleteItem)
|
||||
@@ -35,6 +36,7 @@ E(OP_RespondAA)
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_SendAATable)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_SpecialMesg)
|
||||
E(OP_Track)
|
||||
E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
@@ -49,6 +51,7 @@ D(OP_AdventureMerchantSell)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_CastSpell)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_Consume)
|
||||
D(OP_DeleteItem)
|
||||
@@ -59,6 +62,7 @@ D(OP_ItemLinkClick)
|
||||
D(OP_LFGuild)
|
||||
D(OP_LootItem)
|
||||
D(OP_MoveItem)
|
||||
D(OP_PetCommands)
|
||||
D(OP_ReadBook)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerSell)
|
||||
|
||||
@@ -3332,16 +3332,4 @@ struct LFGuild_GuildToggle_Struct
|
||||
}; //end namespace structs
|
||||
}; //end namespace Titanium
|
||||
|
||||
|
||||
|
||||
#endif /*Titanium_STRUCTS_H_*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+137
-55
@@ -31,6 +31,12 @@ namespace Underfoot
|
||||
static inline uint32 UnderfootToServerSlot(uint32 UnderfootSlot);
|
||||
static inline uint32 UnderfootToServerCorpseSlot(uint32 UnderfootCorpse);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToUnderfootTextLink(std::string& underfootTextLink, const std::string& serverTextLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void UnderfootToServerTextLink(std::string& serverTextLink, const std::string& underfootTextLink);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@@ -432,7 +438,12 @@ namespace Underfoot
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToUnderfootTextLink(new_message, old_message);
|
||||
|
||||
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||
in->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
|
||||
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
@@ -446,7 +457,7 @@ namespace Underfoot
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->skill_in_language);
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->message);
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
@@ -2298,6 +2309,44 @@ namespace Underfoot
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SpecialMesg)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
ServerToUnderfootTextLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = 25 + strlen(emu->sayer) + new_message.length();
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_Stun)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Stun_Struct);
|
||||
@@ -3036,7 +3085,13 @@ namespace Underfoot
|
||||
|
||||
uint32 Skill = VARSTRUCT_DECODE_TYPE(uint32, InBuffer);
|
||||
|
||||
__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||
std::string old_message = InBuffer;
|
||||
std::string new_message;
|
||||
UnderfootToServerTextLink(new_message, old_message);
|
||||
|
||||
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
ChannelMessage_Struct *emu = (ChannelMessage_Struct *)__packet->pBuffer;
|
||||
|
||||
@@ -3045,7 +3100,7 @@ namespace Underfoot
|
||||
emu->language = Language;
|
||||
emu->chan_num = Channel;
|
||||
emu->skill_in_language = Skill;
|
||||
strcpy(emu->message, InBuffer);
|
||||
strcpy(emu->message, new_message.c_str());
|
||||
|
||||
delete[] __eq_buffer;
|
||||
}
|
||||
@@ -3364,57 +3419,8 @@ namespace Underfoot
|
||||
DECODE_LENGTH_EXACT(structs::PetCommand_Struct);
|
||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||
|
||||
switch (eq->command)
|
||||
{
|
||||
case 0x00:
|
||||
emu->command = 0x04; // Health
|
||||
break;
|
||||
case 0x01:
|
||||
emu->command = 0x10; // Leader
|
||||
break;
|
||||
case 0x02:
|
||||
emu->command = 0x07; // Attack
|
||||
break;
|
||||
case 0x04:
|
||||
emu->command = 0x08; // Follow
|
||||
break;
|
||||
case 0x05:
|
||||
emu->command = 0x05; // Guard
|
||||
break;
|
||||
case 0x06:
|
||||
emu->command = 0x09; // Sit. Needs work. This appears to be a toggle between Sit/Stand now.
|
||||
break;
|
||||
case 0x0c:
|
||||
emu->command = 0x0b; // Taunt
|
||||
break;
|
||||
case 0x0f:
|
||||
emu->command = 0x0c; // Hold
|
||||
break;
|
||||
case 0x10:
|
||||
emu->command = 0x1b; // Hold on
|
||||
break;
|
||||
case 0x11:
|
||||
emu->command = 0x1c; // Hold off
|
||||
break;
|
||||
case 0x1c:
|
||||
emu->command = 0x01; // Back
|
||||
break;
|
||||
case 0x1d:
|
||||
emu->command = 0x02; // Leave/Go Away
|
||||
break;
|
||||
case 0x15:
|
||||
emu->command = 0x12; // No Cast - /command
|
||||
break;
|
||||
case 0x16:
|
||||
emu->command = 0x12; // No Cast - Pet Window
|
||||
break;
|
||||
case 0x18:
|
||||
emu->command = 0x13; // Focus - Pet Window
|
||||
break;
|
||||
default:
|
||||
emu->command = eq->command;
|
||||
}
|
||||
OUT(unknown);
|
||||
IN(command);
|
||||
IN(unknown);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@@ -4155,5 +4161,81 @@ namespace Underfoot
|
||||
//uint32 ServerCorpse;
|
||||
return (UnderfootCorpse - 1);
|
||||
}
|
||||
|
||||
static inline void ServerToUnderfootTextLink(std::string& underfootTextLink, const std::string& serverTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find(delimiter) == std::string::npos)) {
|
||||
underfootTextLink = serverTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 31).c_str());
|
||||
new_segment.append(segments[segment_iter].substr(36, 5).c_str());
|
||||
|
||||
if (segments[segment_iter].substr(41, 1) == "0")
|
||||
new_segment.append(segments[segment_iter].substr(42, 1).c_str());
|
||||
else
|
||||
new_segment.append("F");
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(43).c_str());
|
||||
|
||||
underfootTextLink.push_back(delimiter);
|
||||
underfootTextLink.append(new_segment.c_str());
|
||||
underfootTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
underfootTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void UnderfootToServerTextLink(std::string& serverTextLink, const std::string& underfootTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (underfootTextLink.find(delimiter) == std::string::npos)) {
|
||||
serverTextLink = underfootTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(underfootTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 32 36 37 42 (Source)
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 31).c_str());
|
||||
new_segment.append("00000");
|
||||
new_segment.append(segments[segment_iter].substr(31, 5).c_str());
|
||||
new_segment.append("0");
|
||||
new_segment.append(segments[segment_iter].substr(36).c_str());
|
||||
|
||||
serverTextLink.push_back(delimiter);
|
||||
serverTextLink.append(new_segment.c_str());
|
||||
serverTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// end namespace Underfoot
|
||||
|
||||
@@ -177,6 +177,8 @@ namespace Underfoot {
|
||||
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 5;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 50;
|
||||
}
|
||||
|
||||
namespace limits {
|
||||
|
||||
@@ -65,6 +65,7 @@ E(OP_ShopPlayerSell)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnAppearance)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_SpecialMesg)
|
||||
E(OP_Stun)
|
||||
E(OP_TargetBuffs)
|
||||
E(OP_Track)
|
||||
|
||||
Reference in New Issue
Block a user