From e10351bde6906899ad4602e89f14a860bbdd2878 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Fri, 6 Oct 2023 01:57:18 -0700 Subject: [PATCH] Server: Secure Master packet handling --- dNet/dServer.cpp | 32 ++----- dWorldServer/WorldServer.cpp | 159 ++++++++++++++++++----------------- 2 files changed, 87 insertions(+), 104 deletions(-) diff --git a/dNet/dServer.cpp b/dNet/dServer.cpp index 75cd4091..3e3c36b0 100644 --- a/dNet/dServer.cpp +++ b/dNet/dServer.cpp @@ -110,40 +110,20 @@ Packet* dServer::ReceiveFromMaster() { if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION || packet->data[0] == ID_CONNECTION_LOST) { mLogger->Log("dServer", "Lost our connection to master, shutting DOWN!"); mMasterConnectionActive = false; + mMasterPeer->DeallocatePacket(packet); + packet = nullptr; //ConnectToMaster(); //We'll just shut down now - } - - if (packet->data[0] == ID_CONNECTION_REQUEST_ACCEPTED) { + } else if (packet->data[0] == ID_CONNECTION_REQUEST_ACCEPTED) { mLogger->Log("dServer", "Established connection to master, zone (%i), instance (%i)", this->GetZoneID(), this->GetInstanceID()); mMasterConnectionActive = true; mMasterSystemAddress = packet->systemAddress; MasterPackets::SendServerInfo(this, packet); + mMasterPeer->DeallocatePacket(packet); + packet = nullptr; } - - if (packet->data[0] == ID_USER_PACKET_ENUM) { - if (static_cast(packet->data[1]) == eConnectionType::MASTER) { - switch (static_cast(packet->data[3])) { - case eMasterMessageType::REQUEST_ZONE_TRANSFER_RESPONSE: { - uint64_t requestID = PacketUtils::ReadU64(8, packet); - ZoneInstanceManager::Instance()->HandleRequestZoneTransferResponse(requestID, packet); - break; - } - case eMasterMessageType::SHUTDOWN: - *mShouldShutdown = true; - break; - - //When we handle these packets in World instead dServer, we just return the packet's pointer. - default: - - return packet; - } - } - } - - mMasterPeer->DeallocatePacket(packet); } - return nullptr; + return packet; } Packet* dServer::Receive() { diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 6e038b06..492f87ba 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -97,6 +97,7 @@ void WorldShutdownSequence(); void WorldShutdownProcess(uint32_t zoneId); void FinalizeShutdown(); void SendShutdownMessageToMaster(); +void HandleMasterPacket(Packet* packet); dLogger* SetupLogger(uint32_t zoneID, uint32_t instanceID); void HandlePacketChat(Packet* packet); @@ -413,7 +414,7 @@ int main(int argc, char** argv) { //Check for packets here: packet = Game::server->ReceiveFromMaster(); if (packet) { //We can get messages not handle-able by the dServer class, so handle them if we returned anything. - HandlePacket(packet); + HandleMasterPacket(packet); Game::server->DeallocateMasterPacket(packet); } @@ -677,64 +678,7 @@ void HandlePacketChat(Packet* packet) { } } -void HandlePacket(Packet* packet) { - if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION || packet->data[0] == ID_CONNECTION_LOST) { - auto user = UserManager::Instance()->GetUser(packet->systemAddress); - if (!user) return; - - auto c = user->GetLastUsedChar(); - if (!c) { - UserManager::Instance()->DeleteUser(packet->systemAddress); - return; - } - - auto* entity = Game::entityManager->GetEntity(c->GetObjectID()); - - if (!entity) { - entity = Player::GetPlayer(packet->systemAddress); - } - - if (entity) { - auto* skillComponent = entity->GetComponent(); - - if (skillComponent != nullptr) { - skillComponent->Reset(); - } - - entity->GetCharacter()->SaveXMLToDatabase(); - - Game::logger->Log("WorldServer", "Deleting player %llu", entity->GetObjectID()); - - Game::entityManager->DestroyEntity(entity); - } - - { - CBITSTREAM; - BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_REMOVED_NOTIFICATION); - bitStream.Write(user->GetLoggedInChar()); - Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); - } - - UserManager::Instance()->DeleteUser(packet->systemAddress); - - if (PropertyManagementComponent::Instance() != nullptr) { - PropertyManagementComponent::Instance()->Save(); - } - - CBITSTREAM; - BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PLAYER_REMOVED); - bitStream.Write((LWOMAPID)Game::server->GetZoneID()); - bitStream.Write((LWOINSTANCEID)instanceID); - Game::server->SendToMaster(&bitStream); - } - - if (packet->data[0] != ID_USER_PACKET_ENUM || packet->length < 4) return; - if (static_cast(packet->data[1]) == eConnectionType::SERVER) { - if (static_cast(packet->data[3]) == eServerMessageType::VERSION_CONFIRM) { - AuthPackets::HandleHandshake(Game::server, packet); - } - } - +void HandleMasterPacket(Packet* packet) { if (static_cast(packet->data[1]) == eConnectionType::MASTER) { switch (static_cast(packet->data[3])) { case eMasterMessageType::REQUEST_PERSISTENT_ID_RESPONSE: { @@ -873,6 +817,65 @@ void HandlePacket(Packet* packet) { return; } +} + +void HandlePacket(Packet* packet) { + if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION || packet->data[0] == ID_CONNECTION_LOST) { + auto user = UserManager::Instance()->GetUser(packet->systemAddress); + if (!user) return; + + auto c = user->GetLastUsedChar(); + if (!c) { + UserManager::Instance()->DeleteUser(packet->systemAddress); + return; + } + + auto* entity = Game::entityManager->GetEntity(c->GetObjectID()); + + if (!entity) { + entity = Player::GetPlayer(packet->systemAddress); + } + + if (entity) { + auto* skillComponent = entity->GetComponent(); + + if (skillComponent != nullptr) { + skillComponent->Reset(); + } + + entity->GetCharacter()->SaveXMLToDatabase(); + + Game::logger->Log("WorldServer", "Deleting player %llu", entity->GetObjectID()); + + Game::entityManager->DestroyEntity(entity); + } + + { + CBITSTREAM; + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_REMOVED_NOTIFICATION); + bitStream.Write(user->GetLoggedInChar()); + Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); + } + + UserManager::Instance()->DeleteUser(packet->systemAddress); + + if (PropertyManagementComponent::Instance() != nullptr) { + PropertyManagementComponent::Instance()->Save(); + } + + CBITSTREAM; + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PLAYER_REMOVED); + bitStream.Write((LWOMAPID)Game::server->GetZoneID()); + bitStream.Write((LWOINSTANCEID)instanceID); + Game::server->SendToMaster(&bitStream); + } + + if (packet->data[0] != ID_USER_PACKET_ENUM || packet->length < 4) return; + if (static_cast(packet->data[1]) == eConnectionType::SERVER) { + if (static_cast(packet->data[3]) == eServerMessageType::VERSION_CONFIRM) { + AuthPackets::HandleHandshake(Game::server, packet); + } + } if (static_cast(packet->data[1]) != eConnectionType::WORLD) return; @@ -964,7 +967,7 @@ void HandlePacket(Packet* packet) { CheckType::Entity, "Sending GM with a sending player that does not match their own. GM ID: %i", static_cast(messageID) - ); + ); if (isSender) GameMessageHandler::HandleMessage(&dataStream, packet->systemAddress, objectID, messageID); break; @@ -988,7 +991,7 @@ void HandlePacket(Packet* packet) { CheckType::User, "Sending login request with a sending player that does not match their own. Player ID: %llu", playerID - ); + ); if (!valid) return; @@ -1059,23 +1062,23 @@ void HandlePacket(Packet* packet) { if (!levelComponent) return; auto version = levelComponent->GetCharacterVersion(); - switch(version) { - case eCharacterVersion::RELEASE: - // TODO: Implement, super low priority - case eCharacterVersion::LIVE: - Game::logger->Log("WorldServer", "Updating Character Flags"); - c->SetRetroactiveFlags(); - levelComponent->SetCharacterVersion(eCharacterVersion::PLAYER_FACTION_FLAGS); - case eCharacterVersion::PLAYER_FACTION_FLAGS: - Game::logger->Log("WorldServer", "Updating Vault Size"); - player->RetroactiveVaultSize(); - levelComponent->SetCharacterVersion(eCharacterVersion::VAULT_SIZE); - case eCharacterVersion::VAULT_SIZE: - Game::logger->Log("WorldServer", "Updaing Speedbase"); - levelComponent->SetRetroactiveBaseSpeed(); - levelComponent->SetCharacterVersion(eCharacterVersion::UP_TO_DATE); - case eCharacterVersion::UP_TO_DATE: - break; + switch (version) { + case eCharacterVersion::RELEASE: + // TODO: Implement, super low priority + case eCharacterVersion::LIVE: + Game::logger->Log("WorldServer", "Updating Character Flags"); + c->SetRetroactiveFlags(); + levelComponent->SetCharacterVersion(eCharacterVersion::PLAYER_FACTION_FLAGS); + case eCharacterVersion::PLAYER_FACTION_FLAGS: + Game::logger->Log("WorldServer", "Updating Vault Size"); + player->RetroactiveVaultSize(); + levelComponent->SetCharacterVersion(eCharacterVersion::VAULT_SIZE); + case eCharacterVersion::VAULT_SIZE: + Game::logger->Log("WorldServer", "Updaing Speedbase"); + levelComponent->SetRetroactiveBaseSpeed(); + levelComponent->SetCharacterVersion(eCharacterVersion::UP_TO_DATE); + case eCharacterVersion::UP_TO_DATE: + break; } player->GetCharacter()->SetTargetScene("");