mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-12-16 20:24:39 -06:00
Compare commits
13 Commits
v2.1.0
...
I-love-pla
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48d37d00ab | ||
| 6592bbea46 | |||
|
|
52ed34de48 | ||
|
|
a62f6d63c6 | ||
|
|
d77c0cd409 | ||
|
|
d3eb5a56d9 | ||
|
|
1c5b8cc265 | ||
|
|
ee01d13969 | ||
|
|
0dd3cce8ed | ||
|
|
87d5bd0229 | ||
|
|
f4a6086e4c | ||
|
|
eccd6f691f | ||
|
|
a54085945f |
@@ -2,7 +2,6 @@
|
||||
#include "PlayerContainer.h"
|
||||
#include "Database.h"
|
||||
#include <vector>
|
||||
#include "PacketUtils.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "Game.h"
|
||||
#include "dServer.h"
|
||||
@@ -18,6 +17,8 @@
|
||||
#include "eChatInternalMessageType.h"
|
||||
#include "eClientMessageType.h"
|
||||
#include "eGameMessageType.h"
|
||||
#include "StringifiedEnum.h"
|
||||
#include "eGameMasterLevel.h"
|
||||
|
||||
void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
|
||||
//Get from the packet which player we want to do something with:
|
||||
@@ -78,31 +79,27 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
|
||||
|
||||
void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
|
||||
LWOOBJID requestorPlayerID;
|
||||
inStream.Read(requestorPlayerID);
|
||||
uint32_t spacing{};
|
||||
inStream.Read(spacing);
|
||||
std::string playerName = "";
|
||||
uint16_t character;
|
||||
bool noMoreLettersInName = false;
|
||||
|
||||
for (uint32_t j = 0; j < 33; j++) {
|
||||
inStream.Read(character);
|
||||
if (character == '\0') noMoreLettersInName = true;
|
||||
if (!noMoreLettersInName) playerName.push_back(static_cast<char>(character));
|
||||
}
|
||||
|
||||
LUWString LUplayerName;
|
||||
char isBestFriendRequest{};
|
||||
|
||||
inStream.Read(requestorPlayerID);
|
||||
inStream.IgnoreBytes(4);
|
||||
inStream.Read(LUplayerName);
|
||||
inStream.Read(isBestFriendRequest);
|
||||
|
||||
auto playerName = LUplayerName.GetAsString();
|
||||
|
||||
auto& requestor = Game::playerContainer.GetPlayerDataMutable(requestorPlayerID);
|
||||
if (!requestor) {
|
||||
LOG("No requestor player %llu sent to %s found.", requestorPlayerID, playerName.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// you cannot friend yourself
|
||||
if (requestor.playerName == playerName) {
|
||||
SendFriendResponse(requestor, requestor, eAddFriendResponseType::MYTHRAN);
|
||||
SendFriendResponse(requestor, requestor, eAddFriendResponseType::GENERALERROR);
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -141,6 +138,13 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent GM friend spam
|
||||
// If the player we are trying to be friends with is not a civilian and we are a civilian, abort the process
|
||||
if (requestee.gmLevel > eGameMasterLevel::CIVILIAN && requestor.gmLevel == eGameMasterLevel::CIVILIAN ) {
|
||||
SendFriendResponse(requestor, requestee, eAddFriendResponseType::MYTHRAN);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isBestFriendRequest) {
|
||||
|
||||
uint8_t oldBestFriendStatus{};
|
||||
@@ -218,15 +222,19 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
|
||||
|
||||
void ChatPacketHandler::HandleFriendResponse(Packet* packet) {
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
LWOOBJID playerID;
|
||||
inStream.Read(playerID);
|
||||
|
||||
eAddFriendResponseCode clientResponseCode = static_cast<eAddFriendResponseCode>(packet->data[0x14]);
|
||||
std::string friendName = PacketUtils::ReadString(0x15, packet, true);
|
||||
LWOOBJID playerID;
|
||||
eAddFriendResponseCode clientResponseCode;
|
||||
LUWString friendName;
|
||||
|
||||
inStream.Read(playerID);
|
||||
inStream.IgnoreBytes(4);
|
||||
inStream.Read(clientResponseCode);
|
||||
inStream.Read(friendName);
|
||||
|
||||
//Now to try and find both of these:
|
||||
auto& requestor = Game::playerContainer.GetPlayerDataMutable(playerID);
|
||||
auto& requestee = Game::playerContainer.GetPlayerDataMutable(friendName);
|
||||
auto& requestee = Game::playerContainer.GetPlayerDataMutable(friendName.GetAsString());
|
||||
if (!requestor || !requestee) return;
|
||||
|
||||
eAddFriendResponseType serverResponseCode{};
|
||||
@@ -288,8 +296,11 @@ void ChatPacketHandler::HandleFriendResponse(Packet* packet) {
|
||||
void ChatPacketHandler::HandleRemoveFriend(Packet* packet) {
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
LWOOBJID playerID;
|
||||
LUWString LUFriendName;
|
||||
inStream.Read(playerID);
|
||||
std::string friendName = PacketUtils::ReadString(0x14, packet, true);
|
||||
inStream.IgnoreBytes(4);
|
||||
inStream.Read(LUFriendName);
|
||||
auto friendName = LUFriendName.GetAsString();
|
||||
|
||||
//we'll have to query the db here to find the user, since you can delete them while they're offline.
|
||||
//First, we need to find their ID:
|
||||
@@ -335,123 +346,144 @@ void ChatPacketHandler::HandleRemoveFriend(Packet* packet) {
|
||||
SendRemoveFriend(goonB, goonAName, true);
|
||||
}
|
||||
|
||||
void ChatPacketHandler::HandleChatMessage(Packet* packet) {
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
LWOOBJID playerID = LWOOBJID_EMPTY;
|
||||
inStream.Read(playerID);
|
||||
|
||||
const auto& sender = Game::playerContainer.GetPlayerData(playerID);
|
||||
|
||||
if (!sender) return;
|
||||
|
||||
if (sender.GetIsMuted()) return;
|
||||
|
||||
inStream.SetReadOffset(0x14 * 8);
|
||||
|
||||
uint8_t channel = 0;
|
||||
inStream.Read(channel);
|
||||
|
||||
std::string message = PacketUtils::ReadString(0x66, packet, true, 512);
|
||||
|
||||
LOG("Got a message from (%s) [%d]: %s", sender.playerName.c_str(), channel, message.c_str());
|
||||
|
||||
if (channel != 8) return;
|
||||
|
||||
auto* team = Game::playerContainer.GetTeam(playerID);
|
||||
|
||||
if (team == nullptr) return;
|
||||
|
||||
for (const auto memberId : team->memberIDs) {
|
||||
const auto& otherMember = Game::playerContainer.GetPlayerData(memberId);
|
||||
|
||||
if (!otherMember) return;
|
||||
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||
bitStream.Write(otherMember.playerID);
|
||||
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE);
|
||||
bitStream.Write(otherMember.playerID);
|
||||
bitStream.Write<uint8_t>(8);
|
||||
bitStream.Write<unsigned int>(69);
|
||||
bitStream.Write(LUWString(sender.playerName));
|
||||
bitStream.Write(sender.playerID);
|
||||
bitStream.Write<uint16_t>(0);
|
||||
bitStream.Write<uint8_t>(0); //not mythran nametag
|
||||
bitStream.Write(LUWString(otherMember.playerName));
|
||||
bitStream.Write<uint8_t>(0); //not mythran for receiver
|
||||
bitStream.Write<uint8_t>(0); //teams?
|
||||
bitStream.Write(LUWString(message, 512));
|
||||
|
||||
SystemAddress sysAddr = otherMember.sysAddr;
|
||||
SEND_PACKET;
|
||||
}
|
||||
}
|
||||
|
||||
void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) {
|
||||
LWOOBJID senderID = PacketUtils::ReadS64(0x08, packet);
|
||||
std::string receiverName = PacketUtils::ReadString(0x66, packet, true);
|
||||
std::string message = PacketUtils::ReadString(0xAA, packet, true, 512);
|
||||
|
||||
//Get the bois:
|
||||
const auto& goonA = Game::playerContainer.GetPlayerData(senderID);
|
||||
const auto& goonB = Game::playerContainer.GetPlayerData(receiverName);
|
||||
if (!goonA || !goonB) return;
|
||||
|
||||
if (goonA.GetIsMuted()) return;
|
||||
|
||||
//To the sender:
|
||||
{
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||
bitStream.Write(goonA.playerID);
|
||||
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE);
|
||||
bitStream.Write(goonA.playerID);
|
||||
bitStream.Write<uint8_t>(7);
|
||||
bitStream.Write<unsigned int>(69);
|
||||
bitStream.Write(LUWString(goonA.playerName));
|
||||
bitStream.Write(goonA.playerID);
|
||||
bitStream.Write<uint16_t>(0);
|
||||
bitStream.Write<uint8_t>(0); //not mythran nametag
|
||||
bitStream.Write(LUWString(goonB.playerName));
|
||||
bitStream.Write<uint8_t>(0); //not mythran for receiver
|
||||
bitStream.Write<uint8_t>(0); //success
|
||||
bitStream.Write(LUWString(message, 512));
|
||||
|
||||
SystemAddress sysAddr = goonA.sysAddr;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
//To the receiver:
|
||||
{
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||
bitStream.Write(goonB.playerID);
|
||||
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE);
|
||||
bitStream.Write(goonA.playerID);
|
||||
bitStream.Write<uint8_t>(7);
|
||||
bitStream.Write<unsigned int>(69);
|
||||
bitStream.Write(LUWString(goonA.playerName));
|
||||
bitStream.Write(goonA.playerID);
|
||||
bitStream.Write<uint16_t>(0);
|
||||
bitStream.Write<uint8_t>(0); //not mythran nametag
|
||||
bitStream.Write(LUWString(goonB.playerName));
|
||||
bitStream.Write<uint8_t>(0); //not mythran for receiver
|
||||
bitStream.Write<uint8_t>(3); //new whisper
|
||||
bitStream.Write(LUWString(message, 512));
|
||||
|
||||
SystemAddress sysAddr = goonB.sysAddr;
|
||||
SEND_PACKET;
|
||||
}
|
||||
}
|
||||
|
||||
void ChatPacketHandler::HandleTeamInvite(Packet* packet) {
|
||||
void ChatPacketHandler::HandleGMLevelUpdate(Packet* packet) {
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
LWOOBJID playerID;
|
||||
inStream.Read(playerID);
|
||||
std::string invitedPlayer = PacketUtils::ReadString(0x14, packet, true);
|
||||
auto& player = Game::playerContainer.GetPlayerData(playerID);
|
||||
if (!player) return;
|
||||
inStream.Read(player.gmLevel);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
LWOOBJID playerID;
|
||||
inStream.Read(playerID);
|
||||
|
||||
const auto& sender = Game::playerContainer.GetPlayerData(playerID);
|
||||
if (!sender || sender.GetIsMuted()) return;
|
||||
|
||||
eChatChannel channel;
|
||||
uint32_t size;
|
||||
|
||||
inStream.IgnoreBytes(4);
|
||||
inStream.Read(channel);
|
||||
inStream.Read(size);
|
||||
inStream.IgnoreBytes(77);
|
||||
|
||||
LUWString message(size);
|
||||
inStream.Read(message);
|
||||
|
||||
LOG("Got a message from (%s) via [%s]: %s", sender.playerName.c_str(), StringifiedEnum::ToString(channel).data(), message.GetAsString().c_str());
|
||||
|
||||
switch (channel) {
|
||||
case eChatChannel::TEAM: {
|
||||
auto* team = Game::playerContainer.GetTeam(playerID);
|
||||
if (team == nullptr) return;
|
||||
|
||||
for (const auto memberId : team->memberIDs) {
|
||||
const auto& otherMember = Game::playerContainer.GetPlayerData(memberId);
|
||||
if (!otherMember) return;
|
||||
SendPrivateChatMessage(sender, otherMember, otherMember, message, eChatChannel::TEAM, eChatMessageResponseCode::SENT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG("Unhandled Chat channel [%s]", StringifiedEnum::ToString(channel).data());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 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::HandlePrivateChatMessage(Packet* packet) {
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
LWOOBJID playerID;
|
||||
inStream.Read(playerID);
|
||||
|
||||
const auto& sender = Game::playerContainer.GetPlayerData(playerID);
|
||||
if (!sender || sender.GetIsMuted()) return;
|
||||
|
||||
eChatChannel channel;
|
||||
uint32_t size;
|
||||
LUWString LUReceiverName;
|
||||
|
||||
inStream.IgnoreBytes(4);
|
||||
inStream.Read(channel);
|
||||
if (channel != eChatChannel::PRIVATE_CHAT) LOG("WARNING: Received Private chat with the wrong channel!");
|
||||
|
||||
inStream.Read(size);
|
||||
inStream.IgnoreBytes(77);
|
||||
|
||||
inStream.Read(LUReceiverName);
|
||||
auto receiverName = LUReceiverName.GetAsString();
|
||||
inStream.IgnoreBytes(2);
|
||||
|
||||
LUWString message(size);
|
||||
inStream.Read(message);
|
||||
|
||||
LOG("Got a message from (%s) via [%s]: %s to %s", sender.playerName.c_str(), StringifiedEnum::ToString(channel).data(), message.GetAsString().c_str(), receiverName.c_str());
|
||||
|
||||
const auto& receiver = Game::playerContainer.GetPlayerData(receiverName);
|
||||
if (!receiver) {
|
||||
PlayerData otherPlayer;
|
||||
otherPlayer.playerName = receiverName;
|
||||
auto responseType = Database::Get()->GetCharacterInfo(receiverName)
|
||||
? eChatMessageResponseCode::NOTONLINE
|
||||
: eChatMessageResponseCode::GENERALERROR;
|
||||
|
||||
SendPrivateChatMessage(sender, otherPlayer, sender, message, eChatChannel::GENERAL, responseType);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check to see if they are friends
|
||||
// only freinds can whispr each other
|
||||
for (const auto& fr : receiver.friends) {
|
||||
if (fr.friendID == sender.playerID) {
|
||||
//To the sender:
|
||||
SendPrivateChatMessage(sender, receiver, sender, message, eChatChannel::PRIVATE_CHAT, eChatMessageResponseCode::SENT);
|
||||
//To the receiver:
|
||||
SendPrivateChatMessage(sender, receiver, receiver, message, eChatChannel::PRIVATE_CHAT, eChatMessageResponseCode::RECEIVEDNEWWHISPER);
|
||||
return;
|
||||
}
|
||||
}
|
||||
SendPrivateChatMessage(sender, receiver, sender, message, eChatChannel::GENERAL, eChatMessageResponseCode::NOTFRIENDS);
|
||||
}
|
||||
|
||||
void ChatPacketHandler::SendPrivateChatMessage(const PlayerData& sender, const PlayerData& receiver, const PlayerData& routeTo, const LUWString& message, const eChatChannel channel, const eChatMessageResponseCode responseCode) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER);
|
||||
bitStream.Write(routeTo.playerID);
|
||||
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE);
|
||||
bitStream.Write(sender.playerID);
|
||||
bitStream.Write(channel);
|
||||
bitStream.Write<uint32_t>(0); // not used
|
||||
bitStream.Write(LUWString(sender.playerName));
|
||||
bitStream.Write(sender.playerID);
|
||||
bitStream.Write<uint16_t>(0); // sourceID
|
||||
bitStream.Write(sender.gmLevel);
|
||||
bitStream.Write(LUWString(receiver.playerName));
|
||||
bitStream.Write(receiver.gmLevel);
|
||||
bitStream.Write(responseCode);
|
||||
bitStream.Write(message);
|
||||
|
||||
SystemAddress sysAddr = routeTo.sysAddr;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
|
||||
void ChatPacketHandler::HandleTeamInvite(Packet* packet) {
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
|
||||
LWOOBJID playerID;
|
||||
LUWString invitedPlayer;
|
||||
|
||||
inStream.Read(playerID);
|
||||
inStream.IgnoreBytes(4);
|
||||
inStream.Read(invitedPlayer);
|
||||
|
||||
const auto& player = Game::playerContainer.GetPlayerData(playerID);
|
||||
|
||||
@@ -463,7 +495,7 @@ void ChatPacketHandler::HandleTeamInvite(Packet* packet) {
|
||||
team = Game::playerContainer.CreateTeam(playerID);
|
||||
}
|
||||
|
||||
const auto& other = Game::playerContainer.GetPlayerData(invitedPlayer);
|
||||
const auto& other = Game::playerContainer.GetPlayerData(invitedPlayer.GetAsString());
|
||||
|
||||
if (!other) return;
|
||||
|
||||
@@ -480,7 +512,7 @@ void ChatPacketHandler::HandleTeamInvite(Packet* packet) {
|
||||
|
||||
SendTeamInvite(other, player);
|
||||
|
||||
LOG("Got team invite: %llu -> %s", playerID, invitedPlayer.c_str());
|
||||
LOG("Got team invite: %llu -> %s", playerID, invitedPlayer.GetAsString().c_str());
|
||||
}
|
||||
|
||||
void ChatPacketHandler::HandleTeamInviteResponse(Packet* packet) {
|
||||
@@ -534,21 +566,25 @@ void ChatPacketHandler::HandleTeamLeave(Packet* packet) {
|
||||
|
||||
void ChatPacketHandler::HandleTeamKick(Packet* packet) {
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
|
||||
LWOOBJID playerID = LWOOBJID_EMPTY;
|
||||
LUWString kickedPlayer;
|
||||
|
||||
inStream.Read(playerID);
|
||||
inStream.IgnoreBytes(4);
|
||||
inStream.Read(kickedPlayer);
|
||||
|
||||
std::string kickedPlayer = PacketUtils::ReadString(0x14, packet, true);
|
||||
|
||||
LOG("(%llu) kicking (%s) from team", playerID, kickedPlayer.c_str());
|
||||
LOG("(%llu) kicking (%s) from team", playerID, kickedPlayer.GetAsString().c_str());
|
||||
|
||||
const auto& kicked = Game::playerContainer.GetPlayerData(kickedPlayer);
|
||||
const auto& kicked = Game::playerContainer.GetPlayerData(kickedPlayer.GetAsString());
|
||||
|
||||
LWOOBJID kickedId = LWOOBJID_EMPTY;
|
||||
|
||||
if (kicked) {
|
||||
kickedId = kicked.playerID;
|
||||
} else {
|
||||
kickedId = Game::playerContainer.GetId(GeneralUtils::UTF8ToUTF16(kickedPlayer));
|
||||
kickedId = Game::playerContainer.GetId(kickedPlayer.string);
|
||||
}
|
||||
|
||||
if (kickedId == LWOOBJID_EMPTY) return;
|
||||
@@ -564,14 +600,17 @@ void ChatPacketHandler::HandleTeamKick(Packet* packet) {
|
||||
|
||||
void ChatPacketHandler::HandleTeamPromote(Packet* packet) {
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
|
||||
LWOOBJID playerID = LWOOBJID_EMPTY;
|
||||
LUWString promotedPlayer;
|
||||
|
||||
inStream.Read(playerID);
|
||||
inStream.IgnoreBytes(4);
|
||||
inStream.Read(promotedPlayer);
|
||||
|
||||
std::string promotedPlayer = PacketUtils::ReadString(0x14, packet, true);
|
||||
LOG("(%llu) promoting (%s) to team leader", playerID, promotedPlayer.GetAsString().c_str());
|
||||
|
||||
LOG("(%llu) promoting (%s) to team leader", playerID, promotedPlayer.c_str());
|
||||
|
||||
const auto& promoted = Game::playerContainer.GetPlayerData(promotedPlayer);
|
||||
const auto& promoted = Game::playerContainer.GetPlayerData(promotedPlayer.GetAsString());
|
||||
|
||||
if (!promoted) return;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "eChatInternalMessageType.h"
|
||||
#include "eWorldMessageType.h"
|
||||
#include "ChatIgnoreList.h"
|
||||
#include "StringifiedEnum.h"
|
||||
|
||||
#include "Game.h"
|
||||
#include "Server.h"
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "Database.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "eChatInternalMessageType.h"
|
||||
#include "eGameMasterLevel.h"
|
||||
#include "ChatPackets.h"
|
||||
#include "dConfig.h"
|
||||
|
||||
@@ -22,6 +23,10 @@ PlayerContainer::~PlayerContainer() {
|
||||
m_Players.clear();
|
||||
}
|
||||
|
||||
PlayerData::PlayerData() {
|
||||
gmLevel == eGameMasterLevel::CIVILIAN;
|
||||
}
|
||||
|
||||
TeamData::TeamData() {
|
||||
lootFlag = Game::config->GetValue("default_team_loot") == "0" ? 0 : 1;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
@@ -22,6 +24,7 @@ struct IgnoreData {
|
||||
};
|
||||
|
||||
struct PlayerData {
|
||||
PlayerData();
|
||||
operator bool() const noexcept {
|
||||
return playerID != LWOOBJID_EMPTY;
|
||||
}
|
||||
@@ -42,6 +45,8 @@ struct PlayerData {
|
||||
std::string playerName;
|
||||
std::vector<FriendData> friends;
|
||||
std::vector<IgnoreData> ignoredPlayers;
|
||||
eGameMasterLevel gmLevel;
|
||||
bool isFTP = false;
|
||||
};
|
||||
|
||||
struct TeamData {
|
||||
|
||||
@@ -3,6 +3,7 @@ set(DGAME_SOURCES "Character.cpp"
|
||||
"EntityManager.cpp"
|
||||
"LeaderboardManager.cpp"
|
||||
"Player.cpp"
|
||||
"PlayerManager.cpp"
|
||||
"TeamManager.cpp"
|
||||
"TradingManager.cpp"
|
||||
"User.cpp"
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "eTriggerEventType.h"
|
||||
#include "eObjectBits.h"
|
||||
#include "PositionUpdate.h"
|
||||
#include "eChatMessageType.h"
|
||||
|
||||
//Component includes:
|
||||
#include "Component.h"
|
||||
@@ -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) {
|
||||
@@ -2125,9 +2137,9 @@ void Entity::ProcessPositionUpdate(PositionUpdate& update) {
|
||||
controllablePhysicsComponent->SetAngularVelocity(update.angularVelocity);
|
||||
controllablePhysicsComponent->SetDirtyAngularVelocity(update.angularVelocity != NiPoint3::ZERO);
|
||||
|
||||
auto* player = static_cast<Player*>(this);
|
||||
player->SetGhostReferencePoint(update.position);
|
||||
Game::entityManager->QueueGhostUpdate(player->GetObjectID());
|
||||
auto* ghostComponent = GetComponent<GhostComponent>();
|
||||
if (ghostComponent) ghostComponent->SetGhostReferencePoint(update.position);
|
||||
Game::entityManager->QueueGhostUpdate(GetObjectID());
|
||||
|
||||
if (updateChar) Game::entityManager->SerializeEntity(this);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include "eGameMasterLevel.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "eReplicaPacketType.h"
|
||||
#include "PlayerManager.h"
|
||||
#include "GhostComponent.h"
|
||||
|
||||
// Configure which zones have ghosting disabled, mostly small worlds.
|
||||
std::vector<LWOMAPID> EntityManager::m_GhostingExcludedZones = {
|
||||
@@ -187,8 +189,9 @@ void EntityManager::SerializeEntities() {
|
||||
entity->WriteComponents(&stream, eReplicaPacketType::SERIALIZATION);
|
||||
|
||||
if (entity->GetIsGhostingCandidate()) {
|
||||
for (auto* player : Player::GetAllPlayers()) {
|
||||
if (player->IsObserved(toSerialize)) {
|
||||
for (auto* player : PlayerManager::GetAllPlayers()) {
|
||||
auto* ghostComponent = player->GetComponent<GhostComponent>();
|
||||
if (ghostComponent && ghostComponent->IsObserved(toSerialize)) {
|
||||
Game::server->Send(&stream, player->GetSystemAddress(), false);
|
||||
}
|
||||
}
|
||||
@@ -376,11 +379,12 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr
|
||||
if (skipChecks) {
|
||||
Game::server->Send(&stream, UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||
} else {
|
||||
for (auto* player : Player::GetAllPlayers()) {
|
||||
for (auto* player : PlayerManager::GetAllPlayers()) {
|
||||
if (player->GetPlayerReadyForUpdates()) {
|
||||
Game::server->Send(&stream, player->GetSystemAddress(), false);
|
||||
} else {
|
||||
player->AddLimboConstruction(entity->GetObjectID());
|
||||
auto* ghostComponent = player->GetComponent<GhostComponent>();
|
||||
if (ghostComponent) ghostComponent->AddLimboConstruction(entity->GetObjectID());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -405,7 +409,7 @@ void EntityManager::ConstructAllEntities(const SystemAddress& sysAddr) {
|
||||
}
|
||||
}
|
||||
|
||||
UpdateGhosting(Player::GetPlayer(sysAddr));
|
||||
UpdateGhosting(PlayerManager::GetPlayer(sysAddr));
|
||||
}
|
||||
|
||||
void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr) {
|
||||
@@ -418,9 +422,10 @@ void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr)
|
||||
|
||||
Game::server->Send(&stream, sysAddr, sysAddr == UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
for (auto* player : Player::GetAllPlayers()) {
|
||||
for (auto* player : PlayerManager::GetAllPlayers()) {
|
||||
if (!player->GetPlayerReadyForUpdates()) {
|
||||
player->RemoveLimboConstruction(entity->GetObjectID());
|
||||
auto* ghostComponent = player->GetComponent<GhostComponent>();
|
||||
if (ghostComponent) ghostComponent->RemoveLimboConstruction(entity->GetObjectID());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -465,7 +470,7 @@ void EntityManager::QueueGhostUpdate(LWOOBJID playerID) {
|
||||
|
||||
void EntityManager::UpdateGhosting() {
|
||||
for (const auto playerID : m_PlayersToUpdateGhosting) {
|
||||
auto* player = Player::GetPlayer(playerID);
|
||||
auto* player = PlayerManager::GetPlayer(playerID);
|
||||
|
||||
if (player == nullptr) {
|
||||
continue;
|
||||
@@ -483,13 +488,14 @@ void EntityManager::UpdateGhosting(Player* player) {
|
||||
}
|
||||
|
||||
auto* missionComponent = player->GetComponent<MissionComponent>();
|
||||
auto* ghostComponent = player->GetComponent<GhostComponent>();
|
||||
|
||||
if (missionComponent == nullptr) {
|
||||
if (missionComponent == nullptr || !ghostComponent) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& referencePoint = player->GetGhostReferencePoint();
|
||||
const auto isOverride = player->GetGhostOverride();
|
||||
const auto& referencePoint = ghostComponent->GetGhostReferencePoint();
|
||||
const auto isOverride = ghostComponent->GetGhostOverride();
|
||||
|
||||
for (auto* entity : m_EntitiesToGhost) {
|
||||
const auto isAudioEmitter = entity->GetLOT() == 6368;
|
||||
@@ -498,7 +504,7 @@ void EntityManager::UpdateGhosting(Player* player) {
|
||||
|
||||
const int32_t id = entity->GetObjectID();
|
||||
|
||||
const auto observed = player->IsObserved(id);
|
||||
const auto observed = ghostComponent->IsObserved(id);
|
||||
|
||||
const auto distance = NiPoint3::DistanceSquared(referencePoint, entityPoint);
|
||||
|
||||
@@ -510,7 +516,7 @@ void EntityManager::UpdateGhosting(Player* player) {
|
||||
}
|
||||
|
||||
if (observed && distance > ghostingDistanceMax && !isOverride) {
|
||||
player->GhostEntity(id);
|
||||
ghostComponent->GhostEntity(id);
|
||||
|
||||
DestructEntity(entity, player->GetSystemAddress());
|
||||
|
||||
@@ -527,7 +533,7 @@ void EntityManager::UpdateGhosting(Player* player) {
|
||||
}
|
||||
}
|
||||
|
||||
player->ObserveEntity(id);
|
||||
ghostComponent->ObserveEntity(id);
|
||||
|
||||
ConstructEntity(entity, player->GetSystemAddress());
|
||||
|
||||
@@ -548,23 +554,26 @@ void EntityManager::CheckGhosting(Entity* entity) {
|
||||
|
||||
const auto isAudioEmitter = entity->GetLOT() == 6368;
|
||||
|
||||
for (auto* player : Player::GetAllPlayers()) {
|
||||
const auto& entityPoint = player->GetGhostReferencePoint();
|
||||
for (auto* player : PlayerManager::GetAllPlayers()) {
|
||||
auto* ghostComponent = player->GetComponent<GhostComponent>();
|
||||
if (!ghostComponent) continue;
|
||||
|
||||
const auto& entityPoint = ghostComponent->GetGhostReferencePoint();
|
||||
|
||||
const int32_t id = entity->GetObjectID();
|
||||
|
||||
const auto observed = player->IsObserved(id);
|
||||
const auto observed = ghostComponent->IsObserved(id);
|
||||
|
||||
const auto distance = NiPoint3::DistanceSquared(referencePoint, entityPoint);
|
||||
|
||||
if (observed && distance > ghostingDistanceMax) {
|
||||
player->GhostEntity(id);
|
||||
ghostComponent->GhostEntity(id);
|
||||
|
||||
DestructEntity(entity, player->GetSystemAddress());
|
||||
|
||||
entity->SetObservers(entity->GetObservers() - 1);
|
||||
} else if (!observed && ghostingDistanceMin > distance) {
|
||||
player->ObserveEntity(id);
|
||||
ghostComponent->ObserveEntity(id);
|
||||
|
||||
ConstructEntity(entity, player->GetSystemAddress());
|
||||
|
||||
|
||||
134
dGame/Player.cpp
134
dGame/Player.cpp
@@ -12,22 +12,7 @@
|
||||
#include "CppScripts.h"
|
||||
#include "Loot.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
|
||||
namespace {
|
||||
std::vector<Player*> m_Players;
|
||||
};
|
||||
|
||||
const std::vector<Player*>& Player::GetAllPlayers() {
|
||||
return m_Players;
|
||||
}
|
||||
|
||||
void Player::SetGhostReferencePoint(const NiPoint3& value) {
|
||||
m_GhostReferencePoint = value;
|
||||
}
|
||||
|
||||
void Player::SetGhostOverridePoint(const NiPoint3& value) {
|
||||
m_GhostOverridePoint = value;
|
||||
}
|
||||
#include "PlayerManager.h"
|
||||
|
||||
void Player::SetRespawnPos(const NiPoint3& position) {
|
||||
if (!m_Character) return;
|
||||
@@ -54,122 +39,17 @@ Player::Player(const LWOOBJID& objectID, const EntityInfo info, User* user, Enti
|
||||
m_SystemAddress = m_ParentUser->GetSystemAddress();
|
||||
m_DroppedCoins = 0;
|
||||
|
||||
m_GhostReferencePoint = NiPoint3::ZERO;
|
||||
m_GhostOverridePoint = NiPoint3::ZERO;
|
||||
m_GhostOverride = false;
|
||||
|
||||
int32_t initialObservedEntitiesCapacity = 256;
|
||||
m_ObservedEntities.resize(initialObservedEntitiesCapacity);
|
||||
|
||||
m_Character->SetEntity(this);
|
||||
|
||||
const auto& iter = std::find(m_Players.begin(), m_Players.end(), this);
|
||||
|
||||
if (iter == m_Players.end()) {
|
||||
m_Players.push_back(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::AddLimboConstruction(LWOOBJID objectId) {
|
||||
const auto iter = std::find(m_LimboConstructions.begin(), m_LimboConstructions.end(), objectId);
|
||||
if (iter == m_LimboConstructions.end()) {
|
||||
m_LimboConstructions.push_back(objectId);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::RemoveLimboConstruction(LWOOBJID objectId) {
|
||||
const auto iter = std::find(m_LimboConstructions.begin(), m_LimboConstructions.end(), objectId);
|
||||
if (iter != m_LimboConstructions.end()) {
|
||||
m_LimboConstructions.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::ConstructLimboEntities() {
|
||||
for (const auto& objectId : m_LimboConstructions) {
|
||||
auto* entity = Game::entityManager->GetEntity(objectId);
|
||||
if (!entity) continue;
|
||||
|
||||
Game::entityManager->ConstructEntity(entity, m_SystemAddress);
|
||||
}
|
||||
|
||||
m_LimboConstructions.clear();
|
||||
}
|
||||
|
||||
void Player::ObserveEntity(int32_t id) {
|
||||
for (auto& observedEntity : m_ObservedEntities) {
|
||||
if (observedEntity == 0 || observedEntity == id) {
|
||||
observedEntity = id;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_ObservedEntities.reserve(m_ObservedEntities.size() + 1);
|
||||
|
||||
m_ObservedEntities.push_back(id);
|
||||
}
|
||||
|
||||
bool Player::IsObserved(int32_t id) {
|
||||
return std::find(m_ObservedEntities.begin(), m_ObservedEntities.end(), id) != m_ObservedEntities.end();
|
||||
}
|
||||
|
||||
void Player::GhostEntity(int32_t id) {
|
||||
for (auto& observedEntity : m_ObservedEntities) {
|
||||
if (observedEntity == id) {
|
||||
observedEntity = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Player* Player::GetPlayer(const SystemAddress& sysAddr) {
|
||||
auto* entity = UserManager::Instance()->GetUser(sysAddr)->GetLastUsedChar()->GetEntity();
|
||||
|
||||
return static_cast<Player*>(entity);
|
||||
}
|
||||
|
||||
Player* Player::GetPlayer(const std::string& name) {
|
||||
const auto characters = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::CHARACTER);
|
||||
|
||||
Player* player = nullptr;
|
||||
for (auto* character : characters) {
|
||||
if (!character->IsPlayer()) continue;
|
||||
|
||||
if (GeneralUtils::CaseInsensitiveStringCompare(name, character->GetCharacter()->GetName())) {
|
||||
player = dynamic_cast<Player*>(character);
|
||||
}
|
||||
}
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
Player* Player::GetPlayer(LWOOBJID playerID) {
|
||||
Player* playerToReturn = nullptr;
|
||||
for (auto* player : m_Players) {
|
||||
if (player->GetObjectID() == playerID) {
|
||||
playerToReturn = player;
|
||||
}
|
||||
}
|
||||
|
||||
return playerToReturn;
|
||||
PlayerManager::AddPlayer(this);
|
||||
}
|
||||
|
||||
Player::~Player() {
|
||||
LOG("Deleted player");
|
||||
|
||||
for (auto& observedEntity : m_ObservedEntities) {
|
||||
if (observedEntity == 0) continue;
|
||||
|
||||
auto* entity = Game::entityManager->GetGhostCandidate(observedEntity);
|
||||
if (!entity) continue;
|
||||
|
||||
entity->SetObservers(entity->GetObservers() - 1);
|
||||
}
|
||||
|
||||
m_LimboConstructions.clear();
|
||||
|
||||
const auto iter = std::find(m_Players.begin(), m_Players.end(), this);
|
||||
|
||||
if (iter == m_Players.end()) {
|
||||
|
||||
// Make sure the player exists first. Remove afterwards to prevent the OnPlayerExist functions from not being able to find the player.
|
||||
if (!PlayerManager::RemovePlayer(this)) {
|
||||
LOG("Unable to find player to remove from manager.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -188,6 +68,4 @@ Player::~Player() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_Players.erase(iter);
|
||||
}
|
||||
|
||||
@@ -26,14 +26,6 @@ public:
|
||||
|
||||
const NiQuaternion& GetRespawnRotation() const override { return m_respawnRot; };
|
||||
|
||||
const NiPoint3& GetGhostReferencePoint() const { return m_GhostOverride ? m_GhostOverridePoint : m_GhostReferencePoint; };
|
||||
|
||||
const NiPoint3& GetOriginGhostReferencePoint() const { return m_GhostReferencePoint; };
|
||||
|
||||
const NiPoint3& GetGhostOverridePoint() const { return m_GhostOverridePoint; };
|
||||
|
||||
bool GetGhostOverride() const { return m_GhostOverride; };
|
||||
|
||||
std::map<LWOOBJID, Loot::Info>& GetDroppedLoot() { return m_DroppedLoot; };
|
||||
|
||||
uint64_t GetDroppedCoins() const { return m_DroppedCoins; };
|
||||
@@ -42,8 +34,6 @@ public:
|
||||
* Setters
|
||||
*/
|
||||
|
||||
void SetGhostOverride(bool value) { m_GhostOverride = value; };
|
||||
|
||||
void SetDroppedCoins(const uint64_t value) { m_DroppedCoins = value; };
|
||||
|
||||
void SetSystemAddress(const SystemAddress& value) override;
|
||||
@@ -52,38 +42,10 @@ public:
|
||||
|
||||
void SetRespawnRot(const NiQuaternion& rotation) override;
|
||||
|
||||
void SetGhostReferencePoint(const NiPoint3& value);
|
||||
|
||||
void SetGhostOverridePoint(const NiPoint3& value);
|
||||
|
||||
/**
|
||||
* Ghosting
|
||||
*/
|
||||
|
||||
void AddLimboConstruction(LWOOBJID objectId);
|
||||
|
||||
void RemoveLimboConstruction(LWOOBJID objectId);
|
||||
|
||||
void ConstructLimboEntities();
|
||||
|
||||
void ObserveEntity(const int32_t id);
|
||||
|
||||
bool IsObserved(const int32_t id);
|
||||
|
||||
void GhostEntity(const int32_t id);
|
||||
|
||||
/**
|
||||
* Static methods
|
||||
*/
|
||||
|
||||
static Player* GetPlayer(const SystemAddress& sysAddr);
|
||||
|
||||
static Player* GetPlayer(const std::string& name);
|
||||
|
||||
static Player* GetPlayer(LWOOBJID playerID);
|
||||
|
||||
static const std::vector<Player*>& GetAllPlayers();
|
||||
|
||||
~Player() override;
|
||||
private:
|
||||
SystemAddress m_SystemAddress;
|
||||
@@ -94,16 +56,6 @@ private:
|
||||
|
||||
User* m_ParentUser;
|
||||
|
||||
NiPoint3 m_GhostReferencePoint;
|
||||
|
||||
NiPoint3 m_GhostOverridePoint;
|
||||
|
||||
bool m_GhostOverride;
|
||||
|
||||
std::vector<int32_t> m_ObservedEntities;
|
||||
|
||||
std::vector<LWOOBJID> m_LimboConstructions;
|
||||
|
||||
std::map<LWOOBJID, Loot::Info> m_DroppedLoot;
|
||||
|
||||
uint64_t m_DroppedCoins;
|
||||
|
||||
68
dGame/PlayerManager.cpp
Normal file
68
dGame/PlayerManager.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#include "PlayerManager.h"
|
||||
|
||||
#include "Character.h"
|
||||
#include "Player.h"
|
||||
#include "User.h"
|
||||
#include "UserManager.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
|
||||
namespace {
|
||||
std::vector<Player*> m_Players;
|
||||
};
|
||||
|
||||
const std::vector<Player*>& PlayerManager::GetAllPlayers() {
|
||||
return m_Players;
|
||||
}
|
||||
|
||||
void PlayerManager::AddPlayer(Player* player) {
|
||||
const auto& iter = std::find(m_Players.begin(), m_Players.end(), player);
|
||||
|
||||
if (iter == m_Players.end()) {
|
||||
m_Players.push_back(player);
|
||||
}
|
||||
}
|
||||
|
||||
bool PlayerManager::RemovePlayer(Player* player) {
|
||||
const auto iter = std::find(m_Players.begin(), m_Players.end(), player);
|
||||
|
||||
const bool toReturn = iter != m_Players.end();
|
||||
if (toReturn) {
|
||||
m_Players.erase(iter);
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
Player* PlayerManager::GetPlayer(const SystemAddress& sysAddr) {
|
||||
auto* entity = UserManager::Instance()->GetUser(sysAddr)->GetLastUsedChar()->GetEntity();
|
||||
|
||||
return static_cast<Player*>(entity);
|
||||
}
|
||||
|
||||
Player* PlayerManager::GetPlayer(const std::string& name) {
|
||||
const auto characters = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::CHARACTER);
|
||||
|
||||
Player* player = nullptr;
|
||||
for (auto* character : characters) {
|
||||
if (!character->IsPlayer()) continue;
|
||||
|
||||
if (GeneralUtils::CaseInsensitiveStringCompare(name, character->GetCharacter()->GetName())) {
|
||||
player = dynamic_cast<Player*>(character);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
Player* PlayerManager::GetPlayer(LWOOBJID playerID) {
|
||||
Player* playerToReturn = nullptr;
|
||||
for (auto* player : m_Players) {
|
||||
if (player->GetObjectID() == playerID) {
|
||||
playerToReturn = player;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return playerToReturn;
|
||||
}
|
||||
25
dGame/PlayerManager.h
Normal file
25
dGame/PlayerManager.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef __PLAYERMANAGER__H__
|
||||
#define __PLAYERMANAGER__H__
|
||||
|
||||
#include "dCommonVars.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class Player;
|
||||
struct SystemAddress;
|
||||
|
||||
namespace PlayerManager {
|
||||
void AddPlayer(Player* player);
|
||||
|
||||
bool RemovePlayer(Player* player);
|
||||
|
||||
Player* GetPlayer(const SystemAddress& sysAddr);
|
||||
|
||||
Player* GetPlayer(const std::string& name);
|
||||
|
||||
Player* GetPlayer(LWOOBJID playerID);
|
||||
|
||||
const std::vector<Player*>& GetAllPlayers();
|
||||
};
|
||||
|
||||
#endif //!__PLAYERMANAGER__H__
|
||||
@@ -1,4 +1,57 @@
|
||||
#include "GhostComponent.h"
|
||||
|
||||
// TODO Move ghosting related code from Player to here
|
||||
GhostComponent::GhostComponent(Entity* parent) : Component(parent) {}
|
||||
GhostComponent::GhostComponent(Entity* parent) : Component(parent) {
|
||||
m_GhostReferencePoint = NiPoint3::ZERO;
|
||||
m_GhostOverridePoint = NiPoint3::ZERO;
|
||||
m_GhostOverride = false;
|
||||
}
|
||||
|
||||
GhostComponent::~GhostComponent() {
|
||||
for (auto& observedEntity : m_ObservedEntities) {
|
||||
if (observedEntity == 0) continue;
|
||||
|
||||
auto* entity = Game::entityManager->GetGhostCandidate(observedEntity);
|
||||
if (!entity) continue;
|
||||
|
||||
entity->SetObservers(entity->GetObservers() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void GhostComponent::SetGhostReferencePoint(const NiPoint3& value) {
|
||||
m_GhostReferencePoint = value;
|
||||
}
|
||||
|
||||
void GhostComponent::SetGhostOverridePoint(const NiPoint3& value) {
|
||||
m_GhostOverridePoint = value;
|
||||
}
|
||||
|
||||
void GhostComponent::AddLimboConstruction(LWOOBJID objectId) {
|
||||
m_LimboConstructions.insert(objectId);
|
||||
}
|
||||
|
||||
void GhostComponent::RemoveLimboConstruction(LWOOBJID objectId) {
|
||||
m_LimboConstructions.erase(objectId);
|
||||
}
|
||||
|
||||
void GhostComponent::ConstructLimboEntities() {
|
||||
for (const auto& objectId : m_LimboConstructions) {
|
||||
auto* entity = Game::entityManager->GetEntity(objectId);
|
||||
if (!entity) continue;
|
||||
|
||||
Game::entityManager->ConstructEntity(entity, m_Parent->GetSystemAddress());
|
||||
}
|
||||
|
||||
m_LimboConstructions.clear();
|
||||
}
|
||||
|
||||
void GhostComponent::ObserveEntity(int32_t id) {
|
||||
m_ObservedEntities.insert(id);
|
||||
}
|
||||
|
||||
bool GhostComponent::IsObserved(int32_t id) {
|
||||
return m_ObservedEntities.contains(id);
|
||||
}
|
||||
|
||||
void GhostComponent::GhostEntity(int32_t id) {
|
||||
m_ObservedEntities.erase(id);
|
||||
}
|
||||
|
||||
@@ -3,11 +3,52 @@
|
||||
|
||||
#include "Component.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include <unordered_set>
|
||||
|
||||
class NiPoint3;
|
||||
|
||||
class GhostComponent : public Component {
|
||||
public:
|
||||
static inline const eReplicaComponentType ComponentType = eReplicaComponentType::GHOST;
|
||||
GhostComponent(Entity* parent);
|
||||
~GhostComponent() override;
|
||||
|
||||
void SetGhostOverride(bool value) { m_GhostOverride = value; };
|
||||
|
||||
const NiPoint3& GetGhostReferencePoint() const { return m_GhostOverride ? m_GhostOverridePoint : m_GhostReferencePoint; };
|
||||
|
||||
const NiPoint3& GetOriginGhostReferencePoint() const { return m_GhostReferencePoint; };
|
||||
|
||||
const NiPoint3& GetGhostOverridePoint() const { return m_GhostOverridePoint; };
|
||||
|
||||
bool GetGhostOverride() const { return m_GhostOverride; };
|
||||
|
||||
void SetGhostReferencePoint(const NiPoint3& value);
|
||||
|
||||
void SetGhostOverridePoint(const NiPoint3& value);
|
||||
|
||||
void AddLimboConstruction(const LWOOBJID objectId);
|
||||
|
||||
void RemoveLimboConstruction(const LWOOBJID objectId);
|
||||
|
||||
void ConstructLimboEntities();
|
||||
|
||||
void ObserveEntity(const int32_t id);
|
||||
|
||||
bool IsObserved(const int32_t id);
|
||||
|
||||
void GhostEntity(const int32_t id);
|
||||
|
||||
private:
|
||||
NiPoint3 m_GhostReferencePoint;
|
||||
|
||||
NiPoint3 m_GhostOverridePoint;
|
||||
|
||||
std::unordered_set<int32_t> m_ObservedEntities;
|
||||
|
||||
std::unordered_set<LWOOBJID> m_LimboConstructions;
|
||||
|
||||
bool m_GhostOverride;
|
||||
};
|
||||
|
||||
#endif //!__GHOSTCOMPONENT__H__
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "eMissionTaskType.h"
|
||||
#include "eObjectBits.h"
|
||||
#include "CharacterComponent.h"
|
||||
#include "PlayerManager.h"
|
||||
|
||||
#include <vector>
|
||||
#include "CppScripts.h"
|
||||
@@ -227,7 +228,7 @@ void PropertyManagementComponent::OnStartBuilding() {
|
||||
|
||||
if (ownerEntity == nullptr) return;
|
||||
|
||||
const auto players = Player::GetAllPlayers();
|
||||
const auto players = PlayerManager::GetAllPlayers();
|
||||
|
||||
LWOMAPID zoneId = 1100;
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "QuickBuildComponent.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "eEndBehavior.h"
|
||||
#include "PlayerManager.h"
|
||||
|
||||
|
||||
TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo): Component(parent) {
|
||||
@@ -175,7 +176,7 @@ std::vector<Entity*> TriggerComponent::GatherTargets(LUTriggers::Command* comman
|
||||
}
|
||||
} else if (command->target == "objGroup") entities = Game::entityManager->GetEntitiesInGroup(command->targetName);
|
||||
else if (command->target == "allPlayers") {
|
||||
for (auto* player : Player::GetAllPlayers()) {
|
||||
for (auto* player : PlayerManager::GetAllPlayers()) {
|
||||
entities.push_back(player);
|
||||
}
|
||||
} else if (command->target == "allNPCs") { /*UNUSED*/ }
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "eGameMessageType.h"
|
||||
#include "ePlayerFlag.h"
|
||||
#include "dConfig.h"
|
||||
#include "GhostComponent.h"
|
||||
#include "StringifiedEnum.h"
|
||||
|
||||
void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const SystemAddress& sysAddr, LWOOBJID objectID, eGameMessageType messageID) {
|
||||
@@ -108,9 +109,9 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
|
||||
GameMessages::SendRestoreToPostLoadStats(entity, sysAddr);
|
||||
entity->SetPlayerReadyForUpdates();
|
||||
|
||||
auto* player = dynamic_cast<Player*>(entity);
|
||||
if (player != nullptr) {
|
||||
player->ConstructLimboEntities();
|
||||
auto* ghostComponent = entity->GetComponent<GhostComponent>();
|
||||
if (ghostComponent != nullptr) {
|
||||
ghostComponent->ConstructLimboEntities();
|
||||
}
|
||||
|
||||
InventoryComponent* inv = entity->GetComponent<InventoryComponent>();
|
||||
@@ -137,14 +138,14 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
|
||||
|
||||
Entity* zoneControl = Game::entityManager->GetZoneControlEntity();
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) {
|
||||
script->OnPlayerLoaded(zoneControl, player);
|
||||
script->OnPlayerLoaded(zoneControl, entity);
|
||||
}
|
||||
|
||||
std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPT);
|
||||
for (Entity* scriptEntity : scriptedActs) {
|
||||
if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) {
|
||||
script->OnPlayerLoaded(scriptEntity, player);
|
||||
script->OnPlayerLoaded(scriptEntity, entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
#include "RailActivatorComponent.h"
|
||||
#include "LevelProgressionComponent.h"
|
||||
#include "DonationVendorComponent.h"
|
||||
#include "GhostComponent.h"
|
||||
|
||||
// Message includes:
|
||||
#include "dZoneManager.h"
|
||||
@@ -96,6 +97,7 @@
|
||||
#include "eGameMessageType.h"
|
||||
#include "ePetAbilityType.h"
|
||||
#include "ActivityManager.h"
|
||||
#include "PlayerManager.h"
|
||||
|
||||
#include "CDComponentsRegistryTable.h"
|
||||
#include "CDObjectsTable.h"
|
||||
@@ -2693,7 +2695,7 @@ void GameMessages::HandlePropertyEntranceSync(RakNet::BitStream* inStream, Entit
|
||||
filterText.push_back(c);
|
||||
}
|
||||
|
||||
auto* player = Player::GetPlayer(sysAddr);
|
||||
auto* player = PlayerManager::GetPlayer(sysAddr);
|
||||
|
||||
auto* entranceComponent = entity->GetComponent<PropertyEntranceComponent>();
|
||||
|
||||
@@ -2720,7 +2722,7 @@ void GameMessages::HandleEnterProperty(RakNet::BitStream* inStream, Entity* enti
|
||||
inStream->Read(index);
|
||||
inStream->Read(returnToZone);
|
||||
|
||||
auto* player = Player::GetPlayer(sysAddr);
|
||||
auto* player = PlayerManager::GetPlayer(sysAddr);
|
||||
|
||||
auto* entranceComponent = entity->GetComponent<PropertyEntranceComponent>();
|
||||
if (entranceComponent != nullptr) {
|
||||
@@ -4601,10 +4603,11 @@ void GameMessages::HandleToggleGhostReferenceOverride(RakNet::BitStream* inStrea
|
||||
|
||||
inStream->Read(bOverride);
|
||||
|
||||
auto* player = Player::GetPlayer(sysAddr);
|
||||
auto* player = PlayerManager::GetPlayer(sysAddr);
|
||||
|
||||
if (player != nullptr) {
|
||||
player->SetGhostOverride(bOverride);
|
||||
auto* ghostComponent = entity->GetComponent<GhostComponent>();
|
||||
if (ghostComponent) ghostComponent->SetGhostOverride(bOverride);
|
||||
|
||||
Game::entityManager->UpdateGhosting(player);
|
||||
}
|
||||
@@ -4616,10 +4619,11 @@ void GameMessages::HandleSetGhostReferencePosition(RakNet::BitStream* inStream,
|
||||
|
||||
inStream->Read(position);
|
||||
|
||||
auto* player = Player::GetPlayer(sysAddr);
|
||||
auto* player = PlayerManager::GetPlayer(sysAddr);
|
||||
|
||||
if (player != nullptr) {
|
||||
player->SetGhostOverridePoint(position);
|
||||
auto* ghostComponent = entity->GetComponent<GhostComponent>();
|
||||
if (ghostComponent) ghostComponent->SetGhostOverridePoint(position);
|
||||
|
||||
Game::entityManager->UpdateGhosting(player);
|
||||
}
|
||||
@@ -4880,7 +4884,7 @@ void GameMessages::HandleFireEventServerSide(RakNet::BitStream* inStream, Entity
|
||||
inStream->Read(senderID);
|
||||
|
||||
auto* sender = Game::entityManager->GetEntity(senderID);
|
||||
auto* player = Player::GetPlayer(sysAddr);
|
||||
auto* player = PlayerManager::GetPlayer(sysAddr);
|
||||
|
||||
if (!player) {
|
||||
return;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "UserManager.h"
|
||||
#include "dConfig.h"
|
||||
#include <optional>
|
||||
#include "PlayerManager.h"
|
||||
|
||||
Entity* GetPossessedEntity(const LWOOBJID& objId) {
|
||||
auto* entity = Game::entityManager->GetEntity(objId);
|
||||
@@ -49,7 +50,7 @@ void LogAndSaveFailedAntiCheatCheck(const LWOOBJID& id, const SystemAddress& sys
|
||||
User* toReport = nullptr;
|
||||
switch (checkType) {
|
||||
case CheckType::Entity: {
|
||||
auto* player = Player::GetPlayer(sysAddr);
|
||||
auto* player = PlayerManager::GetPlayer(sysAddr);
|
||||
auto* entity = GetPossessedEntity(id);
|
||||
|
||||
// If player exists and entity exists in world, use both for logging info.
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
#include "eConnectionType.h"
|
||||
#include "eChatInternalMessageType.h"
|
||||
#include "eMasterMessageType.h"
|
||||
#include "PlayerManager.h"
|
||||
|
||||
#include "CDRewardCodesTable.h"
|
||||
#include "CDObjectsTable.h"
|
||||
@@ -214,10 +215,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
if (chatCommand == "who") {
|
||||
ChatPackets::SendSystemMessage(
|
||||
sysAddr,
|
||||
u"Players in this instance: (" + GeneralUtils::to_u16string(Player::GetAllPlayers().size()) + u")"
|
||||
u"Players in this instance: (" + GeneralUtils::to_u16string(PlayerManager::GetAllPlayers().size()) + u")"
|
||||
);
|
||||
|
||||
for (auto* player : Player::GetAllPlayers()) {
|
||||
for (auto* player : PlayerManager::GetAllPlayers()) {
|
||||
const auto& name = player->GetCharacter()->GetName();
|
||||
|
||||
ChatPackets::SendSystemMessage(
|
||||
@@ -473,7 +474,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
if (chatCommand == "kill" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
|
||||
ChatPackets::SendSystemMessage(sysAddr, u"Brutally murdering that player, if online on this server.");
|
||||
|
||||
auto* player = Player::GetPlayer(args[0]);
|
||||
auto* player = PlayerManager::GetPlayer(args[0]);
|
||||
if (player) {
|
||||
player->Smash(entity->GetObjectID());
|
||||
ChatPackets::SendSystemMessage(sysAddr, u"It has been done, do you feel good about yourself now?");
|
||||
@@ -993,7 +994,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
|
||||
if (chatCommand == "mute" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) {
|
||||
if (args.size() >= 1) {
|
||||
auto* player = Player::GetPlayer(args[0]);
|
||||
auto* player = PlayerManager::GetPlayer(args[0]);
|
||||
|
||||
uint32_t accountId = 0;
|
||||
LWOOBJID characterId = 0;
|
||||
@@ -1072,7 +1073,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
|
||||
if (chatCommand == "kick" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_MODERATOR) {
|
||||
if (args.size() == 1) {
|
||||
auto* player = Player::GetPlayer(args[0]);
|
||||
auto* player = PlayerManager::GetPlayer(args[0]);
|
||||
|
||||
std::u16string username = GeneralUtils::UTF8ToUTF16(args[0]);
|
||||
if (player == nullptr) {
|
||||
@@ -1090,7 +1091,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
|
||||
if (chatCommand == "ban" && entity->GetGMLevel() >= eGameMasterLevel::SENIOR_MODERATOR) {
|
||||
if (args.size() == 1) {
|
||||
auto* player = Player::GetPlayer(args[0]);
|
||||
auto* player = PlayerManager::GetPlayer(args[0]);
|
||||
|
||||
uint32_t accountId = 0;
|
||||
|
||||
@@ -1303,7 +1304,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
if (args.size() > 1) {
|
||||
requestedPlayerToSetLevelOf = args[1];
|
||||
|
||||
auto requestedPlayer = Player::GetPlayer(requestedPlayerToSetLevelOf);
|
||||
auto requestedPlayer = PlayerManager::GetPlayer(requestedPlayerToSetLevelOf);
|
||||
|
||||
if (!requestedPlayer) {
|
||||
ChatPackets::SendSystemMessage(sysAddr, u"No player found with username: (" + GeneralUtils::UTF8ToUTF16(requestedPlayerToSetLevelOf) + u").");
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
#include "StringifiedEnum.h"
|
||||
#include "Server.h"
|
||||
#include "PositionUpdate.h"
|
||||
#include "PlayerManager.h"
|
||||
|
||||
namespace Game {
|
||||
Logger* logger = nullptr;
|
||||
@@ -798,7 +799,7 @@ void HandlePacket(Packet* packet) {
|
||||
auto* entity = Game::entityManager->GetEntity(c->GetObjectID());
|
||||
|
||||
if (!entity) {
|
||||
entity = Player::GetPlayer(packet->systemAddress);
|
||||
entity = PlayerManager::GetPlayer(packet->systemAddress);
|
||||
}
|
||||
|
||||
if (entity) {
|
||||
@@ -1125,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);
|
||||
}
|
||||
@@ -1205,7 +1207,7 @@ void HandlePacket(Packet* packet) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* entity = Player::GetPlayer(packet->systemAddress);
|
||||
auto* entity = PlayerManager::GetPlayer(packet->systemAddress);
|
||||
|
||||
if (entity == nullptr) {
|
||||
LOG("Unable to get player to parse chat moderation request");
|
||||
@@ -1365,7 +1367,7 @@ void WorldShutdownProcess(uint32_t zoneId) {
|
||||
for (auto i = 0; i < Game::server->GetReplicaManager()->GetParticipantCount(); ++i) {
|
||||
const auto& player = Game::server->GetReplicaManager()->GetParticipantAtIndex(i);
|
||||
|
||||
auto* entity = Player::GetPlayer(player);
|
||||
auto* entity = PlayerManager::GetPlayer(player);
|
||||
LOG("Saving data!");
|
||||
if (entity != nullptr && entity->GetCharacter() != nullptr) {
|
||||
auto* skillComponent = entity->GetComponent<SkillComponent>();
|
||||
|
||||
Reference in New Issue
Block a user