diff --git a/server/server_internals.cpp b/server/server_internals.cpp index 1a96d5b..e1a9cb9 100644 --- a/server/server_internals.cpp +++ b/server/server_internals.cpp @@ -1,4 +1,4 @@ -/* Copyright: (c) Kayne Ruse 2013, 2014 +/* 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 @@ -21,7 +21,7 @@ */ #include "server_application.hpp" -#include "utility.hpp" +#include "server_utility.hpp" #include #include @@ -36,8 +36,6 @@ void ServerApplication::Init(int argc, char** argv) { std::cout << "Beginning startup" << std::endl; //initial setup - ClientEntry::uidCounter = 0; - PlayerEntry::uidCounter = 0; config.Load("rsc\\config.cfg"); //Init SDL @@ -109,6 +107,8 @@ void ServerApplication::Proc() { //we need to go deeper HandlePacket(packet); } + //update the internals + //TODO: update the internals i.e. player positions //give the computer a break SDL_Delay(10); } @@ -116,6 +116,10 @@ void ServerApplication::Proc() { void ServerApplication::Quit() { std::cout << "Shutting down" << std::endl; + + //save the server state + //TODO: save the existing players + //empty the members regionPager.UnloadAll(); @@ -125,6 +129,7 @@ void ServerApplication::Quit() { network.Close(); SDLNet_Quit(); SDL_Quit(); + std::cout << "Shutdown finished" << std::endl; } @@ -140,21 +145,15 @@ void ServerApplication::HandlePacket(SerialPacket packet) { case SerialPacket::Type::JOIN_REQUEST: HandleJoinRequest(packet); break; - case SerialPacket::Type::DISCONNECT: - HandleDisconnect(packet); - break; case SerialPacket::Type::SYNCHRONIZE: HandleSynchronize(packet); break; + case SerialPacket::Type::DISCONNECT: + HandleDisconnect(packet); + break; case SerialPacket::Type::SHUTDOWN: HandleShutdown(packet); break; - case SerialPacket::Type::PLAYER_NEW: - HandlePlayerNew(packet); - break; - case SerialPacket::Type::PLAYER_DELETE: - HandlePlayerDelete(packet); - break; case SerialPacket::Type::PLAYER_UPDATE: HandlePlayerUpdate(packet); break; @@ -167,202 +166,3 @@ void ServerApplication::HandlePacket(SerialPacket packet) { break; } } - -//------------------------- -//Handle various network input -//------------------------- - -void ServerApplication::HandleBroadcastRequest(SerialPacket packet) { - //send back the server's metadata - packet.meta.type = SerialPacket::Type::BROADCAST_RESPONSE; - - //pack the data - snprintf(packet.serverInfo.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str()); - packet.serverInfo.playerCount = playerMap.size(); - packet.serverInfo.regionWidth = REGION_WIDTH; - packet.serverInfo.regionHeight = REGION_HEIGHT; - packet.serverInfo.regionDepth = REGION_DEPTH; - - //send the data - char buffer[PACKET_BUFFER_SIZE]; - serialize(&packet, buffer); - network.Send(&packet.meta.srcAddress, buffer, PACKET_BUFFER_SIZE); -} - -void ServerApplication::HandleJoinRequest(SerialPacket packet) { - //register the new client - ClientEntry newClient; - newClient.address = packet.meta.srcAddress; - clientMap[ClientEntry::uidCounter] = newClient; - - //send the client their index - char buffer[PACKET_BUFFER_SIZE]; - packet.meta.type = SerialPacket::Type::JOIN_RESPONSE; - packet.clientInfo.index = ClientEntry::uidCounter; - serialize(&packet, buffer); - - //bounce this packet - network.Send(&newClient.address, buffer, PACKET_BUFFER_SIZE); - - //finished this routine - ClientEntry::uidCounter++; - std::cout << "Connect, total: " << clientMap.size() << std::endl; -} - -void ServerApplication::HandleDisconnect(SerialPacket packet) { - //TODO: authenticate who is disconnecting/kicking - - //disconnect the specified client - char buffer[PACKET_BUFFER_SIZE]; - serialize(&packet, buffer); - network.Send(&clientMap[packet.clientInfo.index].address, buffer, PACKET_BUFFER_SIZE); - clientMap.erase(packet.clientInfo.index); - - //prep the delete packet - SerialPacket delPacket; - delPacket.meta.type = SerialPacket::Type::PLAYER_DELETE; - - //TODO: can this use DeletePlayer() instead? - //delete server and client side players - erase_if(playerMap, [&](std::pair it) -> bool { - //find the internal players to delete - if (it.second.clientIndex == packet.clientInfo.index) { - //send the delete player command to all clients - delPacket.playerInfo.playerIndex = it.first; - PumpPacket(delPacket); - - //delete this player object - return true; - } - - //don't delete this player object - return false; - }); - - //finished this routine - std::cout << "Disconnect, total: " << clientMap.size() << std::endl; -} - -void ServerApplication::HandleSynchronize(SerialPacket packet) { - //TODO: compensate for large distances - - //send all the server's data to this client - SerialPacket newPacket; - char buffer[PACKET_BUFFER_SIZE]; - - //players - newPacket.meta.type = SerialPacket::Type::PLAYER_UPDATE; - for (auto& it : playerMap) { - //TODO: update this for the expanded PlayerEntry structure - newPacket.playerInfo.playerIndex = it.first; - snprintf(newPacket.playerInfo.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str()); - snprintf(newPacket.playerInfo.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str()); - newPacket.playerInfo.position = it.second.position; - newPacket.playerInfo.motion = it.second.motion; - serialize(&newPacket, buffer); - network.Send(&clientMap[packet.clientInfo.index].address, buffer, PACKET_BUFFER_SIZE); - } -} - -void ServerApplication::HandleShutdown(SerialPacket packet) { - //end the server - running = false; - - //disconnect all clients - packet.meta.type = SerialPacket::Type::DISCONNECT; - PumpPacket(packet); - - //finished this routine - std::cout << "Shutdown signal accepted" << std::endl; -} - -void ServerApplication::HandlePlayerNew(SerialPacket packet) { - //register the new PlayerEntry - //NOTE: assigning each field one-by-one so adding or moving a field doesn't break this code - PlayerEntry newPlayer; - - //metadata - newPlayer.clientIndex = packet.playerInfo.clientIndex; - newPlayer.handle = packet.playerInfo.handle; - newPlayer.avatar = packet.playerInfo.avatar; - - //position - newPlayer.mapIndex = 0; - newPlayer.position = {0,0}; - newPlayer.motion = {0,0}; - newPlayer.bbox = {0, 0, 0, 0}; - - //TODO: Add the statistic creation code here - - //push this player - playerMap[PlayerEntry::uidCounter] = newPlayer; - - //send the client their info - packet.playerInfo.playerIndex = PlayerEntry::uidCounter; - packet.playerInfo.position = newPlayer.position; - packet.playerInfo.motion = newPlayer.motion; - - //actually send to everyone - PumpPacket(packet); - - //finish this routine - PlayerEntry::uidCounter++; -} - -//TODO: differentiate between delete and unload -void ServerApplication::HandlePlayerDelete(SerialPacket packet) { - //TODO: authenticate who is deleting this player - if (playerMap.find(packet.playerInfo.playerIndex) == playerMap.end()) { - throw(std::runtime_error("Cannot delete a non-existant player")); - } - - //TODO: remove the deleted player from the database? - - //prep the delete packet - SerialPacket delPacket; - delPacket.meta.type = SerialPacket::Type::PLAYER_DELETE; - - //delete the specified playerEntry - erase_if(playerMap, [&](std::pair it) -> bool { - //find the specified PlayerEntry - if (it.first == packet.playerInfo.playerIndex) { - //send to all - delPacket.playerInfo.playerIndex = it.first; - PumpPacket(delPacket); - - //delete this player - return true; - } - //skip this player - return false; - }); -} - -void ServerApplication::HandlePlayerUpdate(SerialPacket packet) { - if (playerMap.find(packet.playerInfo.playerIndex) == playerMap.end()) { - throw(std::runtime_error("Cannot update a non-existant player")); - } - - //TODO: the server needs it's own movement system too - playerMap[packet.playerInfo.playerIndex].position = packet.playerInfo.position; - playerMap[packet.playerInfo.playerIndex].motion = packet.playerInfo.motion; - - PumpPacket(packet); -} - -void ServerApplication::HandleRegionRequest(SerialPacket packet) { - char buffer[PACKET_BUFFER_SIZE]; - packet.meta.type = SerialPacket::Type::REGION_CONTENT; - packet.regionInfo.region = regionPager.GetRegion(packet.regionInfo.x, packet.regionInfo.y); - serialize(&packet, buffer); - network.Send(&packet.meta.srcAddress, buffer, PACKET_BUFFER_SIZE); -} - -void ServerApplication::PumpPacket(SerialPacket packet) { - //NOTE: I don't really like this, but it'll do for now - char buffer[PACKET_BUFFER_SIZE]; - serialize(&packet, buffer); - for (auto& it : clientMap) { - network.Send(&it.second.address, buffer, PACKET_BUFFER_SIZE); - } -}