mirror of
https://github.com/BeyondDimension/SteamTools.git
synced 2026-10-26 20:20:14 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5419530031 | ||
|
|
415fd30cc5 | ||
|
|
ef627692ef | ||
|
|
6f28ce0993 | ||
|
|
2dbb13db87 | ||
|
|
40d3c0e669 | ||
|
|
6be424dc5f | ||
|
|
6babd615cd |
@@ -239,13 +239,13 @@
|
||||
<PackageVersion Include="Polly" Version="7.2.3" />
|
||||
|
||||
<!--Avalonia Start-->
|
||||
<PackageVersion Include="Avalonia" Version="0.10.17" />
|
||||
<PackageVersion Include="Avalonia.Desktop" Version="0.10.17" />
|
||||
<PackageVersion Include="Avalonia.Skia" Version="0.10.17" />
|
||||
<PackageVersion Include="Avalonia.Diagnostics" Version="0.10.17" />
|
||||
<PackageVersion Include="Avalonia.ReactiveUI" Version="0.10.17" />
|
||||
<PackageVersion Include="Avalonia" Version="0.10.18" />
|
||||
<PackageVersion Include="Avalonia.Desktop" Version="0.10.18" />
|
||||
<PackageVersion Include="Avalonia.Skia" Version="0.10.18" />
|
||||
<PackageVersion Include="Avalonia.Diagnostics" Version="0.10.18" />
|
||||
<PackageVersion Include="Avalonia.ReactiveUI" Version="0.10.18" />
|
||||
<!--<PackageVersion Include="Avalonia.Direct2D1" Version="0.10.16" />-->
|
||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="0.10.17" />
|
||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="0.10.18" />
|
||||
<PackageVersion Include="Avalonia.Xaml.Behaviors" Version="0.10.17" />
|
||||
<!--<PackageVersion Include="Avalonia.AvaloniaEdit" Version="0.10.12.2" />-->
|
||||
<!--<PackageVersion Include="CefNet.Avalonia" Version="93.1.21240.857" />-->
|
||||
@@ -253,9 +253,9 @@
|
||||
<!--<PackageVersion Include="FluentAvaloniaUI" Version="1.4.1" />-->
|
||||
<PackageVersion Include="LiveChartsCore.SkiaSharpView.Avalonia" Version="2.0.0-beta.350" />
|
||||
<PackageVersion Include="JumpLists.Win32.Avalonia" Version="1.0.0" />
|
||||
<PackageVersion Include="Avalonia.Native" Version="0.10.17" />
|
||||
<PackageVersion Include="Avalonia.Win32" Version="0.10.17" />
|
||||
<PackageVersion Include="Avalonia.X11" Version="0.10.17" />
|
||||
<PackageVersion Include="Avalonia.Native" Version="0.10.18" />
|
||||
<PackageVersion Include="Avalonia.Win32" Version="0.10.18" />
|
||||
<PackageVersion Include="Avalonia.X11" Version="0.10.18" />
|
||||
<!--<PackageVersion Include="Avalonia.HtmlRenderer" Version="0.10.0" />-->
|
||||
<PackageVersion Include="WebView2.Avalonia" Version="1.0.1264.42-preview.220713.10" />
|
||||
<!--Avalonia End-->
|
||||
|
||||
@@ -49,28 +49,91 @@ public static class SettingsHost
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试备份配置
|
||||
/// </summary>
|
||||
/// <param name="bakLocalFilePath"></param>
|
||||
static void TryBackup(string bakLocalFilePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var localFilePath = SettingsHostBase.LocalFilePath;
|
||||
if (File.Exists(localFilePath))
|
||||
{
|
||||
File.Copy(localFilePath, bakLocalFilePath, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(nameof(SettingsHost), ex, "Config TryBackUp");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试还原备份配置,返回是否有备份文件
|
||||
/// </summary>
|
||||
/// <param name="bakLocalFilePath"></param>
|
||||
/// <returns></returns>
|
||||
static bool TryRestoreBackup(string bakLocalFilePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var exists = File.Exists(bakLocalFilePath);
|
||||
if (exists)
|
||||
{
|
||||
var localFilePath = SettingsHostBase.LocalFilePath;
|
||||
File.Copy(bakLocalFilePath, localFilePath, true);
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(nameof(SettingsHost), ex, "Config TryRestoreBackup");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试删除配置
|
||||
/// </summary>
|
||||
static void TryDelete()
|
||||
{
|
||||
try
|
||||
{
|
||||
var localFilePath = SettingsHostBase.LocalFilePath;
|
||||
if (File.Exists(localFilePath))
|
||||
{
|
||||
File.Delete(localFilePath);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(nameof(SettingsHost), ex, "Config TryDelete");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Load()
|
||||
{
|
||||
var isLoad = false;
|
||||
var bakLocalFilePath = $"{SettingsHostBase.LocalFilePath}.bak";
|
||||
try
|
||||
{
|
||||
SettingsHostBase.Local.Load();
|
||||
isLoad = true;
|
||||
|
||||
File.Copy(SettingsHostBase.LocalFilePath, bakLocalFilePath, true);
|
||||
TryBackup(bakLocalFilePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (File.Exists(bakLocalFilePath))
|
||||
if (!TryRestoreBackup(bakLocalFilePath))
|
||||
{
|
||||
File.Copy(bakLocalFilePath, SettingsHostBase.LocalFilePath, true);
|
||||
// 还原备份文件失败,删除当前配置
|
||||
TryDelete();
|
||||
}
|
||||
else
|
||||
{
|
||||
File.Delete(SettingsHostBase.LocalFilePath);
|
||||
}
|
||||
Log.Error(nameof(SettingsHost), ex, "Config Load");
|
||||
|
||||
SettingsHostBase.Local.Load();
|
||||
Log.Error(nameof(SettingsHost), ex, $"Config Load, isLoad: {isLoad}");
|
||||
|
||||
if (!isLoad) SettingsHostBase.Local.Load();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,10 +77,7 @@ public static partial class DI
|
||||
/// <inheritdoc cref="Get{T}"/>
|
||||
public static T? Get_Nullable<T>() where T : notnull
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw GetDIGetFailException(typeof(T));
|
||||
}
|
||||
if (value == null) return default;
|
||||
return value.GetService<T>();
|
||||
}
|
||||
|
||||
@@ -97,10 +94,7 @@ public static partial class DI
|
||||
/// <inheritdoc cref="Get_Nullable{T}"/>
|
||||
public static object? Get_Nullable(Type serviceType)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw GetDIGetFailException(serviceType);
|
||||
}
|
||||
if (value == null) return default;
|
||||
return value.GetService(serviceType);
|
||||
}
|
||||
|
||||
|
||||
@@ -291,6 +291,10 @@ public static class IOPath
|
||||
{
|
||||
paths[i] = item;
|
||||
}
|
||||
else
|
||||
{
|
||||
DirCreateByNotExists(paths[i]);
|
||||
}
|
||||
}
|
||||
|
||||
InitFileSystem(GetAppDataDirectory, GetCacheDirectory);
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace System.Properties
|
||||
/// <item> macOS:\packaging\build-osx-app.sh <CFBundleVersion> <CFBundleShortVersionString> </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public const string Version = "2.8.3";
|
||||
public const string Version = "2.8.4";
|
||||
|
||||
//public const string InfoVersion = Version + "-beta";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.Net.Security;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace System.Net.Http;
|
||||
|
||||
public sealed class ReverseProxyHttpClientHandler : DelegatingHandler
|
||||
{
|
||||
readonly TimeSpan connectTimeout = TimeSpan.FromSeconds(10d);
|
||||
|
||||
public ReverseProxyHttpClientHandler()
|
||||
{
|
||||
InnerHandler = new SocketsHttpHandler()
|
||||
{
|
||||
Proxy = GeneralHttpClientFactory.HttpNoProxy.Instance,
|
||||
UseProxy = false,
|
||||
UseCookies = false,
|
||||
AllowAutoRedirect = false,
|
||||
AutomaticDecompression = DecompressionMethods.None,
|
||||
ConnectCallback = ConnectCallback,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接回调
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
async ValueTask<Stream> ConnectCallback(SocketsHttpConnectionContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
var innerExceptions = new List<Exception>();
|
||||
var ipEndPoints = (await Dns.GetHostAddressesAsync("steamcommunity.rmbgame.net", cancellationToken)).Select(s => new IPEndPoint(s, context.DnsEndPoint.Port));
|
||||
|
||||
foreach (var ipEndPoint in ipEndPoints)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var timeoutTokenSource = new CancellationTokenSource(connectTimeout);
|
||||
using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(timeoutTokenSource.Token, cancellationToken);
|
||||
return await ConnectAsync(context, ipEndPoint, linkedTokenSource.Token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
innerExceptions.Add(new TimeoutException(
|
||||
$"HTTP connection to {ipEndPoint.Address} timed out."));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
innerExceptions.Add(ex);
|
||||
}
|
||||
}
|
||||
|
||||
throw new AggregateException("Could not find any IP that can be successfully connected.", innerExceptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 建立连接
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="ipEndPoint"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
static async ValueTask<Stream> ConnectAsync(SocketsHttpConnectionContext context, IPEndPoint ipEndPoint, CancellationToken cancellationToken)
|
||||
{
|
||||
var socket = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||
await socket.ConnectAsync(ipEndPoint, cancellationToken);
|
||||
var stream = new NetworkStream(socket, ownsSocket: true);
|
||||
|
||||
if (context.DnsEndPoint.Port != 443)
|
||||
{
|
||||
return stream;
|
||||
}
|
||||
|
||||
var sslStream = new SslStream(stream, leaveInnerStreamOpen: false);
|
||||
await sslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions
|
||||
{
|
||||
TargetHost = string.Empty,
|
||||
RemoteCertificateValidationCallback = (_, _, _, _) => true,
|
||||
}, cancellationToken);
|
||||
|
||||
return sslStream;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="20220803" android:versionName="2.8.3" package="net.steampp.app" android:installLocation="auto">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="20220814" android:versionName="2.8.3" package="net.steampp.app" android:installLocation="auto">
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
|
||||
<application android:fullBackupContent="@xml/auto_backup_rules"></application>
|
||||
<!-- Required for API Level 30 to make sure the app can detect browsers and other apps where communication is needed.-->
|
||||
|
||||
Reference in New Issue
Block a user