diff --git a/include/Actor.hpp b/include/Actor.hpp index f997118..1424fae 100644 --- a/include/Actor.hpp +++ b/include/Actor.hpp @@ -95,13 +95,12 @@ namespace Actor { public: Player() : Actor() {} - Player(const sf::Vector2f& pos, const int& ip, const int& lip, const sf::Uint32& ct, const Multiplayer::Inventory& inv) - : Actor(pos, inv), int_ip(ip), int_local_ip(lip), last_update_time(ct) {} - Player(const Player& p) : Player(p.getPosition(), p.getIp(), p.getLocalIp(), p.getLastUpdateTime(), p.getInventory()) {} + Player(const sf::Vector2f& pos, const PlayerId p_id, const sf::Uint32& ct, const Multiplayer::Inventory& inv) + : Actor(pos, inv), player_id(p_id), last_update_time(ct) {} + Player(const Player& p) : Player(p.getPosition(), p.getId(), p.getLastUpdateTime(), p.getInventory()) {} Player(const Multiplayer::PlayerData& pd) - : Player(pd.getPosition() * static_cast(Constants::getPIXEL_SIZE()), pd.getIp(), pd.getPort(), pd.getTime(), pd.getInventory()) {} - inline int getIp() const { return int_ip; } - inline int getLocalIp() const { return int_local_ip; } + : Player(pd.getPosition() * static_cast(Constants::getPIXEL_SIZE()), pd.getId(), pd.getTime(), pd.getInventory()) {} + inline PlayerId getId() const { return player_id; } inline Multiplayer::Time getLastUpdateTime() const { return last_update_time; } void setPosition(const sf::Vector2f& position); void setTime(const sf::Uint32& new_time); @@ -109,7 +108,7 @@ namespace Actor private: sf::Uint32 last_update_time; - int int_ip, int_local_ip; + PlayerId player_id; }; diff --git a/include/Constants.hpp b/include/Constants.hpp index 9d75cac..a767738 100644 --- a/include/Constants.hpp +++ b/include/Constants.hpp @@ -15,6 +15,7 @@ */ class PlayerId { public: + PlayerId() {} PlayerId(size_t ip, size_t port, size_t timestamp, size_t key) : ip(ip), port(port), timestamp(timestamp), key(key) {} inline size_t getIp() const { return ip; } @@ -27,10 +28,10 @@ class PlayerId { } private: - size_t ip; - size_t port; - size_t timestamp; - size_t key; + size_t ip = 0; + size_t port = 0; + size_t timestamp = 0; + size_t key = 0; }; @@ -41,6 +42,9 @@ inline sf::Packet& operator <<(sf::Packet& packet, const PlayerId& id) } +typedef std::pair SocketInfo; + + /** * @brief This class is used to read settings from file */ diff --git a/include/Controls.hpp b/include/Controls.hpp index 7a40441..de636b8 100644 --- a/include/Controls.hpp +++ b/include/Controls.hpp @@ -43,6 +43,6 @@ class Controls static sf::RectangleShape inventory_rect; static inline std::unordered_map inventory; static inline Object::Object selected_object; - static std::map player_pool; + static std::map player_pool; static inline sf::Font font; }; diff --git a/include/Hash.hpp b/include/Hash.hpp index 76c2bb9..ba6c315 100644 --- a/include/Hash.hpp +++ b/include/Hash.hpp @@ -1,6 +1,24 @@ #pragma once #include +#include "Constants.hpp" + + +template <> +struct std::hash +{ + /** + * @brief Hash function for SocketInfo + */ + inline size_t operator()(const SocketInfo& s) const + { + size_t tmp0 = std::hash()(s.first.toInteger()); + size_t tmp1 = std::hash()(s.second); + + tmp0 ^= tmp1 + 0x9e3779b9 + (tmp0 << 6) + (tmp0 >> 2); + return tmp0; + } +}; template diff --git a/include/Multiplayer.hpp b/include/Multiplayer.hpp index 2c0bd96..25470ee 100644 --- a/include/Multiplayer.hpp +++ b/include/Multiplayer.hpp @@ -34,6 +34,7 @@ namespace Multiplayer typedef sf::Uint32 Time; + /** * @brief Class for trasferral data between server and client */ @@ -63,12 +64,11 @@ namespace Multiplayer { public: PlayerData() : Transportable::Transportable() {} - PlayerData(const sf::Vector2f& p, const int& ip, const unsigned int& port, const Time& t, const Inventory& ni) - : Transportable::Transportable(p, t), ip(ip), port(port), inventory(ni) {} + PlayerData(const sf::Vector2f& p, const PlayerId& p_id, const Time& t, const Inventory& ni) + : Transportable::Transportable(p, t), player_id(p_id), inventory(ni) {} PlayerData(const PlayerData& player) - : PlayerData(player.getPosition(), player.getIp(), player.getPort(), player.getTime(), player.getInventory()) {} - inline int getIp() const { return ip; } - inline unsigned int getPort() const { return port; } + : PlayerData(player.getPosition(), player.getId(), player.getTime(), player.getInventory()) {} + inline PlayerId getId() const { return player_id; } const size_t objectNumber(Object::ObjectName) const; const size_t addObject(Object::ObjectName); const size_t removeObject(Object::ObjectName); @@ -76,8 +76,7 @@ namespace Multiplayer private: // data >> new_position.x >> new_position.y >> msg_ip >> port >> sent_time; - int ip; - unsigned int port; + PlayerId player_id; Inventory inventory; }; @@ -103,7 +102,7 @@ namespace Multiplayer }; - typedef std::unordered_map PlayerDataPool; + typedef std::unordered_map PlayerDataPool; typedef std::unordered_map> ObjectDataPool; /** @@ -118,7 +117,7 @@ namespace Multiplayer inline const PlayerDataPool& getPlayerDataPool() const { return player_data_pool; } inline const ObjectDataPool& getObjectDataPool() const { return object_data_pool; } inline void clearObjectDataPool() { object_data_pool.clear(); } - PlayerDataPool::iterator removePlayerById(const std::string& id); + PlayerDataPool::iterator removePlayerBySocketInfo(const SocketInfo& id); bool removeObject(const ObjectData&); void addObject(const Object::Object& object); void addObject(const Multiplayer::ObjectData& object_data); diff --git a/src/common/Controls.cpp b/src/common/Controls.cpp index 58475d3..63a87e0 100644 --- a/src/common/Controls.cpp +++ b/src/common/Controls.cpp @@ -14,7 +14,7 @@ sf::RectangleShape Controls::inventory_rect = sf::RectangleShape(sf::Vector2f(Co WorldMap::ObjectMap Controls::object_map{}; Multiplayer::UdpManager Controls::udp_manager(sf::IpAddress::getLocalAddress(), sf::IpAddress(Constants::getSERVER_IP())); Actor::User Controls::user(sf::Vector2f(0, 0), Controls::udp_manager.getLocalPort()); -std::map Controls::player_pool{}; +std::map Controls::player_pool{}; void Controls::applyWindowSettings() @@ -241,7 +241,7 @@ void Controls::handleFrameStep() else if (ping > Constants::getMAX_PING()) { player_pool.erase(iter->first); - udp_manager.removePlayerById(iter++->first); + udp_manager.removePlayerBySocketInfo(iter++->first); continue; } else diff --git a/src/common/Multiplayer/Multiplayer.cpp b/src/common/Multiplayer/Multiplayer.cpp index 5795aab..d9d2d5d 100644 --- a/src/common/Multiplayer/Multiplayer.cpp +++ b/src/common/Multiplayer/Multiplayer.cpp @@ -83,12 +83,12 @@ namespace Multiplayer { PlayerData player_data; data >> player_data; - player_data = PlayerData(player_data.getPosition(), address_temp.toInteger(), port_temp, player_data.getTime(), player_data.getInventory()); + //player_data = PlayerData(player_data.getPosition(), address_temp.toInteger(), port_temp, player_data.getTime(), player_data.getInventory()); //if (msg_local_ip == local_ip.toInteger()) //{ // std::cout << "its me" << std::endl; //} - auto id = sf::IpAddress(address_temp).toString() + std::to_string(port_temp); + auto id = SocketInfo(address_temp, port_temp); sf::Uint32 time_now = std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); int ping = static_cast(time_now) - static_cast(player_data.getTime()); if (player_data_pool.count(id)) @@ -190,7 +190,7 @@ namespace Multiplayer // receive user PlayerData player_data; data >> player_data; - auto id = sf::IpAddress(address_temp).toString() + std::to_string(port_temp); + auto id = SocketInfo(address_temp, port_temp); sf::Uint32 time_now = std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); int ping = static_cast(time_now) - static_cast(player_data.getTime()); if (player_data_pool.count(id)) @@ -210,7 +210,7 @@ namespace Multiplayer } data << DataType::Event << EventType::removeObject << object_data; for (auto iter = getPlayerDataPool().begin(); iter != getPlayerDataPool().end(); ++iter) - send(data, sf::IpAddress(iter->second.getIp()), iter->second.getPort()); + send(data, id.first, id.second); data.clear(); data << DataType::Event << EventType::addObjectToInvectory << object_data; send(data, address_temp, port_temp); @@ -262,7 +262,7 @@ namespace Multiplayer } - PlayerDataPool::iterator UdpManager::removePlayerById(const std::string& id) + PlayerDataPool::iterator UdpManager::removePlayerBySocketInfo(const SocketInfo& id) { auto iter = player_data_pool.find(id); if (iter == player_data_pool.end()) diff --git a/src/common/Multiplayer/Operators.cpp b/src/common/Multiplayer/Operators.cpp index 8a6996e..d8c8e12 100644 --- a/src/common/Multiplayer/Operators.cpp +++ b/src/common/Multiplayer/Operators.cpp @@ -37,7 +37,7 @@ sf::Packet& operator >>(sf::Packet& data, Multiplayer::ObjectData& object_data) sf::Packet& operator <<(sf::Packet& packet, const Multiplayer::PlayerData& player_data) { - packet << player_data.getPosition().x << player_data.getPosition().y << player_data.getIp() << player_data.getPort() << player_data.getTime(); + packet << player_data.getPosition().x << player_data.getPosition().y << player_data.getId() << player_data.getTime(); packet << static_cast(player_data.getInventory().size()); for (auto pair : player_data.getInventory()) { @@ -47,13 +47,23 @@ sf::Packet& operator <<(sf::Packet& packet, const Multiplayer::PlayerData& playe } +sf::Packet& operator >>(sf::Packet& packet, PlayerId& player_id) +{ + sf::Uint64 ip, port, timestamp, key; + packet >> ip >> port >> timestamp >> key; + player_id = PlayerId(ip, port, timestamp, key); + return packet; +} + + sf::Packet& operator >>(sf::Packet& packet, Multiplayer::PlayerData& player_data) { int msg_ip; sf::Vector2f position; sf::Uint32 sent_time; unsigned int msg_port; - packet >> position.x >> position.y >> msg_ip >> msg_port >> sent_time; + PlayerId player_id; + packet >> position.x >> position.y >> player_id >> sent_time; sf::Uint32 inventory_size_uint32; packet >> inventory_size_uint32; size_t inventory_size = static_cast(inventory_size_uint32); @@ -66,6 +76,6 @@ sf::Packet& operator >>(sf::Packet& packet, Multiplayer::PlayerData& player_data size_t object_num = static_cast(object_num_uint32); inventory[static_cast(object_name_enum)] = std::move(object_num); } - player_data = Multiplayer::PlayerData(std::move(position), std::move(msg_ip), std::move(msg_port), std::move(sent_time), std::move(inventory)); // no inventory needed! + player_data = Multiplayer::PlayerData(std::move(position), std::move(player_id), std::move(sent_time), std::move(inventory)); // no inventory needed! return packet; } diff --git a/src/server/server.cpp b/src/server/server.cpp index 721770f..492d2f7 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -26,16 +26,16 @@ void UdpWorker(Multiplayer::UdpManager& UdpManager) auto time_now = static_cast(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()); iter.second.setTime(time_now); int ping = static_cast(time_now) - static_cast(iter.second.getTime()); - std::cout << sf::IpAddress(iter.second.getIp()) << ":" << iter.second.getPort() << std::endl; + std::cout << iter.first.first << ":" << iter.first.second << std::endl; //std::cout << "id: " << (*iter).first << ", last timepoint: " << std::to_string(time) << std::endl; if (ping > Constants::getMAX_PING()) { //std::cout << "reached MAX_PING" << std::endl; - //UdpManager.removePlayerById((*iter++).first); + //UdpManager.removePlayerBySocketInfo((*iter++).first); continue; } auto sector_data = UdpManager.checkSector(iter.second.getPosition()); - UdpManager.send(sector_data, sf::IpAddress(iter.second.getIp()), iter.second.getPort()); + UdpManager.send(sector_data, iter.first.first, iter.first.second); for (auto dest_iter = UdpManager.getPlayerDataPool().begin(); dest_iter != UdpManager.getPlayerDataPool().end();) { //std::cout << "sending " << iter->first << " data to " << dest_iter->first << std::endl; @@ -48,7 +48,7 @@ void UdpWorker(Multiplayer::UdpManager& UdpManager) } sf::Packet data; data << Multiplayer::DataType::Player << iter.second; - UdpManager.send(data, sf::IpAddress(dest_iter++->second.getIp()), dest_iter->second.getPort()); + UdpManager.send(data, dest_iter->first.first, dest_iter->first.second); //std::cout << "sent" << std::endl; } }