From a3a990cc0184d4ea016cf3cbc02fd80cbe2b9952 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 6 Dec 2013 17:47:03 +1100 Subject: [PATCH] Added player support to the server This code is essentially copied from the old branch, since the two branches are now functionally identical. How much time have I wasted rewriting this? --- common/network/network_packet.hpp | 16 +++++ common/vector2.hpp | 115 ++++++++++++++++++++++++++++++ server/server_application.cpp | 53 ++++++++++++++ server/server_application.hpp | 16 +++++ 4 files changed, 200 insertions(+) create mode 100644 common/vector2.hpp diff --git a/common/network/network_packet.hpp b/common/network/network_packet.hpp index 1954ade..27c5bee 100644 --- a/common/network/network_packet.hpp +++ b/common/network/network_packet.hpp @@ -24,6 +24,8 @@ #include "SDL/SDL_net.h" +#include "vector2.hpp" + #define PACKET_STRING_SIZE 100 #pragma pack(push, 0) @@ -56,6 +58,9 @@ union NetworkPacket { SHUTDOWN = 9, //Player movement, etc. + PLAYER_NEW = 10, + PLAYER_DELETE = 11, + PLAYER_UPDATE = 12, }; //metadata on the packet itself @@ -78,6 +83,17 @@ union NetworkPacket { int index; }clientInfo; + //information about a player + struct PlayerInformation { + Metadata meta; + int clientIndex; + int playerIndex; + char handle[PACKET_STRING_SIZE]; + char avatar[PACKET_STRING_SIZE]; + Vector2 position; + Vector2 motion; + }playerInfo; + //defaults NetworkPacket() { meta.type = Type::NONE; diff --git a/common/vector2.hpp b/common/vector2.hpp new file mode 100644 index 0000000..a7a721d --- /dev/null +++ b/common/vector2.hpp @@ -0,0 +1,115 @@ +/* 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 VECTOR2_HPP_ +#define VECTOR2_HPP_ + +#include +#include + +class Vector2 { +public: + double x, y; + + //This is explicitly a POD + Vector2() = default; + Vector2(double i, double j): x(i), y(j) {}; + ~Vector2() = default; + Vector2& operator=(Vector2 const&) = default; + + double Length() const { + return sqrt(x*x+y*y); + } + double SquaredLength() const { + return x*x+y*y; + } + + double operator[](size_t i) { + if (i >= 2) + throw(std::domain_error("Out of range")); + return *(&x+i); + } + + //Arithmetic operators + Vector2 operator+(Vector2 v) const { + Vector2 ret; + ret.x = x + v.x; + ret.y = y + v.y; + return ret; + } + Vector2 operator-(Vector2 v) const { + Vector2 ret; + ret.x = x - v.x; + ret.y = y - v.y; + return ret; + } + Vector2 operator*(Vector2 v) const { + Vector2 ret; + ret.x = x * v.x; + ret.y = y * v.y; + return ret; + } + Vector2 operator*(double d) const { + Vector2 ret; + ret.x = x * d; + ret.y = y * d; + return ret; + } + + Vector2 operator/(Vector2 v) { + if (!v.x || !v.y) + throw(std::domain_error("Divide by zero")); + Vector2 ret; + ret.x = x / v.x; + ret.y = y / v.y; + return ret; + } + Vector2 operator/(double d) { + if (!d) + throw(std::domain_error("Divide by zero")); + Vector2 ret; + ret.x = x / d; + ret.y = y / d; + return ret; + } + + bool operator==(Vector2 v) { return (x == v.x && y == v.y); } + bool operator!=(Vector2 v) { return (x != v.x || y != v.y); } + + //member templates (curry the above operators) + template Vector2 operator+=(T t) { return *this = *this + t; } + template Vector2 operator-=(T t) { return *this = *this - t; } + template Vector2 operator*=(T t) { return *this = *this * t; } + template Vector2 operator/=(T t) { return *this = *this / t; } + template bool operator==(T t) { return (x == t && y == t); } + template bool operator!=(T t) { return (x != t || y != t); } +}; + +//non-member templates (flip the order) +template Vector2 operator+(T t, Vector2 v) { return v + t; } +template Vector2 operator-(T t, Vector2 v) { return v - t; } +template Vector2 operator*(T t, Vector2 v) { return v * t; } +template Vector2 operator/(T t, Vector2 v) { return v / t; } + +template bool operator==(T t, Vector2 v) { return v == t; } +template bool operator!=(T t, Vector2 v) { return v != t; } + +#endif diff --git a/server/server_application.cpp b/server/server_application.cpp index 9d71ee7..42dcc76 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -35,6 +35,7 @@ using namespace std; //------------------------- int Client::counter = 0; +int Player::counter = 0; //------------------------- //Define the ServerApplication @@ -139,6 +140,18 @@ void ServerApplication::HandlePacket(NetworkPacket packet) { 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")); @@ -195,3 +208,43 @@ void ServerApplication::HandleShutdown(NetworkPacket packet) { cout << "shutting down" << endl; } + +void ServerApplication::HandlePlayerNew(NetworkPacket packet) { + //create the new player object + Player newPlayer; + newPlayer.clientIndex = packet.playerInfo.clientIndex; + newPlayer.handle = packet.playerInfo.handle; + newPlayer.avatar = packet.playerInfo.avatar; + newPlayer.position = {0,0}; + newPlayer.motion = {0,0}; + + //push this player + playerMap[Player::counter] = newPlayer; + + //send the client their info + packet.playerInfo.playerIndex = Player::counter; + packet.playerInfo.position = newPlayer.position; + packet.playerInfo.motion = newPlayer.motion; + network.Send(&clientMap[newPlayer.clientIndex].address, &packet, sizeof(NetworkPacket)); + + //finish this routine + Player::counter++; + cout << "new player, total: " << playerMap.size() << endl; +} + +void ServerApplication::HandlePlayerDelete(NetworkPacket packet) { + if (playerMap.find(packet.playerInfo.playerIndex) == playerMap.end()) { + throw(std::runtime_error("Cannot delete a non-existant player")); + } + + playerMap.erase(packet.playerInfo.playerIndex); +} + +void ServerApplication::HandlePlayerUpdate(NetworkPacket packet) { + if (playerMap.find(packet.playerInfo.playerIndex) == playerMap.end()) { + throw(std::runtime_error("Cannot update a non-existant player")); + } + + playerMap[packet.playerInfo.playerIndex].position = packet.playerInfo.position; + playerMap[packet.playerInfo.playerIndex].motion = packet.playerInfo.motion; +} diff --git a/server/server_application.hpp b/server/server_application.hpp index fb8958c..4b10207 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -32,9 +32,11 @@ //misc #include "config_utility.hpp" +#include "vector2.hpp" //STL #include +#include //hold the client info struct Client { @@ -42,6 +44,16 @@ struct Client { IPaddress address; }; +//hold the player info +struct Player { + static int counter; + int clientIndex; + std::string handle; + std::string avatar; + Vector2 position; + Vector2 motion; +}; + //The main application class class ServerApplication { public: @@ -61,6 +73,9 @@ private: void HandleJoinRequest(NetworkPacket); void HandleDisconnect(NetworkPacket); void HandleShutdown(NetworkPacket); + void HandlePlayerNew(NetworkPacket); + void HandlePlayerDelete(NetworkPacket); + void HandlePlayerUpdate(NetworkPacket); //networking UDPNetworkUtility network; @@ -73,6 +88,7 @@ private: ConfigUtility config; std::map clientMap; + std::map playerMap; }; #endif