private void Dispose(bool disposing) { _isDisposed = true; if (disposing) { if (_socketState != null) { _socketState.Dispose(); } } }
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; } }
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}"); } }
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); }
public void OnApplicationQuit() { client.Dispose(); }
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); }
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); }
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); }