/// <summary> /// Initializes a new instance of the <see cref="ClientGCMsg<BodyType>"/> class. /// This is a recieve constructor. /// </summary> /// <param name="msg">The packet message to build this gc message from.</param> public ClientGCMsg(IPacketGCMsg msg) : this() { DebugLog.Assert(!msg.IsProto, "ClientGCMsg", "ClientGCMsg used for proto message!"); Deserialize(msg.GetData()); }
void ITXIMLoginUIEventExt.OnServerPwd2(ITXData pData, out string pbsEnterCode, out int pbCancel) { pbsEnterCode = string.Empty; pbCancel = 1; DebugLog.Assert(false, "Server要求输入二级密码"); TXLog.TXLog2("Login", "Server要求输入二级密码"); }
private void OnSort(object sender, EventArgs args) { if (this.BuddyList != null) { foreach (BuddyGroup group in this.BuddyList) { ICollectionView defaultView = CollectionViewSource.GetDefaultView(group); if (defaultView == null) { DebugLog.Assert(false, "严重错误,必看"); } else { if (defaultView.SortDescriptions.Count != 3) { defaultView.SortDescriptions.Clear(); defaultView.SortDescriptions.Add(new SortDescription("PresenceInfo.PresenceWeight", ListSortDirection.Descending)); defaultView.SortDescriptions.Add(new SortDescription("QQMemberWeight", ListSortDirection.Descending)); defaultView.SortDescriptions.Add(new SortDescription("NickName", ListSortDirection.Ascending)); continue; } defaultView.Refresh(); } } } }
private bool ReauthConnection(CDNClient client, CDNClient.Server server, uint depotId, byte[] depotKey) { DebugLog.Assert(server.Type == "CDN" || steamSession.AppTickets[depotId] == null, "CDNClientPool", "Re-authing a CDN or anonymous connection"); String cdnAuthToken = null; if (server.Type == "CDN") { steamSession.RequestCDNAuthToken(depotId, server.Host); cdnAuthToken = steamSession.CDNAuthTokens[Tuple.Create(depotId, server.Host)].Token; } try { client.AuthenticateDepot(depotId, depotKey, cdnAuthToken); activeClientAuthed[client] = Tuple.Create(depotId, server); return(true); } catch (Exception ex) { Console.WriteLine("Failed to reauth to content server {0}: {1}", server, ex.Message); } return(false); }
void Disconnected(object?sender, DisconnectedEventArgs e) { var connectionRelease = Interlocked.Exchange(ref connection, null); if (connectionRelease == null) { return; } IsConnected = false; if (!e.UserInitiated && !ExpectDisconnection) { DebugLog.Assert(connectionRelease.CurrentEndPoint != null, nameof(CMClient), "No connection endpoint while disconnecting - cannot update server list"); Servers.TryMark(connectionRelease.CurrentEndPoint !, connectionRelease.ProtocolTypes, ServerQuality.Bad); } SessionID = null; SteamID = null; connectionRelease.NetMsgReceived -= NetMsgReceived; connectionRelease.Connected -= Connected; connectionRelease.Disconnected -= Disconnected; heartBeatFunc.Stop(); OnClientDisconnected(userInitiated: e.UserInitiated || ExpectDisconnection); }
/// <summary> /// Processes the specified depot key by decrypting the data with the given depot encryption key, and then by decompressing the data. /// If the chunk has already been processed, this function does nothing. /// </summary> /// <param name="depotKey">The depot decryption key.</param> /// <exception cref="System.IO.InvalidDataException">Thrown if the processed data does not match the expected checksum given in it's chunk information.</exception> public void Process(byte[] depotKey) { if (depotKey == null) { throw new ArgumentNullException(nameof(depotKey)); } if (IsProcessed) { return; } byte[] processedData = CryptoHelper.SymmetricDecrypt(Data, depotKey); if (processedData.Length > 1 && processedData[0] == 'V' && processedData[1] == 'Z') { processedData = VZipUtil.Decompress(processedData); } else { processedData = ZipUtil.Decompress(processedData); } DebugLog.Assert(ChunkInfo.Checksum != null, nameof(DepotChunk), "Expected data chunk to have a checksum."); byte[] dataCrc = CryptoHelper.AdlerHash(processedData); if (!dataCrc.SequenceEqual(ChunkInfo.Checksum)) { throw new InvalidDataException("Processed data checksum is incorrect! Downloaded depot chunk is corrupt or invalid/wrong depot key?"); } Data = processedData; IsProcessed = true; }
/// <summary> /// Initializes a new instance of the <see cref="ClientGCMsgProtobuf<BodyType>"/> class. /// This is a recieve constructor. /// </summary> /// <param name="msg">The packet message to build this gc message from.</param> public ClientGCMsgProtobuf(IPacketGCMsg msg) : this(msg.MsgType) { DebugLog.Assert(msg.IsProto, "ClientGCMsgProtobuf", "ClientGCMsgProtobuf used for non-proto message!"); Deserialize(msg.GetData()); }
void Connected(object?sender, EventArgs e) { DebugLog.Assert(connection != null, nameof(CMClient), "No connection object after connecting."); DebugLog.Assert(connection.CurrentEndPoint != null, nameof(CMClient), "No connection endpoint after connecting - cannot update server list"); Servers.TryMark(connection.CurrentEndPoint, connection.ProtocolTypes, ServerQuality.Good); IsConnected = true; OnClientConnected(); }
void HandleCMList(IPacketMsg packetMsg) { var cmMsg = new ClientMsgProtobuf <CMsgClientCMList>(packetMsg); DebugLog.Assert(cmMsg.Body.cm_addresses.Count == cmMsg.Body.cm_ports.Count, "CMClient", "HandleCMList received malformed message"); var cmList = cmMsg.Body.cm_addresses .Zip(cmMsg.Body.cm_ports, (addr, port) => new IPEndPoint(NetHelpers.GetIPAddress(addr), ( int )port)); // update our list with steam's list of CMs Servers.MergeWithList(cmList); }
private static void SendRequest(string page, string pageTitle, string category, string action, string label, int?value) { if (!VCSettings.Analytics || !HasInternet()) { return; } string requestURL = GenerateRequestURL(page, pageTitle, category, action, label, value); DebugLog.Assert(!requestURL.Contains(archivedURLSeperator), () => "URL contains the 'archivedURLSeperator'"); requestQueue.Enqueue(requestURL); ProcessRequestQueue(); }
void HandleCMList(IPacketMsg packetMsg) { var cmMsg = new ClientMsgProtobuf <CMsgClientCMList>(packetMsg); DebugLog.Assert(cmMsg.Body.cm_addresses.Count == cmMsg.Body.cm_ports.Count, "CMClient", "HandleCMList received malformed message"); var cmList = cmMsg.Body.cm_addresses .Zip(cmMsg.Body.cm_ports, (addr, port) => ServerRecord.CreateSocketServer(new IPEndPoint(NetHelpers.GetIPAddress(addr), ( int )port))); var webSocketList = cmMsg.Body.cm_websocket_addresses.Select(addr => ServerRecord.CreateWebSocketServer(addr)); // update our list with steam's list of CMs Servers.ReplaceList(cmList.Concat(webSocketList)); }
/// <summary> /// Sends the specified client message to the server. /// This method automatically assigns the correct SessionID and SteamID of the message. /// </summary> /// <param name="msg">The client message to send.</param> public void Send(IClientMsg msg) { if (msg == null) { throw new ArgumentNullException(nameof(msg), "A value for 'msg' must be supplied"); } DebugLog.Assert(IsConnected, nameof(CMClient), "Send() was called while not connected to Steam."); var sessionID = this.SessionID; if (sessionID.HasValue) { msg.SessionID = sessionID.Value; } var steamID = this.SteamID; if (steamID != null) { msg.SteamID = steamID; } var serialized = msg.Serialize(); try { DebugNetworkListener?.OnOutgoingNetworkMessage(msg.MsgType, serialized); } catch (Exception e) { LogDebug("CMClient", "DebugNetworkListener threw an exception: {0}", e); } // we'll swallow any network failures here because they will be thrown later // on the network thread, and that will lead to a disconnect callback // down the line try { connection?.Send(serialized); } catch (IOException) { } catch (SocketException) { } }
private void SetSelection(PasswordBox passwordBox, int start, int length) { try { if (start < 0x0) { start = passwordBox.Password.Length; } passwordBox.GetType().GetMethod("Select", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(passwordBox, new object[] { start, length }); } catch (Exception exception) { DebugLog.Assert(false, exception.Message); passwordBox.SelectAll(); } }
private void OnCommunitiesSort(object sender, EventArgs args) { ICollectionView defaultView = CollectionViewSource.GetDefaultView(InstanceAnswerPro.Core.ComponentManager.GetCommunitiesManager().GetCommunityList()); if (defaultView == null) { DebugLog.Assert(false, "严重错误,必看"); } else if (defaultView.SortDescriptions.Count != 1) { defaultView.SortDescriptions.Clear(); defaultView.SortDescriptions.Add(new SortDescription("CombineName", ListSortDirection.Ascending)); } else { defaultView.Refresh(); } }
private async Task <bool> ReauthConnectionAsync(CDNClient client, CDNClient.Server server, uint appId, uint depotId, byte[] depotKey) { DebugLog.Assert(server.Type == "CDN" || server.Type == "SteamCache" || steamSession.AppTickets[depotId] == null, "CDNClientPool", "Re-authing a CDN or anonymous connection"); String cdnAuthToken = null; try { if (DepotKeyStore.ContainsKey(depotId)) { ((ConcurrentDictionary <uint, byte[]>)(typeof(CDNClient).GetField("depotKeys", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(client))).GetOrAdd(depotId, depotKey); } else { if (server.Type == "CDN" || server.Type == "SteamCache") { steamSession.RequestCDNAuthToken(appId, depotId, server.Host); var cdnKey = string.Format("{0:D}:{1}", depotId, steamSession.ResolveCDNTopLevelHost(server.Host)); SteamApps.CDNAuthTokenCallback authTokenCallback; if (steamSession.CDNAuthTokens.TryGetValue(cdnKey, out authTokenCallback)) { cdnAuthToken = authTokenCallback.Token; } else { throw new Exception(String.Format("Failed to retrieve CDN token for server {0} depot {1}", server.Host, depotId)); } } await client.AuthenticateDepotAsync(depotId, depotKey, cdnAuthToken).ConfigureAwait(false); } activeClientAuthed[client] = Tuple.Create(depotId, server); return(true); } catch (Exception ex) { Console.WriteLine("Failed to reauth to content server {0}: {1}", server, ex.Message); } return(false); }
private void Hyperlink_Click(object sender, RoutedEventArgs e) { Hyperlink hyperlink = sender as Hyperlink; if (hyperlink != null) { HyperLinkObj tag = hyperlink.Tag as HyperLinkObj; if (tag != null) { if (tag is HyperLinkObj_Url) { HyperLinkObj_Url url = tag as HyperLinkObj_Url; BrowserHelper.OpenUrl(BrowserType.System, url.Url); } else { DebugLog.Assert(false, "响应未处理"); } } } }
private async Task <bool> ReauthConnectionAsync(CDNClient client, CDNClient.Server server, uint appId, uint depotId, byte[] depotKey) { DebugLog.Assert(server.Type == "CDN" || server.Type == "SteamCache" || steamSession.AppTickets[depotId] == null, "CDNClientPool", "Re-authing a CDN or anonymous connection"); string cdnAuthToken = null; try { if (server.Type == "CDN" || server.Type == "SteamCache") { await steamSession.RequestCDNAuthToken(appId, depotId, server.Host); var cdnKey = string.Format("{0:D}:{1}", depotId, steamSession.ResolveCDNTopLevelHost(server.Host)); SteamApps.CDNAuthTokenCallback authTokenCallback; if (steamSession.CDNAuthTokens.TryGetValue(cdnKey, out authTokenCallback)) { cdnAuthToken = authTokenCallback.Token; } else { throw new Exception(String.Format("Failed to retrieve CDN token for server {0} depot {1}", server.Host, depotId)); } } await client.AuthenticateDepotAsync(depotId, depotKey, cdnAuthToken).ConfigureAwait(false); //await client.AuthenticateDepotAsync(depotId, depotKey, cdnAuthToken); activeClientAuthed[client] = Tuple.Create(depotId, server); return(true); } catch (Exception ex) { DebugLog.WriteLine("CDNClientPool", "Failed to reauth to content server " + server + ": " + ex.Message); } return(false); }
void HandleEncryptRequest(IPacketMsg packetMsg) { var encRequest = new Msg <MsgChannelEncryptRequest>(packetMsg); EUniverse eUniv = encRequest.Body.Universe; uint protoVersion = encRequest.Body.ProtocolVersion; DebugLog.WriteLine("CMClient", "Got encryption request. Universe: {0} Protocol ver: {1}", eUniv, protoVersion); DebugLog.Assert(protoVersion == 1, "CMClient", "Encryption handshake protocol version mismatch!"); byte[] pubKey = KeyDictionary.GetPublicKey(eUniv); if (pubKey == null) { DebugLog.WriteLine("CMClient", "HandleEncryptionRequest got request for invalid universe! Universe: {0} Protocol ver: {1}", eUniv, protoVersion); return; } ConnectedUniverse = eUniv; var encResp = new Msg <MsgChannelEncryptResponse>(); tempSessionKey = CryptoHelper.GenerateRandomBlock(32); byte[] cryptedSessKey = null; using (var rsa = new RSACrypto(pubKey)) { cryptedSessKey = rsa.Encrypt(tempSessionKey); } byte[] keyCrc = CryptoHelper.CRCHash(cryptedSessKey); encResp.Write(cryptedSessKey); encResp.Write(keyCrc); encResp.Write(( uint )0); this.Send(encResp); }
private protected void Disconnect(bool userInitiated) { lock ( connectionLock ) { heartBeatFunc.Stop(); if (connectionCancellation != null) { connectionCancellation.Cancel(); connectionCancellation.Dispose(); connectionCancellation = null; } var connectionSetupTaskToWait = Interlocked.Exchange(ref connectionSetupTask, null); // though it's ugly, we want to wait for the completion of this task and keep hold of the lock connectionSetupTaskToWait?.GetAwaiter().GetResult(); // Connection implementations are required to issue the Disconnected callback before Disconnect() returns connection?.Disconnect(userInitiated); DebugLog.Assert(connection == null, nameof(CMClient), "Connection was not released in disconnect."); } }
void HandleLoggedOff(IPacketMsg packetMsg) { SessionID = null; SteamID = null; CellID = null; PublicIP = null; IPCountryCode = null; heartBeatFunc.Stop(); if (packetMsg.IsProto) { var logoffMsg = new ClientMsgProtobuf <CMsgClientLoggedOff>(packetMsg); var logoffResult = ( EResult )logoffMsg.Body.eresult; if (logoffResult == EResult.TryAnotherCM || logoffResult == EResult.ServiceUnavailable) { DebugLog.Assert(connection != null, nameof(CMClient), "No connection object during ClientLoggedOff."); DebugLog.Assert(connection.CurrentEndPoint != null, nameof(CMClient), "No connection endpoint during ClientLoggedOff - cannot update server list status"); Servers.TryMark(connection.CurrentEndPoint, connection.ProtocolTypes, ServerQuality.Bad); } } }
void ITXIMLoginUIEventExt.OnServerPwdGuard(ITXData pAskData, ITXData pReplyData, out byte pbOptType) { pbOptType = 0; DebugLog.Assert(false, "Server要求输入密保因子"); TXLog.TXLog2("Login", "Server要求输入密保因子"); }
bool HandleEncryptRequest(IPacketMsg packetMsg) { var encRequest = new Msg <MsgChannelEncryptRequest>(packetMsg); EUniverse eUniv = encRequest.Body.Universe; uint protoVersion = encRequest.Body.ProtocolVersion; DebugLog.WriteLine("CMClient", "Got encryption request. Universe: {0} Protocol ver: {1}", eUniv, protoVersion); DebugLog.Assert(protoVersion == 1, "CMClient", "Encryption handshake protocol version mismatch!"); byte[] randomChallenge; if (encRequest.Payload.Length >= 16) { randomChallenge = encRequest.Payload.ToArray(); } else { randomChallenge = null; } byte[] pubKey = KeyDictionary.GetPublicKey(eUniv); if (pubKey == null) { connection.Disconnect(); DebugLog.WriteLine("CMClient", "HandleEncryptionRequest got request for invalid universe! Universe: {0} Protocol ver: {1}", eUniv, protoVersion); return(false); } ConnectedUniverse = eUniv; var encResp = new Msg <MsgChannelEncryptResponse>(); var tempSessionKey = CryptoHelper.GenerateRandomBlock(32); byte[] encryptedHandshakeBlob = null; using (var rsa = new RSACrypto(pubKey)) { if (randomChallenge != null) { var blobToEncrypt = new byte[tempSessionKey.Length + randomChallenge.Length]; Array.Copy(tempSessionKey, blobToEncrypt, tempSessionKey.Length); Array.Copy(randomChallenge, 0, blobToEncrypt, tempSessionKey.Length, randomChallenge.Length); encryptedHandshakeBlob = rsa.Encrypt(blobToEncrypt); } else { encryptedHandshakeBlob = rsa.Encrypt(tempSessionKey); } } var keyCrc = CryptoHelper.CRCHash(encryptedHandshakeBlob); encResp.Write(encryptedHandshakeBlob); encResp.Write(keyCrc); encResp.Write(( uint )0); if (randomChallenge != null) { pendingNetFilterEncryption = new NetFilterEncryptionWithHMAC(tempSessionKey); } else { pendingNetFilterEncryption = new NetFilterEncryption(tempSessionKey); } this.Send(encResp); return(true); }
void ITXIMLoginUIEventExt.OnServerVerifyFailed(ITXData pData, out int pbRetry) { pbRetry = 0; DebugLog.Assert(false, "server验证失败"); TXLog.TXLog2("Login", "server验证失败"); }
void ITXIMLoginUIEventExt.OnEMBKPic(ITXBuffer pPicBuf) { DebugLog.Assert(false, "收到密保图片"); TXLog.TXLog2("Login", "收到密保图片"); }
void ITXIMLoginUIEventExt.OnGetEMBKPicFailed(out byte pbOptType) { pbOptType = 0; DebugLog.Assert(false, "密保图片图片拉取失败"); TXLog.TXLog2("Login", "密保图片图片拉取失败"); }
void ITXIMLoginUIEventExt.OnMBVerifiedExInfo(ITXData pExData) { DebugLog.Assert(false, "密保返回附带信息"); TXLog.TXLog2("Login", "密保返回附带信息"); }
/// <summary> /// Connects this client to a Steam3 server. /// This begins the process of connecting and encrypting the data channel between the client and the server. /// Results are returned asynchronously in a <see cref="SteamClient.ConnectedCallback"/>. /// If the server that SteamKit attempts to connect to is down, a <see cref="SteamClient.DisconnectedCallback"/> /// will be posted instead. /// SteamKit will not attempt to reconnect to Steam, you must handle this callback and call Connect again /// preferrably after a short delay. /// </summary> /// <param name="cmServer"> /// The <see cref="IPEndPoint"/> of the CM server to connect to. /// If <c>null</c>, SteamKit will randomly select a CM server from its internal list. /// </param> public void Connect(ServerRecord?cmServer = null) { lock ( connectionLock ) { Disconnect(userInitiated: true); DebugLog.Assert(connection == null, nameof(CMClient), "Connection is not null"); DebugLog.Assert(connectionSetupTask == null, nameof(CMClient), "Connection setup task is not null"); DebugLog.Assert(connectionCancellation == null, nameof(CMClient), "Connection cancellation token is not null"); connectionCancellation = new CancellationTokenSource(); var token = connectionCancellation.Token; ExpectDisconnection = false; Task <ServerRecord?> recordTask; if (cmServer == null) { recordTask = Servers.GetNextServerCandidateAsync(Configuration.ProtocolTypes); } else { recordTask = Task.FromResult(( ServerRecord? )cmServer); } connectionSetupTask = recordTask.ContinueWith(t => { if (token.IsCancellationRequested) { LogDebug(nameof(CMClient), "Connection cancelled before a server could be chosen."); OnClientDisconnected(userInitiated: true); return; } else if (t.IsFaulted || t.IsCanceled) { LogDebug(nameof(CMClient), "Server record task threw exception: {0}", t.Exception); OnClientDisconnected(userInitiated: false); return; } var record = t.Result; if (record is null) { LogDebug(nameof(CMClient), "Server record task returned no result."); OnClientDisconnected(userInitiated: false); return; } var newConnection = CreateConnection(record.ProtocolTypes & Configuration.ProtocolTypes); var connectionRelease = Interlocked.Exchange(ref connection, newConnection); DebugLog.Assert(connectionRelease == null, nameof(CMClient), "Connection was set during a connect, did you call CMClient.Connect() on multiple threads?"); newConnection.NetMsgReceived += NetMsgReceived; newConnection.Connected += Connected; newConnection.Disconnected += Disconnected; newConnection.Connect(record.EndPoint, ( int )ConnectionTimeout.TotalMilliseconds); }, TaskContinuationOptions.ExecuteSynchronously).ContinueWith(t => { if (t.IsFaulted) { LogDebug(nameof(CMClient), "Unhandled exception when attempting to connect to Steam: {0}", t.Exception); OnClientDisconnected(userInitiated: false); } connectionSetupTask = null; }, TaskContinuationOptions.ExecuteSynchronously); } }