public override bool Serialize(BitStream stream, EndpointId forClient, uint timestamp, byte packetId, int maxBitPosition) { bool lowPrecisionOrientation = true; bool applyWhenReading = true; SetSupport(FindSupportDelegate()); if (stream.Writing) { bool moving = IsMoving(Entity); stream.WriteBool(moving); SerializeVelocities(stream, Entity, MyEntityPhysicsStateGroup.EffectiveSimulationRatio, applyWhenReading, moving); SerializeTransform(stream, Entity, null, lowPrecisionOrientation, applyWhenReading, moving, timestamp); } else { bool moving = stream.ReadBool(); // reading SerializeServerVelocities(stream, Entity, MyEntityPhysicsStateGroup.EffectiveSimulationRatio, moving, ref Entity.m_serverLinearVelocity, ref Entity.m_serverAngularVelocity); applyWhenReading = SerializeServerTransform(stream, Entity, null, moving, timestamp, lowPrecisionOrientation, ref Entity.m_serverPosition, ref Entity.m_serverOrientation, ref Entity.m_serverWorldMatrix, m_positionValidation); if (applyWhenReading && moving) { Entity.PositionComp.SetWorldMatrix(Entity.m_serverWorldMatrix, null, true); Entity.SetSpeedsAccordingToServerValues(); } } SerializeFriction(stream, Entity); SerializeActive(stream, Entity); return true; }
public static bool CompressedQuaternionUnitTest() { var stream = new VRage.Library.Collections.BitStream(); stream.ResetWrite(); Quaternion q = Quaternion.Identity; stream.WriteQuaternionNormCompressed(q); stream.ResetRead(); var q2 = stream.ReadQuaternionNormCompressed(); bool fail = !q.Equals(q2, 1 / 511.0f); stream.ResetWrite(); q = Quaternion.CreateFromAxisAngle(Vector3.Forward, (float)Math.PI / 3.0f); stream.WriteQuaternionNormCompressed(q); stream.ResetRead(); q2 = stream.ReadQuaternionNormCompressed(); fail |= !q.Equals(q2, 1 / 511.0f); stream.ResetWrite(); var v = new Vector3(1, -1, 3); v.Normalize(); q = Quaternion.CreateFromAxisAngle(v, (float)Math.PI / 3.0f); stream.WriteQuaternionNormCompressed(q); stream.ResetRead(); q2 = stream.ReadQuaternionNormCompressed(); fail |= !q.Equals(q2, 1 / 511.0f); return(fail); }
public override void Serialize(BitStream stream,uint serverTimeStamp) { if (stream.Writing) Write(stream); else Read(stream, serverTimeStamp); }
public BitReaderWriter(IBitSerializable writeData) { m_writeData = writeData; m_readStream = null; m_readStreamPosition = 0; IsReading = false; }
protected void SerializeActive(BitStream stream, MyEntity entity) { if (stream.Writing) { if (entity.Physics.RigidBody != null && entity.Physics.RigidBody.IsActive) stream.WriteBool(true); else stream.WriteBool(false); } else { // reading bool isActive = stream.ReadBool(); if (entity != null && entity.Physics != null) { HkRigidBody rb = entity.Physics.RigidBody; if (rb != null) { if (isActive) rb.Activate(); else rb.Deactivate(); } } } }
private BitReaderWriter(BitStream readStream, int readPos) { m_writeData = null; m_readStream = readStream; m_readStreamPosition = readPos; IsReading = true; }
public void Serialize(BitStream stream, MyClientStateBase forClient, byte packetId, int maxBitPosition) { SmallBitField dirtyFlags; if (stream.Writing) { var data = m_clientData[forClient]; dirtyFlags = data.DirtyProperties; stream.WriteUInt64(dirtyFlags.Bits, m_properties.Count); } else { dirtyFlags.Bits = stream.ReadUInt64(m_properties.Count); } for (int i = 0; i < m_properties.Count; i++) { if (dirtyFlags[i]) { m_properties[i].Serialize(stream, false); // Received from server, don't validate if (stream.Reading) // Received from server, it's no longer dirty m_dirtyProperties[i] = false; } } if (stream.Writing && stream.BitPosition <= maxBitPosition) { var data = m_clientData[forClient]; data.PacketId = packetId; data.SentProperties.Bits = data.DirtyProperties.Bits; data.DirtyProperties.Bits = 0; } }
public override void Serialize(BitStream stream) { if (stream.Writing) Write(stream); else Read(stream); }
public void Write(BitStream stream) { // TODO: this is suboptimal if (stream == null || m_writeData == null) { if (stream == null) Debug.Fail("BitReaderWriter - Write - stream is null"); if ( m_writeData == null) Debug.Fail("BitReaderWriter - Write - m_writeData is null"); return; } // Store old bit position int pos = stream.BitPosition; // Write data m_writeData.Serialize(stream, false); // Measure data len int len = stream.BitPosition - pos; // Restore old position stream.SetBitPositionWrite(pos); // Write data len stream.WriteVariant((uint)len); // Write data again m_writeData.Serialize(stream, false); }
public static BitReaderWriter ReadFrom(BitStream stream) { Debug.Assert(stream.Reading, "Read stream should be set for reading!"); // Move current position after the data uint dataBitLen = stream.ReadUInt32Variant(); var reader = new BitReaderWriter(stream, stream.BitPosition); stream.SetBitPositionRead(stream.BitPosition + (int)dataBitLen); return reader; }
void Write(BitStream stream) { // TODO: Make sure sleeping, server controlled entities are not moving locally (or they can be but eventually their position should be corrected) stream.WriteBool(MySession.ControlledEntity != null); if (MySession.ControlledEntity == null) { Vector3D pos = MySpectatorCameraController.Static.Position; stream.WriteDouble(pos.X); stream.WriteDouble(pos.Y); stream.WriteDouble(pos.Z); } else { var controlledEntity = MySession.ControlledEntity.Entity.GetTopMostParent(); // Send controlled entity every other frame to server if (MyMultiplayer.Static.FrameCounter % 2 == 0) { // TODO: Write additional client data, context if (controlledEntity != null && controlledEntity.SyncFlag && ((MySyncEntity)controlledEntity.SyncObject).ResponsibleForUpdate(Sync.Clients.LocalClient)) { stream.WriteInt64(controlledEntity.EntityId); switch (MyGuiScreenTerminal.GetCurrentScreen()) { case MyTerminalPageEnum.Inventory: stream.WriteInt32((int)MyContextKind.Inventory, 2); break; case MyTerminalPageEnum.ControlPanel: stream.WriteInt32((int)MyContextKind.Terminal, 2); break; case MyTerminalPageEnum.Production: stream.WriteInt32((int)MyContextKind.Production, 2); break; default: stream.WriteInt32((int)MyContextKind.None, 2); break; } if (MyGuiScreenTerminal.InteractedEntity != null) { stream.WriteInt64(MyGuiScreenTerminal.InteractedEntity.EntityId); } else { stream.WriteInt64(0); } ((MySyncEntity)controlledEntity.SyncObject).SerializePhysics(stream, null); } } } }
protected override void WriteInternal(BitStream stream, MyEntity controlledEntity) { MyContextKind context = GetContextByPage(MyGuiScreenTerminal.GetCurrentScreen()); stream.WriteInt32((int)context, 2); if (context != MyContextKind.None) { var entityId = MyGuiScreenTerminal.InteractedEntity != null ? MyGuiScreenTerminal.InteractedEntity.EntityId : 0; stream.WriteInt64(entityId); } }
private void Write(BitStream stream) { // TODO: Make sure sleeping, server controlled entities are not moving locally (or they can be but eventually their position should be corrected) MyEntity controlledEntity = GetControlledEntity(); WriteShared(stream, controlledEntity); if (controlledEntity != null) { WriteInternal(stream, controlledEntity); WritePhysics(stream, controlledEntity); } }
protected override void ReadInternal(BitStream stream, MyNetworkClient sender, MyEntity controlledEntity) { Context = (MyContextKind)stream.ReadInt32(2); if (Context != MyContextKind.None) { long entityId = stream.ReadInt64(); ContextEntity = MyEntities.GetEntityByIdOrDefault(entityId); } else { ContextEntity = null; } }
public override bool Serialize(BitStream stream, EndpointId forClient,uint timeStamp, byte packetId, int maxBitPosition) { base.Serialize(stream, forClient,timeStamp, packetId, maxBitPosition); if (stream.Writing) { // Head and spine stuff, 36 - 152b (4.5B - 19 B) stream.WriteHalf(Entity.HeadLocalXAngle); // 2B stream.WriteHalf(Entity.HeadLocalYAngle); // 2B // TODO: Spine has only one angle (bending forward backward) // Getting EULER angles from Matrix seems good way to get it (z-component) stream.WriteQuaternionNormCompressedIdentity(Entity.GetAdditionalRotation(Entity.Definition.SpineBone)); // 1b / 30b stream.WriteQuaternionNormCompressedIdentity(Entity.GetAdditionalRotation(Entity.Definition.HeadBone)); // 1b / 30b // Movement state, 2B stream.WriteUInt16((ushort)Entity.GetCurrentMovementState()); // Movement flag. stream.WriteUInt16((ushort)Entity.MovementFlags); // Flags, 6 bits bool hasJetpack = Entity.JetpackComp != null; stream.WriteBool(hasJetpack ? Entity.JetpackComp.TurnedOn : false); stream.WriteBool(hasJetpack ? Entity.JetpackComp.DampenersTurnedOn : false); stream.WriteBool(Entity.LightEnabled); // TODO: Remove stream.WriteBool(Entity.ZoomMode == MyZoomModeEnum.IronSight); stream.WriteBool(Entity.RadioBroadcaster.WantsToBeEnabled); // TODO: Remove stream.WriteBool(Entity.TargetFromCamera); stream.WriteNormalizedSignedVector3(Entity.MoveIndicator, 8); float speed = Entity.Physics.CharacterProxy != null ? Entity.Physics.CharacterProxy.Speed : 0.0f; stream.WriteFloat(speed); stream.WriteFloat(Entity.RotationIndicator.X); stream.WriteFloat(Entity.RotationIndicator.Y); stream.WriteFloat(Entity.RollIndicator); } else { Vector3 move; MyCharacterNetState charNetState = ReadCharacterState(stream); if (!IsControlledLocally && !Entity.Closed) { Entity.SetStateFromNetwork(ref charNetState); } } return true; }
public void Serialize(BitStream stream, Type baseType, ref Type obj) { if (stream.Reading) { var id = new TypeId(stream.ReadUInt32()); obj = MyMultiplayer.Static.ReplicationLayer.GetType(id); } else { var id = MyMultiplayer.Static.ReplicationLayer.GetTypeId(obj); stream.WriteUInt32(id); } }
public bool Serialize(BitStream stream, bool validate) { if (stream.Reading) { SenderUserId = stream.ReadInt64(); NumElements = stream.ReadInt32(); stream.ReadBytes(CompressedVoiceBuffer, 0,NumElements); } else { stream.WriteInt64(SenderUserId); stream.WriteInt32(NumElements); stream.WriteBytes(CompressedVoiceBuffer, 0, NumElements); } return true; }
private void Read(BitStream stream) { MyNetworkClient sender; if (!Sync.Clients.TryGetClient(EndpointId.Value, out sender)) { Debug.Fail("Unknown sender"); return; } MyEntity controlledEntity; ReadShared(stream, sender, out controlledEntity); if (controlledEntity != null) { ReadInternal(stream, sender, controlledEntity); ReadPhysics(stream, sender, controlledEntity); } }
public void Write(BitStream stream) { // TODO: this is suboptimal // Store old bit position int pos = stream.BitPosition; // Write data m_writeData.Serialize(stream, false); // Measure data len int len = stream.BitPosition - pos; // Restore old position stream.SetBitPositionWrite(pos); // Write data len stream.WriteVariant((uint)len); // Write data again m_writeData.Serialize(stream, false); }
public override bool Serialize(BitStream stream, EndpointId forClient, uint timestamp, byte packetId, int maxBitPosition) { bool lowPrecisionOrientation = true; bool applyWhenReading = true; if (stream.Writing) { bool moving = IsMoving(Entity); stream.WriteBool(moving); SerializeVelocities(stream, Entity, MyEntityPhysicsStateGroup.EffectiveSimulationRatio, applyWhenReading, moving); SerializeTransform(stream, Entity, null, lowPrecisionOrientation, applyWhenReading, moving, timestamp); } else { bool moving = stream.ReadBool(); // reading SerializeServerVelocities(stream, Entity, MyEntityPhysicsStateGroup.EffectiveSimulationRatio, moving, ref Entity.m_serverLinearVelocity, ref Entity.m_serverAngularVelocity); float positionTolerancy = Math.Max(Entity.PositionComp.MaximalSize * 0.1f, 0.1f); float smallSpeed = 0.1f; if (Entity.m_serverLinearVelocity == Vector3.Zero || Entity.m_serverLinearVelocity.Length() < smallSpeed) { positionTolerancy = Math.Max(Entity.PositionComp.MaximalSize * 0.5f, 1.0f); } applyWhenReading = SerializeServerTransform(stream, Entity, null, moving, timestamp, lowPrecisionOrientation, positionTolerancy, ref Entity.m_serverPosition, ref Entity.m_serverOrientation, ref Entity.m_serverWorldMatrix, m_positionValidation); if (applyWhenReading && moving) { Entity.PositionComp.SetWorldMatrix(Entity.m_serverWorldMatrix, null, true); Entity.SetSpeedsAccordingToServerValues(); } } SerializeFriction(stream, Entity); SerializeActive(stream, Entity); return true; }
private void WritePlanetSectors(BitStream stream) { stream.WriteInt32(0x42424242); var planets = MyPlanets.GetPlanets(); stream.WriteInt32(planets.Count); foreach (var planet in planets) { stream.WriteInt64(planet.EntityId); foreach (var sector in planet.EnvironmentSectors.Values) { if (sector.HasPhysics || sector.ServerOwned) { stream.WriteInt64(sector.SectorId.Pack64()); } } // don't know how many in advance so I will use -1 termination instead of count. stream.WriteInt64(-1); } }
public void EnqueueEvent(BitStream stream, NetworkId objectInstance, uint eventId, EndpointId sender) { int requiredByteSize = stream.ByteLength - stream.BytePosition + 1; var e = ObtainEvent(); e.Stream.ResetWrite(); e.Stream.WriteBitStream(stream); e.Stream.ResetRead(); e.ObjectInstance = objectInstance; e.EventId = eventId; e.Sender = sender; List<BufferedEvent> events; if (!m_buffer.TryGetValue(objectInstance, out events)) { events = ObtainList(); m_buffer.Add(objectInstance, events); } events.Add(e); }
internal override void ProcessEvent(BitStream stream, CallSite site, object obj, IMyNetObject sendAs, EndpointId source) { // Client blindly invokes everything received from server (without validation) Invoke(site, stream, obj, source, null, false); }
protected override void ProcessEvent(BitStream stream, NetworkId networkId, uint eventId, EndpointId sender) { if (networkId.IsValid && m_pendingReplicables.ContainsKey(networkId)) { m_eventBuffer.EnqueueEvent(stream, networkId, eventId, sender); } else { base.ProcessEvent(stream, networkId, eventId, sender); } }
internal override bool DispatchEvent(BitStream stream, CallSite site, EndpointId target, IMyNetObject instance, float unreliablePriority) { Debug.Assert(site.HasServerFlag, String.Format("Event '{0}' does not have server flag, it can't be invoked on server!", site)); if (site.HasServerFlag) { m_callback.SendEvent(stream, site.IsReliable); //Client.SendMessageToServer(stream, site.Reliability, PacketPriorityEnum.LOW_PRIORITY, MyChannelEnum.Replication); } else if (site.HasClientFlag) { // Invoke locally only when it has ClientFlag and no ServerFlag return true; } return false; }
public void WriteBitStream(BitStream readStream) { // Make better, preferably by reading to aligned area int numBits = readStream.BitLength - readStream.m_bitPosition; while (numBits > 0) { int readBits = Math.Min(64, numBits); ulong value = readStream.ReadUInt64(readBits); WriteUInt64(value, readBits); numBits -= readBits; } }
private void SerializeRopeData(BitStream stream, bool applyWhenReading, List<MyCubeGrid> gridsGroup = null) { if (MyRopeComponent.Static == null) return; if (stream.Writing) { m_tmpRopes.Clear(); m_tmpRopeGrids.Clear(); m_tmpRopeGrids.Add(Entity); Debug.Assert(gridsGroup != null); if (gridsGroup != null) { foreach (var grid in gridsGroup) m_tmpRopeGrids.Add(grid); } MyRopeComponent.Static.GetRopesForGrids(m_tmpRopeGrids, m_tmpRopes); MyRopeData ropeData; stream.WriteUInt16((ushort)m_tmpRopes.Count); foreach (var rope in m_tmpRopes) { var ropeProxyTarget = MyMultiplayer.Static.ReplicationLayer.GetProxyTarget((IMyEventProxy)rope); NetworkId ropeNetworkId = MyMultiplayer.Static.ReplicationLayer.GetNetworkIdByObject(ropeProxyTarget); stream.WriteNetworkId(ropeNetworkId); //TODO - MyRopeComponent should be rewritten to singleton MyRopeComponent.GetRopeData(rope.EntityId, out ropeData); stream.WriteFloat(ropeData.CurrentRopeLength); } m_tmpRopes.Clear(); m_tmpRopeGrids.Clear(); } else { uint ropesCount = stream.ReadUInt16(); for (uint i = 0; i < ropesCount; ++i) { NetworkId ropeNetworkId = stream.ReadNetworkId(); float ropeLength = stream.ReadFloat(); MyRopeReplicable replicable = MyMultiplayer.Static.ReplicationLayer.GetObjectByNetworkId(ropeNetworkId) as MyRopeReplicable; MyRope rope = replicable != null ? replicable.Instance : null; if (rope != null && applyWhenReading) MyRopeComponent.Static.SetRopeLengthSynced(rope.EntityId, ropeLength); } } }
public override bool Serialize(BitStream stream, EndpointId forClient,uint timestamp, byte packetId, int maxBitPosition) { // Client does not care about slave grids, he always synced group through controlled object Debug.Assert(stream.Reading || !Sync.IsServer || Entity == GetMasterGrid(Entity), "Writing data from SlaveGrid!"); bool apply = !IsControlledLocally; bool moving = false; if (stream.Writing) { moving = IsMoving(Entity); stream.WriteBool(moving); } else { moving = stream.ReadBool(); } // Serialize this grid apply = SerializeTransform(stream, Entity, null, m_lowPrecisionOrientation, apply,moving, timestamp, m_positionValidation, MoveHandler); SerializeVelocities(stream, Entity, EffectiveSimulationRatio, apply, moving,VelocityHandler); // Serialize other grids in group Vector3D basePos = Entity.WorldMatrix.Translation; if (stream.Writing) { bool fullyWritten = true; UpdateGridMaxSpeed(Entity, Sync.IsServer); var g = MyCubeGridGroups.Static.PhysicalDynamic.GetGroup(Entity); if (g == null) { stream.WriteBool(false); } else { m_groups.Clear(); int i = 0; foreach (var node in g.Nodes) { i++; if (ResponsibleForUpdate(node.NodeData, forClient)) { continue; } if(i < m_currentSentPosition) { continue; } var target = MyMultiplayer.Static.ReplicationLayer.GetProxyTarget((IMyEventProxy)node.NodeData); int pos = stream.BitPosition; if (node.NodeData != Entity && !node.NodeData.IsStatic && target != null) { stream.WriteBool(true); // ~26.5 bytes per grid, not bad NetworkId networkId = MyMultiplayer.Static.ReplicationLayer.GetNetworkIdByObject(target); stream.WriteNetworkId(networkId); // ~2 bytes moving = IsMoving(node.NodeData); stream.WriteBool(moving); SerializeTransform(stream, node.NodeData, basePos, m_lowPrecisionOrientation, apply, moving, timestamp, null, null); // 12.5 bytes SerializeVelocities(stream, node.NodeData, EffectiveSimulationRatio, apply, moving); // 12 byte UpdateGridMaxSpeed(node.NodeData, Sync.IsServer); m_groups.Add(node.NodeData); m_currentSentPosition++; } if (stream.BitPosition > maxBitPosition) { stream.SetBitPositionWrite(pos); fullyWritten = false; m_currentSentPosition--; break; } if (i == g.Nodes.Count) { m_currentSentPosition = 0; } } stream.WriteBool(false); } stream.WriteBool(fullyWritten); if (fullyWritten) { SerializeRopeData(stream, apply, gridsGroup: m_groups); } return fullyWritten; } else { UpdateGridMaxSpeed(Entity, !Sync.IsServer); while (stream.ReadBool()) { NetworkId networkId = stream.ReadNetworkId(); // ~2 bytes MyCubeGridReplicable replicable = MyMultiplayer.Static.ReplicationLayer.GetObjectByNetworkId(networkId) as MyCubeGridReplicable; MyCubeGrid grid = replicable != null ? replicable.Grid : null; moving = stream.ReadBool(); SerializeTransform(stream, grid, basePos, m_lowPrecisionOrientation, apply && grid != null, moving, timestamp, null, null); // 12.5 bytes SerializeVelocities(stream, grid, EffectiveSimulationRatio, apply && grid != null, moving); // 12 bytes UpdateGridMaxSpeed(grid,!Sync.IsServer); } if (stream.ReadBool()) { SerializeRopeData(stream, apply); } } return true; }
void IReplicationServerCallback.SendEvent(BitStream stream, bool reliable, EndpointId endpoint) { SyncLayer.TransportLayer.SendMessage(MyMessageId.RPC, stream, reliable, endpoint); }
void IReplicationServerCallback.SendStateSync(BitStream stream, EndpointId endpoint,bool reliable) { SyncLayer.TransportLayer.SendMessage(MyMessageId.SERVER_STATE_SYNC, stream, reliable, endpoint); }
void IReplicationServerCallback.SendReplicationDestroy(BitStream stream, EndpointId endpoint) { SyncLayer.TransportLayer.SendMessage(MyMessageId.REPLICATION_DESTROY, stream, true, endpoint); }
public static TypeId ReadTypeId(this VRage.Library.Collections.BitStream stream) { return(new TypeId(stream.ReadUInt32Variant())); }
public static void WriteNetworkId(this VRage.Library.Collections.BitStream stream, NetworkId networkId) { stream.WriteVariant((uint)networkId.Value); }
public static void WriteTypeId(this VRage.Library.Collections.BitStream stream, TypeId typeId) { stream.WriteVariant((uint)typeId.Value); }