Merge remote-tracking branch 'origin/master' into FixNetworkBugs

# Conflicts:
#	include/Engine/Network/Client.h
#	include/Engine/Network/MessageType.h
#	include/Engine/Network/Server.h
#	include/Engine/Network/TCPServer.h
#	src/Engine/Network/Client.cpp
#	src/Engine/Network/TCPServer.cpp
This commit is contained in:
Jocke
2016-02-25 15:13:11 +01:00
60 changed files with 1006 additions and 257 deletions
+92 -8
View File
@@ -2,6 +2,7 @@
Server::Server(World* world, EventBroker* eventBroker, int port)
: Network(world, eventBroker)
, m_ServerlistRequest(13)
{
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
snapshotInterval = 1000 * config->Get<float>("Networking.SnapshotInterval", 0.05f);
@@ -13,7 +14,7 @@ Server::Server(World* world, EventBroker* eventBroker, int port)
EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Server::OnPlayerDamage);
// Bind
// BindWW
if (port == 0) {
port = config->Get<float>("Networking.Port", 27666);
}
@@ -58,8 +59,24 @@ void Server::Update()
parseMessageType(packet);
}
}
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
for (int i = 0; i < m_PlayersToDisconnect.size(); i++) {
for (int i = 0; i < m_PlayersToDisconnect.size(); i++) {
disconnect(m_PlayersToDisconnect.at(i));
}
m_PlayersToDisconnect.clear();
@@ -75,6 +92,7 @@ void Server::Update()
sendPing();
previousePingMessage = currentTime;
}
// Time out logic
if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) {
checkForTimeOuts();
@@ -118,7 +136,7 @@ void Server::parseMessageType(Packet& packet)
parseOnPlayerDamage(packet);
break;
case MessageType::PlayerTransform:
parsePlayerTransform(packet);
parsePlayerTransform(packet);
break;
case MessageType::OnDoubleJump:
parseDoubleJump(packet);
@@ -149,7 +167,7 @@ void Server::sendSnapshot()
{
Packet packet(MessageType::Snapshot);
addInputCommandsToPacket(packet);
addChildrenToPacket(packet, EntityID_Invalid);
addPlayersToPacket(packet, EntityID_Invalid);
unreliableBroadcast(packet);
}
@@ -166,7 +184,7 @@ void Server::addInputCommandsToPacket(Packet& packet)
m_InputCommandsToBroadcast.clear();
}
void Server::addChildrenToPacket(Packet & packet, EntityID entityID)
void Server::addPlayersToPacket(Packet & packet, EntityID entityID)
{
auto itPair = m_World->GetChildren(entityID);
std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools();
@@ -174,6 +192,7 @@ void Server::addChildrenToPacket(Packet & packet, EntityID entityID)
for (auto it = itPair.first; it != itPair.second; it++) {
EntityID childEntityID = it->second;
// HACK: Only sync players for now, since the map turned out to be TOO LARGE to send in one snapshot and Simon's computer shits itself
// HACK: Also checked CapturePointHUD for now. (this would get out of sync);
EntityWrapper childEntity(m_World, childEntityID);
if (!shouldSendToClient(childEntity)) {
continue;
@@ -215,6 +234,49 @@ void Server::addChildrenToPacket(Packet & packet, EntityID entityID)
}
}
void Server::addChildrenToPacket(Packet & packet, EntityID entityID)
{
auto itPair = m_World->GetChildren(entityID);
std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools();
// Loop through every child
for (auto it = itPair.first; it != itPair.second; it++) {
EntityID childEntityID = it->second;
// Write EntityID and parentsID and Entity name
packet.WritePrimitive(childEntityID);
packet.WritePrimitive(entityID);
packet.WriteString(m_World->GetName(childEntityID));
// Write components to child
int numberOfComponents = 0;
for (auto& i : worldComponentPools) {
if (i.second->KnowsEntity(childEntityID)) {
numberOfComponents++;
}
}
// Write how many components should be read
packet.WritePrimitive(numberOfComponents);
for (auto& i : worldComponentPools) {
// If the entity exist in the pool
if (i.second->KnowsEntity(childEntityID)) {
ComponentWrapper componentWrapper = i.second->GetByEntity(childEntityID);
// ComponentType
packet.WriteString(componentWrapper.Info.Name);
// Loop through fields
for (auto& componentField : componentWrapper.Info.FieldsInOrder) {
ComponentInfo::Field_t fieldInfo = componentWrapper.Info.Fields.at(componentField);
if (fieldInfo.Type == "string") {
std::string& value = componentWrapper[componentField];
packet.WriteString(value);
} else {
packet.WriteData(componentWrapper.Data + fieldInfo.Offset, fieldInfo.Stride);
}
}
}
}
// Go to to your children
addChildrenToPacket(packet, childEntityID);
}
}
void Server::sendPing()
{
// Prints connected players ping
@@ -233,6 +295,8 @@ void Server::sendPing()
reliableBroadcast(packet);
}
void Server::checkForTimeOuts()
{
double startPing = 1000 * m_StartPingTime
@@ -307,6 +371,11 @@ void Server::parseTCPConnect(Packet & packet)
connnectPacket.WritePrimitive(playerID);
m_Reliable.Send(connnectPacket);
Packet firstSnapshot(MessageType::Snapshot);
addInputCommandsToPacket(firstSnapshot);
addChildrenToPacket(firstSnapshot, EntityID_Invalid);
m_Reliable.Send(firstSnapshot);
// Send notification that a player has connected
//Packet notificationPacket(MessageType::PlayerConnected);
//broadcast(notificationPacket);
@@ -325,6 +394,17 @@ 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());
m_ServerlistRequest.Send(packet);
}
void Server::disconnect(PlayerID playerID)
{
//broadcast("A player disconnected");
@@ -349,6 +429,7 @@ void Server::parseOnPlayerDamage(Packet & packet)
e.Victim = EntityWrapper(m_World, packet.ReadPrimitive<EntityID>());
e.Damage = packet.ReadPrimitive<double>();
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());
}
@@ -378,7 +459,7 @@ bool Server::OnInputCommand(const Events::InputCommand & e)
isReadingData = !isReadingData;
m_SaveDataTimer = std::clock();
}
if (e.Command == "KickPlayer" && e.Value > 0) {
else if (e.Command == "KickPlayer" && e.Value > 0) {
kick(0);
}
@@ -449,7 +530,9 @@ void Server::parsePing()
{
for (auto& kv : m_ConnectedPlayers) {
if (kv.second.TCPAddress == m_Address &&
kv.second.TCPPort == m_Port) {
kv.second.TCPPort == m_Port
|| (kv.second.Endpoint.address() == m_Address
&& kv.second.Endpoint.port() == m_Port)) {
kv.second.StopTime = std::clock();
break;
}
@@ -521,7 +604,8 @@ void Server::parsePlayerTransform(Packet& packet)
bool Server::shouldSendToClient(EntityWrapper childEntity)
{
return childEntity.HasComponent("Player") || childEntity.FirstParentWithComponent("Player").Valid();
return childEntity.HasComponent("Player") || childEntity.FirstParentWithComponent("Player").Valid()
|| childEntity.HasComponent("CapturePoint") || childEntity.FirstParentWithComponent("CapturePoint").Valid();
}
PlayerID Server::GetPlayerIDFromEndpoint()