Пример #1
0
        public void ReleaseControlInternal(IMessageRider token)
        {
            NetAssert.True(Flags & EntityFlags.HAS_CONTROL);

            Flags &= ~EntityFlags.HAS_CONTROL;
            CommandQueue.Clear();
            CommandSequence     = 0;
            CommandLastExecuted = null;

            ControlLostToken   = token;
            ControlGainedToken = null;

            // call to serializer
            Serializer.OnControlLost();

            // call to user behaviours
            foreach (IEntityBehaviour eb in Behaviours)
            {
                if (ReferenceEquals(eb.entity, this.UnityObject))
                {
                    eb.ControlLost();
                }
            }

            // call user event
            GlobalEventListenerBase.ControlOfEntityLostInvoke(UnityObject);

            // de-freeze
            Freeze(false);
        }
Пример #2
0
        public BasePacket Acquire()
        {
            BasePacket stream = null;

            lock (pool)
            {
                if (pool.Count > 0)
                {
                    stream = pool.Pop();
                }
            }

            if (stream == null)
            {
                stream      = new BasePacket(new byte[1500]);
                stream.pool = this;
            }

            NetAssert.True(stream.isPooled);

            stream.isPooled = false;
            stream.Position = 0;
            stream.Size     = (1500) << 3;

            return(stream);
        }
Пример #3
0
        public static float InterpolateFloat(ListExtended <NetworkStorage> frames, int offset, int frame, bool angle)
        {
            var f0 = frames.First;
            var p0 = f0.Values[offset].Float1;

            if ((frames.Count == 1) || (f0.Frame >= frame))
            {
                return(p0);
            }
            else
            {
                var f1 = frames.Next(f0);
                var p1 = f1.Values[offset].Float1;

                NetAssert.True(f1.Frame > f0.Frame);
                NetAssert.True(f1.Frame > frame);

                int f0Frame = f0.Frame;
                if (f0Frame < (f1.Frame - Core.RemoteSendRate * 2))
                {
                    f0Frame = f1.Frame - Core.RemoteSendRate * 2;
                }

                float t = f1.Frame - f0Frame;
                float d = frame - f0Frame;

                return(angle ? Mathf.LerpAngle(p0, p1, d / t) : Mathf.Lerp(p0, p1, d / t));
            }
        }
Пример #4
0
        public Packet Acquire()
        {
            Packet stream = null;

            lock (pool)
            {
                if (pool.Count > 0)
                {
                    stream = pool.Pop();
                }
            }

            if (stream == null)
            {
                stream      = new Packet(new byte[RuntimeSettings.Instance.packetSize - 100]);
                stream.pool = this;
            }

            NetAssert.True(stream.isPooled);

            stream.isPooled = false;
            stream.Position = 0;
            stream.Size     = (RuntimeSettings.Instance.packetSize - 100) << 3;

            return(stream);
        }
Пример #5
0
        public override void Lost(Packet packet)
        {
            while (packet.EntityUpdates.Count > 0)
            {
                var env     = packet.EntityUpdates.Dequeue();
                var pending = env.Proxy.Envelopes.Dequeue();

                //NetLog.Error("LOST ENV {0}, IN TRANSIT: {1}", env.Proxy, env.Proxy.Envelopes.Count);
                //NetAssert.Same(env.Proxy, _outgoingProxiesByNetId[env.Proxy.NetId], string.Format("PROXY MISS-MATCH {0} <> {1}", env.Proxy, _outgoingProxiesByNetId[env.Proxy.NetId]));
                //NetAssert.Same(env, pending, string.Format("ENVELOPE MISS-MATCH {0} <> {1}", envNumber, pendingNumber));

                // copy back all priorities
                ApplyPropertyPriorities(env);

                // push skipped count up one
                env.Proxy.Skipped += 1;

                // if this was a forced sync, set flag on proxy again
                if (env.Flags & ProxyFlags.FORCE_SYNC)
                {
                    env.Proxy.Flags |= ProxyFlags.FORCE_SYNC;
                }

                // if we failed to destroy this clear destroying flag
                if (env.Flags & ProxyFlags.DESTROY_PENDING)
                {
                    NetAssert.True(env.Proxy.Flags & ProxyFlags.DESTROY_PENDING);
                    env.Proxy.Flags &= ~ProxyFlags.DESTROY_PENDING;
                }

                env.Dispose();
            }
        }
Пример #6
0
        public bool QueueInput(Command cmd)
        {
            if (canQueueCommands)
            {
                NetAssert.True(HasControl);

                if (CommandQueue.Count < Core.Config.commandQueueSize)
                {
                    cmd.ServerFrame = Core.ServerFrame;
                    cmd.Sequence    = CommandSequence = NetMath.SeqNext(CommandSequence, Command.SEQ_MASK);
                }
                else
                {
                    NetLog.Error("Input queue for {0} is full", this);
                    return(false);
                }

                CommandQueue.AddLast(cmd);
                return(true);
            }
            else
            {
                NetLog.Error("You can only queue commands to the host in the 'SimulateController' callback");
                return(false);
            }
        }
Пример #7
0
        int ExecuteCommandsFromRemote()
        {
            int commandsExecuted = 0;

            NetAssert.True(IsOwner);

            do
            {
                var it = CommandQueue.GetIterator();

                while (it.Next())
                {
                    if (it.val.Flags & CommandFlags.HAS_EXECUTED)
                    {
                        continue;
                    }

                    try
                    {
                        ExecuteCommand(it.val, false);
                        commandsExecuted += 1;
                        break;
                    }
                    finally
                    {
                        it.val.Flags |= CommandFlags.SEND_STATE;
                    }
                }
            } while (UnexecutedCommandCount() > Core.Config.commandDejitterDelay);

            return(commandsExecuted);
        }
Пример #8
0
        public Scene(int index, int sequence)
        {
            NetAssert.True(index == (index & 255));
            NetAssert.True(sequence == (sequence & 255));

            this.Index    = index & 255;
            this.Sequence = sequence & 255;
        }
Пример #9
0
        public static NetworkId ReadNetworkId(this BasePacket packet)
        {
            uint connection = packet.ReadUIntVB();
            uint entity     = packet.ReadUIntVB();

            NetAssert.True(connection != uint.MaxValue);
            return(new NetworkId(connection, entity));
        }
Пример #10
0
        public void InitRoot()
        {
            RootObjects = new List <NetworkObj>(Meta.CountObjects);

            Path = null;
            Meta.InitObject(this, this, new NetworkObj_Meta.Offsets());

            NetAssert.True(RootObjects.Count == Meta.CountObjects, "RootObjects.Count == Meta.CountObjects");
        }
Пример #11
0
        public void InvokeOnce(Command command, CommandCallback callback, int delay)
        {
            NetAssert.True(delay > 0);

            if (!canQueueCallbacks)
            {
                NetLog.Error("Can only queue callbacks when commands with 'IsFirstExecution' set to true are executing");
                return;
            }

            //CommandCallbacks.Add(new CommandCallbackItem { Command = command, Callback = callback, Start = -1, End = command.Number + delay, Mode = CommandCallbackModes.InvokeOnce });
        }
Пример #12
0
        public void InvokeRepeating(Command command, CommandCallback callback, int period)
        {
            NetAssert.True(period > 0);

            if (!canQueueCallbacks)
            {
                NetLog.Error("Can only queue callbacks when commands with 'IsFirstExecution' set to true are executing");
                return;
            }

            //CommandCallbacks.Add(new CommandCallbackItem { Command = command, Callback = callback, Start = command.Number + 1, End = command.Number + period, Mode = CommandCallbackModes.InvokeRepeating });
        }
Пример #13
0
        public static void Assigned(long connectionId)
        {
            //Converts the long connection id to a unsigned integer with data loss, as well as with overflow protection
            //This is useful if long.MaxValue is passed to the previous System.Convert.ToInt32
            uint convertedConnection = unchecked ((uint)connectionId);

            NetAssert.True(Core.IsClient, "Core.IsClient");
            NetAssert.True(convertedConnection > 0U, "connectionId > 0U");
            NetAssert.True(convertedConnection != uint.MaxValue, "connectionId != uint.MaxValue");

            // verify connection id
            NetAssert.True(ConnectionId == uint.MaxValue, "ConnectionId == uint.MaxValue");

            NetLog.Debug("Assigned id {0} from server", connectionId);
            ConnectionId = convertedConnection;
        }
Пример #14
0
        int IEntitySerializer.Pack(Connection connection, Packet stream, EntityProxyEnvelope env)
        {
            int propertyCount = 0;

            BitSet filter = ((IEntitySerializer)this).GetFilter(connection, env.Proxy);

            Priority[] tempPriority  = Meta.PropertiesTempPriority;
            Priority[] proxyPriority = env.Proxy.PropertyPriority;

            for (int i = 0; i < proxyPriority.Length; ++i)
            {
                NetAssert.True(proxyPriority[i].PropertyIndex == i);

                // if this property is set both in our filter and the proxy mask we can consider it for sending
                if (filter.IsSet(i) && env.Proxy.IsSet(i))
                {
                    // increment priority for this property
                    proxyPriority[i].PropertyPriority += Meta.Properties[i].Property.PropertyPriority;
                    proxyPriority[i].PropertyPriority  = UE.Mathf.Clamp(proxyPriority[i].PropertyPriority, 0, Core.Config.maxPropertyPriority);

                    // copy to our temp array
                    tempPriority[propertyCount] = proxyPriority[i];

                    // increment temp count
                    propertyCount += 1;
                }
            }

            // sort temp array based on priority
            Array.Sort <Priority>(tempPriority, 0, propertyCount, Priority.Comparer.Instance);

            // write into stream
            PackProperties(connection, stream, env, tempPriority, propertyCount);

            for (int i = 0; i < env.Written.Count; ++i)
            {
                Priority p = env.Written[i];

                // clear priority for written property
                env.Proxy.PropertyPriority[p.PropertyIndex].PropertyPriority = 0;

                // clear mask for it
                env.Proxy.Clear(p.PropertyIndex);
            }

            return(env.Written.Count);
        }
Пример #15
0
        public int this[NetworkProperty property]
        {
            get
            {
#if DEBUG
                NetAssert.NotNull(property);

                NetAssert.True(OffsetObjects >= 0);
                NetAssert.True(OffsetObjects < Root.Meta.CountObjects);

                NetAssert.Same(Root.Objects[OffsetObjects], this);
                NetAssert.Same(Root.Objects[OffsetObjects].Meta, property.PropertyMeta);
                NetAssert.Same(Root.Meta.Properties[Root.Objects[OffsetObjects].OffsetProperties + property.OffsetProperties].Property, property);
#endif

                return(this.OffsetStorage + property.OffsetStorage);
            }
        }
Пример #16
0
        public static Quaternion InterpolateQuaternion(ListExtended <NetworkStorage> frames, int offset, int frame)
        {
            var f0 = frames.First;
            var p0 = f0.Values[offset].Quaternion;

            if (p0 == default(Quaternion))
            {
                p0 = Quaternion.identity;
            }

            if ((frames.Count == 1) || (f0.Frame >= frame))
            {
                return(p0);
            }
            else
            {
                var f1 = frames.Next(f0);
                var p1 = f1.Values[offset].Quaternion;

                if (p1 == default(Quaternion))
                {
                    p1 = Quaternion.identity;
                }

                NetAssert.True(f1.Frame > f0.Frame);
                NetAssert.True(f1.Frame > frame);

                int f0Frame = f0.Frame;
                if (f0Frame < (f1.Frame - Core.RemoteSendRate * 2))
                {
                    f0Frame = f1.Frame - Core.RemoteSendRate * 2;
                }

                float t = f1.Frame - f0Frame;
                float d = frame - f0Frame;

                return(Quaternion.Lerp(p0, p1, d / t));
            }
        }
Пример #17
0
        public static Vector3 InterpolateVector(ListExtended <NetworkStorage> frames, int offset, int frame, float snapLimit, ref bool snapped)
        {
            var f0 = frames.First;
            var p0 = f0.Values[offset].Vector3;

            if ((frames.Count == 1) || (f0.Frame >= frame))
            {
                return(p0);
            }
            else
            {
                var f1 = frames.Next(f0);
                var p1 = f1.Values[offset].Vector3;

                NetAssert.True(f1.Frame > f0.Frame);
                NetAssert.True(f1.Frame > frame);

                if ((p0 - p1).sqrMagnitude > (snapLimit * snapLimit))
                {
                    snapped = true;
                    return(p1);
                }
                else
                {
                    int f0Frame = f0.Frame;

                    if (f0Frame < (f1.Frame - Core.RemoteSendRate * 2))
                    {
                        f0Frame = f1.Frame - Core.RemoteSendRate * 2;
                    }

                    float t = f1.Frame - f0Frame;
                    float d = frame - f0Frame;

                    return(Vector3.Lerp(p0, p1, d / t));
                }
            }
        }
Пример #18
0
        void AddPropertyToArray(int offsetProperties, int offsetObjects, NetworkProperty property)
        {
            NetAssert.Null(Properties[offsetProperties].Property);

            if (offsetProperties > 0)
            {
                NetAssert.NotNull(Properties[offsetProperties - 1].Property);
            }

            Properties[offsetProperties].Property      = property;
            Properties[offsetProperties].OffsetObjects = offsetObjects;

            for (int i = 0; i < 32; ++i)
            {
                int f = 1 << i;

                // this can't be set
                if (Filters[i] != null)
                {
                    NetAssert.False(Filters[i].IsSet(offsetProperties));
                }

                // if property is included in this filter, flag it
                if ((property.PropertyFilters & f) == f)
                {
                    if (Filters[i] == null)
                    {
                        Filters[i] = new BitSet();
                    }

                    Filters[i].Set(offsetProperties);

                    // now it must be set
                    NetAssert.True(Filters[i].IsSet(offsetProperties));
                }
            }
        }
Пример #19
0
        public UniqueId(byte[] bytes)
        {
            NetAssert.NotNull(bytes);
            NetAssert.True(bytes.Length == 16);

            this = default(UniqueId);

            this.byte0  = bytes[0];
            this.byte1  = bytes[1];
            this.byte2  = bytes[2];
            this.byte3  = bytes[3];
            this.byte4  = bytes[4];
            this.byte5  = bytes[5];
            this.byte6  = bytes[6];
            this.byte7  = bytes[7];
            this.byte8  = bytes[8];
            this.byte9  = bytes[9];
            this.byte10 = bytes[10];
            this.byte11 = bytes[11];
            this.byte12 = bytes[12];
            this.byte13 = bytes[13];
            this.byte14 = bytes[14];
            this.byte15 = bytes[15];
        }
Пример #20
0
        public override void Delivered(Packet packet)
        {
            while (packet.EntityUpdates.Count > 0)
            {
                var env     = packet.EntityUpdates.Dequeue();
                var pending = env.Proxy.Envelopes.Dequeue();

                //NetLog.Info("DELIVERED ENV {0}, IN TRANSIT: {1}", env.Proxy, env.Proxy.Envelopes.Count);
                //NetAssert.Same(env.Proxy, _outgoingProxiesByNetId[env.Proxy.NetId], string.Format("PROXY MISS-MATCH {0} <> {1}", env.Proxy, _outgoingProxiesByNetId[env.Proxy.NetId]));
                //NetAssert.Same(env, pending, string.Format("ENVELOPE MISS-MATCH {0} <> {1}", envNumber, pendingNumber));

                if (env.Flags & ProxyFlags.DESTROY_PENDING)
                {
                    NetAssert.True(env.Proxy.Flags & ProxyFlags.DESTROY_PENDING);

                    // delete proxy
                    DestroyOutgoingProxy(env.Proxy);
                }
                else if (env.Flags & ProxyFlags.CREATE_REQUESTED)
                {
                    // if this token has been sent, clear it
                    if (ReferenceEquals(env.ControlTokenGained, env.Proxy.ControlTokenGained))
                    {
                        env.Proxy.ControlTokenGained = null;
                    }

                    // clear out request / progress for create
                    env.Proxy.Flags &= ~ProxyFlags.CREATE_REQUESTED;

                    // set create done
                    env.Proxy.Flags |= ProxyFlags.CREATE_DONE;
                }

                env.Dispose();
            }
        }
Пример #21
0
 public void Add()
 {
     NetAssert.True(OffsetObjects == Objects.Count);
     Objects.Add(this);
 }
Пример #22
0
 public NetworkArray_Quaternion(int length, int stride)
     : base(length, stride)
 {
     NetAssert.True((stride == 1) || (stride == 2));
 }
Пример #23
0
 public NetworkArray_Vector(int length, int stride)
     : base(length, stride)
 {
     NetAssert.True((stride == 1) || (stride == 2));
 }
Пример #24
0
 public NetworkArray_PrefabId(int length, int stride)
     : base(length, stride)
 {
     NetAssert.True(stride == 1);
 }
Пример #25
0
        void PackProperties(Connection connection, Packet packet, EntityProxyEnvelope env, Priority[] priority, int count)
        {
            int propertyCountPtr = packet.Position;

            packet.WriteByte(0, Meta.PacketMaxPropertiesBits);

            // how many bits can we write at the most
            int bits = System.Math.Min(Meta.PacketMaxBits, packet.Size - packet.Position);

            for (int i = 0; i < count; ++i)
            {
                // this means we can even fit another property id
                if (bits <= Meta.PropertyIdBits)
                {
                    break;
                }

                // we have written enough properties
                if (env.Written.Count == Meta.PacketMaxProperties)
                {
                    break;
                }

                Priority            p  = priority[i];
                NetworkPropertyInfo pi = Meta.Properties[p.PropertyIndex];

                if (p.PropertyPriority == 0)
                {
                    break;
                }

                int b   = Meta.PropertyIdBits + pi.Property.BitCount(Objects[pi.OffsetObjects]);
                int ptr = packet.Position;

                if (bits >= b)
                {
                    // write property id
                    packet.WriteInt(p.PropertyIndex, Meta.PropertyIdBits);

                    if (pi.Property.Write(connection, Objects[pi.OffsetObjects], Storage, packet))
                    {
#if DEBUG
                        int totalBits = packet.Position - ptr;
                        if (totalBits != b)
                        {
                            //NetLog.Warn("Property of type {0} did not write the correct amount of bits, written: {1}, expected: {2}", pi.Property, totalBits, b);
                        }
#endif

                        if (packet.Overflowing)
                        {
                            packet.Position = ptr;
                            break;
                        }

                        // use up bits
                        bits -= b;

                        // add to written list
                        env.Written.Add(p);
                    }
                    else
                    {
                        // reset position
                        packet.Position = ptr;
                    }
                }
            }

            // gotta be less then 256
            NetAssert.True(env.Written.Count <= Meta.PacketMaxProperties);

            // write the amount of properties
            Packet.WriteByteAt(packet.ByteBuffer, propertyCountPtr, Meta.PacketMaxPropertiesBits, (byte)env.Written.Count);
        }
Пример #26
0
        public void Attach()
        {
            NetAssert.NotNull(UnityObject);
            NetAssert.False(IsAttached);
            NetAssert.True((NetworkId.Packed == 0UL) || (Source != null));

            try
            {
                AttachIsRunning = true;

                // mark as don't destroy on load
                GameObject.DontDestroyOnLoad(UnityObject.gameObject);

                // assign network id
                if (Source == null)
                {
                    NetworkId = NetworkIdAllocator.Allocate();
                }

                // add to entities list
                Core.entitiesThawed.AddLast(this);

                // mark as attached
                Flags |= EntityFlags.ATTACHED;

                // call out to behaviours
                foreach (IEntityBehaviour eb in Behaviours)
                {
                    try
                    {
                        if (eb.Invoke && ReferenceEquals(eb.entity, this.UnityObject))
                        {
                            eb.Attached();
                        }
                    }
                    catch (Exception exn)
                    {
                        NetLog.Error("User code threw exception inside Attached callback");
                        NetLog.Exception(exn);
                    }
                }

                // call out to user
                try
                {
                    GlobalEventListenerBase.EntityAttachedInvoke(this.UnityObject);
                }
                catch (Exception exn)
                {
                    NetLog.Error("User code threw exception inside Attached callback");
                    NetLog.Exception(exn);
                }

                // log
                NetLog.Debug("Attached {0} (Token: {1})", this, AttachToken);
            }
            finally
            {
                AttachIsRunning = false;
            }
        }
Пример #27
0
        public void Detach()
        {
            NetAssert.NotNull(UnityObject);
            NetAssert.True(IsAttached);
            NetAssert.True(NetworkId.Packed != 0UL);

            if (AutoRemoveChildEntities)
            {
                foreach (AscensionEntity child in UnityObject.GetComponentsInChildren(typeof(AscensionEntity), true))
                {
                    if (child.IsAttached && (ReferenceEquals(child.entity, this) == false))
                    {
                        child.transform.parent = null;
                    }
                }
            }

            if (Controller)
            {
                RevokeControl(null);
            }

            // destroy on all connections
            var it = Core.connections.GetIterator();

            while (it.Next())
            {
                it.val.entityChannel.DestroyOnRemote(this);
            }

            // call out to behaviours
            foreach (IEntityBehaviour eb in Behaviours)
            {
                try
                {
                    if (eb.Invoke && ReferenceEquals(eb.entity, this.UnityObject))
                    {
                        eb.Detached();
                        eb.entity = null;
                    }
                }
                catch (Exception exn)
                {
                    NetLog.Error("User code threw exception inside Detach callback");
                    NetLog.Exception(exn);
                }
            }

            // call out to user
            try
            {
                GlobalEventListenerBase.EntityDetachedInvoke(this.UnityObject);
            }
            catch (Exception exn)
            {
                NetLog.Error("User code threw exception inside Detach callback");
                NetLog.Exception(exn);
            }

            // clear out attached flag
            Flags &= ~EntityFlags.ATTACHED;

            // remove from entities list
            if (Core.entitiesFrozen.Contains(this))
            {
                Core.entitiesFrozen.Remove(this);
            }

            if (Core.entitiesThawed.Contains(this))
            {
                Core.entitiesThawed.Remove(this);
            }

            // clear from unity object
            UnityObject.entity = null;

            // log
            NetLog.Debug("Detached {0}", this);
        }
Пример #28
0
        public void Simulate()
        {
            Serializer.OnSimulateBefore();

            Iterator <Command> it;

            if (IsOwner)
            {
                foreach (IEntityBehaviour eb in Behaviours)
                {
                    try
                    {
                        if (eb != null && ((MonoBehaviour)(object)eb) && eb.Invoke && ReferenceEquals(eb.entity, this.UnityObject))
                        {
                            eb.SimulateOwner();
                        }
                    }
                    catch (Exception exn)
                    {
                        Debug.LogException(exn);
                    }
                }
            }

            else
            {
                //FIXED: Entities getting frozen on clients after 10 seconds.
                //if (AscensionNetwork.IsClient)
                //{
                //    var diff = AscensionNetwork.ServerFrame - (Serializer as NetworkState).Frames.Last.Frame;
                //    if (diff > 600)
                //    {
                //        Freeze(true);
                //    }
                //}
            }

            if (HasControl)
            {
                NetAssert.Null(Controller);

                // execute all old commands (in order)
                it = CommandQueue.GetIterator();

                while (it.Next())
                {
                    NetAssert.True(it.val.Flags & CommandFlags.HAS_EXECUTED);

                    var resetState = ReferenceEquals(it.val, CommandQueue.First);
                    if (resetState)
                    {
                        it.val.SmoothCorrection();
                    }

                    // exec old command
                    ExecuteCommand(it.val, resetState);
                }

                try
                {
                    canQueueCommands = true;

                    foreach (IEntityBehaviour eb in Behaviours)
                    {
                        if (eb.Invoke && ReferenceEquals(eb.entity, this.UnityObject))
                        {
                            eb.SimulateController();
                        }
                    }
                }
                finally
                {
                    canQueueCommands = false;
                }

                // execute all new commands (in order)
                it = CommandQueue.GetIterator();

                while (it.Next())
                {
                    if (it.val.Flags & CommandFlags.HAS_EXECUTED)
                    {
                        continue;
                    }

                    ExecuteCommand(it.val, false);
                }

                // if this is a local entity we are controlling
                // we should dispose all commands (there is no need to store them)
                if (IsOwner)
                {
                    while (CommandQueue.Count > 0)
                    {
                        CommandQueue.RemoveFirst();
                    }

                    //RemoveOldCommandCallbacks(CommandSequence);
                }
                else
                {
                    //if (CommandQueue.count > 0) {
                    //  RemoveOldCommandCallbacks(CommandQueue.First.Sequence);
                    //}
                }
            }
            else
            {
                if (Controller != null)
                {
                    //if (CommandQueue.count > 0) {
                    //  RemoveOldCommandCallbacks(CommandQueue.First.Sequence);
                    //}

                    if (ExecuteCommandsFromRemote() == 0)
                    {
                        Command cmd = CommandQueue.LastOrDefault;

                        for (int i = 0; i < Behaviours.Length; ++i)
                        {
                            if (ReferenceEquals(Behaviours[i].entity, this.UnityObject))
                            {
                                Behaviours[i].MissingCommand(cmd);
                            }
                        }
                    }
                }
            }

            Serializer.OnSimulateAfter();
        }
Пример #29
0
        private void PackResult(Packet packet)
        {
            foreach (EntityProxy proxy in OutgoingProxiesByNetworkId.Values)
            {
                Entity entity = proxy.Entity;

                // four conditions have to hold
                // 1) Entity must exist locally (not null)
                // 2) The connection must be the controller
                // 3) The entity must exist remotely
                // 4) The entity has to have unsent states
                if ((entity != null) && ReferenceEquals(entity.Controller, connection) &&
                    connection.entityChannel.ExistsOnRemote(entity) && EntityHasUnsentState(entity))
                {
                    NetAssert.True(entity.IsOwner);

                    int proxyPos      = packet.Position;
                    int cmdWriteCount = 0;

                    packet.WriteBool(true);
                    packet.WriteNetworkId(proxy.NetworkId);

                    var it = entity.CommandQueue.GetIterator();

                    while (it.Next())
                    {
                        if (it.val.Flags & CommandFlags.HAS_EXECUTED)
                        {
                            if (it.val.Flags & CommandFlags.SEND_STATE)
                            {
                                int cmdPos = packet.Position;

                                packet.WriteBool(true);
                                packet.WriteTypeId(it.val.ResultObject.Meta.TypeId);
                                packet.WriteUShort(it.val.Sequence, Command.SEQ_BITS);
                                packet.WriteToken(it.val.ResultObject.Token);

                                it.val.PackResult(connection, packet);

                                if (packet.Overflowing)
                                {
                                    packet.Position = cmdPos;
                                    break;
                                }
                                else
                                {
                                    cmdWriteCount += 1;

                                    it.val.Flags &= ~CommandFlags.SEND_STATE;
                                    it.val.Flags |= CommandFlags.SEND_STATE_PERFORMED;
                                }
                            }
                        }
                    }

                    // we wrote too much or nothing at all
                    if (packet.Overflowing || (cmdWriteCount == 0))
                    {
                        packet.Position = proxyPos;
                        break;
                    }
                    else
                    {
                        // stop marker for states
                        packet.WriteStopMarker();
                    }

                    // dispose commands we dont need anymore
                    while ((entity.CommandQueue.Count > 1) &&
                           (entity.CommandQueue.First.Flags & CommandFlags.SEND_STATE_PERFORMED))
                    {
                        entity.CommandQueue.RemoveFirst().Free();
                    }
                }
            }

            // stop marker for proxies
            packet.WriteStopMarker();
        }
Пример #30
0
        void IEntitySerializer.Read(Connection connection, Packet packet, int frame)
        {
            int count   = packet.ReadByte(Meta.PacketMaxPropertiesBits);
            var storage = default(NetworkStorage);

            if (Entity.HasPredictedControl)
            {
                NetAssert.True(Frames.Count == 1);

                storage       = Frames.First;
                storage.Frame = Core.Frame;
            }
            else
            {
                if (Frames.First.Frame == -1)
                {
                    NetAssert.True(Frames.Count == 1);

                    storage       = Frames.First;
                    storage.Frame = frame;
                }
                else
                {
                    storage       = DuplicateStorage(Frames.Last);
                    storage.Frame = frame;
                    storage.ClearAll();

                    // tell the properties that need to know about this
                    for (int i = 0; i < Meta.OnFrameCloned.Count; ++i)
                    {
                        // grab property info
                        var pi = Meta.OnFrameCloned[i];

                        // invoke callback
                        pi.Property.OnFrameCloned(Objects[pi.OffsetObjects], storage);
                    }

                    Frames.AddLast(storage);
                }
            }

            //fixes bug #224
            //IState.SetTransforms to replace NetworkTransform.SetTransforms,
            //this new methods works around the issue of position snapping for
            //entities when their position updates are delayed.

            //NetworkTransform.ChangeTransform to replace the previous NetworkTransform.SetTransforms
            //for changing the transform target for interpolation after it's been set once.
            if (Entity.HasControl && !Entity.HasPredictedControl && !Entity.IsOwner)
            {
                for (int i = 0; i < Meta.Properties.Length; ++i)
                {
                    var pi = Meta.Properties[i];
                    if (pi.Property.ToController == false)
                    {
                        // calculate property index
                        int index = Objects[pi.OffsetObjects][pi.Property];

                        // copy value from latest frame
                        storage.Values[index] = Frames.First.Values[index];
                    }
                }
            }

            while (--count >= 0)
            {
                var propertyIndex = packet.ReadInt(Meta.PropertyIdBits);
                var propertyInfo  = Meta.Properties[propertyIndex];

                if (!Entity.IsOwner)
                {
                    EntityProxy proxy;

                    if (Entity.Source.entityChannel.TryFindProxy(Entity, out proxy))
                    {
                        proxy.PropertyPriority[propertyIndex].PropertyUpdated = frame;
                    }
                }

                // make sure this is the correct one
                NetAssert.True(propertyIndex == Objects[propertyInfo.OffsetObjects].OffsetProperties + propertyInfo.Property.OffsetProperties);

                // read data into frame
                propertyInfo.Property.Read(connection, Objects[propertyInfo.OffsetObjects], storage, packet);

                // set changed flag
                storage.Set(propertyIndex);
            }
        }