diff --git a/server/server_application.hpp b/server/server_application.hpp index 4300c9b..fa39475 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -53,6 +53,10 @@ #include #include +//global utility functions +bool operator==(IPaddress lhs, IPaddress rhs); +bool operator!=(IPaddress lhs, IPaddress rhs); + //The main application class class ServerApplication: public Singleton { public: diff --git a/server/server_connections.cpp b/server/server_connections.cpp new file mode 100644 index 0000000..0f8f2b3 --- /dev/null +++ b/server/server_connections.cpp @@ -0,0 +1,199 @@ +/* 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 + +//------------------------- +//heartbeat system +//------------------------- + +void ServerApplication::HandlePing(ServerPacket* const argPacket) { + ServerPacket newPacket; + newPacket.type = SerialPacketType::PONG; + network.SendTo(argPacket->srcAddress, &newPacket); +} + +void ServerApplication::HandlePong(ServerPacket* const argPacket) { + clientMgr.HandlePong(argPacket); +} + +//------------------------- +//basic connections +//------------------------- + +void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) { + //send the server's data + ServerPacket newPacket; + + newPacket.type = SerialPacketType::BROADCAST_RESPONSE; + strncpy(newPacket.name, config["server.name"].c_str(), PACKET_STRING_SIZE); + newPacket.playerCount = characterMgr.GetLoadedCount(); + newPacket.version = NETWORK_VERSION; + + network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); +} + +void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { + //register the client + int clientIndex = clientMgr.Create(argPacket->srcAddress); + + //send the client their info + ClientPacket newPacket; + newPacket.type = SerialPacketType::JOIN_RESPONSE; + newPacket.clientIndex = clientIndex; + + network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); + + //finished this routine + std::cout << "New join, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; +} + +void ServerApplication::HandleLoginRequest(ClientPacket* const argPacket) { + //get the client data + ClientData* clientData = clientMgr.Get(argPacket->clientIndex); + + if (clientData == nullptr || clientData->GetAddress() != argPacket->srcAddress) { + std::cerr << "Falsified client index detected: " << argPacket->clientIndex << std::endl; + return; + } + + //load the user account + int accountIndex = accountMgr.Load(argPacket->username, argPacket->clientIndex); + + //Cannot load + if (accountIndex < 0) { + //build the message + std::ostringstream msg; + msg << "Account already loaded: " << argPacket->username; + + //build the packet + TextPacket newPacket; + newPacket.type = SerialPacketType::LOGIN_REJECTION; + strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE); + network.SendTo(clientData->GetAddress(), static_cast(&newPacket)); + + //log the error + std::cerr << "Error message sent: " << newPacket.text << std::endl; + return; + } + + //send the client their info + ClientPacket newPacket; + newPacket.type = SerialPacketType::LOGIN_RESPONSE; + newPacket.clientIndex = argPacket->clientIndex; + newPacket.accountIndex = accountIndex; + + network.SendTo(clientData->GetAddress(), static_cast(&newPacket)); + + //finished this routine + std::cout << "New login, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; +} + +void ServerApplication::HandleLogoutRequest(ClientPacket* const argPacket) { + //get the account and client data + AccountData* accountData = accountMgr.Get(argPacket->accountIndex); + if (!accountData) { + return; + } + + ClientData* clientData = clientMgr.Get(accountData->GetClientIndex()); + if (!clientData) { + std::ostringstream msg; + msg << "No client found for an account: " << accountData->GetUsername(); + throw(std::logic_error(msg.str())); + } + + //check for fraud + if (clientData->GetAddress() != argPacket->srcAddress) { + std::cerr << "Falsified logout detected targeting: " << accountData->GetUsername() << std::endl; + return; + } + + //send the logout response + ClientPacket newPacket; + newPacket.type = SerialPacketType::LOGOUT_RESPONSE; + newPacket.accountIndex = argPacket->accountIndex; + + network.SendTo(clientData->GetAddress(), static_cast(&newPacket)); + + //save and unload this accounts characters + characterMgr.UnloadIf([&](std::pair it) -> bool { + if (argPacket->accountIndex == it.second.GetOwner()) { + //pump the unload message to all remaining clients + //TODO: pump character unload + return true; + } + return false; + }); + + //unload this account + accountMgr.Unload(argPacket->accountIndex); + + //finished this routine + std::cout << "New logout, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; +} + +void ServerApplication::HandleDisconnectRequest(ClientPacket* const argPacket) { + //get the client data + ClientData* clientData = clientMgr.Get(argPacket->clientIndex); + if (!clientData) { + return; + } + + //check for fraud + if (clientData->GetAddress() != argPacket->srcAddress) { + std::cerr << "Falsified disconnection detected targeting: " << argPacket->clientIndex << std::endl; + return; + } + + //send the disconnect response + ClientPacket newPacket; + newPacket.type = SerialPacketType::DISCONNECT_RESPONSE; + newPacket.clientIndex = argPacket->clientIndex; + + network.SendTo(clientData->GetAddress(), static_cast(&newPacket)); + + //TODO: need a method for this redundunt chunk of redundant code + //find and unload the accounts associated with this client + accountMgr.UnloadIf([&](std::pair account) -> bool { + if (account.second.GetClientIndex() == argPacket->clientIndex) { + //find and unload the characters associated with this account + characterMgr.UnloadIf([&](std::pair character) -> bool { + if (character.second.GetOwner() == account.first) { + //TODO: pump character unload + return true; + } + return false; + }); + return true; + } + return false; + }); + + //unload this client + clientMgr.Unload(argPacket->clientIndex); + + //finished this routine + std::cout << "New disconnection, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; +} diff --git a/server/server_methods.cpp b/server/server_methods.cpp index f3a21b9..b335e37 100644 --- a/server/server_methods.cpp +++ b/server/server_methods.cpp @@ -25,192 +25,6 @@ #include #include -//------------------------- -//these should've come standard -//------------------------- - -bool operator==(IPaddress lhs, IPaddress rhs) { - return lhs.host == rhs.host && lhs.port == rhs.port; -} - -bool operator!=(IPaddress lhs, IPaddress rhs) { - return !(lhs == rhs); -} - -//------------------------- -//heartbeat system -//------------------------- - -void ServerApplication::HandlePing(ServerPacket* const argPacket) { - ServerPacket newPacket; - newPacket.type = SerialPacketType::PONG; - network.SendTo(argPacket->srcAddress, &newPacket); -} - -void ServerApplication::HandlePong(ServerPacket* const argPacket) { - clientMgr.HandlePong(argPacket); -} - -//------------------------- -//basic connections -//------------------------- - -void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) { - //send the server's data - ServerPacket newPacket; - - newPacket.type = SerialPacketType::BROADCAST_RESPONSE; - strncpy(newPacket.name, config["server.name"].c_str(), PACKET_STRING_SIZE); - newPacket.playerCount = characterMgr.GetLoadedCount(); - newPacket.version = NETWORK_VERSION; - - network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); -} - -void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { - //register the client - int clientIndex = clientMgr.Create(argPacket->srcAddress); - - //send the client their info - ClientPacket newPacket; - newPacket.type = SerialPacketType::JOIN_RESPONSE; - newPacket.clientIndex = clientIndex; - - network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); - - //finished this routine - std::cout << "New join, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; -} - -void ServerApplication::HandleLoginRequest(ClientPacket* const argPacket) { - //get the client data - ClientData* clientData = clientMgr.Get(argPacket->clientIndex); - - if (clientData == nullptr || clientData->GetAddress() != argPacket->srcAddress) { - std::cerr << "Falsified client index detected: " << argPacket->clientIndex << std::endl; - return; - } - - //load the user account - int accountIndex = accountMgr.Load(argPacket->username, argPacket->clientIndex); - - //Cannot load - if (accountIndex < 0) { - //build the message - std::ostringstream msg; - msg << "Account already loaded: " << argPacket->username; - - //build the packet - TextPacket newPacket; - newPacket.type = SerialPacketType::LOGIN_REJECTION; - strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE); - network.SendTo(clientData->GetAddress(), static_cast(&newPacket)); - - //log the error - std::cerr << "Error message sent: " << newPacket.text << std::endl; - return; - } - - //send the client their info - ClientPacket newPacket; - newPacket.type = SerialPacketType::LOGIN_RESPONSE; - newPacket.clientIndex = argPacket->clientIndex; - newPacket.accountIndex = accountIndex; - - network.SendTo(clientData->GetAddress(), static_cast(&newPacket)); - - //finished this routine - std::cout << "New login, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; -} - -void ServerApplication::HandleLogoutRequest(ClientPacket* const argPacket) { - //get the account and client data - AccountData* accountData = accountMgr.Get(argPacket->accountIndex); - if (!accountData) { - return; - } - - ClientData* clientData = clientMgr.Get(accountData->GetClientIndex()); - if (!clientData) { - std::ostringstream msg; - msg << "No client found for an account: " << accountData->GetUsername(); - throw(std::logic_error(msg.str())); - } - - //check for fraud - if (clientData->GetAddress() != argPacket->srcAddress) { - std::cerr << "Falsified logout detected targeting: " << accountData->GetUsername() << std::endl; - return; - } - - //send the logout response - ClientPacket newPacket; - newPacket.type = SerialPacketType::LOGOUT_RESPONSE; - newPacket.accountIndex = argPacket->accountIndex; - - network.SendTo(clientData->GetAddress(), static_cast(&newPacket)); - - //save and unload this accounts characters - characterMgr.UnloadIf([&](std::pair it) -> bool { - if (argPacket->accountIndex == it.second.GetOwner()) { - //pump the unload message to all remaining clients -// PumpCharacterUnload(it.first); - return true; - } - return false; - }); - - //unload this account - accountMgr.Unload(argPacket->accountIndex); - - //finished this routine - std::cout << "New logout, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; -} - -void ServerApplication::HandleDisconnectRequest(ClientPacket* const argPacket) { - //get the client data - ClientData* clientData = clientMgr.Get(argPacket->clientIndex); - if (!clientData) { - return; - } - - //check for fraud - if (clientData->GetAddress() != argPacket->srcAddress) { - std::cerr << "Falsified disconnection detected targeting: " << argPacket->clientIndex << std::endl; - return; - } - - //send the disconnect response - ClientPacket newPacket; - newPacket.type = SerialPacketType::DISCONNECT_RESPONSE; - newPacket.clientIndex = argPacket->clientIndex; - - network.SendTo(clientData->GetAddress(), static_cast(&newPacket)); - - //TODO: need a method for this redundunt chunk of redundant code - //find and unload the accounts associated with this client - accountMgr.UnloadIf([&](std::pair account) -> bool { - if (account.second.GetClientIndex() == argPacket->clientIndex) { - //find and unload the characters associated with this account - characterMgr.UnloadIf([&](std::pair character) -> bool { - if (character.second.GetOwner() == account.first) { -// PumpCharacterUnload(character.first); - return true; - } - return false; - }); - return true; - } - return false; - }); - - //unload this client - clientMgr.Unload(argPacket->clientIndex); - - //finished this routine - std::cout << "New disconnection, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; -} - //------------------------- //server commands //------------------------- @@ -261,9 +75,9 @@ void ServerApplication::HandleShutdownRequest(ClientPacket* const argPacket) { running = false; //disconnect all clients -// ClientPacket newPacket; -// newPacket.type = SerialPacketType::DISCONNECT_FORCED; -// PumpPacket(&newPacket); + //ClientPacket newPacket; + //newPacket.type = SerialPacketType::DISCONNECT_FORCED; + //PumpPacket(&newPacket); //finished this routine std::cout << "Shutdown signal accepted" << std::endl; diff --git a/server/server_util.cpp b/server/server_util.cpp new file mode 100644 index 0000000..b0defb8 --- /dev/null +++ b/server/server_util.cpp @@ -0,0 +1,34 @@ +/* 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" + +//------------------------- +//these should've come standard +//------------------------- + +bool operator==(IPaddress lhs, IPaddress rhs) { + return lhs.host == rhs.host && lhs.port == rhs.port; +} + +bool operator!=(IPaddress lhs, IPaddress rhs) { + return !(lhs == rhs); +} \ No newline at end of file