protected override void ServerRead(VRage.Library.Collections.BitStream stream, ulong clientId, uint timestamp)
        {
            base.ServerRead(stream, clientId, timestamp);
            if (stream.ReadBool())
            {
                if (m_grid != null)
                {
                    bool isStatic = stream.ReadBool();
                    if (isStatic == false)
                    {
                        if (stream.ReadBool())
                        {
                            long    entityId = stream.ReadInt64();
                            Vector2 rotation = new Vector2();
                            rotation.X = stream.ReadFloat();
                            rotation.Y = stream.ReadFloat();

                            float roll = stream.ReadHalf();

                            Vector3 move = new Vector3();
                            move.X = stream.ReadHalf();
                            move.Y = stream.ReadHalf();
                            move.Z = stream.ReadHalf();

                            MyShipController controller;
                            if (MyEntities.TryGetEntityById <MyShipController>(entityId, out controller))
                            {
                                controller.CacheMoveAndRotate(ref move, ref rotation, roll);
                            }
                        }
                    }
                }
            }
        }
        void ClientRead(VRage.Library.Collections.BitStream stream)
        {
            bool hasClientData = stream.ReadBool();
            uint?timeStamp     = null;

            if (hasClientData)
            {
                timeStamp = stream.ReadUInt32();
                m_lastRecievedTimeStamp = timeStamp.Value;

                bool isUpdate = stream.ReadBool();
                if (isUpdate)
                {
                    MyTransformD serverTransform = new MyTransformD();
                    serverTransform.Position = stream.ReadVector3D();
                    serverTransform.Rotation = Quaternion.Identity;

                    CustomClientRead(timeStamp.Value, ref serverTransform, stream);
                }
            }

            Vector3 serverLinearVelocity  = stream.ReadVector3();
            Vector3 serverAngularVelocity = stream.ReadVector3();

            MyTimeStampValues?clientData = null;

            if (timeStamp.HasValue)
            {
                clientData = m_timestamp.GetTransform(timeStamp.Value);
            }

            if (clientData.HasValue)
            {
                Vector3 linearDelta = serverLinearVelocity / MyEntityPhysicsStateGroup.EffectiveSimulationRatio - clientData.Value.LinearVelocity;
                Entity.Physics.LinearVelocity += Vector3.Round(linearDelta, 2);
                Vector3 angularDelta = serverAngularVelocity / MyEntityPhysicsStateGroup.EffectiveSimulationRatio - clientData.Value.AngularVelocity;
                Entity.Physics.AngularVelocity += Vector3.Round(angularDelta, 2);

                m_timestamp.UpdateDeltaVelocities(timeStamp.Value, ref linearDelta, ref angularDelta);
            }
            else
            {
                Vector3 linearVelocity = serverLinearVelocity / MyEntityPhysicsStateGroup.EffectiveSimulationRatio;
                Entity.Physics.LinearVelocity = Vector3.Round(linearVelocity, 2);
                Vector3 angularVelocity = serverAngularVelocity / MyEntityPhysicsStateGroup.EffectiveSimulationRatio;
                Entity.Physics.AngularVelocity = Vector3.Round(angularVelocity, 2);
            }
        }
예제 #3
0
        protected override void ServerRead(VRage.Library.Collections.BitStream stream, ulong clientId, uint timestamp)
        {
            base.ServerRead(stream, clientId, timestamp);

            if (m_additionalServerClientData == null)
            {
                m_additionalServerClientData = new Dictionary <ulong, Vector3D>();
            }

            m_additionalServerClientData[clientId] = stream.ReadVector3D();

            if (stream.ReadBool())
            {
                if (m_grid != null)
                {
                    bool isStatic = stream.ReadBool();
                    if (isStatic == false)
                    {
                        if (stream.ReadBool())
                        {
                            long    entityId = stream.ReadInt64();
                            Vector2 rotation = new Vector2();
                            rotation.X = stream.ReadFloat();
                            rotation.Y = stream.ReadFloat();

                            float roll = stream.ReadHalf();

                            Vector3 move = new Vector3();
                            move.X = stream.ReadHalf();
                            move.Y = stream.ReadHalf();
                            move.Z = stream.ReadHalf();

                            Vector3D         gridPos = Vector3D.Zero;
                            MyShipController controller;
                            if (MyEntities.TryGetEntityById <MyShipController>(entityId, out controller))
                            {
                                controller.CacheMoveAndRotate(move, rotation, roll);
                                gridPos = controller.CubeGrid.PositionComp.GetPosition();
                            }

                            MyGridPhysicsStateGroup.ReadSubGrids(stream, timestamp, true, m_lowPositionOrientation, ref gridPos);
                        }
                    }
                }
            }
        }
        private void ProcessRead(ref VRage.Library.Collections.BitStream stream)
        {
            //becaouse client state group is unreliable, it can happen, that some acks are not recieved at server
            //and server sends them again. In streaming this is not good, so we need to drop streaming when we got stream again
            if (stream.BitLength == stream.BitPosition || m_streamed)
            {
                return;
            }

            bool hasData = stream.ReadBool();

            if (hasData)
            {
                m_uncompressedSize = stream.ReadInt32();

                if (ReadPart(ref stream) == false)
                {
                    //something wrong happened, server send bad data, don't know what to do,
                    //cancel replicable on server
                    m_recivedParts = null;
                    Instance.LoadCancel();
                    return;
                }

                if (m_recivedParts.Count == m_numPartsToRecive)
                {
                    m_streamed = true;
                    CreateReplicable(m_uncompressedSize);
                }
            }
            else
            {
                Debug.Assert(false, "testing assert to find issue, if you got this and game is running, please ignore it");
                MyLog.Default.WriteLine("received empty state group");
                //something went wrong we need to cancel this replicable and hope next time it will be ok
                if (m_recivedParts != null)
                {
                    m_recivedParts.Clear();
                }
                m_recivedParts = null;
                Instance.LoadCancel();
            }
        }
        protected override void CustomClientRead(uint timeStamp, ref MyTimeStampValues serverPositionAndOrientation, VRage.Library.Collections.BitStream stream)
        {
            bool hasSupport = stream.ReadBool();

            if (hasSupport)
            {
                long entityId = stream.ReadInt64();

                Vector3D serverDelta      = stream.ReadVector3D();
                Vector3D serverSupportPos = stream.ReadVector3D();

                if (!MyEntities.EntityExists(entityId))
                {
                    return;
                }

                MyEntity support = MyEntities.GetEntityById(entityId);

                MyTimeStampValues?clientTransform = m_timestamp.GetTransform(timeStamp);

                Vector3D   clientDelta    = Vector3.Zero;
                Vector3D   clientVelocity = Vector3D.Zero;
                Quaternion rotationComp   = Quaternion.Identity;

                if (clientTransform != null)
                {
                    if (m_supportTimeStamp == null)
                    {
                        return;
                    }
                    MyTimeStampValues?supportTransform = m_supportTimeStamp.GetTransform(timeStamp);

                    Vector3D supportPosition = support.PositionComp.WorldMatrix.Translation;

                    if (supportTransform.HasValue)
                    {
                        supportPosition = supportTransform.Value.Transform.Position;

                        if (supportTransform.Value.EntityId != entityId)
                        {
                            supportPosition = serverSupportPos;
                            return;
                        }
                    }

                    clientDelta    = supportPosition - clientTransform.Value.Transform.Position;
                    clientVelocity = clientTransform.Value.LinearVelocity;
                    rotationComp   = Quaternion.Inverse(clientTransform.Value.Transform.Rotation);
                }
                else
                {
                    m_character.PositionComp.SetWorldMatrix(serverPositionAndOrientation.Transform.TransformMatrix, null, true);
                    return;
                }

                MyTimeStampValues delta = new MyTimeStampValues();

                Quaternion.Multiply(ref serverPositionAndOrientation.Transform.Rotation, ref rotationComp, out delta.Transform.Rotation);

                delta.Transform.Position = clientDelta - serverDelta;
                delta.LinearVelocity     = serverPositionAndOrientation.LinearVelocity - clientVelocity;

                double deltaL = delta.Transform.Position.Length();

                //if difference is more than
                if (deltaL < (MyGridPhysics.ShipMaxLinearVelocity() * Sync.RelativeSimulationRatio))
                {
                    delta.Transform.Position = delta.Transform.Position * 0.2;
                    delta.Transform.Rotation = Quaternion.Slerp(delta.Transform.Rotation, Quaternion.Identity, 0.2f);
                }


                Quaternion normalized = delta.Transform.Rotation;
                normalized.Normalize();
                delta.Transform.Rotation = normalized;
                normalized = serverPositionAndOrientation.Transform.Rotation;
                normalized.Normalize();
                serverPositionAndOrientation.Transform.Rotation = normalized;

                Quaternion clientNormalized = clientTransform.Value.Transform.Rotation;
                clientNormalized.Normalize();

                double eps = 0.001;
                if (Math.Abs(Quaternion.Dot(serverPositionAndOrientation.Transform.Rotation, clientNormalized)) < 1 - eps && m_character.IsDead == false)
                {
                    Quaternion currentOrientation = Quaternion.CreateFromForwardUp(m_character.WorldMatrix.Forward, m_character.WorldMatrix.Up);
                    Quaternion.Multiply(ref delta.Transform.Rotation, ref currentOrientation, out currentOrientation);

                    MatrixD matrix        = MatrixD.CreateFromQuaternion(currentOrientation);
                    MatrixD currentMatrix = m_character.PositionComp.WorldMatrix;
                    currentMatrix.Translation = Vector3D.Zero;

                    if (currentMatrix.EqualsFast(ref matrix) == false)
                    {
                        if (m_character.Physics.CharacterProxy != null)
                        {
                            m_character.Physics.CharacterProxy.Forward = matrix.Forward;
                            m_character.Physics.CharacterProxy.Up      = matrix.Up;
                        }
                    }
                }

                if (deltaL > (MyGridPhysics.ShipMaxLinearVelocity() * Sync.RelativeSimulationRatio))
                {
                    m_character.PositionComp.SetPosition(serverPositionAndOrientation.Transform.Position);
                    m_character.Physics.LinearVelocity = serverPositionAndOrientation.LinearVelocity;
                    m_timestamp.OverwriteServerPosition(timeStamp, ref serverPositionAndOrientation);
                    return;
                }
                else if (deltaL > 5.0f * MyTimestampHelper.POSITION_TOLERANCE)
                {
                    m_character.CacheMoveDelta(ref delta.Transform.Position);
                }

                m_character.Physics.LinearVelocity += delta.LinearVelocity;

                m_timestamp.UpdateDeltaPosition(timeStamp, ref delta);
            }
            else
            {
                base.CustomClientRead(timeStamp, ref serverPositionAndOrientation, stream);
            }
        }
        protected override void ServerRead(VRage.Library.Collections.BitStream stream, ulong clientId, uint timestamp)
        {
            base.ServerRead(stream, clientId, timestamp);

            if (m_character != null)
            {
                Vector3 move = new Vector3();
                move.X = stream.ReadHalf();
                move.Y = stream.ReadHalf();
                move.Z = stream.ReadHalf();

                Vector2 rotate = new Vector2();
                rotate.X = stream.ReadFloat();
                rotate.Y = stream.ReadFloat();

                float roll = stream.ReadFloat();

                MyCharacterMovementEnum  MovementState = (MyCharacterMovementEnum)stream.ReadUInt16();
                MyCharacterMovementFlags MovementFlag  = (MyCharacterMovementFlags)stream.ReadUInt16();

                bool  Jetpack          = stream.ReadBool();
                bool  Dampeners        = stream.ReadBool();
                bool  Lights           = stream.ReadBool(); // TODO: Remove
                bool  Ironsight        = stream.ReadBool();
                bool  Broadcast        = stream.ReadBool(); // TODO: Remove
                bool  TargetFromCamera = stream.ReadBool();
                float headXAngle       = stream.ReadFloat();
                float headYAngle       = stream.ReadFloat();

                Quaternion rotation = Quaternion.Identity;

                if (Jetpack == false)
                {
                    rotation = stream.ReadQuaternionNorm();
                }

                if (m_character.IsDead || m_character.IsUsing != null)
                {
                    return;
                }

                var jetpack = m_character.JetpackComp;
                if (jetpack != null)
                {
                    if (Jetpack != jetpack.TurnedOn)
                    {
                        jetpack.TurnOnJetpack(Jetpack, true);
                    }
                    if (Dampeners != jetpack.DampenersTurnedOn)
                    {
                        jetpack.EnableDampeners(Dampeners, false);
                    }
                }
                if (Lights != m_character.LightEnabled)
                {
                    m_character.EnableLights(Lights);
                }

                if (m_character.RadioBroadcaster != null && Broadcast != m_character.RadioBroadcaster.Enabled)
                {
                    m_character.EnableBroadcasting(Broadcast);
                }

                m_character.TargetFromCamera = TargetFromCamera;

                // Set client movement state directly and don't perform other operations
                // that may have side-effects to let server side Character.UpdateAfterSimulation()
                // perform exactly same operations as on client
                m_character.MovementFlags = MovementFlag;
                m_character.SetCurrentMovementState(MovementState);
                m_character.HeadLocalXAngle = headXAngle;
                m_character.HeadLocalYAngle = headYAngle;


                m_character.CacheMove(ref move, ref rotate, ref roll);


                if (Jetpack == false)
                {
                    m_character.CacheRotation(ref rotation);
                }
            }
        }
예제 #7
0
        protected override void CustomClientRead(uint timeStamp, ref MyTransformD serverPositionAndOrientation, VRage.Library.Collections.BitStream stream)
        {
            bool hasSupport = stream.ReadBool();

            if (hasSupport)
            {
                long entityId = stream.ReadInt64();

                Vector3D serverSupportPos = stream.ReadVector3D();

                if (!MyEntities.EntityExists(entityId))
                {
                    return;
                }

                MyEntity support = MyEntities.GetEntityById(entityId);

                MyTimeStampValues?clientTransform = m_timestamp.GetTransform(timeStamp);

                Vector3D   clientPosition        = Vector3D.Zero;
                Vector3D   clientSupportPosition = Vector3D.Zero;
                Quaternion rotationComp          = Quaternion.Identity;

                if (clientTransform != null)
                {
                    if (m_supportTimeStamp == null)
                    {
                        return;
                    }

                    MyTimeStampValues?supportTransform = m_supportTimeStamp.GetTransform(timeStamp);
                    Vector3D          supportPosition  = support.PositionComp.WorldMatrix.Translation;

                    if (supportTransform.HasValue)
                    {
                        supportPosition = supportTransform.Value.Transform.Position;

                        if (supportTransform.Value.EntityId != entityId)
                        {
                            return;
                        }
                    }

                    clientPosition        = clientTransform.Value.Transform.Position;
                    clientSupportPosition = supportPosition;
                    rotationComp          = Quaternion.Inverse(clientTransform.Value.Transform.Rotation);
                }
                else
                {
                    m_character.PositionComp.SetWorldMatrix(serverPositionAndOrientation.TransformMatrix, null, true);
                    return;
                }

                MyTransformD delta = new MyTransformD();

                delta.Rotation = Quaternion.Identity;

                Vector3D characterDelta = serverPositionAndOrientation.Position - clientPosition;
                Vector3D supportDelta   = serverSupportPos - clientSupportPosition;

                delta.Position = characterDelta - supportDelta;
                m_character.CacheMoveDelta(ref delta.Position);
                m_timestamp.UpdateDeltaPosition(timeStamp, ref delta);
            }
            else
            {
                base.CustomClientRead(timeStamp, ref serverPositionAndOrientation, stream);
            }
        }
예제 #8
0
        protected override void ServerRead(VRage.Library.Collections.BitStream stream, ulong clientId, uint timestamp)
        {
            base.ServerRead(stream, clientId, timestamp);
            bool clientHasCharacter = stream.ReadBool();

            if (clientHasCharacter)
            {
                MyEntity support;
                bool     hasSupport      = stream.ReadBool();
                Vector3D supportPosition = Vector3D.Zero;

                if (m_character != null)
                {
                    var physGroup = MyExternalReplicable.FindByObject(m_character).FindStateGroup <MyCharacterPhysicsStateGroup>();
                    if (physGroup != null)
                    {
                        m_support = MySupportHelper.FindSupportForCharacterAABB(m_character);
                        physGroup.SetSupport(MySupportHelper.FindPhysics(m_support));
                    }
                }

                if (hasSupport)
                {
                    long supportId = stream.ReadInt64();
                    bool apply     = MyEntities.TryGetEntityById(supportId, out support);
                    supportPosition = stream.ReadVector3D();
                }


                if (m_additionalServerClientData == null)
                {
                    m_additionalServerClientData = new Dictionary <ulong, ClientData>();
                }

                m_additionalServerClientData[clientId] = new ClientData()
                {
                    HasSupport = hasSupport, SupportPosition = supportPosition
                };

                Vector3 move = new Vector3();
                move.X = stream.ReadHalf();
                move.Y = stream.ReadHalf();
                move.Z = stream.ReadHalf();

                Vector2 rotate = new Vector2();
                rotate.X = stream.ReadFloat();
                rotate.Y = stream.ReadFloat();

                float roll = stream.ReadFloat();

                MyCharacterMovementEnum  MovementState = (MyCharacterMovementEnum)stream.ReadUInt16();
                MyCharacterMovementFlags MovementFlag  = (MyCharacterMovementFlags)stream.ReadUInt16();

                bool  Jetpack          = stream.ReadBool();
                bool  Dampeners        = stream.ReadBool();
                bool  Lights           = stream.ReadBool(); // TODO: Remove
                bool  Ironsight        = stream.ReadBool();
                bool  Broadcast        = stream.ReadBool(); // TODO: Remove
                bool  TargetFromCamera = stream.ReadBool();
                float headXAngle       = stream.ReadFloat();
                float headYAngle       = stream.ReadFloat();

                if (m_character == null)
                {
                    return;
                }

                if (m_character.IsUsing != null)
                {
                    return;
                }

                var jetpack = m_character.JetpackComp;
                if (jetpack != null)
                {
                    if (Jetpack != jetpack.TurnedOn)
                    {
                        jetpack.TurnOnJetpack(Jetpack, true);
                    }
                    if (Dampeners != jetpack.DampenersTurnedOn)
                    {
                        jetpack.EnableDampeners(Dampeners, false);
                    }
                }

                if (Lights != m_character.LightEnabled)
                {
                    m_character.EnableLights(Lights);
                }

                if (m_character.RadioBroadcaster != null && Broadcast != m_character.RadioBroadcaster.Enabled)
                {
                    m_character.EnableBroadcasting(Broadcast);
                }

                m_character.TargetFromCamera = TargetFromCamera;

                // Set client movement state directly and don't perform other operations
                // that may have side-effects to let server side Character.UpdateAfterSimulation()
                // perform exactly same operations as on client
                m_character.MovementFlags = MovementFlag;
                if (m_character.IsDead == false)
                {
                    m_character.SetCurrentMovementState(MovementState);
                }
                m_character.HeadLocalXAngle = headXAngle;
                m_character.HeadLocalYAngle = headYAngle;
                if (m_commandsApplied == null)
                {
                    m_commandsApplied = new Dictionary <ulong, bool>();
                }

                if (Vector3.IsZero(move, 0.01f) == false || Vector2.IsZero(ref rotate, 0.01f) == false || Math.Abs(roll - 0.0) > 0.01f)
                {
                    m_commandsApplied[clientId] = true;
                }

                m_character.CacheMove(ref move, ref rotate, ref roll);
            }
        }