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);
        }
Beispiel #2
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));
            }
        }
        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);
            }
        }
Beispiel #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);
        }
        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);
        }
Beispiel #6
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);
        }
        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();
            }
        }
        public Scene(int index, int sequence)
        {
            NetAssert.True(index == (index & 255));
            NetAssert.True(sequence == (sequence & 255));

            this.Index    = index & 255;
            this.Sequence = sequence & 255;
        }
Beispiel #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));
        }
Beispiel #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");
        }
Beispiel #11
0
        void IState.SetTransforms(NetworkTransform transform, UE.Transform simulate, UE.Transform render)
        {
            transform.SetTransformsInternal(simulate, render);

            if (Entity.AttachIsRunning && simulate)
            {
                NetAssert.Same(transform, this.Storage.Values[transform.PropertyIndex].Transform);

                this.Storage.Values[transform.PropertyIndex].Vector3        = simulate.position;
                this.Storage.Values[transform.PropertyIndex + 1].Quaternion = simulate.rotation;
            }
        }
Beispiel #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 });
        }
Beispiel #13
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 });
        }
Beispiel #14
0
        public void Release(Packet stream)
        {
            NetAssert.False(stream.isPooled);

            lock (pool)
            {
                stream.Size     = 0;
                stream.Position = 0;
                stream.isPooled = true;

                pool.Push(stream);
            }
        }
Beispiel #15
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;
        }
Beispiel #16
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);
        }
Beispiel #17
0
        public void PacketReceived(Packet Packet)
        {
            try
            {
                using (Packet packet = Core.AllocatePacket())
                {
                    packet.Set(Packet); //This copies the values into the newly acquired packet
                    //Read signature & frame
                    packet.Type  = packet.ReadByte();
                    packet.Frame = packet.ReadIntVB();

                    if (packet.Frame > remoteFrameActual)
                    {
                        remoteFrameAdjust = true;
                        remoteFrameActual = packet.Frame;
                    }

                    //OLD method
                    //bitsSecondInAcc += packet.ActualSize;
                    bitsSecondInAcc += packet.Position;
                    packetsReceived += 1;

                    for (int i = 0; i < channels.Length; ++i)
                    {
                        channels[i].Read(packet);
                    }
                    //for (int i = 0; i < channels.Length; ++i)
                    //{
                    //    channels[i].ReadDone();
                    //}

                    packetStatsIn.Enqueue(packet.Stats);

                    NetAssert.False(Packet.Overflowing);

                    //SocketLog.Info("Received packet of length {0}", packet.ActualSize);
                }
            }
            catch (Exception exn)
            {
                NetLog.Exception(exn);
                NetLog.Error("exception thrown while unpacking data from {0}, disconnecting", sockConn.RemoteEndPoint);
                Disconnect();
            }
        }
Beispiel #18
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);
            }
        }
Beispiel #19
0
        public void Set(int bit)
        {
            switch (bit / 64)
            {
            case 0: this.Bits0 |= (1UL << (bit % 64)); break;

            case 1: this.Bits1 |= (1UL << (bit % 64)); break;

            case 2: this.Bits2 |= (1UL << (bit % 64)); break;

            case 3: this.Bits3 |= (1UL << (bit % 64)); break;

            case 4: this.Bits4 |= (1UL << (bit % 64)); break;

            case 5: this.Bits5 |= (1UL << (bit % 64)); break;

            case 6: this.Bits6 |= (1UL << (bit % 64)); break;

            case 7: this.Bits7 |= (1UL << (bit % 64)); break;

            case 8: this.Bits8 |= (1UL << (bit % 64)); break;

            case 9: this.Bits9 |= (1UL << (bit % 64)); break;

            case 10: this.Bits10 |= (1UL << (bit % 64)); break;

            case 11: this.Bits11 |= (1UL << (bit % 64)); break;

            case 12: this.Bits12 |= (1UL << (bit % 64)); break;

            case 13: this.Bits13 |= (1UL << (bit % 64)); break;

            case 14: this.Bits14 |= (1UL << (bit % 64)); break;

            case 15: this.Bits15 |= (1UL << (bit % 64)); break;

            default:
                throw new IndexOutOfRangeException();
            }

            NetAssert.False(IsZero);
        }
Beispiel #20
0
        public bool Send(out Packet sentPacket)
        {
            bool sent;

            try
            {
                Packet packet = Core.AllocatePacket();
                packet.Frame  = Core.Frame;
                packet.Number = ++packetCounter;
                packet.Type   = (byte)NetworkMsg.Data;

                packet.UserToken = packet;
                //Write signature & frame
                packet.WriteByte(packet.Type);
                packet.WriteIntVB(packet.Frame);

                for (int i = 0; i < channels.Length; ++i)
                {
                    channels[i].Pack(packet);
                }

                NetAssert.False(packet.Overflowing);

                sockConn.Send(packet);

                sent       = true;
                sentPacket = packet;
                sentPacket.Set(packet);
                //SocketLog.Info("Sending packet of length {0}", packet.ActualSize);

                bitsSecondOutAcc += packet.Position;
                packetStatsOut.Enqueue(packet.Stats);
            }
            catch (Exception exn)
            {
                NetLog.Exception(exn);
                throw;
            }

            return(sent);
        }
Beispiel #21
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));
            }
        }
Beispiel #22
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));
                }
            }
        }
Beispiel #23
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));
                }
            }
        }
        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();
            }
        }
Beispiel #25
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];
        }
Beispiel #26
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();
        }
Beispiel #27
0
 public void SetExtrapolationClamper(System.Func <AscensionEntity, Vector3, Vector3> clamper)
 {
     NetAssert.NotNull(clamper);
     Clamper = clamper;
 }
Beispiel #28
0
 public void Add()
 {
     NetAssert.True(OffsetObjects == Objects.Count);
     Objects.Add(this);
 }
Beispiel #29
0
 public UniqueId(string guid)
 {
     NetAssert.NotNull(guid);
     this      = default(UniqueId);
     this.guid = new Guid(guid);
 }
        private int PackUpdate(Packet packet, EntityProxy proxy)
        {
            int pos       = packet.Position;
            int packCount = 0;

            EntityProxyEnvelope env = proxy.CreateEnvelope();

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

            if (packet.WriteBool(proxy.Entity.IsController(connection)))
            {
                packet.WriteToken(proxy.ControlTokenGained);
                proxy.ControlTokenLost = null;
            }
            else
            {
                packet.WriteToken(proxy.ControlTokenLost);
                proxy.ControlTokenGained = null;
            }

            if (packet.WriteBool(proxy.Flags & ProxyFlags.DESTROY_REQUESTED))
            {
                packet.WriteToken(proxy.Entity.DetachToken);
            }
            else
            {
                // data for first packet
                if (packet.WriteBool(proxy.Flags & ProxyFlags.CREATE_REQUESTED))
                {
                    packet.WriteToken(proxy.Entity.AttachToken);

                    packet.WritePrefabId(proxy.Entity.PrefabId);
                    packet.WriteTypeId(proxy.Entity.Serializer.TypeId);

                    packet.WriteVector3(proxy.Entity.UnityObject.transform.position);
                    packet.WriteQuaternion(proxy.Entity.UnityObject.transform.rotation);

                    if (packet.WriteBool(proxy.Entity.IsSceneObject))
                    {
                        NetAssert.False(proxy.Entity.SceneId.IsNone,
                                        string.Format("'{0}' is marked a scene object but has no scene id ",
                                                      proxy.Entity.UnityObject.gameObject));
                        packet.WriteUniqueId(proxy.Entity.SceneId);
                    }
                }

                packCount = proxy.Entity.Serializer.Pack(connection, packet, env);
            }

            if (packet.Overflowing)
            {
                packet.Position = pos;
                return(-1);
            }
            if (packCount == -1)
            {
                packet.Position = pos;
                return(0);
            }
            else
            {
                var isForce   = proxy.Flags & ProxyFlags.FORCE_SYNC;
                var isCreate  = proxy.Flags & ProxyFlags.CREATE_REQUESTED;
                var isDestroy = proxy.Flags & ProxyFlags.DESTROY_REQUESTED;

                // if we didn't pack anything and we are not creating or destroying this, just goto next
                if ((packCount == 0) && !isCreate && !isDestroy && !isForce)
                {
                    packet.Position = pos;
                    return(0);
                }

                // set in progress flags
                if (isDestroy)
                {
                    env.Flags = (proxy.Flags |= ProxyFlags.DESTROY_PENDING);
                }

                // clear force sync flag
                proxy.Flags &= ~ProxyFlags.FORCE_SYNC;

                // clear skipped count
                proxy.Skipped = 0;

                // set packet number
                env.PacketNumber = packet.Number;

                // put on packets list
                packet.EntityUpdates.Enqueue(env);

                // put on proxies pending queue
                // NetLog.Info("adding envelope to {0}, count: {1}", proxy, proxy.Envelopes.Count + 1);
                proxy.Envelopes.Enqueue(env);

                // keep going!
                return(1);
            }
        }