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); }