From 1c032bfc4703a804634e2053cc8527d1f25a9cee Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 6 Dec 2013 23:03:46 +1100 Subject: [PATCH] Implemented client-side player creation; incomplete --- client/scenes/in_world.cpp | 80 ++++++++++++++++++++++++++++++++--- client/scenes/in_world.hpp | 8 ++++ server/server_application.cpp | 22 +++++++--- server/server_application.hpp | 2 + 4 files changed, 100 insertions(+), 12 deletions(-) diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index fdbea22..e792422 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -54,6 +54,18 @@ InWorld::InWorld(ConfigUtility* const arg1, UDPNetworkUtility* const arg2, int* //set the button texts disconnectButton.SetText("Disconnect"); shutDownButton.SetText("Shut Down"); + + //create the server-side player object + NetworkPacket packet; + packet.meta.type = NetworkPacket::Type::PLAYER_NEW; + packet.playerInfo.clientIndex = clientIndex; + snprintf(packet.playerInfo.handle, PACKET_STRING_SIZE, "%s", config["player.handle"].c_str()); + snprintf(packet.playerInfo.avatar, PACKET_STRING_SIZE, "%s", config["player.avatar"].c_str()); + packet.playerInfo.position = {0,0}; + packet.playerInfo.motion = {0,0}; + + //send it + network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket)); } InWorld::~InWorld() { @@ -76,6 +88,10 @@ void InWorld::Update(double delta) { packet.meta.srcAddress = network.GetInPacket()->address; HandlePacket(packet); } + + for (auto& it : playerCharacters) { + it.second.Update(delta); + } } void InWorld::FrameEnd() { @@ -83,6 +99,9 @@ void InWorld::FrameEnd() { } void InWorld::Render(SDL_Surface* const screen) { + for (auto& it : playerCharacters) { + it.second.DrawTo(screen); + } disconnectButton.DrawTo(screen); shutDownButton.DrawTo(screen); } @@ -135,14 +154,21 @@ void InWorld::KeyUp(SDL_KeyboardEvent const& key) { } void InWorld::HandlePacket(NetworkPacket packet) { - switch(packet.meta.type) { + switch(packet.meta.type) { case NetworkPacket::Type::DISCONNECT: - network.Unbind(Channels::SERVER); - clientIndex = -1; - SetNextScene(SceneList::MAINMENU); + HandleDisconnect(packet); break; - case NetworkPacket::Type::SYNCHRONIZE: - //TODO + + 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 @@ -150,4 +176,44 @@ void InWorld::HandlePacket(NetworkPacket packet) { throw(std::runtime_error("Unknown NetworkPacket::Type encountered")); break; } -} \ No newline at end of file +} + +void InWorld::HandleDisconnect(NetworkPacket packet) { + network.Unbind(Channels::SERVER); + clientIndex = -1; + SetNextScene(SceneList::MAINMENU); +} + +void InWorld::HandlePlayerNew(NetworkPacket packet) { + if (playerCharacters.find(packet.playerInfo.playerIndex) != playerCharacters.end()) { + throw(std::runtime_error("Cannot create duplicate players")); + } + + playerCharacters[packet.playerInfo.playerIndex].GetSprite()->LoadSurface(config["dir.sprites"] + packet.playerInfo.avatar, 4, 4); + playerCharacters[packet.playerInfo.playerIndex].SetPosition(packet.playerInfo.position); + playerCharacters[packet.playerInfo.playerIndex].SetMotion(packet.playerInfo.motion); + playerCharacters[packet.playerInfo.playerIndex].ResetDirection(); + + //TODO: catch this client's player object +} + +void InWorld::HandlePlayerDelete(NetworkPacket packet) { + if (playerCharacters.find(packet.playerInfo.playerIndex) == playerCharacters.end()) { + throw(std::runtime_error("Cannot delete non-existant players")); + } + + playerCharacters.erase(packet.playerInfo.playerIndex); + + //TODO: catch this client's player object +} + +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")); + } + + playerCharacters[packet.playerInfo.playerIndex].SetPosition(packet.playerInfo.position); + playerCharacters[packet.playerInfo.playerIndex].SetMotion(packet.playerInfo.motion); + playerCharacters[packet.playerInfo.playerIndex].ResetDirection(); +} diff --git a/client/scenes/in_world.hpp b/client/scenes/in_world.hpp index 7af63a1..a832bc3 100644 --- a/client/scenes/in_world.hpp +++ b/client/scenes/in_world.hpp @@ -30,6 +30,9 @@ #include "image.hpp" #include "raster_font.hpp" #include "button.hpp" +#include "player_character.hpp" + +#include class InWorld : public BaseScene { public: @@ -52,6 +55,10 @@ protected: void KeyUp(SDL_KeyboardEvent const&); void HandlePacket(NetworkPacket); + void HandleDisconnect(NetworkPacket); + void HandlePlayerNew(NetworkPacket); + void HandlePlayerDelete(NetworkPacket); + void HandlePlayerUpdate(NetworkPacket); //global ConfigUtility& config; @@ -63,6 +70,7 @@ protected: RasterFont font; Button disconnectButton; Button shutDownButton; + std::map playerCharacters; }; #endif diff --git a/server/server_application.cpp b/server/server_application.cpp index 42dcc76..b8ae69d 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -191,7 +191,7 @@ void ServerApplication::HandleDisconnect(NetworkPacket packet) { network.Send(&clientMap[packet.clientInfo.index].address, &packet, sizeof(NetworkPacket)); clientMap.erase(packet.clientInfo.index); - //TODO: remove players? + //TODO: remove players cout << "disconnect, total: " << clientMap.size() << endl; } @@ -202,9 +202,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); cout << "shutting down" << endl; } @@ -225,7 +223,9 @@ void ServerApplication::HandlePlayerNew(NetworkPacket packet) { packet.playerInfo.playerIndex = Player::counter; packet.playerInfo.position = newPlayer.position; packet.playerInfo.motion = newPlayer.motion; - network.Send(&clientMap[newPlayer.clientIndex].address, &packet, sizeof(NetworkPacket)); + + //actually send to everyone + PumpPacket(packet); //finish this routine Player::counter++; @@ -238,6 +238,8 @@ void ServerApplication::HandlePlayerDelete(NetworkPacket packet) { } playerMap.erase(packet.playerInfo.playerIndex); + + PumpPacket(packet); } void ServerApplication::HandlePlayerUpdate(NetworkPacket packet) { @@ -245,6 +247,16 @@ void ServerApplication::HandlePlayerUpdate(NetworkPacket packet) { throw(std::runtime_error("Cannot update a non-existant player")); } + //server is the slave to the clients, but only for now playerMap[packet.playerInfo.playerIndex].position = packet.playerInfo.position; playerMap[packet.playerInfo.playerIndex].motion = packet.playerInfo.motion; + + 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 4b10207..15ed55e 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -77,6 +77,8 @@ private: void HandlePlayerDelete(NetworkPacket); void HandlePlayerUpdate(NetworkPacket); + void PumpPacket(NetworkPacket); + //networking UDPNetworkUtility network;