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; }
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); }