Переглянути джерело

controls sent to host only, host updates replicated scene nodes

Arnis Lielturks 7 роки тому
батько
коміт
360498d12e

+ 3 - 0
Source/Samples/Sample.inl

@@ -62,6 +62,9 @@ void Sample::Setup()
     engineParameters_[EP_FULL_SCREEN]  = false;
     engineParameters_[EP_FULL_SCREEN]  = false;
     engineParameters_[EP_HEADLESS]     = false;
     engineParameters_[EP_HEADLESS]     = false;
     engineParameters_[EP_SOUND]        = false;
     engineParameters_[EP_SOUND]        = false;
+    engineParameters_[EP_WINDOW_HEIGHT] = 480;
+    engineParameters_[EP_WINDOW_WIDTH] = 640;
+    engineParameters_[EP_MONITOR] = 1;
 
 
     // Construct a search path to find the resource prefix with two entries:
     // Construct a search path to find the resource prefix with two entries:
     // The first entry is an empty path which will be substituted with program/bin directory -- this entry is for binary when it is still in build tree
     // The first entry is an empty path which will be substituted with program/bin directory -- this entry is for binary when it is still in build tree

+ 20 - 6
Source/Urho3D/Network/Connection.cpp

@@ -198,10 +198,19 @@ void Connection::SetScene(Scene* newScene)
     {
     {
         // Make sure there is no existing async loading
         // Make sure there is no existing async loading
         scene_->StopAsyncLoading();
         scene_->StopAsyncLoading();
-        SubscribeToEvent(scene_, E_ASYNCLOADFINISHED, URHO3D_HANDLER(Connection, HandleAsyncLoadFinished));
+        if (scene_->IsAsyncLoading()) {
+            SubscribeToEvent(scene_, E_ASYNCLOADFINISHED, URHO3D_HANDLER(Connection, HandleAsyncLoadFinished));
+        } else {
+            sceneLoaded_ = true;
+        }
     }
     }
 }
 }
 
 
+void Connection::SetSceneLoaded(bool value)
+{
+    sceneLoaded_ = value;
+}
+
 void Connection::SetIdentity(const VariantMap& identity)
 void Connection::SetIdentity(const VariantMap& identity)
 {
 {
     identity_ = identity;
     identity_ = identity;
@@ -243,8 +252,10 @@ void Connection::Disconnect(int waitMSec)
 
 
 void Connection::SendServerUpdate()
 void Connection::SendServerUpdate()
 {
 {
-    if (!scene_ || !sceneLoaded_)
+    if (!scene_ || !sceneLoaded_) {
+        URHO3D_LOGERROR("Server update failed " + String(sceneLoaded_));
         return;
         return;
+    }
 
 
     // Always check the root node (scene) first so that the scene-wide components get sent first,
     // Always check the root node (scene) first so that the scene-wide components get sent first,
     // and all other replicated nodes get added to the dirty set for sending the initial state
     // and all other replicated nodes get added to the dirty set for sending the initial state
@@ -265,8 +276,10 @@ void Connection::SendServerUpdate()
 
 
 void Connection::SendClientUpdate()
 void Connection::SendClientUpdate()
 {
 {
-    if (!scene_ || !sceneLoaded_)
+    if (!scene_ || !sceneLoaded_) {
+        URHO3D_LOGERROR("No scene, not sending client update " + String(sceneLoaded_));
         return;
         return;
+    }
 
 
     msg_.Clear();
     msg_.Clear();
     msg_.WriteUInt(controls_.buttons_);
     msg_.WriteUInt(controls_.buttons_);
@@ -399,7 +412,7 @@ void Connection::ProcessPendingLatestData()
 
 
 bool Connection::ProcessMessage(int msgID, MemoryBuffer& msg)
 bool Connection::ProcessMessage(int msgID, MemoryBuffer& msg)
 {
 {
-    URHO3D_LOGINFO("Process message " + String(msgID));
+    //URHO3D_LOGINFO("Process message " + String(msgID));
     // New incomming message, reset last heard timer
     // New incomming message, reset last heard timer
     lastHeardTimer_.Reset();
     lastHeardTimer_.Reset();
     tempPacketCounter_.x_++;
     tempPacketCounter_.x_++;
@@ -472,7 +485,7 @@ void Connection::ProcessLoadScene(int msgID, MemoryBuffer& msg)
 {
 {
     if (IsClient())
     if (IsClient())
     {
     {
-        URHO3D_LOGWARNING("Received unexpected LoadScene message from client " + ToString());
+        URHO3D_LOGWARNING("Received unexpected LoadScene message from client " + ToString() + " => " + String(peer_->GetMyGUID()));
         return;
         return;
     }
     }
 
 
@@ -1584,7 +1597,8 @@ String Connection::GetAddress() const {
 }
 }
 
 
 void Connection::SetAddressOrGUID(const SLNet::AddressOrGUID& addr)
 void Connection::SetAddressOrGUID(const SLNet::AddressOrGUID& addr)
-{ 
+{
+    URHO3D_LOGINFO("SetAddressOrGUID " + String(addr.rakNetGuid.ToString()));
     delete address_;
     delete address_;
     address_ = nullptr;
     address_ = nullptr;
     address_ = new SLNet::AddressOrGUID(addr);
     address_ = new SLNet::AddressOrGUID(addr);

+ 1 - 0
Source/Urho3D/Network/Connection.h

@@ -128,6 +128,7 @@ public:
     void SendRemoteEvent(Node* node, StringHash eventType, bool inOrder, const VariantMap& eventData = Variant::emptyVariantMap);
     void SendRemoteEvent(Node* node, StringHash eventType, bool inOrder, const VariantMap& eventData = Variant::emptyVariantMap);
     /// Assign scene. On the server, this will cause the client to load it.
     /// Assign scene. On the server, this will cause the client to load it.
     void SetScene(Scene* newScene);
     void SetScene(Scene* newScene);
+    void SetSceneLoaded(bool value);
     /// Assign identity. Called by Network.
     /// Assign identity. Called by Network.
     void SetIdentity(const VariantMap& identity);
     void SetIdentity(const VariantMap& identity);
     /// Set new controls.
     /// Set new controls.

+ 60 - 19
Source/Urho3D/Network/Network.cpp

@@ -284,6 +284,7 @@ Network::Network(Context* context) :
 
 
 Network::~Network()
 Network::~Network()
 {
 {
+    fullyConnectedMesh2_->ResetHostCalculation();
     rakPeer_->DetachPlugin(natPunchthroughServerClient_);
     rakPeer_->DetachPlugin(natPunchthroughServerClient_);
     rakPeerClient_->DetachPlugin(natPunchthroughClient_);
     rakPeerClient_->DetachPlugin(natPunchthroughClient_);
     rakPeer_->DetachPlugin(fullyConnectedMesh2_);
     rakPeer_->DetachPlugin(fullyConnectedMesh2_);
@@ -335,15 +336,20 @@ void Network::HandleMessage(const SLNet::AddressOrGUID& source, int packetID, in
         connection->SendEvent(E_NETWORKMESSAGE, eventData);
         connection->SendEvent(E_NETWORKMESSAGE, eventData);
     }
     }
     else
     else
-        URHO3D_LOGWARNING("Discarding message from unknown MessageConnection " + String(source.ToString()));
+        URHO3D_LOGWARNING("Discarding message from unknown MessageConnection " + String(source.ToString()) + " => " + source.rakNetGuid.ToString());
 }
 }
 
 
 void Network::NewConnectionEstablished(const SLNet::AddressOrGUID& connection)
 void Network::NewConnectionEstablished(const SLNet::AddressOrGUID& connection)
 {
 {
-    URHO3D_LOGINFO("NewConnectionEstablished ---------------------------");
+    if (clientConnections_[connection]) {
+        URHO3D_LOGWARNINGF("Client already in the client list.", connection.rakNetGuid.ToString());
+        return;
+    }
+    URHO3D_LOGINFOF("NewConnectionEstablished ---------------------------", connection.rakNetGuid.ToString());
     // Create a new client connection corresponding to this MessageConnection
     // Create a new client connection corresponding to this MessageConnection
     SharedPtr<Connection> newConnection(new Connection(context_, true, connection, rakPeer_));
     SharedPtr<Connection> newConnection(new Connection(context_, true, connection, rakPeer_));
     newConnection->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
     newConnection->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
+    newConnection->SetScene(serverConnection_->GetScene());
     clientConnections_[connection] = newConnection;
     clientConnections_[connection] = newConnection;
     URHO3D_LOGINFO("Client " + newConnection->ToString() + " connected");
     URHO3D_LOGINFO("Client " + newConnection->ToString() + " connected");
 
 
@@ -752,9 +758,6 @@ Vector<SharedPtr<Connection> > Network::GetClientConnections() const
 
 
 bool Network::IsServerRunning() const
 bool Network::IsServerRunning() const
 {
 {
-    if (fullyConnectedMesh2_->IsHostSystem()) {
-        return true;
-    }
     if (!rakPeer_)
     if (!rakPeer_)
         return false;
         return false;
     return rakPeer_->IsActive() && isServer_;
     return rakPeer_->IsActive() && isServer_;
@@ -789,7 +792,7 @@ void Network::HandleIncomingPacket(SLNet::Packet* packet, bool isServer)
         URHO3D_LOGINFOF("ID_NEW_INCOMING_CONNECTION from %s. guid=%s.", packet->systemAddress.ToString(true), packet->guid.ToString());
         URHO3D_LOGINFOF("ID_NEW_INCOMING_CONNECTION from %s. guid=%s.", packet->systemAddress.ToString(true), packet->guid.ToString());
         if (isServer)
         if (isServer)
         {
         {
-            NewConnectionEstablished(packet->systemAddress);
+            NewConnectionEstablished(packet->guid);
         }
         }
 //        fullyConnectedMesh2_->ResetHostCalculation();
 //        fullyConnectedMesh2_->ResetHostCalculation();
         packetHandled = true;
         packetHandled = true;
@@ -797,8 +800,22 @@ void Network::HandleIncomingPacket(SLNet::Packet* packet, bool isServer)
     if (packetID == ID_REMOTE_NEW_INCOMING_CONNECTION)
     if (packetID == ID_REMOTE_NEW_INCOMING_CONNECTION)
     {
     {
         URHO3D_LOGINFOF("ID_REMOTE_NEW_INCOMING_CONNECTION from %s. guid=%s.", packet->systemAddress.ToString(true), packet->guid.ToString());
         URHO3D_LOGINFOF("ID_REMOTE_NEW_INCOMING_CONNECTION from %s. guid=%s.", packet->systemAddress.ToString(true), packet->guid.ToString());
-        if (isServer)
+//        if (isServer)
         {
         {
+            unsigned int count;
+            SLNet::BitStream bsIn(packet->data, packet->length, false);
+            bsIn.IgnoreBytes(sizeof(SLNet::MessageID));
+            bsIn.Read(count);
+            SLNet::SystemAddress remoteAddress;
+            SLNet::RakNetGUID remoteGuid;
+            NewConnectionEstablished(packet->guid);
+            for (unsigned int i=0; i < count; i++)
+            {
+                bsIn.Read(remoteAddress);
+                bsIn.Read(remoteGuid);
+                URHO3D_LOGINFO("Remote connection " + String(remoteGuid.ToString()) + " / " + String(packet->guid));
+                NewConnectionEstablished(packet->guid);
+            }
             //NewConnectionEstablished(packet->systemAddress);
             //NewConnectionEstablished(packet->systemAddress);
         }
         }
 //        fullyConnectedMesh2_->ResetHostCalculation();
 //        fullyConnectedMesh2_->ResetHostCalculation();
@@ -849,7 +866,7 @@ void Network::HandleIncomingPacket(SLNet::Packet* packet, bool isServer)
     {
     {
         if (isServer)
         if (isServer)
         {
         {
-            ClientDisconnected(packet->systemAddress);
+            ClientDisconnected(packet->guid);
         }
         }
         else
         else
         {
         {
@@ -861,7 +878,7 @@ void Network::HandleIncomingPacket(SLNet::Packet* packet, bool isServer)
     {
     {
         if (isServer)
         if (isServer)
         {
         {
-            ClientDisconnected(packet->systemAddress);
+            ClientDisconnected(packet->guid);
         }
         }
         else
         else
         {
         {
@@ -935,27 +952,27 @@ void Network::HandleIncomingPacket(SLNet::Packet* packet, bool isServer)
     }
     }
     else if (packetID == ID_READY_EVENT_SET)
     else if (packetID == ID_READY_EVENT_SET)
     {
     {
-        URHO3D_LOGINFOF("`````````````````````````` Got ID_READY_EVENT_SET from %s", packet->systemAddress.ToString(true));
+        URHO3D_LOGINFOF("`````````````````````````` Got ID_READY_EVENT_SET from %s", packet->guid.ToString());
         P2PShowReadyStatus();
         P2PShowReadyStatus();
     }
     }
     else if (packetID == ID_READY_EVENT_UNSET)
     else if (packetID == ID_READY_EVENT_UNSET)
     {
     {
-        URHO3D_LOGINFOF("`````````````````````````` Got ID_READY_EVENT_UNSET from %s", packet->systemAddress.ToString(true));
+        URHO3D_LOGINFOF("`````````````````````````` Got ID_READY_EVENT_UNSET from %s", packet->guid.ToString());
         P2PShowReadyStatus();
         P2PShowReadyStatus();
     }
     }
     else if (packetID == ID_READY_EVENT_ALL_SET)
     else if (packetID == ID_READY_EVENT_ALL_SET)
     {
     {
-        URHO3D_LOGINFOF("`````````````````````````` Got ID_READY_EVENT_ALL_SET from %s", packet->systemAddress.ToString(true));
+        URHO3D_LOGINFOF("`````````````````````````` Got ID_READY_EVENT_ALL_SET from %s", packet->guid.ToString());
         P2PShowReadyStatus();
         P2PShowReadyStatus();
     }
     }
     else if (packetID == ID_READY_EVENT_QUERY)
     else if (packetID == ID_READY_EVENT_QUERY)
     {
     {
-        URHO3D_LOGINFOF("`````````````````````````` Got ID_READY_EVENT_QUERY from %s", packet->systemAddress.ToString(true));
+        URHO3D_LOGINFOF("`````````````````````````` Got ID_READY_EVENT_QUERY from %s", packet->guid.ToString());
         P2PShowReadyStatus();
         P2PShowReadyStatus();
     }
     }
     else if (packetID == ID_READY_EVENT_FORCE_ALL_SET)
     else if (packetID == ID_READY_EVENT_FORCE_ALL_SET)
     {
     {
-        URHO3D_LOGINFOF("`````````````````````````` Got ID_READY_EVENT_FORCE_ALL_SET from %s", packet->systemAddress.ToString(true));
+        URHO3D_LOGINFOF("`````````````````````````` Got ID_READY_EVENT_FORCE_ALL_SET from %s", packet->guid.ToString());
         P2PShowReadyStatus();
         P2PShowReadyStatus();
     }
     }
     else if (packetID == ID_UNCONNECTED_PONG) // Host discovery response
     else if (packetID == ID_UNCONNECTED_PONG) // Host discovery response
@@ -990,8 +1007,13 @@ void Network::HandleIncomingPacket(SLNet::Packet* packet, bool isServer)
         SLNet::RakNetGUID oldHost;
         SLNet::RakNetGUID oldHost;
         bs.Read(oldHost);
         bs.Read(oldHost);
 
 
+        if (serverConnection_) {
+            serverConnection_->SetAddressOrGUID(packet->guid);
+        }
+        hostGuid_ = packet->guid.ToString();
         if (packet->guid == rakPeer_->GetMyGUID())
         if (packet->guid == rakPeer_->GetMyGUID())
         {
         {
+            isServer_ = true;
             if (oldHost != SLNet::UNASSIGNED_RAKNET_GUID)
             if (oldHost != SLNet::UNASSIGNED_RAKNET_GUID)
             {
             {
                 URHO3D_LOGINFOF("ID_FCM2_NEW_HOST: Taking over as host from the old host [%s].", oldHost.ToString());
                 URHO3D_LOGINFOF("ID_FCM2_NEW_HOST: Taking over as host from the old host [%s].", oldHost.ToString());
@@ -1002,6 +1024,12 @@ void Network::HandleIncomingPacket(SLNet::Packet* packet, bool isServer)
                 URHO3D_LOGINFO("ID_FCM2_NEW_HOST: We have become host for the first time");
                 URHO3D_LOGINFO("ID_FCM2_NEW_HOST: We have become host for the first time");
             }
             }
 
 
+            for (auto it = clientConnections_.Begin(); it != clientConnections_.End(); ++it) {
+                URHO3D_LOGINFO("Setting new scene for clients");
+//                (*it).second_->SetScene(serverConnection_->GetScene());
+                (*it).second_->SetSceneLoaded(true);
+            }
+
 //            DataStructures::List<SLNet::RakNetGUID> participantList;
 //            DataStructures::List<SLNet::RakNetGUID> participantList;
 //            fullyConnectedMesh2_->GetParticipantList(participantList);
 //            fullyConnectedMesh2_->GetParticipantList(participantList);
 //            for (unsigned int i = 0; i < participantList.Size(); i++) {
 //            for (unsigned int i = 0; i < participantList.Size(); i++) {
@@ -1012,6 +1040,7 @@ void Network::HandleIncomingPacket(SLNet::Packet* packet, bool isServer)
         }
         }
         else
         else
         {
         {
+            isServer_ = false;
 //            DataStructures::List<SLNet::RakNetGUID> participantList;
 //            DataStructures::List<SLNet::RakNetGUID> participantList;
 //            fullyConnectedMesh2_->GetParticipantList(participantList);
 //            fullyConnectedMesh2_->GetParticipantList(participantList);
 //            for (unsigned int i = 0; i < participantList.Size(); i++) {
 //            for (unsigned int i = 0; i < participantList.Size(); i++) {
@@ -1096,17 +1125,19 @@ void Network::HandleIncomingPacket(SLNet::Packet* packet, bool isServer)
             fullyConnectedMesh2_->StartVerifiedJoin(packet->guid);
             fullyConnectedMesh2_->StartVerifiedJoin(packet->guid);
         } else if (packetID == MSG_P2P_DENY) {
         } else if (packetID == MSG_P2P_DENY) {
             URHO3D_LOGERROR("MSG_P2P_DENY");
             URHO3D_LOGERROR("MSG_P2P_DENY");
-        } else if (1 == 1 || isServer)
+        } else if (P2PIsHostSystem())
         {
         {
-            HandleMessage(packet->systemAddress, 0, packetID, (const char*)(packet->data + dataStart), packet->length - dataStart);
+            URHO3D_LOGINFO("Host system handler " + String(packet->guid.ToString()));
+            HandleMessage(packet->guid, 0, packetID, (const char*)(packet->data + dataStart), packet->length - dataStart);
         }
         }
         else
         else
         {
         {
+            URHO3D_LOGINFO("Client system handler");
             MemoryBuffer buffer(packet->data + dataStart, packet->length - dataStart);
             MemoryBuffer buffer(packet->data + dataStart, packet->length - dataStart);
             bool processed = serverConnection_->ProcessMessage(packetID, buffer);
             bool processed = serverConnection_->ProcessMessage(packetID, buffer);
             if (!processed)
             if (!processed)
             {
             {
-                HandleMessage(packet->systemAddress, 0, packetID, (const char*)(packet->data + dataStart), packet->length - dataStart);
+                HandleMessage(packet->guid, 0, packetID, (const char*)(packet->data + dataStart), packet->length - dataStart);
             }
             }
         }
         }
         packetHandled = true;
         packetHandled = true;
@@ -1197,8 +1228,9 @@ void Network::PostUpdate(float timeStep)
             }
             }
         }
         }
 
 
-        if (serverConnection_)
+        if (serverConnection_ && !isServer_)
         {
         {
+            URHO3D_LOGINFO("Sending client update");
             // Send the client update
             // Send the client update
             serverConnection_->SendClientUpdate();
             serverConnection_->SendClientUpdate();
             serverConnection_->SendRemoteEvents();
             serverConnection_->SendRemoteEvents();
@@ -1267,9 +1299,11 @@ void Network::ConfigureNetworkSimulator()
 
 
 bool Network::StartP2PSession(Scene* scene, const VariantMap& identity)
 bool Network::StartP2PSession(Scene* scene, const VariantMap& identity)
 {
 {
+    isServer_ = true;
     if (!serverConnection_) {
     if (!serverConnection_) {
         serverConnection_ = new Connection(context_, false, rakPeer_->GetMyBoundAddress(), rakPeer_);
         serverConnection_ = new Connection(context_, false, rakPeer_->GetMyBoundAddress(), rakPeer_);
         serverConnection_->SetScene(scene);
         serverConnection_->SetScene(scene);
+        serverConnection_->SetSceneLoaded(true);
         serverConnection_->SetIdentity(identity);
         serverConnection_->SetIdentity(identity);
         serverConnection_->SetConnectPending(true);
         serverConnection_->SetConnectPending(true);
         serverConnection_->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
         serverConnection_->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
@@ -1277,6 +1311,8 @@ bool Network::StartP2PSession(Scene* scene, const VariantMap& identity)
     rakPeer_->AttachPlugin(natPunchthroughServerClient_);
     rakPeer_->AttachPlugin(natPunchthroughServerClient_);
     fullyConnectedMesh2_->Clear();
     fullyConnectedMesh2_->Clear();
     fullyConnectedMesh2_->ResetHostCalculation();
     fullyConnectedMesh2_->ResetHostCalculation();
+
+    hostGuid_ = P2PGetGUID();
     P2PSetReady(false);
     P2PSetReady(false);
     return true;
     return true;
 }
 }
@@ -1287,6 +1323,7 @@ void Network::JoinP2PSession(String guid, Scene* scene, const VariantMap& identi
     if (!serverConnection_) {
     if (!serverConnection_) {
         serverConnection_ = new Connection(context_, false, rakPeer_->GetMyBoundAddress(), rakPeer_);
         serverConnection_ = new Connection(context_, false, rakPeer_->GetMyBoundAddress(), rakPeer_);
         serverConnection_->SetScene(scene);
         serverConnection_->SetScene(scene);
+        serverConnection_->SetSceneLoaded(true);
         serverConnection_->SetIdentity(identity);
         serverConnection_->SetIdentity(identity);
         serverConnection_->SetConnectPending(true);
         serverConnection_->SetConnectPending(true);
         serverConnection_->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
         serverConnection_->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
@@ -1314,7 +1351,11 @@ bool Network::P2PIsConnectedHost()
 
 
 bool Network::P2PIsHostSystem()
 bool Network::P2PIsHostSystem()
 {
 {
-    return fullyConnectedMesh2_->IsHostSystem();
+    if (P2PGetGUID() == hostGuid_) {
+        return true;
+    }
+    return false;
+//    return fullyConnectedMesh2_->IsHostSystem();
 }
 }
 
 
 String Network::P2PGetHostAddress()
 String Network::P2PGetHostAddress()

+ 1 - 0
Source/Urho3D/Network/Network.h

@@ -212,6 +212,7 @@ private:
     bool natPunchtroughAttempt_;
     bool natPunchtroughAttempt_;
     SLNet::ReadyEvent *readyEvent_;
     SLNet::ReadyEvent *readyEvent_;
     SLNet::ConnectionGraph2 *connectionGraph2_;
     SLNet::ConnectionGraph2 *connectionGraph2_;
+    String hostGuid_;
 };
 };
 
 
 /// Register Network library objects.
 /// Register Network library objects.