diff --git a/common/network/network_packet.hpp b/common/network/network_packet.hpp index 27c5bee..a031f00 100644 --- a/common/network/network_packet.hpp +++ b/common/network/network_packet.hpp @@ -94,6 +94,9 @@ union NetworkPacket { Vector2 motion; }playerInfo; + //map data + //... + //defaults NetworkPacket() { meta.type = Type::NONE; diff --git a/server/client_manager.cpp b/server/client_manager.cpp index f17faec..a4d9800 100644 --- a/server/client_manager.cpp +++ b/server/client_manager.cpp @@ -38,6 +38,12 @@ int ClientManager::HandleDisconnection(int i) { return -1; } +void ClientManager::ForEach(Lambda fn) { + for(Iterator it = clientMap.begin(); it != clientMap.end(); it++) { + fn(it); + } +} + ClientEntry* ClientManager::GetClient(int i) { for (auto& it : clientMap) { if (it.first == i) { diff --git a/server/client_manager.hpp b/server/client_manager.hpp index 36a5f23..946c946 100644 --- a/server/client_manager.hpp +++ b/server/client_manager.hpp @@ -24,6 +24,7 @@ #include "SDL/SDL_net.h" +#include #include struct ClientEntry { @@ -32,15 +33,24 @@ struct ClientEntry { class ClientManager { public: + //clarity typedefs + typedef std::map Container; + typedef Container::iterator Iterator; + typedef std::function Lambda; + //returns the internal index int HandleConnection(IPaddress); int HandleDisconnection(int i); + //lambdas + void ForEach(Lambda); + //accessors ClientEntry* GetClient(int i); ClientEntry* GetClient(IPaddress); + int Size() { return clientMap.size(); } private: - std::map clientMap; + Container clientMap; int counter = 0; }; diff --git a/server/server_application.cpp b/server/server_application.cpp index c2f79a4..0b008b3 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -30,21 +30,23 @@ using namespace std; -//------------------------- -//Define the ServerApplication -//------------------------- - -ServerApplication::ServerApplication() { - // +void runSQLScript(sqlite3* db, std::string fname) { + //Run setup scripts + ifstream is(fname); + if (!is.is_open()) { + throw(runtime_error("Failed to run SQL script")); + } + string script; + getline(is, script, '\0'); + is.close(); + sqlite3_exec(db, script.c_str(), nullptr, nullptr, nullptr); } -ServerApplication::~ServerApplication() { - // -} +//------------------------- +//Define the public members +//------------------------- void ServerApplication::Init(int argc, char** argv) { - //TODO: proper command line option parsing - //load config config.Load("rsc\\config.cfg"); @@ -56,97 +58,85 @@ void ServerApplication::Init(int argc, char** argv) { //Init SDL_net if (SDLNet_Init()) { - throw(runtime_error("Failed to init SDL_net")); + throw(runtime_error("Failed to initialize SDL_net")); } network.Open(config.Int("server.port"), sizeof(NetworkPacket)); cout << "initialized SDL_net" << endl; //Init SQL - string dbname = (config["server.dbname"].size()) ? config["server.dbname"] : std::string(argv[0]) + ".db"; //fancy and unnecessary - int ret = sqlite3_open_v2(dbname.c_str(), &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_FULLMUTEX, nullptr); + int ret = sqlite3_open_v2(config["server.dbname"].c_str(), &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, nullptr); if (ret != SQLITE_OK || !database) { throw(runtime_error("Failed to open the server database")); } cout << "initialized SQL" << endl; - cout << "Database filename: " << dbname << endl; - //TODO: move this into a function? - //Run setup scripts - ifstream is("rsc\\scripts\\setup_server.sql"); - if (!is.is_open()) { - throw(runtime_error("Failed to run database setup script")); - } - string script; - getline(is, script, '\0'); - is.close(); - sqlite3_exec(database, script.c_str(), nullptr, nullptr, nullptr); + //setup the database + runSQLScript(database, config["dir.scripts"] + "setup_server.sql"); + cout << "initialized " << config["server.dbname"] << endl; + + //lua + //TODO } void ServerApplication::Loop() { NetworkPacket packet; - while(running) { //suck in the waiting packets & process them - try { - while(network.Receive()) { - memcpy(&packet, network.GetInData(), sizeof(NetworkPacket)); - packet.meta.srcAddress = network.GetInPacket()->address; - HandlePacket(packet); - } + while(network.Receive()) { + //get the packet + memcpy(&packet, network.GetInData(), sizeof(NetworkPacket)); + //cache the source address + packet.meta.srcAddress = network.GetInPacket()->address; + //we need to go deeper + HandlePacket(packet); } - catch(exception& e) { - cerr << "Network Error: " << e.what() << endl; - } - //give the computer a break SDL_Delay(10); } } void ServerApplication::Quit() { - //members - network.Close(); + //empty the members + //TODO: player manager + //TODO: client manager //APIs sqlite3_close_v2(database); + network.Close(); SDLNet_Quit(); SDL_Quit(); } +//------------------------- +//Define the uber switch +//------------------------- + void ServerApplication::HandlePacket(NetworkPacket packet) { switch(packet.meta.type) { case NetworkPacket::Type::BROADCAST_REQUEST: HandleBroadcastRequest(packet); break; - case NetworkPacket::Type::JOIN_REQUEST: HandleJoinRequest(packet); break; - case NetworkPacket::Type::DISCONNECT: HandleDisconnect(packet); break; - case NetworkPacket::Type::SYNCHRONIZE: - HandleSynchronize(packet); +// HandleSynchronize(packet); break; - case NetworkPacket::Type::SHUTDOWN: HandleShutdown(packet); break; - case NetworkPacket::Type::PLAYER_NEW: - HandlePlayerNew(packet); +// HandlePlayerNew(packet); break; - case NetworkPacket::Type::PLAYER_DELETE: - HandlePlayerDelete(packet); +// HandlePlayerDelete(packet); break; - case NetworkPacket::Type::PLAYER_UPDATE: - HandlePlayerUpdate(packet); +// HandlePlayerUpdate(packet); break; - //handle errors default: throw(runtime_error("Unknown NetworkPacket::Type encountered")); @@ -154,39 +144,38 @@ void ServerApplication::HandlePacket(NetworkPacket packet) { } } +//------------------------- +//Handle various network input +//------------------------- + void ServerApplication::HandleBroadcastRequest(NetworkPacket packet) { //send back the server's name packet.meta.type = NetworkPacket::Type::BROADCAST_RESPONSE; + //TODO: version info snprintf(packet.serverInfo.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str()); + //TODO: player count network.Send(&packet.meta.srcAddress, &packet, sizeof(NetworkPacket)); } void ServerApplication::HandleJoinRequest(NetworkPacket packet) { - //TODO: prevent duplicate logins from the same address? - - //create the new client, filling it with the correct info - Client newClient; - newClient.address = packet.meta.srcAddress; - - //push the new client - clientMap[clientCounter] = newClient; + //register the new client + int index = clientMgr.HandleConnection(packet.meta.srcAddress); //send the client their info packet.meta.type = NetworkPacket::Type::JOIN_RESPONSE; - packet.clientInfo.index = clientCounter; - network.Send(&newClient.address, &packet, sizeof(NetworkPacket)); + packet.clientInfo.index = index; + network.Send(&clientMgr.GetClient(index)->address, &packet, sizeof(NetworkPacket)); //finished this routine - clientCounter++; - cout << "connect, total: " << clientMap.size() << endl; + cout << "connect, total: " << clientMgr.Size() << endl; } void ServerApplication::HandleDisconnect(NetworkPacket packet) { //disconnect the specified client - network.Send(&clientMap[packet.clientInfo.index].address, &packet, sizeof(NetworkPacket)); - clientMap.erase(packet.clientInfo.index); + network.Send(&clientMgr.GetClient(packet.clientInfo.index)->address, &packet, sizeof(NetworkPacket)); + clientMgr.HandleDisconnection(packet.clientInfo.index); - //delete players +/* //delete players erase_if(playerMap, [&](pair it) -> bool { if (it.second.clientIndex == packet.clientInfo.index) { NetworkPacket delPacket; @@ -202,10 +191,12 @@ void ServerApplication::HandleDisconnect(NetworkPacket packet) { } return false; }); +*/ - cout << "disconnect, total: " << clientMap.size() << endl; + //finished this routine + cout << "disconnect, total: " << clientMgr.Size() << endl; } - +/* void ServerApplication::HandleSynchronize(NetworkPacket packet) { //send all the server's data to this client NetworkPacket newPacket; @@ -221,18 +212,21 @@ void ServerApplication::HandleSynchronize(NetworkPacket packet) { network.Send(&clientMap[packet.clientInfo.index].address, &newPacket, sizeof(NetworkPacket)); } } - +*/ void ServerApplication::HandleShutdown(NetworkPacket packet) { //end the server running = false; //disconnect all clients packet.meta.type = NetworkPacket::Type::DISCONNECT; - PumpPacket(packet); + clientMgr.ForEach([&](ClientManager::Iterator it) -> void { + this->network.Send(&it->second.address, &packet, sizeof(NetworkPacket)); + }); + //finished this routine cout << "shutting down" << endl; } - +/* void ServerApplication::HandlePlayerNew(NetworkPacket packet) { //create the new player object Player newPlayer; @@ -291,10 +285,4 @@ void ServerApplication::HandlePlayerUpdate(NetworkPacket packet) { PumpPacket(packet); } - -void ServerApplication::PumpPacket(NetworkPacket packet) { - //send this packet to all clients - for (auto& it : clientMap) { - network.Send(&it.second.address, &packet, sizeof(NetworkPacket)); - } -} \ No newline at end of file +*/ diff --git a/server/server_application.hpp b/server/server_application.hpp index 073d480..5aeb872 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -31,12 +31,13 @@ #include "SDL/SDL.h" //misc +#include "client_manager.hpp" +#include "player_manager.hpp" + +//common #include "config_utility.hpp" #include "vector2.hpp" -#include "client.hpp" -#include "player.hpp" - //STL #include #include @@ -45,8 +46,8 @@ class ServerApplication { public: //standard functions - ServerApplication(); - ~ServerApplication(); + ServerApplication() = default; + ~ServerApplication() = default; void Init(int argc, char** argv); void Loop(); @@ -59,13 +60,11 @@ private: void HandleBroadcastRequest(NetworkPacket); void HandleJoinRequest(NetworkPacket); void HandleDisconnect(NetworkPacket); - void HandleSynchronize(NetworkPacket); +// void HandleSynchronize(NetworkPacket); void HandleShutdown(NetworkPacket); - void HandlePlayerNew(NetworkPacket); - void HandlePlayerDelete(NetworkPacket); - void HandlePlayerUpdate(NetworkPacket); - - void PumpPacket(NetworkPacket); +// void HandlePlayerNew(NetworkPacket); +// void HandlePlayerDelete(NetworkPacket); +// void HandlePlayerUpdate(NetworkPacket); //networking UDPNetworkUtility network; @@ -73,16 +72,14 @@ private: //database sqlite3* database = nullptr; + //lua + //TODO + //misc bool running = true; ConfigUtility config; - //global lists - ClientMap clientMap; - PlayerMap playerMap; - - int clientCounter = 0; - int playerCounter = 0; + ClientManager clientMgr; }; #endif