Fix for UCS-based messages containing saylinks

This commit is contained in:
Uleat 2018-02-26 22:38:14 -05:00
parent 03b2550520
commit 1e316102ea
3 changed files with 274 additions and 3 deletions

View File

@ -28,6 +28,10 @@
extern Database database;
extern uint32 ChatMessagesSent;
void ServerToClient45SayLink(std::string& clientSayLink, const std::string& serverSayLink);
void ServerToClient50SayLink(std::string& clientSayLink, const std::string& serverSayLink);
void ServerToClient55SayLink(std::string& clientSayLink, const std::string& serverSayLink);
ChatChannel::ChatChannel(std::string inName, std::string inOwner, std::string inPassword, bool inPermanent, int inMinimumStatus) :
DeleteTimer(0) {
@ -384,6 +388,8 @@ void ChatChannel::SendMessageToChannel(std::string Message, Client* Sender) {
if(!Sender) return;
std::string cv_messages[EQEmu::versions::ClientVersionCount];
ChatMessagesSent++;
LinkedListIterator<Client*> iterator(ClientsInChannel);
@ -398,7 +404,28 @@ void ChatChannel::SendMessageToChannel(std::string Message, Client* Sender) {
{
Log(Logs::Detail, Logs::UCS_Server, "Sending message to %s from %s",
ChannelClient->GetName().c_str(), Sender->GetName().c_str());
ChannelClient->SendChannelMessage(Name, Message, Sender);
if (cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())].length() == 0) {
switch (ChannelClient->GetClientVersion()) {
case EQEmu::versions::ClientVersion::Titanium:
ServerToClient45SayLink(cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())], Message);
break;
case EQEmu::versions::ClientVersion::SoF:
case EQEmu::versions::ClientVersion::SoD:
case EQEmu::versions::ClientVersion::UF:
ServerToClient50SayLink(cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())], Message);
break;
case EQEmu::versions::ClientVersion::RoF:
ServerToClient55SayLink(cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())], Message);
break;
case EQEmu::versions::ClientVersion::RoF2:
default:
cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())] = Message;
break;
}
}
ChannelClient->SendChannelMessage(Name, cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())], Sender);
}
iterator.Advance();
@ -655,3 +682,118 @@ std::string CapitaliseName(std::string inString) {
return NormalisedName;
}
void ServerToClient45SayLink(std::string& clientSayLink, const std::string& serverSayLink) {
if (serverSayLink.find('\x12') == std::string::npos) {
clientSayLink = serverSayLink;
return;
}
auto segments = SplitString(serverSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
if (segments[segment_iter].length() <= 56) {
clientSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
// 6.2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXXXXX (45)
// Diff: ^^^^^ ^ ^^^^^
clientSayLink.push_back('\x12');
clientSayLink.append(segments[segment_iter].substr(0, 31));
clientSayLink.append(segments[segment_iter].substr(36, 5));
if (segments[segment_iter][41] == '0')
clientSayLink.push_back(segments[segment_iter][42]);
else
clientSayLink.push_back('F');
clientSayLink.append(segments[segment_iter].substr(48));
clientSayLink.push_back('\x12');
}
else {
clientSayLink.append(segments[segment_iter]);
}
}
}
void ServerToClient50SayLink(std::string& clientSayLink, const std::string& serverSayLink) {
if (serverSayLink.find('\x12') == std::string::npos) {
clientSayLink = serverSayLink;
return;
}
auto segments = SplitString(serverSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
if (segments[segment_iter].length() <= 56) {
clientSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
// Diff: ^^^^^ ^
clientSayLink.push_back('\x12');
clientSayLink.append(segments[segment_iter].substr(0, 31));
clientSayLink.append(segments[segment_iter].substr(36, 5));
if (segments[segment_iter][41] == '0')
clientSayLink.push_back(segments[segment_iter][42]);
else
clientSayLink.push_back('F');
clientSayLink.append(segments[segment_iter].substr(43));
clientSayLink.push_back('\x12');
}
else {
clientSayLink.append(segments[segment_iter]);
}
}
}
void ServerToClient55SayLink(std::string& clientSayLink, const std::string& serverSayLink) {
if (serverSayLink.find('\x12') == std::string::npos) {
clientSayLink = serverSayLink;
return;
}
auto segments = SplitString(serverSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
if (segments[segment_iter].length() <= 56) {
clientSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
// RoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (55)
// Diff: ^
clientSayLink.push_back('\x12');
clientSayLink.append(segments[segment_iter].substr(0, 41));
if (segments[segment_iter][41] == '0')
clientSayLink.push_back(segments[segment_iter][42]);
else
clientSayLink.push_back('F');
clientSayLink.append(segments[segment_iter].substr(43));
clientSayLink.push_back('\x12');
}
else {
clientSayLink.append(segments[segment_iter]);
}
}
}

View File

@ -893,7 +893,7 @@ void Clientlist::RequestClientVersion(uint32 character_id) {
bool Clientlist::QueueClientVersionReply(uint32 character_id, EQEmu::versions::ClientVersion client_version) {
if (!character_id)
return true;
if (client_version == EQEmu::versions::ClientVersion::Unknown)
if (client_version < EQEmu::versions::ClientVersion::Titanium || client_version > EQEmu::versions::ClientVersion::RoF2)
return false;
if (LogSys.log_settings[Logs::UCS_Server].is_category_enabled) {

View File

@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "../common/misc_functions.h"
#include "../common/packet_functions.h"
#include "../common/md5.h"
#include "../common/string_util.h"
#include "worldserver.h"
#include "clientlist.h"
#include "ucsconfig.h"
@ -41,6 +42,10 @@ extern Database database;
void ProcessMailTo(Client *c, std::string from, std::string subject, std::string message);
void Client45ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink);
void Client50ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink);
void Client55ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink);
WorldServer::WorldServer()
{
m_connection.reset(new EQ::Net::ServertalkClient(Config->WorldIP, Config->WorldTCPPort, false, "UCS", Config->SharedKey));
@ -96,7 +101,26 @@ void WorldServer::ProcessMessage(uint16 opcode, EQ::Net::Packet &p)
if (Message[0] == ';')
{
c->SendChannelMessageByNumber(Message.substr(1, std::string::npos));
std::string new_message;
switch (c->GetClientVersion()) {
case EQEmu::versions::ClientVersion::Titanium:
Client45ToServerSayLink(new_message, Message.substr(1, std::string::npos));
break;
case EQEmu::versions::ClientVersion::SoF:
case EQEmu::versions::ClientVersion::SoD:
case EQEmu::versions::ClientVersion::UF:
Client50ToServerSayLink(new_message, Message.substr(1, std::string::npos));
break;
case EQEmu::versions::ClientVersion::RoF:
Client55ToServerSayLink(new_message, Message.substr(1, std::string::npos));
break;
case EQEmu::versions::ClientVersion::RoF2:
default:
new_message = Message.substr(1, std::string::npos);
break;
}
c->SendChannelMessageByNumber(new_message);
}
else if (Message[0] == '[')
{
@ -170,3 +194,108 @@ void WorldServer::ActivateBroadcastServerReadyTimer() {
// and clients will not re-connect to ucs until that occurs
*m_bsr_timer = (Timer::GetCurrentTime() + (RuleI(Chat, UCSBroadcastServerReadyDelay) * 1000));
}
void Client45ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink) {
if (clientSayLink.find('\x12') == std::string::npos) {
serverSayLink = clientSayLink;
return;
}
auto segments = SplitString(clientSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
if (segments[segment_iter].length() <= 45) {
serverSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// Idx: 0 1 6 11 16 21 26 31 32 36 37 (Source)
// 6.2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXXXXX (45)
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
// Diff: ^^^^^ ^ ^^^^^
serverSayLink.push_back('\x12');
serverSayLink.append(segments[segment_iter].substr(0, 31));
serverSayLink.append("00000");
serverSayLink.append(segments[segment_iter].substr(31, 5));
serverSayLink.push_back('0');
serverSayLink.push_back(segments[segment_iter][36]);
serverSayLink.append("00000");
serverSayLink.append(segments[segment_iter].substr(37));
serverSayLink.push_back('\x12');
}
else {
serverSayLink.append(segments[segment_iter]);
}
}
}
void Client50ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink) {
if (clientSayLink.find('\x12') == std::string::npos) {
serverSayLink = clientSayLink;
return;
}
auto segments = SplitString(clientSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
if (segments[segment_iter].length() <= 50) {
serverSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// Idx: 0 1 6 11 16 21 26 31 32 36 37 42 (Source)
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
// Diff: ^^^^^ ^
serverSayLink.push_back('\x12');
serverSayLink.append(segments[segment_iter].substr(0, 31));
serverSayLink.append("00000");
serverSayLink.append(segments[segment_iter].substr(31, 5));
serverSayLink.push_back('0');
serverSayLink.append(segments[segment_iter].substr(36));
serverSayLink.push_back('\x12');
}
else {
serverSayLink.append(segments[segment_iter]);
}
}
}
void Client55ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink) {
if (clientSayLink.find('\x12') == std::string::npos) {
serverSayLink = clientSayLink;
return;
}
auto segments = SplitString(clientSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
if (segments[segment_iter].length() <= 55) {
serverSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
// Idx: 0 1 6 11 16 21 26 31 36 37 41 42 47 (Source)
// RoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (55)
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
// Diff: ^
serverSayLink.push_back('\x12');
serverSayLink.append(segments[segment_iter].substr(0, 41));
serverSayLink.push_back('0');
serverSayLink.append(segments[segment_iter].substr(41));
serverSayLink.push_back('\x12');
}
else {
serverSayLink.append(segments[segment_iter]);
}
}
}