mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-12-22 05:23:34 +00:00
feat: slashcommands for showall, findplayer, get/openhttpmoninfo, and debug world packet (#1545)
* feat: showall, findplayer, get/openhttpmoninfo http monitor info is planned to be used later, just putting in info that i've since reverse engineered and don't want lost Additionally add debug world packet for duture dev use Tested all new commands and variation of command arguments * fix missing newline at eofs * address most feedback * Compormise and use struct with (de)serialize * remove httpmoninfo commands
This commit is contained in:
parent
fafe2aefad
commit
99e7349f6c
@ -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:
|
||||
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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());
|
||||
|
||||
@ -87,6 +88,7 @@ void PlayerContainer::RemovePlayer(Packet* packet) {
|
||||
}
|
||||
}
|
||||
|
||||
m_PlayerCount--;
|
||||
LOG("Removed user: %llu", playerID);
|
||||
m_Players.erase(playerID);
|
||||
|
||||
|
@ -71,6 +71,9 @@ public:
|
||||
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);
|
||||
@ -93,5 +96,7 @@ private:
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -878,8 +878,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.",
|
||||
|
@ -70,4 +70,4 @@ 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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
@ -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);
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
@ -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);
|
||||
@ -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…
Reference in New Issue
Block a user