From 7bb5e8ce0dbf2d6090b91b2ba68037ad09970653 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 2 Mar 2014 23:20:37 +1100 Subject: [PATCH 01/12] 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 02/12] 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 03/12] 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 From a850d6b1af693d8a68d1f0a65a33fbac6007bf6b Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Thu, 6 Mar 2014 00:20:31 +1100 Subject: [PATCH 04/12] Added dummy serialization functions --- client/scenes/in_world.cpp | 20 +++++++++++++++----- client/scenes/in_world.hpp | 1 + client/scenes/lobby_menu.cpp | 10 +++++++--- client/scenes/lobby_menu.hpp | 1 + common/network/serial.cpp | 32 ++++++++++++++++++++++++++++++++ common/network/serial.hpp | 30 ++++++++++++++++++++++++++++++ server/server_application.cpp | 22 ++++++++++++++++------ server/server_application.hpp | 1 + 8 files changed, 103 insertions(+), 14 deletions(-) create mode 100644 common/network/serial.cpp create mode 100644 common/network/serial.hpp diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index cefcc86..9a8ba5b 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -65,11 +65,14 @@ InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNet packet.playerInfo.motion = {0,0}; //send it - network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket)); + char buffer[sizeof(NetworkPacket)]; + serialize(&packet, buffer); + network.Send(Channels::SERVER, buffer, sizeof(NetworkPacket)); //request a sync packet.meta.type = NetworkPacket::Type::SYNCHRONIZE; - network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket)); + serialize(&packet, buffer); + network.Send(Channels::SERVER, buffer, sizeof(NetworkPacket)); } InWorld::~InWorld() { @@ -295,7 +298,10 @@ void InWorld::SendState() { packet.playerInfo.position = localCharacter->GetPosition(); packet.playerInfo.motion = localCharacter->GetMotion(); - network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket)); + char buffer[sizeof(NetworkPacket)]; + serialize(&packet, buffer); + + network.Send(Channels::SERVER, buffer, sizeof(NetworkPacket)); } void InWorld::RequestDisconnect() { @@ -303,7 +309,9 @@ void InWorld::RequestDisconnect() { NetworkPacket packet; packet.meta.type = NetworkPacket::Type::DISCONNECT; packet.clientInfo.index = clientIndex; - network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket)); + char buffer[sizeof(NetworkPacket)]; + serialize(&packet, buffer); + network.Send(Channels::SERVER, buffer, sizeof(NetworkPacket)); } void InWorld::RequestShutDown() { @@ -311,5 +319,7 @@ void InWorld::RequestShutDown() { NetworkPacket packet; packet.meta.type = NetworkPacket::Type::SHUTDOWN; packet.clientInfo.index = clientIndex; - network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket)); + char buffer[sizeof(NetworkPacket)]; + serialize(&packet, buffer); + network.Send(Channels::SERVER, buffer, sizeof(NetworkPacket)); } \ No newline at end of file diff --git a/client/scenes/in_world.hpp b/client/scenes/in_world.hpp index 666437a..b3b74f9 100644 --- a/client/scenes/in_world.hpp +++ b/client/scenes/in_world.hpp @@ -27,6 +27,7 @@ #include "config_utility.hpp" #include "udp_network_utility.hpp" #include "network_packet.hpp" +#include "serial.hpp" #include "image.hpp" #include "raster_font.hpp" #include "button.hpp" diff --git a/client/scenes/lobby_menu.cpp b/client/scenes/lobby_menu.cpp index 9f91b68..dfed9e4 100644 --- a/client/scenes/lobby_menu.cpp +++ b/client/scenes/lobby_menu.cpp @@ -80,7 +80,7 @@ void LobbyMenu::Update(double delta) { //suck in all waiting packets NetworkPacket packet; while(network.Receive()) { - memcpy(&packet, network.GetInData(), sizeof(NetworkPacket)); + deserialize(&packet, network.GetInData()); packet.meta.srcAddress = network.GetInPacket()->address; HandlePacket(packet); } @@ -128,7 +128,9 @@ void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { //broadcast to the network, or a specific server NetworkPacket packet; packet.meta.type = NetworkPacket::Type::BROADCAST_REQUEST; - network.Send(config["server.host"].c_str(), config.Int("server.port"), reinterpret_cast(&packet), sizeof(NetworkPacket)); + char buffer[sizeof(NetworkPacket)]; + serialize(&packet, buffer); + network.Send(config["server.host"].c_str(), config.Int("server.port"), buffer, sizeof(NetworkPacket)); //reset the server list serverInfo.clear(); @@ -139,7 +141,9 @@ void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { //join the selected server NetworkPacket packet; packet.meta.type = NetworkPacket::Type::JOIN_REQUEST; - network.Send(&selection->address, &packet, sizeof(NetworkPacket)); + char buffer[sizeof(NetworkPacket)]; + serialize(&packet, buffer); + network.Send(&selection->address, buffer, sizeof(NetworkPacket)); selection = nullptr; } diff --git a/client/scenes/lobby_menu.hpp b/client/scenes/lobby_menu.hpp index fc3551a..36cfbe7 100644 --- a/client/scenes/lobby_menu.hpp +++ b/client/scenes/lobby_menu.hpp @@ -31,6 +31,7 @@ #include "config_utility.hpp" #include "udp_network_utility.hpp" #include "network_packet.hpp" +#include "serial.hpp" #include diff --git a/common/network/serial.cpp b/common/network/serial.cpp new file mode 100644 index 0000000..73f92c1 --- /dev/null +++ b/common/network/serial.cpp @@ -0,0 +1,32 @@ +/* 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 "serial.hpp" + +#include + +void serialize(NetworkPacket* const packet, void* buffer) { + memcpy(buffer, packet, sizeof(NetworkPacket)); +} + +void deserialize(NetworkPacket* const packet, void* buffer) { + memcpy(packet, buffer, sizeof(NetworkPacket)); +} \ No newline at end of file diff --git a/common/network/serial.hpp b/common/network/serial.hpp new file mode 100644 index 0000000..ef0c291 --- /dev/null +++ b/common/network/serial.hpp @@ -0,0 +1,30 @@ +/* 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 SERIAL_HPP_ +#define SERIAL_HPP_ + +#include "network_packet.hpp" + +void serialize(NetworkPacket* const, void*); +void deserialize(NetworkPacket* const, void*); + +#endif diff --git a/server/server_application.cpp b/server/server_application.cpp index c2f79a4..9136327 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -89,7 +89,7 @@ void ServerApplication::Loop() { //suck in the waiting packets & process them try { while(network.Receive()) { - memcpy(&packet, network.GetInData(), sizeof(NetworkPacket)); + deserialize(&packet, network.GetInData()); packet.meta.srcAddress = network.GetInPacket()->address; HandlePacket(packet); } @@ -158,7 +158,9 @@ void ServerApplication::HandleBroadcastRequest(NetworkPacket packet) { //send back the server's name packet.meta.type = NetworkPacket::Type::BROADCAST_RESPONSE; snprintf(packet.serverInfo.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str()); - network.Send(&packet.meta.srcAddress, &packet, sizeof(NetworkPacket)); + char buffer[sizeof(NetworkPacket)]; + serialize(&packet, buffer); + network.Send(&packet.meta.srcAddress, buffer, sizeof(NetworkPacket)); } void ServerApplication::HandleJoinRequest(NetworkPacket packet) { @@ -174,7 +176,9 @@ void ServerApplication::HandleJoinRequest(NetworkPacket packet) { //send the client their info packet.meta.type = NetworkPacket::Type::JOIN_RESPONSE; packet.clientInfo.index = clientCounter; - network.Send(&newClient.address, &packet, sizeof(NetworkPacket)); + char buffer[sizeof(NetworkPacket)]; + serialize(&packet, buffer); + network.Send(&newClient.address, buffer, sizeof(NetworkPacket)); //finished this routine clientCounter++; @@ -183,7 +187,9 @@ void ServerApplication::HandleJoinRequest(NetworkPacket packet) { void ServerApplication::HandleDisconnect(NetworkPacket packet) { //disconnect the specified client - network.Send(&clientMap[packet.clientInfo.index].address, &packet, sizeof(NetworkPacket)); + char buffer[sizeof(NetworkPacket)]; + serialize(&packet, buffer); + network.Send(&clientMap[packet.clientInfo.index].address, buffer, sizeof(NetworkPacket)); clientMap.erase(packet.clientInfo.index); //delete players @@ -209,6 +215,7 @@ void ServerApplication::HandleDisconnect(NetworkPacket packet) { void ServerApplication::HandleSynchronize(NetworkPacket packet) { //send all the server's data to this client NetworkPacket newPacket; + char buffer[sizeof(NetworkPacket)]; //players newPacket.meta.type = NetworkPacket::Type::PLAYER_UPDATE; @@ -218,7 +225,8 @@ void ServerApplication::HandleSynchronize(NetworkPacket packet) { 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; - network.Send(&clientMap[packet.clientInfo.index].address, &newPacket, sizeof(NetworkPacket)); + serialize(&newPacket, buffer); + network.Send(&clientMap[packet.clientInfo.index].address, buffer, sizeof(NetworkPacket)); } } @@ -294,7 +302,9 @@ void ServerApplication::HandlePlayerUpdate(NetworkPacket packet) { void ServerApplication::PumpPacket(NetworkPacket packet) { //send this packet to all clients + char buffer[sizeof(NetworkPacket)]; + serialize(&packet, buffer); for (auto& it : clientMap) { - network.Send(&it.second.address, &packet, sizeof(NetworkPacket)); + network.Send(&it.second.address, buffer, sizeof(NetworkPacket)); } } \ No newline at end of file diff --git a/server/server_application.hpp b/server/server_application.hpp index 073d480..a339c77 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -25,6 +25,7 @@ //networking #include "network_packet.hpp" #include "udp_network_utility.hpp" +#include "serial.hpp" //APIs #include "sqlite3/sqlite3.h" From 59285d1630481bb6c81ec5f6557193106d6bc957 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 7 Mar 2014 04:49:16 +1100 Subject: [PATCH 05/12] This isn't fucking working --- common/network/serial.cpp | 122 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 118 insertions(+), 4 deletions(-) diff --git a/common/network/serial.cpp b/common/network/serial.cpp index 73f92c1..29f46e1 100644 --- a/common/network/serial.cpp +++ b/common/network/serial.cpp @@ -22,11 +22,125 @@ #include "serial.hpp" #include +#include +using namespace std; -void serialize(NetworkPacket* const packet, void* buffer) { - memcpy(buffer, packet, sizeof(NetworkPacket)); +//------------------------- +//internal serialization functions +//------------------------- + +void serializeType(NetworkPacket* packet, void* buffer) { + memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type)); } -void deserialize(NetworkPacket* const packet, void* buffer) { - memcpy(packet, buffer, sizeof(NetworkPacket)); +void serializeServer(NetworkPacket* packet, void* buffer) { + int len = 0; + memcpy((void*)((int)buffer + len), &packet->meta.type, sizeof(NetworkPacket::Type)); + len += sizeof(NetworkPacket::Type); + memcpy((void*)((int)buffer + len), packet->serverInfo.name, PACKET_STRING_SIZE); + len += PACKET_STRING_SIZE; +} + +void serializeClient(NetworkPacket* packet, void* buffer) { + //TODO +} + +void serializePlayer(NetworkPacket* packet, void* buffer) { + //TODO +} + +//------------------------- +//internal deserialization functions +//------------------------- + +void deserializeType(NetworkPacket* packet, void* buffer) { + memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type)); +} + +void deserializeServer(NetworkPacket* packet, void* buffer) { + int len = 0; + memcpy(&packet->meta.type, (void*)((int)buffer + len), sizeof(NetworkPacket::Type)); + len += sizeof(NetworkPacket::Type); + memcpy(packet->serverInfo.name, (void*)((int)buffer + len), PACKET_STRING_SIZE); + len += PACKET_STRING_SIZE; +} + +void deserializeClient(NetworkPacket* packet, void* buffer) { + //TODO +} + +void deserializePlayer(NetworkPacket* packet, void* buffer) { + //TODO +} + +//------------------------- +//the interface functions +//------------------------- + +void serialize(NetworkPacket* packet, void* buffer) { + cout << (int)packet->meta.type << endl; + switch(packet->meta.type) { + //No extra data + case NetworkPacket::Type::NONE: + case NetworkPacket::Type::PING: + case NetworkPacket::Type::PONG: + case NetworkPacket::Type::BROADCAST_REQUEST: + case NetworkPacket::Type::JOIN_REQUEST: + case NetworkPacket::Type::SHUTDOWN: + serializeType(packet, buffer); + break; + + //Server info + case NetworkPacket::Type::BROADCAST_RESPONSE: + serializeServer(packet, buffer); + break; + + //Client info + case NetworkPacket::Type::JOIN_RESPONSE: + case NetworkPacket::Type::DISCONNECT: + case NetworkPacket::Type::SYNCHRONIZE: + serializeClient(packet, buffer); + break; + + //Player info + case NetworkPacket::Type::PLAYER_NEW: + case NetworkPacket::Type::PLAYER_DELETE: + case NetworkPacket::Type::PLAYER_UPDATE: + serializePlayer(packet, buffer); + break; + } +} + +void deserialize(NetworkPacket* packet, void* buffer) { + cout << (int)packet->meta.type << endl; + switch(packet->meta.type) { + //No extra data + case NetworkPacket::Type::NONE: + case NetworkPacket::Type::PING: + case NetworkPacket::Type::PONG: + case NetworkPacket::Type::BROADCAST_REQUEST: + case NetworkPacket::Type::JOIN_REQUEST: + case NetworkPacket::Type::SHUTDOWN: + deserializeType(packet, buffer); + break; + + //Server info + case NetworkPacket::Type::BROADCAST_RESPONSE: + deserializeServer(packet, buffer); + break; + + //Client info + case NetworkPacket::Type::JOIN_RESPONSE: + case NetworkPacket::Type::DISCONNECT: + case NetworkPacket::Type::SYNCHRONIZE: + deserializeClient(packet, buffer); + break; + + //Player info + case NetworkPacket::Type::PLAYER_NEW: + case NetworkPacket::Type::PLAYER_DELETE: + case NetworkPacket::Type::PLAYER_UPDATE: + deserializePlayer(packet, buffer); + break; + } } \ No newline at end of file From 6a204643f692c445b013183d7830af54d8818ec0 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 7 Mar 2014 20:17:11 +1100 Subject: [PATCH 06/12] Serialization is finally functional --- client/scenes/in_world.cpp | 2 +- common/network/serial.cpp | 133 +++++++++++++++++++++++++++---------- 2 files changed, 98 insertions(+), 37 deletions(-) diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index 9a8ba5b..c316ae8 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -91,7 +91,7 @@ void InWorld::Update(double delta) { //suck in all waiting packets NetworkPacket packet; while(network.Receive()) { - memcpy(&packet, network.GetInData(), sizeof(NetworkPacket)); + deserialize(&packet, network.GetInData()); packet.meta.srcAddress = network.GetInPacket()->address; HandlePacket(packet); } diff --git a/common/network/serial.cpp b/common/network/serial.cpp index 29f46e1..24e802c 100644 --- a/common/network/serial.cpp +++ b/common/network/serial.cpp @@ -22,55 +22,108 @@ #include "serial.hpp" #include -#include -using namespace std; +//#include + +//using namespace std; //------------------------- //internal serialization functions //------------------------- -void serializeType(NetworkPacket* packet, void* buffer) { +void serializeType(NetworkPacket* packet, char* buffer) { +// cout << "serializeType" << endl; memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type)); } -void serializeServer(NetworkPacket* packet, void* buffer) { - int len = 0; - memcpy((void*)((int)buffer + len), &packet->meta.type, sizeof(NetworkPacket::Type)); - len += sizeof(NetworkPacket::Type); - memcpy((void*)((int)buffer + len), packet->serverInfo.name, PACKET_STRING_SIZE); - len += PACKET_STRING_SIZE; +void serializeServer(NetworkPacket* packet, char* buffer) { +// cout << "serializeServer" << endl; + memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type)); + buffer += sizeof(NetworkPacket::Type); + memcpy(buffer, packet->serverInfo.name, PACKET_STRING_SIZE); } -void serializeClient(NetworkPacket* packet, void* buffer) { - //TODO +void serializeClient(NetworkPacket* packet, char* buffer) { +// cout << "serializeClient" << endl; + memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type)); + buffer += sizeof(NetworkPacket::Type); + memcpy(buffer, &packet->clientInfo.index, sizeof(int)); } -void serializePlayer(NetworkPacket* packet, void* buffer) { - //TODO +void serializePlayer(NetworkPacket* packet, char* buffer) { +// cout << "serializePlayer" << endl; + memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type)); + buffer += sizeof(NetworkPacket::Type); + + //indexes + memcpy(buffer, &packet->playerInfo.clientIndex, sizeof(int)); + buffer += sizeof(int); + memcpy(buffer, &packet->playerInfo.playerIndex, sizeof(int)); + buffer += sizeof(int); + + //text + memcpy(buffer, packet->playerInfo.handle, PACKET_STRING_SIZE); + buffer += PACKET_STRING_SIZE; + memcpy(buffer, packet->playerInfo.avatar, PACKET_STRING_SIZE); + buffer += PACKET_STRING_SIZE; + + //vectors + memcpy(buffer, &packet->playerInfo.position.x, sizeof(double)); + buffer += sizeof(double); + memcpy(buffer, &packet->playerInfo.position.y, sizeof(double)); + buffer += sizeof(double); + memcpy(buffer, &packet->playerInfo.motion.x, sizeof(double)); + buffer += sizeof(double); + memcpy(buffer, &packet->playerInfo.motion.y, sizeof(double)); } //------------------------- //internal deserialization functions //------------------------- -void deserializeType(NetworkPacket* packet, void* buffer) { +void deserializeType(NetworkPacket* packet, char* buffer) { +// cout << "deserializeType" << endl; memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type)); } -void deserializeServer(NetworkPacket* packet, void* buffer) { - int len = 0; - memcpy(&packet->meta.type, (void*)((int)buffer + len), sizeof(NetworkPacket::Type)); - len += sizeof(NetworkPacket::Type); - memcpy(packet->serverInfo.name, (void*)((int)buffer + len), PACKET_STRING_SIZE); - len += PACKET_STRING_SIZE; +void deserializeServer(NetworkPacket* packet, char* buffer) { +// cout << "deserializeServer" << endl; + memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type)); + buffer += sizeof(NetworkPacket::Type); + memcpy(packet->serverInfo.name, buffer, PACKET_STRING_SIZE); } -void deserializeClient(NetworkPacket* packet, void* buffer) { - //TODO +void deserializeClient(NetworkPacket* packet, char* buffer) { +// cout << "deserializeClient" << endl; + memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type)); + buffer += sizeof(NetworkPacket::Type); + memcpy(&packet->clientInfo.index, buffer, sizeof(int)); } -void deserializePlayer(NetworkPacket* packet, void* buffer) { - //TODO +void deserializePlayer(NetworkPacket* packet, char* buffer) { +// cout << "deserializePlayer" << endl; + memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type)); + buffer += sizeof(NetworkPacket::Type); + + //indexes + memcpy(&packet->playerInfo.clientIndex, buffer, sizeof(int)); + buffer += sizeof(int); + memcpy(&packet->playerInfo.playerIndex, buffer, sizeof(int)); + buffer += sizeof(int); + + //text + memcpy(packet->playerInfo.handle, buffer, PACKET_STRING_SIZE); + buffer += PACKET_STRING_SIZE; + memcpy(packet->playerInfo.avatar, buffer, PACKET_STRING_SIZE); + buffer += PACKET_STRING_SIZE; + + //vectors + memcpy(&packet->playerInfo.position.x, buffer, sizeof(double)); + buffer += sizeof(double); + memcpy(&packet->playerInfo.position.y, buffer, sizeof(double)); + buffer += sizeof(double); + memcpy(&packet->playerInfo.motion.x, buffer, sizeof(double)); + buffer += sizeof(double); + memcpy(&packet->playerInfo.motion.y, buffer, sizeof(double)); } //------------------------- @@ -78,7 +131,6 @@ void deserializePlayer(NetworkPacket* packet, void* buffer) { //------------------------- void serialize(NetworkPacket* packet, void* buffer) { - cout << (int)packet->meta.type << endl; switch(packet->meta.type) { //No extra data case NetworkPacket::Type::NONE: @@ -86,33 +138,38 @@ void serialize(NetworkPacket* packet, void* buffer) { case NetworkPacket::Type::PONG: case NetworkPacket::Type::BROADCAST_REQUEST: case NetworkPacket::Type::JOIN_REQUEST: + case NetworkPacket::Type::SYNCHRONIZE: case NetworkPacket::Type::SHUTDOWN: - serializeType(packet, buffer); + serializeType(packet, reinterpret_cast(buffer)); break; //Server info case NetworkPacket::Type::BROADCAST_RESPONSE: - serializeServer(packet, buffer); + serializeServer(packet, reinterpret_cast(buffer)); break; //Client info case NetworkPacket::Type::JOIN_RESPONSE: case NetworkPacket::Type::DISCONNECT: - case NetworkPacket::Type::SYNCHRONIZE: - serializeClient(packet, buffer); + serializeClient(packet, reinterpret_cast(buffer)); break; //Player info case NetworkPacket::Type::PLAYER_NEW: case NetworkPacket::Type::PLAYER_DELETE: case NetworkPacket::Type::PLAYER_UPDATE: - serializePlayer(packet, buffer); + serializePlayer(packet, reinterpret_cast(buffer)); break; } +// for (int i = 0; i < sizeof(NetworkPacket); i++) { +// cout << ((char*)(buffer))[i]; +// } +// cout << endl; } void deserialize(NetworkPacket* packet, void* buffer) { - cout << (int)packet->meta.type << endl; + //find the type, so that you can actually deserialize the packet! + deserializeType(packet, reinterpret_cast(buffer)); switch(packet->meta.type) { //No extra data case NetworkPacket::Type::NONE: @@ -120,27 +177,31 @@ void deserialize(NetworkPacket* packet, void* buffer) { case NetworkPacket::Type::PONG: case NetworkPacket::Type::BROADCAST_REQUEST: case NetworkPacket::Type::JOIN_REQUEST: + case NetworkPacket::Type::SYNCHRONIZE: case NetworkPacket::Type::SHUTDOWN: - deserializeType(packet, buffer); + // break; //Server info case NetworkPacket::Type::BROADCAST_RESPONSE: - deserializeServer(packet, buffer); + deserializeServer(packet, reinterpret_cast(buffer)); break; //Client info case NetworkPacket::Type::JOIN_RESPONSE: case NetworkPacket::Type::DISCONNECT: - case NetworkPacket::Type::SYNCHRONIZE: - deserializeClient(packet, buffer); + deserializeClient(packet, reinterpret_cast(buffer)); break; //Player info case NetworkPacket::Type::PLAYER_NEW: case NetworkPacket::Type::PLAYER_DELETE: case NetworkPacket::Type::PLAYER_UPDATE: - deserializePlayer(packet, buffer); + deserializePlayer(packet, reinterpret_cast(buffer)); break; } +// for (int i = 0; i < sizeof(NetworkPacket); i++) { +// cout << ((char*)(buffer))[i]; +// } +// cout << endl; } \ No newline at end of file From 60c31ff56df6fdc524dabfab404b5a0124c94ad3 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 7 Mar 2014 20:27:34 +1100 Subject: [PATCH 07/12] Slight code tweak --- client/scenes/in_world.cpp | 15 +++++++++------ client/scenes/lobby_menu.cpp | 12 ++++++++---- common/network/serial.cpp | 4 ++-- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index c316ae8..b156064 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -290,6 +290,9 @@ void InWorld::HandlePlayerUpdate(NetworkPacket packet) { void InWorld::SendState() { NetworkPacket packet; + char buffer[sizeof(NetworkPacket)]; + + //pack the packet packet.meta.type = NetworkPacket::Type::PLAYER_UPDATE; packet.playerInfo.clientIndex = clientIndex; packet.playerInfo.playerIndex = playerIndex; @@ -298,28 +301,28 @@ void InWorld::SendState() { packet.playerInfo.position = localCharacter->GetPosition(); packet.playerInfo.motion = localCharacter->GetMotion(); - char buffer[sizeof(NetworkPacket)]; serialize(&packet, buffer); - network.Send(Channels::SERVER, buffer, sizeof(NetworkPacket)); } void InWorld::RequestDisconnect() { - //send a disconnect request NetworkPacket packet; + char buffer[sizeof(NetworkPacket)]; + + //send a disconnect request packet.meta.type = NetworkPacket::Type::DISCONNECT; packet.clientInfo.index = clientIndex; - char buffer[sizeof(NetworkPacket)]; serialize(&packet, buffer); network.Send(Channels::SERVER, buffer, sizeof(NetworkPacket)); } void InWorld::RequestShutDown() { - //send a shutdown request NetworkPacket packet; + char buffer[sizeof(NetworkPacket)]; + + //send a shutdown request packet.meta.type = NetworkPacket::Type::SHUTDOWN; packet.clientInfo.index = clientIndex; - char buffer[sizeof(NetworkPacket)]; serialize(&packet, buffer); network.Send(Channels::SERVER, buffer, sizeof(NetworkPacket)); } \ No newline at end of file diff --git a/client/scenes/lobby_menu.cpp b/client/scenes/lobby_menu.cpp index dfed9e4..4b1c5fb 100644 --- a/client/scenes/lobby_menu.cpp +++ b/client/scenes/lobby_menu.cpp @@ -125,10 +125,12 @@ void LobbyMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) { void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { if (search.MouseButtonUp(button) == Button::State::HOVER) { - //broadcast to the network, or a specific server + //the vars NetworkPacket packet; - packet.meta.type = NetworkPacket::Type::BROADCAST_REQUEST; char buffer[sizeof(NetworkPacket)]; + + //broadcast to the network, or a specific server + packet.meta.type = NetworkPacket::Type::BROADCAST_REQUEST; serialize(&packet, buffer); network.Send(config["server.host"].c_str(), config.Int("server.port"), buffer, sizeof(NetworkPacket)); @@ -138,10 +140,12 @@ void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { } else if (join.MouseButtonUp(button) == Button::State::HOVER && selection != nullptr) { - //join the selected server + //the vars NetworkPacket packet; - packet.meta.type = NetworkPacket::Type::JOIN_REQUEST; char buffer[sizeof(NetworkPacket)]; + + //join the selected server + packet.meta.type = NetworkPacket::Type::JOIN_REQUEST; serialize(&packet, buffer); network.Send(&selection->address, buffer, sizeof(NetworkPacket)); selection = nullptr; diff --git a/common/network/serial.cpp b/common/network/serial.cpp index 24e802c..c6f263b 100644 --- a/common/network/serial.cpp +++ b/common/network/serial.cpp @@ -139,7 +139,6 @@ void serialize(NetworkPacket* packet, void* buffer) { case NetworkPacket::Type::BROADCAST_REQUEST: case NetworkPacket::Type::JOIN_REQUEST: case NetworkPacket::Type::SYNCHRONIZE: - case NetworkPacket::Type::SHUTDOWN: serializeType(packet, reinterpret_cast(buffer)); break; @@ -151,6 +150,7 @@ void serialize(NetworkPacket* packet, void* buffer) { //Client info case NetworkPacket::Type::JOIN_RESPONSE: case NetworkPacket::Type::DISCONNECT: + case NetworkPacket::Type::SHUTDOWN: serializeClient(packet, reinterpret_cast(buffer)); break; @@ -178,7 +178,6 @@ void deserialize(NetworkPacket* packet, void* buffer) { case NetworkPacket::Type::BROADCAST_REQUEST: case NetworkPacket::Type::JOIN_REQUEST: case NetworkPacket::Type::SYNCHRONIZE: - case NetworkPacket::Type::SHUTDOWN: // break; @@ -190,6 +189,7 @@ void deserialize(NetworkPacket* packet, void* buffer) { //Client info case NetworkPacket::Type::JOIN_RESPONSE: case NetworkPacket::Type::DISCONNECT: + case NetworkPacket::Type::SHUTDOWN: deserializeClient(packet, reinterpret_cast(buffer)); break; From 56d02ad8d416dcc88178ba30aeb87f3428e46191 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 7 Mar 2014 22:09:50 +1100 Subject: [PATCH 08/12] Working on reimplementing the player characters I've also added EraseIf() to the manager classes. --- server/client_manager.cpp | 13 ++++++++++++- server/client_manager.hpp | 8 ++++---- server/player_manager.cpp | 13 ++++++++++++- server/player_manager.hpp | 8 ++++---- server/server_application.cpp | 29 ++++++++++++++++++----------- server/server_application.hpp | 10 ++++++---- 6 files changed, 56 insertions(+), 25 deletions(-) diff --git a/server/client_manager.cpp b/server/client_manager.cpp index a4d9800..bfcd0a5 100644 --- a/server/client_manager.cpp +++ b/server/client_manager.cpp @@ -38,12 +38,23 @@ int ClientManager::HandleDisconnection(int i) { return -1; } -void ClientManager::ForEach(Lambda fn) { +void ClientManager::ForEach(std::function fn) { for(Iterator it = clientMap.begin(); it != clientMap.end(); it++) { fn(it); } } +void ClientManager::EraseIf(std::function fn) { + for(Iterator it = clientMap.begin(); it != clientMap.end(); /* empty */) { + if(fn(it)) { + it = clientMap.erase(it); + } + else { + ++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 946c946..6f189d4 100644 --- a/server/client_manager.hpp +++ b/server/client_manager.hpp @@ -34,16 +34,16 @@ struct ClientEntry { class ClientManager { public: //clarity typedefs - typedef std::map Container; - typedef Container::iterator Iterator; - typedef std::function Lambda; + typedef std::map Container; + typedef Container::iterator Iterator; //returns the internal index int HandleConnection(IPaddress); int HandleDisconnection(int i); //lambdas - void ForEach(Lambda); + void ForEach(std::function fn); + void EraseIf(std::function fn); //accessors ClientEntry* GetClient(int i); diff --git a/server/player_manager.cpp b/server/player_manager.cpp index d5bfebe..7b08374 100644 --- a/server/player_manager.cpp +++ b/server/player_manager.cpp @@ -37,12 +37,23 @@ int PlayerManager::HandlePlayerUnload(int uniqueID) { // } -void PlayerManager::ForEach(Lambda fn) { +void PlayerManager::ForEach(std::function fn) { for(Iterator it = playerMap.begin(); it != playerMap.end(); it++) { fn(it); } } +void PlayerManager::EraseIf(std::function fn) { + for(Iterator it = playerMap.begin(); it != playerMap.end(); /* empty */) { + if(fn(it)) { + it = playerMap.erase(it); + } + else { + ++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 d4051bd..82770af 100644 --- a/server/player_manager.hpp +++ b/server/player_manager.hpp @@ -40,9 +40,8 @@ struct PlayerEntry { class PlayerManager { public: //clarity typedefs - typedef std::map Container; - typedef Container::iterator Iterator; - typedef std::function Lambda; + typedef std::map Container; + typedef Container::iterator Iterator; //These functions interact with the database //*Deletion, *Load and *Unload returns: 0 success, -1 failure @@ -54,7 +53,8 @@ public: int HandlePlayerUnload (int uniqueID); //lambdas - void ForEach(Lambda); + void ForEach(std::function fn); + void EraseIf(std::function fn); //accessors PlayerEntry* GetPlayer(int uniqueID); diff --git a/server/server_application.cpp b/server/server_application.cpp index b7d7a00..7955ef3 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -209,23 +209,20 @@ void ServerApplication::HandleDisconnect(NetworkPacket packet) { network.Send(&clientMgr.GetClient(packet.clientInfo.index)->address, buffer, sizeof(NetworkPacket)); clientMgr.HandleDisconnection(packet.clientInfo.index); -/* //delete players - erase_if(playerMap, [&](pair it) -> bool { - if (it.second.clientIndex == packet.clientInfo.index) { - NetworkPacket delPacket; + //delete players from all clients + NetworkPacket delPacket; + delPacket.meta.type = NetworkPacket::Type::PLAYER_DELETE; - //data to delete one specific player - delPacket.meta.type = NetworkPacket::Type::PLAYER_DELETE; - delPacket.playerInfo.playerIndex = it.first; - - //send to all + playerMgr.EraseIf([&](PlayerManager::Iterator it) -> bool { + //find the internal players to delete + if (it->first == packet.clientInfo.index) { + delPacket.playerInfo.playerIndex = it->first; + //send the delete player command to all clients PumpPacket(delPacket); - return true; } return false; }); -*/ //finished this routine cout << "disconnect, total: " << clientMgr.Size() << endl; @@ -233,6 +230,7 @@ void ServerApplication::HandleDisconnect(NetworkPacket packet) { /* void ServerApplication::HandleSynchronize(NetworkPacket packet) { //send all the server's data to this client + //TODO: compensate for large distances NetworkPacket newPacket; char buffer[sizeof(NetworkPacket)]; @@ -322,3 +320,12 @@ void ServerApplication::HandlePlayerUpdate(NetworkPacket packet) { PumpPacket(packet); } */ + +void ServerApplication::PumpPacket(NetworkPacket packet) { + //I don't really like this, but it'll do for now + char buffer[sizeof(NetworkPacket)]; + serialize(&packet, buffer); + clientMgr.ForEach([&](ClientManager::Iterator it) { + network.Send(&it->second.address, buffer, sizeof(NetworkPacket)); + }); +} \ No newline at end of file diff --git a/server/server_application.hpp b/server/server_application.hpp index 2733623..d6983ab 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -62,11 +62,13 @@ 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 HandlePlayerNew(NetworkPacket); + void HandlePlayerDelete(NetworkPacket); + void HandlePlayerUpdate(NetworkPacket); + + void PumpPacket(NetworkPacket); //networking UDPNetworkUtility network; From 5cf62f55175032044069b76a16207f22f3baae76 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 9 Mar 2014 01:51:17 +1100 Subject: [PATCH 09/12] Nothing special, just commiting minor changes --- server/server_application.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/server/server_application.cpp b/server/server_application.cpp index 7955ef3..11da6f6 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -150,7 +150,7 @@ void ServerApplication::HandlePacket(NetworkPacket packet) { HandleDisconnect(packet); break; case NetworkPacket::Type::SYNCHRONIZE: -// HandleSynchronize(packet); + HandleSynchronize(packet); break; case NetworkPacket::Type::SHUTDOWN: HandleShutdown(packet); @@ -227,7 +227,7 @@ void ServerApplication::HandleDisconnect(NetworkPacket packet) { //finished this routine cout << "disconnect, total: " << clientMgr.Size() << endl; } -/* + void ServerApplication::HandleSynchronize(NetworkPacket packet) { //send all the server's data to this client //TODO: compensate for large distances @@ -235,18 +235,19 @@ void ServerApplication::HandleSynchronize(NetworkPacket packet) { char buffer[sizeof(NetworkPacket)]; //players + //TODO: replace these lambda functions with proper iteration members newPacket.meta.type = NetworkPacket::Type::PLAYER_UPDATE; - for (auto& it : playerMap) { - 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; + playerMgr.ForEach([&](PlayerManager::Iterator it) { + 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, sizeof(NetworkPacket)); - } + network.Send(&clientMgr.GetClient(it->second.clientIndex)->address, buffer, sizeof(NetworkPacket)); + }); } -*/ + void ServerApplication::HandleShutdown(NetworkPacket packet) { //end the server running = false; @@ -320,7 +321,6 @@ void ServerApplication::HandlePlayerUpdate(NetworkPacket packet) { PumpPacket(packet); } */ - void ServerApplication::PumpPacket(NetworkPacket packet) { //I don't really like this, but it'll do for now char buffer[sizeof(NetworkPacket)]; From 19c1b1197d30064baa2fff46eb65685ad475ba0c Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Mon, 10 Mar 2014 23:15:57 +1100 Subject: [PATCH 10/12] Added a brand new bug, I hate this branch --- server/client_manager.cpp | 75 ---------------------------------- server/client_manager.hpp | 57 -------------------------- server/player_manager.cpp | 70 -------------------------------- server/player_manager.hpp | 71 -------------------------------- server/server_application.cpp | 76 ++++++++++++++++++----------------- server/server_application.hpp | 24 ++++++++--- 6 files changed, 58 insertions(+), 315 deletions(-) delete mode 100644 server/client_manager.cpp delete mode 100644 server/client_manager.hpp delete mode 100644 server/player_manager.cpp delete mode 100644 server/player_manager.hpp diff --git a/server/client_manager.cpp b/server/client_manager.cpp deleted file mode 100644 index bfcd0a5..0000000 --- a/server/client_manager.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* 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; -} - -void ClientManager::ForEach(std::function fn) { - for(Iterator it = clientMap.begin(); it != clientMap.end(); it++) { - fn(it); - } -} - -void ClientManager::EraseIf(std::function fn) { - for(Iterator it = clientMap.begin(); it != clientMap.end(); /* empty */) { - if(fn(it)) { - it = clientMap.erase(it); - } - else { - ++it; - } - } -} - -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_manager.hpp b/server/client_manager.hpp deleted file mode 100644 index 6f189d4..0000000 --- a/server/client_manager.hpp +++ /dev/null @@ -1,57 +0,0 @@ -/* 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 CLIENTMANAGER_HPP_ -#define CLIENTMANAGER_HPP_ - -#include "SDL/SDL_net.h" - -#include -#include - -struct ClientEntry { - IPaddress address; -}; - -class ClientManager { -public: - //clarity typedefs - typedef std::map Container; - typedef Container::iterator Iterator; - - //returns the internal index - int HandleConnection(IPaddress); - int HandleDisconnection(int i); - - //lambdas - void ForEach(std::function fn); - void EraseIf(std::function fn); - - //accessors - ClientEntry* GetClient(int i); - ClientEntry* GetClient(IPaddress); - int Size() { return clientMap.size(); } -private: - Container clientMap; - int counter = 0; -}; - -#endif diff --git a/server/player_manager.cpp b/server/player_manager.cpp deleted file mode 100644 index 7b08374..0000000 --- a/server/player_manager.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* 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 "player_manager.hpp" - -int PlayerManager::HandlePlayerCreation(std::string name, std::string avatar) { - // -} - -int PlayerManager::HandlePlayerDeletion(int uniqueID) { - // -} - -int PlayerManager::HandlePlayerLoad(int uniqueID, int clientIndex) { - // -} - -int PlayerManager::HandlePlayerUnload(int uniqueID) { - // -} - -void PlayerManager::ForEach(std::function fn) { - for(Iterator it = playerMap.begin(); it != playerMap.end(); it++) { - fn(it); - } -} - -void PlayerManager::EraseIf(std::function fn) { - for(Iterator it = playerMap.begin(); it != playerMap.end(); /* empty */) { - if(fn(it)) { - it = playerMap.erase(it); - } - else { - ++it; - } - } -} - -PlayerEntry* PlayerManager::GetPlayer(int uniqueID) { - for (auto& it : playerMap) { - if (it.first == uniqueID) { - return &it.second; - } - } - return nullptr; -} - -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 deleted file mode 100644 index 82770af..0000000 --- a/server/player_manager.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* 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 "sqlite3/sqlite3.h" - -#include -#include -#include - -struct PlayerEntry { - int clientIndex; - int mapIndex; - Vector2 position; - Vector2 motion; -}; - -class PlayerManager { -public: - //clarity typedefs - typedef std::map Container; - typedef Container::iterator Iterator; - - //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); - - //lambdas - void ForEach(std::function fn); - void EraseIf(std::function fn); - - //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: - Container playerMap; - sqlite3* database = nullptr; -}; - -#endif diff --git a/server/server_application.cpp b/server/server_application.cpp index 11da6f6..16c87c3 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -74,7 +74,6 @@ void ServerApplication::Init(int argc, char** argv) { if (ret != SQLITE_OK || !database) { throw(runtime_error(string() + "Failed to initialize SQL: " + sqlite3_errmsg(database) )); } - playerMgr.SetDatabase(database); cout << "Initialized SQL" << endl; //setup the database @@ -126,7 +125,6 @@ void ServerApplication::Quit() { //APIs lua_close(luaState); - playerMgr.SetDatabase(nullptr); sqlite3_close_v2(database); network.Close(); SDLNet_Quit(); @@ -156,13 +154,13 @@ void ServerApplication::HandlePacket(NetworkPacket packet) { 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: @@ -188,35 +186,40 @@ void ServerApplication::HandleBroadcastRequest(NetworkPacket packet) { void ServerApplication::HandleJoinRequest(NetworkPacket packet) { //register the new client - int index = clientMgr.HandleConnection(packet.meta.srcAddress); + ClientEntry c; + c.address = packet.meta.srcAddress; + clientMap[clientCounter] = c; //send the client their info - packet.meta.type = NetworkPacket::Type::JOIN_RESPONSE; - packet.clientInfo.index = index; - char buffer[sizeof(NetworkPacket)]; + + packet.meta.type = NetworkPacket::Type::JOIN_RESPONSE; + packet.clientInfo.index = clientCounter; serialize(&packet, buffer); - network.Send(&clientMgr.GetClient(index)->address, buffer, sizeof(NetworkPacket)); + + network.Send(&clientMap[clientCounter].address, buffer, sizeof(NetworkPacket)); //finished this routine - cout << "connect, total: " << clientMgr.Size() << endl; + clientCounter++; + cout << "connect, total: " << clientMap.size() << endl; } void ServerApplication::HandleDisconnect(NetworkPacket packet) { //disconnect the specified client + //TODO: authenticate who is disconnecting/kicking char buffer[sizeof(NetworkPacket)]; serialize(&packet, buffer); - network.Send(&clientMgr.GetClient(packet.clientInfo.index)->address, buffer, sizeof(NetworkPacket)); - clientMgr.HandleDisconnection(packet.clientInfo.index); + network.Send(&clientMap[packet.clientInfo.index].address, buffer, sizeof(NetworkPacket)); + clientMap.erase(packet.clientInfo.index); //delete players from all clients NetworkPacket delPacket; delPacket.meta.type = NetworkPacket::Type::PLAYER_DELETE; - playerMgr.EraseIf([&](PlayerManager::Iterator it) -> bool { + erase_if(playerMap, [&](std::pair it) -> bool { //find the internal players to delete - if (it->first == packet.clientInfo.index) { - delPacket.playerInfo.playerIndex = it->first; + if (it.first == packet.clientInfo.index) { + delPacket.playerInfo.playerIndex = it.first; //send the delete player command to all clients PumpPacket(delPacket); return true; @@ -225,7 +228,7 @@ void ServerApplication::HandleDisconnect(NetworkPacket packet) { }); //finished this routine - cout << "disconnect, total: " << clientMgr.Size() << endl; + cout << "disconnect, total: " << clientMap.size() << endl; } void ServerApplication::HandleSynchronize(NetworkPacket packet) { @@ -237,15 +240,15 @@ void ServerApplication::HandleSynchronize(NetworkPacket packet) { //players //TODO: replace these lambda functions with proper iteration members newPacket.meta.type = NetworkPacket::Type::PLAYER_UPDATE; - playerMgr.ForEach([&](PlayerManager::Iterator it) { - 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; + for (auto& it : playerMap) { + 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(&clientMgr.GetClient(it->second.clientIndex)->address, buffer, sizeof(NetworkPacket)); - }); + network.Send(&clientMap[it.second.clientIndex].address, buffer, sizeof(NetworkPacket)); + } } void ServerApplication::HandleShutdown(NetworkPacket packet) { @@ -254,18 +257,19 @@ void ServerApplication::HandleShutdown(NetworkPacket packet) { //disconnect all clients packet.meta.type = NetworkPacket::Type::DISCONNECT; - clientMgr.ForEach([&](ClientManager::Iterator it) -> void { - this->network.Send(&it->second.address, &packet, sizeof(NetworkPacket)); - }); + for (auto& it : clientMap) { + 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; + PlayerEntry newPlayer; newPlayer.clientIndex = packet.playerInfo.clientIndex; + newPlayer.mapIndex = 0; newPlayer.handle = packet.playerInfo.handle; newPlayer.avatar = packet.playerInfo.avatar; newPlayer.position = {0,0}; @@ -292,7 +296,7 @@ void ServerApplication::HandlePlayerDelete(NetworkPacket packet) { } //delete players - erase_if(playerMap, [&](pair it) -> bool { + erase_if(playerMap, [&](pair it) -> bool { if (it.first == packet.playerInfo.playerIndex) { NetworkPacket delPacket; @@ -320,12 +324,12 @@ void ServerApplication::HandlePlayerUpdate(NetworkPacket packet) { PumpPacket(packet); } -*/ + void ServerApplication::PumpPacket(NetworkPacket packet) { //I don't really like this, but it'll do for now char buffer[sizeof(NetworkPacket)]; serialize(&packet, buffer); - clientMgr.ForEach([&](ClientManager::Iterator it) { - network.Send(&it->second.address, buffer, sizeof(NetworkPacket)); - }); -} \ No newline at end of file + for (auto& it : clientMap) { + network.Send(&it.second.address, buffer, sizeof(NetworkPacket)); + } +} diff --git a/server/server_application.hpp b/server/server_application.hpp index d6983ab..c131958 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -32,10 +32,6 @@ #include "sqlite3/sqlite3.h" #include "SDL/SDL.h" -//misc -#include "client_manager.hpp" -#include "player_manager.hpp" - //common #include "config_utility.hpp" #include "vector2.hpp" @@ -44,6 +40,19 @@ #include #include +struct ClientEntry { + IPaddress address; +}; + +struct PlayerEntry { + int clientIndex; + int mapIndex; + std::string handle; + std::string avatar; + Vector2 position; + Vector2 motion; +}; + //The main application class class ServerApplication { public: @@ -83,8 +92,11 @@ private: bool running = true; ConfigUtility config; - ClientManager clientMgr; - PlayerManager playerMgr; + std::map clientMap; + std::map playerMap; + + int clientCounter = 0; + int playerCounter = 0; }; #endif From 706aa5e1d73b1c9a462cc35dac527bc34e69a775 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Mon, 10 Mar 2014 23:56:47 +1100 Subject: [PATCH 11/12] Another worthless tweak --- server/server_application.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/server/server_application.cpp b/server/server_application.cpp index 16c87c3..7c2e3d2 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -238,7 +238,6 @@ void ServerApplication::HandleSynchronize(NetworkPacket packet) { char buffer[sizeof(NetworkPacket)]; //players - //TODO: replace these lambda functions with proper iteration members newPacket.meta.type = NetworkPacket::Type::PLAYER_UPDATE; for (auto& it : playerMap) { newPacket.playerInfo.playerIndex = it.first; From 5a57888305a2d8b351b3aa1c3c3d2da5864a1e33 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 11 Mar 2014 18:54:06 +1100 Subject: [PATCH 12/12] Fixed the crash bug --- server/server_application.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/server/server_application.cpp b/server/server_application.cpp index 7c2e3d2..56d1e4f 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -218,7 +218,7 @@ void ServerApplication::HandleDisconnect(NetworkPacket packet) { erase_if(playerMap, [&](std::pair it) -> bool { //find the internal players to delete - if (it.first == packet.clientInfo.index) { + if (it.second.clientIndex == packet.clientInfo.index) { delPacket.playerInfo.playerIndex = it.first; //send the delete player command to all clients PumpPacket(delPacket); @@ -246,7 +246,7 @@ void ServerApplication::HandleSynchronize(NetworkPacket packet) { newPacket.playerInfo.position = it.second.position; newPacket.playerInfo.motion = it.second.motion; serialize(&newPacket, buffer); - network.Send(&clientMap[it.second.clientIndex].address, buffer, sizeof(NetworkPacket)); + network.Send(&clientMap[packet.clientInfo.index].address, buffer, sizeof(NetworkPacket)); } } @@ -256,9 +256,7 @@ void ServerApplication::HandleShutdown(NetworkPacket packet) { //disconnect all clients packet.meta.type = NetworkPacket::Type::DISCONNECT; - for (auto& it : clientMap) { - network.Send(&it.second.address, &packet, sizeof(NetworkPacket)); - } + PumpPacket(packet); //finished this routine cout << "shutting down" << endl;