Skip to content

Commit

Permalink
chore: remove all raw packet reading from chat packet handler (#1415)
Browse files Browse the repository at this point in the history
* chore: default size to 33 on LU(W)Strings since that's the most common lenght
Was doing this on other places, but not the main one

* chore: remove all raw packet reading from chat packet handler

and general chat packet cleanup

* fix team invite/promote/kick

* Address feedback

* fix friends check

* update comments

* Address feedback
Add GM level handeling

* Address feedback
  • Loading branch information
aronwk-aaron authored Jan 14, 2024
1 parent a62f6d6 commit 6592bbe
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 187 deletions.
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 @@ PlayerContainer::~PlayerContainer() {
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 @@ void PlayerContainer::InsertPlayer(Packet* packet) {

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 @@ -1126,6 +1126,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

0 comments on commit 6592bbe

Please sign in to comment.