diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index cefcc86..b156064 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() { @@ -88,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); } @@ -287,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; @@ -295,21 +301,28 @@ void InWorld::SendState() { packet.playerInfo.position = localCharacter->GetPosition(); packet.playerInfo.motion = localCharacter->GetMotion(); - network.Send(Channels::SERVER, &packet, 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; - network.Send(Channels::SERVER, &packet, 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; - network.Send(Channels::SERVER, &packet, 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..4b1c5fb 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); } @@ -125,10 +125,14 @@ 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; + char buffer[sizeof(NetworkPacket)]; + + //broadcast to the network, or a specific server packet.meta.type = NetworkPacket::Type::BROADCAST_REQUEST; - network.Send(config["server.host"].c_str(), config.Int("server.port"), reinterpret_cast(&packet), 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(); @@ -136,10 +140,14 @@ 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; + char buffer[sizeof(NetworkPacket)]; + + //join the selected server packet.meta.type = NetworkPacket::Type::JOIN_REQUEST; - network.Send(&selection->address, &packet, 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/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/common/network/serial.cpp b/common/network/serial.cpp new file mode 100644 index 0000000..c6f263b --- /dev/null +++ b/common/network/serial.cpp @@ -0,0 +1,207 @@ +/* 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 +//#include + +//using namespace std; + +//------------------------- +//internal serialization functions +//------------------------- + +void serializeType(NetworkPacket* packet, char* buffer) { +// cout << "serializeType" << endl; + memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type)); +} + +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, 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, 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, char* buffer) { +// cout << "deserializeType" << endl; + memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type)); +} + +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, 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, 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)); +} + +//------------------------- +//the interface functions +//------------------------- + +void serialize(NetworkPacket* packet, void* buffer) { + 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::SYNCHRONIZE: + serializeType(packet, reinterpret_cast(buffer)); + break; + + //Server info + case NetworkPacket::Type::BROADCAST_RESPONSE: + serializeServer(packet, reinterpret_cast(buffer)); + break; + + //Client info + case NetworkPacket::Type::JOIN_RESPONSE: + case NetworkPacket::Type::DISCONNECT: + case NetworkPacket::Type::SHUTDOWN: + 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, reinterpret_cast(buffer)); + break; + } +// for (int i = 0; i < sizeof(NetworkPacket); i++) { +// cout << ((char*)(buffer))[i]; +// } +// cout << endl; +} + +void deserialize(NetworkPacket* packet, void* buffer) { + //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: + case NetworkPacket::Type::PING: + case NetworkPacket::Type::PONG: + case NetworkPacket::Type::BROADCAST_REQUEST: + case NetworkPacket::Type::JOIN_REQUEST: + case NetworkPacket::Type::SYNCHRONIZE: + // + break; + + //Server info + case NetworkPacket::Type::BROADCAST_RESPONSE: + deserializeServer(packet, reinterpret_cast(buffer)); + break; + + //Client info + case NetworkPacket::Type::JOIN_RESPONSE: + case NetworkPacket::Type::DISCONNECT: + case NetworkPacket::Type::SHUTDOWN: + 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, reinterpret_cast(buffer)); + break; + } +// for (int i = 0; i < sizeof(NetworkPacket); i++) { +// cout << ((char*)(buffer))[i]; +// } +// cout << endl; +} \ No newline at end of file diff --git a/server/client.hpp b/common/network/serial.hpp similarity index 79% rename from server/client.hpp rename to common/network/serial.hpp index c2d2194..ef0c291 100644 --- a/server/client.hpp +++ b/common/network/serial.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,12 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#ifndef CLIENT_HPP_ -#define CLIENT_HPP_ +#ifndef SERIAL_HPP_ +#define SERIAL_HPP_ -#include "SDL/SDL_net.h" +#include "network_packet.hpp" -#include - -/* Hold the client info. -*/ - -struct Client { - IPaddress address; -}; - -typedef std::map ClientMap; +void serialize(NetworkPacket* const, void*); +void deserialize(NetworkPacket* const, void*); #endif 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.hpp b/server/player.hpp deleted file mode 100644 index e709ba4..0000000 --- a/server/player.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright: (c) Kayne Ruse 2013 - * - * 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 PLAYER_HPP_ -#define PLAYER_HPP_ - -#include "vector2.hpp" - -#include -#include - -/* Hold the player info. -*/ - -struct Player { - int clientIndex; - std::string handle; - std::string avatar; - Vector2 position; - Vector2 motion; -}; - -typedef std::map PlayerMap; - -#endif diff --git a/server/server_application.cpp b/server/server_application.cpp index c2f79a4..56d1e4f 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -30,20 +30,28 @@ using namespace std; -//------------------------- -//Define the ServerApplication -//------------------------- - -ServerApplication::ServerApplication() { - // +int runSQLScript(sqlite3* db, std::string fname) { + ifstream is(fname); + if (!is.is_open()) { + return -1; + } + string script; + getline(is, script, '\0'); + is.close(); + //TODO: flesh out this error if needed + if (sqlite3_exec(db, script.c_str(), nullptr, nullptr, nullptr) != SQLITE_OK) { + return -2; + } + return 0; } -ServerApplication::~ServerApplication() { - // -} +//------------------------- +//Define the public members +//------------------------- void ServerApplication::Init(int argc, char** argv) { - //TODO: proper command line option parsing + cout << "Beginning startup" << endl; + int ret = 0; //load config config.Load("rsc\\config.cfg"); @@ -52,101 +60,108 @@ 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 init SDL_net")); + 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 - 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); + 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; - cout << "Database filename: " << dbname << endl; + cout << "Initialized SQL" << 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")); + //setup the database + if (runSQLScript(database, config["dir.scripts"] + "setup_server.sql")) { + throw(runtime_error("Failed to initialize SQL's setup script")); } - string script; - getline(is, script, '\0'); - is.close(); - sqlite3_exec(database, script.c_str(), nullptr, nullptr, nullptr); + cout << "Initialized SQL's setup script" << endl; + + //lua + 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() { 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 + deserialize(&packet, network.GetInData()); + //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(); + cout << "Shutting down" << endl; + //empty the members + //TODO: player manager + //TODO: client manager //APIs + lua_close(luaState); sqlite3_close_v2(database); + network.Close(); SDLNet_Quit(); SDL_Quit(); + cout << "Shutdown finished" << endl; } +//------------------------- +//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); break; - case NetworkPacket::Type::SHUTDOWN: HandleShutdown(packet); break; - case NetworkPacket::Type::PLAYER_NEW: HandlePlayerNew(packet); break; - case NetworkPacket::Type::PLAYER_DELETE: HandlePlayerDelete(packet); break; - case NetworkPacket::Type::PLAYER_UPDATE: HandlePlayerUpdate(packet); break; - //handle errors default: throw(runtime_error("Unknown NetworkPacket::Type encountered")); @@ -154,27 +169,35 @@ void ServerApplication::HandlePacket(NetworkPacket packet) { } } +//------------------------- +//Handle various network input +//------------------------- + void ServerApplication::HandleBroadcastRequest(NetworkPacket packet) { - //send back the server's name + //send back the server's metadata packet.meta.type = NetworkPacket::Type::BROADCAST_RESPONSE; + //TODO: version info snprintf(packet.serverInfo.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str()); - network.Send(&packet.meta.srcAddress, &packet, sizeof(NetworkPacket)); + //TODO: player count + char buffer[sizeof(NetworkPacket)]; + serialize(&packet, buffer); + network.Send(&packet.meta.srcAddress, buffer, 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 + ClientEntry c; + c.address = packet.meta.srcAddress; + clientMap[clientCounter] = c; //send the client their info + char buffer[sizeof(NetworkPacket)]; + packet.meta.type = NetworkPacket::Type::JOIN_RESPONSE; packet.clientInfo.index = clientCounter; - network.Send(&newClient.address, &packet, sizeof(NetworkPacket)); + serialize(&packet, buffer); + + network.Send(&clientMap[clientCounter].address, buffer, sizeof(NetworkPacket)); //finished this routine clientCounter++; @@ -183,32 +206,36 @@ void ServerApplication::HandleJoinRequest(NetworkPacket packet) { void ServerApplication::HandleDisconnect(NetworkPacket packet) { //disconnect the specified client - network.Send(&clientMap[packet.clientInfo.index].address, &packet, sizeof(NetworkPacket)); + //TODO: authenticate who is disconnecting/kicking + char buffer[sizeof(NetworkPacket)]; + serialize(&packet, buffer); + network.Send(&clientMap[packet.clientInfo.index].address, buffer, sizeof(NetworkPacket)); clientMap.erase(packet.clientInfo.index); - //delete players - erase_if(playerMap, [&](pair it) -> bool { + //delete players from all clients + NetworkPacket delPacket; + delPacket.meta.type = NetworkPacket::Type::PLAYER_DELETE; + + erase_if(playerMap, [&](std::pair it) -> bool { + //find the internal players to delete if (it.second.clientIndex == packet.clientInfo.index) { - NetworkPacket delPacket; - - //data to delete one specific player - delPacket.meta.type = NetworkPacket::Type::PLAYER_DELETE; delPacket.playerInfo.playerIndex = it.first; - - //send to all + //send the delete player command to all clients PumpPacket(delPacket); - return true; } return false; }); + //finished this routine cout << "disconnect, total: " << clientMap.size() << endl; } 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)]; //players newPacket.meta.type = NetworkPacket::Type::PLAYER_UPDATE; @@ -218,7 +245,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)); } } @@ -230,13 +258,15 @@ void ServerApplication::HandleShutdown(NetworkPacket packet) { packet.meta.type = NetworkPacket::Type::DISCONNECT; PumpPacket(packet); + //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}; @@ -263,7 +293,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; @@ -293,8 +323,10 @@ void ServerApplication::HandlePlayerUpdate(NetworkPacket packet) { } void ServerApplication::PumpPacket(NetworkPacket packet) { - //send this packet to all clients + //I don't really like this, but it'll do for now + 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..c131958 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -25,28 +25,40 @@ //networking #include "network_packet.hpp" #include "udp_network_utility.hpp" +#include "serial.hpp" //APIs +#include "lua/lua.hpp" #include "sqlite3/sqlite3.h" #include "SDL/SDL.h" -//misc +//common #include "config_utility.hpp" #include "vector2.hpp" -#include "client.hpp" -#include "player.hpp" - //STL #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: //standard functions - ServerApplication(); - ~ServerApplication(); + ServerApplication() = default; + ~ServerApplication() = default; void Init(int argc, char** argv); void Loop(); @@ -73,13 +85,15 @@ private: //database sqlite3* database = nullptr; + //lua + lua_State* luaState = nullptr; + //misc bool running = true; ConfigUtility config; - //global lists - ClientMap clientMap; - PlayerMap playerMap; + std::map clientMap; + std::map playerMap; int clientCounter = 0; int playerCounter = 0;