diff --git a/ucs/chatchannel.cpp b/ucs/chatchannel.cpp index 16403c295..11a000712 100644 --- a/ucs/chatchannel.cpp +++ b/ucs/chatchannel.cpp @@ -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 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(ChannelClient->GetClientVersion())].length() == 0) { + switch (ChannelClient->GetClientVersion()) { + case EQEmu::versions::ClientVersion::Titanium: + ServerToClient45SayLink(cv_messages[static_cast(ChannelClient->GetClientVersion())], Message); + break; + case EQEmu::versions::ClientVersion::SoF: + case EQEmu::versions::ClientVersion::SoD: + case EQEmu::versions::ClientVersion::UF: + ServerToClient50SayLink(cv_messages[static_cast(ChannelClient->GetClientVersion())], Message); + break; + case EQEmu::versions::ClientVersion::RoF: + ServerToClient55SayLink(cv_messages[static_cast(ChannelClient->GetClientVersion())], Message); + break; + case EQEmu::versions::ClientVersion::RoF2: + default: + cv_messages[static_cast(ChannelClient->GetClientVersion())] = Message; + break; + } + } + + ChannelClient->SendChannelMessage(Name, cv_messages[static_cast(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]); + } + } +} diff --git a/ucs/clientlist.cpp b/ucs/clientlist.cpp index 751cf4089..e5076a150 100644 --- a/ucs/clientlist.cpp +++ b/ucs/clientlist.cpp @@ -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) { diff --git a/ucs/worldserver.cpp b/ucs/worldserver.cpp index 556be152f..48ec03dca 100644 --- a/ucs/worldserver.cpp +++ b/ucs/worldserver.cpp @@ -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]); + } + } +}