mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-12-16 20:24:39 -06:00
Compare commits
6 Commits
v3.2.0
...
copilot/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5c6a61c82 | ||
|
|
d5822e2d24 | ||
|
|
93354af834 | ||
|
|
21a2ddcfd9 | ||
|
|
50e6cf9059 | ||
|
|
3364884126 |
@@ -6,6 +6,12 @@ Darkflame Universe (DLU) is a server emulator for LEGO® Universe. Development s
|
||||
### LEGO® Universe
|
||||
Developed by NetDevil and The LEGO Group, LEGO® Universe launched in October 2010 and ceased operation in January 2012.
|
||||
|
||||
## Architecture Documentation
|
||||
For developers and those interested in understanding the server architecture:
|
||||
* [Server Architecture Diagram](docs/server-architecture-diagram.md) - Comprehensive visual diagrams of server components and communication flows
|
||||
* [Server Architecture ASCII](docs/server-architecture-ascii.md) - Text-based architecture diagrams
|
||||
* [Implementation Notes](docs/implementation-notes.md) - Technical implementation details and code organization
|
||||
|
||||
## License
|
||||
Darkflame Universe is licensed under AGPLv3, please read [LICENSE](LICENSE). Some important points:
|
||||
* We are not liable for anything you do with the code
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
//Auth includes:
|
||||
#include "AuthPackets.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "MessageType/Server.h"
|
||||
#include "MessageType/Auth.h"
|
||||
|
||||
@@ -92,7 +92,7 @@ int main(int argc, char** argv) {
|
||||
const auto externalIPString = Game::config->GetValue("external_ip");
|
||||
if (!externalIPString.empty()) ourIP = externalIPString;
|
||||
|
||||
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config, &Game::lastSignal, masterPassword);
|
||||
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServiceType::AUTH, Game::config, &Game::lastSignal, masterPassword);
|
||||
|
||||
//Run it until server gets a kill message from Master:
|
||||
auto t = std::chrono::high_resolution_clock::now();
|
||||
@@ -167,11 +167,11 @@ void HandlePacket(Packet* packet) {
|
||||
if (packet->length < 4) return;
|
||||
|
||||
if (packet->data[0] == ID_USER_PACKET_ENUM) {
|
||||
if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::SERVER) {
|
||||
if (static_cast<ServiceType>(packet->data[1]) == ServiceType::COMMON) {
|
||||
if (static_cast<MessageType::Server>(packet->data[3]) == MessageType::Server::VERSION_CONFIRM) {
|
||||
AuthPackets::HandleHandshake(Game::server, packet);
|
||||
}
|
||||
} else if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::AUTH) {
|
||||
} else if (static_cast<ServiceType>(packet->data[1]) == ServiceType::AUTH) {
|
||||
if (static_cast<MessageType::Auth>(packet->data[3]) == MessageType::Auth::LOGIN_REQUEST) {
|
||||
AuthPackets::HandleLoginRequest(Game::server, packet);
|
||||
}
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
// The only thing not auto-handled is instance activities force joining the team on the server.
|
||||
|
||||
void WriteOutgoingReplyHeader(RakNet::BitStream& bitStream, const LWOOBJID& receivingPlayer, const MessageType::Client type) {
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receivingPlayer);
|
||||
|
||||
//portion that will get routed:
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, type);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, type);
|
||||
}
|
||||
|
||||
void ChatIgnoreList::GetIgnoreList(Packet* packet) {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "RakString.h"
|
||||
#include "dConfig.h"
|
||||
#include "eObjectBits.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "MessageType/Chat.h"
|
||||
#include "MessageType/Client.h"
|
||||
#include "MessageType/Game.h"
|
||||
@@ -61,11 +61,11 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
|
||||
|
||||
//Now, we need to send the friendlist to the server they came from:
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::GET_FRIENDS_LIST_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::GET_FRIENDS_LIST_RESPONSE);
|
||||
bitStream.Write<uint8_t>(0);
|
||||
bitStream.Write<uint16_t>(1); //Length of packet -- just writing one as it doesn't matter, client skips it.
|
||||
bitStream.Write<uint16_t>(player.friends.size());
|
||||
@@ -375,10 +375,10 @@ void ChatPacketHandler::HandleWho(Packet* packet) {
|
||||
bool online = player;
|
||||
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(request.requestor);
|
||||
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::WHO_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::WHO_RESPONSE);
|
||||
bitStream.Write<uint8_t>(online);
|
||||
bitStream.Write(player.zoneID.GetMapID());
|
||||
bitStream.Write(player.zoneID.GetInstanceID());
|
||||
@@ -398,10 +398,10 @@ void ChatPacketHandler::HandleShowAll(Packet* packet) {
|
||||
if (!sender) return;
|
||||
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(request.requestor);
|
||||
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::SHOW_ALL_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::SHOW_ALL_RESPONSE);
|
||||
bitStream.Write<uint8_t>(!request.displayZoneData && !request.displayIndividualPlayers);
|
||||
bitStream.Write(Game::playerContainer.GetPlayerCount());
|
||||
bitStream.Write(Game::playerContainer.GetSimCount());
|
||||
@@ -533,7 +533,7 @@ void ChatPacketHandler::OnAchievementNotify(RakNet::BitStream& bitstream, const
|
||||
LOG_DEBUG("Sending achievement notify to %s", notify.targetPlayerName.GetAsString().c_str());
|
||||
|
||||
RakNet::BitStream worldStream;
|
||||
BitStreamUtils::WriteHeader(worldStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(worldStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
worldStream.Write(friendData.playerID);
|
||||
notify.WriteHeader(worldStream);
|
||||
notify.Serialize(worldStream);
|
||||
@@ -544,10 +544,10 @@ void ChatPacketHandler::OnAchievementNotify(RakNet::BitStream& bitstream, const
|
||||
|
||||
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, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(routeTo.playerID);
|
||||
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::PRIVATE_CHAT_MESSAGE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::PRIVATE_CHAT_MESSAGE);
|
||||
bitStream.Write(sender.playerID);
|
||||
bitStream.Write(channel);
|
||||
bitStream.Write<uint32_t>(0); // not used
|
||||
@@ -579,11 +579,11 @@ void ChatPacketHandler::SendFriendUpdate(const PlayerData& friendData, const Pla
|
||||
[bool] - is FTP*/
|
||||
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(friendData.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::UPDATE_FRIEND_NOTIFY);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::UPDATE_FRIEND_NOTIFY);
|
||||
bitStream.Write<uint8_t>(notifyType);
|
||||
|
||||
std::string playerName = playerData.playerName.c_str();
|
||||
@@ -616,11 +616,11 @@ void ChatPacketHandler::SendFriendRequest(const PlayerData& receiver, const Play
|
||||
}
|
||||
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::ADD_FRIEND_REQUEST);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::ADD_FRIEND_REQUEST);
|
||||
bitStream.Write(LUWString(sender.playerName));
|
||||
bitStream.Write<uint8_t>(0); // This is a BFF flag however this is unused in live and does not have an implementation client side.
|
||||
|
||||
@@ -630,11 +630,11 @@ void ChatPacketHandler::SendFriendRequest(const PlayerData& receiver, const Play
|
||||
|
||||
void ChatPacketHandler::SendFriendResponse(const PlayerData& receiver, const PlayerData& sender, eAddFriendResponseType responseCode, uint8_t isBestFriendsAlready, uint8_t isBestFriendRequest) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
// Portion that will get routed:
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::ADD_FRIEND_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::ADD_FRIEND_RESPONSE);
|
||||
bitStream.Write(responseCode);
|
||||
// For all requests besides accepted, write a flag that says whether or not we are already best friends with the receiver.
|
||||
bitStream.Write<uint8_t>(responseCode != eAddFriendResponseType::ACCEPTED ? isBestFriendsAlready : sender.worldServerSysAddr != UNASSIGNED_SYSTEM_ADDRESS);
|
||||
@@ -653,11 +653,11 @@ void ChatPacketHandler::SendFriendResponse(const PlayerData& receiver, const Pla
|
||||
|
||||
void ChatPacketHandler::SendRemoveFriend(const PlayerData& receiver, std::string& personToRemove, bool isSuccessful) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::REMOVE_FRIEND_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::REMOVE_FRIEND_RESPONSE);
|
||||
bitStream.Write<uint8_t>(isSuccessful); //isOnline
|
||||
bitStream.Write(LUWString(personToRemove));
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "Diagnostics.h"
|
||||
#include "AssetManager.h"
|
||||
#include "BinaryPathFinder.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "PlayerContainer.h"
|
||||
#include "ChatPacketHandler.h"
|
||||
#include "MessageType/Chat.h"
|
||||
@@ -123,7 +123,7 @@ int main(int argc, char** argv) {
|
||||
const auto externalIPString = Game::config->GetValue("external_ip");
|
||||
if (!externalIPString.empty()) ourIP = externalIPString;
|
||||
|
||||
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::lastSignal, masterPassword);
|
||||
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServiceType::CHAT, Game::config, &Game::lastSignal, masterPassword);
|
||||
|
||||
const bool dontGenerateDCF = GeneralUtils::TryParse<bool>(Game::config->GetValue("dont_generate_dcf")).value_or(false);
|
||||
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", dontGenerateDCF);
|
||||
@@ -218,11 +218,11 @@ void HandlePacket(Packet* packet) {
|
||||
CINSTREAM;
|
||||
inStream.SetReadOffset(BYTES_TO_BITS(1));
|
||||
|
||||
eConnectionType connection;
|
||||
MessageType::Chat chatMessageID;
|
||||
|
||||
ServiceType connection;
|
||||
inStream.Read(connection);
|
||||
if (connection != eConnectionType::CHAT) return;
|
||||
if (connection != ServiceType::CHAT) return;
|
||||
|
||||
MessageType::Chat chatMessageID;
|
||||
inStream.Read(chatMessageID);
|
||||
|
||||
// Our packing byte wasnt there? Probably a false packet
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "GeneralUtils.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "Database.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "ChatPackets.h"
|
||||
#include "dConfig.h"
|
||||
#include "MessageType/Chat.h"
|
||||
@@ -147,7 +147,7 @@ void PlayerContainer::MuteUpdate(Packet* packet) {
|
||||
|
||||
void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::GM_MUTE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::GM_MUTE);
|
||||
|
||||
bitStream.Write(player);
|
||||
bitStream.Write(time);
|
||||
|
||||
@@ -264,11 +264,11 @@ void TeamContainer::HandleTeamStatusRequest(Packet* packet) {
|
||||
|
||||
void TeamContainer::SendTeamInvite(const PlayerData& receiver, const PlayerData& sender) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::TEAM_INVITE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::TEAM_INVITE);
|
||||
|
||||
bitStream.Write(LUWString(sender.playerName.c_str()));
|
||||
bitStream.Write(sender.playerID);
|
||||
@@ -279,7 +279,7 @@ void TeamContainer::SendTeamInvite(const PlayerData& receiver, const PlayerData&
|
||||
|
||||
void TeamContainer::SendTeamInviteConfirm(const PlayerData& receiver, bool bLeaderIsFreeTrial, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, uint8_t ucResponseCode, std::u16string wsLeaderName) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
@@ -306,7 +306,7 @@ void TeamContainer::SendTeamInviteConfirm(const PlayerData& receiver, bool bLead
|
||||
|
||||
void TeamContainer::SendTeamStatus(const PlayerData& receiver, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, std::u16string wsLeaderName) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
@@ -331,7 +331,7 @@ void TeamContainer::SendTeamStatus(const PlayerData& receiver, LWOOBJID i64Leade
|
||||
|
||||
void TeamContainer::SendTeamSetLeader(const PlayerData& receiver, LWOOBJID i64PlayerID) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
@@ -348,7 +348,7 @@ void TeamContainer::SendTeamSetLeader(const PlayerData& receiver, LWOOBJID i64Pl
|
||||
|
||||
void TeamContainer::SendTeamAddPlayer(const PlayerData& receiver, bool bIsFreeTrial, bool bLocal, bool bNoLootOnDeath, LWOOBJID i64PlayerID, std::u16string wsPlayerName, LWOZONEID zoneID) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
@@ -377,7 +377,7 @@ void TeamContainer::SendTeamAddPlayer(const PlayerData& receiver, bool bIsFreeTr
|
||||
|
||||
void TeamContainer::SendTeamRemovePlayer(const PlayerData& receiver, bool bDisband, bool bIsKicked, bool bIsLeaving, bool bLocal, LWOOBJID i64LeaderID, LWOOBJID i64PlayerID, std::u16string wsPlayerName) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
@@ -403,7 +403,7 @@ void TeamContainer::SendTeamRemovePlayer(const PlayerData& receiver, bool bDisba
|
||||
|
||||
void TeamContainer::SendTeamSetOffWorldFlag(const PlayerData& receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
@@ -652,7 +652,7 @@ void TeamContainer::TeamStatusUpdate(TeamData* team) {
|
||||
|
||||
void TeamContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::TEAM_GET_STATUS);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::TEAM_GET_STATUS);
|
||||
|
||||
bitStream.Write(team->teamID);
|
||||
bitStream.Write(deleteTeam);
|
||||
|
||||
14
dCommon/dEnums/ServiceType.h
Normal file
14
dCommon/dEnums/ServiceType.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef __SERVICETYPE__H__
|
||||
#define __SERVICETYPE__H__
|
||||
|
||||
enum class ServiceType : uint16_t {
|
||||
COMMON = 0,
|
||||
AUTH,
|
||||
CHAT,
|
||||
WORLD = 4,
|
||||
CLIENT,
|
||||
MASTER,
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
#endif //!__SERVICETYPE__H__
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "BitStream.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "MessageType/Client.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
|
||||
#pragma warning (disable:4251) //Disables SQL warnings
|
||||
|
||||
@@ -34,7 +34,7 @@ constexpr uint32_t lowFrameDelta = FRAMES_TO_MS(lowFramerate);
|
||||
#define CBITSTREAM RakNet::BitStream bitStream;
|
||||
#define CINSTREAM RakNet::BitStream inStream(packet->data, packet->length, false);
|
||||
#define CINSTREAM_SKIP_HEADER CINSTREAM if (inStream.GetNumberOfUnreadBits() >= BYTES_TO_BITS(HEADER_SIZE)) inStream.IgnoreBytes(HEADER_SIZE); else inStream.IgnoreBits(inStream.GetNumberOfUnreadBits());
|
||||
#define CMSGHEADER BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
#define CMSGHEADER BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
#define SEND_PACKET Game::server->Send(bitStream, sysAddr, false);
|
||||
#define SEND_PACKET_BROADCAST Game::server->Send(bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#ifndef __ECONNECTIONTYPE__H__
|
||||
#define __ECONNECTIONTYPE__H__
|
||||
|
||||
enum class eConnectionType : uint16_t {
|
||||
SERVER = 0,
|
||||
AUTH,
|
||||
CHAT,
|
||||
WORLD = 4,
|
||||
CLIENT,
|
||||
MASTER,
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
#endif //!__ECONNECTIONTYPE__H__
|
||||
@@ -902,7 +902,7 @@ void Entity::SetGMLevel(eGameMasterLevel value) {
|
||||
// Update the chat server of our GM Level
|
||||
{
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::GMLEVEL_UPDATE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::GMLEVEL_UPDATE);
|
||||
bitStream.Write(m_ObjectID);
|
||||
bitStream.Write(m_GMLevel);
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "eGameMasterLevel.h"
|
||||
#include "eCharacterCreationResponse.h"
|
||||
#include "eRenameResponse.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "MessageType/Chat.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "CheatDetection.h"
|
||||
@@ -217,7 +217,7 @@ void UserManager::RequestCharacterList(const SystemAddress& sysAddr) {
|
||||
}
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::CHARACTER_LIST_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::CHARACTER_LIST_RESPONSE);
|
||||
|
||||
std::vector<Character*> characters = u->GetCharacters();
|
||||
bitStream.Write<uint8_t>(characters.size());
|
||||
@@ -427,7 +427,7 @@ void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet)
|
||||
Database::Get()->DeleteCharacter(charID);
|
||||
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::UNEXPECTED_DISCONNECT);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::UNEXPECTED_DISCONNECT);
|
||||
bitStream.Write(objectID);
|
||||
Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false);
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "QuickBuildComponent.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "TeamManager.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
|
||||
BehaviorSyncEntry::BehaviorSyncEntry() {
|
||||
}
|
||||
@@ -212,7 +212,7 @@ void BehaviorContext::UpdatePlayerSyncs(float deltaTime) {
|
||||
echo.sBitStream.assign(reinterpret_cast<char*>(bitStream.GetData()), bitStream.GetNumberOfBytesUsed());
|
||||
|
||||
RakNet::BitStream message;
|
||||
BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
BitStreamUtils::WriteHeader(message, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
message.Write(this->originator);
|
||||
echo.Serialize(message);
|
||||
|
||||
@@ -285,7 +285,7 @@ bool BehaviorContext::CalculateUpdate(const float deltaTime) {
|
||||
// Write message
|
||||
RakNet::BitStream message;
|
||||
|
||||
BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
BitStreamUtils::WriteHeader(message, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
message.Write(this->originator);
|
||||
echo.Serialize(message);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "Loot.h"
|
||||
#include "eMissionTaskType.h"
|
||||
#include "eMatchUpdate.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "MessageType/Chat.h"
|
||||
|
||||
#include "CDCurrencyTableTable.h"
|
||||
@@ -512,7 +512,7 @@ void ActivityInstance::StartZone() {
|
||||
// only make a team if we have more than one participant
|
||||
if (participants.size() > 1) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::CREATE_TEAM);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::CREATE_TEAM);
|
||||
|
||||
bitStream.Write(leader->GetObjectID());
|
||||
bitStream.Write(m_Participants.size());
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "dServer.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "eObjectWorldState.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "MessageType/Master.h"
|
||||
|
||||
RocketLaunchpadControlComponent::RocketLaunchpadControlComponent(Entity* parent, int rocketId) : Component(parent) {
|
||||
@@ -137,7 +137,7 @@ LWOCLONEID RocketLaunchpadControlComponent::GetSelectedCloneId(LWOOBJID player)
|
||||
|
||||
void RocketLaunchpadControlComponent::TellMasterToPrepZone(int zoneID) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::PREP_ZONE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::PREP_ZONE);
|
||||
bitStream.Write(zoneID);
|
||||
Game::server->SendToMaster(bitStream);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "DoClientProjectileImpact.h"
|
||||
#include "CDClientManager.h"
|
||||
#include "CDSkillBehaviorTable.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "MessageType/Client.h"
|
||||
|
||||
ProjectileSyncEntry::ProjectileSyncEntry() {
|
||||
@@ -326,7 +326,7 @@ SkillExecutionResult SkillComponent::CalculateBehavior(
|
||||
// Write message
|
||||
RakNet::BitStream message;
|
||||
|
||||
BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
BitStreamUtils::WriteHeader(message, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
message.Write(this->m_Parent->GetObjectID());
|
||||
start.Serialize(message);
|
||||
|
||||
@@ -457,7 +457,7 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry)
|
||||
|
||||
RakNet::BitStream message;
|
||||
|
||||
BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
BitStreamUtils::WriteHeader(message, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
message.Write(this->m_Parent->GetObjectID());
|
||||
projectileImpact.Serialize(message);
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "EchoSyncSkill.h"
|
||||
#include "eMissionTaskType.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "MessageType/Game.h"
|
||||
#include "ePlayerFlag.h"
|
||||
#include "dConfig.h"
|
||||
@@ -353,7 +353,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const System
|
||||
if (success) {
|
||||
//Broadcast our startSkill:
|
||||
RakNet::BitStream bitStreamLocal;
|
||||
BitStreamUtils::WriteHeader(bitStreamLocal, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
BitStreamUtils::WriteHeader(bitStreamLocal, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
bitStreamLocal.Write(entity->GetObjectID());
|
||||
|
||||
EchoStartSkill echoStartSkill;
|
||||
@@ -375,7 +375,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const System
|
||||
|
||||
case MessageType::Game::SYNC_SKILL: {
|
||||
RakNet::BitStream bitStreamLocal;
|
||||
BitStreamUtils::WriteHeader(bitStreamLocal, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
BitStreamUtils::WriteHeader(bitStreamLocal, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
bitStreamLocal.Write(entity->GetObjectID());
|
||||
|
||||
SyncSkill sync = SyncSkill(inStream); // inStream replaced &bitStream
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include "eQuickBuildFailReason.h"
|
||||
#include "eControlScheme.h"
|
||||
#include "eStateChangeType.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "ePlayerFlag.h"
|
||||
|
||||
#include <sstream>
|
||||
@@ -2208,7 +2208,7 @@ void GameMessages::HandleUnUseModel(RakNet::BitStream& inStream, Entity* entity,
|
||||
|
||||
if (unknown) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::BLUEPRINT_SAVE_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::BLUEPRINT_SAVE_RESPONSE);
|
||||
bitStream.Write<LWOOBJID>(LWOOBJID_EMPTY); //always zero so that a check on the client passes
|
||||
bitStream.Write(eBlueprintSaveResponseType::PlacementFailed); // Sending a non-zero error code here prevents the client from deleting its in progress build for some reason?
|
||||
bitStream.Write<uint32_t>(0);
|
||||
@@ -2460,7 +2460,7 @@ void GameMessages::HandleBBBLoadItemRequest(RakNet::BitStream& inStream, Entity*
|
||||
|
||||
void GameMessages::SendBlueprintLoadItemResponse(const SystemAddress& sysAddr, bool success, LWOOBJID oldItemId, LWOOBJID newItemId) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::BLUEPRINT_LOAD_RESPONSE_ITEMID);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::BLUEPRINT_LOAD_RESPONSE_ITEMID);
|
||||
bitStream.Write<uint8_t>(success);
|
||||
bitStream.Write<LWOOBJID>(oldItemId);
|
||||
bitStream.Write<LWOOBJID>(newItemId);
|
||||
@@ -2652,7 +2652,7 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream& inStream, Entity* ent
|
||||
uint32_t sd0Size{};
|
||||
for (const auto& chunk : newSd0) sd0Size += chunk.size();
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::BLUEPRINT_SAVE_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::BLUEPRINT_SAVE_RESPONSE);
|
||||
bitStream.Write(localId);
|
||||
bitStream.Write(eBlueprintSaveResponseType::EverythingWorked);
|
||||
bitStream.Write<uint32_t>(1);
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "WorldConfig.h"
|
||||
#include "eMissionTaskType.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "User.h"
|
||||
#include "StringifiedEnum.h"
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace Mail {
|
||||
Entity* player = nullptr;
|
||||
|
||||
MailLUBitStream() = default;
|
||||
MailLUBitStream(eMessageID _messageID) : LUBitStream(eConnectionType::CLIENT, MessageType::Client::MAIL), messageID{_messageID} {};
|
||||
MailLUBitStream(eMessageID _messageID) : LUBitStream(ServiceType::CLIENT, MessageType::Client::MAIL), messageID{_messageID} {};
|
||||
|
||||
virtual void Serialize(RakNet::BitStream& bitStream) const override;
|
||||
virtual bool Deserialize(RakNet::BitStream& bitStream) override;
|
||||
|
||||
@@ -153,7 +153,7 @@ void SlashCommandHandler::SendAnnouncement(const std::string& title, const std::
|
||||
|
||||
//Notify chat about it
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::GM_ANNOUNCE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::GM_ANNOUNCE);
|
||||
|
||||
bitStream.Write<uint32_t>(title.size());
|
||||
for (auto character : title) {
|
||||
|
||||
@@ -507,7 +507,7 @@ namespace DEVGMCommands {
|
||||
void ShutdownUniverse(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
|
||||
//Tell the master server that we're going to be shutting down whole "universe":
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::SHUTDOWN_UNIVERSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::SHUTDOWN_UNIVERSE);
|
||||
Game::server->SendToMaster(bitStream);
|
||||
ChatPackets::SendSystemMessage(sysAddr, u"Sent universe shutdown notification to master.");
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ namespace GMGreaterThanZeroCommands {
|
||||
|
||||
//Notify chat about it
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::GM_MUTE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::GM_MUTE);
|
||||
|
||||
bitStream.Write(characterId);
|
||||
bitStream.Write(expire);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "CDZoneTableTable.h"
|
||||
#include "MasterPackets.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "MessageType/Master.h"
|
||||
|
||||
#include "Start.h"
|
||||
@@ -172,7 +172,7 @@ void InstanceManager::RequestAffirmation(const InstancePtr& instance, const Pend
|
||||
|
||||
CBITSTREAM;
|
||||
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::AFFIRM_TRANSFER_REQUEST);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::AFFIRM_TRANSFER_REQUEST);
|
||||
|
||||
bitStream.Write(request.id);
|
||||
|
||||
@@ -343,7 +343,7 @@ bool Instance::GetShutdownComplete() const {
|
||||
void Instance::Shutdown() {
|
||||
CBITSTREAM;
|
||||
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::SHUTDOWN);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::SHUTDOWN);
|
||||
|
||||
Game::server->Send(bitStream, this->m_SysAddr, false);
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "dServer.h"
|
||||
#include "AssetManager.h"
|
||||
#include "BinaryPathFinder.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "MessageType/Master.h"
|
||||
|
||||
//RakNet includes:
|
||||
@@ -343,7 +343,7 @@ int main(int argc, char** argv) {
|
||||
int res = GenerateBCryptPassword(!cfgPassword.empty() ? cfgPassword : "3.25DARKFLAME1", 13, salt, hash);
|
||||
assert(res == 0);
|
||||
|
||||
Game::server = new dServer(ourIP, ourPort, 0, maxClients, true, false, Game::logger, "", 0, ServerType::Master, Game::config, &Game::lastSignal, hash);
|
||||
Game::server = new dServer(ourIP, ourPort, 0, maxClients, true, false, Game::logger, "", 0, ServiceType::MASTER, Game::config, &Game::lastSignal, hash);
|
||||
|
||||
std::string master_server_ip = "localhost";
|
||||
const auto masterServerIPString = Game::config->GetValue("master_ip");
|
||||
@@ -530,7 +530,7 @@ void HandlePacket(Packet* packet) {
|
||||
|
||||
if (packet->length < 4) return;
|
||||
|
||||
if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::MASTER) {
|
||||
if (static_cast<ServiceType>(packet->data[1]) == ServiceType::MASTER) {
|
||||
switch (static_cast<MessageType::Master>(packet->data[3])) {
|
||||
case MessageType::Master::REQUEST_PERSISTENT_ID: {
|
||||
LOG("A persistent ID req");
|
||||
@@ -592,7 +592,7 @@ void HandlePacket(Packet* packet) {
|
||||
uint32_t theirPort = 0;
|
||||
uint32_t theirZoneID = 0;
|
||||
uint32_t theirInstanceID = 0;
|
||||
ServerType theirServerType;
|
||||
ServiceType theirServerType;
|
||||
LUString theirIP;
|
||||
|
||||
inStream.Read(theirPort);
|
||||
@@ -601,10 +601,10 @@ void HandlePacket(Packet* packet) {
|
||||
inStream.Read(theirServerType);
|
||||
inStream.Read(theirIP);
|
||||
|
||||
if (theirServerType == ServerType::World) {
|
||||
switch (theirServerType) {
|
||||
case ServiceType::WORLD:
|
||||
if (!Game::im->IsPortInUse(theirPort)) {
|
||||
auto in = std::make_unique<Instance>(theirIP.string, theirPort, theirZoneID, theirInstanceID, 0, 12, 12);
|
||||
|
||||
in->SetSysAddr(packet->systemAddress);
|
||||
Game::im->AddInstance(in);
|
||||
} else {
|
||||
@@ -613,14 +613,16 @@ void HandlePacket(Packet* packet) {
|
||||
instance->SetSysAddr(packet->systemAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (theirServerType == ServerType::Chat) {
|
||||
break;
|
||||
case ServiceType::CHAT:
|
||||
chatServerMasterPeerSysAddr = packet->systemAddress;
|
||||
}
|
||||
|
||||
if (theirServerType == ServerType::Auth) {
|
||||
authServerMasterPeerSysAddr = packet->systemAddress;
|
||||
break;
|
||||
case ServiceType::AUTH:
|
||||
authServerMasterPeerSysAddr = packet->systemAddress;
|
||||
break;
|
||||
default:
|
||||
// We just ignore any other server type
|
||||
break;
|
||||
}
|
||||
|
||||
LOG("Received %s server info, instance: %i port: %i", StringifiedEnum::ToString(theirServerType).data(), theirInstanceID, theirPort);
|
||||
@@ -640,7 +642,7 @@ void HandlePacket(Packet* packet) {
|
||||
activeSessions.erase(it.first);
|
||||
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::NEW_SESSION_ALERT);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::NEW_SESSION_ALERT);
|
||||
bitStream.Write(sessionKey);
|
||||
bitStream.Write(username);
|
||||
SEND_PACKET_BROADCAST;
|
||||
@@ -662,7 +664,7 @@ void HandlePacket(Packet* packet) {
|
||||
for (auto key : activeSessions) {
|
||||
if (key.second == username.GetAsString()) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::SESSION_KEY_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::SESSION_KEY_RESPONSE);
|
||||
bitStream.Write(key.first);
|
||||
bitStream.Write(username);
|
||||
Game::server->Send(bitStream, packet->systemAddress, false);
|
||||
@@ -873,7 +875,7 @@ int ShutdownSequence(int32_t signal) {
|
||||
|
||||
{
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::SHUTDOWN);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::SHUTDOWN);
|
||||
Game::server->Send(bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||
LOG("Triggered master shutdown");
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "dConfig.h"
|
||||
#include "eServerDisconnectIdentifiers.h"
|
||||
#include "eLoginResponse.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "MessageType/Server.h"
|
||||
#include "MessageType/Master.h"
|
||||
#include "eGameMasterLevel.h"
|
||||
@@ -51,9 +51,10 @@ void AuthPackets::HandleHandshake(dServer* server, Packet* packet) {
|
||||
inStream.Read(clientVersion);
|
||||
inStream.IgnoreBytes(4);
|
||||
|
||||
ServiceId serviceId;
|
||||
inStream.Read(serviceId);
|
||||
if (serviceId != ServiceId::Client) LOG("WARNING: Service ID is not a Client!");
|
||||
ServiceType serviceType;
|
||||
inStream.Read(serviceType);
|
||||
if (serviceType != ServiceType::CLIENT) LOG("WARNING: Service is not a Client!");
|
||||
inStream.IgnoreBytes(2);
|
||||
|
||||
uint32_t processID;
|
||||
inStream.Read(processID);
|
||||
@@ -64,24 +65,21 @@ void AuthPackets::HandleHandshake(dServer* server, Packet* packet) {
|
||||
|
||||
inStream.IgnoreBytes(33);
|
||||
|
||||
LOG_DEBUG("Client Data [Version: %i, Service: %s, Process: %u, Port: %u, Sysaddr Port: %u]", clientVersion, StringifiedEnum::ToString(serviceId).data(), processID, port, packet->systemAddress.port);
|
||||
LOG_DEBUG("Client Data [Version: %i, Service: %s, Process: %u, Port: %u, Sysaddr Port: %u]", clientVersion, StringifiedEnum::ToString(serviceType).data(), processID, port, packet->systemAddress.port);
|
||||
|
||||
SendHandshake(server, packet->systemAddress, server->GetIP(), server->GetPort(), server->GetServerType());
|
||||
}
|
||||
|
||||
void AuthPackets::SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort, const ServerType serverType) {
|
||||
void AuthPackets::SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort, const ServiceType serverType) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::SERVER, MessageType::Server::VERSION_CONFIRM);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::COMMON, MessageType::Server::VERSION_CONFIRM);
|
||||
|
||||
const auto clientNetVersionString = Game::config->GetValue("client_net_version");
|
||||
const auto& clientNetVersionString = Game::config->GetValue("client_net_version");
|
||||
const uint32_t clientNetVersion = GeneralUtils::TryParse<uint32_t>(clientNetVersionString).value_or(171022);
|
||||
|
||||
bitStream.Write<uint32_t>(clientNetVersion);
|
||||
bitStream.Write<uint32_t>(861228100);
|
||||
|
||||
if (serverType == ServerType::Auth) bitStream.Write(ServiceId::Auth);
|
||||
else if (serverType == ServerType::World) bitStream.Write(ServiceId::World);
|
||||
else bitStream.Write(ServiceId::General);
|
||||
bitStream.Write(static_cast<uint32_t>(serverType));
|
||||
bitStream.Write<uint64_t>(219818307120);
|
||||
|
||||
server->Send(bitStream, sysAddr, false);
|
||||
@@ -234,7 +232,7 @@ void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) {
|
||||
void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAddr, eLoginResponse responseCode, const std::string& errorMsg, const std::string& wServerIP, uint16_t wServerPort, std::string username, std::vector<Stamp>& stamps) {
|
||||
stamps.emplace_back(eStamps::PASSPORT_AUTH_IM_LOGIN_START, 1);
|
||||
RakNet::BitStream loginResponse;
|
||||
BitStreamUtils::WriteHeader(loginResponse, eConnectionType::CLIENT, MessageType::Client::LOGIN_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(loginResponse, ServiceType::CLIENT, MessageType::Client::LOGIN_RESPONSE);
|
||||
|
||||
loginResponse.Write(responseCode);
|
||||
|
||||
@@ -304,7 +302,7 @@ void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAdd
|
||||
//Inform the master server that we've created a session for this user:
|
||||
if (responseCode == eLoginResponse::SUCCESS) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::SET_SESSION_KEY);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::SET_SESSION_KEY);
|
||||
bitStream.Write(sessionKey);
|
||||
bitStream.Write(LUString(username));
|
||||
server->SendToMaster(bitStream);
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#include "dNetCommon.h"
|
||||
#include "magic_enum.hpp"
|
||||
|
||||
enum class ServerType : uint32_t;
|
||||
enum class eLoginResponse : uint8_t;
|
||||
enum class ServiceType : uint16_t;
|
||||
class dServer;
|
||||
|
||||
enum class eStamps : uint32_t {
|
||||
@@ -93,7 +93,7 @@ enum class Language : uint32_t {
|
||||
|
||||
namespace AuthPackets {
|
||||
void HandleHandshake(dServer* server, Packet* packet);
|
||||
void SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort, const ServerType serverType);
|
||||
void SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort, const ServiceType serverType);
|
||||
|
||||
void HandleLoginRequest(dServer* server, Packet* packet);
|
||||
void SendLoginResponse(dServer* server, const SystemAddress& sysAddr, eLoginResponse responseCode, const std::string& errorMsg, const std::string& wServerIP, uint16_t wServerPort, std::string username, std::vector<Stamp>& stamps);
|
||||
|
||||
@@ -17,8 +17,7 @@ bool LUBitStream::ReadHeader(RakNet::BitStream& bitStream) {
|
||||
if (messageID != ID_USER_PACKET_ENUM) return false;
|
||||
VALIDATE_READ(bitStream.Read(this->connectionType));
|
||||
VALIDATE_READ(bitStream.Read(this->internalPacketID));
|
||||
uint8_t padding;
|
||||
VALIDATE_READ(bitStream.Read<uint8_t>(padding));
|
||||
bitStream.IgnoreBytes(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "GeneralUtils.h"
|
||||
#include "BitStream.h"
|
||||
#include "MessageIdentifiers.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -47,13 +47,13 @@ struct LUWString {
|
||||
};
|
||||
|
||||
struct LUBitStream {
|
||||
eConnectionType connectionType = eConnectionType::UNKNOWN;
|
||||
ServiceType connectionType = ServiceType::UNKNOWN;
|
||||
uint32_t internalPacketID = 0xFFFFFFFF;
|
||||
|
||||
LUBitStream() = default;
|
||||
|
||||
template <typename T>
|
||||
LUBitStream(eConnectionType connectionType, T internalPacketID) {
|
||||
LUBitStream(ServiceType connectionType, T internalPacketID) {
|
||||
this->connectionType = connectionType;
|
||||
this->internalPacketID = static_cast<uint32_t>(internalPacketID);
|
||||
}
|
||||
@@ -71,9 +71,9 @@ struct LUBitStream {
|
||||
|
||||
namespace BitStreamUtils {
|
||||
template<typename T>
|
||||
void WriteHeader(RakNet::BitStream& bitStream, eConnectionType connectionType, T internalPacketID) {
|
||||
void WriteHeader(RakNet::BitStream& bitStream, ServiceType connectionType, T internalPacketID) {
|
||||
bitStream.Write<MessageID>(ID_USER_PACKET_ENUM);
|
||||
bitStream.Write<eConnectionType>(connectionType);
|
||||
bitStream.Write<ServiceType>(connectionType);
|
||||
bitStream.Write(static_cast<uint32_t>(internalPacketID));
|
||||
bitStream.Write<uint8_t>(0);
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
#include "Game.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "dServer.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "MessageType/Chat.h"
|
||||
|
||||
void ShowAllRequest::Serialize(RakNet::BitStream& bitStream) {
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::SHOW_ALL);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::SHOW_ALL);
|
||||
bitStream.Write(this->requestor);
|
||||
bitStream.Write(this->displayZoneData);
|
||||
bitStream.Write(this->displayIndividualPlayers);
|
||||
@@ -26,7 +26,7 @@ void ShowAllRequest::Deserialize(RakNet::BitStream& inStream) {
|
||||
}
|
||||
|
||||
void FindPlayerRequest::Serialize(RakNet::BitStream& bitStream) {
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WHO);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WHO);
|
||||
bitStream.Write(this->requestor);
|
||||
bitStream.Write(this->playerName);
|
||||
}
|
||||
@@ -38,7 +38,7 @@ void FindPlayerRequest::Deserialize(RakNet::BitStream& inStream) {
|
||||
|
||||
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, MessageType::Chat::GENERAL_CHAT_MESSAGE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::GENERAL_CHAT_MESSAGE);
|
||||
|
||||
bitStream.Write<uint64_t>(0);
|
||||
bitStream.Write(chatChannel);
|
||||
@@ -60,7 +60,7 @@ void ChatPackets::SendChatMessage(const SystemAddress& sysAddr, char chatChannel
|
||||
|
||||
void ChatPackets::SendSystemMessage(const SystemAddress& sysAddr, const std::u16string& message, const bool broadcast) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::GENERAL_CHAT_MESSAGE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::GENERAL_CHAT_MESSAGE);
|
||||
|
||||
bitStream.Write<uint64_t>(0);
|
||||
bitStream.Write<char>(4);
|
||||
@@ -92,7 +92,7 @@ void ChatPackets::SendMessageFail(const SystemAddress& sysAddr) {
|
||||
//0x01 - "Upgrade to a full LEGO Universe Membership to chat with other players."
|
||||
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::SEND_CANNED_TEXT);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::SEND_CANNED_TEXT);
|
||||
bitStream.Write<uint8_t>(0); //response type, options above ^
|
||||
//docs say there's a wstring here-- no idea what it's for, or if it's even needed so leaving it as is for now.
|
||||
SEND_PACKET;
|
||||
@@ -139,7 +139,7 @@ void ChatPackets::TeamInviteInitialResponse::Serialize(RakNet::BitStream& bitstr
|
||||
|
||||
void ChatPackets::SendRoutedMsg(const LUBitStream& msg, const LWOOBJID targetID, const SystemAddress& sysAddr) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(targetID);
|
||||
|
||||
// Now write the actual packet
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace ChatPackets {
|
||||
std::string title;
|
||||
std::string message;
|
||||
|
||||
Announcement() : LUBitStream(eConnectionType::CHAT, MessageType::Chat::GM_ANNOUNCE) {};
|
||||
Announcement() : LUBitStream(ServiceType::CHAT, MessageType::Chat::GM_ANNOUNCE) {};
|
||||
virtual void Serialize(RakNet::BitStream& bitStream) const override;
|
||||
};
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace ChatPackets {
|
||||
uint32_t missionEmailID{};
|
||||
LWOOBJID earningPlayerID{};
|
||||
LUWString earnerName{};
|
||||
AchievementNotify() : LUBitStream(eConnectionType::CHAT, MessageType::Chat::ACHIEVEMENT_NOTIFY) {}
|
||||
AchievementNotify() : LUBitStream(ServiceType::CHAT, MessageType::Chat::ACHIEVEMENT_NOTIFY) {}
|
||||
void Serialize(RakNet::BitStream& bitstream) const override;
|
||||
bool Deserialize(RakNet::BitStream& bitstream) override;
|
||||
};
|
||||
@@ -51,7 +51,7 @@ namespace ChatPackets {
|
||||
struct TeamInviteInitialResponse : public LUBitStream {
|
||||
bool inviteFailedToSend{};
|
||||
LUWString playerName{};
|
||||
TeamInviteInitialResponse() : LUBitStream(eConnectionType::CLIENT, MessageType::Client::TEAM_INVITE_INITIAL_RESPONSE) {}
|
||||
TeamInviteInitialResponse() : LUBitStream(ServiceType::CLIENT, MessageType::Client::TEAM_INVITE_INITIAL_RESPONSE) {}
|
||||
|
||||
void Serialize(RakNet::BitStream& bitstream) const override;
|
||||
// No Deserialize needed on our end
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "BitStream.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "dServer.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "MessageType/Master.h"
|
||||
#include "BitStreamUtils.h"
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
|
||||
void MasterPackets::SendPersistentIDRequest(dServer* server, uint64_t requestID) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::REQUEST_PERSISTENT_ID);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::REQUEST_PERSISTENT_ID);
|
||||
bitStream.Write(requestID);
|
||||
server->SendToMaster(bitStream);
|
||||
}
|
||||
|
||||
void MasterPackets::SendPersistentIDResponse(dServer* server, const SystemAddress& sysAddr, uint64_t requestID, uint32_t objID) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::REQUEST_PERSISTENT_ID_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::REQUEST_PERSISTENT_ID_RESPONSE);
|
||||
|
||||
bitStream.Write(requestID);
|
||||
bitStream.Write(objID);
|
||||
@@ -27,7 +27,7 @@ void MasterPackets::SendPersistentIDResponse(dServer* server, const SystemAddres
|
||||
|
||||
void MasterPackets::SendZoneTransferRequest(dServer* server, uint64_t requestID, bool mythranShift, uint32_t zoneID, uint32_t cloneID) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::REQUEST_ZONE_TRANSFER);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::REQUEST_ZONE_TRANSFER);
|
||||
|
||||
bitStream.Write(requestID);
|
||||
bitStream.Write<uint8_t>(mythranShift);
|
||||
@@ -39,7 +39,7 @@ void MasterPackets::SendZoneTransferRequest(dServer* server, uint64_t requestID,
|
||||
|
||||
void MasterPackets::SendZoneCreatePrivate(dServer* server, uint32_t zoneID, uint32_t cloneID, const std::string& password) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::CREATE_PRIVATE_ZONE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::CREATE_PRIVATE_ZONE);
|
||||
|
||||
bitStream.Write(zoneID);
|
||||
bitStream.Write(cloneID);
|
||||
@@ -54,7 +54,7 @@ void MasterPackets::SendZoneCreatePrivate(dServer* server, uint32_t zoneID, uint
|
||||
|
||||
void MasterPackets::SendZoneRequestPrivate(dServer* server, uint64_t requestID, bool mythranShift, const std::string& password) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::REQUEST_PRIVATE_ZONE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::REQUEST_PRIVATE_ZONE);
|
||||
|
||||
bitStream.Write(requestID);
|
||||
bitStream.Write<uint8_t>(mythranShift);
|
||||
@@ -69,7 +69,7 @@ void MasterPackets::SendZoneRequestPrivate(dServer* server, uint64_t requestID,
|
||||
|
||||
void MasterPackets::SendWorldReady(dServer* server, LWOMAPID zoneId, LWOINSTANCEID instanceId) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::WORLD_READY);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::WORLD_READY);
|
||||
|
||||
bitStream.Write(zoneId);
|
||||
bitStream.Write(instanceId);
|
||||
@@ -79,7 +79,7 @@ void MasterPackets::SendWorldReady(dServer* server, LWOMAPID zoneId, LWOINSTANCE
|
||||
|
||||
void MasterPackets::SendZoneTransferResponse(dServer* server, const SystemAddress& sysAddr, uint64_t requestID, bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, const std::string& serverIP, uint32_t serverPort) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::REQUEST_ZONE_TRANSFER_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::REQUEST_ZONE_TRANSFER_RESPONSE);
|
||||
|
||||
bitStream.Write(requestID);
|
||||
bitStream.Write<uint8_t>(mythranShift);
|
||||
@@ -111,7 +111,7 @@ void MasterPackets::HandleServerInfo(Packet* packet) {
|
||||
|
||||
void MasterPackets::SendServerInfo(dServer* server, Packet* packet) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::SERVER_INFO);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::SERVER_INFO);
|
||||
|
||||
bitStream.Write(server->GetPort());
|
||||
bitStream.Write(server->GetZoneID());
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "BitStream.h"
|
||||
#include <string>
|
||||
|
||||
enum class eConnectionType : uint16_t;
|
||||
enum class ServiceType : uint16_t;
|
||||
|
||||
namespace PacketUtils {
|
||||
void SavePacket(const std::string& filename, const char* data, size_t length);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "LDFFormat.h"
|
||||
#include "dServer.h"
|
||||
#include "ZCompression.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "BitStreamUtils.h"
|
||||
|
||||
#include <iostream>
|
||||
@@ -23,7 +23,7 @@ void HTTPMonitorInfo::Serialize(RakNet::BitStream& bitStream) const {
|
||||
|
||||
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, MessageType::Client::LOAD_STATIC_ZONE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::LOAD_STATIC_ZONE);
|
||||
|
||||
bitStream.Write<uint16_t>(zone.GetMapID());
|
||||
bitStream.Write<uint16_t>(zone.GetInstanceID());
|
||||
@@ -44,28 +44,28 @@ void WorldPackets::SendLoadStaticZone(const SystemAddress& sysAddr, float x, flo
|
||||
|
||||
void WorldPackets::SendCharacterCreationResponse(const SystemAddress& sysAddr, eCharacterCreationResponse response) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::CHARACTER_CREATE_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::CHARACTER_CREATE_RESPONSE);
|
||||
bitStream.Write(response);
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void WorldPackets::SendCharacterRenameResponse(const SystemAddress& sysAddr, eRenameResponse response) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::CHARACTER_RENAME_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::CHARACTER_RENAME_RESPONSE);
|
||||
bitStream.Write(response);
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void WorldPackets::SendCharacterDeleteResponse(const SystemAddress& sysAddr, bool response) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::DELETE_CHARACTER_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::DELETE_CHARACTER_RESPONSE);
|
||||
bitStream.Write<uint8_t>(response);
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void WorldPackets::SendTransferToWorld(const SystemAddress& sysAddr, const std::string& serverIP, uint32_t serverPort, bool mythranShift) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::TRANSFER_TO_WORLD);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::TRANSFER_TO_WORLD);
|
||||
|
||||
bitStream.Write(LUString(serverIP));
|
||||
bitStream.Write<uint16_t>(serverPort);
|
||||
@@ -76,7 +76,7 @@ void WorldPackets::SendTransferToWorld(const SystemAddress& sysAddr, const std::
|
||||
|
||||
void WorldPackets::SendServerState(const SystemAddress& sysAddr) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::SERVER_STATES);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::SERVER_STATES);
|
||||
bitStream.Write<uint8_t>(1); //If the server is receiving this request, it probably is ready anyway.
|
||||
SEND_PACKET;
|
||||
}
|
||||
@@ -84,7 +84,7 @@ void WorldPackets::SendServerState(const SystemAddress& sysAddr) {
|
||||
void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, int64_t reputation, LWOOBJID player, const std::string& xmlData, const std::u16string& username, eGameMasterLevel gm, const LWOCLONEID cloneID) {
|
||||
using namespace std;
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::CREATE_CHARACTER);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::CREATE_CHARACTER);
|
||||
|
||||
RakNet::BitStream data;
|
||||
|
||||
@@ -133,7 +133,7 @@ void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, int64_t rep
|
||||
|
||||
void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool requestAccepted, uint32_t requestID, const std::string& receiver, std::set<std::pair<uint8_t, uint8_t>> unacceptedItems) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::CHAT_MODERATION_STRING);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::CHAT_MODERATION_STRING);
|
||||
|
||||
bitStream.Write<uint8_t>(unacceptedItems.empty()); // Is sentence ok?
|
||||
bitStream.Write<uint16_t>(0x16); // Source ID, unknown
|
||||
@@ -157,7 +157,7 @@ void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool
|
||||
|
||||
void WorldPackets::SendGMLevelChange(const SystemAddress& sysAddr, bool success, eGameMasterLevel highestLevel, eGameMasterLevel prevLevel, eGameMasterLevel newLevel) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::MAKE_GM_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::MAKE_GM_RESPONSE);
|
||||
|
||||
bitStream.Write<uint8_t>(success);
|
||||
bitStream.Write(static_cast<uint16_t>(highestLevel));
|
||||
@@ -169,14 +169,14 @@ void WorldPackets::SendGMLevelChange(const SystemAddress& sysAddr, bool success,
|
||||
|
||||
void WorldPackets::SendHTTPMonitorInfo(const SystemAddress& sysAddr, const HTTPMonitorInfo& info) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::HTTP_MONITOR_INFO_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::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, MessageType::Client::DEBUG_OUTPUT);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::DEBUG_OUTPUT);
|
||||
bitStream.Write<uint32_t>(data.size());
|
||||
bitStream.Write(data);
|
||||
SEND_PACKET;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include "RakNetworkFactory.h"
|
||||
#include "MessageIdentifiers.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "MessageType/Server.h"
|
||||
#include "MessageType/Master.h"
|
||||
|
||||
@@ -50,7 +50,7 @@ dServer::dServer(
|
||||
Logger* logger,
|
||||
const std::string masterIP,
|
||||
int masterPort,
|
||||
ServerType serverType,
|
||||
ServiceType serverType,
|
||||
dConfig* config,
|
||||
Game::signal_t* lastSignal,
|
||||
const std::string& masterPassword,
|
||||
@@ -87,7 +87,7 @@ dServer::dServer(
|
||||
} else {
|
||||
LOG("FAILED TO START SERVER ON IP/PORT: %s:%i", ip.c_str(), port);
|
||||
#ifdef DARKFLAME_PLATFORM_LINUX
|
||||
if (mServerType == ServerType::Auth) {
|
||||
if (mServerType == ServiceType::AUTH) {
|
||||
const auto cwd = BinaryPathFinder::GetBinaryDir();
|
||||
LOG("Try running the following command before launching again:\n sudo setcap 'cap_net_bind_service=+ep' \"%s/AuthServer\"", cwd.string().c_str());
|
||||
}
|
||||
@@ -98,7 +98,7 @@ dServer::dServer(
|
||||
mLogger->SetLogToConsole(prevLogSetting);
|
||||
|
||||
//Connect to master if we are not master:
|
||||
if (serverType != ServerType::Master) {
|
||||
if (serverType != ServiceType::MASTER) {
|
||||
SetupForMasterConnection();
|
||||
if (!ConnectToMaster()) {
|
||||
LOG("Failed ConnectToMaster!");
|
||||
@@ -106,7 +106,7 @@ dServer::dServer(
|
||||
}
|
||||
|
||||
//Set up Replica if we're a world server:
|
||||
if (serverType == ServerType::World) {
|
||||
if (serverType == ServiceType::WORLD) {
|
||||
mNetIDManager = new NetworkIDManager();
|
||||
mNetIDManager->SetIsNetworkIDAuthority(true);
|
||||
|
||||
@@ -151,7 +151,7 @@ Packet* dServer::ReceiveFromMaster() {
|
||||
break;
|
||||
}
|
||||
case ID_USER_PACKET_ENUM: {
|
||||
if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::MASTER) {
|
||||
if (static_cast<ServiceType>(packet->data[1]) == ServiceType::MASTER) {
|
||||
switch (static_cast<MessageType::Master>(packet->data[3])) {
|
||||
case MessageType::Master::REQUEST_ZONE_TRANSFER_RESPONSE: {
|
||||
ZoneInstanceManager::Instance()->HandleRequestZoneTransferResponse(packet);
|
||||
@@ -199,7 +199,7 @@ void dServer::SendToMaster(RakNet::BitStream& bitStream) {
|
||||
|
||||
void dServer::Disconnect(const SystemAddress& sysAddr, eServerDisconnectIdentifiers disconNotifyID) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::SERVER, MessageType::Server::DISCONNECT_NOTIFY);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::COMMON, MessageType::Server::DISCONNECT_NOTIFY);
|
||||
bitStream.Write(disconNotifyID);
|
||||
mPeer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, sysAddr, false);
|
||||
|
||||
@@ -257,7 +257,7 @@ void dServer::Shutdown() {
|
||||
mReplicaManager = nullptr;
|
||||
}
|
||||
|
||||
if (mServerType != ServerType::Master && mMasterPeer) {
|
||||
if (mServerType != ServiceType::MASTER && mMasterPeer) {
|
||||
mMasterPeer->Shutdown(1000);
|
||||
RakNetworkFactory::DestroyRakPeerInterface(mMasterPeer);
|
||||
}
|
||||
|
||||
@@ -9,21 +9,7 @@
|
||||
class Logger;
|
||||
class dConfig;
|
||||
enum class eServerDisconnectIdentifiers : uint32_t;
|
||||
|
||||
enum class ServerType : uint32_t {
|
||||
Master,
|
||||
Auth,
|
||||
Chat,
|
||||
World
|
||||
};
|
||||
|
||||
enum class ServiceId : uint32_t{
|
||||
General = 0,
|
||||
Auth = 1,
|
||||
Chat = 2,
|
||||
World = 4,
|
||||
Client = 5,
|
||||
};
|
||||
enum class ServiceType : uint16_t;
|
||||
|
||||
namespace Game {
|
||||
using signal_t = volatile std::sig_atomic_t;
|
||||
@@ -43,7 +29,7 @@ public:
|
||||
Logger* logger,
|
||||
const std::string masterIP,
|
||||
int masterPort,
|
||||
ServerType serverType,
|
||||
ServiceType serverType,
|
||||
dConfig* config,
|
||||
Game::signal_t* shouldShutdown,
|
||||
const std::string& masterPassword,
|
||||
@@ -80,7 +66,7 @@ public:
|
||||
|
||||
NetworkIDManager* GetNetworkIDManager() { return mNetIDManager; }
|
||||
|
||||
const ServerType GetServerType() const { return mServerType; }
|
||||
ServiceType GetServerType() const { return mServerType; }
|
||||
|
||||
[[nodiscard]]
|
||||
std::chrono::steady_clock::duration GetUptime() const {
|
||||
@@ -114,7 +100,7 @@ protected:
|
||||
bool mIsInternal;
|
||||
bool mIsOkay;
|
||||
bool mMasterConnectionActive;
|
||||
ServerType mServerType;
|
||||
ServiceType mServerType;
|
||||
|
||||
RakPeerInterface* mMasterPeer = nullptr;
|
||||
SocketDescriptor mMasterSocketDescriptor;
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
#include "NiPoint3.h"
|
||||
#include "eServerDisconnectIdentifiers.h"
|
||||
#include "eObjectBits.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ServiceType.h"
|
||||
#include "MessageType/Server.h"
|
||||
#include "MessageType/Chat.h"
|
||||
#include "MessageType/World.h"
|
||||
@@ -235,7 +235,7 @@ int main(int argc, char** argv) {
|
||||
Game::logger,
|
||||
masterIP,
|
||||
masterPort,
|
||||
ServerType::World,
|
||||
ServiceType::WORLD,
|
||||
Game::config,
|
||||
&Game::lastSignal,
|
||||
masterPassword,
|
||||
@@ -554,7 +554,7 @@ void HandlePacketChat(Packet* packet) {
|
||||
}
|
||||
|
||||
if (packet->data[0] == ID_USER_PACKET_ENUM && packet->length >= 4) {
|
||||
if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::CHAT) {
|
||||
if (static_cast<ServiceType>(packet->data[1]) == ServiceType::CHAT) {
|
||||
switch (static_cast<MessageType::Chat>(packet->data[3])) {
|
||||
case MessageType::Chat::WORLD_ROUTE_PACKET: {
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
@@ -672,7 +672,7 @@ void HandlePacketChat(Packet* packet) {
|
||||
|
||||
void HandleMasterPacket(Packet* packet) {
|
||||
if (packet->length < 2) return;
|
||||
if (static_cast<eConnectionType>(packet->data[1]) != eConnectionType::MASTER || packet->length < 4) return;
|
||||
if (static_cast<ServiceType>(packet->data[1]) != ServiceType::MASTER || packet->length < 4) return;
|
||||
switch (static_cast<MessageType::Master>(packet->data[3])) {
|
||||
case MessageType::Master::REQUEST_PERSISTENT_ID_RESPONSE: {
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
@@ -739,7 +739,7 @@ void HandleMasterPacket(Packet* packet) {
|
||||
//Notify master:
|
||||
{
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::PLAYER_ADDED);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::PLAYER_ADDED);
|
||||
bitStream.Write<LWOMAPID>(Game::server->GetZoneID());
|
||||
bitStream.Write<LWOINSTANCEID>(g_InstanceID);
|
||||
Game::server->SendToMaster(bitStream);
|
||||
@@ -756,7 +756,7 @@ void HandleMasterPacket(Packet* packet) {
|
||||
|
||||
CBITSTREAM;
|
||||
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::AFFIRM_TRANSFER_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::AFFIRM_TRANSFER_RESPONSE);
|
||||
bitStream.Write(requestID);
|
||||
Game::server->SendToMaster(bitStream);
|
||||
|
||||
@@ -830,7 +830,7 @@ void HandlePacket(Packet* packet) {
|
||||
|
||||
{
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::UNEXPECTED_DISCONNECT);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::UNEXPECTED_DISCONNECT);
|
||||
bitStream.Write(user->GetLoggedInChar());
|
||||
Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false);
|
||||
}
|
||||
@@ -842,7 +842,7 @@ void HandlePacket(Packet* packet) {
|
||||
}
|
||||
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::PLAYER_REMOVED);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::PLAYER_REMOVED);
|
||||
bitStream.Write<LWOMAPID>(Game::server->GetZoneID());
|
||||
bitStream.Write<LWOINSTANCEID>(g_InstanceID);
|
||||
Game::server->SendToMaster(bitStream);
|
||||
@@ -854,13 +854,13 @@ void HandlePacket(Packet* packet) {
|
||||
LUBitStream luBitStream;
|
||||
luBitStream.ReadHeader(inStream);
|
||||
|
||||
if (luBitStream.connectionType == eConnectionType::SERVER) {
|
||||
if (luBitStream.connectionType == ServiceType::COMMON) {
|
||||
if (static_cast<MessageType::Server>(luBitStream.internalPacketID) == MessageType::Server::VERSION_CONFIRM) {
|
||||
AuthPackets::HandleHandshake(Game::server, packet);
|
||||
}
|
||||
}
|
||||
|
||||
if (luBitStream.connectionType != eConnectionType::WORLD) return;
|
||||
if (luBitStream.connectionType != ServiceType::WORLD) return;
|
||||
|
||||
switch (static_cast<MessageType::World>(luBitStream.internalPacketID)) {
|
||||
case MessageType::World::VALIDATION: {
|
||||
@@ -911,7 +911,7 @@ void HandlePacket(Packet* packet) {
|
||||
|
||||
//Request the session info from Master:
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::REQUEST_SESSION_KEY);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::REQUEST_SESSION_KEY);
|
||||
bitStream.Write(username);
|
||||
Game::server->SendToMaster(bitStream);
|
||||
|
||||
@@ -1004,7 +1004,7 @@ void HandlePacket(Packet* packet) {
|
||||
// This means we swapped characters and we need to remove the previous player from the container.
|
||||
if (static_cast<uint32_t>(lastCharacter) != playerID) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::UNEXPECTED_DISCONNECT);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::UNEXPECTED_DISCONNECT);
|
||||
bitStream.Write(lastCharacter);
|
||||
Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false);
|
||||
}
|
||||
@@ -1157,7 +1157,7 @@ void HandlePacket(Packet* packet) {
|
||||
// Workaround for not having a UGC server to get model LXFML onto the client so it
|
||||
// can generate the physics and nif for the object.
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::BLUEPRINT_SAVE_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::BLUEPRINT_SAVE_RESPONSE);
|
||||
bitStream.Write<LWOOBJID>(LWOOBJID_EMPTY); //always zero so that a check on the client passes
|
||||
bitStream.Write(eBlueprintSaveResponseType::EverythingWorked);
|
||||
bitStream.Write<uint32_t>(1);
|
||||
@@ -1189,7 +1189,7 @@ void HandlePacket(Packet* packet) {
|
||||
const auto& playerName = character->GetName();
|
||||
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::LOGIN_SESSION_NOTIFY);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::LOGIN_SESSION_NOTIFY);
|
||||
bitStream.Write(player->GetObjectID());
|
||||
bitStream.Write<uint32_t>(playerName.size());
|
||||
for (size_t i = 0; i < playerName.size(); i++) {
|
||||
@@ -1247,7 +1247,7 @@ void HandlePacket(Packet* packet) {
|
||||
|
||||
CBITSTREAM;
|
||||
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, packet->data[14]);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, packet->data[14]);
|
||||
|
||||
//We need to insert the player's objectID so the chat server can find who originated this request:
|
||||
LWOOBJID objectID = 0;
|
||||
@@ -1513,6 +1513,6 @@ void FinalizeShutdown() {
|
||||
|
||||
void SendShutdownMessageToMaster() {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::SHUTDOWN_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::SHUTDOWN_RESPONSE);
|
||||
Game::server->SendToMaster(bitStream);
|
||||
}
|
||||
|
||||
177
docs/implementation-notes.md
Normal file
177
docs/implementation-notes.md
Normal file
@@ -0,0 +1,177 @@
|
||||
# DarkflameServer Implementation Notes
|
||||
|
||||
## Key Implementation Files by Server Type
|
||||
|
||||
### Master Server (`dMasterServer/`)
|
||||
- **MasterServer.cpp**: Main server loop and packet handling
|
||||
- **InstanceManager.cpp**: Manages zone instances and player distribution
|
||||
- **PersistentIDManager.cpp**: Generates unique object IDs across servers
|
||||
- **Start.cpp**: Utility functions for starting other server types
|
||||
|
||||
### Authentication Server (`dAuthServer/`)
|
||||
- **AuthServer.cpp**: Handles login, account creation, session management
|
||||
- **AuthPackets.cpp**: Authentication protocol implementation
|
||||
|
||||
### Chat Server (`dChatServer/`)
|
||||
- **ChatServer.cpp**: Main chat server with social features
|
||||
- **ChatPacketHandler.cpp**: Routes chat and social messages
|
||||
- **PlayerContainer.cpp**: Manages online player registry
|
||||
- **TeamContainer.cpp**: Handles team/group functionality
|
||||
|
||||
### World Server (`dWorldServer/`)
|
||||
- **WorldServer.cpp**: Game world simulation and entity management
|
||||
- **PerformanceManager.cpp**: Monitors server performance metrics
|
||||
|
||||
### Game Logic (`dGame/`)
|
||||
- **CheatDetection.cpp**: Anti-cheat system with database logging
|
||||
- **UserManager.cpp**: Player session and character management
|
||||
- **EntityManager.cpp**: Game entity lifecycle and updates
|
||||
|
||||
### Networking Layer (`dNet/`)
|
||||
- **dServer.cpp/h**: Base server class with master communication
|
||||
- **MasterPackets.cpp/h**: Master server protocol implementation
|
||||
- **AuthPackets.cpp/h**: Authentication protocol
|
||||
- **ChatPackets.cpp/h**: Chat and social protocols
|
||||
- **WorldPackets.cpp/h**: World server protocols
|
||||
|
||||
## Message Flow Implementation
|
||||
|
||||
### Packet Structure
|
||||
```cpp
|
||||
// All packets use this basic structure:
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType, MessageType);
|
||||
// Followed by message-specific data
|
||||
```
|
||||
|
||||
### Service Types (from `ServiceType.h`)
|
||||
```cpp
|
||||
enum class ServiceType : uint16_t {
|
||||
COMMON = 0,
|
||||
AUTH, // Authentication Server
|
||||
CHAT, // Chat Server
|
||||
WORLD = 4, // World Server
|
||||
CLIENT, // Client messages
|
||||
MASTER, // Master Server
|
||||
UNKNOWN
|
||||
};
|
||||
```
|
||||
|
||||
### Critical Communication Patterns
|
||||
|
||||
#### 1. Server-to-Master Registration
|
||||
```cpp
|
||||
// All servers connect to master on startup
|
||||
void dServer::ConnectToMaster() {
|
||||
mMasterPeer->Connect(mMasterIP.c_str(), mMasterPort,
|
||||
mMasterPassword.c_str(), mMasterPassword.size());
|
||||
}
|
||||
|
||||
// On connection, servers send their info
|
||||
case ID_CONNECTION_REQUEST_ACCEPTED: {
|
||||
MasterPackets::SendServerInfo(this, packet);
|
||||
break;
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. Zone Transfer Protocol
|
||||
```cpp
|
||||
// World Server requests transfer
|
||||
MasterPackets::SendZoneTransferRequest(server, requestID, mythranShift, zoneID, cloneID);
|
||||
|
||||
// Master finds/creates instance and responds
|
||||
void HandleZoneTransferRequest() {
|
||||
auto instance = Game::im->GetInstance(zoneID, false, zoneClone);
|
||||
// Send response with target server info
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. Chat Message Routing
|
||||
```cpp
|
||||
// World Server forwards chat to Chat Server
|
||||
void HandleChatMessage() {
|
||||
// Route through Chat Server for processing
|
||||
Game::chatServer->Send(bitStream, chatServerAddr, false);
|
||||
}
|
||||
|
||||
// Chat Server routes to all relevant World Servers
|
||||
void RouteMessage() {
|
||||
for (auto& worldServer : connectedWorldServers) {
|
||||
Send(message, worldServer.address, false);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Database Architecture
|
||||
|
||||
### Core Tables
|
||||
- **accounts**: User account information
|
||||
- **charinfo**: Character data and statistics
|
||||
- **friends**: Friend relationships
|
||||
- **mail**: In-game mail system
|
||||
- **properties**: Player property data
|
||||
- **leaderboards**: Competition scores
|
||||
- **servers**: Server configuration
|
||||
|
||||
### Connection Management
|
||||
```cpp
|
||||
// Shared database connection across all servers
|
||||
Database::Connect(); // Uses connection pooling
|
||||
auto result = Database::Get()->Query(sql);
|
||||
```
|
||||
|
||||
## Scalability Design
|
||||
|
||||
### Load Distribution
|
||||
- Master Server acts as load balancer
|
||||
- Multiple World Servers can run different zones
|
||||
- Instance Manager distributes players across zones
|
||||
- Chat Server handles all social features centrally
|
||||
|
||||
### Fault Tolerance
|
||||
- All servers maintain connections with Master Server
|
||||
- Database connection monitoring and error handling
|
||||
- Player state persisted in database
|
||||
- Graceful degradation when servers unavailable
|
||||
|
||||
### Performance Optimizations
|
||||
- Entity serialization only to relevant players (ghosting)
|
||||
- Spatial partitioning for efficient updates
|
||||
- Database query optimization with prepared statements
|
||||
- Network packet compression and optimization
|
||||
|
||||
## Security Features
|
||||
|
||||
### Network Security
|
||||
- RakNet encryption for client connections
|
||||
- Server-to-server authentication via passwords
|
||||
- Session key validation across servers
|
||||
- Packet validation and sanitization
|
||||
|
||||
### Game Security
|
||||
- Server-side validation of all game actions
|
||||
- Cheat detection system with database logging (`CheatDetection.cpp`)
|
||||
- Player cheat detection table tracks suspicious activities
|
||||
- Rate limiting on client requests
|
||||
- Database injection prevention
|
||||
|
||||
## Development Notes
|
||||
|
||||
### Build System
|
||||
- CMake-based build with modular components
|
||||
- Cross-platform support (Windows, Linux, macOS)
|
||||
- Dependency management through git submodules
|
||||
- Automated testing framework
|
||||
|
||||
### Configuration
|
||||
- INI-based configuration files per server type
|
||||
- Environment variable support
|
||||
- Runtime configuration updates
|
||||
- Database-driven server settings
|
||||
|
||||
### Debugging Features
|
||||
- Comprehensive logging system
|
||||
- Performance metrics collection
|
||||
- Packet capture and analysis tools
|
||||
- Real-time server monitoring
|
||||
|
||||
This implementation successfully recreates the LEGO Universe MMO experience through a robust, scalable architecture that can support thousands of concurrent players across multiple game zones while maintaining the original game's functionality and performance characteristics.
|
||||
141
docs/server-architecture-ascii.md
Normal file
141
docs/server-architecture-ascii.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# DarkflameServer Architecture - ASCII Diagram
|
||||
|
||||
```
|
||||
DARKFLAME SERVER ARCHITECTURE
|
||||
===============================
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ CLIENT LAYER │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │LEGO Universe│ │LEGO Universe│ │LEGO Universe│ │LEGO Universe│ │
|
||||
│ │ Client │ │ Client │ │ Client │ │ Client │ │
|
||||
│ │ (Player) │ │ (Player) │ │ (Player) │ │ (Player) │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
│ │ │ │ │ │
|
||||
└─────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┘
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
┌─────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┐
|
||||
│ │ SERVER COMMUNICATION LAYER │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ ▼ ▼ ▼ ▼ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │AUTH SERVER │ │WORLD SERVER │ │WORLD SERVER │ │WORLD SERVER │ │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│ │Port: 1001 │ │Port: Dynamic│ │Port: Dynamic│ │Port: Dynamic│ │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│ │• Login │ │• Game Logic │ │• Game Logic │ │• Game Logic │ │
|
||||
│ │• Accounts │ │• Entities │ │• Entities │ │• Entities │ │
|
||||
│ │• Sessions │ │• Physics │ │• Physics │ │• Physics │ │
|
||||
│ │• Keys │ │• Zone Mgmt │ │• Zone Mgmt │ │• Zone Mgmt │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ ┌─────────────┐ │ │ │ │
|
||||
│ │ │CHAT SERVER │←──────┼───────────────────┼───────────────────┘ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │Port: 1501 │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │• Chat Msgs │ │ │ │
|
||||
│ │ │• Teams │ │ │ │
|
||||
│ │ │• Guilds │ │ │ │
|
||||
│ │ │• Friends │ │ │ │
|
||||
│ │ └─────────────┘ │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ └─────────────────┼───────────┼───────────────────┼────────────────────────────┤
|
||||
│ │ │ │ │
|
||||
│ ┌─────────────────┼───────────┼───────────────────┼───────────────────┐ │
|
||||
│ │ │ │ │ │ │
|
||||
│ ▼ ▼ ▼ ▼ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ MASTER SERVER (Port: 1500) │ │
|
||||
│ │ │ │
|
||||
│ │ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ │
|
||||
│ │ │ Instance Manager │ │Persistent ID Mgr │ │ Session Manager │ │ │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│ │ │• Zone Instances │ │• Object ID Gen │ │• Player Sessions │ │ │
|
||||
│ │ │• Load Balance │ │• Unique IDs │ │• Server Registry │ │ │
|
||||
│ │ │• Player Transfer │ │• Cross-Server │ │• Coordination │ │ │
|
||||
│ │ └──────────────────┘ └──────────────────┘ └──────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
└────────────────────────────────────────┼────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ DATABASE LAYER │
|
||||
│ │
|
||||
│ ┌─────────────────────┐ │
|
||||
│ │ MySQL Database │ │
|
||||
│ │ │ │
|
||||
│ │ • Player Data │ │
|
||||
│ │ • Characters │ │
|
||||
│ │ • Friends/Mail │ │
|
||||
│ │ • Properties │ │
|
||||
│ │ • Leaderboards │ │
|
||||
│ │ • Configuration │ │
|
||||
│ └─────────────────────┘ │
|
||||
└─────────────────────────────────────────┘
|
||||
|
||||
|
||||
MESSAGE FLOW OVERVIEW
|
||||
====================
|
||||
|
||||
Auth Messages Chat Messages World Messages
|
||||
============= ============= ==============
|
||||
|
||||
LOGIN_REQUEST GENERAL_CHAT_MESSAGE CHARACTER_LIST_REQUEST
|
||||
CREATE_ACCOUNT PRIVATE_CHAT_MESSAGE GAME_MSG (1000+ types)
|
||||
SESSION_KEY TEAM_INVITE LEVEL_LOAD_COMPLETE
|
||||
AUTH_RESPONSE ADD_FRIEND POSITION_UPDATE
|
||||
GUILD_OPERATIONS ZONE_TRANSFER_REQUEST
|
||||
|
||||
Master Coordination Messages
|
||||
============================
|
||||
|
||||
SERVER_INFO REQUEST_PERSISTENT_ID WORLD_READY
|
||||
PLAYER_ADDED/REMOVED REQUEST_ZONE_TRANSFER SHUTDOWN
|
||||
SET_SESSION_KEY AFFIRM_TRANSFER NEW_SESSION_ALERT
|
||||
|
||||
|
||||
COMMUNICATION PATTERNS
|
||||
======================
|
||||
|
||||
1. Client Authentication Flow:
|
||||
Client → Auth Server → Master Server → World Server → Chat Server
|
||||
|
||||
2. Zone Transfer Flow:
|
||||
World Server → Master Server → Target World Server → Client
|
||||
|
||||
3. Chat Message Flow:
|
||||
Client → World Server → Chat Server → Target World Server(s) → Target Client(s)
|
||||
|
||||
4. Entity Updates Flow:
|
||||
World Server → EntityManager → ReplicaManager → All Clients in Zone
|
||||
|
||||
5. Master Coordination:
|
||||
All Servers ↔ Master Server (Heartbeat, Registration, Coordination)
|
||||
|
||||
|
||||
NETWORK SPECIFICATIONS
|
||||
======================
|
||||
|
||||
Protocol: RakNet (UDP-based)
|
||||
Encryption: Enabled for client connections
|
||||
Packet Structure: [RakNet Header][Message Type][Service Type][Message Data]
|
||||
|
||||
Service Type Codes:
|
||||
- MASTER (5): Server coordination
|
||||
- AUTH (1): Authentication
|
||||
- CHAT (2): Social features
|
||||
- WORLD (4): Game simulation
|
||||
- CLIENT (4): Client-specific
|
||||
|
||||
Key Features:
|
||||
- Distributed architecture for scalability
|
||||
- Fault tolerance through master coordination
|
||||
- Real-time entity replication
|
||||
- Cross-server player transfers
|
||||
- Persistent world state
|
||||
```
|
||||
379
docs/server-architecture-diagram.md
Normal file
379
docs/server-architecture-diagram.md
Normal file
@@ -0,0 +1,379 @@
|
||||
# DarkflameServer Architecture and Communication Diagram
|
||||
|
||||
This document provides a comprehensive overview of the server architecture, inter-server communication patterns, and message flows in the DarkflameServer LEGO Universe emulator.
|
||||
|
||||
## Server Architecture Overview
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Client Layer"
|
||||
Client1[LEGO Universe Client]
|
||||
Client2[LEGO Universe Client]
|
||||
Client3[LEGO Universe Client]
|
||||
end
|
||||
|
||||
subgraph "DarkflameServer Infrastructure"
|
||||
subgraph "Master Server (Port 1500)"
|
||||
MasterServer[Master Server<br/>- Zone Management<br/>- Instance Coordination<br/>- Session Management<br/>- Server Registration]
|
||||
IM[Instance Manager<br/>- Zone Instances<br/>- Player Transfers<br/>- Load Balancing]
|
||||
PIM[Persistent ID Manager<br/>- Object ID Generation<br/>- Unique Identifiers]
|
||||
end
|
||||
|
||||
subgraph "Authentication Server (Port 1001)"
|
||||
AuthServer[Auth Server<br/>- Login Processing<br/>- Account Management<br/>- Session Keys<br/>- Player Authentication]
|
||||
end
|
||||
|
||||
subgraph "Chat Server (Port 1501)"
|
||||
ChatServer[Chat Server<br/>- General Chat<br/>- Private Messages<br/>- Team Management<br/>- Guild System<br/>- Friend Lists<br/>- Mail System]
|
||||
PC[Player Container<br/>- Online Players<br/>- Chat Routing]
|
||||
end
|
||||
|
||||
subgraph "World Servers (Dynamic Ports)"
|
||||
WorldServer1[World Server 1<br/>- Game Logic<br/>- Entity Management<br/>- Physics Simulation<br/>- Zone: Avant Gardens]
|
||||
WorldServer2[World Server 2<br/>- Game Logic<br/>- Entity Management<br/>- Physics Simulation<br/>- Zone: Nimbus Station]
|
||||
WorldServer3[World Server N<br/>- Game Logic<br/>- Entity Management<br/>- Physics Simulation<br/>- Zone: Custom]
|
||||
EM1[Entity Manager]
|
||||
EM2[Entity Manager]
|
||||
EM3[Entity Manager]
|
||||
WorldServer1 --- EM1
|
||||
WorldServer2 --- EM2
|
||||
WorldServer3 --- EM3
|
||||
end
|
||||
end
|
||||
|
||||
subgraph "Database Layer"
|
||||
Database[(MySQL Database<br/>- Player Data<br/>- Characters<br/>- Properties<br/>- Leaderboards<br/>- Mail<br/>- Friends)]
|
||||
end
|
||||
|
||||
%% Client Connections
|
||||
Client1 -.->|1. Authentication| AuthServer
|
||||
Client1 -.->|2. Character/Zone Data| WorldServer1
|
||||
|
||||
Client2 -.->|Authentication| AuthServer
|
||||
Client2 -.->|Character/Zone Data| WorldServer2
|
||||
|
||||
Client3 -.->|Authentication| AuthServer
|
||||
Client3 -.->|Character/Zone Data| WorldServer3
|
||||
|
||||
%% Server-to-Master Connections (All servers connect to master)
|
||||
AuthServer <-.->|SERVER_INFO<br/>SESSION_KEY<br/>PLAYER_ADDED/REMOVED| MasterServer
|
||||
ChatServer <-.->|SERVER_INFO<br/>PLAYER_ADDED/REMOVED| MasterServer
|
||||
WorldServer1 <-.->|ZONE_TRANSFER<br/>PERSISTENT_ID<br/>WORLD_READY<br/>SERVER_INFO| MasterServer
|
||||
WorldServer2 <-.->|ZONE_TRANSFER<br/>PERSISTENT_ID<br/>WORLD_READY<br/>SERVER_INFO| MasterServer
|
||||
WorldServer3 <-.->|ZONE_TRANSFER<br/>PERSISTENT_ID<br/>WORLD_READY<br/>SERVER_INFO| MasterServer
|
||||
|
||||
%% Master Server Internal Communication
|
||||
MasterServer --- IM
|
||||
MasterServer --- PIM
|
||||
|
||||
%% Database Connections
|
||||
AuthServer <--> Database
|
||||
ChatServer <--> Database
|
||||
WorldServer1 <--> Database
|
||||
WorldServer2 <--> Database
|
||||
WorldServer3 <--> Database
|
||||
MasterServer <--> Database
|
||||
|
||||
%% Chat Server Communication (World Servers route chat, clients never connect directly)
|
||||
WorldServer1 <-.->|Chat Messages<br/>Team Operations<br/>Social Features| ChatServer
|
||||
WorldServer2 <-.->|Chat Messages<br/>Team Operations<br/>Social Features| ChatServer
|
||||
WorldServer3 <-.->|Chat Messages<br/>Team Operations<br/>Social Features| ChatServer
|
||||
|
||||
style MasterServer fill:#ff9999
|
||||
style AuthServer fill:#99ccff
|
||||
style ChatServer fill:#99ff99
|
||||
style WorldServer1 fill:#ffcc99
|
||||
style WorldServer2 fill:#ffcc99
|
||||
style WorldServer3 fill:#ffcc99
|
||||
style Database fill:#cc99ff
|
||||
```
|
||||
|
||||
## Message Type Breakdown
|
||||
|
||||
### Master Server Messages (`MessageType::Master`)
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "Master Server Communication"
|
||||
Master[Master Server]
|
||||
|
||||
subgraph "To/From Other Servers"
|
||||
M1[REQUEST_PERSISTENT_ID<br/>↔ World Servers]
|
||||
M2[REQUEST_ZONE_TRANSFER<br/>↔ World Servers]
|
||||
M3[SERVER_INFO<br/>← All Servers]
|
||||
M4[SET_SESSION_KEY<br/>↔ Auth Server]
|
||||
M5[PLAYER_ADDED/REMOVED<br/>← All Servers]
|
||||
M6[WORLD_READY<br/>← World Servers]
|
||||
M7[SHUTDOWN<br/>→ All Servers]
|
||||
end
|
||||
|
||||
Master -.-> M1
|
||||
Master -.-> M2
|
||||
Master -.-> M3
|
||||
Master -.-> M4
|
||||
Master -.-> M5
|
||||
Master -.-> M6
|
||||
Master -.-> M7
|
||||
end
|
||||
```
|
||||
|
||||
### Authentication Server Messages (`MessageType::Auth`)
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "Auth Server Communication"
|
||||
Auth[Auth Server]
|
||||
|
||||
subgraph "To/From Clients"
|
||||
A1[LOGIN_REQUEST<br/>← Clients]
|
||||
A2[CREATE_NEW_ACCOUNT_REQUEST<br/>← Clients]
|
||||
A3[LEGOINTERFACE_AUTH_RESPONSE<br/>→ Clients]
|
||||
end
|
||||
|
||||
subgraph "To/From Master"
|
||||
A4[SESSION_KEY<br/>→ Master]
|
||||
A5[PLAYER_NOTIFICATION<br/>→ Master]
|
||||
end
|
||||
|
||||
Auth -.-> A1
|
||||
Auth -.-> A2
|
||||
Auth -.-> A3
|
||||
Auth -.-> A4
|
||||
Auth -.-> A5
|
||||
end
|
||||
```
|
||||
|
||||
### Chat Server Messages (`MessageType::Chat`)
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "Chat Server Communication"
|
||||
Chat[Chat Server]
|
||||
|
||||
subgraph "Player Social Features"
|
||||
C1[GENERAL_CHAT_MESSAGE<br/>↔ All Players]
|
||||
C2[PRIVATE_CHAT_MESSAGE<br/>↔ Players]
|
||||
C3[TEAM_INVITE/RESPONSE<br/>↔ Players]
|
||||
C4[ADD_FRIEND_REQUEST<br/>↔ Players]
|
||||
C5[GUILD_OPERATIONS<br/>↔ Players]
|
||||
C6[MAIL_SYSTEM<br/>↔ Players]
|
||||
end
|
||||
|
||||
subgraph "World Server Integration"
|
||||
C7[WORLD_ROUTE_PACKET<br/>↔ World Servers]
|
||||
C8[PLAYER_READY<br/>← World Servers]
|
||||
C9[LOGIN_SESSION_NOTIFY<br/>← World Servers]
|
||||
end
|
||||
|
||||
Chat -.-> C1
|
||||
Chat -.-> C2
|
||||
Chat -.-> C3
|
||||
Chat -.-> C4
|
||||
Chat -.-> C5
|
||||
Chat -.-> C6
|
||||
Chat -.-> C7
|
||||
Chat -.-> C8
|
||||
Chat -.-> C9
|
||||
end
|
||||
```
|
||||
|
||||
### World Server Messages (`MessageType::World` & `MessageType::Game`)
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "World Server Communication"
|
||||
World[World Server]
|
||||
|
||||
subgraph "Client Game Messages"
|
||||
W1[CHARACTER_LIST_REQUEST<br/>← Clients]
|
||||
W2[CHARACTER_CREATE_REQUEST<br/>← Clients]
|
||||
W3[LOGIN_REQUEST<br/>← Clients]
|
||||
W4[GAME_MSG<br/>↔ Clients]
|
||||
W5[LEVEL_LOAD_COMPLETE<br/>← Clients]
|
||||
W6[POSITION_UPDATE<br/>↔ Clients]
|
||||
end
|
||||
|
||||
subgraph "Entity & Game Logic (1000+ Game Messages)"
|
||||
G1[Entity Serialization<br/>Player/NPC Updates]
|
||||
G2[Combat System<br/>Skills & Damage]
|
||||
G3[Building System<br/>Property Management]
|
||||
G4[Mission System<br/>Quest Management]
|
||||
G5[Inventory System<br/>Item Management]
|
||||
G6[Racing System<br/>Vehicle Physics]
|
||||
end
|
||||
|
||||
subgraph "Master Server Communication"
|
||||
W7[ZONE_TRANSFER_REQUEST<br/>→ Master]
|
||||
W8[PERSISTENT_ID_REQUEST<br/>→ Master]
|
||||
W9[WORLD_READY<br/>→ Master]
|
||||
end
|
||||
|
||||
subgraph "Chat Server Communication"
|
||||
W10[Chat Messages<br/>↔ Chat Server]
|
||||
W11[Team Operations<br/>↔ Chat Server]
|
||||
end
|
||||
|
||||
World -.-> W1
|
||||
World -.-> W2
|
||||
World -.-> W3
|
||||
World -.-> W4
|
||||
World -.-> W5
|
||||
World -.-> W6
|
||||
World -.-> W7
|
||||
World -.-> W8
|
||||
World -.-> W9
|
||||
World -.-> W10
|
||||
World -.-> W11
|
||||
|
||||
World --- G1
|
||||
World --- G2
|
||||
World --- G3
|
||||
World --- G4
|
||||
World --- G5
|
||||
World --- G6
|
||||
end
|
||||
```
|
||||
|
||||
## Communication Flow Diagrams
|
||||
|
||||
### Player Login Flow
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant C as Client
|
||||
participant A as Auth Server
|
||||
participant M as Master Server
|
||||
participant W as World Server
|
||||
participant Ch as Chat Server
|
||||
participant DB as Database
|
||||
|
||||
C->>A: LOGIN_REQUEST
|
||||
A->>DB: Validate credentials
|
||||
DB-->>A: User data
|
||||
A->>M: SET_SESSION_KEY
|
||||
A->>C: LEGOINTERFACE_AUTH_RESPONSE
|
||||
C->>W: CHARACTER_LIST_REQUEST
|
||||
W->>DB: Get characters
|
||||
DB-->>W: Character data
|
||||
W->>C: Character list
|
||||
C->>W: LOGIN_REQUEST (character selected)
|
||||
W->>M: PLAYER_ADDED
|
||||
W->>Ch: LOGIN_SESSION_NOTIFY
|
||||
W->>C: Zone data & enter world
|
||||
```
|
||||
|
||||
### Zone Transfer Flow
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant C as Client
|
||||
participant W1 as Source World Server
|
||||
participant M as Master Server
|
||||
participant W2 as Target World Server
|
||||
participant Ch as Chat Server
|
||||
|
||||
C->>W1: Transfer request (rocket, door, etc.)
|
||||
W1->>M: REQUEST_ZONE_TRANSFER
|
||||
M->>M: Find/create zone instance
|
||||
M-->>W1: ZONE_TRANSFER_RESPONSE
|
||||
W1->>C: TRANSFER_TO_ZONE
|
||||
C->>W2: Connect to new world server
|
||||
W2->>M: Confirm player transfer
|
||||
W2->>Ch: Update player location
|
||||
W1->>M: PLAYER_REMOVED
|
||||
W2->>M: PLAYER_ADDED
|
||||
```
|
||||
|
||||
### Chat Message Flow
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant C1 as Client 1
|
||||
participant W1 as World Server 1
|
||||
participant Ch as Chat Server
|
||||
participant W2 as World Server 2
|
||||
participant C2 as Client 2
|
||||
|
||||
C1->>W1: Chat message
|
||||
W1->>Ch: GENERAL_CHAT_MESSAGE
|
||||
Ch->>Ch: Process & route message
|
||||
Ch->>W2: WORLD_ROUTE_PACKET (to relevant world servers)
|
||||
W2->>C2: Display message
|
||||
Ch->>W1: Message confirmation
|
||||
W1->>C1: Message sent confirmation
|
||||
```
|
||||
|
||||
## Technical Implementation Details
|
||||
|
||||
### Network Architecture
|
||||
- **Protocol**: RakNet UDP-based networking
|
||||
- **Security**: Encryption enabled for external connections
|
||||
- **Port Configuration**:
|
||||
- Master Server: 1500 (default)
|
||||
- Auth Server: 1001 (hardcoded in client)
|
||||
- Chat Server: 1501 (configurable)
|
||||
- World Servers: Dynamic ports assigned by Master
|
||||
|
||||
### Server-to-Server Communication
|
||||
```cpp
|
||||
// All servers maintain connection to Master
|
||||
class dServer {
|
||||
Packet* ReceiveFromMaster();
|
||||
void SendToMaster(RakNet::BitStream& bitStream);
|
||||
bool ConnectToMaster();
|
||||
void SetupForMasterConnection();
|
||||
};
|
||||
```
|
||||
|
||||
### Key Classes and Components
|
||||
|
||||
#### Master Server Components
|
||||
- `InstanceManager`: Manages zone instances and player distribution
|
||||
- `PersistentIDManager`: Generates unique object IDs across all servers
|
||||
- `MasterPackets`: Handles inter-server message protocols
|
||||
|
||||
#### World Server Components
|
||||
- `EntityManager`: Manages all game entities and their serialization
|
||||
- `UserManager`: Tracks connected players and their sessions
|
||||
- `ReplicaManager`: Handles object replication to clients
|
||||
- `GameMessages`: Processes 1000+ different game mechanic messages
|
||||
|
||||
#### Chat Server Components
|
||||
- `PlayerContainer`: Maintains online player registry
|
||||
- `TeamContainer`: Manages team/group functionality
|
||||
- `ChatPacketHandler`: Routes all chat and social messages
|
||||
|
||||
### Database Integration
|
||||
- All servers connect to shared MySQL database
|
||||
- Player data, characters, mail, friends, properties stored centrally
|
||||
- Concurrent access managed through connection pooling
|
||||
- Migration system for database schema updates
|
||||
|
||||
### Scalability Features
|
||||
- Multiple World Server instances for different zones
|
||||
- Load balancing through Master Server's Instance Manager
|
||||
- Dynamic server spawning capability
|
||||
- Horizontal scaling support for high player counts
|
||||
|
||||
## Message Protocol Specifications
|
||||
|
||||
### Packet Structure
|
||||
```
|
||||
[RakNet Header][Message Type][Service Type][Message Data]
|
||||
```
|
||||
|
||||
### Service Types
|
||||
- `MASTER (5)`: Master server coordination
|
||||
- `AUTH (1)`: Authentication services
|
||||
- `CHAT (2)`: Chat and social features
|
||||
- `WORLD (4)`: Game world simulation
|
||||
- `CLIENT (4)`: Client-specific messages
|
||||
|
||||
### Critical Message Types by Frequency
|
||||
1. **GAME_MSG** (~60% of traffic): Real-time game mechanics
|
||||
2. **POSITION_UPDATE** (~20% of traffic): Player movement
|
||||
3. **Chat Messages** (~10% of traffic): Social communication
|
||||
4. **Entity Serialization** (~8% of traffic): World state sync
|
||||
5. **Administrative** (~2% of traffic): Server coordination
|
||||
|
||||
This architecture enables the DarkflameServer to faithfully recreate the LEGO Universe MMO experience through a distributed, scalable server infrastructure that can handle thousands of concurrent players across multiple game zones.
|
||||
@@ -57,16 +57,16 @@ TEST_F(GameMessageTests, SendBlueprintLoadItemResponse) {
|
||||
ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 200);
|
||||
// First read in the packets' header
|
||||
uint8_t rakNetPacketId{};
|
||||
uint16_t remoteConnectionType{};
|
||||
uint16_t remoteServiceType{};
|
||||
uint32_t packetId{};
|
||||
uint8_t always0{};
|
||||
|
||||
bitStream->Read(rakNetPacketId);
|
||||
bitStream->Read(remoteConnectionType);
|
||||
bitStream->Read(remoteServiceType);
|
||||
bitStream->Read(packetId);
|
||||
bitStream->Read(always0);
|
||||
ASSERT_EQ(rakNetPacketId, 0x53);
|
||||
ASSERT_EQ(remoteConnectionType, 0x05);
|
||||
ASSERT_EQ(remoteServiceType, 0x5);
|
||||
ASSERT_EQ(packetId, 0x17);
|
||||
ASSERT_EQ(always0, 0x00);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user