Merge remote-tracking branch 'remotes/origin/master' into logging_changes

Conflicts:
	zone/command.cpp
	zone/command.h
	zone/inventory.cpp
This commit is contained in:
Akkadius
2015-01-21 16:40:46 -06:00
37 changed files with 6196 additions and 3324 deletions
+1 -1
View File
@@ -2388,7 +2388,7 @@ struct AugmentItem_Struct {
// OP_Emote
struct Emote_Struct {
/*0000*/ uint32 unknown01;
/*0000*/ uint32 type; // 0 - custom, 0xffffffff - command (/dance, /flip, etc...)
/*0004*/ char message[1024];
/*1028*/
};
+394 -387
View File
File diff suppressed because it is too large Load Diff
+20 -18
View File
@@ -34,7 +34,6 @@ class EvolveInfo; // Stores information about an evolving item family
#include <map>
// Helper typedefs
typedef std::list<ItemInst*>::const_iterator iter_queue;
typedef std::map<int16, ItemInst*>::const_iterator iter_inst;
typedef std::map<uint8, ItemInst*>::const_iterator iter_contents;
@@ -87,15 +86,17 @@ public:
// Public Methods
/////////////////////////
inline iter_queue begin() { return m_list.begin(); }
inline iter_queue end() { return m_list.end(); }
inline std::list<ItemInst*>::const_iterator begin() { return m_list.begin(); }
inline std::list<ItemInst*>::const_iterator end() { return m_list.end(); }
inline int size() { return static_cast<int>(m_list.size()); } // TODO: change to size_t
inline bool empty() { return m_list.empty(); }
void push(ItemInst* inst);
void push_front(ItemInst* inst);
ItemInst* pop();
ItemInst* pop_back();
ItemInst* peek_front() const;
inline int size() { return static_cast<int>(m_list.size()); }
protected:
/////////////////////////
@@ -103,7 +104,6 @@ protected:
/////////////////////////
std::list<ItemInst*> m_list;
};
// ########################################
@@ -140,9 +140,11 @@ public:
ItemInst* GetItem(int16 slot_id) const;
ItemInst* GetItem(int16 slot_id, uint8 bagidx) const;
inline iter_queue cursor_begin() { return m_cursor.begin(); }
inline iter_queue cursor_end() { return m_cursor.end(); }
inline bool CursorEmpty() { return (m_cursor.size() == 0); }
inline std::list<ItemInst*>::const_iterator cursor_begin() { return m_cursor.begin(); }
inline std::list<ItemInst*>::const_iterator cursor_end() { return m_cursor.end(); }
inline int CursorSize() { return m_cursor.size(); }
inline bool CursorEmpty() { return m_cursor.empty(); }
// Retrieve a read-only item from inventory
inline const ItemInst* operator[](int16 slot_id) const { return GetItem(slot_id); }
@@ -291,15 +293,15 @@ public:
bool IsEquipable(int16 slot_id) const;
//
// Augements
// Augments
//
inline bool IsAugmentable() const { return m_item->AugSlotType[0] != 0 || m_item->AugSlotType[1] != 0 || m_item->AugSlotType[2] != 0 || m_item->AugSlotType[3] != 0 || m_item->AugSlotType[4] != 0 || m_item->AugSlotType[5] != 0; }
bool IsAugmentable() const;
bool AvailableWearSlot(uint32 aug_wear_slots) const;
int8 AvailableAugmentSlot(int32 augtype) const;
bool IsAugmentSlotAvailable(int32 augtype, uint8 slot) const;
inline int32 GetAugmentType() const { return m_item->AugType; }
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : NO_ITEM); }
inline bool IsExpendable() const { return ((m_item->Click.Type == ET_Expendable ) || (m_item->ItemType == ItemTypePotion)); }
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == ET_Expendable ) || (m_item->ItemType == ItemTypePotion)) : false); }
//
// Contents
@@ -337,8 +339,8 @@ public:
bool IsAmmo() const;
// Accessors
const uint32 GetID() const { return m_item->ID; }
const uint32 GetItemScriptID() const { return m_item->ScriptFileID; }
const uint32 GetID() const { return ((m_item) ? m_item->ID : NO_ITEM); }
const uint32 GetItemScriptID() const { return ((m_item) ? m_item->ScriptFileID : NO_ITEM); }
const Item_Struct* GetItem() const;
const Item_Struct* GetUnscaledItem() const;
@@ -351,18 +353,18 @@ public:
void SetColor(uint32 color) { m_color = color; }
uint32 GetColor() const { return m_color; }
uint32 GetMerchantSlot() const { return m_merchantslot; }
uint32 GetMerchantSlot() const { return m_merchantslot; }
void SetMerchantSlot(uint32 slot) { m_merchantslot = slot; }
int32 GetMerchantCount() const { return m_merchantcount; }
int32 GetMerchantCount() const { return m_merchantcount; }
void SetMerchantCount(int32 count) { m_merchantcount = count; }
int16 GetCurrentSlot() const { return m_currentslot; }
void SetCurrentSlot(int16 curr_slot) { m_currentslot = curr_slot; }
// Is this item already attuned?
bool IsAttuned() const { return m_attuned; }
void SetAttuned(bool flag) { m_attuned=flag; }
bool IsAttuned() const { return m_attuned; }
void SetAttuned(bool flag) { m_attuned=flag; }
std::string GetCustomDataString() const;
std::string GetCustomData(std::string identifier);
+186 -32
View File
@@ -831,6 +831,34 @@ namespace RoF
FINISH_ENCODE();
}
ENCODE(OP_Emote)
{
EQApplicationPacket *in = *p;
*p = nullptr;
Emote_Struct *emu = (Emote_Struct *)in->pBuffer;
unsigned char *__emu_buffer = in->pBuffer;
std::string old_message = emu->message;
std::string new_message;
ServerToRoFTextLink(new_message, old_message);
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
// new_message = new_message.substr(0, 512);
in->size = new_message.length() + 5;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_ExpansionInfo)
{
ENCODE_LENGTH_EXACT(ExpansionInfo_Struct);
@@ -841,6 +869,55 @@ namespace RoF
FINISH_ENCODE();
}
ENCODE(OP_FormattedMessage)
{
EQApplicationPacket *in = *p;
*p = nullptr;
FormattedMessage_Struct *emu = (FormattedMessage_Struct *)in->pBuffer;
unsigned char *__emu_buffer = in->pBuffer;
char *old_message_ptr = (char *)in->pBuffer;
old_message_ptr += sizeof(FormattedMessage_Struct);
std::string old_message_array[9];
for (int i = 0; i < 9; ++i) {
if (*old_message_ptr == 0) { break; }
old_message_array[i] = old_message_ptr;
old_message_ptr += old_message_array[i].length() + 1;
}
uint32 new_message_size = 0;
std::string new_message_array[9];
for (int i = 0; i < 9; ++i) {
if (old_message_array[i].length() == 0) { break; }
ServerToRoFTextLink(new_message_array[i], old_message_array[i]);
new_message_size += new_message_array[i].length() + 1;
}
in->size = sizeof(FormattedMessage_Struct) + new_message_size + 1;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->unknown0);
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->string_id);
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type);
for (int i = 0; i < 9; ++i) {
if (new_message_array[i].length() == 0) { break; }
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str());
}
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0);
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_GMLastName)
{
ENCODE_LENGTH_EXACT(GMLastName_Struct);
@@ -3118,10 +3195,11 @@ namespace RoF
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->size = strlen(emu->sayer) + new_message.length() + 25;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
@@ -3135,9 +3213,18 @@ namespace RoF
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_TYPE(uint8, OutBuffer, emu->unknown12[0]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[1]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[2]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[3]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[4]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[5]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[6]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[7]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[8]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[9]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[10]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[11]);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
@@ -3164,6 +3251,51 @@ namespace RoF
EQApplicationPacket *in = *p;
*p = nullptr;
unsigned char *__emu_buffer = in->pBuffer;
char *InBuffer = (char *)in->pBuffer;
char *block_start = InBuffer;
InBuffer += sizeof(TaskDescriptionHeader_Struct);
uint32 title_size = strlen(InBuffer) + 1;
InBuffer += title_size;
TaskDescriptionData1_Struct *emu_tdd1 = (TaskDescriptionData1_Struct *)InBuffer;
emu_tdd1->StartTime = (time(nullptr) - emu_tdd1->StartTime); // RoF has elapsed time here rather than start time
InBuffer += sizeof(TaskDescriptionData1_Struct);
uint32 description_size = strlen(InBuffer) + 1;
InBuffer += description_size;
InBuffer += sizeof(TaskDescriptionData2_Struct);
std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message;
ServerToRoFTextLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
title_size + description_size + new_message.length() + 1;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
memcpy(OutBuffer, block_start, (InBuffer - block_start));
OutBuffer += (InBuffer - block_start);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
InBuffer += strlen(InBuffer) + 1;
memcpy(OutBuffer, InBuffer, sizeof(TaskDescriptionTrailer_Struct));
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
#if 0 // original code
EQApplicationPacket *in = *p;
*p = nullptr;
EQApplicationPacket *outapp = new EQApplicationPacket(OP_TaskDescription, in->size + 1);
// Set the Write pointer as we don't know what has been done with the packet before we get it.
in->SetReadPosition(0);
@@ -3187,6 +3319,7 @@ namespace RoF
delete in;
dest->FastQueuePacket(&outapp, ack_req);
#endif
}
ENCODE(OP_TaskHistoryReply)
@@ -4220,6 +4353,27 @@ namespace RoF
FINISH_DIRECT_DECODE();
}
DECODE(OP_Emote)
{
unsigned char *__eq_buffer = __packet->pBuffer;
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message;
RoFToServerTextLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size];
char *InBuffer = (char *)__packet->pBuffer;
memcpy(InBuffer, __eq_buffer, 4);
InBuffer += 4;
strcpy(InBuffer, new_message.substr(0, 1023).c_str());
InBuffer[1023] = '\0';
delete[] __eq_buffer;
}
DECODE(OP_EnvDamage)
{
DECODE_LENGTH_EXACT(structs::EnvDamage2_Struct);
@@ -5644,73 +5798,73 @@ namespace RoF
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)) {
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
rofTextLink = serverTextLink;
return;
}
auto segments = SplitString(serverTextLink, delimiter);
auto segments = SplitString(serverTextLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
std::string new_segment;
if (segments[segment_iter].length() <= EmuConstants::TEXT_LINK_BODY_LENGTH) {
rofTextLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// 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());
rofTextLink.push_back('\x12');
rofTextLink.append(segments[segment_iter].substr(0, 41));
if (segments[segment_iter].substr(41, 1) == "0")
new_segment.append(segments[segment_iter].substr(42, 1).c_str());
if (segments[segment_iter][41] == '0')
rofTextLink.push_back(segments[segment_iter][42]);
else
new_segment.append("F");
rofTextLink.push_back('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);
rofTextLink.append(segments[segment_iter].substr(43));
rofTextLink.push_back('\x12');
}
else {
rofTextLink.append(segments[segment_iter].c_str());
rofTextLink.append(segments[segment_iter]);
}
}
}
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)) {
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (rofTextLink.find('\x12') == std::string::npos)) {
serverTextLink = rofTextLink;
return;
}
auto segments = SplitString(rofTextLink, delimiter);
auto segments = SplitString(rofTextLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
std::string new_segment;
if (segments[segment_iter].length() <= consts::TEXT_LINK_BODY_LENGTH) {
serverTextLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// 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);
serverTextLink.push_back('\x12');
serverTextLink.append(segments[segment_iter].substr(0, 41));
serverTextLink.push_back('0');
serverTextLink.append(segments[segment_iter].substr(41));
serverTextLink.push_back('\x12');
}
else {
serverTextLink.append(segments[segment_iter].c_str());
serverTextLink.append(segments[segment_iter]);
}
}
}
+180 -26
View File
@@ -897,6 +897,34 @@ namespace RoF2
FINISH_ENCODE();
}
ENCODE(OP_Emote)
{
EQApplicationPacket *in = *p;
*p = nullptr;
Emote_Struct *emu = (Emote_Struct *)in->pBuffer;
unsigned char *__emu_buffer = in->pBuffer;
std::string old_message = emu->message;
std::string new_message;
ServerToRoF2TextLink(new_message, old_message);
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
// new_message = new_message.substr(0, 512);
in->size = new_message.length() + 5;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_ExpansionInfo)
{
ENCODE_LENGTH_EXACT(ExpansionInfo_Struct);
@@ -907,6 +935,55 @@ namespace RoF2
FINISH_ENCODE();
}
ENCODE(OP_FormattedMessage)
{
EQApplicationPacket *in = *p;
*p = nullptr;
FormattedMessage_Struct *emu = (FormattedMessage_Struct *)in->pBuffer;
unsigned char *__emu_buffer = in->pBuffer;
char *old_message_ptr = (char *)in->pBuffer;
old_message_ptr += sizeof(FormattedMessage_Struct);
std::string old_message_array[9];
for (int i = 0; i < 9; ++i) {
if (*old_message_ptr == 0) { break; }
old_message_array[i] = old_message_ptr;
old_message_ptr += old_message_array[i].length() + 1;
}
uint32 new_message_size = 0;
std::string new_message_array[9];
for (int i = 0; i < 9; ++i) {
if (old_message_array[i].length() == 0) { break; }
ServerToRoF2TextLink(new_message_array[i], old_message_array[i]);
new_message_size += new_message_array[i].length() + 1;
}
in->size = sizeof(FormattedMessage_Struct) + new_message_size + 1;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->unknown0);
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->string_id);
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type);
for (int i = 0; i < 9; ++i) {
if (new_message_array[i].length() == 0) { break; }
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str());
}
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0);
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_GMLastName)
{
ENCODE_LENGTH_EXACT(GMLastName_Struct);
@@ -3184,10 +3261,11 @@ namespace RoF2
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->size = strlen(emu->sayer) + new_message.length() + 25;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
@@ -3201,9 +3279,18 @@ namespace RoF2
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_TYPE(uint8, OutBuffer, emu->unknown12[0]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[1]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[2]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[3]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[4]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[5]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[6]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[7]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[8]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[9]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[10]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[11]);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
@@ -3230,6 +3317,51 @@ namespace RoF2
EQApplicationPacket *in = *p;
*p = nullptr;
unsigned char *__emu_buffer = in->pBuffer;
char *InBuffer = (char *)in->pBuffer;
char *block_start = InBuffer;
InBuffer += sizeof(TaskDescriptionHeader_Struct);
uint32 title_size = strlen(InBuffer) + 1;
InBuffer += title_size;
TaskDescriptionData1_Struct *emu_tdd1 = (TaskDescriptionData1_Struct *)InBuffer;
emu_tdd1->StartTime = (time(nullptr) - emu_tdd1->StartTime); // RoF2 has elapsed time here rather than start time
InBuffer += sizeof(TaskDescriptionData1_Struct);
uint32 description_size = strlen(InBuffer) + 1;
InBuffer += description_size;
InBuffer += sizeof(TaskDescriptionData2_Struct);
std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message;
ServerToRoF2TextLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
title_size + description_size + new_message.length() + 1;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
memcpy(OutBuffer, block_start, (InBuffer - block_start));
OutBuffer += (InBuffer - block_start);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
InBuffer += strlen(InBuffer) + 1;
memcpy(OutBuffer, InBuffer, sizeof(TaskDescriptionTrailer_Struct));
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
#if 0 // original code
EQApplicationPacket *in = *p;
*p = nullptr;
EQApplicationPacket *outapp = new EQApplicationPacket(OP_TaskDescription, in->size + 1);
// Set the Write pointer as we don't know what has been done with the packet before we get it.
in->SetReadPosition(0);
@@ -3253,6 +3385,7 @@ namespace RoF2
delete in;
dest->FastQueuePacket(&outapp, ack_req);
#endif
}
ENCODE(OP_TaskHistoryReply)
@@ -4292,6 +4425,27 @@ namespace RoF2
FINISH_DIRECT_DECODE();
}
DECODE(OP_Emote)
{
unsigned char *__eq_buffer = __packet->pBuffer;
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message;
RoF2ToServerTextLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size];
char *InBuffer = (char *)__packet->pBuffer;
memcpy(InBuffer, __eq_buffer, 4);
InBuffer += 4;
strcpy(InBuffer, new_message.substr(0, 1023).c_str());
InBuffer[1023] = '\0';
delete[] __eq_buffer;
}
DECODE(OP_EnvDamage)
{
DECODE_LENGTH_EXACT(structs::EnvDamage2_Struct);
@@ -5738,64 +5892,64 @@ namespace RoF2
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)) {
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
rof2TextLink = serverTextLink;
return;
}
auto segments = SplitString(serverTextLink, delimiter);
auto segments = SplitString(serverTextLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
std::string new_segment;
if (segments[segment_iter].length() <= EmuConstants::TEXT_LINK_BODY_LENGTH) {
rof2TextLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// 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);
rof2TextLink.push_back('\x12');
rof2TextLink.append(segments[segment_iter]);
rof2TextLink.push_back('\x12');
}
else {
rof2TextLink.append(segments[segment_iter].c_str());
rof2TextLink.append(segments[segment_iter]);
}
}
}
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)) {
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (rof2TextLink.find('\x12') == std::string::npos)) {
serverTextLink = rof2TextLink;
return;
}
auto segments = SplitString(rof2TextLink, delimiter);
auto segments = SplitString(rof2TextLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
std::string new_segment;
if (segments[segment_iter].length() <= consts::TEXT_LINK_BODY_LENGTH) {
serverTextLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// 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);
serverTextLink.push_back('\x12');
serverTextLink.append(segments[segment_iter]);
serverTextLink.push_back('\x12');
}
else {
serverTextLink.append(segments[segment_iter].c_str());
serverTextLink.append(segments[segment_iter]);
}
}
}
+3
View File
@@ -42,7 +42,9 @@ E(OP_DzExpeditionList)
E(OP_DzJoinExpeditionConfirm)
E(OP_DzLeaderStatus)
E(OP_DzMemberList)
E(OP_Emote)
E(OP_ExpansionInfo)
E(OP_FormattedMessage)
E(OP_GMLastName)
E(OP_GMTrainSkillConfirm)
E(OP_GroundSpawn)
@@ -133,6 +135,7 @@ D(OP_ConsiderCorpse)
D(OP_Consume)
D(OP_Damage)
D(OP_DeleteItem)
D(OP_Emote)
D(OP_EnvDamage)
D(OP_FaceChange)
D(OP_FindPersonRequest)
+3
View File
@@ -31,7 +31,9 @@ E(OP_DzExpeditionList)
E(OP_DzJoinExpeditionConfirm)
E(OP_DzLeaderStatus)
E(OP_DzMemberList)
E(OP_Emote)
E(OP_ExpansionInfo)
E(OP_FormattedMessage)
E(OP_GMLastName)
E(OP_GMTrainSkillConfirm)
E(OP_GroundSpawn)
@@ -122,6 +124,7 @@ D(OP_ConsiderCorpse)
D(OP_Consume)
D(OP_Damage)
D(OP_DeleteItem)
D(OP_Emote)
D(OP_EnvDamage)
D(OP_FaceChange)
D(OP_FindPersonRequest)
+186 -35
View File
@@ -600,6 +600,34 @@ namespace SoD
FINISH_ENCODE();
}
ENCODE(OP_Emote)
{
EQApplicationPacket *in = *p;
*p = nullptr;
Emote_Struct *emu = (Emote_Struct *)in->pBuffer;
unsigned char *__emu_buffer = in->pBuffer;
std::string old_message = emu->message;
std::string new_message;
ServerToSoDTextLink(new_message, old_message);
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
// new_message = new_message.substr(0, 512);
in->size = new_message.length() + 5;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_ExpansionInfo)
{
ENCODE_LENGTH_EXACT(ExpansionInfo_Struct);
@@ -610,6 +638,55 @@ namespace SoD
FINISH_ENCODE();
}
ENCODE(OP_FormattedMessage)
{
EQApplicationPacket *in = *p;
*p = nullptr;
FormattedMessage_Struct *emu = (FormattedMessage_Struct *)in->pBuffer;
unsigned char *__emu_buffer = in->pBuffer;
char *old_message_ptr = (char *)in->pBuffer;
old_message_ptr += sizeof(FormattedMessage_Struct);
std::string old_message_array[9];
for (int i = 0; i < 9; ++i) {
if (*old_message_ptr == 0) { break; }
old_message_array[i] = old_message_ptr;
old_message_ptr += old_message_array[i].length() + 1;
}
uint32 new_message_size = 0;
std::string new_message_array[9];
for (int i = 0; i < 9; ++i) {
if (old_message_array[i].length() == 0) { break; }
ServerToSoDTextLink(new_message_array[i], old_message_array[i]);
new_message_size += new_message_array[i].length() + 1;
}
in->size = sizeof(FormattedMessage_Struct) + new_message_size + 1;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->unknown0);
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->string_id);
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type);
for (int i = 0; i < 9; ++i) {
if (new_message_array[i].length() == 0) { break; }
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str());
}
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0);
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_GroundSpawn)
{
ENCODE_LENGTH_EXACT(Object_Struct);
@@ -2010,10 +2087,11 @@ namespace SoD
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->size = strlen(emu->sayer) + new_message.length() + 25;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
@@ -2027,9 +2105,18 @@ namespace SoD
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_TYPE(uint8, OutBuffer, emu->unknown12[0]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[1]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[2]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[3]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[4]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[5]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[6]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[7]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[8]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[9]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[10]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[11]);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
@@ -2096,6 +2183,49 @@ namespace SoD
FINISH_ENCODE();
}
ENCODE(OP_TaskDescription)
{
EQApplicationPacket *in = *p;
*p = nullptr;
unsigned char *__emu_buffer = in->pBuffer;
char *InBuffer = (char *)in->pBuffer;
char *block_start = InBuffer;
InBuffer += sizeof(TaskDescriptionHeader_Struct);
uint32 title_size = strlen(InBuffer) + 1;
InBuffer += title_size;
InBuffer += sizeof(TaskDescriptionData1_Struct);
uint32 description_size = strlen(InBuffer) + 1;
InBuffer += description_size;
InBuffer += sizeof(TaskDescriptionData2_Struct);
std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message;
ServerToSoDTextLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
title_size + description_size + new_message.length() + 1;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
memcpy(OutBuffer, block_start, (InBuffer - block_start));
OutBuffer += (InBuffer - block_start);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
InBuffer += strlen(InBuffer) + 1;
memcpy(OutBuffer, InBuffer, sizeof(TaskDescriptionTrailer_Struct));
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_Track)
{
EQApplicationPacket *in = *p;
@@ -2917,6 +3047,27 @@ namespace SoD
FINISH_DIRECT_DECODE();
}
DECODE(OP_Emote)
{
unsigned char *__eq_buffer = __packet->pBuffer;
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message;
SoDToServerTextLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size];
char *InBuffer = (char *)__packet->pBuffer;
memcpy(InBuffer, __eq_buffer, 4);
InBuffer += 4;
strcpy(InBuffer, new_message.substr(0, 1023).c_str());
InBuffer[1023] = '\0';
delete[] __eq_buffer;
}
DECODE(OP_FaceChange)
{
DECODE_LENGTH_EXACT(structs::FaceChange_Struct);
@@ -3862,76 +4013,76 @@ namespace SoD
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)) {
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
sodTextLink = serverTextLink;
return;
}
auto segments = SplitString(serverTextLink, delimiter);
auto segments = SplitString(serverTextLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
std::string new_segment;
if (segments[segment_iter].length() <= EmuConstants::TEXT_LINK_BODY_LENGTH) {
sodTextLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// 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());
sodTextLink.push_back('\x12');
sodTextLink.append(segments[segment_iter].substr(0, 31));
sodTextLink.append(segments[segment_iter].substr(36, 5));
if (segments[segment_iter].substr(41, 1) == "0")
new_segment.append(segments[segment_iter].substr(42, 1).c_str());
if (segments[segment_iter][41] == '0')
sodTextLink.push_back(segments[segment_iter][42]);
else
new_segment.append("F");
sodTextLink.push_back('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);
sodTextLink.append(segments[segment_iter].substr(43));
sodTextLink.push_back('\x12');
}
else {
sodTextLink.append(segments[segment_iter].c_str());
sodTextLink.append(segments[segment_iter]);
}
}
}
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)) {
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (sodTextLink.find('\x12') == std::string::npos)) {
serverTextLink = sodTextLink;
return;
}
auto segments = SplitString(sodTextLink, delimiter);
auto segments = SplitString(sodTextLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
std::string new_segment;
if (segments[segment_iter].length() <= consts::TEXT_LINK_BODY_LENGTH) {
serverTextLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// 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);
serverTextLink.push_back('\x12');
serverTextLink.append(segments[segment_iter].substr(0, 31));
serverTextLink.append("00000");
serverTextLink.append(segments[segment_iter].substr(31, 5));
serverTextLink.push_back('0');
serverTextLink.append(segments[segment_iter].substr(36));
serverTextLink.push_back('\x12');
}
else {
serverTextLink.append(segments[segment_iter].c_str());
serverTextLink.append(segments[segment_iter]);
}
}
}
+4
View File
@@ -22,7 +22,9 @@ E(OP_DzExpeditionList)
E(OP_DzJoinExpeditionConfirm)
E(OP_DzLeaderStatus)
E(OP_DzMemberList)
E(OP_Emote)
E(OP_ExpansionInfo)
E(OP_FormattedMessage)
E(OP_GroundSpawn)
E(OP_GroupCancelInvite)
E(OP_GroupFollow)
@@ -61,6 +63,7 @@ E(OP_SpawnDoor)
E(OP_SpecialMesg)
E(OP_Stun)
E(OP_TargetBuffs)
E(OP_TaskDescription)
E(OP_Track)
E(OP_Trader)
E(OP_TraderBuy)
@@ -90,6 +93,7 @@ D(OP_Consider)
D(OP_ConsiderCorpse)
D(OP_Consume)
D(OP_DeleteItem)
D(OP_Emote)
D(OP_FaceChange)
D(OP_FindPersonRequest)
D(OP_GroupCancelInvite)
+186 -35
View File
@@ -587,6 +587,34 @@ namespace SoF
FINISH_ENCODE();
}
ENCODE(OP_Emote)
{
EQApplicationPacket *in = *p;
*p = nullptr;
Emote_Struct *emu = (Emote_Struct *)in->pBuffer;
unsigned char *__emu_buffer = in->pBuffer;
std::string old_message = emu->message;
std::string new_message;
ServerToSoFTextLink(new_message, old_message);
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
// new_message = new_message.substr(0, 512);
in->size = new_message.length() + 5;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_ExpansionInfo)
{
ENCODE_LENGTH_EXACT(ExpansionInfo_Struct);
@@ -597,6 +625,55 @@ namespace SoF
FINISH_ENCODE();
}
ENCODE(OP_FormattedMessage)
{
EQApplicationPacket *in = *p;
*p = nullptr;
FormattedMessage_Struct *emu = (FormattedMessage_Struct *)in->pBuffer;
unsigned char *__emu_buffer = in->pBuffer;
char *old_message_ptr = (char *)in->pBuffer;
old_message_ptr += sizeof(FormattedMessage_Struct);
std::string old_message_array[9];
for (int i = 0; i < 9; ++i) {
if (*old_message_ptr == 0) { break; }
old_message_array[i] = old_message_ptr;
old_message_ptr += old_message_array[i].length() + 1;
}
uint32 new_message_size = 0;
std::string new_message_array[9];
for (int i = 0; i < 9; ++i) {
if (old_message_array[i].length() == 0) { break; }
ServerToSoFTextLink(new_message_array[i], old_message_array[i]);
new_message_size += new_message_array[i].length() + 1;
}
in->size = sizeof(FormattedMessage_Struct) + new_message_size + 1;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->unknown0);
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->string_id);
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type);
for (int i = 0; i < 9; ++i) {
if (new_message_array[i].length() == 0) { break; }
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str());
}
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0);
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_GroundSpawn)
{
ENCODE_LENGTH_EXACT(Object_Struct);
@@ -1656,10 +1733,11 @@ namespace SoF
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->size = strlen(emu->sayer) + new_message.length() + 25;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
@@ -1673,9 +1751,18 @@ namespace SoF
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_TYPE(uint8, OutBuffer, emu->unknown12[0]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[1]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[2]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[3]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[4]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[5]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[6]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[7]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[8]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[9]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[10]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[11]);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
@@ -1695,6 +1782,49 @@ namespace SoF
FINISH_ENCODE();
}
ENCODE(OP_TaskDescription)
{
EQApplicationPacket *in = *p;
*p = nullptr;
unsigned char *__emu_buffer = in->pBuffer;
char *InBuffer = (char *)in->pBuffer;
char *block_start = InBuffer;
InBuffer += sizeof(TaskDescriptionHeader_Struct);
uint32 title_size = strlen(InBuffer) + 1;
InBuffer += title_size;
InBuffer += sizeof(TaskDescriptionData1_Struct);
uint32 description_size = strlen(InBuffer) + 1;
InBuffer += description_size;
InBuffer += sizeof(TaskDescriptionData2_Struct);
std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message;
ServerToSoFTextLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
title_size + description_size + new_message.length() + 1;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
memcpy(OutBuffer, block_start, (InBuffer - block_start));
OutBuffer += (InBuffer - block_start);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
InBuffer += strlen(InBuffer) + 1;
memcpy(OutBuffer, InBuffer, sizeof(TaskDescriptionTrailer_Struct));
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_Track)
{
EQApplicationPacket *in = *p;
@@ -2317,6 +2447,27 @@ namespace SoF
FINISH_DIRECT_DECODE();
}
DECODE(OP_Emote)
{
unsigned char *__eq_buffer = __packet->pBuffer;
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message;
SoFToServerTextLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size];
char *InBuffer = (char *)__packet->pBuffer;
memcpy(InBuffer, __eq_buffer, 4);
InBuffer += 4;
strcpy(InBuffer, new_message.substr(0, 1023).c_str());
InBuffer[1023] = '\0';
delete[] __eq_buffer;
}
DECODE(OP_FaceChange)
{
DECODE_LENGTH_EXACT(structs::FaceChange_Struct);
@@ -3184,76 +3335,76 @@ namespace SoF
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)) {
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
sofTextLink = serverTextLink;
return;
}
auto segments = SplitString(serverTextLink, delimiter);
auto segments = SplitString(serverTextLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
std::string new_segment;
if (segments[segment_iter].length() <= EmuConstants::TEXT_LINK_BODY_LENGTH) {
sofTextLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// 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());
sofTextLink.push_back('\x12');
sofTextLink.append(segments[segment_iter].substr(0, 31));
sofTextLink.append(segments[segment_iter].substr(36, 5));
if (segments[segment_iter].substr(41, 1) == "0")
new_segment.append(segments[segment_iter].substr(42, 1).c_str());
if (segments[segment_iter][41] == '0')
sofTextLink.push_back(segments[segment_iter][42]);
else
new_segment.append("F");
sofTextLink.push_back('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);
sofTextLink.append(segments[segment_iter].substr(43));
sofTextLink.push_back('\x12');
}
else {
sofTextLink.append(segments[segment_iter].c_str());
sofTextLink.append(segments[segment_iter]);
}
}
}
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)) {
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (sofTextLink.find('\x12') == std::string::npos)) {
serverTextLink = sofTextLink;
return;
}
auto segments = SplitString(sofTextLink, delimiter);
auto segments = SplitString(sofTextLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
std::string new_segment;
if (segments[segment_iter].length() <= consts::TEXT_LINK_BODY_LENGTH) {
serverTextLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// 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);
serverTextLink.push_back('\x12');
serverTextLink.append(segments[segment_iter].substr(0, 31));
serverTextLink.append("00000");
serverTextLink.append(segments[segment_iter].substr(31, 5));
serverTextLink.push_back('0');
serverTextLink.append(segments[segment_iter].substr(36));
serverTextLink.push_back('\x12');
}
else {
serverTextLink.append(segments[segment_iter].c_str());
serverTextLink.append(segments[segment_iter]);
}
}
}
+4
View File
@@ -23,7 +23,9 @@ E(OP_DzExpeditionList)
E(OP_DzJoinExpeditionConfirm)
E(OP_DzLeaderStatus)
E(OP_DzMemberList)
E(OP_Emote)
E(OP_ExpansionInfo)
E(OP_FormattedMessage)
E(OP_GroundSpawn)
E(OP_GuildMemberList)
E(OP_Illusion)
@@ -53,6 +55,7 @@ E(OP_SomeItemPacketMaybe)
E(OP_SpawnDoor)
E(OP_SpecialMesg)
E(OP_Stun)
E(OP_TaskDescription)
E(OP_Track)
E(OP_Trader)
E(OP_TraderBuy)
@@ -79,6 +82,7 @@ D(OP_Consider)
D(OP_ConsiderCorpse)
D(OP_Consume)
D(OP_DeleteItem)
D(OP_Emote)
D(OP_FaceChange)
D(OP_FindPersonRequest)
D(OP_GroupFollow)
+188 -37
View File
@@ -456,6 +456,83 @@ namespace Titanium
FINISH_ENCODE();
}
ENCODE(OP_Emote)
{
EQApplicationPacket *in = *p;
*p = nullptr;
Emote_Struct *emu = (Emote_Struct *)in->pBuffer;
unsigned char *__emu_buffer = in->pBuffer;
std::string old_message = emu->message;
std::string new_message;
ServerToTitaniumTextLink(new_message, old_message);
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
// new_message = new_message.substr(0, 512);
in->size = new_message.length() + 5;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_FormattedMessage)
{
EQApplicationPacket *in = *p;
*p = nullptr;
FormattedMessage_Struct *emu = (FormattedMessage_Struct *)in->pBuffer;
unsigned char *__emu_buffer = in->pBuffer;
char *old_message_ptr = (char *)in->pBuffer;
old_message_ptr += sizeof(FormattedMessage_Struct);
std::string old_message_array[9];
for (int i = 0; i < 9; ++i) {
if (*old_message_ptr == 0) { break; }
old_message_array[i] = old_message_ptr;
old_message_ptr += old_message_array[i].length() + 1;
}
uint32 new_message_size = 0;
std::string new_message_array[9];
for (int i = 0; i < 9; ++i) {
if (old_message_array[i].length() == 0) { break; }
ServerToTitaniumTextLink(new_message_array[i], old_message_array[i]);
new_message_size += new_message_array[i].length() + 1;
}
in->size = sizeof(FormattedMessage_Struct) + new_message_size + 1;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->unknown0);
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->string_id);
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type);
for (int i = 0; i < 9; ++i) {
if (new_message_array[i].length() == 0) { break; }
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str());
}
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0);
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_GuildMemberList)
{
//consume the packet
@@ -1118,10 +1195,11 @@ namespace Titanium
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->size = strlen(emu->sayer) + new_message.length() + 25;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
@@ -1135,12 +1213,64 @@ namespace Titanium
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_TYPE(uint8, OutBuffer, emu->unknown12[0]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[1]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[2]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[3]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[4]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[5]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[6]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[7]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[8]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[9]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[10]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[11]);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_TaskDescription)
{
EQApplicationPacket *in = *p;
*p = nullptr;
unsigned char *__emu_buffer = in->pBuffer;
char *InBuffer = (char *)in->pBuffer;
char *block_start = InBuffer;
InBuffer += sizeof(TaskDescriptionHeader_Struct);
uint32 title_size = strlen(InBuffer) + 1;
InBuffer += title_size;
InBuffer += sizeof(TaskDescriptionData1_Struct);
uint32 description_size = strlen(InBuffer) + 1;
InBuffer += description_size;
InBuffer += sizeof(TaskDescriptionData2_Struct);
std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message;
ServerToTitaniumTextLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct) +
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct) +
title_size + description_size + new_message.length() + 1;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
memcpy(OutBuffer, block_start, (InBuffer - block_start));
OutBuffer += (InBuffer - block_start);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
InBuffer += strlen(InBuffer) + 1;
memcpy(OutBuffer, InBuffer, sizeof(TaskDescriptionTrailer_Struct));
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
@@ -1518,6 +1648,27 @@ namespace Titanium
FINISH_DIRECT_DECODE();
}
DECODE(OP_Emote)
{
unsigned char *__eq_buffer = __packet->pBuffer;
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message;
TitaniumToServerTextLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size];
char *InBuffer = (char *)__packet->pBuffer;
memcpy(InBuffer, __eq_buffer, 4);
InBuffer += 4;
strcpy(InBuffer, new_message.substr(0, 1023).c_str());
InBuffer[1023] = '\0';
delete[] __eq_buffer;
}
DECODE(OP_FaceChange)
{
DECODE_LENGTH_EXACT(structs::FaceChange_Struct);
@@ -1943,78 +2094,78 @@ namespace Titanium
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)) {
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
titaniumTextLink = serverTextLink;
return;
}
auto segments = SplitString(serverTextLink, delimiter);
auto segments = SplitString(serverTextLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
std::string new_segment;
if (segments[segment_iter].length() <= EmuConstants::TEXT_LINK_BODY_LENGTH) {
titaniumTextLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// 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());
titaniumTextLink.push_back('\x12');
titaniumTextLink.append(segments[segment_iter].substr(0, 31));
titaniumTextLink.append(segments[segment_iter].substr(36, 5));
if (segments[segment_iter].substr(41, 1) == "0")
new_segment.append(segments[segment_iter].substr(42, 1).c_str());
if (segments[segment_iter][41] == '0')
titaniumTextLink.push_back(segments[segment_iter][42]);
else
new_segment.append("F");
titaniumTextLink.push_back('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);
titaniumTextLink.append(segments[segment_iter].substr(48));
titaniumTextLink.push_back('\x12');
}
else {
titaniumTextLink.append(segments[segment_iter].c_str());
titaniumTextLink.append(segments[segment_iter]);
}
}
}
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)) {
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (titaniumTextLink.find('\x12') == std::string::npos)) {
serverTextLink = titaniumTextLink;
return;
}
auto segments = SplitString(titaniumTextLink, delimiter);
auto segments = SplitString(titaniumTextLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
std::string new_segment;
if (segments[segment_iter].length() <= consts::TEXT_LINK_BODY_LENGTH) {
serverTextLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// 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);
serverTextLink.push_back('\x12');
serverTextLink.append(segments[segment_iter].substr(0, 31));
serverTextLink.append("00000");
serverTextLink.append(segments[segment_iter].substr(31, 5));
serverTextLink.push_back('0');
serverTextLink.push_back(segments[segment_iter][36]);
serverTextLink.append("00000");
serverTextLink.append(segments[segment_iter].substr(37));
serverTextLink.push_back('\x12');
}
else {
serverTextLink.append(segments[segment_iter].c_str());
serverTextLink.append(segments[segment_iter]);
}
}
}
+4
View File
@@ -16,6 +16,8 @@ E(OP_DzExpeditionList)
E(OP_DzJoinExpeditionConfirm)
E(OP_DzLeaderStatus)
E(OP_DzMemberList)
E(OP_Emote)
E(OP_FormattedMessage)
E(OP_GuildMemberLevelUpdate)
E(OP_GuildMemberList)
E(OP_Illusion)
@@ -37,6 +39,7 @@ E(OP_SendCharInfo)
E(OP_SendAATable)
E(OP_ShopPlayerSell)
E(OP_SpecialMesg)
E(OP_TaskDescription)
E(OP_Track)
E(OP_Trader)
E(OP_TraderBuy)
@@ -55,6 +58,7 @@ D(OP_ChannelMessage)
D(OP_CharacterCreate)
D(OP_Consume)
D(OP_DeleteItem)
D(OP_Emote)
D(OP_FaceChange)
D(OP_InspectAnswer)
D(OP_InspectRequest)
+186 -35
View File
@@ -744,6 +744,34 @@ namespace Underfoot
FINISH_ENCODE();
}
ENCODE(OP_Emote)
{
EQApplicationPacket *in = *p;
*p = nullptr;
Emote_Struct *emu = (Emote_Struct *)in->pBuffer;
unsigned char *__emu_buffer = in->pBuffer;
std::string old_message = emu->message;
std::string new_message;
ServerToUnderfootTextLink(new_message, old_message);
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
// new_message = new_message.substr(0, 512);
in->size = new_message.length() + 5;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_ExpansionInfo)
{
ENCODE_LENGTH_EXACT(ExpansionInfo_Struct);
@@ -754,6 +782,55 @@ namespace Underfoot
FINISH_ENCODE();
}
ENCODE(OP_FormattedMessage)
{
EQApplicationPacket *in = *p;
*p = nullptr;
FormattedMessage_Struct *emu = (FormattedMessage_Struct *)in->pBuffer;
unsigned char *__emu_buffer = in->pBuffer;
char *old_message_ptr = (char *)in->pBuffer;
old_message_ptr += sizeof(FormattedMessage_Struct);
std::string old_message_array[9];
for (int i = 0; i < 9; ++i) {
if (*old_message_ptr == 0) { break; }
old_message_array[i] = old_message_ptr;
old_message_ptr += old_message_array[i].length() + 1;
}
uint32 new_message_size = 0;
std::string new_message_array[9];
for (int i = 0; i < 9; ++i) {
if (old_message_array[i].length() == 0) { break; }
ServerToUnderfootTextLink(new_message_array[i], old_message_array[i]);
new_message_size += new_message_array[i].length() + 1;
}
in->size = sizeof(FormattedMessage_Struct) + new_message_size + 1;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->unknown0);
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->string_id);
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type);
for (int i = 0; i < 9; ++i) {
if (new_message_array[i].length() == 0) { break; }
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str());
}
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0);
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_GroundSpawn)
{
// We are not encoding the spawn_id field here, or a size but it doesn't appear to matter.
@@ -2321,10 +2398,11 @@ namespace Underfoot
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->size = strlen(emu->sayer) + new_message.length() + 25;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
@@ -2338,9 +2416,18 @@ namespace Underfoot
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_TYPE(uint8, OutBuffer, emu->unknown12[0]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[1]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[2]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[3]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[4]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[5]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[6]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[7]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[8]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[9]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[10]);
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[11]);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
@@ -2362,6 +2449,49 @@ namespace Underfoot
ENCODE(OP_TargetBuffs) { ENCODE_FORWARD(OP_BuffCreate); }
ENCODE(OP_TaskDescription)
{
EQApplicationPacket *in = *p;
*p = nullptr;
unsigned char *__emu_buffer = in->pBuffer;
char *InBuffer = (char *)in->pBuffer;
char *block_start = InBuffer;
InBuffer += sizeof(TaskDescriptionHeader_Struct);
uint32 title_size = strlen(InBuffer) + 1;
InBuffer += title_size;
InBuffer += sizeof(TaskDescriptionData1_Struct);
uint32 description_size = strlen(InBuffer) + 1;
InBuffer += description_size;
InBuffer += sizeof(TaskDescriptionData2_Struct);
std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message;
ServerToUnderfootTextLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
title_size + description_size + new_message.length() + 1;
in->pBuffer = new unsigned char[in->size];
char *OutBuffer = (char *)in->pBuffer;
memcpy(OutBuffer, block_start, (InBuffer - block_start));
OutBuffer += (InBuffer - block_start);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
InBuffer += strlen(InBuffer) + 1;
memcpy(OutBuffer, InBuffer, sizeof(TaskDescriptionTrailer_Struct));
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_Track)
{
EQApplicationPacket *in = *p;
@@ -3216,6 +3346,27 @@ namespace Underfoot
FINISH_DIRECT_DECODE();
}
DECODE(OP_Emote)
{
unsigned char *__eq_buffer = __packet->pBuffer;
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message;
UnderfootToServerTextLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size];
char *InBuffer = (char *)__packet->pBuffer;
memcpy(InBuffer, __eq_buffer, 4);
InBuffer += 4;
strcpy(InBuffer, new_message.substr(0, 1023).c_str());
InBuffer[1023] = '\0';
delete[] __eq_buffer;
}
DECODE(OP_EnvDamage)
{
DECODE_LENGTH_EXACT(structs::EnvDamage2_Struct);
@@ -4165,76 +4316,76 @@ namespace Underfoot
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)) {
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
underfootTextLink = serverTextLink;
return;
}
auto segments = SplitString(serverTextLink, delimiter);
auto segments = SplitString(serverTextLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
std::string new_segment;
if (segments[segment_iter].length() <= EmuConstants::TEXT_LINK_BODY_LENGTH) {
underfootTextLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// 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());
underfootTextLink.push_back('\x12');
underfootTextLink.append(segments[segment_iter].substr(0, 31));
underfootTextLink.append(segments[segment_iter].substr(36, 5));
if (segments[segment_iter].substr(41, 1) == "0")
new_segment.append(segments[segment_iter].substr(42, 1).c_str());
if (segments[segment_iter][41] == '0')
underfootTextLink.push_back(segments[segment_iter][42]);
else
new_segment.append("F");
underfootTextLink.push_back('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);
underfootTextLink.append(segments[segment_iter].substr(43));
underfootTextLink.push_back('\x12');
}
else {
underfootTextLink.append(segments[segment_iter].c_str());
underfootTextLink.append(segments[segment_iter]);
}
}
}
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)) {
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (underfootTextLink.find('\x12') == std::string::npos)) {
serverTextLink = underfootTextLink;
return;
}
auto segments = SplitString(underfootTextLink, delimiter);
auto segments = SplitString(underfootTextLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
std::string new_segment;
if (segments[segment_iter].length() <= consts::TEXT_LINK_BODY_LENGTH) {
serverTextLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// 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);
serverTextLink.push_back('\x12');
serverTextLink.append(segments[segment_iter].substr(0, 31));
serverTextLink.append("00000");
serverTextLink.append(segments[segment_iter].substr(31, 5));
serverTextLink.push_back('0');
serverTextLink.append(segments[segment_iter].substr(36));
serverTextLink.push_back('\x12');
}
else {
serverTextLink.append(segments[segment_iter].c_str());
serverTextLink.append(segments[segment_iter]);
}
}
}
+4
View File
@@ -25,7 +25,9 @@ E(OP_DzExpeditionList)
E(OP_DzJoinExpeditionConfirm)
E(OP_DzLeaderStatus)
E(OP_DzMemberList)
E(OP_Emote)
E(OP_ExpansionInfo)
E(OP_FormattedMessage)
E(OP_GroundSpawn)
E(OP_GroupCancelInvite)
E(OP_GroupFollow)
@@ -68,6 +70,7 @@ E(OP_SpawnDoor)
E(OP_SpecialMesg)
E(OP_Stun)
E(OP_TargetBuffs)
E(OP_TaskDescription)
E(OP_Track)
E(OP_Trader)
E(OP_TraderBuy)
@@ -98,6 +101,7 @@ D(OP_ConsiderCorpse)
D(OP_Consume)
D(OP_Damage)
D(OP_DeleteItem)
D(OP_Emote)
D(OP_EnvDamage)
D(OP_FaceChange)
D(OP_FindPersonRequest)
+35 -25
View File
@@ -105,9 +105,12 @@ bool SharedDatabase::SaveCursor(uint32 char_id, std::list<ItemInst*>::const_iter
int i = 8000;
for(auto it = start; it != end; ++it, i++) {
if (i > 8999) { break; } // shouldn't be anything in the queue that indexes this high
ItemInst *inst = *it;
if (!SaveInventory(char_id,inst,(i == 8000) ? MainCursor : i))
return false;
int16 use_slot = (i == 8000) ? MainCursor : i;
if (!SaveInventory(char_id, inst, use_slot)) {
return false;
}
}
return true;
@@ -166,8 +169,9 @@ bool SharedDatabase::SaveInventory(uint32 char_id, const ItemInst* inst, int16 s
else
return UpdateSharedBankSlot(char_id, inst, slot_id);
}
else if (!inst) // All other inventory
return DeleteInventorySlot(char_id, slot_id);
else if (!inst) { // All other inventory
return DeleteInventorySlot(char_id, slot_id);
}
return UpdateInventorySlot(char_id, inst, slot_id);
}
@@ -176,11 +180,12 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, i
// need to check 'inst' argument for valid pointer
uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM };
if (inst->IsType(ItemClassCommon))
for(int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
ItemInst *auginst=inst->GetItem(i);
augslot[i]=(auginst && auginst->GetItem()) ? auginst->GetItem()->ID : NO_ITEM;
if (inst->IsType(ItemClassCommon)) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
ItemInst *auginst = inst->GetItem(i);
augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : NO_ITEM;
}
}
uint16 charges = 0;
if(inst->GetCharges() >= 0)
@@ -220,11 +225,12 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst,
// need to check 'inst' argument for valid pointer
uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM };
if (inst->IsType(ItemClassCommon))
for(int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
ItemInst *auginst=inst->GetItem(i);
augslot[i]=(auginst && auginst->GetItem()) ? auginst->GetItem()->ID : NO_ITEM;
if (inst->IsType(ItemClassCommon)) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
ItemInst *auginst = inst->GetItem(i);
augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : NO_ITEM;
}
}
// Update/Insert item
uint32 account_id = GetAccountIDByChar(char_id);
@@ -246,11 +252,12 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst,
auto results = QueryDatabase(query);
// Save bag contents, if slot supports bag contents
if (inst->IsType(ItemClassContainer) && Inventory::SupportsContainers(slot_id))
if (inst->IsType(ItemClassContainer) && Inventory::SupportsContainers(slot_id)) {
for (uint8 idx = SUB_BEGIN; idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) {
const ItemInst* baginst = inst->GetItem(idx);
SaveInventory(char_id, baginst, Inventory::CalcSlotId(slot_id, idx));
}
}
if (!results.Success()) {
return false;
@@ -422,9 +429,8 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory* inv, bool is_charid) {
ItemInst* inst = CreateBaseItem(item, charges);
if (inst && item->ItemClass == ItemClassCommon) {
for(int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
if (aug[i]) {
inst->PutAugment(this, i, aug[i]);
}
if (aug[i])
inst->PutAugment(this, i, aug[i]);
}
}
@@ -562,10 +568,12 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) {
else
inst->SetCharges(charges);
if (item->ItemClass == ItemClassCommon)
for(int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++)
if (aug[i])
inst->PutAugment(this, i, aug[i]);
if (item->ItemClass == ItemClassCommon) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
if (aug[i])
inst->PutAugment(this, i, aug[i]);
}
}
if (slot_id >= 8000 && slot_id <= 8999)
{
@@ -676,10 +684,12 @@ bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv)
inst->SetCharges(charges);
if (item->ItemClass == ItemClassCommon)
for(int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++)
if (aug[i])
inst->PutAugment(this, i, aug[i]);
if (item->ItemClass == ItemClassCommon) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
if (aug[i])
inst->PutAugment(this, i, aug[i]);
}
}
if (slot_id>=8000 && slot_id <= 8999)
put_slot_id = inv->PushCursor(*inst);
@@ -1950,7 +1960,7 @@ void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMes
std::string query = StringFormat("SELECT `inspect_message` FROM `character_inspect_messages` WHERE `id` = %u LIMIT 1", character_id);
auto results = QueryDatabase(query);
auto row = results.begin();
memcpy(message, "", sizeof(InspectMessage_Struct));
memset(message, '\0', sizeof(InspectMessage_Struct));
for (auto row = results.begin(); row != results.end(); ++row) {
memcpy(message, row[0], sizeof(InspectMessage_Struct));
}