From 3b054766897666fe5b3e59c8d1a9fff9a8daa0a0 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 7 Dec 2013 01:33:27 +1100 Subject: [PATCH] Connections and disconnections are working across different clients --- client/scenes/in_world.cpp | 8 +++-- common/utility.hpp | 13 ++++++++ rsc/config.cfg | 4 +++ server/server_application.cpp | 59 ++++++++++++++++++++++++++++++++--- server/server_application.hpp | 1 + 5 files changed, 78 insertions(+), 7 deletions(-) diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index e792422..034e05d 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -66,6 +66,10 @@ InWorld::InWorld(ConfigUtility* const arg1, UDPNetworkUtility* const arg2, int* //send it network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket)); + + //request a sync + packet.meta.type = NetworkPacket::Type::SYNCHRONIZE; + network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket)); } InWorld::~InWorld() { @@ -209,8 +213,8 @@ void InWorld::HandlePlayerDelete(NetworkPacket packet) { void InWorld::HandlePlayerUpdate(NetworkPacket packet) { if (playerCharacters.find(packet.playerInfo.playerIndex) == playerCharacters.end()) { - //TODO: reroute to HandlePlayerNew() - throw(std::runtime_error("Cannot update non-existant players")); + HandlePlayerNew(packet); + return; } playerCharacters[packet.playerInfo.playerIndex].SetPosition(packet.playerInfo.position); diff --git a/common/utility.hpp b/common/utility.hpp index 4bb9ac8..7e380b7 100644 --- a/common/utility.hpp +++ b/common/utility.hpp @@ -32,4 +32,17 @@ std::string to_string_custom(int i); int to_integer_custom(std::string); +//wow +template +void erase_if(ContainerT& items, const PredicateT& predicate) { + for(auto it = items.begin(); it != items.end(); /* empty */) { + if(predicate(*it)) { + it = items.erase(it); + } + else { + ++it; + } + } +}; + #endif diff --git a/rsc/config.cfg b/rsc/config.cfg index 2f7b71b..7790217 100644 --- a/rsc/config.cfg +++ b/rsc/config.cfg @@ -17,4 +17,8 @@ dir.tilesets = rsc/graphics/tilesets/ dir.interface = rsc/graphics/interface/ dir.scripts = rsc/scripts/ +#player options +player.handle = username +player.avatar = elliot2.bmp + #debugging diff --git a/server/server_application.cpp b/server/server_application.cpp index b8ae69d..7b6da76 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -23,6 +23,8 @@ #include "network_packet.hpp" +#include "utility.hpp" + #include #include #include @@ -136,6 +138,10 @@ void ServerApplication::HandlePacket(NetworkPacket packet) { HandleDisconnect(packet); break; + case NetworkPacket::Type::SYNCHRONIZE: + HandleSynchronize(packet); + break; + case NetworkPacket::Type::SHUTDOWN: HandleShutdown(packet); break; @@ -191,11 +197,42 @@ void ServerApplication::HandleDisconnect(NetworkPacket packet) { network.Send(&clientMap[packet.clientInfo.index].address, &packet, sizeof(NetworkPacket)); clientMap.erase(packet.clientInfo.index); - //TODO: remove players + //delete players + erase_if(playerMap, [&](pair it) -> bool { + 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 + PumpPacket(delPacket); + + return true; + } + return false; + }); cout << "disconnect, total: " << clientMap.size() << endl; } +void ServerApplication::HandleSynchronize(NetworkPacket packet) { + //send all the server's data to this client + NetworkPacket newPacket; + + //players + 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; + network.Send(&clientMap[packet.clientInfo.index].address, &newPacket, sizeof(NetworkPacket)); + } +} + void ServerApplication::HandleShutdown(NetworkPacket packet) { //end the server running = false; @@ -213,7 +250,7 @@ void ServerApplication::HandlePlayerNew(NetworkPacket packet) { newPlayer.clientIndex = packet.playerInfo.clientIndex; newPlayer.handle = packet.playerInfo.handle; newPlayer.avatar = packet.playerInfo.avatar; - newPlayer.position = {0,0}; + newPlayer.position = {(rand() % config.Int("screen.w")),(rand() % config.Int("screen.h"))}; newPlayer.motion = {0,0}; //push this player @@ -229,7 +266,6 @@ void ServerApplication::HandlePlayerNew(NetworkPacket packet) { //finish this routine Player::counter++; - cout << "new player, total: " << playerMap.size() << endl; } void ServerApplication::HandlePlayerDelete(NetworkPacket packet) { @@ -237,9 +273,22 @@ void ServerApplication::HandlePlayerDelete(NetworkPacket packet) { throw(std::runtime_error("Cannot delete a non-existant player")); } - playerMap.erase(packet.playerInfo.playerIndex); + //delete players + erase_if(playerMap, [&](pair it) -> bool { + if (it.first == packet.playerInfo.playerIndex) { + NetworkPacket delPacket; - PumpPacket(packet); + //data to delete one specific player + delPacket.meta.type = NetworkPacket::Type::PLAYER_DELETE; + delPacket.playerInfo.playerIndex = it.first; + + //send to all + PumpPacket(delPacket); + + return true; + } + return false; + }); } void ServerApplication::HandlePlayerUpdate(NetworkPacket packet) { diff --git a/server/server_application.hpp b/server/server_application.hpp index 15ed55e..1aaad4f 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -72,6 +72,7 @@ private: void HandleBroadcastRequest(NetworkPacket); void HandleJoinRequest(NetworkPacket); void HandleDisconnect(NetworkPacket); + void HandleSynchronize(NetworkPacket); void HandleShutdown(NetworkPacket); void HandlePlayerNew(NetworkPacket); void HandlePlayerDelete(NetworkPacket);