public void TestInt() { var value = 21; var bytes = BitConverter.GetBytes(value); var queue = new ByteQueue(); // Enqueue first two bytes of int var buffer = new byte[2]; Array.Copy(bytes, 0, buffer, 0, 2); queue.Enqueue(buffer); Assert.IsTrue(queue.HasBytes(2)); Assert.IsFalse(queue.HasBytes(3)); Assert.IsNull(queue.Dequeue()); // Enqueue last two bytes of int buffer = new byte[2]; Array.Copy(bytes, 2, buffer, 0, 2); queue.Enqueue(buffer); Assert.IsTrue(queue.HasBytes(4)); Assert.IsFalse(queue.HasBytes(5)); var dequeuedValue = queue.Dequeue(); Assert.AreEqual(value, dequeuedValue.Value); Assert.IsFalse(queue.HasBytes(1)); }
public void TestReadAfterCapacityChanged() { ByteQueue queue = new ByteQueue(20); int capacity = queue.Capacity; byte[] input = Encoding.ASCII.GetBytes("hello world!"); // Write then read so the read head != 0. queue.Enqueue(input, 0, input.Length); byte[] output = new byte[input.Length]; queue.Dequeue(output, 0, output.Length); // Write until the capacity changes. while (queue.Capacity == capacity) { queue.Enqueue(input, 0, input.Length); } queue.Dequeue(output, 0, output.Length); Assert.AreEqual(Encoding.ASCII.GetString(input), Encoding.ASCII.GetString(output)); }
public RecordLayer.Record FromByteQueue(ByteQueue queue) { if (queue.Length == 0) { return(null); } else { if (queue.Length >= 5) { byte[] recordHeader = queue.Peek(5); ProtoType recordType = (ProtoType)recordHeader[0]; ProtocolVersion version = new ProtocolVersion(recordHeader[1], recordHeader[2]); /* TODO: Check for the right version */ if (BitConverter.IsLittleEndian) { Array.Reverse(recordHeader, 3, 2); } int payloadLength = BitConverter.ToUInt16(recordHeader, 3); if (queue.Length < payloadLength) { throw new SslInsufficientReceiveException(); } queue.Dequeue(5); // discard header return(new RecordLayer.Record(queue.Dequeue(payloadLength), recordType, version)); } else { throw new SslInsufficientReceiveException(); } } }
public int RecvPartial(byte[] buffer, int offset, int length, bool waitForSomeData) { if (!Connected) { return(-1); } if (StreamDataEvent != null) { throw new UserFriendlyException("Tried to RecvPartial() data from IGE.Net.RawClient while it has a StreamDataEvent attached. You cannot use both blocking and asynchronous receiving at the same time.", "Connection error"); } if (Thread.CurrentThread == m_ReceiverThread) { throw new UserFriendlyException("Tried to use RecvPartial() within receiver thread. This would lock the thread.", "Connection error"); } int received = 0; lock (SyncRecv) { while (length > 0) { if (waitForSomeData) { try { WaitRecvReady(); } catch { Log(LogLevel.Debug, "RecvPartial interrupted"); return(-1); } } lock (m_Input) { received = Math.Min(length, m_Input.Length); if (received > 0) { m_Input.Dequeue(buffer, offset, received); if (m_Input.Length == 0) { m_InputReady.Reset(); m_InputEmpty.Set(); m_InputAccepts.Set(); } else if (m_Input.Length < MaxRecvBufferSize) { m_InputAccepts.Set(); } Log(LogLevel.Debug, "RecvPartial dequeued {0} bytes (total buffered {1} bytes)", received, m_Input.Length); break; } if (!waitForSomeData) { break; } } } } return(received); }
private byte[] GetBufferToBeRead(int length) { int availableData = _fragPackets.Size + _readingBufferQueue.Size; if (length > availableData) { return(null); } int fromFrag; byte[] data = new byte[length]; if (length >= _fragPackets.Size) { fromFrag = _fragPackets.Size; } else { fromFrag = length; } _fragPackets.Dequeue(data, 0, fromFrag); int fromProcessed = length - fromFrag; _readingBufferQueue.Dequeue(data, fromFrag, fromProcessed); return(data); }
/// <summary> /// Read a byte. /// </summary> /// <returns>-1 if no data, else the first byte available.</returns> public int read() { Thread.Yield(); int result = -1; byte[] buffer = new byte[1]; if (_receiveQueue.Length > 0) { if (_receiveQueue.Dequeue(buffer, 0, 1) == 1) { result = buffer[0]; } } return(result); }
public void TestWriteThenReadWithWrapAround() { ByteQueue queue = new ByteQueue(10); byte[] input = Encoding.ASCII.GetBytes("123456"); queue.Enqueue(input, 0, input.Length); byte[] output = new byte[input.Length]; queue.Dequeue(output, 0, output.Length); queue.Enqueue(input, 0, input.Length); Array.Clear(output, 0, output.Length); queue.Dequeue(output, 0, output.Length); Assert.AreEqual(Encoding.ASCII.GetString(input), Encoding.ASCII.GetString(output)); }
public void TestWriteThenRead() { ByteQueue queue = new ByteQueue(); byte[] input = Encoding.ASCII.GetBytes("hello world!"); queue.Enqueue(input, 0, input.Length); byte[] output = new byte[input.Length]; queue.Dequeue(output, 0, output.Length); Assert.AreEqual(Encoding.ASCII.GetString(input), Encoding.ASCII.GetString(output)); }
/// <summary> /// Read a number of bytes and store in a buffer. /// </summary> /// <param name="buf">buffer to write to.</param> /// <param name="bytes">number of bytes to read.</param> /// <returns>-1 if no data or number of read bytes.</returns> public int read(ref byte[] buf, uint bytes) { Thread.Yield(); int result = -1; int length = _receiveQueue.Length; length = bytes > length ? length : (int)bytes; if (length > 0) { result = _receiveQueue.Dequeue(buf, 0, length); } return(result); }
public void TestBytes() { var value = "TestStringBytes"; var bytes = Encoding.UTF8.GetBytes(value); var queue = new ByteQueue(); queue.Enqueue(bytes); Assert.IsTrue(queue.HasBytes(bytes.Length)); Assert.IsFalse(queue.HasBytes(bytes.Length + 1)); var dequeuedBytes = queue.Dequeue(bytes.Length); var dequeuedValue = Encoding.UTF8.GetString(dequeuedBytes); Assert.AreEqual(value, dequeuedValue); }
private void Send() { while (true) { if (ByteQueue.Any()) { try { string strMsg = this.txt_Msg.Text.Trim(); byte[] buffer = Encoding.Default.GetBytes(strMsg); List <byte> list = new List <byte>(); list.Add(0); list.AddRange(buffer); //将泛型集合转换为数组 byte[] newBuffer = list.ToArray(); //获得用户选择的IP地址 //var mess = new byte[] { 0xff, 0x08, 0x07 }; //= @"FF 08 07"; var mess = DivisionHEX(txt_Msg.Text).TrimEnd(); //var strings = mess.Split(' '); //var bytes = Array.ConvertAll(strings, input => Convert.ToByte(input, 16)); var bytes = ByteQueue.Dequeue(); foreach (var ip in dicPCSocket.Keys) { try { dicPCSocket[ip].Send(bytes); } catch (Exception ex) { }; } txt_Log.Invoke(receiveCallBack, $"发送成功"); } catch (Exception ex) { MessageBox.Show("给客户端发送消息出错:" + ex.Message); } } else { Thread.Sleep(1); } } }
internal int CheckQueues(Bus bus) { ByteQueue sendQueue = bus.GetSendQueue(); if (sendQueue.Length > 0) { byte[] dataToSend = sendQueue.Dequeue(sendQueue.Length); Send(m_SecureSocket.InternalSocket, dataToSend); } ByteQueue userQueue = bus.GetUserQueue(); if (userQueue.Length > 0) { int length = Math.Min(m_Count, userQueue.Length); byte[] data = userQueue.Dequeue(length); System.Buffer.BlockCopy(data, 0, m_Buffer, m_Offset, length); return(length); } return(0); }
/// <inheritdoc/> public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { var read = 0; while (read < count && !cancellationToken.IsCancellationRequested) { if (!EndOfStream) { await _readerEvent.WaitAsync(cancellationToken); } var bytesDequeued = _reader.Dequeue(buffer, offset + read, count - read); read += bytesDequeued; if (bytesDequeued == 0 && EndOfStream) { break; } } return(read); }
public int endPacket() { byte[] buffer = new byte[_sendQueue.Length]; _sendQueue.Dequeue(buffer, 0, _sendQueue.Length); return(_client.Send(buffer, buffer.Length, _packetEndpoint)); }
private void SenderThread(object param) { Socket socket = (Socket)param; IAsyncResult async; byte[] buffer; int sent, offset, length; bool keepRunning = true; Log(LogLevel.Debug, "SenderThread: started"); try { while (socket.Connected) { keepRunning = keepRunning && KeepRunning; try { if (keepRunning) { Log(LogLevel.Debug, "SenderThread: waiting for data"); m_OutputReady.WaitOne(); } } catch (ThreadInterruptedException) { Log(LogLevel.Debug, "SenderThread: interrupted while waiting for data"); keepRunning = false; } if (!socket.Connected) { Log(LogLevel.Debug, "SenderThread: socket was closed while waiting for data"); break; } lock (m_Output) { if (m_Output.Length == 0) { Log(LogLevel.Debug, "SenderThread: seems i was interrupted"); if (keepRunning) { continue; } Log(LogLevel.Debug, "SenderThread: got signal to stop so quitting"); break; } buffer = m_Output.Dequeue(m_Output.Length); m_OutputReady.Reset(); m_OutputEmpty.Set(); m_OutputAccepts.Set(); Log(LogLevel.Debug, "SenderThread: read {0} bytes from the queue", buffer.Length); } length = buffer.Length; offset = 0; while (offset < length && socket.Connected) { Log(LogLevel.Debug, "SenderThread: beginning to send"); async = socket.BeginSend(buffer, offset, length - offset, SocketFlags.None, null, null); try { async.AsyncWaitHandle.WaitOne(1000); } catch (ThreadInterruptedException) { Log(LogLevel.Debug, "SenderThread: interrupted while sending"); keepRunning = false; } sent = socket.EndSend(async); Log(LogLevel.Debug, "SenderThread: sent {0} bytes", sent); //sent = socket.Send(buffer, offset, length - offset, SocketFlags.None); if (sent > 0) { offset += sent; } } buffer = null; } Log(LogLevel.Debug, "SenderThread: end loop"); } catch (Exception ex) { Log(LogLevel.Debug, "SenderThread exception: {0}", ex); } if (KeepRunning) { Log(LogLevel.Debug, "SenderThread: doing internal disconnect"); DisconnectInternal(m_SenderThread); } Log(LogLevel.Debug, "SenderThread: ended"); }
// Try to decrypt incoming data. public void DecodeIncomingPacket(NetState from, ref byte[] buffer, ref int length) { #region m_Encryption != null if (m_Encryption != null) { // If we're decrypting using LoginCrypt and we've already been relayed, // only decrypt a single packet using logincrypt and then disable it if (m_AlreadyRelayed && m_Encryption is LoginEncryption) { uint newSeed = ((((LoginEncryption)(m_Encryption)).Key1 + 1) ^ ((LoginEncryption)(m_Encryption)).Key2); // Swap the seed newSeed = ((newSeed >> 24) & 0xFF) | ((newSeed >> 8) & 0xFF00) | ((newSeed << 8) & 0xFF0000) | ((newSeed << 24) & 0xFF000000); // XOR it with the old seed newSeed ^= m_Seed; IClientEncryption newEncryption = new GameEncryption(newSeed); // Game Encryption comes first newEncryption.clientDecrypt(ref buffer, length); // The login encryption is still used for this one packet m_Encryption.clientDecrypt(ref buffer, length); // Swap the encryption schemes m_Encryption = newEncryption; m_Seed = newSeed; return; } m_Encryption.clientDecrypt(ref buffer, length); return; } #endregion #region Port Scan //11JUN2008 RunUO SVN fix ** START *** // If the client did not connect on the game server port, // it's not our business to handle encryption for it //if (((IPEndPoint)from.Socket.LocalEndPoint).Port != Listener.Port) //{ // m_Encryption = new NoEncryption(); // return; //} bool handle = false; for (int i = 0; i < Listener.EndPoints.Length; i++) { IPEndPoint ipep = (IPEndPoint)Listener.EndPoints[i]; if (((IPEndPoint)from.Socket.LocalEndPoint).Port == ipep.Port) { handle = true; } } if (!handle) { m_Encryption = new NoEncryption(); return; } //11JUN2008 RunUO SVN fix ** END *** #endregion #region !m_Seeded // For simplicities sake, enqueue what we just received as long as we're not initialized m_Buffer.Enqueue(buffer, 0, length); // Clear the array length = 0; // If we didn't receive the seed yet, queue data until we can read the seed //if (!m_Seeded) //{ // // Now check if we have at least 4 bytes to get the seed // if (m_Buffer.Length >= 4) // { // byte[] m_Peek = new byte[m_Buffer.Length]; // m_Buffer.Dequeue( m_Peek, 0, m_Buffer.Length ); // Dequeue everything // m_Seed = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]); // m_Seeded = true; // Buffer.BlockCopy(m_Peek, 0, buffer, 0, 4); // length = 4; // } // else // { // return; // } //} //http://uodev.de/viewtopic.php?t=5097&postdays=0&postorder=asc&start=15&sid=dfb8e6c73b9e3eb95c1634ca3586e8a7 //if (!m_Seeded) //{ // int seed_length = m_Buffer.GetSeedLength(); // if (m_Buffer.Length >= seed_length) // { // byte[] m_Peek = new byte[m_Buffer.Length]; // m_Buffer.Dequeue(m_Peek, 0, seed_length); // if (seed_length == 4) // m_Seed = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]); // else if (seed_length == 21) // m_Seed = (uint)((m_Peek[1] << 24) | (m_Peek[2] << 16) | (m_Peek[3] << 8) | m_Peek[4]); // m_Seeded = true; // Buffer.BlockCopy(m_Peek, 0, buffer, 0, seed_length); // length = seed_length; // } // else // { // return; // } //} //11JUN2008 My Version if (!m_Seeded) { if (m_Buffer.Length <= 3) //Short Length, try again. { Console.WriteLine("Encryption: Failed - Short Lenght"); return; } //else if ((m_Buffer.Length == 83) && (m_Buffer.GetPacketID() == 239)) //New Client //{ // byte[] m_Peek = new byte[21]; // m_Buffer.Dequeue(m_Peek, 0, 21); // m_Seed = (uint)((m_Peek[1] << 24) | (m_Peek[2] << 16) | (m_Peek[3] << 8) | m_Peek[4]); // m_Seeded = true; // Buffer.BlockCopy(m_Peek, 0, buffer, 0, 21); // length = 21; // Console.WriteLine("Encryption: Passed - New Client"); //} //05MAR2009 Smjert's fix for double log in. *** START *** else if ((m_Buffer.Length == 83 || m_Buffer.Length == 21) && (m_Buffer.GetPacketID() == 239)) //New Client { length = m_Buffer.Length; byte[] m_Peek = new byte[21]; m_Buffer.Dequeue(m_Peek, 0, 21); m_Seed = (uint)((m_Peek[1] << 24) | (m_Peek[2] << 16) | (m_Peek[3] << 8) | m_Peek[4]); m_Seeded = true; Buffer.BlockCopy(m_Peek, 0, buffer, 0, 21); Console.WriteLine("Encryption: Passed - New Client"); // We need to wait the next packet if (length == 21) { return; } length = 21; } else if (m_Buffer.Length >= 4) //Old Client //05MAR2009 Smjert's fix for double log in. *** END *** { byte[] m_Peek = new byte[4]; m_Buffer.Dequeue(m_Peek, 0, 4); m_Seed = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]); m_Seeded = true; Buffer.BlockCopy(m_Peek, 0, buffer, 0, 4); length = 4; Console.WriteLine("Encryption: Passed - Old Client"); } else //It should never reach here. { Console.WriteLine("Encryption: Failed - It should never reach here"); return; } } #endregion // If the context isn't initialized yet, that means we haven't decided on an encryption method yet #region m_Encryption == null if (m_Encryption == null) { int packetLength = m_Buffer.Length; int packetOffset = length; m_Buffer.Dequeue(buffer, length, packetLength); // Dequeue everything length += packetLength; // This is special handling for the "special" UOG packet if (packetLength >= 3) { if (buffer[packetOffset] == 0xf1 && buffer[packetOffset + 1] == ((packetLength >> 8) & 0xFF) && buffer[packetOffset + 2] == (packetLength & 0xFF)) { m_Encryption = new NoEncryption(); return; } } // Check if the current buffer contains a valid login packet (62 byte + 4 byte header) // Please note that the client sends these in two chunks. One 4 byte and one 62 byte. if (packetLength == 62) { Console.WriteLine("Checking packetLength 62 == " + packetLength); // Check certain indices in the array to see if the given data is unencrypted if (buffer[packetOffset] == 0x80 && buffer[packetOffset + 30] == 0x00 && buffer[packetOffset + 60] == 0x00) { if (Configuration.AllowUnencryptedClients) { m_Encryption = new NoEncryption(); } else { RejectNoEncryption(from); from.Dispose(); return; } } else { LoginEncryption encryption = new LoginEncryption(); if (encryption.init(m_Seed, buffer, packetOffset, packetLength)) { Console.WriteLine("Client: {0}: Encrypted client detected, using keys of client {1}", from, encryption.Name); m_Encryption = encryption; Console.WriteLine("Encryption: Check 1"); byte[] packet = new byte[packetLength]; Console.WriteLine("Encryption: Check 2"); Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength); Console.WriteLine("Encryption: Check 3"); encryption.clientDecrypt(ref packet, packet.Length); Console.WriteLine("Encryption: Check 4"); Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength); Console.WriteLine("Encryption: Check 5"); //return; //Just throwing this in. } else { Console.WriteLine("Detected an unknown client."); } } } else if (packetLength == 65) { Console.WriteLine("Checking packetLength 65 == " + packetLength); // If its unencrypted, use the NoEncryption class if (buffer[packetOffset] == '\x91' && buffer[packetOffset + 1] == ((m_Seed >> 24) & 0xFF) && buffer[packetOffset + 2] == ((m_Seed >> 16) & 0xFF) && buffer[packetOffset + 3] == ((m_Seed >> 8) & 0xFF) && buffer[packetOffset + 4] == (m_Seed & 0xFF)) { if (Configuration.AllowUnencryptedClients) { m_Encryption = new NoEncryption(); } else { RejectNoEncryption(from); from.Dispose(); } } else { // If it's not an unencrypted packet, simply assume it's encrypted with the seed m_Encryption = new GameEncryption(m_Seed); byte[] packet = new byte[packetLength]; Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength); m_Encryption.clientDecrypt(ref packet, packet.Length); Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength); } } // If it's still not initialized, copy the data back to the queue and wait for more if (m_Encryption == null) { Console.WriteLine("Encryption: Check - Waiting"); m_Buffer.Enqueue(buffer, packetOffset, packetLength); length -= packetLength; return; } } #endregion }
internal void Send_Start() { if (!Running || !_socket.Connected) { DisposeSendSystem(); return; } Packet packet = null; try { ByteQueue byteQueue = new ByteQueue(); int length = 0; while (!PacketsToBeSent.IsEmpty && length <= 1024) { if (!PacketsToBeSent.TryDequeue(out packet)) { Interlocked.Exchange(ref _TimesEnqueuedForSend, 0); return; } if (!packet.Shared) packet.Write(); byte[] packetBuffer = packet.GetBuffer(); length += packetBuffer.Length; byteQueue.Enqueue(packetBuffer, 0, packetBuffer.Length); packet.Release(); } if (byteQueue.Length > 0) { byte[] data = new byte[length]; byteQueue.Dequeue(data, 0, data.Length); Send_Async(data); } else { Interlocked.Exchange(ref _TimesEnqueuedForSend, 0); if (!PacketsToBeSent.IsEmpty) { int newValue = Interlocked.Increment(ref _TimesEnqueuedForSend); if (newValue == 1) { Server.SendClientQueue.Enqueue(this); Server.NetworkSignal.Set(); } } } } catch (Exception e) { MarkToDispose(); DisposeSendSystem(); if(packet != null) Logger.Log(Logger.LogLevel.Error, "Sending packet: {0}", packet.ToString()); Logger.Log(Logger.LogLevel.Error, e.ToString()); // TODO: log something? } }
private bool HandleSeed(NetState ns, ByteQueue buffer) { if (buffer.GetPacketID() == 0xEF) { // new packet in client 6.0.5.0 replaces the traditional seed method with a seed packet // 0xEF = 239 = multicast IP, so this should never appear in a normal seed. So this is backwards compatible with older clients. ns.Seeded = true; return true; } else if (buffer.Length >= 4) { byte[] m_Peek = new byte[4]; buffer.Dequeue(m_Peek, 0, 4); int seed = (m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]; if (seed == 0) { Console.WriteLine("Login: {0}: Invalid client detected, disconnecting", ns); ns.Dispose(); return false; } ns.m_Seed = seed; ns.Seeded = true; return true; } else { return false; } }
public bool HandleReceive(NetState ns) { ByteQueue buffer = ns.Buffer; if (buffer == null || buffer.Length <= 0) { return(true); } CConsole.DebugLine("{0}: Incoming Data - {1} Bytes", ns, buffer.Length); /* * Packet Analyse/verify && Parsing */ lock ( buffer ) { int length = buffer.Length; // debug Data while (length > 0 && ns.Running) { short packetID = buffer.GetPacketID(); // debug log using (TextWriter writer = File.CreateText(AppDomain.CurrentDomain.BaseDirectory + @"\packet_" + DateTime.Now.UnixTimestamp() + ".log")) { using (MemoryStream ms = new MemoryStream(buffer.ByteBuffer)) Tools.FormatBuffer(writer, ms, (int)ms.Length); } CConsole.DebugLine("{0}: packetID {1}, {2} bytes", ns, packetID, length); PacketHandler handler = PacketHandlers.GetHandler(packetID); if (handler == null) { byte[] data = new byte[length]; length = buffer.Dequeue(data, 0, length); CConsole.ErrorLine("{0}: no Handler found! Data dispose", ns); break; } CConsole.StatusLine("{0}: Handler found ({1} bytes)! Trigger Callback...", ns, handler.Length); byte[] packetBuffer; if (mBufferSize >= handler.Length) { packetBuffer = mBuffers.AcquireBuffer(); } else { packetBuffer = new byte[handler.Length]; } buffer.Dequeue(packetBuffer, 0, handler.Length); PacketReader r = new PacketReader(packetBuffer, handler.Length, 0); handler.OnReceive(ns, r); length = buffer.Length; if (mBufferSize >= handler.Length) { mBuffers.ReleaseBuffer(packetBuffer); } } // end while()*/ } // end Lock() return(true); }
public bool OnReceive(NetState ns) { ByteQueue buffer = ns.Buffer; if (buffer == null || buffer.Length <= 0) { return(true); } lock (buffer) { int length = buffer.Length; while (length > 0) { int packetID = buffer.GetPacketID(); PacketHandler handler = ns.GetHandler(packetID); if (handler == null) { byte[] data = new byte[length]; length = buffer.Dequeue(data, 0, length); new PacketReader(data, length, false).Trace(ns); break; } int packetLength = handler.Length; if (packetLength <= 0) { if (length >= 3) { packetLength = buffer.GetPacketLength(); if (packetLength < 3) { ns.Dispose(); break; } } else { break; } } if (length < packetLength) { break; } byte[] packetBuffer = BufferSize >= packetLength?_buffers.AcquireBuffer() : new byte[packetLength]; packetLength = buffer.Dequeue(packetBuffer, 0, packetLength); PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0); handler.OnReceive(ns, r); length = buffer.Length; if (BufferSize >= packetLength) { _buffers.ReleaseBuffer(packetBuffer); } } } return(true); }
public bool HandleReceive(ByteQueue ns) { ByteQueue buffer = ns; if (buffer == null || buffer.Length <= 0) { return(true); } lock (buffer) { int length = buffer.Length; if (!ns.Sender.Seeded) { if (buffer.GetPacketID() == 0xEF) { // new packet in client 6.0.5.0 replaces the traditional seed method with a seed packet // 0xEF = 239 = multicast IP, so this should never appear in a normal seed. So this is backwards compatible with older clients. ns.Sender.Seeded = true; } else if (buffer.Length >= 4) { buffer.Dequeue(m_Peek, 0, 4); int seed = (m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]; if (seed == 0) { Console.WriteLine("Login: {0}: Invalid client detected, disconnecting", ns); ns.Socket.Dispose(); return(false); } ns.Sender.Seed = seed; ns.Sender.Seeded = true; length = buffer.Length; } else { return(true); } } while (length > 0) { int packetID = buffer.GetPacketID(); PacketHandler handler = m_PacketsHander.GetHandler(packetID); if (handler == null) { return(false); } int packetLength = handler.Length; if (packetLength <= 0) { if (length >= 3) { packetLength = buffer.GetPacketLength(); if (packetLength < 3) { break; } } else { break; } } if (length >= packetLength) { byte[] packetBuffer; if (BufferSize >= packetLength) { packetBuffer = m_Buffers.AcquireBuffer(); } else { packetBuffer = new byte[packetLength]; } packetLength = buffer.Dequeue(packetBuffer, 0, packetLength); PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0); handler.OnReceive(ns, r, ns.Socket); length = buffer.Length; if (BufferSize >= packetLength) { m_Buffers.ReleaseBuffer(packetBuffer); } } else { break; } } } return(true); }
public void DecodeIncomingPacket(NetState from, ref byte[] buffer, ref int length) { if (m_Encryption != null) { if (m_AlreadyRelayed && m_Encryption is LoginEncryption) { uint newSeed = ((((LoginEncryption)(m_Encryption)).Key1 + 1) ^ ((LoginEncryption)(m_Encryption)).Key2); newSeed = ((newSeed >> 24) & 0xFF) | ((newSeed >> 8) & 0xFF00) | ((newSeed << 8) & 0xFF0000) | ((newSeed << 24) & 0xFF000000); newSeed ^= m_Seed; IClientEncryption newEncryption = new GameEncryption(newSeed); newEncryption.clientDecrypt(ref buffer, length); m_Encryption.clientDecrypt(ref buffer, length); m_Encryption = newEncryption; m_Seed = newSeed; return; } m_Encryption.clientDecrypt(ref buffer, length); return; } bool handle = false; for (int i = 0; i < Listener.EndPoints.Length; i++) { IPEndPoint ipep = (IPEndPoint)Listener.EndPoints[i]; if (((IPEndPoint)from.Socket.LocalEndPoint).Port == ipep.Port) { handle = true; } } if (!handle) { m_Encryption = new NoEncryption(); return; } m_Buffer.Enqueue(buffer, 0, length); length = 0; if (!m_Seeded) { if (m_Buffer.Length <= 3) { Console.WriteLine("Encryption: Failed - Short Lenght"); return; } else if ((m_Buffer.Length == 83 || m_Buffer.Length == 21) && (m_Buffer.GetPacketID() == 239)) //New Client { length = m_Buffer.Length; byte[] m_Peek = new byte[21]; m_Buffer.Dequeue(m_Peek, 0, 21); m_Seed = (uint)((m_Peek[1] << 24) | (m_Peek[2] << 16) | (m_Peek[3] << 8) | m_Peek[4]); m_Seeded = true; Buffer.BlockCopy(m_Peek, 0, buffer, 0, 21); Console.WriteLine("Encryption: Passed - New Client"); if (length == 21) { return; } length = 21; } else if (m_Buffer.Length >= 4) { byte[] m_Peek = new byte[4]; m_Buffer.Dequeue(m_Peek, 0, 4); m_Seed = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]); m_Seeded = true; Buffer.BlockCopy(m_Peek, 0, buffer, 0, 4); length = 4; Console.WriteLine("Encryption: Passed - Old Client"); } else { Console.WriteLine("Encryption: Failed - It should never reach here"); return; } } if (m_Encryption == null) { int packetLength = m_Buffer.Length; int packetOffset = length; m_Buffer.Dequeue(buffer, length, packetLength); length += packetLength; if (packetLength >= 3) { if (buffer[packetOffset] == 0xf1 && buffer[packetOffset + 1] == ((packetLength >> 8) & 0xFF) && buffer[packetOffset + 2] == (packetLength & 0xFF)) { m_Encryption = new NoEncryption(); return; } } if (packetLength == 62) { if (buffer[packetOffset] == 0x80 && buffer[packetOffset + 30] == 0x00 && buffer[packetOffset + 60] == 0x00) { if (Configuration.AllowUnencryptedClients) { m_Encryption = new NoEncryption(); } else { RejectNoEncryption(from); from.Dispose(); return; } } else { LoginEncryption encryption = new LoginEncryption(); if (encryption.init(m_Seed, buffer, packetOffset, packetLength)) { Console.WriteLine("Client: {0}: Encrypted client detected, using keys of client {1}", from, encryption.Name); m_Encryption = encryption; byte[] packet = new byte[packetLength]; Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength); encryption.clientDecrypt(ref packet, packet.Length); Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength); } else { Console.WriteLine("Client: {0}: Detected an unknown client.", from); } } } else if (packetLength == 65) { if (buffer[packetOffset] == '\x91' && buffer[packetOffset + 1] == ((m_Seed >> 24) & 0xFF) && buffer[packetOffset + 2] == ((m_Seed >> 16) & 0xFF) && buffer[packetOffset + 3] == ((m_Seed >> 8) & 0xFF) && buffer[packetOffset + 4] == (m_Seed & 0xFF)) { if (Configuration.AllowUnencryptedClients) { m_Encryption = new NoEncryption(); } else { RejectNoEncryption(from); from.Dispose(); } } else { m_Encryption = new GameEncryption(m_Seed); byte[] packet = new byte[packetLength]; Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength); m_Encryption.clientDecrypt(ref packet, packet.Length); Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength); } } if (m_Encryption == null) { Console.WriteLine("Encryption: Check - Waiting"); m_Buffer.Enqueue(buffer, packetOffset, packetLength); length -= packetLength; return; } } }
private void handleClient(object obj) { NetworkStream clientStream = null; try { var client = obj as TcpClient; clientStream = client.GetStream(); byte[] buffer = new byte[128]; int count; while (_treadActive) { _socketConnected = isSocketConnected(client); if (clientStream.DataAvailable) { int length = buffer.Length - _receiveQueue.Length; count = clientStream.Read(buffer, 0, length); if (count > 0) { _receiveQueue.Enqueue(buffer, 0, count); } } count = _sendQueue.Length; if (count > 0) { if (count > buffer.Length) { count = buffer.Length; } _sendQueue.Dequeue(buffer, 0, count); clientStream.Write(buffer, 0, count); } // prevent high CPU usage Thread.Sleep(10); } } catch (Exception e) { setExceptionMessage(e); } finally { _socketConnected = false; // One have to close the stream before closing the connection // see: https://stackoverflow.com/questions/425235/how-to-properly-and-completely-close-reset-a-tcpclient-connection if (clientStream != null) { try { clientStream.Close(); } catch (Exception e) { setExceptionMessage(e); } } _mreHandleClient.Set(); } }
// Try to decrypt incoming data. public void DecodeIncomingPacket(NetState from, ref byte[] buffer, ref int length) { #region m_Encryption != null if (m_Encryption != null) { // If we're decrypting using LoginCrypt and we've already been relayed, // only decrypt a single packet using logincrypt and then disable it if (m_AlreadyRelayed && m_Encryption is LoginEncryption) { uint newSeed = ((((LoginEncryption)(m_Encryption)).Key1 + 1) ^ ((LoginEncryption)(m_Encryption)).Key2); // Swap the seed newSeed = ((newSeed >> 24) & 0xFF) | ((newSeed >> 8) & 0xFF00) | ((newSeed << 8) & 0xFF0000) | ((newSeed << 24) & 0xFF000000); // XOR it with the old seed newSeed ^= m_Seed; IClientEncryption newEncryption = new GameEncryption(newSeed); // Game Encryption comes first newEncryption.ClientDecrypt(ref buffer, length); // The login encryption is still used for this one packet m_Encryption.ClientDecrypt(ref buffer, length); // Swap the encryption schemes m_Encryption = newEncryption; m_Seed = newSeed; return; } m_Encryption.ClientDecrypt(ref buffer, length); return; } #endregion #region Port Scan bool handle = false; for (int i = 0; i < Listener.EndPoints.Length; i++) { IPEndPoint ipep = Listener.EndPoints[i]; if (((IPEndPoint)from.Socket.LocalEndPoint).Port == ipep.Port) { handle = true; } } if (!handle) { m_Encryption = new NoEncryption(); return; } #endregion #region !m_Seeded // For simplicities sake, enqueue what we just received as long as we're not initialized m_Buffer.Enqueue(buffer, 0, length); // Clear the array length = 0; if (!m_Seeded) { if ((m_Buffer.Length == 83 || m_Buffer.Length == 21) && (m_Buffer.GetPacketID() == 239)) //New Client { length = m_Buffer.Length; byte[] m_Peek = new byte[21]; m_Buffer.Dequeue(m_Peek, 0, 21); m_Seed = (uint)((m_Peek[1] << 24) | (m_Peek[2] << 16) | (m_Peek[3] << 8) | m_Peek[4]); m_Seeded = true; Buffer.BlockCopy(m_Peek, 0, buffer, 0, 21); // We need to wait the next packet if (length == 21) { return; } length = 21; } else if (m_Buffer.Length >= 4) // Old Client { byte[] m_Peek = new byte[4]; m_Buffer.Dequeue(m_Peek, 0, 4); m_Seed = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]); m_Seeded = true; Buffer.BlockCopy(m_Peek, 0, buffer, 0, 4); length = 4; } else { //Console.WriteLine("Encryption: Failed - Invalid Client."); return; } } #endregion // If the context isn't initialized yet, that means we haven't decided on an encryption method yet #region m_Encryption == null if (m_Encryption == null) { int packetLength = m_Buffer.Length; int packetOffset = length; m_Buffer.Dequeue(buffer, length, packetLength); // Dequeue everything length += packetLength; // This is special handling for the "special" UOG packet if (packetLength >= 3) { if (buffer[packetOffset] == 0xf1 && buffer[packetOffset + 1] == ((packetLength >> 8) & 0xFF) && buffer[packetOffset + 2] == (packetLength & 0xFF)) { m_Encryption = new NoEncryption(); return; } } // Check if the current buffer contains a valid login packet (62 byte + 4 byte header) // Please note that the client sends these in two chunks. One 4 byte and one 62 byte. if (packetLength == 62) { // Check certain indices in the array to see if the given data is unencrypted if (buffer[packetOffset] == 0x80 && buffer[packetOffset + 30] == 0x00 && buffer[packetOffset + 60] == 0x00) { if (Configuration.AllowUnencryptedClients) { m_Encryption = new NoEncryption(); } else { RejectNoEncryption(from); from.Dispose(); return; } } else { LoginEncryption encryption = new LoginEncryption(); if (encryption.Initialize(m_Seed, buffer, packetOffset, packetLength, from)) { Console.WriteLine("Client: {0}: Encrypted client detected, using keys for client v{1}.", from, encryption.Name); m_Encryption = encryption; byte[] packet = new byte[packetLength]; Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength); encryption.ClientDecrypt(ref packet, packet.Length); Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength); } else { Console.WriteLine("Client: Unknown client detected, disconnecting."); from.Dispose(); } } } else if (packetLength == 65) { // If its unencrypted, use the NoEncryption class if (buffer[packetOffset] == '\x91' && buffer[packetOffset + 1] == ((m_Seed >> 24) & 0xFF) && buffer[packetOffset + 2] == ((m_Seed >> 16) & 0xFF) && buffer[packetOffset + 3] == ((m_Seed >> 8) & 0xFF) && buffer[packetOffset + 4] == (m_Seed & 0xFF)) { if (Configuration.AllowUnencryptedClients) { m_Encryption = new NoEncryption(); } else { RejectNoEncryption(from); } } else { // If it's not an unencrypted packet, simply assume it's encrypted with the seed m_Encryption = new GameEncryption(m_Seed); byte[] packet = new byte[packetLength]; Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength); m_Encryption.ClientDecrypt(ref packet, packet.Length); Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength); } } // If it's still not initialized, copy the data back to the queue and wait for more if (m_Encryption == null) { m_Buffer.Enqueue(buffer, packetOffset, packetLength); length -= packetLength; return; } } #endregion }
// Try to decrypt incoming data. public void DecodeIncomingPacket(NetState from, ref byte[] buffer, ref int length) { if (m_Encryption != null) { // If we're decrypting using LoginCrypt and we've already been relayed, // only decrypt a single packet using logincrypt and then disable it if (m_AlreadyRelayed && m_Encryption is LoginEncryption) { uint newSeed = ((((LoginEncryption)(m_Encryption)).Key1 + 1) ^ ((LoginEncryption)(m_Encryption)).Key2); // Swap the seed newSeed = ((newSeed >> 24) & 0xFF) | ((newSeed >> 8) & 0xFF00) | ((newSeed << 8) & 0xFF0000) | ((newSeed << 24) & 0xFF000000); // XOR it with the old seed newSeed ^= m_Seed; IClientEncryption newEncryption = new GameEncryption(newSeed); // Game Encryption comes first newEncryption.clientDecrypt(ref buffer, length); // The login encryption is still used for this one packet m_Encryption.clientDecrypt(ref buffer, length); // Swap the encryption schemes m_Encryption = newEncryption; m_Seed = newSeed; return; } m_Encryption.clientDecrypt(ref buffer, length); return; } // If the client did not connect on the game server port, // it's not our business to handle encryption for it if (((IPEndPoint)from.Socket.LocalEndPoint).Port != Listener.Port) { m_Encryption = new NoEncryption(); return; } // For simplicities sake, enqueue what we just received as long as we're not initialized m_Buffer.Enqueue(buffer, 0, length); // Clear the array length = 0; // If we didn't receive the seed yet, queue data until we can read the seed if (!m_Seeded) { // Now check if we have at least 4 bytes to get the seed if (m_Buffer.Length >= 4) { byte[] m_Peek = new byte[m_Buffer.Length]; m_Buffer.Dequeue(m_Peek, 0, m_Buffer.Length); // Dequeue everything m_Seed = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]); m_Seeded = true; Buffer.BlockCopy(m_Peek, 0, buffer, 0, 4); length = 4; } else { return; } } // If the context isn't initialized yet, that means we haven't decided on an encryption method yet if (m_Encryption == null) { int packetLength = m_Buffer.Length; int packetOffset = length; m_Buffer.Dequeue(buffer, length, packetLength); // Dequeue everything length += packetLength; // This is special handling for the "special" UOG packet if (packetLength >= 3) { if (buffer[packetOffset] == 0xf1 && buffer[packetOffset + 1] == ((packetLength >> 8) & 0xFF) && buffer[packetOffset + 2] == (packetLength & 0xFF)) { m_Encryption = new NoEncryption(); return; } } // This is special handling for the "Emulator" packet if (packetLength >= 5) { if (buffer[packetOffset] == 0xbf && buffer[packetOffset + 1] < 0x10 && buffer[packetOffset + 3] == 0x55 && buffer[packetOffset + 4] == 0x55) { m_Encryption = new NoEncryption(); return; } } // Check if the current buffer contains a valid login packet (62 byte + 4 byte header) // Please note that the client sends these in two chunks. One 4 byte and one 62 byte. if (packetLength == 62) { // Check certain indices in the array to see if the given data is unencrypted if (buffer[packetOffset] == 0x80 && buffer[packetOffset + 30] == 0x00 && buffer[packetOffset + 60] == 0x00) { if (Configuration.AllowUnencryptedClients) { m_Encryption = new NoEncryption(); } else { RejectNoEncryption(from); from.Dispose(); return; } } else { LoginEncryption encryption = new LoginEncryption(); if (encryption.init(m_Seed, buffer, packetOffset, packetLength)) { log.InfoFormat("Client: {0}: Encrypted client detected, using keys of client {1}", from, encryption.Name); m_Encryption = encryption; byte[] packet = new byte[packetLength]; Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength); encryption.clientDecrypt(ref packet, packet.Length); Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength); } else { log.Warn("Detected an unknown client."); } } } else if (packetLength == 65) { // If its unencrypted, use the NoEncryption class if (buffer[packetOffset] == '\x91' && buffer[packetOffset + 1] == ((m_Seed >> 24) & 0xFF) && buffer[packetOffset + 2] == ((m_Seed >> 16) & 0xFF) && buffer[packetOffset + 3] == ((m_Seed >> 8) & 0xFF) && buffer[packetOffset + 4] == (m_Seed & 0xFF)) { if (Configuration.AllowUnencryptedClients) { m_Encryption = new NoEncryption(); } else { RejectNoEncryption(from); from.Dispose(); return; } } else { // If it's not an unencrypted packet, simply assume it's encrypted with the seed m_Encryption = new GameEncryption(m_Seed); byte[] packet = new byte[packetLength]; Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength); m_Encryption.clientDecrypt(ref packet, packet.Length); Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength); } } // If it's still not initialized, copy the data back to the queue and wait for more if (m_Encryption == null) { m_Buffer.Enqueue(buffer, packetOffset, packetLength); length -= packetLength; return; } } }
public static void OpCode(Decode state, Client ed) { try { LogConsole.Show(LogType.DEBUG, "OpCode()"); Systems sys = (Systems)state.Packet; sys.PacketInformation = state; ByteQueue queue = ed.queue; int length = queue.Length; LogConsole.Show(LogType.DEBUG, "OpCode() {0}", length); while ((length > 0)) { byte[] buffer; int packetID = queue.GetPacketID(); int packetLength = queue.GetPacketLength(); int packetControlCode = queue.GetPacketControlCode(); LogConsole.Show(LogType.DEBUG, "PacketControl: {0} PacketID: 0x{1:X2} Length: {2}", packetControlCode, packetID, packetLength); LogConsole.HexDump(state.buffer, "", 16); PacketHandler handler = PacketHandlers.GetHandler(packetID); if (handler == null) { byte[] buffer2 = new byte[length]; length = queue.Dequeue(buffer2, 0, length); LogConsole.Show(LogType.DEBUG, "Client: {0}: Unhandled packet 0x{1:X2}", new object[] { state, packetID }); break; } int size = handler.Length; if (length >= 4) { size = packetLength; if (packetLength >= 4) { if (length < size) { break; } if (0x400 >= size) { buffer = m_Buffers.AquireBuffer(); } else { buffer = new byte[size]; } size = queue.Dequeue(buffer, 0, size); ushort packetid = ByteQueue.GetPacketID(buffer); bool flag = IsCrypted(packetid); if (flag) { LogConsole.Show(LogType.DEBUG, "Crypted Packet 0x{0:X4}", new object[] { packetid }); } try { PacketReader2 pr = new PacketReader2(buffer, size); handler.OnReceive(ed, pr); } catch { break; } length = queue.Length; if ((0x400 >= size) && !flag) { m_Buffers.ReleaseBuffer(buffer); break; } } } length = 0; } } catch (Exception) { } }