From ebe6fff43f1c232e9e9ecebae495bab5ad7e91c3 Mon Sep 17 00:00:00 2001 From: Malloc of Kuzkycyziklistan Date: Wed, 10 May 2017 16:10:42 -0500 Subject: [PATCH] can i start actually making the game pls thank youi --- server/Libraries/Kneesocks/Connection.cs | 98 ++++++++++++++++-------- server/Libraries/Kneesocks/Frame.cs | 16 ++-- server/Libraries/Kneesocks/ReadBuffer.cs | 16 ++-- server/Libraries/Kneesocks/Stack.cs | 9 ++- 4 files changed, 91 insertions(+), 48 deletions(-) diff --git a/server/Libraries/Kneesocks/Connection.cs b/server/Libraries/Kneesocks/Connection.cs index dab49b4..a61b72a 100644 --- a/server/Libraries/Kneesocks/Connection.cs +++ b/server/Libraries/Kneesocks/Connection.cs @@ -27,7 +27,7 @@ namespace Kneesocks { ReadBuffer Buffer; private byte[] FirstTwoBytes = null; - private int ExtraHeaderSize = 2; + private int ExtraHeaderSize = 0; private byte[] FrameHeader = null; private List FrameBuffer = new List(); @@ -68,7 +68,22 @@ namespace Kneesocks { ClientHandshake = conn.ClientHandshake; } - public byte[] Parse() { + public void ReadIfNotNull(ref byte[] buffer, int length) { + buffer = buffer == null ? Buffer.AttemptRead(length) + : buffer; + } + + public void ReadIfNotNull(ref byte[] buffer, string terminator) { + buffer = buffer == null ? Buffer.AttemptRead(terminator) + : buffer; + } + + public void Parse() { + if(!Stream.CanRead) { + Disconnected = true; + return; + } + byte[] readBuffer = null; if(Buffer.IsReading) { readBuffer = Buffer.AttemptRead(); @@ -76,17 +91,15 @@ namespace Kneesocks { if(Buffer.ElapsedReadTime.Seconds > (Handshaked ? 300 : 30)) Disconnect(Frame.kClosingReason.ProtocolError, "Timed out waiting for a full response"); - return null; + return; } } if(!Handshaked) { - if(readBuffer == null) { - readBuffer = Buffer.AttemptRead("\r\n\r\n"); - if(readBuffer == null) - return null; - } - + ReadIfNotNull(ref readBuffer, "\r\n\r\n"); + if(readBuffer == null) + return; + try { Handshake request = new Handshake(Encoding.ASCII.GetString(readBuffer)); var response = Handshake.AcceptRequest(request).ToBytes(); @@ -95,24 +108,23 @@ namespace Kneesocks { Handshaked = true; } catch(Exception e) { Disconnect(Frame.kClosingReason.ProtocolError, e.Message); - return null; + return; } OnOpen(); - return null; + return; } OnParse(); if(FirstTwoBytes == null) { - if(readBuffer == null) { - readBuffer = Buffer.AttemptRead(2); - if(readBuffer == null) - return null; - } + ReadIfNotNull(ref readBuffer, 2); + if(readBuffer == null) + return; FirstTwoBytes = readBuffer; - ExtraHeaderSize = Frame.HeaderSizeFromBytes(FirstTwoBytes) - 2; + ExtraHeaderSize = Frame.HeaderLengthFromBytes(FirstTwoBytes) - 2; + readBuffer = null; } @@ -120,11 +132,9 @@ namespace Kneesocks { if(ExtraHeaderSize == 0) FrameHeader = FirstTwoBytes; else { - if(readBuffer == null) { - readBuffer = Buffer.AttemptRead(ExtraHeaderSize); - if(readBuffer == null) - return null; - } + ReadIfNotNull(ref readBuffer, ExtraHeaderSize); + if(readBuffer == null) + return; FrameHeader = FirstTwoBytes.Concat(readBuffer).ToArray(); } @@ -133,18 +143,44 @@ namespace Kneesocks { } if(FrameHeader != null) { - var check = Frame.HeaderFromBytes() + Frame tempFrame; - if() + if(readBuffer == null) { + try { + tempFrame = Frame.HeaderFromBytes(FrameHeader); + } catch(Exception e) { + Disconnect(Frame.kClosingReason.ProtocolError, e.Message); + return; + } + + readBuffer = Buffer.AttemptRead(tempFrame.BodyLength); + if(readBuffer == null) + return; + } + + try { + tempFrame = Frame.FromBytes(FrameHeader.Concat(readBuffer).ToArray()); + } catch(Exception e) { + Disconnect(Frame.kClosingReason.ProtocolError, e.Message); + return; + } + + FrameBuffer.Add(tempFrame); + FirstTwoBytes = null; + ExtraHeaderSize = 0; + FrameHeader = null; + + if(tempFrame.IsFinal) { + byte[] byteBuffer = new byte[0]; + foreach(var frame in FrameBuffer) + byteBuffer = byteBuffer.Concat(frame.Content).ToArray(); + + FrameBuffer = new List(); + OnReceive(byteBuffer); + } } - /*if(!Buffer.IsReading) { - readBuffer = Buffer.AttemptRead("\r\n\r\n"); - if(readBuffer == null) - return null; - }*/ - - return null; + return; } public void Disconnect(string reason = null) { diff --git a/server/Libraries/Kneesocks/Frame.cs b/server/Libraries/Kneesocks/Frame.cs index aea0387..11f808b 100644 --- a/server/Libraries/Kneesocks/Frame.cs +++ b/server/Libraries/Kneesocks/Frame.cs @@ -41,7 +41,7 @@ namespace Kneesocks { int length = 2 + (BodyLength >= 0x7E && BodyLength <= 0xFFFF ? 2 : 0) - + (BodyLength > 0xFFFF ? 4 : 0) + + (BodyLength > 0xFFFF ? 8 : 0) + (IsMasked ? 4 : 0); return (_HeaderLength = length); @@ -99,7 +99,7 @@ namespace Kneesocks { return returnValue; } - public static int HeaderSizeFromBytes(byte[] raw) { + public static int HeaderLengthFromBytes(byte[] raw) { if(raw.Length < 2) throw new FormatException("Need first two bytes to analyze"); @@ -107,7 +107,7 @@ namespace Kneesocks { return 2 + ((raw[1] & 0x80) != 0 ? 4: 0) + (lengthByte == 0x7E ? 2 : 0) - + (lengthByte == 0x7F ? 4 : 0); + + (lengthByte == 0x7F ? 8 : 0); } public static Frame HeaderFromBytes(byte[] raw) { @@ -131,12 +131,12 @@ namespace Kneesocks { ? 1 : (bodyLength == 0x7E ? 3 : 9); - if(raw.Length < headerOffset + 1) + if(raw.Length < headerOffset + 1 + (returnFrame.IsMasked ? 4 : 0)) throw new FormatException("Websocket frame is smaller than expected header size"); - bodyLength = bodyLength < 0x7E ? 0 : bodyLength; - for(var i = headerOffset - 1; i > 0; --i) - bodyLength |= (ulong)raw[2 + i] << (8 * (headerOffset - 1 - i)); + if(bodyLength >= 0x7E) + bodyLength = bodyLength == 0x7E ? raw.Subset(2, 2).UnpackUInt16() + : raw.Subset(2, 8).UnpackUInt64(); if(bodyLength > Int32.MaxValue) throw new FormatException("Frame is too large to interpret"); @@ -153,7 +153,7 @@ namespace Kneesocks { var returnFrame = HeaderFromBytes(raw); uint expectedFrameLength = (uint)returnFrame.BodyLength + (uint)returnFrame.HeaderLength; - if(expectedFrameLength < (uint)raw.Length) + if((uint)raw.Length < expectedFrameLength) throw new FormatException("Raw frame length ("+ (uint)raw.Length + ") is less than described size ("+ expectedFrameLength + ")"); returnFrame.Content = new byte[returnFrame.BodyLength]; diff --git a/server/Libraries/Kneesocks/ReadBuffer.cs b/server/Libraries/Kneesocks/ReadBuffer.cs index 5cbc3d5..bfae2f1 100644 --- a/server/Libraries/Kneesocks/ReadBuffer.cs +++ b/server/Libraries/Kneesocks/ReadBuffer.cs @@ -7,6 +7,8 @@ using System.Threading.Tasks; namespace Kneesocks { class ReadBuffer { + private const int BufferSize = 1024; + private List Buffer; private int ExpectedLength; private string ExpectedString; @@ -52,21 +54,21 @@ namespace Kneesocks { if(!IsReading) return null; + if(!Source.CanRead) + return null; + byte[] returnValue; if((returnValue = CheckBuffer()) != null) return returnValue; - var buffer = new byte[1024]; + var buffer = new byte[BufferSize]; while(Source.DataAvailable) { var readAmount = ExpectedString == null - ? Math.Min(1024, ExpectedLength - Buffer.Count) - : 1024; + ? Math.Min(BufferSize, ExpectedLength - Buffer.Count) + : BufferSize; var bytesRead = Source.Read(buffer, 0, readAmount); - if(bytesRead == readAmount) - Buffer.AddRange(buffer); - else - Buffer.AddRange(buffer.Take(readAmount)); + Buffer.AddRange(bytesRead == BufferSize ? buffer : buffer.Take(bytesRead)); if((returnValue = CheckBuffer()) != null) return returnValue; diff --git a/server/Libraries/Kneesocks/Stack.cs b/server/Libraries/Kneesocks/Stack.cs index b36e3bc..df9fac6 100644 --- a/server/Libraries/Kneesocks/Stack.cs +++ b/server/Libraries/Kneesocks/Stack.cs @@ -11,7 +11,6 @@ namespace Kneesocks { private List Clients = new List(); private bool RunWithNoClients = false; private bool Running = true; - private bool _finished = false; public Stack(Pool poolRef, Connection initialConnection = null) { PoolRef = poolRef; @@ -48,7 +47,13 @@ namespace Kneesocks { while(Running && (Count > 0 || RunWithNoClients)) { for(var i = Count - 1; i >= 0 && Running; --i) { var client = Clients[i]; - client.Parse(); + if(!client.Disconnected) + client.Parse(); + else { + lock(Clients) { + Clients.RemoveAt(i); + } + } } }