From 7bb5e8ce0dbf2d6090b91b2ba68037ad09970653 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 2 Mar 2014 23:20:37 +1100 Subject: [PATCH 1/3] Moving client and player data into manager classes Remember: anything with "manager" in its name organizes a number of other objects, as far as I'm concerned. I'll eventually have a database connection in the PlayerManager class; this'll make it easier to manage the database. --- server/client_manager.cpp | 58 ++++++++++++++++++++++ server/{client.hpp => client_manager.hpp} | 25 +++++++--- server/{player.hpp => player_manager.cpp} | 44 ++++++++++------- server/player_manager.hpp | 59 +++++++++++++++++++++++ 4 files changed, 161 insertions(+), 25 deletions(-) create mode 100644 server/client_manager.cpp rename server/{client.hpp => client_manager.hpp} (70%) rename server/{player.hpp => player_manager.cpp} (57%) create mode 100644 server/player_manager.hpp diff --git a/server/client_manager.cpp b/server/client_manager.cpp new file mode 100644 index 0000000..f17faec --- /dev/null +++ b/server/client_manager.cpp @@ -0,0 +1,58 @@ +/* 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 "client_manager.hpp" + +int ClientManager::HandleConnection(IPaddress add) { + ClientEntry c; + c.address = add; + clientMap[counter] = c; + return counter++; +} + +int ClientManager::HandleDisconnection(int i) { + for (auto& it : clientMap) { + if (it.first == i) { + clientMap.erase(it.first); + return 0; + } + } + return -1; +} + +ClientEntry* ClientManager::GetClient(int i) { + for (auto& it : clientMap) { + if (it.first == i) { + return &it.second; + } + } + return nullptr; +} + +ClientEntry* ClientManager::GetClient(IPaddress add) { + for (auto& it : clientMap) { + if (it.second.address.host == add.host && + it.second.address.port == add.port) { + return &it.second; + } + } + return nullptr; +} diff --git a/server/client.hpp b/server/client_manager.hpp similarity index 70% rename from server/client.hpp rename to server/client_manager.hpp index c2d2194..36a5f23 100644 --- a/server/client.hpp +++ b/server/client_manager.hpp @@ -1,4 +1,4 @@ -/* Copyright: (c) Kayne Ruse 2013 +/* 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 @@ -19,20 +19,29 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#ifndef CLIENT_HPP_ -#define CLIENT_HPP_ +#ifndef CLIENTMANAGER_HPP_ +#define CLIENTMANAGER_HPP_ #include "SDL/SDL_net.h" #include -/* Hold the client info. -*/ - -struct Client { +struct ClientEntry { IPaddress address; }; -typedef std::map ClientMap; +class ClientManager { +public: + //returns the internal index + int HandleConnection(IPaddress); + int HandleDisconnection(int i); + + //accessors + ClientEntry* GetClient(int i); + ClientEntry* GetClient(IPaddress); +private: + std::map clientMap; + int counter = 0; +}; #endif diff --git a/server/player.hpp b/server/player_manager.cpp similarity index 57% rename from server/player.hpp rename to server/player_manager.cpp index e709ba4..a708874 100644 --- a/server/player.hpp +++ b/server/player_manager.cpp @@ -1,4 +1,4 @@ -/* Copyright: (c) Kayne Ruse 2013 +/* 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 @@ -19,25 +19,35 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#ifndef PLAYER_HPP_ -#define PLAYER_HPP_ +#include "player_manager.hpp" -#include "vector2.hpp" +int PlayerManager::HandlePlayerCreation(std::string name, std::string avatar) { + // +} -#include -#include +int PlayerManager::HandlePlayerDeletion(int uniqueID) { + // +} -/* Hold the player info. -*/ +int PlayerManager::HandlePlayerLoad(int uniqueID, int clientIndex) { + // +} -struct Player { - int clientIndex; - std::string handle; - std::string avatar; - Vector2 position; - Vector2 motion; -}; +int PlayerManager::HandlePlayerUnload(int uniqueID) { + // +} -typedef std::map PlayerMap; +PlayerEntry* PlayerManager::GetPlayer(int uniqueID) { + for (auto& it : playerMap) { + if (it.first == uniqueID) { + return &it.second; + } + } + return nullptr; +} -#endif +void PlayerManager::Update(double delta) { + for (auto& it : playerMap) { + it.second.position += it.second.motion * delta; + } +} diff --git a/server/player_manager.hpp b/server/player_manager.hpp new file mode 100644 index 0000000..50ba849 --- /dev/null +++ b/server/player_manager.hpp @@ -0,0 +1,59 @@ +/* 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. +*/ +#ifndef PLAYERMANAGER_HPP_ +#define PLAYERMANAGER_HPP_ + +#include "vector2.hpp" + +#include +#include + +struct PlayerEntry { + int clientIndex; + int mapIndex; + Vector2 position; + Vector2 motion; +}; + +class PlayerManager { +public: + //These functions interact with the database + //*Deletion, *Load and *Unload returns: 0 success, -1 failure + //*Creation returns the uniqueID, but doesn't load + // that object; call *Load directly afterward + + int HandlePlayerCreation (std::string name, std::string avatar); + int HandlePlayerDeletion (int uniqueID); + int HandlePlayerLoad (int uniqueID, int clientIndex); + int HandlePlayerUnload (int uniqueID); + + //basic accessor + PlayerEntry* GetPlayer (int uniqueID); + + //update each player's position + void Update(double delta); +private: + std::map playerMap; + //database connection here +}; + +#endif From 756d4e770dc3d6ec9f125e4227cdde4a69da0c58 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 4 Mar 2014 02:46:19 +1100 Subject: [PATCH 2/3] Connection and disconnection are working correctly I've dummied out the player code, so only the client connection code is working. Otherwise the protocol hasn't changed. I've also made a few other tweaks as I went along, but nothing really major. --- common/network/network_packet.hpp | 3 + server/client_manager.cpp | 6 ++ server/client_manager.hpp | 12 ++- server/server_application.cpp | 142 ++++++++++++++---------------- server/server_application.hpp | 31 +++---- 5 files changed, 99 insertions(+), 95 deletions(-) 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 From f17fa0f3459bb91df46bab369f651f2d41d391c4 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Wed, 5 Mar 2014 00:27:21 +1100 Subject: [PATCH 3/3] Added lua, added db connection to PlayerManager I've also revised the startup process a bit. --- rsc/scripts/setup_room.lua | 0 rsc/scripts/setup_server.lua | 1 + server/player_manager.cpp | 6 +++++ server/player_manager.hpp | 22 +++++++++++---- server/server_application.cpp | 50 ++++++++++++++++++++++++++--------- server/server_application.hpp | 4 ++- 6 files changed, 65 insertions(+), 18 deletions(-) delete mode 100644 rsc/scripts/setup_room.lua diff --git a/rsc/scripts/setup_room.lua b/rsc/scripts/setup_room.lua deleted file mode 100644 index e69de29..0000000 diff --git a/rsc/scripts/setup_server.lua b/rsc/scripts/setup_server.lua index e69de29..a2cf14a 100644 --- a/rsc/scripts/setup_server.lua +++ b/rsc/scripts/setup_server.lua @@ -0,0 +1 @@ +print("Lua script check OK") \ No newline at end of file diff --git a/server/player_manager.cpp b/server/player_manager.cpp index a708874..d5bfebe 100644 --- a/server/player_manager.cpp +++ b/server/player_manager.cpp @@ -37,6 +37,12 @@ int PlayerManager::HandlePlayerUnload(int uniqueID) { // } +void PlayerManager::ForEach(Lambda fn) { + for(Iterator it = playerMap.begin(); it != playerMap.end(); it++) { + fn(it); + } +} + PlayerEntry* PlayerManager::GetPlayer(int uniqueID) { for (auto& it : playerMap) { if (it.first == uniqueID) { diff --git a/server/player_manager.hpp b/server/player_manager.hpp index 50ba849..d4051bd 100644 --- a/server/player_manager.hpp +++ b/server/player_manager.hpp @@ -24,6 +24,9 @@ #include "vector2.hpp" +#include "sqlite3/sqlite3.h" + +#include #include #include @@ -36,24 +39,33 @@ struct PlayerEntry { class PlayerManager { public: + //clarity typedefs + typedef std::map Container; + typedef Container::iterator Iterator; + typedef std::function Lambda; + //These functions interact with the database //*Deletion, *Load and *Unload returns: 0 success, -1 failure //*Creation returns the uniqueID, but doesn't load // that object; call *Load directly afterward - int HandlePlayerCreation (std::string name, std::string avatar); int HandlePlayerDeletion (int uniqueID); int HandlePlayerLoad (int uniqueID, int clientIndex); int HandlePlayerUnload (int uniqueID); - //basic accessor - PlayerEntry* GetPlayer (int uniqueID); + //lambdas + void ForEach(Lambda); + + //accessors + PlayerEntry* GetPlayer(int uniqueID); + sqlite3* SetDatabase(sqlite3* db) { return database = db; } + sqlite3* GetDatabase() { return database; } //update each player's position void Update(double delta); private: - std::map playerMap; - //database connection here + Container playerMap; + sqlite3* database = nullptr; }; #endif diff --git a/server/server_application.cpp b/server/server_application.cpp index 0b008b3..e64adbb 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -30,16 +30,18 @@ using namespace std; -void runSQLScript(sqlite3* db, std::string fname) { - //Run setup scripts +int runSQLScript(sqlite3* db, std::string fname) { ifstream is(fname); if (!is.is_open()) { - throw(runtime_error("Failed to run SQL script")); + return -1; } string script; getline(is, script, '\0'); is.close(); - sqlite3_exec(db, script.c_str(), nullptr, nullptr, nullptr); + //TODO: flesh out this error if needed + if (sqlite3_exec(db, script.c_str(), nullptr, nullptr, nullptr) != SQLITE_OK) { + return -2; + } } //------------------------- @@ -47,6 +49,9 @@ void runSQLScript(sqlite3* db, std::string fname) { //------------------------- void ServerApplication::Init(int argc, char** argv) { + cout << "Beginning startup" << endl; + int ret = 0; + //load config config.Load("rsc\\config.cfg"); @@ -54,28 +59,45 @@ void ServerApplication::Init(int argc, char** argv) { if (SDL_Init(0)) { throw(runtime_error("Failed to initialize SDL")); } - cout << "initialized SDL" << endl; + cout << "Initialized SDL" << endl; //Init SDL_net if (SDLNet_Init()) { throw(runtime_error("Failed to initialize SDL_net")); } network.Open(config.Int("server.port"), sizeof(NetworkPacket)); - cout << "initialized SDL_net" << endl; + cout << "Initialized SDL_net" << endl; //Init SQL - int ret = sqlite3_open_v2(config["server.dbname"].c_str(), &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, nullptr); + 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")); + throw(runtime_error(string() + "Failed to initialize SQL: " + sqlite3_errmsg(database) )); } - cout << "initialized SQL" << endl; + playerMgr.SetDatabase(database); + cout << "Initialized SQL" << endl; //setup the database - runSQLScript(database, config["dir.scripts"] + "setup_server.sql"); - cout << "initialized " << config["server.dbname"] << endl; + if (runSQLScript(database, config["dir.scripts"] + "setup_server.sql")) { + throw(runtime_error("Failed to initialize SQL's setup script")); + } + cout << "Initialized SQL's setup script" << endl; //lua - //TODO + luaState = luaL_newstate(); + if (!luaState) { + throw(runtime_error("Failed to initialize lua")); + } + luaL_openlibs(luaState); + cout << "Initialized lua" << endl; + + //run the startup script + if (luaL_dofile(luaState, (config["dir.scripts"] + "setup_server.lua").c_str())) { + throw(runtime_error(string() + "Failed to initialize lua's setup script: " + lua_tostring(luaState, -1) )); + } + cout << "Initialized lua's setup script" << endl; + + //finalize the startup + cout << "Startup completed successfully" << endl; } void ServerApplication::Loop() { @@ -96,15 +118,19 @@ void ServerApplication::Loop() { } void ServerApplication::Quit() { + cout << "Shutting down" << endl; //empty the members //TODO: player manager //TODO: client manager //APIs + lua_close(luaState); + playerMgr.SetDatabase(nullptr); sqlite3_close_v2(database); network.Close(); SDLNet_Quit(); SDL_Quit(); + cout << "Shutdown finished" << endl; } //------------------------- diff --git a/server/server_application.hpp b/server/server_application.hpp index 5aeb872..bc033af 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -27,6 +27,7 @@ #include "udp_network_utility.hpp" //APIs +#include "lua/lua.hpp" #include "sqlite3/sqlite3.h" #include "SDL/SDL.h" @@ -73,13 +74,14 @@ private: sqlite3* database = nullptr; //lua - //TODO + lua_State* luaState = nullptr; //misc bool running = true; ConfigUtility config; ClientManager clientMgr; + PlayerManager playerMgr; }; #endif