/// <summary> /// Processes state sync sent by server. /// </summary> public void ProcessStateSync(MyPacket packet) { LastMessageFromServer = DateTime.UtcNow; // Simulated packet loss // if (MyRandom.Instance.NextFloat() > 0.3f) return; m_receiveStream.ResetRead(packet); bool isStreaming = m_receiveStream.ReadBool(); m_lastStateSyncPacketId = m_receiveStream.ReadByte(); try { while (m_receiveStream.BytePosition < m_receiveStream.ByteLength) { NetworkId networkID = m_receiveStream.ReadNetworkId(); IMyStateGroup obj = GetObjectByNetworkId(networkID) as IMyStateGroup; if (obj == null) { if (isStreaming == false) { Debug.Fail("IMyStateGroup not found by NetworkId"); break; } else { return; } } if (isStreaming && obj.GroupType != StateGroupEnum.Streamining) { Debug.Fail("group type mismatch !"); MyLog.Default.WriteLine("received streaming flag but group is not streaming !"); return; } if (!isStreaming && obj.GroupType == StateGroupEnum.Streamining) { Debug.Fail("group type mismatch !"); MyLog.Default.WriteLine("received non streaming flag but group wants to stream !"); return; } var pos = m_receiveStream.BytePosition; NetProfiler.Begin(obj.GetType().Name); obj.Serialize(m_receiveStream, ClientState.EndpointId, 0, m_lastStateSyncPacketId, 0); NetProfiler.End(m_receiveStream.ByteLength - pos); if (!m_acks.Contains(m_lastStateSyncPacketId)) { m_acks.Add(m_lastStateSyncPacketId); } } } catch (BitStreamException) { } }
private void WritePhysics(BitStream stream, MyEntity controlledEntity) { IMyReplicable controlledReplicable = MyExternalReplicable.FindByObject(controlledEntity); stream.WriteBool(controlledReplicable != null); if (controlledReplicable == null) { return; } IMyStateGroup stateGroup = null; bool useCharacterOnServer = controlledEntity is MyCharacter && MyFakes.ENABLE_CHARACTER_CONTROL_ON_SERVER; bool useGridOnServer = controlledEntity is MyCubeGrid && MyFakes.ENABLE_SHIP_CONTROL_ON_SERVER; MyShipController controller = MySession.Static.ControlledEntity as MyShipController; bool hasWheels = controller != null && controller.HasWheels; long? supportId = null; if (useCharacterOnServer || (useGridOnServer && hasWheels == false)) { MyEntityPositionVerificationStateGroup group = controlledReplicable.FindStateGroup <MyEntityPositionVerificationStateGroup>(); stateGroup = group; supportId = group.GetSupportID(); } else { stateGroup = controlledReplicable.FindStateGroup <MyEntityPhysicsStateGroup>(); } stream.WriteBool(useCharacterOnServer || (useGridOnServer && hasWheels == false)); stream.WriteBool(stateGroup != null); if (stateGroup == null) { return; } stream.WriteBool(supportId.HasValue); if (supportId.HasValue) { stream.WriteInt64(supportId.Value); } bool isResponsible = MyEntityPhysicsStateGroup.ResponsibleForUpdate(controlledEntity, new EndpointId(Sync.MyId)); stream.WriteBool(isResponsible); if (isResponsible) { stateGroup.Serialize(stream, EndpointId, ClientTimeStamp, 0, 1024 * 1024); } }
private void ReadPhysics(BitStream stream, MyNetworkClient sender, MyEntity controlledEntity, uint serverTimeStamp) { bool hasPhysics = stream.ReadBool(); m_currentServerTimeStamp = serverTimeStamp; if (hasPhysics && MyEntityPhysicsStateGroup.ResponsibleForUpdate(controlledEntity, new EndpointId(sender.SteamUserId))) { IMyStateGroup stateGroup = null; SupportId = null; bool enableControlOnServer = stream.ReadBool(); bool stateGroupFound = stream.ReadBool(); if (stateGroupFound == false) { return; } if (stream.ReadBool()) { SupportId = stream.ReadInt64(); } if (enableControlOnServer) { stateGroup = MyExternalReplicable.FindByObject(controlledEntity).FindStateGroup <MyEntityPositionVerificationStateGroup>(); } else { stateGroup = MyExternalReplicable.FindByObject(controlledEntity).FindStateGroup <MyEntityPhysicsStateGroup>(); } if (stream.ReadBool()) { stateGroup.Serialize(stream, new EndpointId(sender.SteamUserId), ClientTimeStamp, 0, 65535); } } }
//List<byte> m_alreadyReceivedPackets = new List<byte>(); /// <summary> /// Processes state sync sent by server. /// </summary> public void ProcessStateSync(MyPacket packet) { LastMessageFromServer = DateTime.UtcNow; // Simulated packet loss // if (MyRandom.Instance.NextFloat() > 0.3f) return; ReceiveStream.ResetRead(packet); bool isStreaming = ReceiveStream.ReadBool(); var packetId = ReceiveStream.ReadByte(); //if (m_alreadyReceivedPackets.Contains(packetId)) //{ //} //if (m_alreadyReceivedPackets.Count > 128) // m_alreadyReceivedPackets.RemoveAt(0); //m_alreadyReceivedPackets.Add(packetId); var serverOrder = m_serverTracker.Add(packetId); m_serverStats.Update(serverOrder); if (serverOrder == MyPacketTracker.OrderType.Duplicate) { return; } m_lastStateSyncPacketId = packetId; MyPacketStatistics stats = new MyPacketStatistics(); stats.Read(ReceiveStream); m_clientStatsFromServer.Add(stats); var serverTimeStamp = MyTimeSpan.FromMilliseconds(ReceiveStream.ReadDouble()); if (m_lastServerTimeStamp < serverTimeStamp) { m_lastServerTimeStamp = serverTimeStamp; } double lastClientRealtime = ReceiveStream.ReadDouble(); if (lastClientRealtime > 0) { var ping = packet.ReceivedTime - MyTimeSpan.FromMilliseconds(lastClientRealtime); if (ping.Milliseconds < 1000) { SetPing(ping); } } MyTimeSpan relevantTimeStamp = serverTimeStamp; m_callback.ReadCustomState(ReceiveStream); while (ReceiveStream.BytePosition < ReceiveStream.ByteLength) { NetworkId networkID = ReceiveStream.ReadNetworkId(); IMyStateGroup obj = GetObjectByNetworkId(networkID) as IMyStateGroup; if (obj == null) { if (isStreaming == false) { Debug.Fail("IMyStateGroup not found by NetworkId"); break; } else { return; } } if (isStreaming && obj.GroupType != StateGroupEnum.Streaming) { Debug.Fail("group type mismatch !"); MyLog.Default.WriteLine("received streaming flag but group is not streaming !"); return; } if (!isStreaming && obj.GroupType == StateGroupEnum.Streaming) { Debug.Fail("group type mismatch !"); MyLog.Default.WriteLine("received non streaming flag but group wants to stream !"); return; } if (VRage.MyCompilationSymbols.EnableNetworkPacketTracking) { Trace.MyTrace.Send(Trace.TraceWindow.MPackets, " ObjSync: " + obj.GetType().Name); } var pos = ReceiveStream.BytePosition; NetProfiler.Begin(obj.GetType().Name); obj.Serialize(ReceiveStream, ClientState.EndpointId, relevantTimeStamp, m_lastStateSyncPacketId, 0); NetProfiler.End(ReceiveStream.ByteLength - pos); if (!m_acks.Contains(m_lastStateSyncPacketId)) { m_acks.Add(m_lastStateSyncPacketId); } } }