Example #1
0
        private void Dispose(bool disposing)
        {
            _isDisposed = true;

            if (disposing)
            {
                if (_socketState != null)
                {
                    _socketState.Dispose();
                }
            }
        }
Example #2
0
        private void OnSent(IAsyncResult async)
        {
            SocketState state = (SocketState)async.AsyncState;

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

            try {
                int sent = state.Socket.EndSend(async);
                Log(Category, String.Format("Sent {0} byte response to: {1}:{2}", sent, ((IPEndPoint)state.Socket.RemoteEndPoint).Address, ((IPEndPoint)state.Socket.RemoteEndPoint).Port));
            } catch (SocketException e) {
                switch (e.SocketErrorCode)
                {
                case SocketError.ConnectionReset:
                case SocketError.Disconnecting:
                    return;

                default:
                    LogError(Category, "Error sending data");
                    LogError(Category, String.Format("{0} {1}", e.SocketErrorCode, e));
                    return;
                }
            } finally {
                state.Dispose();
                state = null;
            }
        }
Example #3
0
        private void SendToClient(SocketState state, byte[] data)
        {
            if (state == null)
            {
                return;
            }

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

            if (_socketSendCallback == null)
            {
                _socketSendCallback = OnSent;
            }

            try {
                state.Socket.BeginSend(data, 0, data.Length, SocketFlags.None, _socketSendCallback, state);
            } catch (SocketException e) {
                LogError(Category, "Error sending data");
                LogError(Category, String.Format("{0} {1}", e.SocketErrorCode, e));
            }
        }
        private void OnSent(IAsyncResult async)
        {
            SocketState state = (SocketState)async.AsyncState;

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

            try
            {
                int sent = state.Socket.EndSend(async);
                Logger.Info($"Sent {sent} byte response to: {((IPEndPoint)state.Socket.RemoteEndPoint).Address}:{((IPEndPoint)state.Socket.RemoteEndPoint).Port}");
            }
            catch (SocketException e)
            {
                switch (e.SocketErrorCode)
                {
                case SocketError.ConnectionReset:
                case SocketError.Disconnecting:
                    return;

                default:
                    Logger.Error(e, $"Error sending data. SocketErrorCode: {e.SocketErrorCode}");
                    return;
                }
            }
            finally
            {
                state.Dispose();
                state = null;
            }
        }
        private void SendToClient(SocketState state, byte[] data)
        {
            if (state == null)
            {
                return;
            }

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

            try
            {
                state.Socket.BeginSend(data, 0, data.Length, SocketFlags.None, OnSent, state);
            }
            catch (SocketException e)
            {
                Logger.Error(e, $"Error sending data. SocketErrorCode: {e.SocketErrorCode}");
            }
        }
Example #6
0
        private 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)
                {
                    // when EndReceive returns 0, it means the socket on the other end has been shut down.
                    return;
                }

                // take what we received, and append it to the received data buffer
                state.ReceivedData.Append(Encoding.UTF8.GetString(state.Buffer, 0, received));
                string receivedData = state.ReceivedData.ToString();

                // does what we received end with \x00\x00\x00\x00\x??
                if (receivedData.Substring(receivedData.Length - 5, 4) == "\x00\x00\x00\x00")
                {
                    state.ReceivedData.Clear();

                    // lets split up the message based on the delimiter
                    string[] messages = receivedData.Split(new string[] { "\x00\x00\x00\x00" }, StringSplitOptions.RemoveEmptyEntries);

                    for (int i = 0; i < messages.Length; i++)
                    {
                        if (messages[i].StartsWith("battlefield2"))
                        {
                            if (ParseRequest(state, messages[i]))
                            {
                                return;
                            }
                        }
                    }
                }
            } 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...
            WaitForData(state);
        }
        private void SendToClient(SocketState state, byte[] data)
        {
            if (state == null)
                return;

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

            if (_socketSendCallback == null)
                _socketSendCallback = OnSent;

            try {
                state.Socket.BeginSend(data, 0, data.Length, SocketFlags.None, _socketSendCallback, state);
            } catch (SocketException e) {
                LogError(Category, "Error sending data");
                LogError(Category, String.Format("{0} {1}", e.SocketErrorCode, e));
            }
        }
        private 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)
                {
                    // when EndReceive returns 0, it means the socket on the other end has been shut down.
                    return;
                }

                var receivedString = Encoding.ASCII.GetString(state.Buffer, 0, received);

                Logger.Info($"Data received: {receivedString}");
                ParseRequest(state, receivedString);
            }
            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...
            WaitForData(state);
        }
Example #9
0
 public void OnApplicationQuit()
 {
     client.Dispose();
 }
Example #10
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);
        }
Example #11
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);
        }
        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;

                var input = Encoding.UTF8.GetString(XorBytes(buffer, 0, received - 7, XorKEY), 0, received);

                Logger.Info($"Receive data from the socket: {input}");

                if (input.StartsWith(@"\auth\\gamename\"))
                {
                    var sesskey = Interlocked.Increment(ref _sessionCounter).ToString("0000000000");

                    SendToClient(state, $@"\lc\2\sesskey\{sesskey}\proof\0\id\1\final\");

                    goto CONTINUE;
                }

                if (input.StartsWith(@"\authp\\pid\"))
                {
                    try
                    {
                        var pid = GetPidFromInput(input, 12);
                        var profileId = long.Parse(pid);

                        state.ProfileId = profileId;
                        state.Nick = Database.UsersDBInstance.GetProfileById(profileId).Name;

                        SendToClient(state, $@"\pauthr\{pid}\lid\1\final\");
                    }
                    catch (Exception)
                    {
                        state.Dispose();
                        return;
                    }

                    goto CONTINUE;
                }

                if (input.StartsWith(@"\getpd\"))
                {
                    // \\getpd\\\\pid\\87654321\\ptype\\3\\dindex\\0\\keys\\\u0001points\u0001points2\u0001points3\u0001stars\u0001games\u0001wins\u0001disconn\u0001a_durat\u0001m_streak\u0001f_race\u0001SM_wins\u0001Chaos_wins\u0001Ork_wins\u0001Tau_wins\u0001SoB_wins\u0001DE_wins\u0001Eldar_wins\u0001IG_wins\u0001Necron_wins\u0001lsw\u0001rnkd_vics\u0001con_rnkd_vics\u0001team_vics\u0001mdls1\u0001mdls2\u0001rg\u0001pw\\lid\\1\\final\\
                    // \getpd\\pid\87654321\ptype\3\dindex\0\keys\pointspoints2points3starsgameswinsdisconna_duratm_streakf_raceSM_winsChaos_winsOrk_winsTau_winsSoB_winsDE_winsEldar_winsIG_winsNecron_winslswrnkd_vicscon_rnkd_vicsteam_vicsmdls1mdls2rgpw\lid\1\final\
                    var pid = GetPidFromInput(input, 12);

                    var keysIndex = input.IndexOf("keys") + 5;
                    var keys = input.Substring(keysIndex);
                    var keysList = keys.Split(new string[] { "\u0001", "\\lid\\1\\final\\", "final", "\\", "lid" }, StringSplitOptions.RemoveEmptyEntries );

                    var keysResult = new StringBuilder();
                    var stats = ProfilesCache.GetProfileByPid(pid);

                    for (int i = 0; i < keysList.Length; i++)
                    {
                        var key = keysList[i];

                        keysResult.Append("\\"+key+"\\");

                        switch (key)
                        {
                            case "points": keysResult.Append(stats.Score1v1); break;
                            case "points2": keysResult.Append(stats.Score2v2); break;
                            case "points3": keysResult.Append(stats.Score3v3); break;

                            case "stars": keysResult.Append(stats.StarsCount); break;

                            case "games": keysResult.Append(stats.GamesCount); break;
                            case "wins": keysResult.Append(stats.WinsCount); break;
                            case "disconn": keysResult.Append(stats.Disconnects); break;
                            case "a_durat": keysResult.Append(stats.AverageDuractionTicks); break;
                            case "m_streak": keysResult.Append(stats.Best1v1Winstreak); break;

                            case "f_race": keysResult.Append(stats.FavouriteRace); break;

                            case "SM_wins": keysResult.Append(stats.Smwincount); break;
                            case "Chaos_wins": keysResult.Append(stats.Csmwincount); break;
                            case "Ork_wins": keysResult.Append(stats.Orkwincount); break;
                            case "Tau_wins": keysResult.Append(stats.Tauwincount); break;
                            case "SoB_wins": keysResult.Append(stats.Sobwincount); break;
                            case "DE_wins": keysResult.Append(stats.Dewincount); break;
                            case "Eldar_wins": keysResult.Append(stats.Eldarwincount); break;
                            case "IG_wins": keysResult.Append(stats.Igwincount); break;
                            case "Necron_wins": keysResult.Append(stats.Necrwincount); break;
                            /*case "lsw": keysResult.Append("123"); break;
                            case "rnkd_vics": keysResult.Append("50"); break;
                            case "con_rnkd_vics": keysResult.Append("200"); break;
                            case "team_vics": keysResult.Append("250"); break;
                            case "mdls1": keysResult.Append("260"); break;
                            case "mdls2": keysResult.Append("270"); break;
                            case "rg": keysResult.Append("280"); break;
                            case "pw": keysResult.Append("290"); break;*/
                            default:
                                keysResult.Append("0");
                                break;
                        }

                    }

                    SendToClient(state, $@"\getpdr\1\lid\1\pid\{pid}\mod\{stats.Modified}\length\{keys.Length}\data\{keysResult}\final\");

                    goto CONTINUE;
                }

                if (input.StartsWith(@"\setpd\"))
                {
                    var pid = GetPidFromInput(input, 12);

                    var lidIndex = input.IndexOf("\\lid\\", StringComparison.OrdinalIgnoreCase);
                    var lid = input.Substring(lidIndex+5, 1);

                    var timeInSeconds = (ulong)((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds);

                    SendToClient(state, $@"\setpdr\1\lid\{lid}\pid\{pid}\mod\{timeInSeconds}\final\");

                    goto CONTINUE;
                }

                if (input.StartsWith(@"\updgame\"))
                {
                    Task.Factory.StartNew(() =>
                    {
                        var gamedataIndex = input.IndexOf("gamedata");
                        var finalIndex = input.IndexOf("final");

                        var gameDataString = input.Substring(gamedataIndex + 9, finalIndex - gamedataIndex - 10);

                        var valuesList = gameDataString.Split(new string[] { "\u0001", "\\lid\\1\\final\\", "final", "\\", "lid" }, StringSplitOptions.RemoveEmptyEntries);

                        var dictionary = new Dictionary<string, string>();

                        for (int i = 0; i < valuesList.Length; i += 2)
                            dictionary[valuesList[i]] = valuesList[i + 1];

                        var playersCount = int.Parse(dictionary["Players"]);

                        for (int i = 0; i < playersCount; i++)
                        {
                            // Dont process games with AI
                            if (dictionary["PHuman_" + i] != "1")
                                return;
                        }

                        var gameInternalSession = dictionary["SessionID"];
                        var teamsCount = int.Parse(dictionary["Teams"]);
                        var version = dictionary["Version"];
                        var mod = dictionary["Mod"];
                        var modVersion = dictionary["ModVer"];

                        var uniqueGameSessionBuilder = new StringBuilder(gameInternalSession);

                        for (int i = 0; i < playersCount; i++)
                        {
                            uniqueGameSessionBuilder.Append('<');
                            uniqueGameSessionBuilder.Append(dictionary["player_" + i]);
                            uniqueGameSessionBuilder.Append('>');
                        }

                        var uniqueSession = uniqueGameSessionBuilder.ToString();

                        if (!HandledGamesCache.Add(uniqueSession, uniqueSession, new CacheItemPolicy() { SlidingExpiration = TimeSpan.FromDays(1) }))
                        {
                            return;
                        }

                        var usersGameInfos = new GameUserInfo[playersCount];

                        GameUserInfo currentUserInfo = null;

                        for (int i = 0; i < playersCount; i++)
                        {
                            var nick = dictionary["player_"+i];

                            var info = new GameUserInfo
                            {
                                Profile = ProfilesCache.GetProfileByName(nick),
                                Race = Enum.Parse<Race>(dictionary["PRace_" + i], true),
                                Team = int.Parse(dictionary["PTeam_" + i]),
                                FinalState = Enum.Parse<PlayerFinalState>(dictionary["PFnlState_" + i]),
                            };

                            usersGameInfos[i] = info;

                            if (nick.Equals(state.Nick, StringComparison.Ordinal))
                                currentUserInfo = info;
                        }

                        var teams = usersGameInfos.GroupBy(x => x.Team).ToDictionary(x => x.Key, x => x.ToArray());
                        var gameDuration = long.Parse(dictionary["Duration"]);

                        foreach (var team in teams)
                        {
                            for (int i = 0; i < team.Value.Length; i++)
                            {
                                var info = team.Value[i];

                                info.Profile.AllInGameTicks += gameDuration;

                                switch (info.Race)
                                {
                                    case Race.space_marine_race:
                                        info.Profile.Smgamescount++;
                                        break;
                                    case Race.chaos_marine_race:
                                        info.Profile.Csmgamescount++;
                                        break;
                                    case Race.ork_race:
                                        info.Profile.Orkgamescount++;
                                        break;
                                    case Race.eldar_race:
                                        info.Profile.Eldargamescount++;
                                        break;
                                    case Race.guard_race:
                                        info.Profile.Iggamescount++;
                                        break;
                                    case Race.necron_race:
                                        info.Profile.Necrgamescount++;
                                        break;
                                    case Race.tau_race:
                                        info.Profile.Taugamescount++;
                                        break;
                                    case Race.dark_eldar_race:
                                        info.Profile.Degamescount++;
                                        break;
                                    case Race.sisters_race:
                                        info.Profile.Sobgamescount++;
                                        break;
                                    default:
                                        break;
                                }

                                if (info.FinalState == PlayerFinalState.Winner)
                                {
                                    switch (info.Race)
                                    {
                                        case Race.space_marine_race:
                                            info.Profile.Smwincount++;
                                            break;
                                        case Race.chaos_marine_race:
                                            info.Profile.Csmwincount++;
                                            break;
                                        case Race.ork_race:
                                            info.Profile.Orkwincount++;
                                            break;
                                        case Race.eldar_race:
                                            info.Profile.Eldarwincount++;
                                            break;
                                        case Race.guard_race:
                                            info.Profile.Igwincount++;
                                            break;
                                        case Race.necron_race:
                                            info.Profile.Necrwincount++;
                                            break;
                                        case Race.tau_race:
                                            info.Profile.Tauwincount++;
                                            break;
                                        case Race.dark_eldar_race:
                                            info.Profile.Dewincount++;
                                            break;
                                        case Race.sisters_race:
                                            info.Profile.Sobwincount++;
                                            break;
                                        default:
                                            break;
                                    }
                                }
                            }
                        }

                        bool isRateGame = false;

                        if (ChatServer.IrcDaemon.Users.TryGetValue(state.ProfileId, out UserInfo chatUserInfo))
                        {
                            var game = chatUserInfo.Game;
                            isRateGame = game != null && game.Clean();

                            // For rated games
                            if (isRateGame)
                            {
                                Console.WriteLine("UPDATE RATING GAME " + uniqueSession);

                                chatUserInfo.Game = null;

                                var usersInGame = game.UsersInGame;

                                if (usersGameInfos.Select(x => x.Profile.Id).OrderBy(x => x).SequenceEqual(usersInGame.OrderBy(x => x)))
                                {
                                    // Update winstreaks for 1v1 only
                                    if (usersInGame.Length == 2)
                                    {
                                        UpdateStreak(usersGameInfos[0]);
                                        UpdateStreak(usersGameInfos[1]);
                                    }

                                    var groupedTeams = usersGameInfos.GroupBy(x => x.Team).Select(x => x.ToArray()).ToArray();

                                    var players1Team = groupedTeams[0];
                                    var players2Team = groupedTeams[1];

                                    Func<ProfileData, long> scoreSelector = null;
                                    Action<ProfileData, long> scoreUpdater = null;

                                    ReatingGameType type = ReatingGameType.Unknown;

                                    switch (usersInGame.Length)
                                    {
                                        case 2:
                                            scoreSelector = StatsDelegates.Score1v1Selector;
                                            scoreUpdater = StatsDelegates.Score1v1Updated;
                                            type = ReatingGameType.Rating1v1;
                                            break;
                                        case 4:
                                            scoreSelector = StatsDelegates.Score2v2Selector;
                                            scoreUpdater = StatsDelegates.Score2v2Updated;
                                            type = ReatingGameType.Rating2v2;
                                            break;
                                        case 6:
                                        case 8:
                                            type = ReatingGameType.Rating3v3_4v4;
                                            scoreSelector = StatsDelegates.Score3v3Selector;
                                            scoreUpdater = StatsDelegates.Score3v3Updated;
                                            break;
                                        default:
                                            goto UPDATE;
                                    }

                                    var team0score = (long)players1Team.Average(x => scoreSelector(x.Profile));
                                    var team1score = (long)players2Team.Average(x => scoreSelector(x.Profile));

                                    var isFirstTeamResult = players1Team.Any(x => x.FinalState == PlayerFinalState.Winner);
                                    var delta = EloRating.CalculateELOdelta(team0score, team1score, isFirstTeamResult ? EloRating.GameOutcome.Win : EloRating.GameOutcome.Loss);

                                    for (int i = 0; i < players1Team.Length; i++)
                                    {
                                        players1Team[i].Delta = delta;
                                        players1Team[i].RatingGameType = type;
                                        scoreUpdater(players1Team[i].Profile, Math.Max(1000L, scoreSelector(players1Team[i].Profile) + delta));
                                    }

                                    for (int i = 0; i < players2Team.Length; i++)
                                    {
                                        players2Team[i].Delta = -delta;
                                        players2Team[i].RatingGameType = type;
                                        scoreUpdater(players2Team[i].Profile, Math.Max(1000L, scoreSelector(players2Team[i].Profile) - delta));
                                    }
                                }
                            }
                        }

                    UPDATE:
                        for (int i = 0; i < usersGameInfos.Length; i++)
                        {
                            var info = usersGameInfos[i];
                            var profile = info.Profile;
                            ProfilesCache.UpdateProfilesCache(profile);
                            Database.UsersDBInstance.UpdateProfileData(profile);

                            if (info.Delta != 0)
                            {
                                Task.Delay(5000).ContinueWith(task =>
                                {
                                    switch (info.RatingGameType)
                                    {
                                        case ReatingGameType.Unknown:
                                            break;
                                        case ReatingGameType.Rating1v1:
                                            ChatServer.IrcDaemon.SendToUser(profile.Id, $@"Ваш рейтинг 1v1 изменился на {GetDeltaString(info.Delta)} и сейчас равен {info.Profile.Score1v1}.");
                                            break;
                                        case ReatingGameType.Rating2v2:
                                            ChatServer.IrcDaemon.SendToUser(profile.Id, $@"Ваш рейтинг 2v2 изменился на {GetDeltaString(info.Delta)} и сейчас равен {info.Profile.Score2v2}.");
                                            break;
                                        case ReatingGameType.Rating3v3_4v4:
                                            ChatServer.IrcDaemon.SendToUser(profile.Id, $@"Ваш рейтинг 3v3/4v4 изменился на {GetDeltaString(info.Delta)} и сейчас равен {info.Profile.Score3v3}.");
                                            break;
                                        default:
                                            break;
                                    }
                                });
                            }
                        }

                        Dowstats.UploadGame(dictionary, usersGameInfos, isRateGame);
                    }, CancellationToken.None, TaskCreationOptions.LongRunning | TaskCreationOptions.PreferFairness, _exclusiveScheduler);

                    goto CONTINUE;
                }
            }
            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);
        }
Example #13
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;

                var input = Encoding.UTF8.GetString(XorBytes(buffer, 0, received - 7, XorKEY), 0, received);

                Log(Category, input);

                if (input.StartsWith(@"\auth\\gamename\"))
                {
                    var sesskey = Interlocked.Increment(ref _sessionCounter).ToString("0000000000");

                    SendToClient(state, $@"\lc\2\sesskey\{sesskey}\proof\0\id\1\final\");

                    goto CONTINUE;
                }

                if (input.StartsWith(@"\authp\\pid\"))
                {
                    //var clientData = LoginDatabase.Instance.GetData(state.Name);


                    // \authp\\pid\87654321\resp\67512e365ba89497d60963caa4ce23d4\lid\1\final\

                    // \authp\\pid\87654321\resp\7e2270c581e8daf5a5321ff218953035\lid\1\final\

                    var pid = input.Substring(12, 9);

                    state.ProfileId = long.Parse(pid);

                    SendToClient(state, $@"\pauthr\{pid}\lid\1\final\");
                    //SendToClient(state, @"\pauthr\-3\lid\1\errmsg\helloworld\final\");
                    //SendToClient(state, @"\pauthr\100000004\lid\1\final\");

                    goto CONTINUE;
                }


                if (input.StartsWith(@"\getpd\"))
                {
                    // \\getpd\\\\pid\\87654321\\ptype\\3\\dindex\\0\\keys\\\u0001points\u0001points2\u0001points3\u0001stars\u0001games\u0001wins\u0001disconn\u0001a_durat\u0001m_streak\u0001f_race\u0001SM_wins\u0001Chaos_wins\u0001Ork_wins\u0001Tau_wins\u0001SoB_wins\u0001DE_wins\u0001Eldar_wins\u0001IG_wins\u0001Necron_wins\u0001lsw\u0001rnkd_vics\u0001con_rnkd_vics\u0001team_vics\u0001mdls1\u0001mdls2\u0001rg\u0001pw\\lid\\1\\final\\
                    // \getpd\\pid\87654321\ptype\3\dindex\0\keys\pointspoints2points3starsgameswinsdisconna_duratm_streakf_raceSM_winsChaos_winsOrk_winsTau_winsSoB_winsDE_winsEldar_winsIG_winsNecron_winslswrnkd_vicscon_rnkd_vicsteam_vicsmdls1mdls2rgpw\lid\1\final\
                    var pid = input.Substring(12, 9);

                    var keysIndex = input.IndexOf("keys") + 5;
                    var keys      = input.Substring(keysIndex);
                    var keysList  = keys.Split(new string[] { "\u0001", "\\lid\\1\\final\\", "final", "\\", "lid" }, StringSplitOptions.RemoveEmptyEntries);

                    var keysResult = new StringBuilder();
                    var stats      = UsersDatabase.Instance.GetStatsDataByProfileId(long.Parse(pid));

                    var gamesCount = stats.GamesCount;
                    var stars      = Math.Min(5, gamesCount);

                    for (int i = 0; i < keysList.Length; i++)
                    {
                        var key = keysList[i];

                        keysResult.Append("\\" + key + "\\");

                        switch (key)
                        {
                        case "points": keysResult.Append(stats.Score1v1); break;

                        case "points2": keysResult.Append(stats.Score2v2); break;

                        case "points3": keysResult.Append(stats.Score3v3); break;

                        case "stars": keysResult.Append(stars); break;

                        case "games": keysResult.Append(gamesCount); break;

                        case "wins": keysResult.Append(stats.WinsCount); break;

                        case "disconn": keysResult.Append(stats.Disconnects); break;

                        case "a_durat": keysResult.Append(stats.AverageDuractionTicks); break;

                        case "m_streak": keysResult.Append(stats.Best1v1Winstreak); break;

                        case "f_race": keysResult.Append(stats.FavouriteRace); break;

                        case "SM_wins": keysResult.Append(stats.Smwincount); break;

                        case "Chaos_wins": keysResult.Append(stats.Csmwincount); break;

                        case "Ork_wins": keysResult.Append(stats.Orkwincount); break;

                        case "Tau_wins": keysResult.Append(stats.Tauwincount); break;

                        case "SoB_wins": keysResult.Append(stats.Sobwincount); break;

                        case "DE_wins": keysResult.Append(stats.Dewincount); break;

                        case "Eldar_wins": keysResult.Append(stats.Eldarwincount); break;

                        case "IG_wins": keysResult.Append(stats.Igwincount); break;

                        case "Necron_wins": keysResult.Append(stats.Necrwincount); break;

                        /*case "lsw": keysResult.Append("123"); break;
                         * case "rnkd_vics": keysResult.Append("50"); break;
                         * case "con_rnkd_vics": keysResult.Append("200"); break;
                         * case "team_vics": keysResult.Append("250"); break;
                         * case "mdls1": keysResult.Append("260"); break;
                         * case "mdls2": keysResult.Append("270"); break;
                         * case "rg": keysResult.Append("280"); break;
                         * case "pw": keysResult.Append("290"); break;*/
                        default:
                            keysResult.Append("0");
                            break;
                        }
                    }

                    SendToClient(state, $@"\getpdr\1\lid\1\pid\{pid}\mod\{stats.Modified}\length\{keys.Length}\data\{keysResult}\final\");

                    goto CONTINUE;
                }

                if (input.StartsWith(@"\setpd\"))
                {
                    var pid = input.Substring(12, 9);

                    var lidIndex = input.IndexOf("\\lid\\", StringComparison.OrdinalIgnoreCase);
                    var lid      = input.Substring(lidIndex + 5, 1);

                    var timeInSeconds = (ulong)((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds);

                    SendToClient(state, $@"\setpdr\1\lid\{lid}\pid\{pid}\mod\{timeInSeconds}\final\");

                    goto CONTINUE;
                }

                if (input.StartsWith(@"\updgame\"))
                {
                    var gamedataIndex = input.IndexOf("gamedata");
                    var finalIndex    = input.IndexOf("final");

                    var gameDataString = input.Substring(gamedataIndex + 9, finalIndex - gamedataIndex - 10);

                    var valuesList = gameDataString.Split(new string[] { "\u0001", "\\lid\\1\\final\\", "final", "\\", "lid" }, StringSplitOptions.RemoveEmptyEntries);

                    var dictionary = new Dictionary <string, string>();

                    for (int i = 0; i < valuesList.Length; i += 2)
                    {
                        dictionary[valuesList[i]] = valuesList[i + 1];
                    }

                    var playersCount = int.Parse(dictionary["Players"]);

                    for (int i = 0; i < playersCount; i++)
                    {
                        // Dont process games with AI
                        if (dictionary["PHuman_" + i] != "1")
                        {
                            goto CONTINUE;
                        }
                    }

                    var gameInternalSession = dictionary["SessionID"];
                    var teamsCount          = int.Parse(dictionary["Teams"]);
                    var version             = dictionary["Version"];
                    var mod        = dictionary["Mod"];
                    var modVersion = dictionary["ModVer"];


                    var uniqueGameSessionBuilder = new StringBuilder(gameInternalSession);

                    for (int i = 0; i < playersCount; i++)
                    {
                        uniqueGameSessionBuilder.Append('<');
                        uniqueGameSessionBuilder.Append(dictionary["PID_" + i]);
                        uniqueGameSessionBuilder.Append('>');
                    }

                    var uniqueSession = uniqueGameSessionBuilder.ToString();

                    if (!HandledGamesCache.Add(uniqueSession, uniqueSession, new CacheItemPolicy()
                    {
                        SlidingExpiration = TimeSpan.FromDays(1)
                    }))
                    {
                        goto CONTINUE;
                    }

                    var usersGameInfos = new GameUserInfo[playersCount];

                    GameUserInfo currentUserInfo = null;

                    for (int i = 0; i < playersCount; i++)
                    {
                        //var nick = dictionary["player_"+i];
                        var pid = long.Parse(dictionary["PID_" + i]);

                        var info = new GameUserInfo()
                        {
                            Stats      = UsersDatabase.Instance.GetStatsDataByProfileId(pid),
                            Race       = (Race)Enum.Parse(typeof(Race), dictionary["PRace_" + i], true),
                            Team       = int.Parse(dictionary["PTeam_" + i]),
                            FinalState = (PlayerFinalState)Enum.Parse(typeof(PlayerFinalState), dictionary["PFnlState_" + i]),
                        };

                        usersGameInfos[i] = info;

                        if (pid == state.ProfileId)
                        {
                            currentUserInfo = info;
                        }
                    }

                    var teams        = usersGameInfos.GroupBy(x => x.Team).ToDictionary(x => x.Key, x => x.ToArray());
                    var gameDuration = long.Parse(dictionary["Duration"]);

                    foreach (var team in teams)
                    {
                        for (int i = 0; i < team.Value.Length; i++)
                        {
                            var info = team.Value[i];

                            info.Stats.AllInGameTicks += gameDuration;

                            switch (info.Race)
                            {
                            case Race.space_marine_race:
                                info.Stats.Smgamescount++;
                                break;

                            case Race.chaos_marine_race:
                                info.Stats.Csmgamescount++;
                                break;

                            case Race.ork_race:
                                info.Stats.Orkgamescount++;
                                break;

                            case Race.eldar_race:
                                info.Stats.Eldargamescount++;
                                break;

                            case Race.guard_race:
                                info.Stats.Iggamescount++;
                                break;

                            case Race.necron_race:
                                info.Stats.Necrgamescount++;
                                break;

                            case Race.tau_race:
                                info.Stats.Taugamescount++;
                                break;

                            case Race.dark_eldar_race:
                                info.Stats.Degamescount++;
                                break;

                            case Race.sisters_race:
                                info.Stats.Sobgamescount++;
                                break;

                            default:
                                break;
                            }

                            if (info.FinalState == PlayerFinalState.Winner)
                            {
                                switch (info.Race)
                                {
                                case Race.space_marine_race:
                                    info.Stats.Smwincount++;
                                    break;

                                case Race.chaos_marine_race:
                                    info.Stats.Csmwincount++;
                                    break;

                                case Race.ork_race:
                                    info.Stats.Orkwincount++;
                                    break;

                                case Race.eldar_race:
                                    info.Stats.Eldarwincount++;
                                    break;

                                case Race.guard_race:
                                    info.Stats.Igwincount++;
                                    break;

                                case Race.necron_race:
                                    info.Stats.Necrwincount++;
                                    break;

                                case Race.tau_race:
                                    info.Stats.Tauwincount++;
                                    break;

                                case Race.dark_eldar_race:
                                    info.Stats.Dewincount++;
                                    break;

                                case Race.sisters_race:
                                    info.Stats.Sobwincount++;
                                    break;

                                default:
                                    break;
                                }
                            }
                        }
                    }

                    var chatUserInfo = ChatServer.IrcDaemon.Users[state.ProfileId];
                    var game         = chatUserInfo.Game;

                    // For rated games
                    if (game != null && game.Clean())
                    {
                        chatUserInfo.Game = null;

                        var usersInGame = game.UsersInGame;

                        if (usersGameInfos.Select(x => x.Stats.ProfileId).OrderBy(x => x).SequenceEqual(usersInGame.OrderBy(x => x)))
                        {
                            // Update winstreaks for 1v1 only
                            if (usersInGame.Length == 2)
                            {
                                UpdateStreak(usersGameInfos[0]);
                                UpdateStreak(usersGameInfos[1]);
                            }

                            var groupedTeams = usersGameInfos.GroupBy(x => x.Team).Select(x => x.ToArray()).ToArray();

                            var players1Team = groupedTeams[0];
                            var players2Team = groupedTeams[1];

                            Func <StatsData, long>   scoreSelector = null;
                            Action <StatsData, long> scoreUpdater  = null;

                            switch (usersInGame.Length)
                            {
                            case 2:
                                scoreSelector = StatsDelegates.Score1v1Selector;
                                scoreUpdater  = StatsDelegates.Score1v1Updated;
                                break;

                            case 4:
                                scoreSelector = StatsDelegates.Score2v2Selector;
                                scoreUpdater  = StatsDelegates.Score2v2Updated;
                                break;

                            case 6:
                            case 8:
                                scoreSelector = StatsDelegates.Score3v3Selector;
                                scoreUpdater  = StatsDelegates.Score3v3Updated;
                                break;

                            default: goto UPDATE;
                            }

                            var team0score = (long)players1Team.Average(x => scoreSelector(x.Stats));
                            var team1score = (long)players2Team.Average(x => scoreSelector(x.Stats));

                            var isFirstTeamResult = players1Team.Any(x => x.FinalState == PlayerFinalState.Winner);
                            var delta             = EloRating.CalculateELOdelta(team0score, team1score, isFirstTeamResult? EloRating.GameOutcome.Win : EloRating.GameOutcome.Loss);

                            //if (isFirstTeamResult)
                            //{
                            for (int i = 0; i < players1Team.Length; i++)
                            {
                                scoreUpdater(players1Team[i].Stats, Math.Max(1000L, scoreSelector(players1Team[i].Stats) + delta));
                            }

                            for (int i = 0; i < players2Team.Length; i++)
                            {
                                scoreUpdater(players2Team[i].Stats, Math.Max(1000L, scoreSelector(players1Team[i].Stats) - delta));
                            }

                            /*}
                             * else
                             * {
                             *  for (int i = 0; i < players1Team.Length; i++)
                             *      scoreUpdater(players1Team[i].Stats, scoreSelector(players1Team[i].Stats) + delta);
                             *
                             *  for (int i = 0; i < players2Team.Length; i++)
                             *      scoreUpdater(players1Team[i].Stats, scoreSelector(players1Team[i].Stats) - delta);
                             * }*/
                        }
                    }

UPDATE:
                    for (int i = 0; i < usersGameInfos.Length; i++)
                    {
                        UsersDatabase.Instance.UpdateUserStats(usersGameInfos[i].Stats);
                    }
                }
            }
            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 : WaitForData(state);
        }