Esempio n. 1
0
        protected override void WritePacket(BitStream stream, PacketNotify note)
        {
            base.WritePacket(stream, note);

            var notify = note as GhostPacketNotify;

            if (notify == null)
            {
                throw new ArgumentException("Note must be GhostPacketNotify", "note");
            }

            if (ConnectionParameters.DebugObjectSizes)
            {
                stream.WriteInt(DebugCheckSum, 32);
            }

            notify.GhostList = null;

            if (!DoesGhostFrom())
            {
                return;
            }

            if (!stream.WriteFlag(Ghosting && ScopeObject != null))
            {
                return;
            }

            for (var i = GhostZeroUpdateIndex - 1; i >= 0; --i)
            {
                if ((GhostArray[i].Flags & (uint)GhostInfoFlags.InScope) == 0)
                {
                    DetachObject(GhostArray[i]);
                }
            }

            var maxIndex = 0U;

            for (var i = GhostZeroUpdateIndex - 1; i >= 0; --i)
            {
                var walk = GhostArray[i];
                if (walk.Index > maxIndex)
                {
                    maxIndex = walk.Index;
                }

                if ((walk.Flags & (uint)GhostInfoFlags.KillGhost) != 0U &&
                    (walk.Flags & (uint)GhostInfoFlags.NotYetGhosted) != 0U)
                {
                    FreeGhostInfo(walk);
                    continue;
                }

                if ((walk.Flags & (uint)(GhostInfoFlags.KillingGhost | GhostInfoFlags.Ghosting)) == 0U)
                {
                    walk.Priority = (walk.Flags & (uint)GhostInfoFlags.KillGhost) != 0U ? 10000.0f : walk.Obj.GetUpdatePriority(ScopeObject, walk.UpdateMask, (int)walk.UpdateSkipCount);
                }
                else
                {
                    walk.Priority = 0.0f;
                }
            }

            GhostRef updateList = null;

            var list = new List <GhostInfo>();

            for (var i = 0; i < GhostZeroUpdateIndex; ++i)
            {
                list.Add(GhostArray[i]);
            }

            list.Sort(new GhostInfoComparer());

            for (var i = 0; i < list.Count; ++i)
            {
                GhostArray[i]            = list[i];
                GhostArray[i].ArrayIndex = i;
            }

            var sendSize = 1;

            while ((maxIndex >>= 1) != 0)
            {
                ++sendSize;
            }

            if (sendSize < 3)
            {
                sendSize = 3;
            }

            stream.WriteInt((uint)sendSize - 3U, 3);

            for (var i = GhostZeroUpdateIndex - 1; i >= 0 && !stream.IsFull(); --i)
            {
                var walk = GhostArray[i];
                if ((walk.Flags & (uint)(GhostInfoFlags.KillingGhost | GhostInfoFlags.Ghosting)) != 0U)
                {
                    continue;
                }

                var updateStart = stream.GetBitPosition();
                var updateMask  = walk.UpdateMask;
                var retMask     = 0UL;

                stream.WriteFlag(true);
                stream.WriteInt(walk.Index, (byte)sendSize);

                if (!stream.WriteFlag((walk.Flags & (uint)GhostInfoFlags.KillGhost) != 0U))
                {
                    if (ConnectionParameters.DebugObjectSizes)
                    {
                        stream.AdvanceBitPosition(BitStreamPosBitSize);
                    }

                    var startPos = stream.GetBitPosition();

                    if ((walk.Flags & (uint)GhostInfoFlags.NotYetGhosted) != 0U)
                    {
                        var classId = walk.Obj.GetClassId(GetNetClassGroup());
                        stream.WriteClassId(classId, (uint)NetClassType.NetClassTypeObject, (uint)GetNetClassGroup());
                        NetObject.PIsInitialUpdate = true;
                    }

                    retMask = walk.Obj.PackUpdate(this, updateMask, stream);

                    if (NetObject.PIsInitialUpdate)
                    {
                        NetObject.PIsInitialUpdate = false;
                        walk.Obj.GetClassRep().AddInitialUpdate(stream.GetBitPosition() - startPos);
                    }
                    else
                    {
                        walk.Obj.GetClassRep().AddPartialUpdate(stream.GetBitPosition() - startPos);
                    }

                    if (ConnectionParameters.DebugObjectSizes)
                    {
                        stream.WriteIntAt(stream.GetBitPosition(), BitStreamPosBitSize, startPos - BitStreamPosBitSize);
                    }
                }

                if (stream.GetBitSpaceAvailable() < MinimumPaddingBits)
                {
                    stream.SetBitPosition(updateStart);
                    stream.ClearError();
                    break;
                }

                var upd = new GhostRef
                {
                    NextRef = updateList
                };

                updateList = upd;

                if (walk.LastUpdateChain != null)
                {
                    walk.LastUpdateChain.UpdateChain = upd;
                }

                walk.LastUpdateChain = upd;

                upd.Ghost          = walk;
                upd.GhostInfoFlags = 0U;
                upd.UpdateChain    = null;

                if ((walk.Flags & (uint)GhostInfoFlags.KillGhost) != 0U)
                {
                    walk.Flags     &= ~(uint)GhostInfoFlags.KillGhost;
                    walk.Flags     |= (uint)GhostInfoFlags.KillingGhost;
                    walk.UpdateMask = 0UL;
                    upd.Mask        = updateMask;
                    GhostPushToZero(walk);
                    upd.GhostInfoFlags = (uint)GhostInfoFlags.KillingGhost;
                }
                else
                {
                    if ((walk.Flags & (uint)GhostInfoFlags.NotYetGhosted) != 0U)
                    {
                        walk.Flags        &= ~(uint)GhostInfoFlags.NotYetGhosted;
                        walk.Flags        |= (uint)GhostInfoFlags.Ghosting;
                        upd.GhostInfoFlags = (uint)GhostInfoFlags.Ghosting;
                    }

                    walk.UpdateMask = retMask;
                    if (retMask == 0UL)
                    {
                        GhostPushToZero(walk);
                    }

                    upd.Mask             = updateMask & ~retMask;
                    walk.UpdateSkipCount = 0U;
                }
            }

            stream.WriteFlag(false);
            notify.GhostList = updateList;
        }
Esempio n. 2
0
        protected override void WritePacket(BitStream stream, PacketNotify note)
        {
            base.WritePacket(stream, note);

            var notify = note as EventPacketNotify;

            if (notify == null)
            {
                throw new ArgumentException("Note must be EventPacketNotify", "note");
            }

            if (ConnectionParameters.DebugObjectSizes)
            {
                stream.WriteInt(DebugCheckSum, 32);
            }

            EventNote packQueueHead = null, packQueueTail = null;

            var totalPacketSpaceFraction = 1.0f / stream.MaxWriteBitNum;

            while (_unorderedSendEventQueueHead != null)
            {
                if (stream.IsFull() || (stream.GetBitPosition() * totalPacketSpaceFraction) > _packetFillFraction)
                {
                    break;
                }

                var ev = _unorderedSendEventQueueHead;
                stream.WriteFlag(true);

                var start = stream.GetBitPosition();

                if (ConnectionParameters.DebugObjectSizes)
                {
                    stream.AdvanceBitPosition(BitStreamPosBitSize);
                }

                var classId = ev.Event.GetClassId(GetNetClassGroup());
                stream.WriteInt(classId, (byte)EventClassBitSize);

                ev.Event.Pack(this, stream);

                if (ConnectionParameters.DebugObjectSizes)
                {
                    stream.WriteIntAt(stream.GetBitPosition(), BitStreamPosBitSize, start);
                }

                if (stream.GetBitSpaceAvailable() < MinimumPaddingBits)
                {
                    stream.SetBitPosition(start - 1);
                    stream.ClearError();
                    break;
                }

                --NumEventsWaiting;

                _unorderedSendEventQueueHead = ev.NextEvent;
                ev.NextEvent = null;

                if (packQueueHead == null)
                {
                    packQueueHead = ev;
                }
                else
                {
                    packQueueTail.NextEvent = ev;
                }

                packQueueTail = ev;
            }

            stream.WriteFlag(false);
            var prevSeq = -2;

            while (_sendEventQueueHead != null)
            {
                if (stream.IsFull())
                {
                    break;
                }

                if (_sendEventQueueHead.SeqCount > _lastAckedEventSeq + 126)
                {
                    break;
                }

                var ev         = _sendEventQueueHead;
                var eventStart = stream.GetBitPosition();

                stream.WriteFlag(true);

                if (!stream.WriteFlag(ev.SeqCount == prevSeq + 1))
                {
                    stream.WriteInt((uint)ev.SeqCount, 7);
                }

                prevSeq = ev.SeqCount;

                if (ConnectionParameters.DebugObjectSizes)
                {
                    stream.AdvanceBitPosition(BitStreamPosBitSize);
                }

                var start = stream.GetBitPosition();

                var classId = ev.Event.GetClassId(GetNetClassGroup());

                stream.WriteInt(classId, (byte)EventClassBitSize);

                ev.Event.Pack(this, stream);

                ev.Event.GetClassRep().AddInitialUpdate(stream.GetBitPosition() - start);

                if (ConnectionParameters.DebugObjectSizes)
                {
                    stream.WriteIntAt(stream.GetBitPosition(), BitStreamPosBitSize, start - BitStreamPosBitSize);
                }

                if (stream.GetBitSpaceAvailable() < MinimumPaddingBits)
                {
                    stream.SetBitPosition(eventStart);
                    stream.ClearError();
                    break;
                }

                --NumEventsWaiting;

                _sendEventQueueHead = ev.NextEvent;
                ev.NextEvent        = null;

                if (packQueueHead == null)
                {
                    packQueueHead = ev;
                }
                else
                {
                    packQueueTail.NextEvent = ev;
                }

                packQueueTail = ev;
            }

            for (var ev = packQueueHead; ev != null; ev = ev.NextEvent)
            {
                ev.Event.NotifySent(this);
            }

            notify.EventList = packQueueHead;
            stream.WriteFlag(false);
        }