SayLink clean-up

This commit is contained in:
Uleat 2018-02-24 09:08:11 -05:00
parent c87380fa54
commit 361937d443
26 changed files with 455 additions and 396 deletions

View File

@ -114,7 +114,11 @@ namespace EQEmu
const EQEmu::versions::ClientVersion CharacterCreationClient = EQEmu::versions::ClientVersion::RoF2; const EQEmu::versions::ClientVersion CharacterCreationClient = EQEmu::versions::ClientVersion::RoF2;
const size_t CharacterCreationMax = RoF2::constants::CharacterCreationLimit; const size_t CharacterCreationMax = RoF2::constants::CharacterCreationLimit;
const size_t SayLinkOpenerSize = 1;
const size_t SayLinkBodySize = RoF2::constants::SayLinkBodySize; const size_t SayLinkBodySize = RoF2::constants::SayLinkBodySize;
const size_t SayLinkTextSize = 256; // this may be varied until it breaks something (tested:374) - the others are constant
const size_t SayLinkCloserSize = 1;
const size_t SayLinkMaximumSize = (SayLinkOpenerSize + SayLinkBodySize + SayLinkTextSize + SayLinkCloserSize);
const int LongBuffs = RoF2::constants::LongBuffs; const int LongBuffs = RoF2::constants::LongBuffs;
const int ShortBuffs = RoF2::constants::ShortBuffs; const int ShortBuffs = RoF2::constants::ShortBuffs;

View File

@ -175,8 +175,6 @@ namespace EQEmu
// POTION_BELT_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?) // POTION_BELT_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
static const size_t POTION_BELT_ITEM_COUNT = 5; static const size_t POTION_BELT_ITEM_COUNT = 5;
static const size_t TEXT_LINK_BODY_LENGTH = 56;
} }
} }

View File

@ -5366,6 +5366,23 @@ struct AuraDestory_Struct {
}; };
// I think we can assume it's just action for 2, client doesn't seem to do anything with the rest of the data in that case // I think we can assume it's just action for 2, client doesn't seem to do anything with the rest of the data in that case
struct SayLinkBodyFrame_Struct {
/*000*/ char ActionID[1];
/*001*/ char ItemID[5];
/*006*/ char Augment1[5];
/*011*/ char Augment2[5];
/*016*/ char Augment3[5];
/*021*/ char Augment4[5];
/*026*/ char Augment5[5];
/*031*/ char Augment6[5];
/*036*/ char IsEvolving[1];
/*037*/ char EvolveGroup[4];
/*041*/ char EvolveLevel[2];
/*043*/ char OrnamentIcon[5];
/*048*/ char Hash[8];
/*056*/
};
// Restore structure packing to default // Restore structure packing to default
#pragma pack() #pragma pack()

View File

@ -57,11 +57,11 @@ namespace RoF
static inline uint32 RoFToServerTypelessSlot(structs::TypelessInventorySlot_Struct rofSlot); static inline uint32 RoFToServerTypelessSlot(structs::TypelessInventorySlot_Struct rofSlot);
static inline uint32 RoFToServerCorpseSlot(uint32 rofCorpseSlot); static inline uint32 RoFToServerCorpseSlot(uint32 rofCorpseSlot);
// server to client text link converter // server to client say link converter
static inline void ServerToRoFTextLink(std::string& rofTextLink, const std::string& serverTextLink); static inline void ServerToRoFSayLink(std::string& rofSayLink, const std::string& serverSayLink);
// client to server text link converter // client to server say link converter
static inline void RoFToServerTextLink(std::string& serverTextLink, const std::string& rofTextLink); static inline void RoFToServerSayLink(std::string& serverSayLink, const std::string& rofSayLink);
static inline CastingSlot ServerToRoFCastingSlot(EQEmu::CastingSlot slot); static inline CastingSlot ServerToRoFCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot RoFToServerCastingSlot(CastingSlot slot); static inline EQEmu::CastingSlot RoFToServerCastingSlot(CastingSlot slot);
@ -520,7 +520,7 @@ namespace RoF
std::string old_message = emu->message; std::string old_message = emu->message;
std::string new_message; std::string new_message;
ServerToRoFTextLink(new_message, old_message); ServerToRoFSayLink(new_message, old_message);
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36; //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->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
@ -847,7 +847,7 @@ namespace RoF
std::string old_message = emu->message; std::string old_message = emu->message;
std::string new_message; std::string new_message;
ServerToRoFTextLink(new_message, old_message); ServerToRoFSayLink(new_message, old_message);
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm) //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); // new_message = new_message.substr(0, 512);
@ -899,7 +899,7 @@ namespace RoF
for (int i = 0; i < 9; ++i) { for (int i = 0; i < 9; ++i) {
if (old_message_array[i].length() == 0) { break; } if (old_message_array[i].length() == 0) { break; }
ServerToRoFTextLink(new_message_array[i], old_message_array[i]); ServerToRoFSayLink(new_message_array[i], old_message_array[i]);
new_message_size += new_message_array[i].length() + 1; new_message_size += new_message_array[i].length() + 1;
} }
@ -3295,7 +3295,7 @@ namespace RoF
std::string old_message = &emu->message[strlen(emu->sayer)]; std::string old_message = &emu->message[strlen(emu->sayer)];
std::string new_message; std::string new_message;
ServerToRoFTextLink(new_message, old_message); ServerToRoFSayLink(new_message, old_message);
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1; //in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
in->size = strlen(emu->sayer) + new_message.length() + 25; in->size = strlen(emu->sayer) + new_message.length() + 25;
@ -3369,7 +3369,7 @@ namespace RoF
std::string old_message = InBuffer; // start 'Reward' as string std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message; std::string new_message;
ServerToRoFTextLink(new_message, old_message); ServerToRoFSayLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+ in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+ sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
@ -4355,7 +4355,7 @@ namespace RoF
std::string old_message = InBuffer; std::string old_message = InBuffer;
std::string new_message; std::string new_message;
RoFToServerTextLink(new_message, old_message); RoFToServerSayLink(new_message, old_message);
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1; //__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1; __packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
@ -4489,7 +4489,7 @@ namespace RoF
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message; std::string new_message;
RoFToServerTextLink(new_message, old_message); RoFToServerSayLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct); __packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size]; __packet->pBuffer = new unsigned char[__packet->size];
@ -5916,19 +5916,19 @@ namespace RoF
return (rofCorpseSlot - 1); return (rofCorpseSlot - 1);
} }
static inline void ServerToRoFTextLink(std::string& rofTextLink, const std::string& serverTextLink) static inline void ServerToRoFSayLink(std::string& rofSayLink, const std::string& serverSayLink)
{ {
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) { if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
rofTextLink = serverTextLink; rofSayLink = serverSayLink;
return; return;
} }
auto segments = SplitString(serverTextLink, '\x12'); auto segments = SplitString(serverSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) { if (segment_iter & 1) {
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) { if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
rofTextLink.append(segments[segment_iter]); rofSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error // TODO: log size mismatch error
continue; continue;
} }
@ -5938,36 +5938,36 @@ namespace RoF
// RoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (55) // RoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (55)
// Diff: ^ // Diff: ^
rofTextLink.push_back('\x12'); rofSayLink.push_back('\x12');
rofTextLink.append(segments[segment_iter].substr(0, 41)); rofSayLink.append(segments[segment_iter].substr(0, 41));
if (segments[segment_iter][41] == '0') if (segments[segment_iter][41] == '0')
rofTextLink.push_back(segments[segment_iter][42]); rofSayLink.push_back(segments[segment_iter][42]);
else else
rofTextLink.push_back('F'); rofSayLink.push_back('F');
rofTextLink.append(segments[segment_iter].substr(43)); rofSayLink.append(segments[segment_iter].substr(43));
rofTextLink.push_back('\x12'); rofSayLink.push_back('\x12');
} }
else { else {
rofTextLink.append(segments[segment_iter]); rofSayLink.append(segments[segment_iter]);
} }
} }
} }
static inline void RoFToServerTextLink(std::string& serverTextLink, const std::string& rofTextLink) static inline void RoFToServerSayLink(std::string& serverSayLink, const std::string& rofSayLink)
{ {
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (rofTextLink.find('\x12') == std::string::npos)) { if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (rofSayLink.find('\x12') == std::string::npos)) {
serverTextLink = rofTextLink; serverSayLink = rofSayLink;
return; return;
} }
auto segments = SplitString(rofTextLink, '\x12'); auto segments = SplitString(rofSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) { if (segment_iter & 1) {
if (segments[segment_iter].length() <= constants::SayLinkBodySize) { if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
serverTextLink.append(segments[segment_iter]); serverSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error // TODO: log size mismatch error
continue; continue;
} }
@ -5977,14 +5977,14 @@ namespace RoF
// 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: ^ // Diff: ^
serverTextLink.push_back('\x12'); serverSayLink.push_back('\x12');
serverTextLink.append(segments[segment_iter].substr(0, 41)); serverSayLink.append(segments[segment_iter].substr(0, 41));
serverTextLink.push_back('0'); serverSayLink.push_back('0');
serverTextLink.append(segments[segment_iter].substr(41)); serverSayLink.append(segments[segment_iter].substr(41));
serverTextLink.push_back('\x12'); serverSayLink.push_back('\x12');
} }
else { else {
serverTextLink.append(segments[segment_iter]); serverSayLink.append(segments[segment_iter]);
} }
} }
} }

View File

@ -57,11 +57,11 @@ namespace RoF2
static inline uint32 RoF2ToServerTypelessSlot(structs::TypelessInventorySlot_Struct rof2Slot); static inline uint32 RoF2ToServerTypelessSlot(structs::TypelessInventorySlot_Struct rof2Slot);
static inline uint32 RoF2ToServerCorpseSlot(uint32 rof2CorpseSlot); static inline uint32 RoF2ToServerCorpseSlot(uint32 rof2CorpseSlot);
// server to client text link converter // server to client say link converter
static inline void ServerToRoF2TextLink(std::string& rof2TextLink, const std::string& serverTextLink); static inline void ServerToRoF2SayLink(std::string& rof2SayLink, const std::string& serverSayLink);
// client to server text link converter // client to server say link converter
static inline void RoF2ToServerTextLink(std::string& serverTextLink, const std::string& rof2TextLink); static inline void RoF2ToServerSayLink(std::string& serverSayLink, const std::string& rof2SayLink);
static inline CastingSlot ServerToRoF2CastingSlot(EQEmu::CastingSlot slot); static inline CastingSlot ServerToRoF2CastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot RoF2ToServerCastingSlot(CastingSlot slot); static inline EQEmu::CastingSlot RoF2ToServerCastingSlot(CastingSlot slot);
@ -588,7 +588,7 @@ namespace RoF2
std::string old_message = emu->message; std::string old_message = emu->message;
std::string new_message; std::string new_message;
ServerToRoF2TextLink(new_message, old_message); ServerToRoF2SayLink(new_message, old_message);
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36; //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->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
@ -915,7 +915,7 @@ namespace RoF2
std::string old_message = emu->message; std::string old_message = emu->message;
std::string new_message; std::string new_message;
ServerToRoF2TextLink(new_message, old_message); ServerToRoF2SayLink(new_message, old_message);
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm) //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); // new_message = new_message.substr(0, 512);
@ -967,7 +967,7 @@ namespace RoF2
for (int i = 0; i < 9; ++i) { for (int i = 0; i < 9; ++i) {
if (old_message_array[i].length() == 0) { break; } if (old_message_array[i].length() == 0) { break; }
ServerToRoF2TextLink(new_message_array[i], old_message_array[i]); ServerToRoF2SayLink(new_message_array[i], old_message_array[i]);
new_message_size += new_message_array[i].length() + 1; new_message_size += new_message_array[i].length() + 1;
} }
@ -3364,7 +3364,7 @@ namespace RoF2
std::string old_message = &emu->message[strlen(emu->sayer)]; std::string old_message = &emu->message[strlen(emu->sayer)];
std::string new_message; std::string new_message;
ServerToRoF2TextLink(new_message, old_message); ServerToRoF2SayLink(new_message, old_message);
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1; //in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
in->size = strlen(emu->sayer) + new_message.length() + 25; in->size = strlen(emu->sayer) + new_message.length() + 25;
@ -3438,7 +3438,7 @@ namespace RoF2
std::string old_message = InBuffer; // start 'Reward' as string std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message; std::string new_message;
ServerToRoF2TextLink(new_message, old_message); ServerToRoF2SayLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+ in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+ sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
@ -4595,7 +4595,7 @@ namespace RoF2
std::string old_message = InBuffer; std::string old_message = InBuffer;
std::string new_message; std::string new_message;
RoF2ToServerTextLink(new_message, old_message); RoF2ToServerSayLink(new_message, old_message);
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1; //__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1; __packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
@ -4729,7 +4729,7 @@ namespace RoF2
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message; std::string new_message;
RoF2ToServerTextLink(new_message, old_message); RoF2ToServerSayLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct); __packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size]; __packet->pBuffer = new unsigned char[__packet->size];
@ -6233,19 +6233,19 @@ namespace RoF2
return (rof2CorpseSlot + EQEmu::legacy::CORPSE_BEGIN - 1); return (rof2CorpseSlot + EQEmu::legacy::CORPSE_BEGIN - 1);
} }
static inline void ServerToRoF2TextLink(std::string& rof2TextLink, const std::string& serverTextLink) static inline void ServerToRoF2SayLink(std::string& rof2SayLink, const std::string& serverSayLink)
{ {
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) { if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
rof2TextLink = serverTextLink; rof2SayLink = serverSayLink;
return; return;
} }
auto segments = SplitString(serverTextLink, '\x12'); auto segments = SplitString(serverSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) { if (segment_iter & 1) {
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) { if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
rof2TextLink.append(segments[segment_iter]); rof2SayLink.append(segments[segment_iter]);
// TODO: log size mismatch error // TODO: log size mismatch error
continue; continue;
} }
@ -6255,29 +6255,29 @@ namespace RoF2
// 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: // Diff:
rof2TextLink.push_back('\x12'); rof2SayLink.push_back('\x12');
rof2TextLink.append(segments[segment_iter]); rof2SayLink.append(segments[segment_iter]);
rof2TextLink.push_back('\x12'); rof2SayLink.push_back('\x12');
} }
else { else {
rof2TextLink.append(segments[segment_iter]); rof2SayLink.append(segments[segment_iter]);
} }
} }
} }
static inline void RoF2ToServerTextLink(std::string& serverTextLink, const std::string& rof2TextLink) static inline void RoF2ToServerSayLink(std::string& serverSayLink, const std::string& rof2SayLink)
{ {
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (rof2TextLink.find('\x12') == std::string::npos)) { if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (rof2SayLink.find('\x12') == std::string::npos)) {
serverTextLink = rof2TextLink; serverSayLink = rof2SayLink;
return; return;
} }
auto segments = SplitString(rof2TextLink, '\x12'); auto segments = SplitString(rof2SayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) { if (segment_iter & 1) {
if (segments[segment_iter].length() <= constants::SayLinkBodySize) { if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
serverTextLink.append(segments[segment_iter]); serverSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error // TODO: log size mismatch error
continue; continue;
} }
@ -6287,12 +6287,12 @@ namespace RoF2
// 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: // Diff:
serverTextLink.push_back('\x12'); serverSayLink.push_back('\x12');
serverTextLink.append(segments[segment_iter]); serverSayLink.append(segments[segment_iter]);
serverTextLink.push_back('\x12'); serverSayLink.push_back('\x12');
} }
else { else {
serverTextLink.append(segments[segment_iter]); serverSayLink.append(segments[segment_iter]);
} }
} }
} }

View File

@ -5089,6 +5089,23 @@ struct CrystalCountUpdate_Struct
/*012*/ uint32 CareerEbonCrystals; /*012*/ uint32 CareerEbonCrystals;
}; };
struct SayLinkBodyFrame_Struct {
/*000*/ char ActionID[1];
/*001*/ char ItemID[5];
/*006*/ char Augment1[5];
/*011*/ char Augment2[5];
/*016*/ char Augment3[5];
/*021*/ char Augment4[5];
/*026*/ char Augment5[5];
/*031*/ char Augment6[5];
/*036*/ char IsEvolving[1];
/*037*/ char EvolveGroup[4];
/*041*/ char EvolveLevel[2];
/*043*/ char OrnamentIcon[5];
/*048*/ char Hash[8];
/*056*/
};
}; /*structs*/ }; /*structs*/
}; /*RoF2*/ }; /*RoF2*/

View File

@ -5006,6 +5006,23 @@ struct MercenaryMerchantRequest_Struct {
struct MercenaryMerchantResponse_Struct { struct MercenaryMerchantResponse_Struct {
/*0000*/ uint32 ResponseType; /*0000*/ uint32 ResponseType;
/*0004*/ /*0004*/
};
struct SayLinkBodyFrame_Struct {
/*000*/ char ActionID[1];
/*001*/ char ItemID[5];
/*006*/ char Augment1[5];
/*011*/ char Augment2[5];
/*016*/ char Augment3[5];
/*021*/ char Augment4[5];
/*026*/ char Augment5[5];
/*031*/ char Augment6[5];
/*036*/ char IsEvolving[1];
/*037*/ char EvolveGroup[4];
/*041*/ char EvolveLevel[1];
/*042*/ char OrnamentIcon[5];
/*047*/ char Hash[8];
/*055*/
}; };
}; /*structs*/ }; /*structs*/

View File

@ -53,11 +53,11 @@ namespace SoD
static inline uint32 SoDToServerSlot(uint32 sodSlot); static inline uint32 SoDToServerSlot(uint32 sodSlot);
static inline uint32 SoDToServerCorpseSlot(uint32 sodCorpseSlot); static inline uint32 SoDToServerCorpseSlot(uint32 sodCorpseSlot);
// server to client text link converter // server to client say link converter
static inline void ServerToSoDTextLink(std::string& sodTextLink, const std::string& serverTextLink); static inline void ServerToSoDSayLink(std::string& sodSayLink, const std::string& serverSayLink);
// client to server text link converter // client to server say link converter
static inline void SoDToServerTextLink(std::string& serverTextLink, const std::string& sodTextLink); static inline void SoDToServerSayLink(std::string& serverSayLink, const std::string& sodSayLink);
static inline CastingSlot ServerToSoDCastingSlot(EQEmu::CastingSlot slot); static inline CastingSlot ServerToSoDCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot SoDToServerCastingSlot(CastingSlot slot); static inline EQEmu::CastingSlot SoDToServerCastingSlot(CastingSlot slot);
@ -346,7 +346,7 @@ namespace SoD
std::string old_message = emu->message; std::string old_message = emu->message;
std::string new_message; std::string new_message;
ServerToSoDTextLink(new_message, old_message); ServerToSoDSayLink(new_message, old_message);
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1; in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
@ -625,7 +625,7 @@ namespace SoD
std::string old_message = emu->message; std::string old_message = emu->message;
std::string new_message; std::string new_message;
ServerToSoDTextLink(new_message, old_message); ServerToSoDSayLink(new_message, old_message);
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm) //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); // new_message = new_message.substr(0, 512);
@ -677,7 +677,7 @@ namespace SoD
for (int i = 0; i < 9; ++i) { for (int i = 0; i < 9; ++i) {
if (old_message_array[i].length() == 0) { break; } if (old_message_array[i].length() == 0) { break; }
ServerToSoDTextLink(new_message_array[i], old_message_array[i]); ServerToSoDSayLink(new_message_array[i], old_message_array[i]);
new_message_size += new_message_array[i].length() + 1; new_message_size += new_message_array[i].length() + 1;
} }
@ -2156,7 +2156,7 @@ namespace SoD
std::string old_message = &emu->message[strlen(emu->sayer)]; std::string old_message = &emu->message[strlen(emu->sayer)];
std::string new_message; std::string new_message;
ServerToSoDTextLink(new_message, old_message); ServerToSoDSayLink(new_message, old_message);
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1; //in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
in->size = strlen(emu->sayer) + new_message.length() + 25; in->size = strlen(emu->sayer) + new_message.length() + 25;
@ -2252,7 +2252,7 @@ namespace SoD
std::string old_message = InBuffer; // start 'Reward' as string std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message; std::string new_message;
ServerToSoDTextLink(new_message, old_message); ServerToSoDSayLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+ in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+ sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
@ -2953,7 +2953,7 @@ namespace SoD
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)]; std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
std::string new_message; std::string new_message;
SoDToServerTextLink(new_message, old_message); SoDToServerSayLink(new_message, old_message);
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1; __packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
__packet->pBuffer = new unsigned char[__packet->size]; __packet->pBuffer = new unsigned char[__packet->size];
@ -3067,7 +3067,7 @@ namespace SoD
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message; std::string new_message;
SoDToServerTextLink(new_message, old_message); SoDToServerSayLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct); __packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size]; __packet->pBuffer = new unsigned char[__packet->size];
@ -3917,19 +3917,19 @@ namespace SoD
return (sodCorpseSlot - 1); return (sodCorpseSlot - 1);
} }
static inline void ServerToSoDTextLink(std::string& sodTextLink, const std::string& serverTextLink) static inline void ServerToSoDSayLink(std::string& sodSayLink, const std::string& serverSayLink)
{ {
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) { if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
sodTextLink = serverTextLink; sodSayLink = serverSayLink;
return; return;
} }
auto segments = SplitString(serverTextLink, '\x12'); auto segments = SplitString(serverSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) { if (segment_iter & 1) {
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) { if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
sodTextLink.append(segments[segment_iter]); sodSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error // TODO: log size mismatch error
continue; continue;
} }
@ -3939,37 +3939,37 @@ namespace SoD
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50) // SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
// Diff: ^^^^^ ^ // Diff: ^^^^^ ^
sodTextLink.push_back('\x12'); sodSayLink.push_back('\x12');
sodTextLink.append(segments[segment_iter].substr(0, 31)); sodSayLink.append(segments[segment_iter].substr(0, 31));
sodTextLink.append(segments[segment_iter].substr(36, 5)); sodSayLink.append(segments[segment_iter].substr(36, 5));
if (segments[segment_iter][41] == '0') if (segments[segment_iter][41] == '0')
sodTextLink.push_back(segments[segment_iter][42]); sodSayLink.push_back(segments[segment_iter][42]);
else else
sodTextLink.push_back('F'); sodSayLink.push_back('F');
sodTextLink.append(segments[segment_iter].substr(43)); sodSayLink.append(segments[segment_iter].substr(43));
sodTextLink.push_back('\x12'); sodSayLink.push_back('\x12');
} }
else { else {
sodTextLink.append(segments[segment_iter]); sodSayLink.append(segments[segment_iter]);
} }
} }
} }
static inline void SoDToServerTextLink(std::string& serverTextLink, const std::string& sodTextLink) static inline void SoDToServerSayLink(std::string& serverSayLink, const std::string& sodSayLink)
{ {
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (sodTextLink.find('\x12') == std::string::npos)) { if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (sodSayLink.find('\x12') == std::string::npos)) {
serverTextLink = sodTextLink; serverSayLink = sodSayLink;
return; return;
} }
auto segments = SplitString(sodTextLink, '\x12'); auto segments = SplitString(sodSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) { if (segment_iter & 1) {
if (segments[segment_iter].length() <= constants::SayLinkBodySize) { if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
serverTextLink.append(segments[segment_iter]); serverSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error // TODO: log size mismatch error
continue; continue;
} }
@ -3979,16 +3979,16 @@ namespace SoD
// 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: ^^^^^ ^ // Diff: ^^^^^ ^
serverTextLink.push_back('\x12'); serverSayLink.push_back('\x12');
serverTextLink.append(segments[segment_iter].substr(0, 31)); serverSayLink.append(segments[segment_iter].substr(0, 31));
serverTextLink.append("00000"); serverSayLink.append("00000");
serverTextLink.append(segments[segment_iter].substr(31, 5)); serverSayLink.append(segments[segment_iter].substr(31, 5));
serverTextLink.push_back('0'); serverSayLink.push_back('0');
serverTextLink.append(segments[segment_iter].substr(36)); serverSayLink.append(segments[segment_iter].substr(36));
serverTextLink.push_back('\x12'); serverSayLink.push_back('\x12');
} }
else { else {
serverTextLink.append(segments[segment_iter]); serverSayLink.append(segments[segment_iter]);
} }
} }
} }

View File

@ -4385,6 +4385,22 @@ struct MercenaryAssign_Struct {
/*0004*/ uint32 MercUnk01; // /*0004*/ uint32 MercUnk01; //
/*0008*/ uint32 MercUnk02; // /*0008*/ uint32 MercUnk02; //
/*0012*/ /*0012*/
};
struct SayLinkBodyFrame_Struct {
/*000*/ char ActionID[1];
/*001*/ char ItemID[5];
/*006*/ char Augment1[5];
/*011*/ char Augment2[5];
/*016*/ char Augment3[5];
/*021*/ char Augment4[5];
/*026*/ char Augment5[5];
/*031*/ char IsEvolving[1];
/*032*/ char EvolveGroup[4];
/*036*/ char EvolveLevel[1];
/*037*/ char OrnamentIcon[5];
/*042*/ char Hash[8];
/*050*/
}; };
}; /*structs*/ }; /*structs*/

View File

@ -53,11 +53,11 @@ namespace SoF
static inline uint32 SoFToServerSlot(uint32 sofSlot); static inline uint32 SoFToServerSlot(uint32 sofSlot);
static inline uint32 SoFToServerCorpseSlot(uint32 sofCorpseSlot); static inline uint32 SoFToServerCorpseSlot(uint32 sofCorpseSlot);
// server to client text link converter // server to client say link converter
static inline void ServerToSoFTextLink(std::string& sofTextLink, const std::string& serverTextLink); static inline void ServerToSoFSayLink(std::string& sofSayLink, const std::string& serverSayLink);
// client to server text link converter // client to server say link converter
static inline void SoFToServerTextLink(std::string& serverTextLink, const std::string& sofTextLink); static inline void SoFToServerSayLink(std::string& serverSayLink, const std::string& sofSayLink);
static inline CastingSlot ServerToSoFCastingSlot(EQEmu::CastingSlot slot); static inline CastingSlot ServerToSoFCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot SoFToServerCastingSlot(CastingSlot slot, uint32 itemlocation); static inline EQEmu::CastingSlot SoFToServerCastingSlot(CastingSlot slot, uint32 itemlocation);
@ -328,7 +328,7 @@ namespace SoF
std::string old_message = emu->message; std::string old_message = emu->message;
std::string new_message; std::string new_message;
ServerToSoFTextLink(new_message, old_message); ServerToSoFSayLink(new_message, old_message);
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1; in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
@ -613,7 +613,7 @@ namespace SoF
std::string old_message = emu->message; std::string old_message = emu->message;
std::string new_message; std::string new_message;
ServerToSoFTextLink(new_message, old_message); ServerToSoFSayLink(new_message, old_message);
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm) //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); // new_message = new_message.substr(0, 512);
@ -665,7 +665,7 @@ namespace SoF
for (int i = 0; i < 9; ++i) { for (int i = 0; i < 9; ++i) {
if (old_message_array[i].length() == 0) { break; } if (old_message_array[i].length() == 0) { break; }
ServerToSoFTextLink(new_message_array[i], old_message_array[i]); ServerToSoFSayLink(new_message_array[i], old_message_array[i]);
new_message_size += new_message_array[i].length() + 1; new_message_size += new_message_array[i].length() + 1;
} }
@ -1814,7 +1814,7 @@ namespace SoF
std::string old_message = &emu->message[strlen(emu->sayer)]; std::string old_message = &emu->message[strlen(emu->sayer)];
std::string new_message; std::string new_message;
ServerToSoFTextLink(new_message, old_message); ServerToSoFSayLink(new_message, old_message);
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1; //in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
in->size = strlen(emu->sayer) + new_message.length() + 25; in->size = strlen(emu->sayer) + new_message.length() + 25;
@ -1882,7 +1882,7 @@ namespace SoF
std::string old_message = InBuffer; // start 'Reward' as string std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message; std::string new_message;
ServerToSoFTextLink(new_message, old_message); ServerToSoFSayLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+ in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+ sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
@ -2415,7 +2415,7 @@ namespace SoF
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)]; std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
std::string new_message; std::string new_message;
SoFToServerTextLink(new_message, old_message); SoFToServerSayLink(new_message, old_message);
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1; __packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
__packet->pBuffer = new unsigned char[__packet->size]; __packet->pBuffer = new unsigned char[__packet->size];
@ -2529,7 +2529,7 @@ namespace SoF
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message; std::string new_message;
SoFToServerTextLink(new_message, old_message); SoFToServerSayLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct); __packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size]; __packet->pBuffer = new unsigned char[__packet->size];
@ -3316,19 +3316,19 @@ namespace SoF
return (sofCorpseSlot - 1); return (sofCorpseSlot - 1);
} }
static inline void ServerToSoFTextLink(std::string& sofTextLink, const std::string& serverTextLink) static inline void ServerToSoFSayLink(std::string& sofSayLink, const std::string& serverSayLink)
{ {
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) { if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
sofTextLink = serverTextLink; sofSayLink = serverSayLink;
return; return;
} }
auto segments = SplitString(serverTextLink, '\x12'); auto segments = SplitString(serverSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) { if (segment_iter & 1) {
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) { if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
sofTextLink.append(segments[segment_iter]); sofSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error // TODO: log size mismatch error
continue; continue;
} }
@ -3338,37 +3338,37 @@ namespace SoF
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50) // SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
// Diff: ^^^^^ ^ // Diff: ^^^^^ ^
sofTextLink.push_back('\x12'); sofSayLink.push_back('\x12');
sofTextLink.append(segments[segment_iter].substr(0, 31)); sofSayLink.append(segments[segment_iter].substr(0, 31));
sofTextLink.append(segments[segment_iter].substr(36, 5)); sofSayLink.append(segments[segment_iter].substr(36, 5));
if (segments[segment_iter][41] == '0') if (segments[segment_iter][41] == '0')
sofTextLink.push_back(segments[segment_iter][42]); sofSayLink.push_back(segments[segment_iter][42]);
else else
sofTextLink.push_back('F'); sofSayLink.push_back('F');
sofTextLink.append(segments[segment_iter].substr(43)); sofSayLink.append(segments[segment_iter].substr(43));
sofTextLink.push_back('\x12'); sofSayLink.push_back('\x12');
} }
else { else {
sofTextLink.append(segments[segment_iter]); sofSayLink.append(segments[segment_iter]);
} }
} }
} }
static inline void SoFToServerTextLink(std::string& serverTextLink, const std::string& sofTextLink) static inline void SoFToServerSayLink(std::string& serverSayLink, const std::string& sofSayLink)
{ {
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (sofTextLink.find('\x12') == std::string::npos)) { if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (sofSayLink.find('\x12') == std::string::npos)) {
serverTextLink = sofTextLink; serverSayLink = sofSayLink;
return; return;
} }
auto segments = SplitString(sofTextLink, '\x12'); auto segments = SplitString(sofSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) { if (segment_iter & 1) {
if (segments[segment_iter].length() <= constants::SayLinkBodySize) { if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
serverTextLink.append(segments[segment_iter]); serverSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error // TODO: log size mismatch error
continue; continue;
} }
@ -3378,16 +3378,16 @@ namespace SoF
// 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: ^^^^^ ^ // Diff: ^^^^^ ^
serverTextLink.push_back('\x12'); serverSayLink.push_back('\x12');
serverTextLink.append(segments[segment_iter].substr(0, 31)); serverSayLink.append(segments[segment_iter].substr(0, 31));
serverTextLink.append("00000"); serverSayLink.append("00000");
serverTextLink.append(segments[segment_iter].substr(31, 5)); serverSayLink.append(segments[segment_iter].substr(31, 5));
serverTextLink.push_back('0'); serverSayLink.push_back('0');
serverTextLink.append(segments[segment_iter].substr(36)); serverSayLink.append(segments[segment_iter].substr(36));
serverTextLink.push_back('\x12'); serverSayLink.push_back('\x12');
} }
else { else {
serverTextLink.append(segments[segment_iter]); serverSayLink.append(segments[segment_iter]);
} }
} }
} }

View File

@ -4156,6 +4156,22 @@ struct AltCurrencySellItem_Struct {
/*004*/ uint32 slot_id; /*004*/ uint32 slot_id;
/*006*/ uint32 charges; /*006*/ uint32 charges;
/*010*/ uint32 cost; /*010*/ uint32 cost;
};
struct SayLinkBodyFrame_Struct {
/*000*/ char ActionID[1];
/*001*/ char ItemID[5];
/*006*/ char Augment1[5];
/*011*/ char Augment2[5];
/*016*/ char Augment3[5];
/*021*/ char Augment4[5];
/*026*/ char Augment5[5];
/*031*/ char IsEvolving[1];
/*032*/ char EvolveGroup[4];
/*036*/ char EvolveLevel[1];
/*037*/ char OrnamentIcon[5];
/*042*/ char Hash[8];
/*050*/
}; };
}; /*structs*/ }; /*structs*/

View File

@ -52,11 +52,11 @@ namespace Titanium
static inline uint32 TitaniumToServerSlot(int16 titaniumSlot); static inline uint32 TitaniumToServerSlot(int16 titaniumSlot);
static inline uint32 TitaniumToServerCorpseSlot(int16 titaniumCorpseSlot); static inline uint32 TitaniumToServerCorpseSlot(int16 titaniumCorpseSlot);
// server to client text link converter // server to client say link converter
static inline void ServerToTitaniumTextLink(std::string& titaniumTextLink, const std::string& serverTextLink); static inline void ServerToTitaniumSayLink(std::string& titaniumSayLink, const std::string& serverSayLink);
// client to server text link converter // client to server say link converter
static inline void TitaniumToServerTextLink(std::string& serverTextLink, const std::string& titaniumTextLink); static inline void TitaniumToServerSayLink(std::string& serverSayLink, const std::string& titaniumSayLink);
static inline CastingSlot ServerToTitaniumCastingSlot(EQEmu::CastingSlot slot); static inline CastingSlot ServerToTitaniumCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot TitaniumToServerCastingSlot(CastingSlot slot, uint32 itemlocation); static inline EQEmu::CastingSlot TitaniumToServerCastingSlot(CastingSlot slot, uint32 itemlocation);
@ -290,7 +290,7 @@ namespace Titanium
std::string old_message = emu->message; std::string old_message = emu->message;
std::string new_message; std::string new_message;
ServerToTitaniumTextLink(new_message, old_message); ServerToTitaniumSayLink(new_message, old_message);
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1; in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
@ -532,7 +532,7 @@ namespace Titanium
std::string old_message = emu->message; std::string old_message = emu->message;
std::string new_message; std::string new_message;
ServerToTitaniumTextLink(new_message, old_message); ServerToTitaniumSayLink(new_message, old_message);
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm) //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); // new_message = new_message.substr(0, 512);
@ -574,7 +574,7 @@ namespace Titanium
for (int i = 0; i < 9; ++i) { for (int i = 0; i < 9; ++i) {
if (old_message_array[i].length() == 0) { break; } if (old_message_array[i].length() == 0) { break; }
ServerToTitaniumTextLink(new_message_array[i], old_message_array[i]); ServerToTitaniumSayLink(new_message_array[i], old_message_array[i]);
new_message_size += new_message_array[i].length() + 1; new_message_size += new_message_array[i].length() + 1;
} }
@ -1402,7 +1402,7 @@ namespace Titanium
std::string old_message = &emu->message[strlen(emu->sayer)]; std::string old_message = &emu->message[strlen(emu->sayer)];
std::string new_message; std::string new_message;
ServerToTitaniumTextLink(new_message, old_message); ServerToTitaniumSayLink(new_message, old_message);
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1; //in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
in->size = strlen(emu->sayer) + new_message.length() + 25; in->size = strlen(emu->sayer) + new_message.length() + 25;
@ -1458,7 +1458,7 @@ namespace Titanium
std::string old_message = InBuffer; // start 'Reward' as string std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message; std::string new_message;
ServerToTitaniumTextLink(new_message, old_message); ServerToTitaniumSayLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct) + in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct) +
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct) + sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct) +
@ -1819,7 +1819,7 @@ namespace Titanium
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)]; std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
std::string new_message; std::string new_message;
TitaniumToServerTextLink(new_message, old_message); TitaniumToServerSayLink(new_message, old_message);
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1; __packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
__packet->pBuffer = new unsigned char[__packet->size]; __packet->pBuffer = new unsigned char[__packet->size];
@ -1891,7 +1891,7 @@ namespace Titanium
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message; std::string new_message;
TitaniumToServerTextLink(new_message, old_message); TitaniumToServerSayLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct); __packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size]; __packet->pBuffer = new unsigned char[__packet->size];
@ -2485,19 +2485,19 @@ namespace Titanium
return titaniumCorpseSlot; return titaniumCorpseSlot;
} }
static inline void ServerToTitaniumTextLink(std::string& titaniumTextLink, const std::string& serverTextLink) static inline void ServerToTitaniumSayLink(std::string& titaniumSayLink, const std::string& serverSayLink)
{ {
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) { if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
titaniumTextLink = serverTextLink; titaniumSayLink = serverSayLink;
return; return;
} }
auto segments = SplitString(serverTextLink, '\x12'); auto segments = SplitString(serverSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) { if (segment_iter & 1) {
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) { if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
titaniumTextLink.append(segments[segment_iter]); titaniumSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error // TODO: log size mismatch error
continue; continue;
} }
@ -2507,37 +2507,37 @@ namespace Titanium
// 6.2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXXXXX (45) // 6.2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXXXXX (45)
// Diff: ^^^^^ ^ ^^^^^ // Diff: ^^^^^ ^ ^^^^^
titaniumTextLink.push_back('\x12'); titaniumSayLink.push_back('\x12');
titaniumTextLink.append(segments[segment_iter].substr(0, 31)); titaniumSayLink.append(segments[segment_iter].substr(0, 31));
titaniumTextLink.append(segments[segment_iter].substr(36, 5)); titaniumSayLink.append(segments[segment_iter].substr(36, 5));
if (segments[segment_iter][41] == '0') if (segments[segment_iter][41] == '0')
titaniumTextLink.push_back(segments[segment_iter][42]); titaniumSayLink.push_back(segments[segment_iter][42]);
else else
titaniumTextLink.push_back('F'); titaniumSayLink.push_back('F');
titaniumTextLink.append(segments[segment_iter].substr(48)); titaniumSayLink.append(segments[segment_iter].substr(48));
titaniumTextLink.push_back('\x12'); titaniumSayLink.push_back('\x12');
} }
else { else {
titaniumTextLink.append(segments[segment_iter]); titaniumSayLink.append(segments[segment_iter]);
} }
} }
} }
static inline void TitaniumToServerTextLink(std::string& serverTextLink, const std::string& titaniumTextLink) static inline void TitaniumToServerSayLink(std::string& serverSayLink, const std::string& titaniumSayLink)
{ {
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (titaniumTextLink.find('\x12') == std::string::npos)) { if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (titaniumSayLink.find('\x12') == std::string::npos)) {
serverTextLink = titaniumTextLink; serverSayLink = titaniumSayLink;
return; return;
} }
auto segments = SplitString(titaniumTextLink, '\x12'); auto segments = SplitString(titaniumSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) { if (segment_iter & 1) {
if (segments[segment_iter].length() <= constants::SayLinkBodySize) { if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
serverTextLink.append(segments[segment_iter]); serverSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error // TODO: log size mismatch error
continue; continue;
} }
@ -2547,18 +2547,18 @@ namespace Titanium
// 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: ^^^^^ ^ ^^^^^ // Diff: ^^^^^ ^ ^^^^^
serverTextLink.push_back('\x12'); serverSayLink.push_back('\x12');
serverTextLink.append(segments[segment_iter].substr(0, 31)); serverSayLink.append(segments[segment_iter].substr(0, 31));
serverTextLink.append("00000"); serverSayLink.append("00000");
serverTextLink.append(segments[segment_iter].substr(31, 5)); serverSayLink.append(segments[segment_iter].substr(31, 5));
serverTextLink.push_back('0'); serverSayLink.push_back('0');
serverTextLink.push_back(segments[segment_iter][36]); serverSayLink.push_back(segments[segment_iter][36]);
serverTextLink.append("00000"); serverSayLink.append("00000");
serverTextLink.append(segments[segment_iter].substr(37)); serverSayLink.append(segments[segment_iter].substr(37));
serverTextLink.push_back('\x12'); serverSayLink.push_back('\x12');
} }
else { else {
serverTextLink.append(segments[segment_iter]); serverSayLink.append(segments[segment_iter]);
} }
} }
} }

View File

@ -3565,6 +3565,21 @@ struct LFGuild_GuildToggle_Struct
// char ScrollName; // '0' // char ScrollName; // '0'
//}; //};
struct SayLinkBodyFrame_Struct {
/*000*/ char ActionID[1];
/*001*/ char ItemID[5];
/*006*/ char Augment1[5];
/*011*/ char Augment2[5];
/*016*/ char Augment3[5];
/*021*/ char Augment4[5];
/*026*/ char Augment5[5];
/*031*/ char IsEvolving[1];
/*032*/ char EvolveGroup[4];
/*036*/ char EvolveLevel[1];
/*037*/ char Hash[8];
/*045*/
};
}; /*structs*/ }; /*structs*/
}; /*Titanium*/ }; /*Titanium*/

View File

@ -53,11 +53,11 @@ namespace UF
static inline uint32 UFToServerSlot(uint32 ufSlot); static inline uint32 UFToServerSlot(uint32 ufSlot);
static inline uint32 UFToServerCorpseSlot(uint32 ufCorpseSlot); static inline uint32 UFToServerCorpseSlot(uint32 ufCorpseSlot);
// server to client text link converter // server to client say link converter
static inline void ServerToUFTextLink(std::string& ufTextLink, const std::string& serverTextLink); static inline void ServerToUFSayLink(std::string& ufSayLink, const std::string& serverSayLink);
// client to server text link converter // client to server say link converter
static inline void UFToServerTextLink(std::string& serverTextLink, const std::string& ufTextLink); static inline void UFToServerSayLink(std::string& serverSayLink, const std::string& ufSayLink);
static inline CastingSlot ServerToUFCastingSlot(EQEmu::CastingSlot slot); static inline CastingSlot ServerToUFCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot UFToServerCastingSlot(CastingSlot slot); static inline EQEmu::CastingSlot UFToServerCastingSlot(CastingSlot slot);
@ -463,7 +463,7 @@ namespace UF
std::string old_message = emu->message; std::string old_message = emu->message;
std::string new_message; std::string new_message;
ServerToUFTextLink(new_message, old_message); ServerToUFSayLink(new_message, old_message);
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36; //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->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
@ -762,7 +762,7 @@ namespace UF
std::string old_message = emu->message; std::string old_message = emu->message;
std::string new_message; std::string new_message;
ServerToUFTextLink(new_message, old_message); ServerToUFSayLink(new_message, old_message);
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm) //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); // new_message = new_message.substr(0, 512);
@ -814,7 +814,7 @@ namespace UF
for (int i = 0; i < 9; ++i) { for (int i = 0; i < 9; ++i) {
if (old_message_array[i].length() == 0) { break; } if (old_message_array[i].length() == 0) { break; }
ServerToUFTextLink(new_message_array[i], old_message_array[i]); ServerToUFSayLink(new_message_array[i], old_message_array[i]);
new_message_size += new_message_array[i].length() + 1; new_message_size += new_message_array[i].length() + 1;
} }
@ -2469,7 +2469,7 @@ namespace UF
std::string old_message = &emu->message[strlen(emu->sayer)]; std::string old_message = &emu->message[strlen(emu->sayer)];
std::string new_message; std::string new_message;
ServerToUFTextLink(new_message, old_message); ServerToUFSayLink(new_message, old_message);
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1; //in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
in->size = strlen(emu->sayer) + new_message.length() + 25; in->size = strlen(emu->sayer) + new_message.length() + 25;
@ -2539,7 +2539,7 @@ namespace UF
std::string old_message = InBuffer; // start 'Reward' as string std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message; std::string new_message;
ServerToUFTextLink(new_message, old_message); ServerToUFSayLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+ in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+ sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
@ -3287,7 +3287,7 @@ namespace UF
std::string old_message = InBuffer; std::string old_message = InBuffer;
std::string new_message; std::string new_message;
UFToServerTextLink(new_message, old_message); UFToServerSayLink(new_message, old_message);
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1; //__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1; __packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
@ -3421,7 +3421,7 @@ namespace UF
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message; std::string new_message;
UFToServerTextLink(new_message, old_message); UFToServerSayLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct); __packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size]; __packet->pBuffer = new unsigned char[__packet->size];
@ -4290,19 +4290,19 @@ namespace UF
return (ufCorpseSlot - 1); return (ufCorpseSlot - 1);
} }
static inline void ServerToUFTextLink(std::string& ufTextLink, const std::string& serverTextLink) static inline void ServerToUFSayLink(std::string& ufSayLink, const std::string& serverSayLink)
{ {
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) { if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
ufTextLink = serverTextLink; ufSayLink = serverSayLink;
return; return;
} }
auto segments = SplitString(serverTextLink, '\x12'); auto segments = SplitString(serverSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) { if (segment_iter & 1) {
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) { if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
ufTextLink.append(segments[segment_iter]); ufSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error // TODO: log size mismatch error
continue; continue;
} }
@ -4312,37 +4312,37 @@ namespace UF
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50) // SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
// Diff: ^^^^^ ^ // Diff: ^^^^^ ^
ufTextLink.push_back('\x12'); ufSayLink.push_back('\x12');
ufTextLink.append(segments[segment_iter].substr(0, 31)); ufSayLink.append(segments[segment_iter].substr(0, 31));
ufTextLink.append(segments[segment_iter].substr(36, 5)); ufSayLink.append(segments[segment_iter].substr(36, 5));
if (segments[segment_iter][41] == '0') if (segments[segment_iter][41] == '0')
ufTextLink.push_back(segments[segment_iter][42]); ufSayLink.push_back(segments[segment_iter][42]);
else else
ufTextLink.push_back('F'); ufSayLink.push_back('F');
ufTextLink.append(segments[segment_iter].substr(43)); ufSayLink.append(segments[segment_iter].substr(43));
ufTextLink.push_back('\x12'); ufSayLink.push_back('\x12');
} }
else { else {
ufTextLink.append(segments[segment_iter]); ufSayLink.append(segments[segment_iter]);
} }
} }
} }
static inline void UFToServerTextLink(std::string& serverTextLink, const std::string& ufTextLink) static inline void UFToServerSayLink(std::string& serverSayLink, const std::string& ufSayLink)
{ {
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (ufTextLink.find('\x12') == std::string::npos)) { if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (ufSayLink.find('\x12') == std::string::npos)) {
serverTextLink = ufTextLink; serverSayLink = ufSayLink;
return; return;
} }
auto segments = SplitString(ufTextLink, '\x12'); auto segments = SplitString(ufSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) { if (segment_iter & 1) {
if (segments[segment_iter].length() <= constants::SayLinkBodySize) { if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
serverTextLink.append(segments[segment_iter]); serverSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error // TODO: log size mismatch error
continue; continue;
} }
@ -4352,16 +4352,16 @@ namespace UF
// 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: ^^^^^ ^ // Diff: ^^^^^ ^
serverTextLink.push_back('\x12'); serverSayLink.push_back('\x12');
serverTextLink.append(segments[segment_iter].substr(0, 31)); serverSayLink.append(segments[segment_iter].substr(0, 31));
serverTextLink.append("00000"); serverSayLink.append("00000");
serverTextLink.append(segments[segment_iter].substr(31, 5)); serverSayLink.append(segments[segment_iter].substr(31, 5));
serverTextLink.push_back('0'); serverSayLink.push_back('0');
serverTextLink.append(segments[segment_iter].substr(36)); serverSayLink.append(segments[segment_iter].substr(36));
serverTextLink.push_back('\x12'); serverSayLink.push_back('\x12');
} }
else { else {
serverTextLink.append(segments[segment_iter]); serverSayLink.append(segments[segment_iter]);
} }
} }
} }

View File

@ -4489,6 +4489,22 @@ struct MercenaryAssign_Struct {
/*0004*/ uint32 MercUnk01; // /*0004*/ uint32 MercUnk01; //
/*0008*/ uint32 MercUnk02; // /*0008*/ uint32 MercUnk02; //
/*0012*/ /*0012*/
};
struct SayLinkBodyFrame_Struct {
/*000*/ char ActionID[1];
/*001*/ char ItemID[5];
/*006*/ char Augment1[5];
/*011*/ char Augment2[5];
/*016*/ char Augment3[5];
/*021*/ char Augment4[5];
/*026*/ char Augment5[5];
/*031*/ char IsEvolving[1];
/*032*/ char EvolveGroup[4];
/*036*/ char EvolveLevel[1];
/*037*/ char OrnamentIcon[5];
/*042*/ char Hash[8];
/*050*/
}; };
}; /*structs*/ }; /*structs*/

View File

@ -29,10 +29,10 @@
bool EQEmu::saylink::DegenerateLinkBody(SayLinkBody_Struct& say_link_body_struct, const std::string& say_link_body) bool EQEmu::saylink::DegenerateLinkBody(SayLinkBody_Struct& say_link_body_struct, const std::string& say_link_body)
{ {
memset(&say_link_body_struct, 0, sizeof(say_link_body_struct)); memset(&say_link_body_struct, 0, sizeof(say_link_body_struct));
if (say_link_body.length() != EQEmu::legacy::TEXT_LINK_BODY_LENGTH) if (say_link_body.length() != EQEmu::constants::SayLinkBodySize)
return false; return false;
say_link_body_struct.unknown_1 = (uint8)strtol(say_link_body.substr(0, 1).c_str(), nullptr, 16); say_link_body_struct.action_id = (uint8)strtol(say_link_body.substr(0, 1).c_str(), nullptr, 16);
say_link_body_struct.item_id = (uint32)strtol(say_link_body.substr(1, 5).c_str(), nullptr, 16); say_link_body_struct.item_id = (uint32)strtol(say_link_body.substr(1, 5).c_str(), nullptr, 16);
say_link_body_struct.augment_1 = (uint32)strtol(say_link_body.substr(6, 5).c_str(), nullptr, 16); say_link_body_struct.augment_1 = (uint32)strtol(say_link_body.substr(6, 5).c_str(), nullptr, 16);
say_link_body_struct.augment_2 = (uint32)strtol(say_link_body.substr(11, 5).c_str(), nullptr, 16); say_link_body_struct.augment_2 = (uint32)strtol(say_link_body.substr(11, 5).c_str(), nullptr, 16);
@ -44,7 +44,7 @@ bool EQEmu::saylink::DegenerateLinkBody(SayLinkBody_Struct& say_link_body_struct
say_link_body_struct.evolve_group = (uint32)strtol(say_link_body.substr(37, 4).c_str(), nullptr, 16); say_link_body_struct.evolve_group = (uint32)strtol(say_link_body.substr(37, 4).c_str(), nullptr, 16);
say_link_body_struct.evolve_level = (uint8)strtol(say_link_body.substr(41, 2).c_str(), nullptr, 16); say_link_body_struct.evolve_level = (uint8)strtol(say_link_body.substr(41, 2).c_str(), nullptr, 16);
say_link_body_struct.ornament_icon = (uint32)strtol(say_link_body.substr(43, 5).c_str(), nullptr, 16); say_link_body_struct.ornament_icon = (uint32)strtol(say_link_body.substr(43, 5).c_str(), nullptr, 16);
say_link_body_struct.hash = (int)strtol(say_link_body.substr(48, 8).c_str(), nullptr, 16); say_link_body_struct.hash = (uint32)strtol(say_link_body.substr(48, 8).c_str(), nullptr, 16);
return true; return true;
} }
@ -53,7 +53,7 @@ bool EQEmu::saylink::GenerateLinkBody(std::string& say_link_body, const SayLinkB
{ {
say_link_body = StringFormat( say_link_body = StringFormat(
"%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X", "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X",
(0x0F & say_link_body_struct.unknown_1), (0x0F & say_link_body_struct.action_id),
(0x000FFFFF & say_link_body_struct.item_id), (0x000FFFFF & say_link_body_struct.item_id),
(0x000FFFFF & say_link_body_struct.augment_1), (0x000FFFFF & say_link_body_struct.augment_1),
(0x000FFFFF & say_link_body_struct.augment_2), (0x000FFFFF & say_link_body_struct.augment_2),
@ -68,7 +68,7 @@ bool EQEmu::saylink::GenerateLinkBody(std::string& say_link_body, const SayLinkB
(0xFFFFFFFF & say_link_body_struct.hash) (0xFFFFFFFF & say_link_body_struct.hash)
); );
if (say_link_body.length() != EQEmu::legacy::TEXT_LINK_BODY_LENGTH) if (say_link_body.length() != EQEmu::constants::SayLinkBodySize)
return false; return false;
return true; return true;
@ -79,7 +79,7 @@ EQEmu::SayLinkEngine::SayLinkEngine()
Reset(); Reset();
} }
std::string EQEmu::SayLinkEngine::GenerateLink() const std::string& EQEmu::SayLinkEngine::GenerateLink()
{ {
m_Link.clear(); m_Link.clear();
m_LinkBody.clear(); m_LinkBody.clear();
@ -88,18 +88,26 @@ std::string EQEmu::SayLinkEngine::GenerateLink()
generate_body(); generate_body();
generate_text(); generate_text();
if ((m_LinkBody.length() == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) && (m_LinkText.length() > 0)) { if ((m_LinkBody.length() == EQEmu::constants::SayLinkBodySize) && (m_LinkText.length() > 0)) {
m_Link.push_back(0x12); m_Link.push_back(0x12);
m_Link.append(m_LinkBody); m_Link.append(m_LinkBody);
m_Link.append(m_LinkText); m_Link.append(m_LinkText);
m_Link.push_back(0x12); m_Link.push_back(0x12);
} }
if ((m_Link.length() == 0) || (m_Link.length() > 250)) { if ((m_Link.length() == 0) || (m_Link.length() > (EQEmu::constants::SayLinkMaximumSize))) {
m_Error = true; m_Error = true;
m_Link = "<LINKER ERROR>"; m_Link = "<LINKER ERROR>";
Log(Logs::General, Logs::Error, "TextLink::GenerateLink() failed to generate a useable text link (LinkType: %i, Lengths: {link: %u, body: %u, text: %u})", Log(Logs::General, Logs::Error, "SayLinkEngine::GenerateLink() failed to generate a useable say link");
m_LinkType, m_Link.length(), m_LinkBody.length(), m_LinkText.length()); Log(Logs::General, Logs::Error, ">> LinkType: %i, Lengths: {link: %u(%u), body: %u(%u), text: %u(%u)}",
m_LinkType,
m_Link.length(),
EQEmu::constants::SayLinkMaximumSize,
m_LinkBody.length(),
EQEmu::constants::SayLinkBodySize,
m_LinkText.length(),
EQEmu::constants::SayLinkTextSize
);
Log(Logs::General, Logs::Error, ">> LinkBody: %s", m_LinkBody.c_str()); Log(Logs::General, Logs::Error, ">> LinkBody: %s", m_LinkBody.c_str());
Log(Logs::General, Logs::Error, ">> LinkText: %s", m_LinkText.c_str()); Log(Logs::General, Logs::Error, ">> LinkText: %s", m_LinkText.c_str());
} }
@ -113,20 +121,10 @@ void EQEmu::SayLinkEngine::Reset()
m_ItemData = nullptr; m_ItemData = nullptr;
m_LootData = nullptr; m_LootData = nullptr;
m_ItemInst = nullptr; m_ItemInst = nullptr;
m_Proxy_unknown_1 = 0;
m_ProxyItemID = 0; memset(&m_LinkBodyStruct, 0, sizeof(SayLinkBody_Struct));
m_ProxyAugment1ID = 0; memset(&m_LinkProxyStruct, 0, sizeof(SayLinkProxy_Struct));
m_ProxyAugment2ID = 0;
m_ProxyAugment3ID = 0;
m_ProxyAugment4ID = 0;
m_ProxyAugment5ID = 0;
m_ProxyAugment6ID = 0;
m_ProxyIsEvolving = 0;
m_ProxyEvolveGroup = 0;
m_ProxyEvolveLevel = 0;
m_ProxyOrnamentIcon = 0;
m_ProxyHash = 0;
m_ProxyText = nullptr;
m_TaskUse = false; m_TaskUse = false;
m_Link.clear(); m_Link.clear();
m_LinkBody.clear(); m_LinkBody.clear();
@ -194,32 +192,32 @@ void EQEmu::SayLinkEngine::generate_body()
break; break;
} }
if (m_Proxy_unknown_1) if (m_LinkProxyStruct.action_id)
m_LinkBodyStruct.unknown_1 = m_Proxy_unknown_1; m_LinkBodyStruct.action_id = m_LinkProxyStruct.action_id;
if (m_ProxyItemID) if (m_LinkProxyStruct.item_id)
m_LinkBodyStruct.item_id = m_ProxyItemID; m_LinkBodyStruct.item_id = m_LinkProxyStruct.item_id;
if (m_ProxyAugment1ID) if (m_LinkProxyStruct.augment_1)
m_LinkBodyStruct.augment_1 = m_ProxyAugment1ID; m_LinkBodyStruct.augment_1 = m_LinkProxyStruct.augment_1;
if (m_ProxyAugment2ID) if (m_LinkProxyStruct.augment_2)
m_LinkBodyStruct.augment_2 = m_ProxyAugment2ID; m_LinkBodyStruct.augment_2 = m_LinkProxyStruct.augment_2;
if (m_ProxyAugment3ID) if (m_LinkProxyStruct.augment_3)
m_LinkBodyStruct.augment_3 = m_ProxyAugment3ID; m_LinkBodyStruct.augment_3 = m_LinkProxyStruct.augment_3;
if (m_ProxyAugment4ID) if (m_LinkProxyStruct.augment_4)
m_LinkBodyStruct.augment_4 = m_ProxyAugment4ID; m_LinkBodyStruct.augment_4 = m_LinkProxyStruct.augment_4;
if (m_ProxyAugment5ID) if (m_LinkProxyStruct.augment_5)
m_LinkBodyStruct.augment_5 = m_ProxyAugment5ID; m_LinkBodyStruct.augment_5 = m_LinkProxyStruct.augment_5;
if (m_ProxyAugment6ID) if (m_LinkProxyStruct.augment_6)
m_LinkBodyStruct.augment_6 = m_ProxyAugment6ID; m_LinkBodyStruct.augment_6 = m_LinkProxyStruct.augment_6;
if (m_ProxyIsEvolving) if (m_LinkProxyStruct.is_evolving)
m_LinkBodyStruct.is_evolving = m_ProxyIsEvolving; m_LinkBodyStruct.is_evolving = m_LinkProxyStruct.is_evolving;
if (m_ProxyEvolveGroup) if (m_LinkProxyStruct.evolve_group)
m_LinkBodyStruct.evolve_group = m_ProxyEvolveGroup; m_LinkBodyStruct.evolve_group = m_LinkProxyStruct.evolve_group;
if (m_ProxyEvolveLevel) if (m_LinkProxyStruct.evolve_level)
m_LinkBodyStruct.evolve_level = m_ProxyEvolveLevel; m_LinkBodyStruct.evolve_level = m_LinkProxyStruct.evolve_level;
if (m_ProxyOrnamentIcon) if (m_LinkProxyStruct.ornament_icon)
m_LinkBodyStruct.ornament_icon = m_ProxyOrnamentIcon; m_LinkBodyStruct.ornament_icon = m_LinkProxyStruct.ornament_icon;
if (m_ProxyHash) if (m_LinkProxyStruct.hash)
m_LinkBodyStruct.hash = m_ProxyHash; m_LinkBodyStruct.hash = m_LinkProxyStruct.hash;
if (m_TaskUse) if (m_TaskUse)
@ -227,7 +225,7 @@ void EQEmu::SayLinkEngine::generate_body()
m_LinkBody = StringFormat( m_LinkBody = StringFormat(
"%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X", "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X",
(0x0F & m_LinkBodyStruct.unknown_1), (0x0F & m_LinkBodyStruct.action_id),
(0x000FFFFF & m_LinkBodyStruct.item_id), (0x000FFFFF & m_LinkBodyStruct.item_id),
(0x000FFFFF & m_LinkBodyStruct.augment_1), (0x000FFFFF & m_LinkBodyStruct.augment_1),
(0x000FFFFF & m_LinkBodyStruct.augment_2), (0x000FFFFF & m_LinkBodyStruct.augment_2),
@ -245,8 +243,8 @@ void EQEmu::SayLinkEngine::generate_body()
void EQEmu::SayLinkEngine::generate_text() void EQEmu::SayLinkEngine::generate_text()
{ {
if (m_ProxyText != nullptr) { if (m_LinkProxyStruct.text != nullptr) {
m_LinkText = m_ProxyText; m_LinkText = m_LinkProxyStruct.text;
return; return;
} }

View File

@ -47,7 +47,7 @@ namespace EQEmu
} /*saylink*/ } /*saylink*/
struct SayLinkBody_Struct { struct SayLinkBody_Struct {
uint8 unknown_1; /* %1X */ uint8 action_id; /* %1X */
uint32 item_id; /* %05X */ uint32 item_id; /* %05X */
uint32 augment_1; /* %05X */ uint32 augment_1; /* %05X */
uint32 augment_2; /* %05X */ uint32 augment_2; /* %05X */
@ -56,13 +56,18 @@ namespace EQEmu
uint32 augment_5; /* %05X */ uint32 augment_5; /* %05X */
uint32 augment_6; /* %05X */ uint32 augment_6; /* %05X */
uint8 is_evolving; /* %1X */ uint8 is_evolving; /* %1X */
uint32 evolve_group; /* %05X */ uint32 evolve_group; /* %04X */
uint8 evolve_level; /* %02X */ uint8 evolve_level; /* %02X */
uint32 ornament_icon; /* %05X */ uint32 ornament_icon; /* %05X */
int hash; /* %08X */ uint32 hash; /* %08X */
};
struct SayLinkProxy_Struct : SayLinkBody_Struct {
const char* text;
}; };
class SayLinkEngine { class SayLinkEngine {
// TODO: consider methods for direct 'saylink' assignments
public: public:
SayLinkEngine(); SayLinkEngine();
@ -72,29 +77,29 @@ namespace EQEmu
void SetItemInst(const ItemInstance* item_inst) { m_ItemInst = item_inst; } void SetItemInst(const ItemInstance* item_inst) { m_ItemInst = item_inst; }
// mainly for saylinks..but, not limited to // mainly for saylinks..but, not limited to
void SetProxyUnknown1(uint8 proxy_unknown_1) { m_Proxy_unknown_1 = proxy_unknown_1; } void SetProxyActionID(uint8 proxy_action_id) { m_LinkProxyStruct.action_id = proxy_action_id; } // should always be '0'
void SetProxyItemID(uint32 proxy_item_id) { m_ProxyItemID = proxy_item_id; } void SetProxyItemID(uint32 proxy_item_id) { m_LinkProxyStruct.item_id = proxy_item_id; }
void SetProxyAugment1ID(uint32 proxy_augment_id) { m_ProxyAugment1ID = proxy_augment_id; } void SetProxyAugment1ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_1 = proxy_augment_id; }
void SetProxyAugment2ID(uint32 proxy_augment_id) { m_ProxyAugment2ID = proxy_augment_id; } void SetProxyAugment2ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_2 = proxy_augment_id; }
void SetProxyAugment3ID(uint32 proxy_augment_id) { m_ProxyAugment3ID = proxy_augment_id; } void SetProxyAugment3ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_3 = proxy_augment_id; }
void SetProxyAugment4ID(uint32 proxy_augment_id) { m_ProxyAugment4ID = proxy_augment_id; } void SetProxyAugment4ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_4 = proxy_augment_id; }
void SetProxyAugment5ID(uint32 proxy_augment_id) { m_ProxyAugment5ID = proxy_augment_id; } void SetProxyAugment5ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_5 = proxy_augment_id; }
void SetProxyAugment6ID(uint32 proxy_augment_id) { m_ProxyAugment6ID = proxy_augment_id; } void SetProxyAugment6ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_6 = proxy_augment_id; }
void SetProxyIsEvolving(uint8 proxy_is_evolving) { m_ProxyIsEvolving = proxy_is_evolving; } void SetProxyIsEvolving(uint8 proxy_is_evolving) { m_LinkProxyStruct.is_evolving = proxy_is_evolving; }
void SetProxyEvolveGroup(uint32 proxy_evolve_group) { m_ProxyEvolveGroup = proxy_evolve_group; } void SetProxyEvolveGroup(uint32 proxy_evolve_group) { m_LinkProxyStruct.evolve_group = proxy_evolve_group; }
void SetProxyEvolveLevel(uint8 proxy_evolve_level) { m_ProxyEvolveLevel = proxy_evolve_level; } void SetProxyEvolveLevel(uint8 proxy_evolve_level) { m_LinkProxyStruct.evolve_level = proxy_evolve_level; }
void SetProxyOrnamentIcon(uint32 proxy_ornament_icon) { m_ProxyOrnamentIcon = proxy_ornament_icon; } void SetProxyOrnamentIcon(uint32 proxy_ornament_icon) { m_LinkProxyStruct.ornament_icon = proxy_ornament_icon; }
void SetProxyHash(int proxy_hash) { m_ProxyHash = proxy_hash; } void SetProxyHash(uint32 proxy_hash) { m_LinkProxyStruct.hash = proxy_hash; }
void SetProxyText(const char* proxy_text) { m_ProxyText = proxy_text; } // overrides standard text use void SetProxyText(const char* proxy_text) { m_LinkProxyStruct.text = proxy_text; } // overrides standard text use
void SetTaskUse() { m_TaskUse = true; } void SetTaskUse() { m_TaskUse = true; }
std::string GenerateLink(); const std::string& GenerateLink();
bool LinkError() { return m_Error; } bool LinkError() { return m_Error; }
std::string Link() { return m_Link; } // contains full string format: '/12x' '<LinkBody>' '<LinkText>' '/12x' const std::string& Link() { return m_Link; } // contains full string format: '\x12' '<LinkBody>' '<LinkText>' '\x12'
std::string LinkBody() { return m_LinkBody; } // contains string format: '<LinkBody>' const std::string& LinkBody() { return m_LinkBody; } // contains string format: '<LinkBody>'
std::string LinkText() { return m_LinkText; } // contains string format: '<LinkText>' const std::string& LinkText() { return m_LinkText; } // contains string format: '<LinkText>'
void Reset(); void Reset();
@ -106,23 +111,9 @@ namespace EQEmu
const ItemData* m_ItemData; const ItemData* m_ItemData;
const ServerLootItem_Struct* m_LootData; const ServerLootItem_Struct* m_LootData;
const ItemInstance* m_ItemInst; const ItemInstance* m_ItemInst;
uint8 m_Proxy_unknown_1;
uint32 m_ProxyItemID;
uint32 m_ProxyAugment1ID;
uint32 m_ProxyAugment2ID;
uint32 m_ProxyAugment3ID;
uint32 m_ProxyAugment4ID;
uint32 m_ProxyAugment5ID;
uint32 m_ProxyAugment6ID;
uint8 m_ProxyIsEvolving;
uint32 m_ProxyEvolveGroup;
uint8 m_ProxyEvolveLevel;
uint32 m_ProxyOrnamentIcon;
int m_ProxyHash;
const char* m_ProxyText;
bool m_TaskUse;
SayLinkBody_Struct m_LinkBodyStruct; SayLinkBody_Struct m_LinkBodyStruct;
SayLinkProxy_Struct m_LinkProxyStruct;
bool m_TaskUse;
std::string m_Link; std::string m_Link;
std::string m_LinkBody; std::string m_LinkBody;
std::string m_LinkText; std::string m_LinkText;

View File

@ -8894,6 +8894,8 @@ bool Bot::DyeArmor(int16 slot_id, uint32 rgb, bool all_flag, bool save_flag)
std::string Bot::CreateSayLink(Client* c, const char* message, const char* name) std::string Bot::CreateSayLink(Client* c, const char* message, const char* name)
{ {
// TODO: review
int saylink_size = strlen(message); int saylink_size = strlen(message);
char* escaped_string = new char[saylink_size * 2]; char* escaped_string = new char[saylink_size * 2];

View File

@ -7085,7 +7085,6 @@ void bot_subcommand_inventory_list(Client *c, const Seperator *sep)
const EQEmu::ItemData* item = nullptr; const EQEmu::ItemData* item = nullptr;
bool is2Hweapon = false; bool is2Hweapon = false;
std::string item_link;
EQEmu::SayLinkEngine linker; EQEmu::SayLinkEngine linker;
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst); linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
@ -7106,8 +7105,7 @@ void bot_subcommand_inventory_list(Client *c, const Seperator *sep)
} }
linker.SetItemInst(inst); linker.SetItemInst(inst);
item_link = linker.GenerateLink(); c->Message(m_message, "Using %s in my %s (slot %i)", linker.GenerateLink().c_str(), GetBotEquipSlotName(i), (i == 22 ? EQEmu::inventory::slotPowerSource : i));
c->Message(m_message, "Using %s in my %s (slot %i)", item_link.c_str(), GetBotEquipSlotName(i), (i == 22 ? EQEmu::inventory::slotPowerSource : i));
++inventory_count; ++inventory_count;
} }
@ -7250,8 +7248,8 @@ void bot_subcommand_inventory_window(Client *c, const Seperator *sep)
std::string window_text; std::string window_text;
//std::string item_link; //std::string item_link;
//Client::TextLink linker; //EQEmu::SayLinkEngine linker;
//linker.SetLinkType(linker.linkItemInst); //linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= (EQEmu::legacy::EQUIPMENT_END + 1); ++i) { for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= (EQEmu::legacy::EQUIPMENT_END + 1); ++i) {
const EQEmu::ItemData* item = nullptr; const EQEmu::ItemData* item = nullptr;

View File

@ -7907,7 +7907,7 @@ void Client::GarbleMessage(char *message, uint8 variance)
for (size_t i = 0; i < strlen(message); i++) { for (size_t i = 0; i < strlen(message); i++) {
// Client expects hex values inside of a text link body // Client expects hex values inside of a text link body
if (message[i] == delimiter) { if (message[i] == delimiter) {
if (!(delimiter_count & 1)) { i += EQEmu::legacy::TEXT_LINK_BODY_LENGTH; } if (!(delimiter_count & 1)) { i += EQEmu::constants::SayLinkBodySize; }
++delimiter_count; ++delimiter_count;
continue; continue;
} }

View File

@ -2549,7 +2549,7 @@ void command_peekinv(Client *c, const Seperator *sep)
const EQEmu::ItemInstance* inst_main = nullptr; const EQEmu::ItemInstance* inst_main = nullptr;
const EQEmu::ItemInstance* inst_sub = nullptr; const EQEmu::ItemInstance* inst_sub = nullptr;
const EQEmu::ItemData* item_data = nullptr; const EQEmu::ItemData* item_data = nullptr;
std::string item_link;
EQEmu::SayLinkEngine linker; EQEmu::SayLinkEngine linker;
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst); linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
@ -2561,10 +2561,8 @@ void command_peekinv(Client *c, const Seperator *sep)
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
linker.SetItemInst(inst_main); linker.SetItemInst(inst_main);
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i", c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); indexMain, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
} }
if ((scopeWhere & peekWorn) && (targetClient->ClientVersion() >= EQEmu::versions::ClientVersion::SoF)) { if ((scopeWhere & peekWorn) && (targetClient->ClientVersion() >= EQEmu::versions::ClientVersion::SoF)) {
@ -2572,10 +2570,8 @@ void command_peekinv(Client *c, const Seperator *sep)
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
linker.SetItemInst(inst_main); linker.SetItemInst(inst_main);
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i", c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i",
EQEmu::inventory::slotPowerSource, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); EQEmu::inventory::slotPowerSource, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
} }
// inv // inv
@ -2584,20 +2580,16 @@ void command_peekinv(Client *c, const Seperator *sep)
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
linker.SetItemInst(inst_main); linker.SetItemInst(inst_main);
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), "InvSlot: %i, Item: %i (%s), Charges: %i", c->Message((item_data == nullptr), "InvSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); indexMain, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) { for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
inst_sub = inst_main->GetItem(indexSub); inst_sub = inst_main->GetItem(indexSub);
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem(); item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
linker.SetItemInst(inst_sub); linker.SetItemInst(inst_sub);
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), " InvBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", c->Message((item_data == nullptr), " InvBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
} }
} }
@ -2606,10 +2598,8 @@ void command_peekinv(Client *c, const Seperator *sep)
if (targetClient->GetInv().CursorEmpty()) { if (targetClient->GetInv().CursorEmpty()) {
linker.SetItemInst(nullptr); linker.SetItemInst(nullptr);
item_link = linker.GenerateLink();
c->Message(1, "CursorSlot: %i, Item: %i (%s), Charges: %i", c->Message(1, "CursorSlot: %i, Item: %i (%s), Charges: %i",
EQEmu::inventory::slotCursor, 0, item_link.c_str(), 0); EQEmu::inventory::slotCursor, 0, linker.GenerateLink().c_str(), 0);
} }
else { else {
int cursorDepth = 0; int cursorDepth = 0;
@ -2618,20 +2608,16 @@ void command_peekinv(Client *c, const Seperator *sep)
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
linker.SetItemInst(inst_main); linker.SetItemInst(inst_main);
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), "CursorSlot: %i, Depth: %i, Item: %i (%s), Charges: %i", c->Message((item_data == nullptr), "CursorSlot: %i, Depth: %i, Item: %i (%s), Charges: %i",
EQEmu::inventory::slotCursor, cursorDepth, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); EQEmu::inventory::slotCursor, cursorDepth, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = EQEmu::inventory::containerBegin; (cursorDepth == 0) && inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) { for (uint8 indexSub = EQEmu::inventory::containerBegin; (cursorDepth == 0) && inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
inst_sub = inst_main->GetItem(indexSub); inst_sub = inst_main->GetItem(indexSub);
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem(); item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
linker.SetItemInst(inst_sub); linker.SetItemInst(inst_sub);
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), " CursorBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", c->Message((item_data == nullptr), " CursorBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
EQEmu::InventoryProfile::CalcSlotId(EQEmu::inventory::slotCursor, indexSub), EQEmu::inventory::slotCursor, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); EQEmu::InventoryProfile::CalcSlotId(EQEmu::inventory::slotCursor, indexSub), EQEmu::inventory::slotCursor, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
} }
} }
} }
@ -2643,10 +2629,8 @@ void command_peekinv(Client *c, const Seperator *sep)
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
linker.SetItemInst(inst_main); linker.SetItemInst(inst_main);
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), "TributeSlot: %i, Item: %i (%s), Charges: %i", c->Message((item_data == nullptr), "TributeSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); indexMain, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
} }
// bank // bank
@ -2655,20 +2639,16 @@ void command_peekinv(Client *c, const Seperator *sep)
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
linker.SetItemInst(inst_main); linker.SetItemInst(inst_main);
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), "BankSlot: %i, Item: %i (%s), Charges: %i", c->Message((item_data == nullptr), "BankSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); indexMain, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) { for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
inst_sub = inst_main->GetItem(indexSub); inst_sub = inst_main->GetItem(indexSub);
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem(); item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
linker.SetItemInst(inst_sub); linker.SetItemInst(inst_sub);
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), " BankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", c->Message((item_data == nullptr), " BankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
} }
} }
@ -2677,20 +2657,16 @@ void command_peekinv(Client *c, const Seperator *sep)
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
linker.SetItemInst(inst_main); linker.SetItemInst(inst_main);
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), "SharedBankSlot: %i, Item: %i (%s), Charges: %i", c->Message((item_data == nullptr), "SharedBankSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); indexMain, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) { for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
inst_sub = inst_main->GetItem(indexSub); inst_sub = inst_main->GetItem(indexSub);
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem(); item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
linker.SetItemInst(inst_sub); linker.SetItemInst(inst_sub);
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), " SharedBankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", c->Message((item_data == nullptr), " SharedBankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
} }
} }
@ -2700,20 +2676,16 @@ void command_peekinv(Client *c, const Seperator *sep)
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
linker.SetItemInst(inst_main); linker.SetItemInst(inst_main);
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), "TradeSlot: %i, Item: %i (%s), Charges: %i", c->Message((item_data == nullptr), "TradeSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); indexMain, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) { for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
inst_sub = inst_main->GetItem(indexSub); inst_sub = inst_main->GetItem(indexSub);
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem(); item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
linker.SetItemInst(inst_sub); linker.SetItemInst(inst_sub);
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), " TradeBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", c->Message((item_data == nullptr), " TradeBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
} }
} }
@ -2732,20 +2704,16 @@ void command_peekinv(Client *c, const Seperator *sep)
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
linker.SetItemInst(inst_main); linker.SetItemInst(inst_main);
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), "WorldSlot: %i, Item: %i (%s), Charges: %i", c->Message((item_data == nullptr), "WorldSlot: %i, Item: %i (%s), Charges: %i",
(EQEmu::legacy::WORLD_BEGIN + indexMain), ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); (EQEmu::legacy::WORLD_BEGIN + indexMain), ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsType(EQEmu::item::ItemClassBag) && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) { for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsType(EQEmu::item::ItemClassBag) && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
inst_sub = inst_main->GetItem(indexSub); inst_sub = inst_main->GetItem(indexSub);
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem(); item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
linker.SetItemInst(inst_sub); linker.SetItemInst(inst_sub);
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), " WorldBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", c->Message((item_data == nullptr), " WorldBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
INVALID_INDEX, indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); INVALID_INDEX, indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
} }
} }
} }
@ -4400,9 +4368,7 @@ void command_iteminfo(Client *c, const Seperator *sep)
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst); linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
linker.SetItemInst(inst); linker.SetItemInst(inst);
auto item_link = linker.GenerateLink(); c->Message(0, "*** Item Info for [%s] ***", linker.GenerateLink().c_str());
c->Message(0, "*** Item Info for [%s] ***", item_link.c_str());
c->Message(0, ">> ID: %u, ItemUseType: %u, ItemClassType: %u", item->ID, item->ItemType, item->ItemClass); c->Message(0, ">> ID: %u, ItemUseType: %u, ItemClassType: %u", item->ID, item->ItemType, item->ItemClass);
c->Message(0, ">> IDFile: '%s', IconID: %u", item->IDFile, item->Icon); c->Message(0, ">> IDFile: '%s', IconID: %u", item->IDFile, item->Icon);
c->Message(0, ">> Size: %u, Weight: %u, Price: %u, LDoNPrice: %u", item->Size, item->Weight, item->Price, item->LDoNPrice); c->Message(0, ">> Size: %u, Weight: %u, Price: %u, LDoNPrice: %u", item->Size, item->Weight, item->Price, item->LDoNPrice);
@ -5546,9 +5512,9 @@ void command_summonitem(Client *c, const Seperator *sep)
std::string cmd_msg = sep->msg; std::string cmd_msg = sep->msg;
size_t link_open = cmd_msg.find('\x12'); size_t link_open = cmd_msg.find('\x12');
size_t link_close = cmd_msg.find_last_of('\x12'); size_t link_close = cmd_msg.find_last_of('\x12');
if (link_open != link_close && (cmd_msg.length() - link_open) > EQEmu::legacy::TEXT_LINK_BODY_LENGTH) { if (link_open != link_close && (cmd_msg.length() - link_open) > EQEmu::constants::SayLinkBodySize) {
EQEmu::SayLinkBody_Struct link_body; EQEmu::SayLinkBody_Struct link_body;
EQEmu::saylink::DegenerateLinkBody(link_body, cmd_msg.substr(link_open + 1, EQEmu::legacy::TEXT_LINK_BODY_LENGTH)); EQEmu::saylink::DegenerateLinkBody(link_body, cmd_msg.substr(link_open + 1, EQEmu::constants::SayLinkBodySize));
itemid = link_body.item_id; itemid = link_body.item_id;
} }
else if (!sep->IsNumber(1)) { else if (!sep->IsNumber(1)) {
@ -5657,7 +5623,6 @@ void command_itemsearch(Client *c, const Seperator *sep)
const char *search_criteria=sep->argplus[1]; const char *search_criteria=sep->argplus[1];
const EQEmu::ItemData* item = nullptr; const EQEmu::ItemData* item = nullptr;
std::string item_link;
EQEmu::SayLinkEngine linker; EQEmu::SayLinkEngine linker;
linker.SetLinkType(EQEmu::saylink::SayLinkItemData); linker.SetLinkType(EQEmu::saylink::SayLinkItemData);
@ -5666,9 +5631,7 @@ void command_itemsearch(Client *c, const Seperator *sep)
if (item) { if (item) {
linker.SetItemData(item); linker.SetItemData(item);
item_link = linker.GenerateLink(); c->Message(0, "%u: %s", item->ID, linker.GenerateLink().c_str());
c->Message(0, "%u: %s", item->ID, item_link.c_str());
} }
else { else {
c->Message(0, "Item #%s not found", search_criteria); c->Message(0, "Item #%s not found", search_criteria);
@ -5691,9 +5654,7 @@ void command_itemsearch(Client *c, const Seperator *sep)
if (pdest != nullptr) { if (pdest != nullptr) {
linker.SetItemData(item); linker.SetItemData(item);
item_link = linker.GenerateLink(); c->Message(0, "%u: %s", item->ID, linker.GenerateLink().c_str());
c->Message(0, "%u: %s", item->ID, item_link.c_str());
++count; ++count;
} }

View File

@ -1253,20 +1253,20 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst); linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
linker.SetItemInst(inst); linker.SetItemInst(inst);
auto item_link = linker.GenerateLink(); linker.GenerateLink();
client->Message_StringID(MT_LootMessages, LOOTED_MESSAGE, item_link.c_str()); client->Message_StringID(MT_LootMessages, LOOTED_MESSAGE, linker.Link().c_str());
if (!IsPlayerCorpse()) { if (!IsPlayerCorpse()) {
Group *g = client->GetGroup(); Group *g = client->GetGroup();
if (g != nullptr) { if (g != nullptr) {
g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE,
client->GetName(), item_link.c_str()); client->GetName(), linker.Link().c_str());
} else { } else {
Raid *r = client->GetRaid(); Raid *r = client->GetRaid();
if (r != nullptr) { if (r != nullptr) {
r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE,
client->GetName(), item_link.c_str()); client->GetName(), linker.Link().c_str());
} }
} }
} }

View File

@ -1326,7 +1326,7 @@ int Client::GetItemLinkHash(const EQEmu::ItemInstance* inst) {
return hash; return hash;
} }
// This appears to still be in use... The core of this should be incorporated into class Client::TextLink // This appears to still be in use... The core of this should be incorporated into class EQEmu::SayLinkEngine
void Client::SendItemLink(const EQEmu::ItemInstance* inst, bool send_to_all) void Client::SendItemLink(const EQEmu::ItemInstance* inst, bool send_to_all)
{ {
/* /*

View File

@ -583,9 +583,7 @@ void NPC::QueryLoot(Client* to)
linker.SetLinkType(EQEmu::saylink::SayLinkLootItem); linker.SetLinkType(EQEmu::saylink::SayLinkLootItem);
linker.SetLootData(*cur); linker.SetLootData(*cur);
auto item_link = linker.GenerateLink(); to->Message(0, "%s, ID: %u, Level: (min: %u, max: %u)", linker.GenerateLink().c_str(), (*cur)->item_id, (*cur)->min_level, (*cur)->max_level);
to->Message(0, "%s, ID: %u, Level: (min: %u, max: %u)", item_link.c_str(), (*cur)->item_id, (*cur)->min_level, (*cur)->max_level);
} }
to->Message(0, "%i items on %s.", x, GetName()); to->Message(0, "%i items on %s.", x, GetName());

View File

@ -1319,9 +1319,7 @@ void QuestManager::itemlink(int item_id) {
linker.SetLinkType(EQEmu::saylink::SayLinkItemData); linker.SetLinkType(EQEmu::saylink::SayLinkItemData);
linker.SetItemData(item); linker.SetItemData(item);
auto item_link = linker.GenerateLink(); initiator->Message(0, "%s tells you, %s", owner->GetCleanName(), linker.GenerateLink().c_str());
initiator->Message(0, "%s tells you, %s", owner->GetCleanName(), item_link.c_str());
} }
} }
@ -2549,9 +2547,8 @@ const char* QuestManager::varlink(char* perltext, int item_id) {
linker.SetLinkType(EQEmu::saylink::SayLinkItemData); linker.SetLinkType(EQEmu::saylink::SayLinkItemData);
linker.SetItemData(item); linker.SetItemData(item);
auto item_link = linker.GenerateLink(); strcpy(perltext, linker.GenerateLink().c_str());
strcpy(perltext, item_link.c_str()); // link length is currently ranged from 1 to 250 in TextLink::GenerateLink()
return perltext; return perltext;
} }
@ -2773,8 +2770,7 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam
linker.SetProxyAugment1ID(sayid); linker.SetProxyAugment1ID(sayid);
linker.SetProxyText(LinkName); linker.SetProxyText(LinkName);
auto say_link = linker.GenerateLink(); strcpy(Phrase, linker.GenerateLink().c_str());
strcpy(Phrase, say_link.c_str()); // link length is currently ranged from 1 to 250 in TextLink::GenerateLink()
return Phrase; return Phrase;
} }

View File

@ -2804,8 +2804,7 @@ void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceN
if (strlen(Tasks[TaskID]->Reward) != 0) if (strlen(Tasks[TaskID]->Reward) != 0)
linker.SetProxyText(Tasks[TaskID]->Reward); linker.SetProxyText(Tasks[TaskID]->Reward);
auto reward_link = linker.GenerateLink(); reward_text.append(linker.GenerateLink());
reward_text.append(reward_link);
} }
else { else {
reward_text.append(Tasks[TaskID]->Reward); reward_text.append(Tasks[TaskID]->Reward);