Exemplo n.º 1
0
        private unsafe void SendToGameSocket(ref SocketState state, byte[] bytes)
        {
            try
            {
                if (state.Disposing)
                {
                    return;
                }

                //  Log(Category, "SERVER RESR: " + Encoding.UTF8.GetString(bytes));

                if (state.ReceivingEncoded)
                {
                    fixed(byte *bytesToSendPtr = bytes)
                    ChatCrypt.GSEncodeDecode(state.SendingGameKey, bytesToSendPtr, bytes.Length);
                }

                state.GameSocket.Send(bytes, bytes.Length, SocketFlags.None);
            }
            catch (Exception ex)
            {
                LogError(Category, "Error receiving data");
                LogError(Category, ex.ToString());
            }
        }
Exemplo n.º 2
0
        public override void ConstructResponse()
        {
            base.ConstructResponse();

            // 2. Prepare two keys
            ChatCrypt.Init(_session.UserInfo.ClientCTX, ChatServer.ClientKey, _session.UserInfo.GameSecretKey);
            ChatCrypt.Init(_session.UserInfo.ServerCTX, ChatServer.ServerKey, _session.UserInfo.GameSecretKey);

            // 3. Response the crypt command
            _sendingBuffer = _cryptCmd.BuildResponse(ChatServer.ClientKey, ChatServer.ServerKey);
        }
Exemplo n.º 3
0
        private unsafe void SendToServerSocket(ref SocketState state, byte[] bytes)
        {
            if (state.Disposing)
            {
                return;
            }

            if (state.SendingEncoded)
            {
                fixed(byte *bytesToSendPtr = bytes)
                ChatCrypt.GSEncodeDecode(state.SendingServerKey, bytesToSendPtr, bytes.Length);
            }

            _serverSocket.Send(bytes, bytes.Length, SocketFlags.None);
        }
Exemplo n.º 4
0
        protected override void DataOperation()
        {
            base.DataOperation();

            string secretKey;

            if (!DataOperationExtensions.GetSecretKey(_request.GameName, out secretKey) ||
                secretKey == null)
            {
                LogWriter.ToLog(LogEventLevel.Error, "secret key not found!");
                _errorCode = ChatError.UnSupportedGame;
                return;
            }
            _session.UserInfo.SetGameSecretKey(secretKey);
            _session.UserInfo.SetGameName(_request.GameName);
            // 2. Prepare two keys
            ChatCrypt.Init(_session.UserInfo.ClientCTX, ChatServer.ClientKey, _session.UserInfo.GameSecretKey);
            ChatCrypt.Init(_session.UserInfo.ServerCTX, ChatServer.ServerKey, _session.UserInfo.GameSecretKey);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Elevates security, for use with CRYPT method.
        /// </summary>
        public void ElevateSecurity(string secretKey)
        {
            string Info = $"{ServerName} Elevating security for user {Id} with game {chatUserInfo.gameName}";

            ToLog(Info);

            // 1. Generate the two keys
            string clientKey = GameSpyRandom.GenerateRandomString(16, GameSpyRandom.StringType.Alpha);
            string serverKey = GameSpyRandom.GenerateRandomString(16, GameSpyRandom.StringType.Alpha);

            // 2. Prepare two keys
            ChatCrypt.Init(chatUserInfo.ClientCTX, clientKey, secretKey);
            ChatCrypt.Init(chatUserInfo.ServerCTX, serverKey, secretKey);

            // 3. Response the crypt command
            SendCommand(ChatRPL.SecureKey, "* " + clientKey + " " + serverKey);

            // 4. Start using encrypted connection
            chatUserInfo.encrypted = true;
        }
Exemplo n.º 6
0
        private unsafe int SendToClient(object abstractState, string message)
        {
            var state = (SocketState)abstractState;

            if (state.Disposing)
            {
                return(0);
            }

            Log("CHATRESP", message);

            var bytesToSend = Encoding.UTF8.GetBytes(message);

            if (state.Encoded)
            {
                fixed(byte *bytesToSendPtr = bytesToSend)
                ChatCrypt.GSEncodeDecode(state.ServerKey, bytesToSendPtr, bytesToSend.Length);
            }

            SendToClient(ref state, bytesToSend);
            return(bytesToSend.Length);
        }
Exemplo n.º 7
0
        private unsafe void SendToServerSocket(ref SocketState state, byte[] bytes)
        {
            try
            {
                if (state.Disposing)
                {
                    return;
                }

                if (state.SendingEncoded)
                {
                    fixed(byte *bytesToSendPtr = bytes)
                    ChatCrypt.GSEncodeDecode(state.SendingServerKey, bytesToSendPtr, bytes.Length);
                }

                _serverSocket.Send(bytes, bytes.Length, SocketFlags.None);
            }
            catch (Exception ex)
            {
                LogError(Category, "Error receiving data");
                LogError(Category, ex.ToString());
            }
        }
Exemplo n.º 8
0
        private unsafe int SendToClient(object abstractState, string message)
        {
            var state = (SocketState)abstractState;

            if (state.Disposing)
            {
                return(0);
            }

            Logger.Info($"CHATRESP: {message}");

            var bytesToSend = Encoding.UTF8.GetBytes(message);


            if (state.Encoded)
            {
                fixed(byte *bytesToSendPtr = bytesToSend)
                {
                    ChatCrypt.GSEncodeDecode(state.ServerKey, bytesToSendPtr, bytesToSend.Length);
                }

                /* var clone = new byte[bytesToSend.Length];
                 *
                 * for (int i = 0; i < bytesToSend.Length; i++)
                 *   clone[i] = bytesToSend[i];
                 *
                 * fixed (byte* bytesToSendPtr = clone)
                 * {
                 *   ChatCrypt.GSEncodeDecode(state.ServerKeyClone, bytesToSendPtr, bytesToSend.Length);
                 * }
                 *
                 * var val = Encoding.UTF8.GetString(clone);*/
            }

            SendToClient(ref state, bytesToSend);
            return(bytesToSend.Length);
        }
Exemplo n.º 9
0
 private void EncryptData(ref byte[] buffer, long size)
 {
     ChatCrypt.Handle(chatUserInfo.ServerCTX, ref buffer, size);
 }
Exemplo n.º 10
0
 private void DecryptData(ref byte[] data, long size)
 {
     ChatCrypt.Handle(chatUserInfo.ClientCTX, ref data, size);
 }
        private static byte[] PackServerList(SocketState state, IEnumerable <Data.GameServer> servers, string[] fields, bool isAutomatch)
        {
            IPEndPoint  remoteEndPoint = ((IPEndPoint)state.Socket.RemoteEndPoint);
            List <byte> data           = new List <byte>();

            data.AddRange(remoteEndPoint.Address.GetAddressBytes());

            byte[] value2 = BitConverter.GetBytes((ushort)remoteEndPoint.Port);
            data.AddRange(BitConverter.IsLittleEndian ? value2.Reverse() : value2);

            if (fields.Length == 1 && fields[0] == "\u0004")
            {
                fields = new string[0];
            }

            data.Add((byte)fields.Length);
            data.Add(0);

            foreach (var field in fields)
            {
                data.AddRange(Encoding.UTF8.GetBytes(field));
                data.AddRange(new byte[] { 0, 0 });
            }

            PortBindingManager.ClearPortBindings();

            foreach (var server in servers)
            {
                if (server.Properties.TryGetValue("gamename", out string gamename))
                {
                    if (isAutomatch && gamename != "whamdowfram")
                    {
                        continue;
                    }

                    if (!isAutomatch && gamename != "whamdowfr")
                    {
                        continue;
                    }
                }

                // commented this stuff out since it caused some issues on testing, might come back to it later and see what's happening...
                // NAT traversal stuff...
                // 126 (\x7E)	= public ip / public port / private ip / private port / icmp ip
                // 115 (\x73)	= public ip / public port / private ip / private port
                // 85 (\x55)	= public ip / public port
                // 81 (\x51)	= public ip / public port

                var    localip0  = server.Get <string>("localip0");
                ushort localport = ushort.Parse(server.Get <string>("localport") ?? "0");
                var    queryPort = (ushort)server.Get <int>("QueryPort");
                var    iPAddress = server.Get <string>("IPAddress");

                var retranslator = PortBindingManager.AddOrUpdatePortBinding(server.HostSteamId);

                retranslator.AttachedServer = server;

                ushort retranslationPort = retranslator.Port;



                var channelHash = ChatCrypt.PiStagingRoomHash("127.0.0.1", "127.0.0.1", retranslationPort);

                // start connection establishment
                SteamNetworking.SendP2PPacket(server.HostSteamId, new byte[] { 0 }, 1, EP2PSend.k_EP2PSendReliable, 1);

                IDByChannelCache[channelHash]        = server.HostSteamId;
                ChannelByIDCache[server.HostSteamId] = channelHash;

                var retranslationPortBytes = BitConverter.IsLittleEndian ? BitConverter.GetBytes(retranslationPort).Reverse() : BitConverter.GetBytes(retranslationPort);

                server["hostport"]  = retranslationPort.ToString();
                server["localport"] = retranslationPort.ToString();

                var flags = ServerFlags.UNSOLICITED_UDP_FLAG |
                            ServerFlags.PRIVATE_IP_FLAG |
                            ServerFlags.NONSTANDARD_PORT_FLAG |
                            ServerFlags.NONSTANDARD_PRIVATE_PORT_FLAG |
                            ServerFlags.HAS_KEYS_FLAG;

                var loopbackIpBytes = IPAddress.Loopback.GetAddressBytes();

                data.Add((byte)flags);
                data.AddRange(loopbackIpBytes);
                data.AddRange(retranslationPortBytes);
                data.AddRange(loopbackIpBytes);
                data.AddRange(retranslationPortBytes);

                data.Add(255);

                for (int i = 0; i < fields.Length; i++)
                {
                    var name = fields[i];
                    var f    = GetField(server, name);

                    data.AddRange(Encoding.UTF8.GetBytes(f));

                    if (i < fields.Length - 1)
                    {
                        data.Add(0);
                        data.Add(255);
                    }
                }

                data.Add(0);
            }

            data.Add(0);
            data.Add(255);
            data.Add(255);
            data.Add(255);
            data.Add(255);

            return(data.ToArray());
        }
Exemplo n.º 12
0
        private unsafe void OnGameDataReceived(IAsyncResult async)
        {
            SocketState state = (SocketState)async.AsyncState;

            if (state == null || state.GameSocket == null || !state.GameSocket.Connected)
            {
                return;
            }

            try
            {
                // receive data from the socket
                int received = state.GameSocket.EndReceive(async);

                if (received == 0)
                {
                    return;
                }

                var buffer = state.GameBuffer;

                using (var ms = new MemoryStream(buffer, 0, received))
                {
                    if (!state.SendingEncoded)
                    {
                        using (var reader = new StreamReader(ms))
                        {
                            var asciValue = reader.ReadToEnd();

                            Log("CHATDATA", asciValue);

                            ms.Position = 0;

                            var line = reader.ReadLine();

                            if (line.StartsWith("CRYPT"))
                            {
                                state.SendingEncoded = true;

                                /*if (line.Contains("whammer40kdc"))
                                 * {
                                 *  Gamename = "whammer40kdc".ToAssciiBytes();
                                 *  Gamekey = "Ue9v3H".ToAssciiBytes();
                                 * }*/

                                if (line.Contains("whamdowfr"))
                                {
                                    Gamename = "whamdowfr".ToAssciiBytes();
                                    Gamekey  = "pXL838".ToAssciiBytes();
                                }

                                if (Gamekey == null)
                                {
                                    state.Dispose();
                                    return;
                                }

                                var chall = "0000000000000000".ToAssciiBytes();

                                var receivingGameKey   = new ChatCrypt.GDCryptKey();
                                var sendingGameKey     = new ChatCrypt.GDCryptKey();
                                var receivingServerKey = new ChatCrypt.GDCryptKey();
                                var sendingServerKey   = new ChatCrypt.GDCryptKey();

                                fixed(byte *challPtr = chall)
                                {
                                    fixed(byte *gamekeyPtr = Gamekey)
                                    {
                                        ChatCrypt.GSCryptKeyInit(receivingGameKey, challPtr, gamekeyPtr, Gamekey.Length);
                                        ChatCrypt.GSCryptKeyInit(sendingGameKey, challPtr, gamekeyPtr, Gamekey.Length);
                                        ChatCrypt.GSCryptKeyInit(receivingServerKey, challPtr, gamekeyPtr, Gamekey.Length);
                                        ChatCrypt.GSCryptKeyInit(sendingServerKey, challPtr, gamekeyPtr, Gamekey.Length);
                                    }
                                }

                                state.ReceivingGameKey   = receivingGameKey;
                                state.SendingGameKey     = sendingGameKey;
                                state.ReceivingServerKey = receivingServerKey;
                                state.SendingServerKey   = sendingServerKey;

                                // Send to server without encoding
                                _serverSocket.Send(buffer, received, SocketFlags.None);
                            }
                            else
                            {
                                // Send to server without encoding
                                _serverSocket.Send(buffer, received, SocketFlags.None);
                            }
                        }
                    }
                    else
                    {
                        using (var reader = new BinaryReader(ms, Encoding.ASCII))
                        {
                            var start = ms.Position;

                            var bytes = reader.ReadBytes((int)(ms.Length - ms.Position));

                            if (state.SendingEncoded)
                            {
                                byte *bytesPtr = stackalloc byte[bytes.Length];

                                for (int i = 0; i < bytes.Length; i++)
                                {
                                    bytesPtr[i] = bytes[i];
                                }

                                ChatCrypt.GSEncodeDecode(state.ReceivingGameKey, bytesPtr, bytes.Length);

                                for (int i = 0; i < bytes.Length; i++)
                                {
                                    bytes[i] = bytesPtr[i];
                                }
                            }

                            var utf8value = Encoding.UTF8.GetString(bytes);

                            Log("CHATDATA", utf8value);

                            if (utf8value.StartsWith("LOGIN", StringComparison.OrdinalIgnoreCase))
                            {
                                var nick = utf8value.Split(' ')[2];

                                ChatNick = nick;

                                SendToServerSocket(ref state, bytes);

                                goto CONTINUE;
                            }

                            if (utf8value.StartsWith("USRIP", StringComparison.OrdinalIgnoreCase))
                            {
                                SendToServerSocket(ref state, bytes);

                                goto CONTINUE;
                            }

                            var hostAddressIndex = utf8value.IndexOf(HOST_ADDRESS_TOKEN, StringComparison.OrdinalIgnoreCase);

                            if (hostAddressIndex != -1)
                            {
                                var port = CutPortValue(utf8value, hostAddressIndex + HOST_ADDRESS_TOKEN.Length, out string portString);

                                port = ByteHelpers.ReverseEndian16(port);

                                var hostSteamId = PortBindingManager.GetSteamIdByPort(port);

                                if (!hostSteamId.HasValue)
                                {
                                    port        = ByteHelpers.ReverseEndian16(port);
                                    hostSteamId = PortBindingManager.GetSteamIdByPort(port);
                                }

                                if (hostSteamId.HasValue)
                                {
                                    utf8value = utf8value.Replace(HOST_ADDRESS_TOKEN + portString, HOST_ADDRESS_TOKEN + hostSteamId.Value.m_SteamID);
                                }
                            }

                            var index = utf8value.IndexOf("#GSP!whamdowfr!", StringComparison.OrdinalIgnoreCase);

                            if (index != -1)
                            {
                                var encodedEndPoint = utf8value.Substring(index + 15, 10);

                                CSteamID steamId;

                                if (ServerListReport.CurrentUserRoomHash == encodedEndPoint)
                                {
                                    steamId = SteamUser.GetSteamID();
                                }
                                else
                                {
                                    if (!ServerListRetrieve.IDByChannelCache.TryGetValue(encodedEndPoint, out steamId))
                                    {
                                        ServerListReport.CurrentUserRoomHash = encodedEndPoint;
                                        steamId = SteamUser.GetSteamID();
                                    }
                                }

                                utf8value = utf8value.Replace(encodedEndPoint, steamId.m_SteamID.ToString());

                                SendToServerSocket(ref state, Encoding.UTF8.GetBytes(utf8value));

                                goto CONTINUE;
                            }

                            //  16777343 ~ 1.0.0.127  inversed port 63349 port
                            // :QWEQWE!X44vf1Wf1X|[email protected] PRIVMSG elamaunt :ACTION 7; 16777343; 63349; 16777343; 63349; 1;

                            SendToServerSocket(ref state, bytes);
                        }
                    }
                }
            }
            catch (ObjectDisposedException)
            {
                if (state != null)
                {
                    state.Dispose();
                }
                state = null;
                return;
            }
            catch (SocketException e)
            {
                switch (e.SocketErrorCode)
                {
                case SocketError.ConnectionReset:
                    if (state != null)
                    {
                        state.Dispose();
                    }
                    state = null;
                    return;

                case SocketError.Disconnecting:
                    if (state != null)
                    {
                        state.Dispose();
                    }
                    state = null;
                    return;

                default:
                    LogError(Category, "Error receiving data");
                    LogError(Category, String.Format("{0} {1}", e.SocketErrorCode, e));
                    if (state != null)
                    {
                        state.Dispose();
                    }
                    state = null;
                    return;
                }
            }
            catch (Exception e)
            {
                LogError(Category, "Error receiving data");
                LogError(Category, e.ToString());
            }

            // and we wait for more data...
            CONTINUE : WaitForGameData(state);
        }
Exemplo n.º 13
0
        private unsafe void OnServerDataReceived(IAsyncResult async)
        {
            SocketState state = (SocketState)async.AsyncState;

            if (state == null || _serverSocket == null || !_serverSocket.Connected || state.GameSocket == null || !state.GameSocket.Connected)
            {
                return;
            }

            try
            {
                // receive data from the socket
                int received = _serverSocket.EndReceive(async);

                if (received == 0)
                {
                    return;
                }

                var bytes = new byte[received];

                for (int i = 0; i < received; i++)
                {
                    bytes[i] = state.ServerBuffer[i];
                }

                if (state.ReceivingEncoded)
                {
                    fixed(byte *bytesToSendPtr = bytes)
                    ChatCrypt.GSEncodeDecode(state.ReceivingServerKey, bytesToSendPtr, received);
                }

                var utf8value = Encoding.UTF8.GetString(bytes);

                Log(Category, utf8value);

                if (utf8value.StartsWith(":s 705", StringComparison.OrdinalIgnoreCase))
                {
                    SendToGameSocket(ref state, bytes);

                    state.ReceivingEncoded = true;
                    goto CONTINUE;
                }

                if (utf8value.IndexOf($@"UTM #GSP!whamdowfr!", StringComparison.OrdinalIgnoreCase) != -1)
                {
                    ProcessHelper.RestoreGameWindow();
                }

                if (utf8value.StartsWith("ROOMCOUNTERS", StringComparison.OrdinalIgnoreCase))
                {
                    var values = utf8value.Split(new string[] { "ROOMCOUNTERS", " ", "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

                    for (int i = 0; i < ChatRoomPlayersCounts.Length; i++)
                    {
                        ChatRoomPlayersCounts[i] = 0;
                    }

                    for (int i = 0; i < values.Length; i += 2)
                    {
                        var roomIndex = values[i];
                        var count     = values[i + 1];

                        ChatRoomPlayersCounts[int.Parse(roomIndex) - 1] = int.Parse(count);
                    }
                    goto CONTINUE;
                }

                var index = utf8value.IndexOf("#GSP!whamdowfr!", StringComparison.OrdinalIgnoreCase);

                if (index != -1)
                {
                    int endIndex = index + 15;
                    for (; endIndex < utf8value.Length; endIndex++)
                    {
                        if (!char.IsDigit(utf8value[endIndex]))
                        {
                            break;
                        }
                    }

                    var stringSteamId = utf8value.Substring(index + 15, endIndex - index - 15);
                    var steamId       = new CSteamID(ulong.Parse(stringSteamId));

                    if (steamId != SteamUser.GetSteamID())
                    {
                        if (ServerListRetrieve.ChannelByIDCache.TryGetValue(steamId, out string roomHash))
                        {
                            utf8value = utf8value.Replace(stringSteamId, ServerListRetrieve.ChannelByIDCache[steamId]);
                        }
                        else
                        {
                            utf8value = utf8value.Replace(stringSteamId, ServerListReport.CurrentUserRoomHash);
                        }
                    }
                    else
                    {
                        utf8value = utf8value.Replace(stringSteamId, ServerListReport.CurrentUserRoomHash);
                    }

                    SendToGameSocket(ref state, Encoding.UTF8.GetBytes(utf8value));

                    goto CONTINUE;
                }

                var hostAddressIndex = utf8value.IndexOf(HOST_ADDRESS_TOKEN, StringComparison.OrdinalIgnoreCase);

                if (hostAddressIndex != -1)
                {
                    var steamIdValue = CutULongValue(utf8value, hostAddressIndex + HOST_ADDRESS_TOKEN.Length, out string idString);

                    if (steamIdValue <= 65536)
                    {
                        return;
                    }

                    var hostSteamId = new CSteamID(steamIdValue);
                    var port        = PortBindingManager.AddOrUpdatePortBinding(hostSteamId).Port;

                    utf8value = utf8value.Replace(HOST_ADDRESS_TOKEN + idString, HOST_ADDRESS_TOKEN + port.ToString());

                    SendToGameSocket(ref state, Encoding.UTF8.GetBytes(utf8value));

                    goto CONTINUE;
                }

                SendToGameSocket(ref state, bytes);
            }

            catch (Exception e)
            {
                LogError(Category, "Error receiving data");
                LogError(Category, e.ToString());
            }

            // and we wait for more data...
            CONTINUE : WaitForServerData(state);
        }
Exemplo n.º 14
0
        private unsafe void OnDataReceived(IAsyncResult async)
        {
            SocketState state = (SocketState)async.AsyncState;

            if (state == null || state.Socket == null || !state.Socket.Connected)
            {
                return;
            }

            try
            {
                // receive data from the socket
                int received = state.Socket.EndReceive(async);

                if (received == 0)
                {
                    return;
                }

                var buffer = state.Buffer;

                using (var ms = new MemoryStream(buffer, 0, received))
                {
                    if (!state.Encoded)
                    {
                        using (var reader = new StreamReader(ms))
                        {
                            var asciValue = reader.ReadToEnd();

                            Logger.Info($"CHATDATA: {asciValue}");

                            ms.Position = 0;

                            var line = reader.ReadLine();

                            if (line.StartsWith("CRYPT", StringComparison.OrdinalIgnoreCase))
                            {
                                state.Encoded = true;

                                if (line.Contains("whammer40kdc"))
                                {
                                    Gamename = "whammer40kdc".ToAssciiBytes();
                                    Gamekey  = "Ue9v3H".ToAssciiBytes();
                                }

                                if (line.Contains("whamdowfr"))
                                {
                                    Gamename = "whamdowfr".ToAssciiBytes();
                                    Gamekey  = "pXL838".ToAssciiBytes();
                                }

                                if (Gamekey == null)
                                {
                                    state.Dispose();
                                    return;
                                }

                                var chall = "0000000000000000".ToAssciiBytes();

                                var clientKey      = new ChatCrypt.GDCryptKey();
                                var serverKey      = new ChatCrypt.GDCryptKey();
                                var serverKeyClone = new ChatCrypt.GDCryptKey();

                                fixed(byte *challPtr = chall)
                                {
                                    fixed(byte *gamekeyPtr = Gamekey)
                                    {
                                        ChatCrypt.GSCryptKeyInit(clientKey, challPtr, gamekeyPtr, Gamekey.Length);
                                        ChatCrypt.GSCryptKeyInit(serverKey, challPtr, gamekeyPtr, Gamekey.Length);
                                        ChatCrypt.GSCryptKeyInit(serverKeyClone, challPtr, gamekeyPtr, Gamekey.Length);
                                    }
                                }

                                state.ClientKey      = clientKey;
                                state.ServerKey      = serverKey;
                                state.ServerKeyClone = serverKeyClone;

                                SendToClient(ref state, DataFunctions.StringToBytes(":s 705 * 0000000000000000 0000000000000000\r\n"));
                            }
                            else
                            {
                                IrcDaemon.ProcessSocketMessage(state.UserInfo, asciValue);
                            }
                        }
                    }
                    else
                    {
                        using (var reader = new BinaryReader(ms, Encoding.ASCII))
                        {
                            var start = ms.Position;

                            var bytes = reader.ReadBytes((int)(ms.Length - ms.Position));

                            byte *bytesPtr = stackalloc byte[bytes.Length];

                            for (int i = 0; i < bytes.Length; i++)
                            {
                                bytesPtr[i] = bytes[i];
                            }

                            ChatCrypt.GSEncodeDecode(state.ClientKey, bytesPtr, bytes.Length);

                            for (int i = 0; i < bytes.Length; i++)
                            {
                                bytes[i] = bytesPtr[i];
                            }

                            var utf8alue = Encoding.UTF8.GetString(bytes);

                            Logger.Info($"CHATDATA: {utf8alue}");

                            if (utf8alue.StartsWith("LOGIN", StringComparison.OrdinalIgnoreCase))
                            {
                                var nick = utf8alue.Split(' ')[2];

                                var profile = Database.MainDBInstance.GetProfileByName(nick);

                                state.UserInfo = IrcDaemon.RegisterNewUser(state.Socket, nick, profile.Id, state, SendToClient);

                                var bytesToSend = $":s 707 {nick} 12345678 {profile.Id}\r\n".ToAssciiBytes();

                                fixed(byte *bytesToSendPtr = bytesToSend)
                                ChatCrypt.GSEncodeDecode(state.ServerKey, bytesToSendPtr, bytesToSend.Length);

                                SendToClient(ref state, bytesToSend);

                                goto CONTINUE;
                            }

                            if (utf8alue.StartsWith("USRIP", StringComparison.OrdinalIgnoreCase))
                            {
                                var remoteEndPoint = ((IPEndPoint)state.Socket.RemoteEndPoint);

                                var bytesToSend = $":s 302  :=+@{remoteEndPoint.Address}\r\n".ToAssciiBytes();

                                fixed(byte *bytesToSendPtr = bytesToSend)
                                ChatCrypt.GSEncodeDecode(state.ServerKey, bytesToSendPtr, bytesToSend.Length);

                                SendToClient(ref state, bytesToSend);

                                goto CONTINUE;
                            }

                            IrcDaemon.ProcessSocketMessage(state.UserInfo, utf8alue);
                        }
                    }
                }
            }
            catch (ObjectDisposedException)
            {
                if (state != null)
                {
                    state.Dispose();
                }
                state = null;
                return;
            }
            catch (SocketException e)
            {
                switch (e.SocketErrorCode)
                {
                case SocketError.ConnectionReset:
                    if (state != null)
                    {
                        state.Dispose();
                    }
                    state = null;
                    return;

                case SocketError.Disconnecting:
                    if (state != null)
                    {
                        state.Dispose();
                    }
                    state = null;
                    return;

                default:
                    Logger.Error(e, $"Error receiving data. SocketErrorCode: {e.SocketErrorCode}");
                    if (state != null)
                    {
                        state.Dispose();
                    }
                    state = null;
                    return;
                }
            }
            catch (Exception e)
            {
                Logger.Error(e, "Error receiving data");
            }

            // and we wait for more data...
            CONTINUE : WaitForData(state);
        }