Added an event to search for servers.
Client now broadcasts a serverlistrequest. An active server will then answer the request and send info about the server. The client saves this data to a list and presents it to the user.
This commit is contained in:
@@ -14,7 +14,6 @@
|
|||||||
#include "Network/MessageType.h"
|
#include "Network/MessageType.h"
|
||||||
#include "Network/PlayerDefinition.h"
|
#include "Network/PlayerDefinition.h"
|
||||||
#include "Network/UDPClient.h"
|
#include "Network/UDPClient.h"
|
||||||
#include "Network/UDPServer.h" //LOL
|
|
||||||
#include "Network/TCPClient.h"
|
#include "Network/TCPClient.h"
|
||||||
#include "Network/SnapshotDefinitions.h"
|
#include "Network/SnapshotDefinitions.h"
|
||||||
#include "Core/World.h"
|
#include "Core/World.h"
|
||||||
@@ -25,6 +24,19 @@
|
|||||||
#include "Network/EInterpolate.h"
|
#include "Network/EInterpolate.h"
|
||||||
#include "Network/SnapshotFilter.h"
|
#include "Network/SnapshotFilter.h"
|
||||||
#include "Core/EPlayerSpawned.h"
|
#include "Core/EPlayerSpawned.h"
|
||||||
|
#include "Network/ESearchForServers.h"
|
||||||
|
|
||||||
|
struct ServerInfo
|
||||||
|
{
|
||||||
|
ServerInfo(std::string a, int b, std::string c, int d)
|
||||||
|
{
|
||||||
|
Address = a; Port = b; Name = c; PlayersConnected = d;
|
||||||
|
}
|
||||||
|
std::string Address = "";
|
||||||
|
int Port = 0;
|
||||||
|
std::string Name = "";
|
||||||
|
int PlayersConnected = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class Client : public Network
|
class Client : public Network
|
||||||
{
|
{
|
||||||
@@ -83,10 +95,11 @@ public:
|
|||||||
void parseTCPConnect(Packet& packet);
|
void parseTCPConnect(Packet& packet);
|
||||||
void parsePlayerConnected(Packet& packet);
|
void parsePlayerConnected(Packet& packet);
|
||||||
void parsePing();
|
void parsePing();
|
||||||
void parseHeartbeat(Packet& packet, PlayerDefinition);
|
void parseServerlist(Packet& packet);
|
||||||
void parseKick();
|
void parseKick();
|
||||||
void parsePlayersSpawned(Packet& packet);
|
void parsePlayersSpawned(Packet& packet);
|
||||||
void parseEntityDeletion(Packet& packet);
|
void parseEntityDeletion(Packet& packet);
|
||||||
|
void parsePlayerDamage(Packet& packet);
|
||||||
void parseComponentDeletion(Packet& packet);
|
void parseComponentDeletion(Packet& packet);
|
||||||
void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType);
|
void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType);
|
||||||
void parseSnapshot(Packet& packet);
|
void parseSnapshot(Packet& packet);
|
||||||
@@ -96,6 +109,7 @@ public:
|
|||||||
void sendInputCommands();
|
void sendInputCommands();
|
||||||
void sendLocalPlayerTransform();
|
void sendLocalPlayerTransform();
|
||||||
void becomePlayer();
|
void becomePlayer();
|
||||||
|
void displayServerlist();
|
||||||
// Mapping Logic
|
// Mapping Logic
|
||||||
// Returns if local EntityID exist in map
|
// Returns if local EntityID exist in map
|
||||||
bool clientServerMapsHasEntity(EntityID clientEntityID);
|
bool clientServerMapsHasEntity(EntityID clientEntityID);
|
||||||
@@ -111,11 +125,16 @@ public:
|
|||||||
bool OnPlayerDamage(const Events::PlayerDamage& e);
|
bool OnPlayerDamage(const Events::PlayerDamage& e);
|
||||||
EventRelay<Client, Events::PlayerSpawned> m_EPlayerSpawned;
|
EventRelay<Client, Events::PlayerSpawned> m_EPlayerSpawned;
|
||||||
bool OnPlayerSpawned(const Events::PlayerSpawned& e);
|
bool OnPlayerSpawned(const Events::PlayerSpawned& e);
|
||||||
void parsePlayerDamage(Packet& packet);
|
EventRelay< Client, Events::SearchForServers> m_ESearchForServers;
|
||||||
|
bool OnSearchForServers(const Events::SearchForServers& e);
|
||||||
private:
|
private:
|
||||||
UDPClient m_Unreliable;
|
UDPClient m_Unreliable;
|
||||||
UDPServer m_Heartbeat;
|
UDPClient m_ServerlistRequest;
|
||||||
TCPClient m_Reliable;
|
TCPClient m_Reliable;
|
||||||
|
std::vector<ServerInfo> m_Serverlist;
|
||||||
|
bool m_SearchingForServers = false;
|
||||||
|
std::clock_t m_StartSearchTime;
|
||||||
|
double m_SearchingTime = 2000; // Config I guess
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef Events_SearchForServers_h__
|
||||||
|
#define Events_SearchForServers_h__
|
||||||
|
|
||||||
|
#include "Core/Event.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
struct SearchForServers : public Event { };
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -19,7 +19,7 @@ enum class MessageType
|
|||||||
EntityDeleted,
|
EntityDeleted,
|
||||||
ComponentDeleted,
|
ComponentDeleted,
|
||||||
PlayerTransform,
|
PlayerTransform,
|
||||||
Heartbeat,
|
ServerlistRequest,
|
||||||
Invalid
|
Invalid
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ private:
|
|||||||
// Network channels
|
// Network channels
|
||||||
TCPServer m_Reliable;
|
TCPServer m_Reliable;
|
||||||
UDPServer m_Unreliable;
|
UDPServer m_Unreliable;
|
||||||
UDPClient m_Heartbeat;
|
UDPServer m_ServerlistRequest;
|
||||||
// dont forget to set these in the childrens receive logic
|
// dont forget to set these in the childrens receive logic
|
||||||
boost::asio::ip::address m_Address;
|
boost::asio::ip::address m_Address;
|
||||||
int m_Port = 27666;
|
int m_Port = 27666;
|
||||||
@@ -46,13 +46,11 @@ private:
|
|||||||
// time for previouse message
|
// time for previouse message
|
||||||
std::clock_t previousePingMessage = std::clock();
|
std::clock_t previousePingMessage = std::clock();
|
||||||
std::clock_t previousSnapshotMessage = std::clock();
|
std::clock_t previousSnapshotMessage = std::clock();
|
||||||
std::clock_t previousHeartbeat = std::clock();
|
|
||||||
std::clock_t timOutTimer = std::clock();
|
std::clock_t timOutTimer = std::clock();
|
||||||
|
|
||||||
// How often we send messages (milliseconds)
|
// How often we send messages (milliseconds)
|
||||||
float pingIntervalMs;
|
float pingIntervalMs;
|
||||||
float snapshotInterval;
|
float snapshotInterval;
|
||||||
float heartbeatInterval = 5000;
|
|
||||||
int checkTimeOutInterval = 100;
|
int checkTimeOutInterval = 100;
|
||||||
int m_NextPlayerID = 0;
|
int m_NextPlayerID = 0;
|
||||||
std::vector<Events::InputCommand> m_InputCommandsToBroadcast;
|
std::vector<Events::InputCommand> m_InputCommandsToBroadcast;
|
||||||
@@ -71,7 +69,6 @@ private:
|
|||||||
void addChildrenToPacket(Packet& packet, EntityID entityID);
|
void addChildrenToPacket(Packet& packet, EntityID entityID);
|
||||||
void addInputCommandsToPacket(Packet& packet);
|
void addInputCommandsToPacket(Packet& packet);
|
||||||
void sendPing();
|
void sendPing();
|
||||||
void sendHeartBeat();
|
|
||||||
void checkForTimeOuts();
|
void checkForTimeOuts();
|
||||||
void disconnect(PlayerID playerID);
|
void disconnect(PlayerID playerID);
|
||||||
void parseMessageType(Packet& packet);
|
void parseMessageType(Packet& packet);
|
||||||
@@ -86,6 +83,7 @@ private:
|
|||||||
void parseUDPConnect(Packet & packet);
|
void parseUDPConnect(Packet & packet);
|
||||||
void parseTCPConnect(Packet & packet);
|
void parseTCPConnect(Packet & packet);
|
||||||
void parseDisconnect();
|
void parseDisconnect();
|
||||||
|
void parseServerlistRequest(boost::asio::ip::udp::endpoint endpoint);
|
||||||
bool shouldSendToClient(EntityWrapper childEntity);
|
bool shouldSendToClient(EntityWrapper childEntity);
|
||||||
|
|
||||||
// Debug event
|
// Debug event
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ public:
|
|||||||
void Send(Packet & packet, PlayerDefinition & playerDefinition);
|
void Send(Packet & packet, PlayerDefinition & playerDefinition);
|
||||||
void Send(Packet & packet);
|
void Send(Packet & packet);
|
||||||
void Disconnect();
|
void Disconnect();
|
||||||
int Port() { return acceptor->local_endpoint().port(); }
|
int Port() { return m_Port; }
|
||||||
std::string Address();
|
std::string Address() { return m_Address; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// TCP logic
|
// TCP logic
|
||||||
boost::asio::io_service m_IOService;
|
boost::asio::io_service m_IOService;
|
||||||
@@ -28,6 +29,10 @@ private:
|
|||||||
int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers,
|
int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers,
|
||||||
const boost::system::error_code& error);
|
const boost::system::error_code& error);
|
||||||
int readBuffer(char* data, PlayerDefinition& playerDefinition);
|
int readBuffer(char* data, PlayerDefinition& playerDefinition);
|
||||||
|
int GetPort();
|
||||||
|
std::string GetAddress();
|
||||||
|
int m_Port = 0;
|
||||||
|
std::string m_Address = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -14,6 +14,7 @@ public:
|
|||||||
void Disconnect();
|
void Disconnect();
|
||||||
void Receive(Packet& packet);
|
void Receive(Packet& packet);
|
||||||
void Send(Packet & packet);
|
void Send(Packet & packet);
|
||||||
|
void Broadcast(Packet& packet, int port);
|
||||||
bool IsSocketAvailable();
|
bool IsSocketAvailable();
|
||||||
private:
|
private:
|
||||||
// Assio UDP logic
|
// Assio UDP logic
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ public:
|
|||||||
void AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers);
|
void AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers);
|
||||||
void Receive(Packet & packet, PlayerDefinition & playerDefinition);
|
void Receive(Packet & packet, PlayerDefinition & playerDefinition);
|
||||||
void Send(Packet & packet, PlayerDefinition & playerDefinition);
|
void Send(Packet & packet, PlayerDefinition & playerDefinition);
|
||||||
void Send(Packet & packet);
|
void Send(Packet & packet);
|
||||||
|
void Send(Packet & packet, boost::asio::ip::udp::endpoint endpoint);
|
||||||
|
void Broadcast(Packet & packet, int port);
|
||||||
bool IsSocketAvailable();
|
bool IsSocketAvailable();
|
||||||
private:
|
private:
|
||||||
// UDP logic
|
// UDP logic
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
#include "Network/Client.h"
|
#include "Network/Client.h"
|
||||||
using namespace boost::asio::ip;
|
using namespace boost::asio::ip;
|
||||||
|
|
||||||
Client::Client(World* world, EventBroker* eventBroker)
|
Client::Client(World* world, EventBroker* eventBroker)
|
||||||
: Network(world, eventBroker)
|
: Network(world, eventBroker)
|
||||||
, m_Heartbeat(13)
|
|
||||||
{
|
{
|
||||||
// Asumes root node is EntityID_Invalid
|
// Asumes root node is EntityID_Invalid
|
||||||
insertIntoServerClientMaps(EntityID_Invalid, EntityID_Invalid);
|
insertIntoServerClientMaps(EntityID_Invalid, EntityID_Invalid);
|
||||||
@@ -14,6 +13,8 @@ Client::Client(World* world, EventBroker* eventBroker)
|
|||||||
m_PlayerName = config->Get<std::string>("Networking.Name", "Raptorcopter");
|
m_PlayerName = config->Get<std::string>("Networking.Name", "Raptorcopter");
|
||||||
m_SendInputIntervalMs = config->Get<int>("Networking.SendInputIntervalMs", 33);
|
m_SendInputIntervalMs = config->Get<int>("Networking.SendInputIntervalMs", 33);
|
||||||
LOG_INFO("Client initialized");
|
LOG_INFO("Client initialized");
|
||||||
|
|
||||||
|
m_ServerlistRequest.Connect(m_PlayerName, "192.168.1.51", 32554);
|
||||||
}
|
}
|
||||||
|
|
||||||
Client::Client(World* world, EventBroker* eventBroker, std::unique_ptr<SnapshotFilter> snapshotFilter)
|
Client::Client(World* world, EventBroker* eventBroker, std::unique_ptr<SnapshotFilter> snapshotFilter)
|
||||||
@@ -31,6 +32,7 @@ void Client::Connect(std::string address, int port)
|
|||||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand);
|
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Client::OnPlayerDamage);
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Client::OnPlayerDamage);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Client::OnPlayerSpawned);
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Client::OnPlayerSpawned);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_ESearchForServers, &Client::OnSearchForServers);
|
||||||
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
|
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||||
m_Address = address;
|
m_Address = address;
|
||||||
if (address.empty()) {
|
if (address.empty()) {
|
||||||
@@ -66,15 +68,22 @@ void Client::Update()
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
while (m_Heartbeat.IsSocketAvailable()) {
|
|
||||||
|
while (m_ServerlistRequest.IsSocketAvailable()) {
|
||||||
Packet packet(MessageType::Invalid);
|
Packet packet(MessageType::Invalid);
|
||||||
PlayerDefinition localArea;
|
m_ServerlistRequest.Receive(packet);
|
||||||
localArea.Endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address().from_string("127.0.0.1"), 13);
|
if (packet.GetMessageType() == MessageType::ServerlistRequest) {
|
||||||
m_Heartbeat.Receive(packet, localArea);
|
parseServerlist(packet);
|
||||||
if(packet.GetMessageType() == MessageType::Heartbeat) {
|
|
||||||
parseHeartbeat(packet, localArea);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_SearchingForServers) {
|
||||||
|
if (m_SearchingTime < (1000* (std::clock() - m_StartSearchTime) / (double)CLOCKS_PER_SEC)) {
|
||||||
|
m_SearchingForServers = false;
|
||||||
|
displayServerlist();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_IsConnected) {
|
if (m_IsConnected) {
|
||||||
// Don't send 1 input in 1 packet, bunch em up.
|
// Don't send 1 input in 1 packet, bunch em up.
|
||||||
if (m_SendInputIntervalMs < (1000 * (std::clock() - m_TimeSinceSentInputs) / (double)CLOCKS_PER_SEC)) {
|
if (m_SendInputIntervalMs < (1000 * (std::clock() - m_TimeSinceSentInputs) / (double)CLOCKS_PER_SEC)) {
|
||||||
@@ -183,20 +192,18 @@ void Client::parsePing()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Client::parseHeartbeat(Packet& packet, PlayerDefinition pd)
|
void Client::parseServerlist(Packet& packet)
|
||||||
{
|
{
|
||||||
// Pop size, message type, and ID
|
// Pop size, message type, and ID
|
||||||
packet.ReadPrimitive<int>();
|
packet.ReadPrimitive<int>();
|
||||||
packet.ReadPrimitive<int>();
|
packet.ReadPrimitive<int>();
|
||||||
packet.ReadPrimitive<int>();
|
packet.ReadPrimitive<int>();
|
||||||
std::string serverName = packet.ReadString();
|
|
||||||
int playersConnected = packet.ReadPrimitive<int>();
|
|
||||||
std::string address = packet.ReadString();
|
std::string address = packet.ReadString();
|
||||||
int port = packet.ReadPrimitive<int>();
|
int port = packet.ReadPrimitive<int>();
|
||||||
//TODO: save these to some kind of list which can be represented to the player
|
std::string serverName = packet.ReadString();
|
||||||
|
int playersConnected = packet.ReadPrimitive<int>();
|
||||||
//TODO: This should not happen when a client is connected to a server
|
//TODO: This should not happen when a client is connected to a server
|
||||||
|
m_Serverlist.push_back({ address, port, serverName, playersConnected });
|
||||||
LOG_INFO("Serverlist\nName\tPlayers\tIP\t\tPort\n%s\t%i\t%s\t%i\n", serverName.c_str(), playersConnected, address, port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::parseKick()
|
void Client::parseKick()
|
||||||
@@ -216,12 +223,12 @@ void Client::parseSpawnEvents()
|
|||||||
}
|
}
|
||||||
e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(m_PlayerSpawnEvents.at(i).Player.ID));
|
e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(m_PlayerSpawnEvents.at(i).Player.ID));
|
||||||
//e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID.at(m_PlayerSpawnEvents.at(i).Spawner.ID));
|
//e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID.at(m_PlayerSpawnEvents.at(i).Spawner.ID));
|
||||||
e.PlayerID = -1;
|
e.PlayerID = -1;
|
||||||
e.PlayerName = m_PlayerSpawnEvents.at(i).PlayerName;
|
e.PlayerName = m_PlayerSpawnEvents.at(i).PlayerName;
|
||||||
m_EventBroker->Publish(e);
|
m_EventBroker->Publish(e);
|
||||||
}
|
}
|
||||||
m_PlayerSpawnEvents = tempSpawn;
|
m_PlayerSpawnEvents = tempSpawn;
|
||||||
// m_PlayerSpawnEvents.clear();
|
// m_PlayerSpawnEvents.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::parsePlayersSpawned(Packet& packet)
|
void Client::parsePlayersSpawned(Packet& packet)
|
||||||
@@ -338,7 +345,7 @@ void Client::parseSnapshot(Packet& packet)
|
|||||||
if (serverClientMapsHasEntity(serverEntityID)) {
|
if (serverClientMapsHasEntity(serverEntityID)) {
|
||||||
EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
|
EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
|
||||||
EntityWrapper localEntity(m_World, localEntityID);
|
EntityWrapper localEntity(m_World, localEntityID);
|
||||||
|
|
||||||
// Update entity
|
// Update entity
|
||||||
if (m_World->HasComponent(localEntityID, componentType)) {
|
if (m_World->HasComponent(localEntityID, componentType)) {
|
||||||
SharedComponentWrapper newComponent = createSharedComponent(packet, localEntityID, componentInfo);
|
SharedComponentWrapper newComponent = createSharedComponent(packet, localEntityID, componentInfo);
|
||||||
@@ -397,6 +404,12 @@ void Client::disconnect()
|
|||||||
|
|
||||||
bool Client::OnInputCommand(const Events::InputCommand & e)
|
bool Client::OnInputCommand(const Events::InputCommand & e)
|
||||||
{
|
{
|
||||||
|
// TEMP
|
||||||
|
if (e.Command == "SearchForServers" && e.Value > 0) {
|
||||||
|
Events::SearchForServers e;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
}
|
||||||
|
|
||||||
if (e.PlayerID != -1) {
|
if (e.PlayerID != -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -459,12 +472,23 @@ bool Client::OnPlayerSpawned(const Events::PlayerSpawned& e)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Client::OnSearchForServers(const Events::SearchForServers& e)
|
||||||
|
{
|
||||||
|
m_SearchingForServers = true;
|
||||||
|
m_StartSearchTime = std::clock();
|
||||||
|
m_Serverlist.clear();
|
||||||
|
LOG_INFO("Searching for LAN servers...\n");
|
||||||
|
Packet packet(MessageType::ServerlistRequest);
|
||||||
|
m_ServerlistRequest.Broadcast(packet, 13); // TODO: Config
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Client::parsePlayerDamage(Packet& packet)
|
void Client::parsePlayerDamage(Packet& packet)
|
||||||
{
|
{
|
||||||
Events::PlayerDamage e;
|
Events::PlayerDamage e;
|
||||||
PlayerID victimID = packet.ReadPrimitive<EntityID>();
|
PlayerID victimID = packet.ReadPrimitive<EntityID>();
|
||||||
PlayerID inflictorID = packet.ReadPrimitive<EntityID>();
|
PlayerID inflictorID = packet.ReadPrimitive<EntityID>();
|
||||||
if(!serverClientMapsHasEntity(victimID) || !serverClientMapsHasEntity(inflictorID)){
|
if (!serverClientMapsHasEntity(victimID) || !serverClientMapsHasEntity(inflictorID)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e.Inflictor = EntityWrapper(m_World, m_ServerIDToClientID.at(victimID));
|
e.Inflictor = EntityWrapper(m_World, m_ServerIDToClientID.at(victimID));
|
||||||
@@ -493,7 +517,7 @@ void Client::sendLocalPlayerTransform()
|
|||||||
packet.WritePrimitive(orientation.x);
|
packet.WritePrimitive(orientation.x);
|
||||||
packet.WritePrimitive(orientation.y);
|
packet.WritePrimitive(orientation.y);
|
||||||
packet.WritePrimitive(orientation.z);
|
packet.WritePrimitive(orientation.z);
|
||||||
|
|
||||||
bool hasAssaultWeapon = m_LocalPlayer.HasComponent("AssaultWeapon");
|
bool hasAssaultWeapon = m_LocalPlayer.HasComponent("AssaultWeapon");
|
||||||
packet.WritePrimitive(hasAssaultWeapon);
|
packet.WritePrimitive(hasAssaultWeapon);
|
||||||
if (hasAssaultWeapon) {
|
if (hasAssaultWeapon) {
|
||||||
@@ -501,7 +525,7 @@ void Client::sendLocalPlayerTransform()
|
|||||||
packet.WritePrimitive((int)cAssaultWeapon["MagazineAmmo"]);
|
packet.WritePrimitive((int)cAssaultWeapon["MagazineAmmo"]);
|
||||||
packet.WritePrimitive((int)cAssaultWeapon["Ammo"]);
|
packet.WritePrimitive((int)cAssaultWeapon["Ammo"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Unreliable.Send(packet);
|
m_Unreliable.Send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,6 +578,16 @@ void Client::becomePlayer()
|
|||||||
m_Reliable.Send(packet);
|
m_Reliable.Send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Client::displayServerlist()
|
||||||
|
{
|
||||||
|
LOG_INFO("This is a serverlist:\n");
|
||||||
|
for (int i = 0; i < m_Serverlist.size(); i++) {
|
||||||
|
ServerInfo si = m_Serverlist[i];
|
||||||
|
LOG_INFO("%s:%i\t%s\t%i\n", si.Address, si.Port, si.Name, si.PlayersConnected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Client::clientServerMapsHasEntity(EntityID clientEntityID)
|
bool Client::clientServerMapsHasEntity(EntityID clientEntityID)
|
||||||
{
|
{
|
||||||
if (m_ClientIDToServerID.find(clientEntityID) != m_ClientIDToServerID.end()) {
|
if (m_ClientIDToServerID.find(clientEntityID) != m_ClientIDToServerID.end()) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
Server::Server(World* world, EventBroker* eventBroker, int port)
|
Server::Server(World* world, EventBroker* eventBroker, int port)
|
||||||
: Network(world, eventBroker)
|
: Network(world, eventBroker)
|
||||||
|
, m_ServerlistRequest(13)
|
||||||
{
|
{
|
||||||
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
|
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||||
snapshotInterval = 1000 * config->Get<float>("Networking.SnapshotInterval", 0.05f);
|
snapshotInterval = 1000 * config->Get<float>("Networking.SnapshotInterval", 0.05f);
|
||||||
@@ -19,7 +20,6 @@ Server::Server(World* world, EventBroker* eventBroker, int port)
|
|||||||
}
|
}
|
||||||
m_Port = port;
|
m_Port = port;
|
||||||
LOG_INFO("Server initialized and bound to port %i", port);
|
LOG_INFO("Server initialized and bound to port %i", port);
|
||||||
m_Heartbeat.Connect("Server", "127.0.0.1", 13);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::~Server()
|
Server::~Server()
|
||||||
@@ -60,8 +60,23 @@ void Server::Update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (m_ServerlistRequest.IsSocketAvailable()) {
|
||||||
|
Packet packet(MessageType::Invalid);
|
||||||
|
PlayerDefinition localArea;
|
||||||
|
localArea.Endpoint = boost::asio::ip::udp::endpoint();
|
||||||
|
m_ServerlistRequest.Receive(packet, localArea);
|
||||||
|
if(packet.GetMessageType() == MessageType::ServerlistRequest) {
|
||||||
|
packet.ReadPrimitive<int>(); // Pop size
|
||||||
|
packet.ReadPrimitive<int>(); // Pop MsgType
|
||||||
|
packet.ReadPrimitive<int>(); // Pop packet ID
|
||||||
|
int port = packet.ReadPrimitive<int>();
|
||||||
|
std::string address = localArea.Endpoint.address().to_string();
|
||||||
|
parseServerlistRequest(boost::asio::ip::udp::endpoint(boost::asio::ip::address().from_string(address), port));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if players have disconnected
|
// Check if players have disconnected
|
||||||
for (int i = 0; i < m_PlayersToDisconnect.size(); i++) {
|
for (int i = 0; i < m_PlayersToDisconnect.size(); i++) {
|
||||||
disconnect(m_PlayersToDisconnect.at(i));
|
disconnect(m_PlayersToDisconnect.at(i));
|
||||||
}
|
}
|
||||||
m_PlayersToDisconnect.clear();
|
m_PlayersToDisconnect.clear();
|
||||||
@@ -77,11 +92,7 @@ void Server::Update()
|
|||||||
sendPing();
|
sendPing();
|
||||||
previousePingMessage = currentTime;
|
previousePingMessage = currentTime;
|
||||||
}
|
}
|
||||||
// Server heartbeat (display server list on clients)
|
|
||||||
if (heartbeatInterval < (1000 * (currentTime - previousHeartbeat) / (double)CLOCKS_PER_SEC)) {
|
|
||||||
sendHeartBeat();
|
|
||||||
previousHeartbeat = currentTime;
|
|
||||||
}
|
|
||||||
// Time out logic
|
// Time out logic
|
||||||
if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) {
|
if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) {
|
||||||
checkForTimeOuts();
|
checkForTimeOuts();
|
||||||
@@ -238,15 +249,6 @@ void Server::sendPing()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Server::sendHeartBeat()
|
|
||||||
{
|
|
||||||
Packet packet(MessageType::Heartbeat);
|
|
||||||
packet.WriteString("Bob"); // server name
|
|
||||||
packet.WritePrimitive<int>(m_ConnectedPlayers.size());
|
|
||||||
packet.WriteString(m_Reliable.Address());
|
|
||||||
packet.WritePrimitive<int>(m_Reliable.Port());
|
|
||||||
m_Heartbeat.Send(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::checkForTimeOuts()
|
void Server::checkForTimeOuts()
|
||||||
{
|
{
|
||||||
@@ -340,6 +342,20 @@ void Server::parseDisconnect()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Server::parseServerlistRequest(boost::asio::ip::udp::endpoint endpoint)
|
||||||
|
{
|
||||||
|
Packet packet(MessageType::ServerlistRequest);
|
||||||
|
packet.WriteString(m_Reliable.Address());
|
||||||
|
packet.WritePrimitive<int>(m_Reliable.Port());
|
||||||
|
packet.WriteString("SERVERNAME");
|
||||||
|
packet.WritePrimitive<int>(m_ConnectedPlayers.size());
|
||||||
|
//PlayerDefinition pDef;
|
||||||
|
//pDef.Endpoint = boost::asio::ip::udp::endpoint(endpoint.address(), 13);
|
||||||
|
|
||||||
|
m_ServerlistRequest.Send(packet/*, endpoint*/);
|
||||||
|
}
|
||||||
|
|
||||||
void Server::disconnect(PlayerID playerID)
|
void Server::disconnect(PlayerID playerID)
|
||||||
{
|
{
|
||||||
//broadcast("A player disconnected");
|
//broadcast("A player disconnected");
|
||||||
@@ -364,6 +380,7 @@ void Server::parseOnPlayerDamage(Packet & packet)
|
|||||||
e.Victim = EntityWrapper(m_World, packet.ReadPrimitive<EntityID>());
|
e.Victim = EntityWrapper(m_World, packet.ReadPrimitive<EntityID>());
|
||||||
e.Damage = packet.ReadPrimitive<double>();
|
e.Damage = packet.ReadPrimitive<double>();
|
||||||
m_EventBroker->Publish(e);
|
m_EventBroker->Publish(e);
|
||||||
|
|
||||||
//LOG_DEBUG("Server::parseOnPlayerDamage: Command is %s. Value is %f. PlayerID is %i.", e.DamageAmount, e.PlayerDamagedID, e.TypeOfDamage.c_str());
|
//LOG_DEBUG("Server::parseOnPlayerDamage: Command is %s. Value is %f. PlayerID is %i.", e.DamageAmount, e.PlayerDamagedID, e.TypeOfDamage.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ using namespace boost::asio::ip;
|
|||||||
TCPServer::TCPServer()
|
TCPServer::TCPServer()
|
||||||
{
|
{
|
||||||
acceptor = std::unique_ptr<tcp::acceptor>(new tcp::acceptor(m_IOService, tcp::endpoint(tcp::v4(), 27666)));
|
acceptor = std::unique_ptr<tcp::acceptor>(new tcp::acceptor(m_IOService, tcp::endpoint(tcp::v4(), 27666)));
|
||||||
|
m_Port = GetPort();
|
||||||
|
m_Address = GetAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
TCPServer::~TCPServer()
|
TCPServer::~TCPServer()
|
||||||
@@ -76,8 +78,12 @@ void TCPServer::Disconnect()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TCPServer::GetPort()
|
||||||
|
{
|
||||||
|
return acceptor->local_endpoint().port();
|
||||||
|
}
|
||||||
|
|
||||||
std::string TCPServer::Address()
|
std::string TCPServer::GetAddress()
|
||||||
{
|
{
|
||||||
boost::asio::ip::tcp::resolver resolver(m_IOService);
|
boost::asio::ip::tcp::resolver resolver(m_IOService);
|
||||||
boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), boost::asio::ip::host_name(), "");
|
boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), boost::asio::ip::host_name(), "");
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ void UDPClient::Connect(std::string playerName, std::string address, int port)
|
|||||||
if (m_Socket) {
|
if (m_Socket) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port);
|
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address().from_string(address), port);
|
||||||
m_Socket = boost::shared_ptr<boost::asio::ip::udp::socket>(new boost::asio::ip::udp::socket(m_IOService));
|
m_Socket = boost::shared_ptr<boost::asio::ip::udp::socket>(new boost::asio::ip::udp::socket(m_IOService));
|
||||||
m_Socket->connect(m_ReceiverEndpoint);
|
m_Socket->open(boost::asio::ip::udp::v4());
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPClient::Disconnect()
|
void UDPClient::Disconnect()
|
||||||
@@ -55,6 +55,17 @@ void UDPClient::Send(Packet& packet)
|
|||||||
packet.Data(),
|
packet.Data(),
|
||||||
packet.Size()),
|
packet.Size()),
|
||||||
m_ReceiverEndpoint, 0);
|
m_ReceiverEndpoint, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPClient::Broadcast(Packet& packet, int port)
|
||||||
|
{
|
||||||
|
m_Socket->set_option(boost::asio::socket_base::broadcast(true));
|
||||||
|
m_Socket->send_to(boost::asio::buffer(
|
||||||
|
packet.Data(),
|
||||||
|
packet.Size()),
|
||||||
|
udp::endpoint(boost::asio::ip::address_v4().broadcast(), port)
|
||||||
|
, 0);
|
||||||
|
m_Socket->set_option(boost::asio::socket_base::broadcast(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UDPClient::IsSocketAvailable()
|
bool UDPClient::IsSocketAvailable()
|
||||||
|
|||||||
@@ -36,7 +36,29 @@ void UDPServer::Send(Packet & packet)
|
|||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Broadcasting respond specific logic
|
||||||
|
void UDPServer::Send(Packet & packet, boost::asio::ip::udp::endpoint endpoint)
|
||||||
|
{
|
||||||
|
m_Socket->send_to(
|
||||||
|
boost::asio::buffer(
|
||||||
|
packet.Data(),
|
||||||
|
packet.Size()),
|
||||||
|
endpoint,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Broadcasting
|
||||||
|
void UDPServer::Broadcast(Packet & packet, int port)
|
||||||
|
{
|
||||||
|
m_Socket->set_option(boost::asio::socket_base::broadcast(true));
|
||||||
|
m_Socket->send_to(
|
||||||
|
boost::asio::buffer(
|
||||||
|
packet.Data(),
|
||||||
|
packet.Size()),
|
||||||
|
boost::asio::ip::udp::endpoint(boost::asio::ip::address_v4().broadcast(),port),
|
||||||
|
0);
|
||||||
|
m_Socket->set_option(boost::asio::socket_base::broadcast(false));
|
||||||
|
}
|
||||||
|
|
||||||
void UDPServer::Receive(Packet & packet, PlayerDefinition & playerDefinition)
|
void UDPServer::Receive(Packet & packet, PlayerDefinition & playerDefinition)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user