diff --git a/server/network_api.cpp b/server/network_api.cpp index f78bd90..db385e4 100644 --- a/server/network_api.cpp +++ b/server/network_api.cpp @@ -33,5 +33,4 @@ static const luaL_Reg networkLib[] = { LUAMOD_API int openNetworkAPI(lua_State* L) { luaL_newlib(L, networkLib); return 1; - } \ No newline at end of file diff --git a/server/server_application.hpp b/server/server_application.hpp index d53ed32..3ba2b39 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -38,6 +38,9 @@ #include "serial_packet.hpp" #include "singleton.hpp" +//server utilities +#include "server_utilities.hpp" + //APIs #include "lua.hpp" #include "sqlite3.h" @@ -111,13 +114,7 @@ private: void hTextWhisper(TextPacket* const); //utility methods - void PumpPacket(SerialPacket* const); - void PumpPacketProximity(SerialPacket* const argPacket, int roomIndex, Vector2 position, int distance); - void CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex); void SaveServerState(); - void FullClientUnload(int index); - void FullAccountUnload(int index); - void FullCharacterUnload(int index); //APIs and utilities sqlite3* database = nullptr; diff --git a/server/server_character_methods.cpp b/server/server_character_methods.cpp index 38127e1..022095b 100644 --- a/server/server_character_methods.cpp +++ b/server/server_character_methods.cpp @@ -46,13 +46,14 @@ void ServerApplication::hCharacterCreate(CharacterPacket* const argPacket) { } //push to the rooms - roomMgr.PushCharacter(characterMgr.Get(characterIndex)); + CharacterData* characterData = characterMgr.Get(characterIndex); + roomMgr.PushCharacter(characterData); //pump this character to all clients CharacterPacket newPacket; - CopyCharacterToPacket(&newPacket, characterIndex); + copyCharacterToPacket(&newPacket, characterIndex); newPacket.type = SerialPacketType::CHARACTER_CREATE; - PumpPacket(&newPacket); + pumpPacketProximity(&newPacket, characterData->GetRoomIndex()); } void ServerApplication::hCharacterDelete(CharacterPacket* const argPacket) { @@ -90,16 +91,17 @@ void ServerApplication::hCharacterDelete(CharacterPacket* const argPacket) { } //pop from the rooms - roomMgr.PopCharacter(characterMgr.Get(characterIndex)); - - //delete the character - characterMgr.Delete(characterIndex); + CharacterData* characterData = characterMgr.Get(characterIndex); + roomMgr.PopCharacter(characterData); //pump character delete CharacterPacket newPacket; newPacket.type = SerialPacketType::CHARACTER_DELETE; newPacket.characterIndex = characterIndex; - PumpPacket(static_cast(&newPacket)); + pumpPacketProximity(static_cast(&newPacket), characterData->GetRoomIndex()); + + //delete the character + characterMgr.Delete(characterIndex); } void ServerApplication::hCharacterLoad(CharacterPacket* const argPacket) { @@ -126,13 +128,14 @@ void ServerApplication::hCharacterLoad(CharacterPacket* const argPacket) { } //push to the rooms - roomMgr.PushCharacter(characterMgr.Get(characterIndex)); + CharacterData* characterData = characterMgr.Get(characterIndex); + roomMgr.PushCharacter(characterData); //pump this character to all clients CharacterPacket newPacket; - CopyCharacterToPacket(&newPacket, characterIndex); + copyCharacterToPacket(&newPacket, characterIndex); newPacket.type = SerialPacketType::CHARACTER_CREATE; - PumpPacket(&newPacket); + pumpPacketProximity(&newPacket, characterData->GetRoomIndex()); } void ServerApplication::hCharacterUnload(CharacterPacket* const argPacket) { @@ -161,14 +164,14 @@ void ServerApplication::hCharacterUnload(CharacterPacket* const argPacket) { //pop from the rooms roomMgr.PopCharacter(characterData); - //unload the character - characterMgr.Unload(argPacket->characterIndex); - //pump character delete CharacterPacket newPacket; newPacket.type = SerialPacketType::CHARACTER_DELETE; newPacket.characterIndex = argPacket->characterIndex; - PumpPacket(static_cast(&newPacket)); + pumpPacketProximity(static_cast(&newPacket), characterData->GetRoomIndex()); + + //unload the character + characterMgr.Unload(argPacket->characterIndex); } //------------------------- @@ -206,9 +209,9 @@ void ServerApplication::hCharacterMovement(CharacterPacket* const argPacket) { if (characterData->GetRoomIndex() != argPacket->roomIndex) { //delete from the old room CharacterPacket newPacket; - CopyCharacterToPacket(&newPacket, argPacket->characterIndex); + copyCharacterToPacket(&newPacket, argPacket->characterIndex); newPacket.type = SerialPacketType::CHARACTER_DELETE; - PumpPacketProximity(&newPacket, characterData->GetRoomIndex(), characterData->GetOrigin(), -1); + pumpPacketProximity(&newPacket, characterData->GetRoomIndex()); //move the character between rooms roomMgr.PopCharacter(characterData); @@ -216,9 +219,9 @@ void ServerApplication::hCharacterMovement(CharacterPacket* const argPacket) { roomMgr.PushCharacter(characterData); //create in the new room - CopyCharacterToPacket(&newPacket, argPacket->characterIndex); + copyCharacterToPacket(&newPacket, argPacket->characterIndex); newPacket.type = SerialPacketType::CHARACTER_CREATE; - PumpPacketProximity(&newPacket, characterData->GetRoomIndex(), characterData->GetOrigin(), -1); + pumpPacketProximity(&newPacket, characterData->GetRoomIndex()); } //if not moving between rooms else { @@ -228,9 +231,9 @@ void ServerApplication::hCharacterMovement(CharacterPacket* const argPacket) { //update the clients CharacterPacket newPacket; - CopyCharacterToPacket(&newPacket, argPacket->characterIndex); + copyCharacterToPacket(&newPacket, argPacket->characterIndex); newPacket.type = SerialPacketType::CHARACTER_MOVEMENT; - PumpPacketProximity(&newPacket, characterData->GetRoomIndex(), characterData->GetOrigin(), -1); + pumpPacketProximity(&newPacket, characterData->GetRoomIndex()); } } diff --git a/server/server_connections.cpp b/server/server_connections.cpp index 36c5bf0..c35fbaa 100644 --- a/server/server_connections.cpp +++ b/server/server_connections.cpp @@ -138,7 +138,7 @@ void ServerApplication::hLogoutRequest(ClientPacket* const argPacket) { network.SendTo(clientData->GetAddress(), static_cast(&newPacket)); //save and unload this account and it's characters - FullAccountUnload(argPacket->accountIndex); + fullAccountUnload(argPacket->accountIndex); //finished this routine std::cout << "New logout, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; @@ -165,7 +165,7 @@ void ServerApplication::hDisconnectRequest(ClientPacket* const argPacket) { network.SendTo(clientData->GetAddress(), static_cast(&newPacket)); //unload the client, it's accounts, and their characters - FullClientUnload(argPacket->clientIndex); + fullClientUnload(argPacket->clientIndex); //finished this routine std::cout << "New disconnection, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; diff --git a/server/server_data_queries.cpp b/server/server_data_queries.cpp index 1019223..7b04ad0 100644 --- a/server/server_data_queries.cpp +++ b/server/server_data_queries.cpp @@ -69,7 +69,7 @@ void ServerApplication::hQueryCharacterExists(CharacterPacket* const argPacket) if (argPacket->roomIndex != -1 && it.second.GetRoomIndex() != argPacket->roomIndex) { continue; } - CopyCharacterToPacket(&newPacket, it.first); + copyCharacterToPacket(&newPacket, it.first); newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS; network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); } diff --git a/server/server_logic.cpp b/server/server_logic.cpp index 32bb812..8a0bd24 100644 --- a/server/server_logic.cpp +++ b/server/server_logic.cpp @@ -188,7 +188,7 @@ void ServerApplication::Proc() { //Check client connections std::list disconnections = clientMgr.CheckConnections(); for(auto const& it : disconnections) { - FullClientUnload(it); + fullClientUnload(it); std::cerr << "Client dropped: " << it << std::endl; } diff --git a/server/server_methods.cpp b/server/server_methods.cpp index d440153..3bcfc96 100644 --- a/server/server_methods.cpp +++ b/server/server_methods.cpp @@ -78,7 +78,7 @@ void ServerApplication::hAdminShutdownRequest(ClientPacket* const argPacket) { TextPacket newPacket; newPacket.type = SerialPacketType::ADMIN_DISCONNECT_FORCED; strncpy(newPacket.text, "Server shutdown", PACKET_STRING_SIZE); - PumpPacket(&newPacket); + pumpPacket(&newPacket); //finished this routine std::cout << "Shutdown signal accepted" << std::endl; @@ -87,118 +87,3 @@ void ServerApplication::hAdminShutdownRequest(ClientPacket* const argPacket) { void ServerApplication::SaveServerState() { //TODO: (9) empty } - -//------------------------- -//full unload methods -//------------------------- - -void ServerApplication::FullClientUnload(int index) { - clientMgr.UnloadIf([&](std::pair client) -> bool { - //skip the wrong clients - if (client.first != index) { - return false; - } - - //unload associated accounts - for (std::map::iterator it = accountMgr.GetContainer()->begin(); it != accountMgr.GetContainer()->end(); /* EMPTY */) { - if (it->second.GetClientIndex() == index) { - FullAccountUnload(it->first); - it = accountMgr.GetContainer()->begin(); - } - else { - ++it; - } - } - - //unload this client - return true; - }); -} - -void ServerApplication::FullAccountUnload(int index) { - accountMgr.UnloadIf([&](std::pair account) -> bool { - //skip the wrong accounts - if (account.first != index) { - return false; - } - - //unload associated characters - for (std::map::iterator it = characterMgr.GetContainer()->begin(); it != characterMgr.GetContainer()->end(); /* EMPTY */) { - if (it->second.GetOwner() == index) { - FullCharacterUnload(it->first); - it = characterMgr.GetContainer()->begin(); - } - else { - ++it; - } - } - - //unload this account - return true; - }); -} - -void ServerApplication::FullCharacterUnload(int index) { - characterMgr.UnloadIf([&](std::pair character) -> bool { - //skip the wrong characters - if (character.first != index) { - return false; - } - - //pop from the rooms - roomMgr.PopCharacter(&character.second); - - //pump character unload - CharacterPacket newPacket; - newPacket.type = SerialPacketType::CHARACTER_DELETE; - newPacket.characterIndex = character.first; - //NOTE: more character info as needed - - PumpPacket(&newPacket); - - //unload this character - return true; - }); -} - -//------------------------- -//utility methods -//------------------------- - -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, Vector2 position, int distance) { - RoomData* room = roomMgr.Get(roomIndex); - - if (!room) { - throw(std::runtime_error("Failed to pump to a non-existant room")); - } - - for (auto& character : *room->GetCharacterList()) { - if (distance == -1 || (character->GetOrigin() - position).Length() <= distance) { - AccountData* account = accountMgr.Get(character->GetOwner()); - ClientData* client = clientMgr.Get(account->GetClientIndex()); - network.SendTo(client->GetAddress(), argPacket); - } - } -} - -void ServerApplication::CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex) { - CharacterData* character = characterMgr.Get(characterIndex); - if (!character) { - throw(std::runtime_error("Failed to copy a character to a packet")); - } - - //NOTE: keep this up to date when the character changes - packet->characterIndex = characterIndex; - strncpy(packet->handle, character->GetHandle().c_str(), PACKET_STRING_SIZE); - strncpy(packet->avatar, character->GetAvatar().c_str(), PACKET_STRING_SIZE); - packet->accountIndex = character->GetOwner(); - packet->roomIndex = character->GetRoomIndex(); - packet->origin = character->GetOrigin(); - packet->motion = character->GetMotion(); -} diff --git a/server/server_utilities/makefile b/server/server_utilities/makefile index 8d12afe..879e339 100644 --- a/server/server_utilities/makefile +++ b/server/server_utilities/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. +INCLUDES+=. ../accounts ../characters ../clients ../entities ../monsters ../rooms ../waypoints ../../common/gameplay ../../common/map ../../common/network ../../common/network/packet_types ../../common/utilities LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/server/server_utilities/server_utilities.cpp b/server/server_utilities/server_utilities.cpp new file mode 100644 index 0000000..58b81ee --- /dev/null +++ b/server/server_utilities/server_utilities.cpp @@ -0,0 +1,151 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * 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_utilities.hpp" + +#include "account_manager.hpp" +#include "character_manager.hpp" +#include "client_manager.hpp" +#include "room_manager.hpp" +#include "udp_network_utility.hpp" + +//------------------------- +//manager unload functions +//------------------------- + +void fullClientUnload(int index) { + ClientManager::GetSingleton().UnloadIf([index](std::pair clientPair) -> bool { + //skip the wrong clients + if (clientPair.first != index) { + return false; + } + + AccountManager& accountMgr = AccountManager::GetSingleton(); + + //unload associated accounts + for (std::map::iterator it = accountMgr.GetContainer()->begin(); it != accountMgr.GetContainer()->end(); /* EMPTY */) { + if (it->second.GetClientIndex() == index) { + fullAccountUnload(it->first); + it = accountMgr.GetContainer()->begin(); + } + else { + ++it; + } + } + + //unload this client + return true; + }); +} + +void fullAccountUnload(int index) { + AccountManager::GetSingleton().UnloadIf([index](std::pair accountPair) -> bool { + //skip the wrong accounts + if (accountPair.first != index) { + return false; + } + + CharacterManager& characterMgr = CharacterManager::GetSingleton(); + + //unload associated characters + for (std::map::iterator it = characterMgr.GetContainer()->begin(); it != characterMgr.GetContainer()->end(); /* EMPTY */) { + if (it->second.GetOwner() == index) { + fullCharacterUnload(it->first); + it = characterMgr.GetContainer()->begin(); + } + else { + ++it; + } + } + + //unload this account + return true; + }); +} + +void fullCharacterUnload(int index) { + CharacterManager::GetSingleton().UnloadIf([index](std::pair characterPair) -> bool { + //skip the wrong characters + if (characterPair.first != index) { + return false; + } + + //pop from the rooms + RoomManager::GetSingleton().PopCharacter(&characterPair.second); + + //pump character unload + CharacterPacket newPacket; + newPacket.type = SerialPacketType::CHARACTER_DELETE; + newPacket.characterIndex = characterPair.first; + //NOTE: more character info as needed + + //TODO: proximity? + pumpPacketProximity(&newPacket, characterPair.second.GetRoomIndex()); + + //unload this character + return true; + }); +} + +//------------------------- +//utility functions +//------------------------- + +void pumpPacket(SerialPacket* const argPacket) { + for (auto& it : *ClientManager::GetSingleton().GetContainer()) { + UDPNetworkUtility::GetSingleton().SendTo(it.second.GetAddress(), argPacket); + } +} + +void pumpPacketProximity(SerialPacket* const argPacket, int roomIndex, Vector2 position, int distance) { + RoomData* roomData = RoomManager::GetSingleton().Get(roomIndex); + + if (!roomData) { + throw(std::runtime_error("Failed to pump to a non-existant room")); + } + + AccountData* accountData = nullptr; + ClientData* clientData = nullptr; + + for (auto& characterIt : *roomData->GetCharacterList()) { + if (distance == -1 || (characterIt->GetOrigin() - position).Length() <= distance) { + accountData = AccountManager::GetSingleton().Get(characterIt->GetOwner()); + clientData = ClientManager::GetSingleton().Get(accountData->GetClientIndex()); + UDPNetworkUtility::GetSingleton().SendTo(clientData->GetAddress(), argPacket); + } + } +} + +void copyCharacterToPacket(CharacterPacket* const packet, int characterIndex) { + CharacterData* characterData = CharacterManager::GetSingleton().Get(characterIndex); + if (!characterData) { + throw(std::runtime_error("Failed to copy a character to a packet")); + } + + //NOTE: keep this up to date when the character changes + packet->characterIndex = characterIndex; + strncpy(packet->handle, characterData->GetHandle().c_str(), PACKET_STRING_SIZE); + strncpy(packet->avatar, characterData->GetAvatar().c_str(), PACKET_STRING_SIZE); + packet->accountIndex = characterData->GetOwner(); + packet->roomIndex = characterData->GetRoomIndex(); + packet->origin = characterData->GetOrigin(); + packet->motion = characterData->GetMotion(); +} diff --git a/server/server_utilities/server_utilities.hpp b/server/server_utilities/server_utilities.hpp new file mode 100644 index 0000000..7da41c6 --- /dev/null +++ b/server/server_utilities/server_utilities.hpp @@ -0,0 +1,35 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * 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. +*/ +#ifndef SERVERUTILITIES_HPP_ +#define SERVERUTILITIES_HPP_ + +#include "serial_packet.hpp" +#include "vector2.hpp" + +void fullClientUnload(int index); +void fullAccountUnload(int index); +void fullCharacterUnload(int index); +void pumpPacket(SerialPacket* const argPacket); +void pumpPacketProximity(SerialPacket* const argPacket, int roomIndex, Vector2 position = {0, 0}, int distance = -1); +void copyCharacterToPacket(CharacterPacket* const packet, int characterIndex); + +#endif \ No newline at end of file