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

feat: slashcommands for showall, findplayer, get/openhttpmoninfo, and debug world packet #1545

Merged
merged 5 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions dChatServer/ChatPacketHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "eGameMessageType.h"
#include "StringifiedEnum.h"
#include "eGameMasterLevel.h"
#include "ChatPackets.h"

void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
//Get from the packet which player we want to do something with:
Expand Down Expand Up @@ -354,6 +355,67 @@ void ChatPacketHandler::HandleGMLevelUpdate(Packet* packet) {
inStream.Read(player.gmLevel);
}


void ChatPacketHandler::HandleWho(Packet* packet) {
CINSTREAM_SKIP_HEADER;
FindPlayerRequest request;
request.Deserialize(inStream);

const auto& sender = Game::playerContainer.GetPlayerData(request.requestor);
if (!sender) return;

const auto& player = Game::playerContainer.GetPlayerData(request.playerName.GetAsString());
bool online = player;

CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
bitStream.Write(request.requestor);

BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::WHO_RESPONSE);
bitStream.Write<uint8_t>(online);
bitStream.Write(player.zoneID.GetMapID());
bitStream.Write(player.zoneID.GetInstanceID());
bitStream.Write(player.zoneID.GetCloneID());
bitStream.Write(request.playerName);

SystemAddress sysAddr = sender.sysAddr;
SEND_PACKET;
}

void ChatPacketHandler::HandleShowAll(Packet* packet) {
CINSTREAM_SKIP_HEADER;
ShowAllRequest request;
request.Deserialize(inStream);

const auto& sender = Game::playerContainer.GetPlayerData(request.requestor);
if (!sender) return;

CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WORLD_ROUTE_PACKET);
bitStream.Write(request.requestor);

BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::SHOW_ALL_RESPONSE);
bitStream.Write<uint8_t>(!request.displayZoneData && !request.displayIndividualPlayers);
bitStream.Write(Game::playerContainer.GetPlayerCount());
bitStream.Write(Game::playerContainer.GetSimCount());
bitStream.Write<uint8_t>(request.displayIndividualPlayers);
bitStream.Write<uint8_t>(request.displayZoneData);
if (request.displayZoneData || request.displayIndividualPlayers){
for (auto& [playerID, playerData ]: Game::playerContainer.GetAllPlayers()){
if (!playerData) continue;
bitStream.Write<uint8_t>(0); // structure packing
if (request.displayIndividualPlayers) bitStream.Write(LUWString(playerData.playerName));
if (request.displayZoneData) {
bitStream.Write(playerData.zoneID.GetMapID());
bitStream.Write(playerData.zoneID.GetInstanceID());
bitStream.Write(playerData.zoneID.GetCloneID());
}
}
}
SystemAddress sysAddr = sender.sysAddr;
SEND_PACKET;
}

// the structure the client uses to send this packet is shared in many chat messages
// that are sent to the server. Because of this, there are large gaps of unused data in chat messages
void ChatPacketHandler::HandleChatMessage(Packet* packet) {
Expand Down
2 changes: 2 additions & 0 deletions dChatServer/ChatPacketHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ namespace ChatPacketHandler {
void HandleFriendResponse(Packet* packet);
void HandleRemoveFriend(Packet* packet);
void HandleGMLevelUpdate(Packet* packet);
void HandleWho(Packet* packet);
void HandleShowAll(Packet* packet);

void HandleChatMessage(Packet* packet);
void HandlePrivateChatMessage(Packet* packet);
Expand Down
4 changes: 4 additions & 0 deletions dChatServer/ChatServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,11 @@ void HandlePacket(Packet* packet) {
Game::playerContainer.RemovePlayer(packet);
break;
case eChatMessageType::WHO:
ChatPacketHandler::HandleWho(packet);
break;
case eChatMessageType::SHOW_ALL:
ChatPacketHandler::HandleShowAll(packet);
break;
case eChatMessageType::USER_CHANNEL_CHAT_MESSAGE:
case eChatMessageType::WORLD_DISCONNECT_REQUEST:
case eChatMessageType::WORLD_PROXIMITY_RESPONSE:
Expand Down
2 changes: 2 additions & 0 deletions dChatServer/PlayerContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ void PlayerContainer::InsertPlayer(Packet* packet) {
data.sysAddr = packet->systemAddress;

m_Names[data.playerID] = GeneralUtils::UTF8ToUTF16(data.playerName);
m_PlayerCount++;

LOG("Added user: %s (%llu), zone: %i", data.playerName.c_str(), data.playerID, data.zoneID.GetMapID());

Expand Down Expand Up @@ -87,6 +88,7 @@ void PlayerContainer::RemovePlayer(Packet* packet) {
}
}

m_PlayerCount--;
LOG("Removed user: %llu", playerID);
m_Players.erase(playerID);

Expand Down
5 changes: 5 additions & 0 deletions dChatServer/PlayerContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ class PlayerContainer {
const PlayerData& GetPlayerData(const std::string& playerName);
PlayerData& GetPlayerDataMutable(const LWOOBJID& playerID);
PlayerData& GetPlayerDataMutable(const std::string& playerName);
uint32_t GetPlayerCount() { return m_PlayerCount; };
uint32_t GetSimCount() { return m_SimCount; };
const std::map<LWOOBJID, PlayerData>& GetAllPlayers() { return m_Players; };

TeamData* CreateLocalTeam(std::vector<LWOOBJID> members);
TeamData* CreateTeam(LWOOBJID leader, bool local = false);
Expand All @@ -93,5 +96,7 @@ class PlayerContainer {
std::unordered_map<LWOOBJID, std::u16string> m_Names;
uint32_t m_MaxNumberOfBestFriends = 5;
uint32_t m_MaxNumberOfFriends = 50;
uint32_t m_PlayerCount = 0;
uint32_t m_SimCount = 0;
};

36 changes: 36 additions & 0 deletions dGame/dUtilities/SlashCommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,24 @@ void SlashCommandHandler::Startup() {
};
RegisterCommand(DeleteInvenCommand);

Command GetHttpMonInfo{
.help = "Gets the IP, port and supported pages for our current World Server's Http Monitor",
.info = "Gets the IP, port and supported pages for our current World Server's Http Monitor",
.aliases = { "gethttpmoninfo" },
.handle = DEVGMCommands::GetHttpMonInfo,
.requiredLevel = eGameMasterLevel::DEVELOPER
};
RegisterCommand(GetHttpMonInfo);

Command OpenHttpMonInfo{
.help = "Opens the Http Monitor for the current server (also prints info to chat)",
.info = "Opens the Http Monitor for the current server (also prints info to chat)",
.aliases = { "openhttpmoninfo" },
.handle = DEVGMCommands::OpenHttpMonInfo,
.requiredLevel = eGameMasterLevel::DEVELOPER
};
RegisterCommand(OpenHttpMonInfo);

// Register Greater Than Zero Commands

Command KickCommand{
Expand Down Expand Up @@ -878,8 +896,26 @@ void SlashCommandHandler::Startup() {
};
RegisterCommand(TitleCommand);

Command ShowAllCommand{
.help = "Show all online players across World Servers",
.info = "Usage: /showall (displayZoneData: Default 1) (displayIndividualPlayers: Default 1)",
.aliases = { "showall" },
.handle = GMGreaterThanZeroCommands::ShowAll,
.requiredLevel = eGameMasterLevel::JUNIOR_MODERATOR
};
RegisterCommand(ShowAllCommand);

Command FindPlayerCommand{
.help = "Find the World Server a player is in if they are online",
.info = "Find the World Server a player is in if they are online",
.aliases = { "findplayer" },
.handle = GMGreaterThanZeroCommands::FindPlayer,
.requiredLevel = eGameMasterLevel::JUNIOR_MODERATOR
};
RegisterCommand(FindPlayerCommand);

// Register GM Zero Commands

Command HelpCommand{
.help = "Display command info",
.info = "If a command is given, display detailed info on that command. Otherwise display a list of commands with short desctiptions.",
Expand Down
15 changes: 15 additions & 0 deletions dGame/dUtilities/SlashCommands/DEVGMCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1589,4 +1589,19 @@ namespace DEVGMCommands {
}
}
}

void GetHttpMonInfo(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
GameMessages::SendSlashCommandFeedbackText(entity, u"HTTP Monitor is not implemented.");
HTTPMonitorInfo info;
info.port = Game::server->GetPort();
WorldPackets::SendHTTPMonitorInfo(sysAddr, info);
}

void OpenHttpMonInfo(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
GameMessages::SendSlashCommandFeedbackText(entity, u"HTTP Monitor is not implemented.");
HTTPMonitorInfo info;
info.port = Game::server->GetPort();
info.openWeb = true;
WorldPackets::SendHTTPMonitorInfo(sysAddr, info);
}
};
4 changes: 3 additions & 1 deletion dGame/dUtilities/SlashCommands/DEVGMCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,6 @@ namespace DEVGMCommands {
void RollLoot(Entity* entity, const SystemAddress& sysAddr, const std::string args);
void CastSkill(Entity* entity, const SystemAddress& sysAddr, const std::string args);
void DeleteInven(Entity* entity, const SystemAddress& sysAddr, const std::string args);
}
void GetHttpMonInfo(Entity* entity, const SystemAddress& sysAddr, const std::string args);
void OpenHttpMonInfo(Entity* entity, const SystemAddress& sysAddr, const std::string args);
}
35 changes: 35 additions & 0 deletions dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,4 +287,39 @@ namespace GMGreaterThanZeroCommands {
std::string name = entity->GetCharacter()->GetName() + " - " + args;
GameMessages::SendSetName(entity->GetObjectID(), GeneralUtils::UTF8ToUTF16(name), UNASSIGNED_SYSTEM_ADDRESS);
}

void ShowAll(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
bool displayZoneData = true;
bool displayIndividualPlayers = true;
const auto splitArgs = GeneralUtils::SplitString(args, ' ');

if (!splitArgs.empty() && !splitArgs.at(0).empty()) displayZoneData = splitArgs.at(0) == "1";
if (splitArgs.size() > 1) displayIndividualPlayers = splitArgs.at(1) == "1";

ShowAllRequest request {
.requestor = entity->GetObjectID(),
.displayZoneData = displayZoneData,
.displayIndividualPlayers = displayIndividualPlayers
};

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

void FindPlayer(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
if (args.empty()) {
GameMessages::SendSlashCommandFeedbackText(entity, u"No player Given");
return;
}

FindPlayerRequest request {
.requestor = entity->GetObjectID(),
.playerName = LUWString(args)
};

CBITSTREAM;
request.Serialize(bitStream);
Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false);
}
}
4 changes: 3 additions & 1 deletion dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ namespace GMGreaterThanZeroCommands {
void GmInvis(Entity* entity, const SystemAddress& sysAddr, const std::string args);
void SetName(Entity* entity, const SystemAddress& sysAddr, const std::string args);
void Title(Entity* entity, const SystemAddress& sysAddr, const std::string args);
}
void ShowAll(Entity* entity, const SystemAddress& sysAddr, const std::string args);
void FindPlayer(Entity* entity, const SystemAddress& sysAddr, const std::string args);
}
24 changes: 24 additions & 0 deletions dNet/ChatPackets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,30 @@
#include "eConnectionType.h"
#include "eChatMessageType.h"

void ShowAllRequest::Serialize(RakNet::BitStream& bitStream) {
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::SHOW_ALL);
bitStream.Write(this->requestor);
bitStream.Write(this->displayZoneData);
bitStream.Write(this->displayIndividualPlayers);
}

void ShowAllRequest::Deserialize(RakNet::BitStream& inStream) {
inStream.Read(this->requestor);
inStream.Read(this->displayZoneData);
inStream.Read(this->displayIndividualPlayers);
}

void FindPlayerRequest::Serialize(RakNet::BitStream& bitStream) {
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::WHO);
bitStream.Write(this->requestor);
bitStream.Write(this->playerName);
}

void FindPlayerRequest::Deserialize(RakNet::BitStream& inStream) {
inStream.Read(this->requestor);
inStream.Read(this->playerName);
}

void ChatPackets::SendChatMessage(const SystemAddress& sysAddr, char chatChannel, const std::string& senderName, LWOOBJID playerObjectID, bool senderMythran, const std::u16string& message) {
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GENERAL_CHAT_MESSAGE);
Expand Down
15 changes: 15 additions & 0 deletions dNet/ChatPackets.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ struct SystemAddress;
#include <string>
#include "dCommonVars.h"

struct ShowAllRequest{
LWOOBJID requestor = LWOOBJID_EMPTY;
bool displayZoneData = true;
bool displayIndividualPlayers = true;
void Serialize(RakNet::BitStream& bitStream);
void Deserialize(RakNet::BitStream& inStream);
};

struct FindPlayerRequest{
LWOOBJID requestor = LWOOBJID_EMPTY;
LUWString playerName;
void Serialize(RakNet::BitStream& bitStream);
void Deserialize(RakNet::BitStream& inStream);
};

namespace ChatPackets {
void SendChatMessage(const SystemAddress& sysAddr, char chatChannel, const std::string& senderName, LWOOBJID playerObjectID, bool senderMythran, const std::u16string& message);
void SendSystemMessage(const SystemAddress& sysAddr, const std::u16string& message, bool broadcast = false);
Expand Down
24 changes: 24 additions & 0 deletions dNet/WorldPackets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@

#include <iostream>

void HTTPMonitorInfo::Serialize(RakNet::BitStream &bitStream) const {
bitStream.Write(port);
bitStream.Write<uint8_t>(openWeb);
bitStream.Write<uint8_t>(supportsSum);
bitStream.Write<uint8_t>(supportsDetail);
bitStream.Write<uint8_t>(supportsWho);
bitStream.Write<uint8_t>(supportsObjects);
}

void WorldPackets::SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum, LWOZONEID zone) {
RakNet::BitStream bitStream;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::LOAD_STATIC_ZONE);
Expand Down Expand Up @@ -160,3 +169,18 @@ void WorldPackets::SendGMLevelChange(const SystemAddress& sysAddr, bool success,

SEND_PACKET;
}

void WorldPackets::SendHTTPMonitorInfo(const SystemAddress& sysAddr, const HTTPMonitorInfo& info) {
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::HTTP_MONITOR_INFO_RESPONSE);
info.Serialize(bitStream);
SEND_PACKET;
}

void WorldPackets::SendDebugOuput(const SystemAddress& sysAddr, const std::string& data){
CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::DEBUG_OUTPUT);
bitStream.Write<uint32_t>(data.size());
bitStream.Write(data);
EmosewaMC marked this conversation as resolved.
Show resolved Hide resolved
SEND_PACKET;
}
15 changes: 15 additions & 0 deletions dNet/WorldPackets.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ struct SystemAddress;
enum class eGameMasterLevel : uint8_t;
enum class eCharacterCreationResponse : uint8_t;
enum class eRenameResponse : uint8_t;
namespace RakNet {
class BitStream;
};

struct HTTPMonitorInfo {
uint16_t port = 80;
bool openWeb = false;
bool supportsSum = false;
bool supportsDetail = false;
bool supportsWho = false;
bool supportsObjects = false;
void Serialize(RakNet::BitStream &bitstream) const;
};

namespace WorldPackets {
void SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum, LWOZONEID zone);
Expand All @@ -21,6 +34,8 @@ namespace WorldPackets {
void SendCreateCharacter(const SystemAddress& sysAddr, int64_t reputation, LWOOBJID player, const std::string& xmlData, const std::u16string& username, eGameMasterLevel gm);
void SendChatModerationResponse(const SystemAddress& sysAddr, bool requestAccepted, uint32_t requestID, const std::string& receiver, std::vector<std::pair<uint8_t, uint8_t>> unacceptedItems);
void SendGMLevelChange(const SystemAddress& sysAddr, bool success, eGameMasterLevel highestLevel, eGameMasterLevel prevLevel, eGameMasterLevel newLevel);
void SendHTTPMonitorInfo(const SystemAddress& sysAddr, const HTTPMonitorInfo& info);
void SendDebugOuput(const SystemAddress& sysAddr, const std::string& data);
}

#endif // WORLDPACKETS_H
Loading