Esempio n. 1
0
        protected override void OnCreate()
        {
            var reliabilityParams = new ReliableUtility.Parameters {
                WindowSize = 32
            };

#if UNITY_EDITOR
            m_ClientPacketDelay = UnityEditor.EditorPrefs.GetInt("MultiplayerPlayMode_" + UnityEngine.Application.productName + "_ClientDelay");
            m_ClientPacketDrop  = UnityEditor.EditorPrefs.GetInt("MultiplayerPlayMode_" + UnityEngine.Application.productName + "_ClientDropRate");
            int networkRate = 60; // TODO: read from some better place
                                  // All 3 packet types every frame stored for maximum delay, doubled for safety margin
            int maxPackets      = 2 * (networkRate * 3 * m_ClientPacketDelay + 999) / 1000;
            var simulatorParams = new SimulatorUtility.Parameters
            {
                MaxPacketSize = NetworkParameterConstants.MTU, MaxPacketCount = maxPackets, PacketDelayMs = m_ClientPacketDelay, PacketDropPercentage = m_ClientPacketDrop
            };
            m_Driver = new UdpNetworkDriver(simulatorParams, reliabilityParams);
#else
            m_Driver = new UdpNetworkDriver(reliabilityParams);
#endif

            m_ConcurrentDriver   = m_Driver.ToConcurrent();
            m_UnreliablePipeline = NetworkPipeline.Null;
            m_ReliablePipeline   = NetworkPipeline.Null;
            m_DriverListening    = false;
            m_Barrier            = World.GetOrCreateSystem <BeginSimulationEntityCommandBufferSystem>();
            numNetworkIds        = new NativeArray <int>(1, Allocator.Persistent);
            freeNetworkIds       = new NativeQueue <int>(Allocator.Persistent);
            rpcQueue             = InternalRpcCollection.GetRpcQueue <RpcSetNetworkId>();
        }
    static NetworkConnection ProcessSingleConnection(UdpNetworkDriver.Concurrent driver, NetworkConnection connection)
    {
        DataStreamReader strm;

        NetworkEvent.Type cmd;
        // Pop all events for the connection
        while ((cmd = driver.PopEventForConnection(connection, out strm)) != NetworkEvent.Type.Empty)
        {
            if (cmd == NetworkEvent.Type.Data)
            {
                // For ping requests we reply with a pong message
                // A DataStreamReader.Context is required to keep track of current read position since
                // DataStreamReader is immutable
                var readerCtx = default(DataStreamReader.Context);
                int id        = strm.ReadInt(ref readerCtx);
                // Create a temporary DataStreamWriter to keep our serialized pong message
                var pongData = new DataStreamWriter(4, Allocator.Temp);
                pongData.Write(id);
                // Send the pong message with the same id as the ping
                driver.Send(NetworkPipeline.Null, connection, pongData);
            }
            else if (cmd == NetworkEvent.Type.Disconnect)
            {
                // When disconnected we make sure the connection return false to IsCreated so the next frames
                // DriverUpdateJob will remove it
                return(default(NetworkConnection));
            }
        }

        return(connection);
    }
 public bool Listen(NetworkEndPoint endpoint)
 {
     LastDriverWriter.Complete();
     if (m_UnreliablePipeline == NetworkPipeline.Null)
     {
         m_UnreliablePipeline = m_Driver.CreatePipeline(typeof(NullPipelineStage));
     }
     if (m_ReliablePipeline == NetworkPipeline.Null)
     {
         m_ReliablePipeline = m_Driver.CreatePipeline(typeof(ReliableSequencedPipelineStage));
     }
     // Switching to server mode
     if (m_Driver.Bind(endpoint) != 0)
     {
         return(false);
     }
     if (m_Driver.Listen() != 0)
     {
         return(false);
     }
     m_DriverListening = true;
     // FIXME: Bind breaks all copies of the driver nad makes them send to the wrong socket
     m_ConcurrentDriver = m_Driver.ToConcurrent();
     return(true);
 }
#pragma warning disable CS0809 // Obsolete member overrides non-obsolete member
    protected override void OnCreateManager()
#pragma warning restore CS0809 // Obsolete member overrides non-obsolete member
    {
        var reliabilityParams = new ReliableUtility.Parameters {
            WindowSize = 32
        };

        if (UnityEngine.Debug.isDebugBuild)
        {
            m_ClientPacketDelay = UnityEngine.PlayerPrefs.GetInt("MultiplayerPlayMode_" + UnityEngine.Application.productName + "_ClientDelay");
            m_ClientPacketDrop  = UnityEngine.PlayerPrefs.GetInt("MultiplayerPlayMode_" + UnityEngine.Application.productName + "_ClientDropRate");
            int networkRate = 60; // TODO: read from some better place
            // All 3 packet types every frame stored for maximum delay, doubled for safety margin
            int maxPackets      = 2 * (networkRate * 3 * m_ClientPacketDelay + 999) / 1000;
            var simulatorParams = new SimulatorUtility.Parameters
            {
                MaxPacketSize = NetworkParameterConstants.MTU, MaxPacketCount = maxPackets, PacketDelayMs = m_ClientPacketDelay, PacketDropPercentage = m_ClientPacketDrop
            };
            m_Driver = new UdpNetworkDriver(simulatorParams, reliabilityParams);
            UnityEngine.Debug.Log("Using simulator with latency=" + m_ClientPacketDelay + " packet drop=" + m_ClientPacketDrop);
        }
        else
        {
            m_Driver = new UdpNetworkDriver(reliabilityParams);
        }

        m_ConcurrentDriver   = m_Driver.ToConcurrent();
        m_UnreliablePipeline = NetworkPipeline.Null;
        m_ReliablePipeline   = NetworkPipeline.Null;
        m_DriverListening    = false;
        m_Barrier            = World.GetOrCreateSystem <BeginSimulationEntityCommandBufferSystem>();
        numNetworkIds        = new NativeArray <int>(1, Allocator.Persistent);
        freeNetworkIds       = new NativeQueue <int>(Allocator.Persistent);
        rpcQueue             = InternalRpcCollection.GetRpcQueue <RpcSetNetworkId>();
    }
        protected void init()
        {
            //
            var reliabilityParams = new ReliableUtility.Parameters {
                WindowSize = 32
            };
            var configParameter = new NetworkConfigParameter
            {
                maxConnectAttempts  = maxConnectAttempts,
                connectTimeoutMS    = NetworkParameterConstants.ConnectTimeoutMS,
                disconnectTimeoutMS = disconnectTimeoutMS
            };

#if UNITY_EDITOR
            int networkRate = (int)(1f / Time.fixedDeltaTime); // TODO: read from some better place
                                                               // All 3 packet types every frame stored for maximum delay, doubled for safety margin
            int maxPackets      = 2 * (networkRate * 3 * clientPacketDelay + 999) / 1000;
            var simulatorParams = new SimulatorUtility.Parameters
            {
                MaxPacketSize = NetworkParameterConstants.MTU, MaxPacketCount = maxPackets, PacketDelayMs = clientPacketDelay, PacketDropPercentage = clientPacketDrop
            };

            _driver = new UdpNetworkDriver(simulatorParams, reliabilityParams, configParameter);
#else
            _driver = new UdpNetworkDriver(reliabilityParams, configParameter);
#endif

            _concurrentDriver   = _driver.ToConcurrent();
            _unreliablePipeline = NetworkPipeline.Null;
            _reliablePipeline   = NetworkPipeline.Null;
            _listening          = false;
        }
        public bool Listen(NetworkEndPoint endpoint)
        {
            if (_unreliablePipeline == NetworkPipeline.Null)
            {
                _unreliablePipeline = _driver.CreatePipeline(typeof(NullPipelineStage));
            }
            if (_reliablePipeline == NetworkPipeline.Null)
            {
                _reliablePipeline = _driver.CreatePipeline(typeof(ReliableSequencedPipelineStage));
            }
            // Switching to server mode
            if (_driver.Bind(endpoint) != 0)
            {
                return(false);
            }
            if (_driver.Listen() != 0)
            {
                return(false);
            }
            _listening = true;
            // FIXME: Bind breaks all copies of the driver nad makes them send to the wrong socket
            _concurrentDriver = _driver.ToConcurrent();


#if UNITY_EDITOR
            renameQuery = GetEntityQuery(new EntityQueryDesc
            {
                All = new ComponentType[] { ComponentType.ReadOnly <NetworkConnectedMessage>() },
            });
#endif
            return(true);
        }
        protected override void OnCreate()
        {
            var reliabilityParams = new ReliableUtility.Parameters {
                WindowSize = 32
            };

#if UNITY_EDITOR || DEVELOPMENT_BUILD
            var netParams = new NetworkConfigParameter
            {
                maxConnectAttempts  = NetworkParameterConstants.MaxConnectAttempts,
                connectTimeoutMS    = NetworkParameterConstants.ConnectTimeoutMS,
                disconnectTimeoutMS = NetworkParameterConstants.DisconnectTimeoutMS,
                maxFrameTimeMS      = 100
            };

            m_ClientPacketDelay = ClientPacketDelayMs;
            var jitter = ClientPacketJitterMs;
            if (jitter > m_ClientPacketDelay)
            {
                jitter = m_ClientPacketDelay;
            }
            m_ClientPacketDrop = ClientPacketDropRate;
            int networkRate = 60; // TODO: read from some better place
            // All 3 packet types every frame stored for maximum delay, doubled for safety margin
            int maxPackets      = 2 * (networkRate * 3 * m_ClientPacketDelay + 999) / 1000;
            var simulatorParams = new SimulatorUtility.Parameters
            {
                MaxPacketSize        = NetworkParameterConstants.MTU, MaxPacketCount = maxPackets,
                PacketDelayMs        = m_ClientPacketDelay, PacketJitterMs = jitter,
                PacketDropPercentage = m_ClientPacketDrop
            };
            m_Driver = new UdpNetworkDriver(netParams, simulatorParams, reliabilityParams);
            UnityEngine.Debug.Log($"Using simulator with latency={m_ClientPacketDelay} packet drop={m_ClientPacketDrop}");
#else
            m_Driver = new UdpNetworkDriver(reliabilityParams);
#endif

            m_ConcurrentDriver             = m_Driver.ToConcurrent();
            m_UnreliablePipeline           = NetworkPipeline.Null;
            m_ReliablePipeline             = NetworkPipeline.Null;
            m_DriverListening              = false;
            m_Barrier                      = World.GetOrCreateSystem <BeginSimulationEntityCommandBufferSystem>();
            numNetworkIds                  = new NativeArray <int>(1, Allocator.Persistent);
            freeNetworkIds                 = new NativeQueue <int>(Allocator.Persistent);
            rpcQueue                       = World.GetOrCreateSystem <RpcSystem>().GetRpcQueue <RpcSetNetworkId>();
            m_NetworkStreamConnectionQuery = EntityManager.CreateEntityQuery(typeof(NetworkStreamConnection));
#if UNITY_EDITOR || DEVELOPMENT_BUILD
            m_NetStats = new NativeArray <uint>(1, Allocator.Persistent);
            m_GhostStatsCollectionSystem = World.GetOrCreateSystem <GhostStatsCollectionSystem>();
#endif
        }
    protected override JobHandle OnUpdate(JobHandle inputDep)
    {
        var commandBuffer = m_Barrier.CreateCommandBuffer();

        // Destroy drivers if the PingDriverComponents were removed
        if (!m_DestroyedDriverGroup.IsEmptyIgnoreFilter)
        {
            inputDep.Complete();
            var destroyedDriverEntity = m_DestroyedDriverGroup.ToEntityArray(Allocator.TempJob);
            var destroyedDriverList   = m_DestroyedDriverGroup.ToComponentDataArray <PingDriverComponentData>(Allocator.TempJob);
            for (int i = 0; i < destroyedDriverList.Length; ++i)
            {
                if (destroyedDriverList[i].isServer != 0)
                {
                    var serverConnectionList = m_ServerConnectionGroup.ToEntityArray(Allocator.TempJob);
                    // Also destroy all active connections when the driver dies
                    for (int con = 0; con < serverConnectionList.Length; ++con)
                    {
                        commandBuffer.DestroyEntity(serverConnectionList[con]);
                    }
                    serverConnectionList.Dispose();
                    ServerDriver.Dispose();
                }
                else
                {
                    ClientDriver.Dispose();
                }

                commandBuffer.RemoveComponent <PingDriverStateComponent>(destroyedDriverEntity[i]);
            }

            destroyedDriverList.Dispose();
            destroyedDriverEntity.Dispose();
        }

        // Create drivers if new PingDriverComponents were added
        if (!m_NewDriverGroup.IsEmptyIgnoreFilter)
        {
            inputDep.Complete();
            var newDriverEntity = m_NewDriverGroup.ToEntityArray(Allocator.TempJob);
            var newDriverList   = m_NewDriverGroup.ToComponentDataArray <PingDriverComponentData>(Allocator.TempJob);
            for (int i = 0; i < newDriverList.Length; ++i)
            {
                if (newDriverList[i].isServer != 0)
                {
                    if (ServerDriver.IsCreated)
                    {
                        throw new InvalidOperationException("Cannot create multiple server drivers");
                    }
                    var drv  = new UdpNetworkDriver(new INetworkParameter[0]);
                    var addr = NetworkEndPoint.AnyIpv4;
                    addr.Port = 9000;
                    if (drv.Bind(addr) != 0)
                    {
                        throw new Exception("Failed to bind to port 9000");
                    }
                    else
                    {
                        drv.Listen();
                    }
                    ServerDriver           = drv;
                    ConcurrentServerDriver = ServerDriver.ToConcurrent();
                }
                else
                {
                    if (ClientDriver.IsCreated)
                    {
                        throw new InvalidOperationException("Cannot create multiple client drivers");
                    }
                    ClientDriver           = new UdpNetworkDriver(new INetworkParameter[0]);
                    ConcurrentClientDriver = ClientDriver.ToConcurrent();
                }

                commandBuffer.AddComponent(newDriverEntity[i],
                                           new PingDriverStateComponent {
                    isServer = newDriverList[i].isServer
                });
            }
            newDriverList.Dispose();
            newDriverEntity.Dispose();
        }

        JobHandle clientDep = default(JobHandle);
        JobHandle serverDep = default(JobHandle);

        // Go through and update all drivers, also accept all incoming connections for server drivers
        if (ServerDriver.IsCreated)
        {
            // Schedule a chain with driver update, a job to accept all connections and finally a job to delete all invalid connections
            serverDep = ServerDriver.ScheduleUpdate(inputDep);
            var acceptJob = new DriverAcceptJob
            {
                driver = ServerDriver, commandBuffer = commandBuffer
            };
            serverDep = acceptJob.Schedule(serverDep);
            var cleanupJob = new DriverCleanupJob
            {
                commandBuffer = m_Barrier.CreateCommandBuffer().ToConcurrent()
            };
            serverDep = cleanupJob.Schedule(this, serverDep);
            m_Barrier.AddJobHandleForProducer(serverDep);
        }

        if (ClientDriver.IsCreated)
        {
            clientDep = ClientDriver.ScheduleUpdate(inputDep);
        }

        return(JobHandle.CombineDependencies(clientDep, serverDep));
    }