diff --git a/server/server_application.hpp b/server/server_application.hpp index fa39475..723899b 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -88,7 +88,7 @@ private: void HandleDisconnectRequest(ClientPacket* const); //server commands -// void HandleDisconnectForced(ClientPacket* const); + void HandleDisconnectForced(ClientPacket* const); void HandleShutdownRequest(ClientPacket* const); //data management @@ -101,13 +101,12 @@ private: void HandleCharacterLoad(CharacterPacket* const); void HandleCharacterUnload(CharacterPacket* const); - //mismanagement -// void HandleSynchronize(ClientPacket* const); + //utility methods + void PumpPacket(SerialPacket* const); + void PumpPacketProximity(SerialPacket* const, int roomIndex, int x, int y, int radius); //utility methods - //TODO: a function that only sends to characters in a certain proximity // void CleanupLostConnection(int index); -// void PumpPacket(SerialPacket* const); // void PumpCharacterUnload(int uid); // void CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex); diff --git a/server/server_connections.cpp b/server/server_connections.cpp index 0f8f2b3..b9ca988 100644 --- a/server/server_connections.cpp +++ b/server/server_connections.cpp @@ -197,3 +197,7 @@ void ServerApplication::HandleDisconnectRequest(ClientPacket* const argPacket) { //finished this routine std::cout << "New disconnection, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; } + +void ServerApplication::HandleDisconnectForced(ClientPacket* const argPacket) { + //TODO: HandleDisconnectForced +} \ No newline at end of file diff --git a/server/server_data.cpp b/server/server_data.cpp new file mode 100644 index 0000000..85ba3ae --- /dev/null +++ b/server/server_data.cpp @@ -0,0 +1,197 @@ +/* Copyright: (c) Kayne Ruse 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "server_application.hpp" + +#include +#include + +//------------------------- +//General data management +//------------------------- + +//TODO: Queries + +void ServerApplication::SaveServerState() { + //TODO: SaveServerState +} + +//------------------------- +//Map management +//------------------------- + +void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) { + //get the region object, send a rejection on error + RoomData* room = roomMgr.Get(argPacket->roomIndex); + if (!room) { + //build the error message + std::ostringstream msg; + msg << "Failed to find Region (" << argPacket->roomIndex << "," << argPacket->x << "," << argPacket->y << "); "; + msg << "Room " << argPacket->roomIndex << " does not exist"; + + //build the packet + TextPacket newPacket; + newPacket.type = SerialPacketType::REGION_REJECTION; + strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE); + network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); + + //log the error + std::cerr << "Error message sent: " << newPacket.text << std::endl; + return; + } + Region* region = room->GetPager()->GetRegion(argPacket->x, argPacket->y); + + //send the content + RegionPacket newPacket; + + newPacket.type = SerialPacketType::REGION_CONTENT; + newPacket.roomIndex = argPacket->roomIndex; + newPacket.x = argPacket->x; + newPacket.y = argPacket->y; + newPacket.region = region; + + network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); +} + +//------------------------- +//Character Management +//------------------------- + +void ServerApplication::HandleCharacterCreate(CharacterPacket* const argPacket) { + int characterIndex = characterMgr.Create(argPacket->accountIndex, argPacket->handle, argPacket->avatar); + + if (characterIndex < 0) { + //build the error message + std::ostringstream msg; + msg << "Character already exists: " << argPacket->handle; + + //build & send the packet + TextPacket newPacket; + newPacket.type = SerialPacketType::CHARACTER_REJECTION; + strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE); + network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); + + return; + } + + //send this character to the player + CharacterPacket newPacket; + newPacket.type = SerialPacketType::CHARACTER_CREATE; + //TODO: pump character load +} + +void ServerApplication::HandleCharacterDelete(CharacterPacket* const argPacket) { + //get the user's data + AccountData* accountData = accountMgr.Get(argPacket->accountIndex); + if (!accountData) { + return; + } + ClientData* clientData = clientMgr.Get(accountData->GetClientIndex()); + if (!clientData) { + return; + } + + //check for fraud + if (clientData->GetAddress() != argPacket->srcAddress) { + std::cerr << "Falsified character deletion detected targeting: " << argPacket->handle << std::endl; + return; + } + + //load the character into memory + int characterIndex = characterMgr.Load(argPacket->accountIndex, argPacket->handle, argPacket->avatar); + + if (characterIndex < 0) { + //build the error message + std::ostringstream msg; + msg << "Cannot delete this character"; + + //build & send the packet + TextPacket newPacket; + newPacket.type = SerialPacketType::CHARACTER_REJECTION; + strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE); + network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); + + return; + } + + //delete the character + characterMgr.Delete(characterIndex); + + //TODO: pump character unload +} + +void ServerApplication::HandleCharacterLoad(CharacterPacket* const argPacket) { + int characterIndex = characterMgr.Load(argPacket->accountIndex, argPacket->handle, argPacket->avatar); + + if (characterIndex < 0) { + //build the error message + std::ostringstream msg; + if (characterIndex == -1) { + msg << "Character already loaded: "; + } + if (characterIndex == -1) { + msg << "Character name is taken: "; + } + msg << argPacket->handle; + + //build & send the packet + TextPacket newPacket; + newPacket.type = SerialPacketType::CHARACTER_REJECTION; + strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE); + network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); + + return; + } + + //send this character to the player + CharacterPacket newPacket; + newPacket.type = SerialPacketType::CHARACTER_CREATE; + //TODO: pump character load +} + +void ServerApplication::HandleCharacterUnload(CharacterPacket* const argPacket) { + //get the entries + CharacterData* characterData = characterMgr.Get(argPacket->characterIndex); + if (!characterData) { + return; + } + + AccountData* accountData = accountMgr.Get(characterData->GetOwner()); + if (!accountData) { + return; //TODO: logic_error + } + + ClientData* clientData = clientMgr.Get(accountData->GetClientIndex()); + if (!clientData) { + return; //TODO: logic_error + } + + //check for fraud + if (clientData->GetAddress() != argPacket->srcAddress) { + std::cerr << "Falsified character unload detected targeting: uid(" << argPacket->characterIndex << ")" << std::endl; + return; + } + + //unload the character + characterMgr.Unload(argPacket->characterIndex); + + //TODO: pump character unload +} \ No newline at end of file diff --git a/server/server_methods.cpp b/server/server_methods.cpp index b335e37..87de59a 100644 --- a/server/server_methods.cpp +++ b/server/server_methods.cpp @@ -29,10 +29,6 @@ //server commands //------------------------- -//void ServerApplication::HandleDisconnectForced(ClientPacket* const argPacket) { -// //TODO -//} - void ServerApplication::HandleShutdownRequest(ClientPacket* const argPacket) { //get the account and client data AccountData* accountData = accountMgr.Get(argPacket->accountIndex); @@ -75,176 +71,15 @@ void ServerApplication::HandleShutdownRequest(ClientPacket* const argPacket) { running = false; //disconnect all clients - //ClientPacket newPacket; - //newPacket.type = SerialPacketType::DISCONNECT_FORCED; - //PumpPacket(&newPacket); + TextPacket newPacket; + newPacket.type = SerialPacketType::DISCONNECT_FORCED; + strncpy(newPacket.text, "Server shutdown", PACKET_STRING_SIZE); + PumpPacket(&newPacket); //finished this routine std::cout << "Shutdown signal accepted" << std::endl; } -//------------------------- -//data management -//------------------------- - -void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) { - //get the region object, send a rejection on error - RoomData* room = roomMgr.Get(argPacket->roomIndex); - if (!room) { - //build the error message - std::ostringstream msg; - msg << "Failed to find Region (" << argPacket->roomIndex << "," << argPacket->x << "," << argPacket->y << "); "; - msg << "Room " << argPacket->roomIndex << " does not exist"; - - //build the packet - TextPacket newPacket; - newPacket.type = SerialPacketType::REGION_REJECTION; - strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE); - network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); - - //log the error - std::cerr << "Error message sent: " << newPacket.text << std::endl; - return; - } - Region* region = room->GetPager()->GetRegion(argPacket->x, argPacket->y); - - //send the content - RegionPacket newPacket; - - newPacket.type = SerialPacketType::REGION_CONTENT; - newPacket.roomIndex = argPacket->roomIndex; - newPacket.x = argPacket->x; - newPacket.y = argPacket->y; - newPacket.region = region; - - network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); -} - -//------------------------- -//Character Management -//------------------------- - -void ServerApplication::HandleCharacterCreate(CharacterPacket* const argPacket) { - int characterIndex = characterMgr.Create(argPacket->accountIndex, argPacket->handle, argPacket->avatar); - - if (characterIndex < 0) { - //build the error message - std::ostringstream msg; - msg << "Character already exists: " << argPacket->handle; - - //build & send the packet - TextPacket newPacket; - newPacket.type = SerialPacketType::CHARACTER_REJECTION; - strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE); - network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); - - return; - } - - //send this character to the player - CharacterPacket newPacket; - newPacket.type = SerialPacketType::CHARACTER_CREATE; - //TODO: pump character load -} - -void ServerApplication::HandleCharacterDelete(CharacterPacket* const argPacket) { - //get the user's data - AccountData* accountData = accountMgr.Get(argPacket->accountIndex); - if (!accountData) { - return; - } - ClientData* clientData = clientMgr.Get(accountData->GetClientIndex()); - if (!clientData) { - return; - } - - //check for fraud - if (clientData->GetAddress() != argPacket->srcAddress) { - std::cerr << "Falsified character deletion detected targeting: " << argPacket->handle << std::endl; - return; - } - - //load the character into memory - int characterIndex = characterMgr.Load(argPacket->accountIndex, argPacket->handle, argPacket->avatar); - - if (characterIndex < 0) { - //build the error message - std::ostringstream msg; - msg << "Cannot delete this character"; - - //build & send the packet - TextPacket newPacket; - newPacket.type = SerialPacketType::CHARACTER_REJECTION; - strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE); - network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); - - return; - } - - //delete the character - characterMgr.Delete(characterIndex); - - //TODO: pump character unload -} - -void ServerApplication::HandleCharacterLoad(CharacterPacket* const argPacket) { - int characterIndex = characterMgr.Load(argPacket->accountIndex, argPacket->handle, argPacket->avatar); - - if (characterIndex < 0) { - //build the error message - std::ostringstream msg; - if (characterIndex == -1) { - msg << "Character already loaded: "; - } - if (characterIndex == -1) { - msg << "Character name is taken: "; - } - msg << argPacket->handle; - - //build & send the packet - TextPacket newPacket; - newPacket.type = SerialPacketType::CHARACTER_REJECTION; - strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE); - network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); - - return; - } - - //send this character to the player - CharacterPacket newPacket; - newPacket.type = SerialPacketType::CHARACTER_CREATE; - //TODO: pump character load -} - -void ServerApplication::HandleCharacterUnload(CharacterPacket* const argPacket) { - //get the entries - CharacterData* characterData = characterMgr.Get(argPacket->characterIndex); - if (!characterData) { - return; - } - - AccountData* accountData = accountMgr.Get(characterData->GetOwner()); - if (!accountData) { - return; //TODO: logic_error - } - - ClientData* clientData = clientMgr.Get(accountData->GetClientIndex()); - if (!clientData) { - return; //TODO: logic_error - } - - //check for fraud - if (clientData->GetAddress() != argPacket->srcAddress) { - std::cerr << "Falsified character unload detected targeting: uid(" << argPacket->characterIndex << ")" << std::endl; - return; - } - - //unload the character - characterMgr.Unload(argPacket->characterIndex); - - //TODO: pump character unload -} - /* //SET: entities @@ -334,16 +169,6 @@ void ServerApplication::CleanupLostConnection(int clientIndex) { std::cout << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; } -//SET: utility -//TODO: a function that only sends to characters in a certain proximity - -//SET: utility -void ServerApplication::PumpPacket(SerialPacket* const argPacket) { - for (auto& it : *clientMgr.GetContainer()) { - network.SendTo(it.second.GetAddress(), argPacket); - } -} - //SET: utility/delete void ServerApplication::PumpCharacterUnload(int uid) { //delete the client-side character(s) diff --git a/server/server_util.cpp b/server/server_util.cpp index b0defb8..4c8a01b 100644 --- a/server/server_util.cpp +++ b/server/server_util.cpp @@ -31,4 +31,23 @@ bool operator==(IPaddress lhs, IPaddress rhs) { bool operator!=(IPaddress lhs, IPaddress rhs) { return !(lhs == rhs); -} \ No newline at end of file +} + +//------------------------- +//Packet pumps +//------------------------- + +void ServerApplication::PumpPacket(SerialPacket* const argPacket) { + for (auto& it : *clientMgr.GetContainer()) { + network.SendTo(it.second.GetAddress(), argPacket); + } +} + +void ServerApplication::PumpPacketProximity(SerialPacket* const argPacket, int roomIndex, int x, int y, int radius) { + //TODO: PumpPacketProximity + //for position (roomIndex, x, y), find all characters within that distance + //find that character's owner + //find that account's client + //send the packet to that client + //NOTE: this is perhaps too complex; I write it if I need it +}