public override byte[] Encode(WsPacket data)
        {
            List <byte> result = new List <byte> {
                (byte)(128 + data.GetOpCode())
            };

            byte[] payloadBytes = Encoding.UTF8.GetBytes(data.GetPayload());

            result.AddRange(CalculateSize(payloadBytes.Length));
            result.AddRange(payloadBytes);
            //Logger.Debug(string.Join(" ", result));

            return(result.ToArray());
        }
        private async Task <Packet> ProcessPacket(byte[] data)
        {
            string str = Encoding.UTF8.GetString(data);

            if (Regex.IsMatch(str, "^GET"))
            {
                requestHeader          = new RequestHeader(str);
                requestHeader.resource = requestHeader.resource.Replace("/csf-websocket-url", "");
                Logger.Info($"Requesting resource: {requestHeader.resource}");

                string ip1 = tcpclient.Client.RemoteEndPoint.ToString();

                string[] ip_parts = ip1.Split(".");

                Logger.Info($"IP: {ip1}");
                Logger.Debug($"Recieved header: {str}");

                if (ip_parts[0] != "172" && ip_parts[0] != "127")
                {
                    ResponseHeader respheader = new ResponseHeader {
                        responseCode = HttpCodes.OK
                    };
                    await Send(respheader);
                    await Send("Hello World!");

                    stillOk = false;
                }
                else if (requestHeader.parameters.ContainsKey("Sec-WebSocket-Key"))
                {
                    ResponseHeader respheader = new ResponseHeader {
                        responseCode = HttpCodes.SwitchingProtocols
                    };
                    respheader.parameters["Server"]               = "CSF-Websocket";
                    respheader.parameters["Connection"]           = "Upgrade";
                    respheader.parameters["Upgrade"]              = "websocket";
                    respheader.parameters["Sec-WebSocket-Accept"] = GenerateSecWebSocketKey(requestHeader.parameters["Sec-WebSocket-Key"]);

                    try {
                        if (requestHeader.parameters.ContainsKey("Sec-WebSocket-Extensions"))
                        {
                            Logger.Info($"Supported extensions: {requestHeader.parameters["Sec-WebSocket-Extensions"]}");
                            Chiper = StreamCipher.Factory(requestHeader.parameters["Sec-WebSocket-Extensions"]);
                        }
                        else
                        {
                            Chiper = StreamCipher.Factory("permessage-deflate");
                        }

                        if (requestHeader.parameters.ContainsKey("Sec-WebSocket-Protocol"))
                        {
                            string[] options = requestHeader.parameters["Sec-WebSocket-Protocol"].Split(",");
                            foreach (string option_raw in options)
                            {
                                string option = option_raw.Trim();
                                if (option.Contains("csf-socket-"))
                                {
                                    respheader.parameters["Sec-WebSocket-Protocol"] = option;
                                }
                            }
                        }
                        await Send(respheader);
                        await SendHello();
                    } catch (UnsupportedExtension) {
                        ResponseHeader invext = new ResponseHeader {
                            responseCode = HttpCodes.NotAcceptable
                        };
                        await Send(invext);
                        await Send("The requested websokcet extension is not supported");

                        stillOk = false;
                    }
                }
                else
                {
                    ResponseHeader respheader = new ResponseHeader {
                        responseCode = HttpCodes.UpgradeRequired
                    };
                    await Send(respheader);
                    await Send("This is not a website! Upgrade your connection to WebSocket");

                    stillOk = false;
                }
            }
            else
            {
                WsPacket WebSocketPacket = Chiper.Decode(data);
                OpCode   opcode          = WebSocketPacket.GetOpCode();
                if (opcode == OpCode.TextFrame)
                {
                    string pstr = WebSocketPacket.GetPayload();
                    try {
                        Packet     p    = new Packet(pstr);
                        PacketType type = p.GetPacketType();

                        if (type == PacketType.Heartbeat)
                        {
                            HeartBeatNow();
                            Packet ack = new Packet(PacketType.HeartbeatACK);
                            await Send(ack);

                            return(null);
                        }
                        else if (type == PacketType.Reconnect)
                        {
                            Reconnect rp = p.GetPacketData <Reconnect>();
                            if (UsedSessions.Contains(rp.session_id))
                            {
                                this.session = rp.session_id;
                                await SendHello();
                            }
                            else
                            {
                                Packet invsess = new Packet(PacketType.InvalidSession);
                                await Send(invsess);

                                stillOk = false;
                            }
                            return(null);
                        }
                        else if (type == PacketType.Identify)
                        {
                            identity = p.GetPacketData <Identity>();
                        }
                        else
                        {
                            if (identity == null)
                            {
                                stillOk = false;
                                return(null);
                            }
                        }

                        return(p);
                    } catch (Exception e) {
                        Logger.Error($"Packet conversion error: {e.Message}");
                        Logger.Error($"Receied data: {string.Join(" ", data)}");
                        Logger.Error($"Decoded: {pstr}");
                        Logger.Error($"{e.StackTrace}");
                    }
                }
                else if (opcode == OpCode.Ping)
                {
                    Logger.Debug("Ping Pong");
                    WsPacket pong = new WsPacket(OpCode.Pong);
                    await Send(pong);
                }
            }
            return(null);
        }