Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: remove all raw packet reading from chat packet handler #1415

Merged
merged 9 commits into from
Jan 14, 2024
283 changes: 161 additions & 122 deletions dChatServer/ChatPacketHandler.cpp

Large diffs are not rendered by default.

39 changes: 39 additions & 0 deletions dChatServer/ChatPacketHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,53 @@ struct PlayerData;

enum class eAddFriendResponseType : uint8_t;

enum class eChatChannel : uint8_t {
SYSTEMNOTIFY = 0,
SYSTEMWARNING,
SYSTEMERROR,
BROADCAST,
LOCAL,
LOCALNOANIM,
EMOTE,
PRIVATE_CHAT,
TEAM,
TEAMLOCAL,
GUILD,
GUILDNOTIFY,
PROPERTY,
ADMIN,
COMBATDAMAGE,
COMBATHEALING,
COMBATLOOT,
COMBATEXP,
COMBATDEATH,
GENERAL,
TRADE,
LFG,
USER
};


enum class eChatMessageResponseCode : uint8_t {
SENT = 0,
NOTONLINE,
GENERALERROR,
RECEIVEDNEWWHISPER,
NOTFRIENDS,
SENDERFREETRIAL,
RECEIVERFREETRIAL,
};

namespace ChatPacketHandler {
void HandleFriendlistRequest(Packet* packet);
void HandleFriendRequest(Packet* packet);
void HandleFriendResponse(Packet* packet);
void HandleRemoveFriend(Packet* packet);
void HandleGMLevelUpdate(Packet* packet);

void HandleChatMessage(Packet* packet);
void HandlePrivateChatMessage(Packet* packet);
void SendPrivateChatMessage(const PlayerData& sender, const PlayerData& receiver, const PlayerData& routeTo, const LUWString& message, const eChatChannel channel, const eChatMessageResponseCode responseCode);

void HandleTeamInvite(Packet* packet);
void HandleTeamInviteResponse(Packet* packet);
Expand Down
60 changes: 57 additions & 3 deletions dChatServer/ChatServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "eChatInternalMessageType.h"
#include "eWorldMessageType.h"
#include "ChatIgnoreList.h"
#include "StringifiedEnum.h"

#include "Game.h"
#include "Server.h"
Expand Down Expand Up @@ -223,7 +224,8 @@ void HandlePacket(Packet* packet) {
}

if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::CHAT) {
switch (static_cast<eChatMessageType>(packet->data[3])) {
eChatMessageType chat_message_type = static_cast<eChatMessageType>(packet->data[3]);
switch (chat_message_type) {
case eChatMessageType::GET_FRIENDS_LIST:
ChatPacketHandler::HandleFriendlistRequest(packet);
break;
Expand Down Expand Up @@ -293,9 +295,61 @@ void HandlePacket(Packet* packet) {
case eChatMessageType::TEAM_SET_LOOT:
ChatPacketHandler::HandleTeamLootOption(packet);
break;

case eChatMessageType::GMLEVEL_UPDATE:
ChatPacketHandler::HandleGMLevelUpdate(packet);
break;
case eChatMessageType::LOGIN_SESSION_NOTIFY:
case eChatMessageType::USER_CHANNEL_CHAT_MESSAGE:
case eChatMessageType::WORLD_DISCONNECT_REQUEST:
case eChatMessageType::WORLD_PROXIMITY_RESPONSE:
case eChatMessageType::WORLD_PARCEL_RESPONSE:
case eChatMessageType::TEAM_MISSED_INVITE_CHECK:
case eChatMessageType::GUILD_CREATE:
case eChatMessageType::GUILD_INVITE:
case eChatMessageType::GUILD_INVITE_RESPONSE:
case eChatMessageType::GUILD_LEAVE:
case eChatMessageType::GUILD_KICK:
case eChatMessageType::GUILD_GET_STATUS:
case eChatMessageType::GUILD_GET_ALL:
case eChatMessageType::SHOW_ALL:
case eChatMessageType::BLUEPRINT_MODERATED:
case eChatMessageType::BLUEPRINT_MODEL_READY:
case eChatMessageType::PROPERTY_READY_FOR_APPROVAL:
case eChatMessageType::PROPERTY_MODERATION_CHANGED:
case eChatMessageType::PROPERTY_BUILDMODE_CHANGED:
case eChatMessageType::PROPERTY_BUILDMODE_CHANGED_REPORT:
case eChatMessageType::MAIL:
case eChatMessageType::WORLD_INSTANCE_LOCATION_REQUEST:
case eChatMessageType::REPUTATION_UPDATE:
case eChatMessageType::SEND_CANNED_TEXT:
case eChatMessageType::CHARACTER_NAME_CHANGE_REQUEST:
case eChatMessageType::CSR_REQUEST:
case eChatMessageType::CSR_REPLY:
case eChatMessageType::GM_KICK:
case eChatMessageType::GM_ANNOUNCE:
case eChatMessageType::WORLD_ROUTE_PACKET:
case eChatMessageType::GET_ZONE_POPULATIONS:
case eChatMessageType::REQUEST_MINIMUM_CHAT_MODE:
case eChatMessageType::MATCH_REQUEST:
case eChatMessageType::UGCMANIFEST_REPORT_MISSING_FILE:
case eChatMessageType::UGCMANIFEST_REPORT_DONE_FILE:
case eChatMessageType::UGCMANIFEST_REPORT_DONE_BLUEPRINT:
case eChatMessageType::UGCC_REQUEST:
case eChatMessageType::WHO:
case eChatMessageType::WORLD_PLAYERS_PET_MODERATED_ACKNOWLEDGE:
case eChatMessageType::ACHIEVEMENT_NOTIFY:
case eChatMessageType::GM_CLOSE_PRIVATE_CHAT_WINDOW:
case eChatMessageType::UNEXPECTED_DISCONNECT:
case eChatMessageType::PLAYER_READY:
case eChatMessageType::GET_DONATION_TOTAL:
case eChatMessageType::UPDATE_DONATION:
case eChatMessageType::PRG_CSR_COMMAND:
case eChatMessageType::HEARTBEAT_REQUEST_FROM_WORLD:
case eChatMessageType::UPDATE_FREE_TRIAL_STATUS:
LOG("Unhandled CHAT Message id: %s (%i)", StringifiedEnum::ToString(chat_message_type).data(), chat_message_type);
break;
default:
LOG("Unknown CHAT id: %i", int(packet->data[3]));
LOG("Unknown CHAT Message id: %i", chat_message_type);
}
}

Expand Down
6 changes: 6 additions & 0 deletions dChatServer/PlayerContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "Database.h"
#include "eConnectionType.h"
#include "eChatInternalMessageType.h"
#include "eGameMasterLevel.h"
#include "ChatPackets.h"
#include "dConfig.h"

Expand All @@ -22,6 +23,10 @@
m_Players.clear();
}

PlayerData::PlayerData() {
gmLevel == eGameMasterLevel::CIVILIAN;

Check warning on line 27 in dChatServer/PlayerContainer.cpp

View workflow job for this annotation

GitHub Actions / Build & Test (macos-11)

equality comparison result unused [-Wunused-comparison]
}

TeamData::TeamData() {
lootFlag = Game::config->GetValue("default_team_loot") == "0" ? 0 : 1;
}
Expand All @@ -47,6 +52,7 @@

inStream.Read(data.zoneID);
inStream.Read(data.muteExpire);
inStream.Read(data.gmLevel);
data.sysAddr = packet->systemAddress;

m_Names[data.playerID] = GeneralUtils::UTF8ToUTF16(data.playerName);
Expand Down
5 changes: 5 additions & 0 deletions dChatServer/PlayerContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "dServer.h"
#include <unordered_map>

enum class eGameMasterLevel : uint8_t;

struct IgnoreData {
IgnoreData(const std::string& name, const LWOOBJID& id) : playerName(name), playerId(id) {}
inline bool operator==(const std::string& other) const noexcept {
Expand All @@ -22,6 +24,7 @@ struct IgnoreData {
};

struct PlayerData {
PlayerData();
operator bool() const noexcept {
return playerID != LWOOBJID_EMPTY;
}
Expand All @@ -42,6 +45,8 @@ struct PlayerData {
std::string playerName;
std::vector<FriendData> friends;
std::vector<IgnoreData> ignoredPlayers;
eGameMasterLevel gmLevel;
bool isFTP = false;
};

struct TeamData {
Expand Down
14 changes: 13 additions & 1 deletion dGame/Entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "eTriggerEventType.h"
#include "eObjectBits.h"
#include "PositionUpdate.h"
#include "eChatMessageType.h"

//Component includes:
#include "Component.h"
Expand Down Expand Up @@ -858,9 +859,20 @@ void Entity::SetGMLevel(eGameMasterLevel value) {
}

CharacterComponent* character = GetComponent<CharacterComponent>();
if (character) character->SetGMLevel(value);
if (!character) return;
character->SetGMLevel(value);

GameMessages::SendGMLevelBroadcast(m_ObjectID, value);

// Update the chat server of our GM Level
{
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GMLEVEL_UPDATE);
bitStream.Write(m_ObjectID);
bitStream.Write(m_GMLevel);

Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false);
}
}

void Entity::WriteBaseReplicaData(RakNet::BitStream* outBitStream, eReplicaPacketType packetType) {
Expand Down
56 changes: 0 additions & 56 deletions dNet/PacketUtils.cpp
Original file line number Diff line number Diff line change
@@ -1,64 +1,8 @@
#include "PacketUtils.h"
#include <vector>
#include <fstream>
#include "Logger.h"
#include "Game.h"

uint16_t PacketUtils::ReadU16(uint32_t startLoc, Packet* packet) {
if (startLoc + 2 > packet->length) return 0;

std::vector<unsigned char> t;
for (uint32_t i = startLoc; i < startLoc + 2; i++) t.push_back(packet->data[i]);
return *(uint16_t*)t.data();
}

uint32_t PacketUtils::ReadU32(uint32_t startLoc, Packet* packet) {
if (startLoc + 4 > packet->length) return 0;

std::vector<unsigned char> t;
for (uint32_t i = startLoc; i < startLoc + 4; i++) {
t.push_back(packet->data[i]);
}
return *(uint32_t*)t.data();
}

uint64_t PacketUtils::ReadU64(uint32_t startLoc, Packet* packet) {
if (startLoc + 8 > packet->length) return 0;

std::vector<unsigned char> t;
for (uint32_t i = startLoc; i < startLoc + 8; i++) t.push_back(packet->data[i]);
return *(uint64_t*)t.data();
}

int64_t PacketUtils::ReadS64(uint32_t startLoc, Packet* packet) {
if (startLoc + 8 > packet->length) return 0;

std::vector<unsigned char> t;
for (size_t i = startLoc; i < startLoc + 8; i++) t.push_back(packet->data[i]);
return *(int64_t*)t.data();
}

std::string PacketUtils::ReadString(uint32_t startLoc, Packet* packet, bool wide, uint32_t maxLen) {
std::string readString = "";

if (wide) maxLen *= 2;

if (packet->length > startLoc) {
uint32_t i = 0;
while (packet->data[startLoc + i] != '\0' && packet->length > static_cast<uint32_t>(startLoc + i) && maxLen > i) {
readString.push_back(packet->data[startLoc + i]);

if (wide) {
i += 2; // Wide-char string
} else {
i++; // Regular string
}
}
}

return readString;
}

//! Saves a packet to the filesystem
void PacketUtils::SavePacket(const std::string& filename, const char* data, size_t length) {
//If we don't log to the console, don't save the bin files either. This takes up a lot of time.
Expand Down
5 changes: 0 additions & 5 deletions dNet/PacketUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@
enum class eConnectionType : uint16_t;

namespace PacketUtils {
uint16_t ReadU16(uint32_t startLoc, Packet* packet);
uint32_t ReadU32(uint32_t startLoc, Packet* packet);
uint64_t ReadU64(uint32_t startLoc, Packet* packet);
int64_t ReadS64(uint32_t startLoc, Packet* packet);
std::string ReadString(uint32_t startLoc, Packet* packet, bool wide, uint32_t maxLen = 33);
void SavePacket(const std::string& filename, const char* data, size_t length);
};

Expand Down
1 change: 1 addition & 0 deletions dWorldServer/WorldServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1125,6 +1125,7 @@ void HandlePacket(Packet* packet) {
bitStream.Write(zone.GetInstanceID());
bitStream.Write(zone.GetCloneID());
bitStream.Write(player->GetParentUser()->GetMuteExpire());
bitStream.Write(player->GetGMLevel());

Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false);
}
Expand Down
Loading