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; } } } }); }
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(); }