From 997f9f928232dee8f44808bd671bdc91787942db Mon Sep 17 00:00:00 2001 From: Aigio Liu Date: Tue, 4 May 2021 02:29:54 +0800 Subject: [PATCH] =?UTF-8?q?Steam=20=E5=BF=AB=E9=80=9F=E7=99=BB=E5=BD=95=20?= =?UTF-8?q?95%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Common.CoreLib/Serializable.cs | 6 ++- .../Application/UI/CefNetApp.cs | 34 +++++++++++++++ .../Application/UI/Views/Controls/WebView3.cs | 43 +++++++++++++------ .../Windows/LoginOrRegisterWindowViewModel.cs | 17 +++++--- .../Windows/WebView3WindowViewModel.cs | 3 +- 5 files changed, 83 insertions(+), 20 deletions(-) diff --git a/src/Common.CoreLib/Serializable.cs b/src/Common.CoreLib/Serializable.cs index 3fb992e16..2838b2933 100644 --- a/src/Common.CoreLib/Serializable.cs +++ b/src/Common.CoreLib/Serializable.cs @@ -1,4 +1,4 @@ -#if !NOT_MP +#if !NOT_MP using MessagePack; #endif #if !NOT_NJSON @@ -147,6 +147,10 @@ namespace System public static byte[] SMP(T value, CancellationToken cancellationToken = default) => MessagePackSerializer.Serialize(value, options: lz4Options, cancellationToken: cancellationToken); + /// + public static byte[] SMP(Type type, object value, CancellationToken cancellationToken = default) + => MessagePackSerializer.Serialize(type, value, options: lz4Options, cancellationToken: cancellationToken); + /// /// (Serialize)MessagePack 序列化 + Base64Url Encode /// diff --git a/src/ST.Client.Desktop.Avalonia/Application/UI/CefNetApp.cs b/src/ST.Client.Desktop.Avalonia/Application/UI/CefNetApp.cs index 88650d59b..2afa79e59 100644 --- a/src/ST.Client.Desktop.Avalonia/Application/UI/CefNetApp.cs +++ b/src/ST.Client.Desktop.Avalonia/Application/UI/CefNetApp.cs @@ -1,5 +1,7 @@ using Avalonia.Threading; using CefNet; +using CefNet.Input; +using System; using System.Application.Models; using System.Globalization; using System.IO; @@ -166,6 +168,8 @@ navigator.__proto__ = newProto; } }; + KeycodeConverter.Default = new FixChineseInptKeycodeConverter(); + app = new CefNetApp { ScheduleMessagePumpWorkCallback = async delayMs => @@ -245,4 +249,34 @@ navigator.__proto__ = newProto; /// Complete, } +} + +namespace CefNet.Input +{ + /// + /// https://github.com/CefNet/CefNet/issues/21 + /// + public class FixChineseInptKeycodeConverter : KeycodeConverter + { + public override VirtualKeys CharacterToVirtualKey(char character) + { + // https://github.com/CefNet/CefNet/blob/master/CefNet/Input/KeycodeConverter.cs#L41 + // https://github.com/CefNet/CefNet/blob/90.5.21109.1453/CefNet/Input/KeycodeConverter.cs#L41 + try + { + return base.CharacterToVirtualKey(character); + } + catch (Exception e) + { + if (PlatformInfo.IsWindows) + { + if (e.Message == "Incompatible input locale.") + { + return VirtualKeys.None; + } + } + throw; + } + } + } } \ No newline at end of file diff --git a/src/ST.Client.Desktop.Avalonia/Application/UI/Views/Controls/WebView3.cs b/src/ST.Client.Desktop.Avalonia/Application/UI/Views/Controls/WebView3.cs index 82d307672..37c5735b0 100644 --- a/src/ST.Client.Desktop.Avalonia/Application/UI/Views/Controls/WebView3.cs +++ b/src/ST.Client.Desktop.Avalonia/Application/UI/Views/Controls/WebView3.cs @@ -65,11 +65,22 @@ namespace System.Application.UI.Views.Controls /// /// 拦截响应流的处理 /// - public Action? OnStreamResponseFilterResourceLoadComplete { get; set; } + public Action? OnStreamResponseFilterResourceLoadComplete { get; set; } public bool IsSecurity { get; set; } public Aes? Aes { get; internal set; } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + Aes?.Dispose(); + StreamResponseFilterUrls = null; + OnStreamResponseFilterResourceLoadComplete = null; + } + base.Dispose(disposing); + } } public class FullscreenModeChangeEventArgs : RoutedEventArgs @@ -217,8 +228,10 @@ namespace System.Application.UI.Views.Controls request.SetHeaderByName(Headers.Request.AppVersion, sc.Settings.AppVersionStr, true); if (webView.IsSecurity) { - webView.Aes?.Dispose(); - webView.Aes = AESUtils.Create(); + if (webView.Aes == null) + { + webView.Aes = AESUtils.Create(); + } var skey_bytes = webView.Aes.ToParamsByteArray(); var conn_helper = DI.Get(); var skey_str = conn_helper.RSA.EncryptToString(skey_bytes); @@ -274,7 +287,7 @@ namespace System.Application.UI.Views.Controls protected override CefResponseFilter GetResourceResponseFilter(CefBrowser browser, CefFrame frame, CefRequest request, CefResponse response) { - if (webView.StreamResponseFilterUrls != null && webView.StreamResponseFilterUrls.Contains(request.Url, StringComparer.OrdinalIgnoreCase)) + if (webView.StreamResponseFilterUrls != null && webView.StreamResponseFilterUrls.Any(x => request.Url.StartsWith(x, StringComparison.OrdinalIgnoreCase))) { var rspIsCiphertext = false; if (webView.IsSecurity) @@ -308,6 +321,7 @@ namespace System.Application.UI.Views.Controls public StreamResponseFilter(WebView3 webView, bool rspIsCiphertext) { this.webView = webView; + this.rspIsCiphertext = rspIsCiphertext; } protected override bool InitFilter() @@ -366,33 +380,36 @@ namespace System.Application.UI.Views.Controls { if (memoryStream != null) { - memoryStream.Dispose(); + memoryStream?.Dispose(); memoryStream = null; + stream?.Dispose(); + stream = null; } } } base.Dispose(disposing); } - byte[]? data; + Stream? stream; - public byte[] Data + public Stream Data { get { - if (data == null) data = GetData(); - return data; + if (stream == null) stream = GetStream(); + return stream; } } - byte[] GetData() + Stream GetStream() { - var value = memoryStream!.ToArray(); if (rspIsCiphertext && webView.Aes != null) { - value = webView.Aes.Decrypt(value); + memoryStream!.Position = 0; + var cryptoStream = new CryptoStream(memoryStream, webView.Aes.CreateDecryptor(), CryptoStreamMode.Read); + return cryptoStream; } - return value; + return memoryStream!; } } } diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/LoginOrRegisterWindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/LoginOrRegisterWindowViewModel.cs index a12e8d499..cc4e4941b 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/LoginOrRegisterWindowViewModel.cs +++ b/src/ST.Client.Desktop/UI/ViewModels/Windows/LoginOrRegisterWindowViewModel.cs @@ -3,6 +3,7 @@ using System.Application.Models; using System.Application.Services; using System.Application.Services.CloudService; using System.Application.UI.Resx; +using System.IO; using System.Properties; using System.Threading; using System.Threading.Tasks; @@ -112,11 +113,11 @@ namespace System.Application.UI.ViewModels TimeoutErrorMessage = AppResources.User_SteamFastLoginTimeoutErrorMessage, IsSecurity = true, }; - async void _OnStreamResponseFilterResourceLoadComplete(string url, byte[] data) + async void _OnStreamResponseFilterResourceLoadComplete(string url, Stream data) { if (url.StartsWith(urlExternalLoginCallback, StringComparison.OrdinalIgnoreCase)) { - var response = ApiResponse.Deserialize(data); + var response = await ApiResponse.DeserializeAsync(data, default); if (response.IsSuccess && response.Content == null) { response.Code = ApiResponseCode.NoResponseContent; @@ -125,12 +126,18 @@ namespace System.Application.UI.ViewModels if (response.IsSuccess) { await conn_helper.OnLoginedAsync(null, response.Content!); - await SuccessAsync(response.Content!, vm?.Close); + await MainThreadDesktop.InvokeOnMainThreadAsync(async () => + { + await SuccessAsync(response.Content!, vm?.Close); + }); } else { - conn_helper.ShowResponseErrorMessage(response); - vm?.Close?.Invoke(); + MainThreadDesktop.BeginInvokeOnMainThread(() => + { + conn_helper.ShowResponseErrorMessage(response); + vm?.Close?.Invoke(); + }); } } } diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/WebView3WindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/WebView3WindowViewModel.cs index 48b182b91..9e9716adc 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/WebView3WindowViewModel.cs +++ b/src/ST.Client.Desktop/UI/ViewModels/Windows/WebView3WindowViewModel.cs @@ -1,4 +1,5 @@ using ReactiveUI; +using System.IO; using System.Net.Http; namespace System.Application.UI.ViewModels @@ -21,7 +22,7 @@ namespace System.Application.UI.ViewModels set => this.RaiseAndSetIfChanged(ref _StreamResponseFilterUrls, value); } - public Action? OnStreamResponseFilterResourceLoadComplete { get; set; } + public Action? OnStreamResponseFilterResourceLoadComplete { get; set; } public bool FixedSinglePage { get; set; }