From a1c20959fefea45d33a64559c5df6a1c2490f5d9 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 9 Nov 2014 23:15:09 +1100 Subject: [PATCH] The server builds using the new packet types; incomplete Most of this was achieved by dummying out calls in HandlePacket(), so the server's actual logic is incomplete. --- common/network/serial_packet_type.hpp | 39 ++++---- common/network/serial_utility.cpp | 52 +++++++---- server/rooms/room_system_api.cpp | 2 +- server/server_application.hpp | 11 +++ server/server_logic.cpp | 130 ++++++++++++++++++-------- server/server_methods.cpp | 64 +++++++------ 6 files changed, 193 insertions(+), 105 deletions(-) diff --git a/common/network/serial_packet_type.hpp b/common/network/serial_packet_type.hpp index b93b51f..e6637af 100644 --- a/common/network/serial_packet_type.hpp +++ b/common/network/serial_packet_type.hpp @@ -27,6 +27,7 @@ * valid data, but it will still be carried in that packet's format. */ +//TODO: This needs to be smoothed out enum class SerialPacketType { //default: there is something wrong NONE = 0, @@ -57,6 +58,14 @@ enum class SerialPacketType { DISCONNECT_REQUEST, DISCONNECT_FORCED, + //load the account + LOGIN_REQUEST, + LOGIN_RESPONSE, + + //unload the account + LOGOUT_REQUEST, + LOGOUT_RESPONSE, + //shut down the server SHUTDOWN_REQUEST, @@ -66,7 +75,7 @@ enum class SerialPacketType { //------------------------- //map data - REGION_REQUEST, + REGION_REQUEST, //NOTE: technically a query REGION_CONTENT, //------------------------- @@ -78,25 +87,23 @@ enum class SerialPacketType { // statistics //------------------------- - //all stats - CHARACTER_STATS_REQUEST, - CHARACTER_STATS_RESPONSE, - //character management - //NOTE: The server sends create & delete messages to the clients, but the clients... don't? - CHARACTER_CREATE - CHARACTER_DELETE - CHARACTER_LOAD - CHARACTER_UNLOAD + CHARACTER_CREATE, + CHARACTER_DELETE, + CHARACTER_LOAD, + CHARACTER_UNLOAD, //find out info from the server - CHARACTER_QUERY_EXISTS - CHARACTER_QUERY_LOCATION + QUERY_CHARACTER_EXISTS, + QUERY_CHARACTER_STATS, + QUERY_CHARACTER_LOCATION, //set the info in the server - CHARACTER_SET_ROOM - CHARACTER_SET_ORIGIN - CHARACTER_SET_MOTION + CHARACTER_SET_ROOM, + CHARACTER_SET_ORIGIN, + CHARACTER_SET_MOTION, + + //TODO: enemy management //------------------------- //TextPacket @@ -107,9 +114,9 @@ enum class SerialPacketType { TEXT_BROADCAST, //rejection/error messages - SHUTDOWN_REJECTION, JOIN_REJECTION, CHARACTER_REJECTION, + SHUTDOWN_REJECTION, //------------------------- //not used diff --git a/common/network/serial_utility.cpp b/common/network/serial_utility.cpp index 6572887..fe2e87e 100644 --- a/common/network/serial_utility.cpp +++ b/common/network/serial_utility.cpp @@ -54,26 +54,35 @@ void serializePacket(void* buffer, SerialPacketBase* packet) { break; case SerialPacketType::JOIN_REQUEST: case SerialPacketType::JOIN_RESPONSE: - case SerialPacketType::SYNCHRONIZE: - case SerialPacketType::DISCONNECT: - case SerialPacketType::SHUTDOWN: + case SerialPacketType::DISCONNECT_REQUEST: + case SerialPacketType::DISCONNECT_FORCED: + case SerialPacketType::LOGIN_REQUEST: + case SerialPacketType::LOGIN_RESPONSE: + case SerialPacketType::LOGOUT_REQUEST: + case SerialPacketType::LOGOUT_RESPONSE: + case SerialPacketType::SHUTDOWN_REQUEST: serializeClient(buffer, static_cast(packet)); break; case SerialPacketType::REGION_REQUEST: case SerialPacketType::REGION_CONTENT: serializeRegion(buffer, static_cast(packet)); break; - case SerialPacketType::CHARACTER_NEW: + case SerialPacketType::CHARACTER_CREATE: case SerialPacketType::CHARACTER_DELETE: - case SerialPacketType::CHARACTER_UPDATE: - case SerialPacketType::CHARACTER_STATS_REQUEST: - case SerialPacketType::CHARACTER_STATS_RESPONSE: + case SerialPacketType::CHARACTER_LOAD: + case SerialPacketType::CHARACTER_UNLOAD: + case SerialPacketType::QUERY_CHARACTER_EXISTS: + case SerialPacketType::QUERY_CHARACTER_STATS: + case SerialPacketType::QUERY_CHARACTER_LOCATION: + case SerialPacketType::CHARACTER_SET_ROOM: + case SerialPacketType::CHARACTER_SET_ORIGIN: + case SerialPacketType::CHARACTER_SET_MOTION: serializeCharacter(buffer, static_cast(packet)); break; case SerialPacketType::TEXT_BROADCAST: case SerialPacketType::JOIN_REJECTION: - case SerialPacketType::SHUTDOWN_REJECTION: case SerialPacketType::CHARACTER_REJECTION: + case SerialPacketType::SHUTDOWN_REJECTION: serializeText(buffer, static_cast(packet)); break; } @@ -84,7 +93,7 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) { SerialPacketType type; memcpy(&type, buffer, sizeof(SerialPacketType)); - switch(type) { + switch(packet->type) { case SerialPacketType::PING: case SerialPacketType::PONG: case SerialPacketType::BROADCAST_REQUEST: @@ -93,26 +102,35 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) { break; case SerialPacketType::JOIN_REQUEST: case SerialPacketType::JOIN_RESPONSE: - case SerialPacketType::SYNCHRONIZE: - case SerialPacketType::DISCONNECT: - case SerialPacketType::SHUTDOWN: + case SerialPacketType::DISCONNECT_REQUEST: + case SerialPacketType::DISCONNECT_FORCED: + case SerialPacketType::LOGIN_REQUEST: + case SerialPacketType::LOGIN_RESPONSE: + case SerialPacketType::LOGOUT_REQUEST: + case SerialPacketType::LOGOUT_RESPONSE: + case SerialPacketType::SHUTDOWN_REQUEST: deserializeClient(buffer, static_cast(packet)); break; case SerialPacketType::REGION_REQUEST: case SerialPacketType::REGION_CONTENT: deserializeRegion(buffer, static_cast(packet)); break; - case SerialPacketType::CHARACTER_NEW: + case SerialPacketType::CHARACTER_CREATE: case SerialPacketType::CHARACTER_DELETE: - case SerialPacketType::CHARACTER_UPDATE: - case SerialPacketType::CHARACTER_STATS_REQUEST: - case SerialPacketType::CHARACTER_STATS_RESPONSE: + case SerialPacketType::CHARACTER_LOAD: + case SerialPacketType::CHARACTER_UNLOAD: + case SerialPacketType::QUERY_CHARACTER_EXISTS: + case SerialPacketType::QUERY_CHARACTER_STATS: + case SerialPacketType::QUERY_CHARACTER_LOCATION: + case SerialPacketType::CHARACTER_SET_ROOM: + case SerialPacketType::CHARACTER_SET_ORIGIN: + case SerialPacketType::CHARACTER_SET_MOTION: deserializeCharacter(buffer, static_cast(packet)); break; case SerialPacketType::TEXT_BROADCAST: case SerialPacketType::JOIN_REJECTION: - case SerialPacketType::SHUTDOWN_REJECTION: case SerialPacketType::CHARACTER_REJECTION: + case SerialPacketType::SHUTDOWN_REJECTION: deserializeText(buffer, static_cast(packet)); break; } diff --git a/server/rooms/room_system_api.cpp b/server/rooms/room_system_api.cpp index fcbb205..35c041a 100644 --- a/server/rooms/room_system_api.cpp +++ b/server/rooms/room_system_api.cpp @@ -40,7 +40,7 @@ static const luaL_Reg libs[] = { {nullptr, nullptr} }; -int openMapSystemAPI(lua_State* L) { +int openRoomSystemAPI(lua_State* L) { //create the table luaL_newlibtable(L, libs); diff --git a/server/server_application.hpp b/server/server_application.hpp index 012c41d..a91bbbc 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -98,6 +98,17 @@ private: sqlite3* database = nullptr; lua_State* luaState = nullptr; + //ugly references; I hate this + AccountManager& accountMgr = AccountManager::GetSingleton(); + CharacterManager& characterMgr = CharacterManager::GetSingleton(); + ClientManager& clientMgr = ClientManager::GetSingleton(); + DoorManager& doorMgr = DoorManager::GetSingleton(); + MonsterManager& monsterMgr = MonsterManager::GetSingleton(); + RoomManager& roomMgr = RoomManager::GetSingleton(); + + ConfigUtility& config = ConfigUtility::GetSingleton(); + UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton(); + //misc bool running = true; }; diff --git a/server/server_logic.cpp b/server/server_logic.cpp index 0c4484c..0c80ff8 100644 --- a/server/server_logic.cpp +++ b/server/server_logic.cpp @@ -43,7 +43,6 @@ void ServerApplication::Init(int argc, char* argv[]) { std::cout << "Beginning " << argv[0] << std::endl; //load the config settings - ConfigUtility& config = ConfigUtility::GetSingleton(); config.Load("rsc/config.cfg", argc, argv); //------------------------- @@ -60,7 +59,7 @@ void ServerApplication::Init(int argc, char* argv[]) { if (SDLNet_Init()) { throw(std::runtime_error("Failed to initialize SDL_net")); } - UDPNetworkUtility::GetSingleton().Open(config.Int("server.port")); + network.Open(config.Int("server.port")); std::cout << "Initialized SDL_net" << std::endl; //Init SQL @@ -102,10 +101,10 @@ void ServerApplication::Init(int argc, char* argv[]) { //------------------------- //set the hooks - AccountManager::GetSingleton().SetDatabase(database); - CharacterManager::GetSingleton().SetDatabase(database); + accountMgr.SetDatabase(database); + characterMgr.SetDatabase(database); - RoomManager::GetSingleton().SetLuaState(luaState); + roomMgr.SetLuaState(luaState); std::cout << "Internal managers initialized" << std::endl; @@ -173,9 +172,23 @@ void ServerApplication::Proc() { //... //Check connections - int disconnected = ClientManager::GetSingleton().CheckConnections(); + int disconnected = clientMgr.CheckConnections(); if (disconnected != -1) { - //TODO: clean up after this disconnection + //find and unload the accounts associated with this client + accountMgr.UnloadIf([&](std::pair account) -> bool { + if (account.second.GetClientIndex() == disconnected) { + //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; + }); } //give the computer a break @@ -187,16 +200,20 @@ void ServerApplication::Proc() { void ServerApplication::Quit() { std::cout << "Shutting down" << std::endl; + //TODO: save the server state + //close the managers - ClientManager::GetSingleton().UnloadAll(); - AccountManager::GetSingleton().UnloadAll(); - CharacterManager::GetSingleton().UnloadAll(); - RoomManager::GetSingleton().UnloadAll(); + accountMgr.UnloadAll(); + characterMgr.UnloadAll(); + clientMgr.UnloadAll(); + doorMgr.UnloadAll(); + monsterMgr.UnloadAll(); + roomMgr.UnloadAll(); //APIs lua_close(luaState); sqlite3_close_v2(database); - UDPNetworkUtility::GetSingleton().Close(); + network.Close(); SDLNet_Quit(); SDL_Quit(); @@ -213,60 +230,93 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) { case SerialPacketType::PING: { ServerPacket newPacket; newPacket.type = SerialPacketType::PONG; - UDPNetworkUtility::GetSingleton().SendTo(argPacket->srcAddress, &newPacket); + network.SendTo(argPacket->srcAddress, &newPacket); } break; case SerialPacketType::PONG: - ClientManager::GetSingleton().HandlePong(static_cast(argPacket)); + clientMgr.HandlePong(static_cast(argPacket)); break; - //connections + //client connections case SerialPacketType::BROADCAST_REQUEST: - HandleBroadcastRequest(static_cast(argPacket)); +// HandleBroadcastRequest(static_cast(argPacket)); break; case SerialPacketType::JOIN_REQUEST: - HandleJoinRequest(static_cast(argPacket)); +// HandleJoinRequest(static_cast(argPacket)); break; - case SerialPacketType::DISCONNECT: - HandleDisconnect(static_cast(argPacket)); - break; - case SerialPacketType::SHUTDOWN: - HandleShutdown(static_cast(argPacket)); + case SerialPacketType::LOGIN_REQUEST: +// HandleLoginRequest(static_cast(argPacket)); break; - //map management + //client disconnections + case SerialPacketType::DISCONNECT_REQUEST: +// HandleDisconnectRequest(static_cast(argPacket)); + break; + case SerialPacketType::DISCONNECT_FORCED: +// HandleDisconnectForced(static_cast(argPacket)); + break; + case SerialPacketType::LOGOUT_REQUEST: +// HandleLogoutRequest(static_cast(argPacket)); + break; + + //server commands + case SerialPacketType::SHUTDOWN_REQUEST: +// HandleShutdownRequest(static_cast(argPacket)); + break; + + //data management & queries case SerialPacketType::REGION_REQUEST: - HandleRegionRequest(static_cast(argPacket)); +// HandleRegionRequest(static_cast(argPacket)); + break; + case SerialPacketType::QUERY_CHARACTER_EXISTS: +// HandleCharacterStatsRequest(static_cast(argPacket)); + break; + case SerialPacketType::QUERY_CHARACTER_STATS: +// HandleCharacterStatsRequest(static_cast(argPacket)); + break; + case SerialPacketType::QUERY_CHARACTER_LOCATION: +// HandleCharacterStatsRequest(static_cast(argPacket)); + break; + case SerialPacketType::TEXT_BROADCAST: +// HandleCharacterStatsRequest(static_cast(argPacket)); break; - - //combat management - //TODO: combat management //character management - case SerialPacketType::CHARACTER_NEW: - HandleCharacterNew(static_cast(argPacket)); + case SerialPacketType::CHARACTER_CREATE: +// HandleCharacterNew(static_cast(argPacket)); break; case SerialPacketType::CHARACTER_DELETE: - HandleCharacterDelete(static_cast(argPacket)); +// HandleCharacterDelete(static_cast(argPacket)); break; - case SerialPacketType::CHARACTER_UPDATE: - case SerialPacketType::CHARACTER_STATS_REQUEST: - HandleCharacterUpdate(static_cast(argPacket)); + case SerialPacketType::CHARACTER_LOAD: +// HandleCharacterNew(static_cast(argPacket)); + break; + case SerialPacketType::CHARACTER_UNLOAD: +// HandleCharacterDelete(static_cast(argPacket)); + break; + + //character movement + case SerialPacketType::CHARACTER_SET_ROOM: +// HandleCharacterUpdate(static_cast(argPacket)); + break; + case SerialPacketType::CHARACTER_SET_ORIGIN: +// HandleCharacterUpdate(static_cast(argPacket)); + break; + case SerialPacketType::CHARACTER_SET_MOTION: +// HandleCharacterUpdate(static_cast(argPacket)); break; //enemy management //TODO: enemy management - //mismanagement - case SerialPacketType::SYNCHRONIZE: - HandleSynchronize(static_cast(argPacket)); - break; + //TODO: text //handle errors default: { - std::string msg = "Unknown SerialPacketType encountered in the server: "; - msg += to_string_custom(static_cast(argPacket->type)); - throw(std::runtime_error(msg)); + std::ostringstream msg; + msg << "Unknown SerialPacketType encountered in the server: "; + msg << to_string_custom(static_cast(argPacket->type)); + throw(std::runtime_error(msg.str())); } break; } diff --git a/server/server_methods.cpp b/server/server_methods.cpp index 5531221..d73d899 100644 --- a/server/server_methods.cpp +++ b/server/server_methods.cpp @@ -23,6 +23,7 @@ #include #include +#include //------------------------- //basic connections @@ -43,18 +44,24 @@ void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) { //SET: connections void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { + //register the client + int clientIndex = clientMgr.Create(argPacket->srcAddress); + //load the user account //TODO: handle passwords int accountIndex = accountMgr.Load(argPacket->username, clientIndex); //Cannot load if (accountIndex < 0) { + std::ostringstream msg; + msg << "Account already loaded: " << argPacket->username; + TextPacket newPacket; newPacket.type = SerialPacketType::JOIN_REJECTION; - std::string msg = std::string() + "Account already loaded: " + argPacket->username; memset(newPacket.name, 0, PACKET_STRING_SIZE); - strncpy(newPacket.text, msg.c_str(), PACKET_STRING_SIZE); //BUG: If the name is too long this would truncate it + strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE); network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); + clientMgr.Unload(clientIndex); return; } @@ -66,13 +73,8 @@ void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); - //register the client - ClientData newClient; - newClient.SetAddress(argPacket->srcAddress); - clientMap[clientIndex++] = newClient; - //finished this routine - std::cout << "New connection, " << clientMap.size() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; + std::cout << "New connection, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; } //SET: connections @@ -90,7 +92,7 @@ void ServerApplication::HandleDisconnect(ClientPacket* const argPacket) { //forward to the specified client network.SendTo( - clientMap[ accountMgr.Get(argPacket->accountIndex)->GetClientIndex() ].GetAddress(), + clientMgr.Get(accountMgr.Get(argPacket->accountIndex)->GetClientIndex())->GetAddress(), static_cast(argPacket) ); @@ -105,11 +107,11 @@ void ServerApplication::HandleDisconnect(ClientPacket* const argPacket) { }); //erase the in-memory stuff - clientMap.erase(accountMgr.Get(argPacket->accountIndex)->GetClientIndex()); + clientMgr.Unload(accountMgr.Get(argPacket->accountIndex)->GetClientIndex()); accountMgr.Unload(argPacket->accountIndex); //finished this routine - std::cout << "Disconnection, " << clientMap.size() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; + std::cout << "Disconnection, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; } //SET: connections @@ -127,7 +129,7 @@ void ServerApplication::HandleShutdown(ClientPacket* const argPacket) { //disconnect all clients ClientPacket newPacket; - newPacket.type = SerialPacketType::DISCONNECT; + newPacket.type = SerialPacketType::DISCONNECT_FORCED; PumpPacket(&newPacket); //finished this routine @@ -166,27 +168,27 @@ void ServerApplication::HandleCharacterNew(CharacterPacket* const argPacket) { //cannot load or create if (characterIndex < 0) { //build the error message - std::string msg; + std::ostringstream msg; if (characterIndex == -1) { - msg += "Character already loaded: "; + msg << "Character already loaded: "; } else if (characterIndex == -2) { - msg += "Character already exists: "; + msg << "Character already exists: "; } - msg += argPacket->handle; + msg << argPacket->handle; //create, fill and send the packet TextPacket newPacket; newPacket.type = SerialPacketType::CHARACTER_REJECTION; memset(newPacket.name, 0, PACKET_STRING_SIZE); - strncpy(newPacket.text, msg.c_str(), PACKET_STRING_SIZE); + strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE); network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); return; } //send this new character to all clients CharacterPacket newPacket; - newPacket.type = SerialPacketType::CHARACTER_NEW; + newPacket.type = SerialPacketType::CHARACTER_CREATE; CopyCharacterToPacket(&newPacket, characterIndex); PumpPacket(&newPacket); } @@ -255,15 +257,15 @@ void ServerApplication::HandleSynchronize(ClientPacket* const argPacket) { //NOTE: I quite dislike this function //send all of the server's data to this client - ClientData& client = clientMap[argPacket->clientIndex]; + ClientData* client = clientMgr.Get(argPacket->clientIndex); //send all characters CharacterPacket newPacket; - newPacket.type = SerialPacketType::CHARACTER_UPDATE; + newPacket.type = SerialPacketType::CHARACTER_SET_ORIGIN; for (auto& it : *characterMgr.GetContainer()) { CopyCharacterToPacket(&newPacket, it.first); - network.SendTo(client.GetAddress(), static_cast(&newPacket)); + network.SendTo(client->GetAddress(), static_cast(&newPacket)); } //TODO: more in HandleSynchronize() @@ -278,6 +280,11 @@ void ServerApplication::CleanupLostConnection(int clientIndex) { //NOTE: This assumes each player has only one account and character at a time //TODO: handle multiple characters (bots, etc.) + //send a disconnection message just in case + ClientPacket newPacket; + newPacket.type = SerialPacketType::DISCONNECT_FORCED; + network.SendTo(clientMgr.Get(clientIndex)->GetAddress(), &newPacket); + //find the account int accountIndex = -1; for (auto& it : *accountMgr.GetContainer()) { @@ -296,15 +303,10 @@ void ServerApplication::CleanupLostConnection(int clientIndex) { } } - //send a disconnection message just in case - ClientPacket newPacket; - newPacket.type = SerialPacketType::DISCONNECT; - network.SendTo(clientMap[clientIndex].GetAddress(), &newPacket); - //clean up this mess characterMgr.Unload(characterIndex); accountMgr.Unload(accountIndex); - clientMap.erase(clientIndex); + clientMgr.Unload(clientIndex); PumpCharacterUnload(characterIndex); @@ -313,7 +315,7 @@ void ServerApplication::CleanupLostConnection(int clientIndex) { std::cerr << "\tClient: " << clientIndex << std::endl; std::cerr << "\tAccount: " << accountIndex << std::endl; std::cerr << "\tCharacter: " << characterIndex << std::endl; - std::cout << clientMap.size() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; + std::cout << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; } //SET: utility @@ -321,12 +323,12 @@ void ServerApplication::CleanupLostConnection(int clientIndex) { //SET: utility void ServerApplication::PumpPacket(SerialPacket* const argPacket) { - for (auto& it : clientMap) { + for (auto& it : *clientMgr.GetContainer()) { network.SendTo(it.second.GetAddress(), argPacket); } } -//SET: utility +//SET: utility/delete void ServerApplication::PumpCharacterUnload(int uid) { //delete the client-side character(s) //NOTE: This is a strange function @@ -336,7 +338,7 @@ void ServerApplication::PumpCharacterUnload(int uid) { PumpPacket(static_cast(&newPacket)); } -//SET: utility +//SET: utility/delete void ServerApplication::CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex) { CharacterData* character = characterMgr.Get(characterIndex); if (!character) {