/// <summary> /// /// </summary> /// <param name="packet"></param> /// <param name="updatingSelf"></param> private void WriteObjectValueUpdate( Packet packet, bool updatingSelf ) { packet.WriterStream.Write( (byte)UpdateTypes.Values ); EntityId entityId = new EntityId( this.Serial ); entityId.WritePacked( packet ); WriteUpdateMaskForValueUpdate( packet ); }
/// <summary> /// /// </summary> /// <param name="packet"></param> /// <param name="bUpdatingSelf"></param> private void WriteUpdateMaskForValueUpdate( Packet packet ) { UpdateMask updateMask = this.PlayerField.PrivateUpdateMask; updateMask.WriteToPacked( packet ); for ( int iIndex = 0; iIndex <= this.PlayerField.PrivateUpdateMask.HighestUpdatedIndex; iIndex++ ) { if ( updateMask.GetBit( iIndex ) == true ) packet.WriterStream.Write( (uint)this.PlayerField.UpdateValues[iIndex].UInt32 ); } }
/// <summary> /// /// </summary> /// <param name="packet"></param> public void AddUpdateData( Packet packet, uint uiUpdateCount ) { ReaderWriterLockSlimEx.EnterWriteLock( m_LockUpdatePacket ); { m_UpdatePacket.Write( packet ); packet.Release(); m_UpdateCount += uiUpdateCount; } ReaderWriterLockSlimEx.ExitWriteLock( m_LockUpdatePacket ); }
/// <summary> /// /// </summary> /// <param name="writer"></param> /// <param name="updatingSelf"></param> public void ObjectCreationUpdate( Packet writer, bool updatingSelf ) { writer.WriterStream.Write( (byte)this.PlayerField.GetCreationUpdateType( updatingSelf ) ); EntityId entityId = new EntityId(); entityId.WritePacked( writer ); writer.WriterStream.Write( (byte)this.PlayerField.ObjectTypeId ); WriteMovementUpdate( writer, updatingSelf ); WriteUpdateMaskForCreation( writer ); }
/// <summary> /// /// </summary> /// <param name="packet"></param> /// <param name="bUpdatingSelf"></param> private void WriteUpdateMaskForCreation( Packet packet ) { UpdateMask updateMask = new UpdateMask( this.PlayerField.PrivateUpdateMask.Blocks ); for ( int iIndex = 0; iIndex < this.PlayerField.UpdateValues.Length; iIndex++ ) { if ( this.PlayerField.UpdateValues[iIndex].UInt32 != 0 ) updateMask.SetBit( iIndex ); } updateMask.WriteToPacked( packet ); for ( int iIndex = 0; iIndex <= updateMask.HighestUpdatedIndex; iIndex++ ) { if ( updateMask.GetBit( iIndex ) == true ) packet.WriterStream.Write( (uint)this.PlayerField.UpdateValues[iIndex].UInt32 ); } }
/// <summary> /// /// </summary> /// <param name="packet"></param> /// <param name="updatingSelf"></param> private void WriteMovementUpdate( Packet packet, bool updatingSelf ) { // Should be 0x10 | 0x20 | 0x40 for 2.1.3 UpdateFlag updateFlags = this.PlayerField.UpdateFlags; if ( updatingSelf == true ) { updateFlags |= UpdateFlag.Self; } packet.WriterStream.Write( (byte)updateFlags ); MovementFlags moveFlags = MovementFlags.None; if ( m_IsSpiritHealer == true ) { moveFlags |= MovementFlags.Waterwalking; } #region Living packet.WriterStream.Write( (uint)moveFlags ); // new in 2.3.0 packet.WriterStream.Write( (byte)0 ); packet.WriterStream.Write( (uint)Environment.TickCount ); #endregion #region Position packet.WriterStream.Write( (float)base.X ); packet.WriterStream.Write( (float)base.Y ); packet.WriterStream.Write( (float)base.Z ); packet.WriterStream.Write( (float)base.O ); #endregion packet.WriterStream.Write( (int)0 ); #region Speed Block packet.WriterStream.Write( (float)m_UnitMechanics.WalkSpeed ); packet.WriterStream.Write( (float)m_UnitMechanics.RunSpeed ); packet.WriterStream.Write( (float)m_UnitMechanics.SwimBackSpeed ); packet.WriterStream.Write( (float)m_UnitMechanics.SwimSpeed ); packet.WriterStream.Write( (float)m_UnitMechanics.WalkBackSpeed ); packet.WriterStream.Write( (float)m_UnitMechanics.FlightSpeed ); packet.WriterStream.Write( (float)m_UnitMechanics.FlightBackSpeed ); packet.WriterStream.Write( (float)m_UnitMechanics.TurnSpeed ); #endregion /*#region Spline if ((moveFlags & MovementFlags.SplineTaxi) == MovementFlags.SplineTaxi) { SplineFlags splineFlags = SplineFlags.None; } #endregion*/ #region UpdateFlag.Flag_0x10 packet.WriterStream.Write( (uint)0 ); #endregion }
/// <summary> /// Writes only the required blocks to the packet /// </summary> /// <param name="packet">The packet to write to</param> /// <param name="highestValue">The highest updated value in the mask</param> public void WriteToPacked( Packet packet ) { int iBlockCount = ( m_HighestUpdatedIndex >> 5 ) + 1; packet.WriterStream.Write( (byte)iBlockCount ); for ( int iIndex = 0; iIndex < iBlockCount; iIndex++ ) packet.WriterStream.Write( (uint)m_UpdateMask[iIndex] ); }
/// <summary> /// /// </summary> /// <param name="characters"></param> /// <param name="packet"></param> protected static void SendUpdatePacket( IEnumerable<WowCharacter> characters, Packet packet ) { foreach ( var character in characters ) character.NetState.Send( packet ); }
/// <summary> /// /// </summary> /// <param name="packet"></param> /// <returns></returns> public int WritePacked( Packet packet ) { byte byMask = 0; long byEndPosition = 0; long byStartPosition = packet.WriterStream.Position; byte[] byteArray = this.ByteArray; // 写入 packet.WriterStream.Write( byMask ); for ( int iIndex = 0; iIndex < byteArray.Length; iIndex++ ) { byte byCheck = byteArray[iIndex]; if ( byCheck != 0 ) { byMask |= (byte)( 1 << iIndex ); packet.WriterStream.Write( byCheck ); } } byEndPosition = packet.WriterStream.Position; packet.WriterStream.Position = byStartPosition; packet.WriterStream.Write( byMask ); packet.WriterStream.Position = byEndPosition; return (int)( byEndPosition - byStartPosition ); }
/// <summary> /// 发送数据(在多线程中主要实现了顺序的发送) /// </summary> /// <param name="packet">需要发送的数据包</param> public void Send( Packet packet ) { this.Send( SendPriority.Normal, packet ); }
/// <summary> /// /// </summary> public void Write( Packet packet ) { WriterStream.Write( packet.WriterStream.ToArray(), 0, (int)packet.WriterStream.Length ); }
public virtual void WriteMovementUpdate( Packet writer, bool updatingSelf ) { }
public virtual void WriteUpdateMask( Packet writer, bool updatingSelf, bool forCreation ) { }
protected static void SendUpdatePacket( IEnumerable<WowCharacter> characters, Packet packet ) { }
protected static void SendUpdatePacket( WowCharacter character, Packet packet ) { }
/// <summary> /// 发送数据(在多线程中主要实现了顺序的发送) /// </summary> /// <param name="packet">需要发送的数据包</param> public void Send( SendPriority sendPriority, Packet packet ) { if ( this.Running == false || m_BlockSend == true ) return; switch ( sendPriority ) { case SendPriority.Highest: m_PacketSendQueue_Highest.Enqueue( packet ); break; case SendPriority.AboveNormal: m_PacketSendQueue_AboveNormal.Enqueue( packet ); break; case SendPriority.Normal: m_PacketSendQueue_Normal.Enqueue( packet ); break; case SendPriority.BelowNormal: m_PacketSendQueue_BelowNormal.Enqueue( packet ); break; case SendPriority.Lowest: m_PacketSendQueue_Lowest.Enqueue( packet ); break; default: break; } // 防止发送的顺序出错 if ( m_LockSend.InLock() == false ) return; Packet sendPacket = null; do { sendPacket = null; if ( m_PacketSendQueue_Highest.TryDequeue( out sendPacket ) == false ) if ( m_PacketSendQueue_AboveNormal.TryDequeue( out sendPacket ) == false ) if ( m_PacketSendQueue_Normal.TryDequeue( out sendPacket ) == false ) if ( m_PacketSendQueue_BelowNormal.TryDequeue( out sendPacket ) == false ) if ( m_PacketSendQueue_Lowest.TryDequeue( out sendPacket ) == false ) break; if ( sendPacket != null ) this.InternalSend( sendPacket ); } while ( sendPacket != null ); m_LockSend.OutLock(); // 如果没有错误且需要等待发送,则放在全局的处理中。。。 if ( m_SendQueue.IsEmpty == false ) m_World.FlushNetStates( this ); }
private void InternalSend( Packet packet ) { if ( this.Running == false || m_BlockSend == true ) { // 表示已处理发送 packet.Release(); return; } // 连接的通知事件 EventHandler<NetStateSendPacketEventArgs> tempEvent = m_EventSendPacket; if ( tempEvent != null ) { NetStateSendPacketEventArgs sendEventArgs = new NetStateSendPacketEventArgs( this, packet ); tempEvent( this, sendEventArgs ); if ( sendEventArgs.IsCancelSend == true ) { // 表示已处理发送 packet.Release(); return; } } long iLength = 0; PacketProfile packetProfile = PacketProfile.GetOutgoingProfile( (byte)packet.PacketID ); DateTime dateTimeStart = ( packetProfile == null ? DateTime.MinValue : DateTime.Now ); { do { PacketBuffer packetBuffer = packet.AcquireBuffer(); if ( packetBuffer.IsNULL == true ) throw new Exception( "NetState.InternalSend(...) - packetBuffer.IsNULL == true error!" ); byte[] byteBuffer = packetBuffer.Buffer; long lLength = packetBuffer.Length; // 加密数据 if ( m_Encoder != null ) m_Encoder.EncodeOutgoingPacket( this, ref byteBuffer, ref lLength ); m_SendQueue.Enqueue( byteBuffer, 0, lLength ); } while ( false ); // 表示已处理发送 packet.Release(); } if ( packetProfile != null ) packetProfile.Record( iLength, DateTime.Now - dateTimeStart ); }
/// <summary> /// /// </summary> /// <param name="writer"></param> /// <param name="updatingSelf"></param> public void ObjectCreationUpdate( Packet packet, bool updatingSelf ) { }
/// <summary> /// /// </summary> /// <param name="character"></param> /// <param name="packet"></param> protected static void SendUpdatePacket( WowCharacter character, Packet packet ) { character.NetState.Send( packet ); }