コード例 #1
0
        protected override void OnUpdate()
        {
            Driver.ScheduleUpdate().Complete();
            if (_driverListening)
            {
                OnAccept();
            }
            else
            {
                if (!HasSingleton <ClientServerTickRate>())
                {
                    var newEntity = World.EntityManager.CreateEntity();
                    var tickRate  = new ClientServerTickRate();
                    tickRate.ResolveDefaults();
                    EntityManager.AddComponentData(newEntity, tickRate);
                }

                var tickRateEntity = GetSingletonEntity <ClientServerTickRate>();
                Entities.WithNone <NetworkStreamDisconnected>()
                .ForEach((Entity ent, ref ClientServerTickRateRefreshRequest req) =>
                {
                    var dataFromEntity = GetComponentDataFromEntity <ClientServerTickRate>();
                    var tickRate       = dataFromEntity[tickRateEntity];
                    tickRate.MaxSimulationStepsPerFrame = req.MaxSimulationStepsPerFrame;
                    tickRate.NetworkTickRate            = req.NetworkTickRate;
                    tickRate.SimulationTickRate         = req.SimulationTickRate;
                    dataFromEntity[tickRateEntity]      = tickRate;
                    PostUpdateCommands.RemoveComponent <ClientServerTickRateRefreshRequest>(ent);
                });
            }

            var rpcBuffer      = GetBufferFromEntity <IncomingRpcDataStreamBufferComponent>();
            var cmdBuffer      = GetBufferFromEntity <IncomingCommandDataStreamBufferComponent>();
            var localTime      = NetworkTimeSystem.TimestampMS;
            var snapshotBuffer = GetBufferFromEntity <IncomingSnapshotDataStreamBufferComponent>();

            Entities.WithNone <NetworkStreamDisconnected>().ForEach(
                (Entity session, ref NetworkStreamConnection connection, ref NetworkSnapshotAckComponent snapshotAck) =>
            {
                if (!connection.Value.IsCreated)
                {
                    return;
                }

                NetworkEvent.Type cmd;
                while ((cmd = connection.Value.PopEvent(Driver, out DataStreamReader reader)) !=
                       NetworkEvent.Type.Empty)
                {
                    switch (cmd)
                    {
                    case NetworkEvent.Type.Connect:
                        {
                            Debug.Log("We are now connected to the server:" + connection.Value.InternalId);
                            break;
                        }

                    case NetworkEvent.Type.Disconnect:
                        {
                            if (rpcBuffer.HasComponent(session))
                            {
                                rpcBuffer[session].Clear();
                            }

                            if (_driverListening)
                            {
                                if (cmdBuffer.HasComponent(session))
                                {
                                    cmdBuffer[session].Clear();
                                }

                                --ConnectionCount;
                            }

                            connection.Value = default;
                            PostUpdateCommands.AddComponent(session, new NetworkStreamDisconnected());

                            Debug.Log("We are now disconnect:" + connection.Value.InternalId);
                            break;
                        }

                    case NetworkEvent.Type.Data:
                        {
                            switch ((NetworkStreamProtocol)reader.ReadByte())
                            {
                            case NetworkStreamProtocol.Snapshot:
                                {
                                    uint remoteTime              = reader.ReadUInt();
                                    uint localTimeMinusRTT       = reader.ReadUInt();
                                    int commandServerAge         = reader.ReadInt();
                                    snapshotAck.ServerCommandAge = commandServerAge;
                                    snapshotAck.UpdateRemoteTime(remoteTime, localTimeMinusRTT, localTime);

                                    var buffer = snapshotBuffer[session];
                                    // buffer.Clear();
                                    buffer.Add(ref reader);
                                    break;
                                }

                            case NetworkStreamProtocol.Command:
                                {
                                    var buffer        = cmdBuffer[session];
                                    uint snapshot     = reader.ReadUInt();
                                    uint snapshotMask = reader.ReadUInt();
                                    snapshotAck.UpdateReceiveByRemote(snapshot, snapshotMask);

                                    uint remoteTime        = reader.ReadUInt();
                                    uint localTimeMinusRTT = reader.ReadUInt();
                                    snapshotAck.UpdateRemoteTime(remoteTime, localTimeMinusRTT, localTime);

                                    // buffer.Clear();
                                    buffer.Add(ref reader);

                                    break;
                                }

                            case NetworkStreamProtocol.Rpc:
                                {
                                    var buffer = rpcBuffer[session];
                                    buffer.Add(ref reader);
                                    break;
                                }
                            }

                            break;
                        }
                    }
                }
            });
        }
コード例 #2
0
        protected override void OnUpdate()
        {
            uint tick = _ghostPredictionSystemGroup.PredictingTick;

            // 新添加的ghost
            Entities.With(ghostSpawnGroup).ForEach((Entity ent, ref GhostComponent ghostComponent) =>
            {
                ++_ghostInstanceId;
                ghostComponent.Id = _ghostInstanceId;
                PostUpdateCommands.AddComponent(ent, new GhostSystemStateComponent {
                    ghostId = ghostComponent.Id
                });
                _newGhosts.Add(ghostComponent.Id, ent);
            });

            ClientServerTickRate tickRate = default;

            if (HasSingleton <ClientServerTickRate>())
            {
                tickRate = GetSingleton <ClientServerTickRate>();
            }

            tickRate.ResolveDefaults();
            int networkTickInterval = tickRate.SimulationTickRate / tickRate.NetworkTickRate;

            if (tick % networkTickInterval != 0)
            {
                return;
            }

            var localTime = NetworkTimeSystem.TimestampMS;

            // 需要发送快照的ghost chunk
            // 已经按照原型分块了
            NativeArray <ArchetypeChunk> ghostChunks =
                ghostGroup.CreateArchetypeChunkArrayAsync(Allocator.TempJob, out JobHandle ghostChunksHandle);
            NativeArray <ArchetypeChunk> despawnChunks =
                ghostDespawnGroup.CreateArchetypeChunkArrayAsync(Allocator.TempJob, out JobHandle despawnChunksHandle);

            JobHandle.CompleteAll(ref ghostChunksHandle, ref despawnChunksHandle);

            var connections = connectionGroup.ToEntityArray(Allocator.TempJob);

            // 获取动态组件类型
            var ghostSerializerCollectionSystem = World.GetExistingSystem <GhostCollectionSystem>();

            for (int i = 0; i < connections.Length; i++)
            {
                SerializeJob serializeJob = new SerializeJob
                {
                    ConnectionEntity     = connections[i],
                    ConnectionFromEntity = GetComponentDataFromEntity <NetworkStreamConnection>(),
                    AckFromEntity        = GetComponentDataFromEntity <NetworkSnapshotAckComponent>(),
                    LocalTime            = localTime,
                    Tick                       = tick,
                    NetDriver                  = _driver.ToConcurrent(),
                    CompressionModel           = _compressionModel,
                    UnreliablePipeline         = _unreliablePipeline,
                    GhostChunks                = ghostChunks,
                    DespawnChunks              = despawnChunks,
                    EntityTypeHandle           = GetEntityTypeHandle(),
                    GhostTypeHandle            = GetComponentTypeHandle <GhostComponent>(),
                    GhostSystemStateTypeHandle = GetComponentTypeHandle <GhostSystemStateComponent>(),
                    GhostTypeCollection        = ghostSerializerCollectionSystem.GhostTypeCollection,
                    GhostComponentIndex        = ghostSerializerCollectionSystem.IndexCollection,
                    GhostComponentSerializers  = ghostSerializerCollectionSystem.Serializers,
                };

                // FIXME
                var listLength = ghostSerializerCollectionSystem.Serializers.Length;
                if (listLength <= 32)
                {
                    var dynamicListJob = new SerializeJob32 {
                        Job = serializeJob
                    };
                    DynamicTypeList.PopulateList(this, ghostSerializerCollectionSystem.Serializers, true,
                                                 ref dynamicListJob.List);

                    dynamicListJob.Schedule().Complete();
                }
            }


            // 移除的ghost
            Entities.With(ghostDespawnGroup).ForEach((Entity ent, ref GhostSystemStateComponent state) =>
            {
                _newGhosts.Remove(state.ghostId);
                PostUpdateCommands.RemoveComponent <GhostSystemStateComponent>(ent);
            });

            connections.Dispose();
            ghostChunks.Dispose();
            despawnChunks.Dispose();
        }