mirror of
https://github.com/BeyondDimension/SteamTools.git
synced 2026-10-19 07:01:35 +08:00
Compare commits
36 Commits
mobile
...
releasse-2.8.6
| Author | SHA1 | Date | |
|---|---|---|---|
| 6a5f8db69f | |||
| 3d3d126c64 | |||
| 8e32b428bd | |||
| 8193c6267a | |||
| c845601863 | |||
| 1309d63389 | |||
| fff5c293c8 | |||
| e9136e7245 | |||
| 66b47e9042 | |||
| 5144b1d1b0 | |||
| 8213f8a776 | |||
| 799185d870 | |||
| 4796bc0b71 | |||
| a5c49c470b | |||
| c3affdde7e | |||
| 066cfa66c5 | |||
| b89430e4cf | |||
| 729c7373fd | |||
| 6f843c3939 | |||
| 64099cf274 | |||
| a33acc16b6 | |||
| 90d0291640 | |||
| fa45e92d2f | |||
| 7aedb5dcef | |||
| 5509004c64 | |||
| 40b46966dc | |||
| f2a3d9cab1 | |||
| b68e4e062e | |||
| 4f9e6591dc | |||
| b9e03e7ed1 | |||
| b7606b2ec0 | |||
| de01020f8b | |||
| b9742c0514 | |||
| 4e1830bd75 | |||
| d6bbb1bd3d | |||
| 22dd40d43b |
@@ -131,6 +131,7 @@
|
||||
<PackageVersion Include="ReactiveUI.XamForms" Version="18.4.1" />
|
||||
<PackageVersion Include="ReactiveUI.AndroidX" Version="18.4.1" />
|
||||
<PackageVersion Include="ReactiveUI.Maui" Version="18.4.1" />
|
||||
|
||||
<!-- SkiaSharp & HarfBuzzSharp -->
|
||||
<!-- https://github.com/AvaloniaUI/Avalonia/blob/master/build/HarfBuzzSharp.props -->
|
||||
<PackageVersion Include="HarfBuzzSharp" Version="2.8.2.3" />
|
||||
@@ -204,7 +205,7 @@
|
||||
|
||||
<!-- .NET Compat -->
|
||||
<PackageVersion Include="OperatingSystem2" Version="2.0.0" />
|
||||
<PackageVersion Include="JustArchiNET.Madness" Version="3.8.0" />
|
||||
<PackageVersion Include="JustArchiNET.Madness" Version="3.9.0" />
|
||||
|
||||
<!-- Serialize -->
|
||||
<PackageVersion Include="MessagePack" Version="2.4.59" />
|
||||
|
||||
Binary file not shown.
Submodule references/SteamAchievementManager updated: b39839a962...99ce54cac5
+11
-4
@@ -4,14 +4,16 @@
|
||||
届时也会放弃继续对 Win7/8.1 系统的支持,所以这也意味着这是最后一个支持 Win7/8.1 的版本。
|
||||
也请各位敬请期待之后的 3.0 版本吧~
|
||||
|
||||
<!--
|
||||
### 版本亮点
|
||||
1. .NET 运行时升级至 6.0.11,使用 fde 版本需要升级运行时
|
||||
1. .NET 运行时升级至 6.0.12,使用 fde 版本需要升级运行时
|
||||
2. ASF 升级至 V5.3.2.4
|
||||
-->
|
||||
|
||||
### 修复问题
|
||||
1. 改进 Mac 安装证书的提示,显示执行命令
|
||||
2. 修复 Steam 启动参数在一些场景下无效
|
||||
3. 修复 网络加速 关闭 http 重定向到 https 依然监听80端口错误
|
||||
3. 修复 网络加速 关闭 http 重定向到 https 依然监听 80 端口错误
|
||||
4. 修复 网络加速 仅启用脚本功能 导致代理网站无法访问的错误
|
||||
5. 修复 网络加速 开启系统代理和 PAC 代理后,非代理网站无法正常访问的错误
|
||||
6. 修改 证书安装路径 为本地计算机 而不在是 当前用户 以支持跨用户访问,这项改动可能导致大家需要重新安装一次证书
|
||||
@@ -19,8 +21,13 @@
|
||||
8. 修复 捐助列表金额显示错位问题
|
||||
9. 修复 Twitch 聊天连接失败问题
|
||||
10. 修复 discord.gg 无法访问导致无法加入频道分享链接问题
|
||||
|
||||
|
||||
11. 修复 Steam 没有正确识别 Steam 国服提示问题
|
||||
12. ASF 升级至 V5.3.2.4
|
||||
12. .NET 运行时升级至 6.0.12,使用 fde 版本需要升级运行时
|
||||
13. 新增 Steam 设置可设置 模拟蒸汽平台启动参数
|
||||
14. 修复 Steam Beta 版库存游戏加载不出游戏详情和名称
|
||||
15. 修复 成就管理、云存档管理 无法打开
|
||||
16. 修复 库存游戏 首次加载后,游戏加载失败提示文本依然存在
|
||||
<!--
|
||||
|
||||
### 已知问题
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
namespace System.Properties
|
||||
{
|
||||
static partial class ThisAssembly
|
||||
{
|
||||
/// <summary>
|
||||
/// 版本号
|
||||
/// <para>在以下平台中还需要将版本号写入相关的清单文件:</para>
|
||||
/// <list type="bullet">
|
||||
/// <item> iOS:\src\ST.Client.Mobile.iOS.App\Info.plist <CFBundleVersion> <CFBundleShortVersionString> </item>
|
||||
/// <item> Android:\src\ST.Client.Mobile.Droid.App\Properties\AndroidManifest.xml <manifest ... android:versionCode(long递增) android:versionName </item>
|
||||
/// <item> UWP(DesktopBridge):\src\ST.Client.Desktop.Avalonia.App.Bridge.Package\Package.appxmanifest <Identity ... Version </item>
|
||||
/// <item> macOS:\packaging\build-osx-app.sh <CFBundleVersion> <CFBundleShortVersionString> </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public const string Version = "2.8.5";
|
||||
namespace System.Properties;
|
||||
|
||||
//public const string InfoVersion = Version + "-beta";
|
||||
}
|
||||
static partial class ThisAssembly
|
||||
{
|
||||
/// <summary>
|
||||
/// 版本号
|
||||
/// <para>在以下平台中还需要将版本号写入相关的清单文件:</para>
|
||||
/// <list type="bullet">
|
||||
/// <item> iOS:\src\ST.Client.Mobile.iOS.App\Info.plist <CFBundleVersion> <CFBundleShortVersionString> </item>
|
||||
/// <item> Android:\src\ST.Client.Mobile.Droid.App\Properties\AndroidManifest.xml <manifest ... android:versionCode(long递增) android:versionName </item>
|
||||
/// <item> UWP(DesktopBridge):\src\ST.Client.Desktop.Avalonia.App.Bridge.Package\Package.appxmanifest <Identity ... Version </item>
|
||||
/// <item> macOS:\packaging\build-osx-app.sh <CFBundleVersion> <CFBundleShortVersionString> </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public const string Version = "2.8.6";
|
||||
|
||||
//public const string InfoVersion = Version + "-beta";
|
||||
}
|
||||
@@ -190,6 +190,13 @@ namespace System
|
||||
|
||||
#endregion
|
||||
|
||||
// https://learn.microsoft.com/zh-cn/dotnet/standard/serialization/system-text-json/character-casing#case-insensitive-property-matching
|
||||
|
||||
static readonly SJsonSerializerOptions S_options = new()
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
};
|
||||
|
||||
#region Deserialize(反序列化)
|
||||
|
||||
/// <summary>
|
||||
@@ -204,7 +211,7 @@ namespace System
|
||||
{
|
||||
return implType switch
|
||||
{
|
||||
JsonImplType.SystemTextJson => SJsonSerializer.Deserialize<T>(value),
|
||||
JsonImplType.SystemTextJson => SJsonSerializer.Deserialize<T>(value, S_options),
|
||||
_ =>
|
||||
#if NOT_NJSON
|
||||
throw new NotSupportedException(),
|
||||
|
||||
@@ -17,10 +17,10 @@ internal static class Program
|
||||
{
|
||||
const string ExecutiveName = "Steam++";
|
||||
static BundleArch matchArch;
|
||||
static readonly SemanticVersion runtimeVersion = new(6, 0, 11);
|
||||
static readonly SemanticVersion sdkVersion1 = new(6, 0, 111);
|
||||
static readonly SemanticVersion sdkVersion3 = new(6, 0, 306);
|
||||
static readonly SemanticVersion sdkVersion4 = new(6, 0, 403);
|
||||
static readonly SemanticVersion runtimeVersion = new(6, 0, 12);
|
||||
static readonly SemanticVersion sdkVersion1 = new(6, 0, 112);
|
||||
static readonly SemanticVersion sdkVersion3 = new(6, 0, 307);
|
||||
static readonly SemanticVersion sdkVersion4 = new(6, 0, 404);
|
||||
|
||||
/// <summary>
|
||||
/// 应用程序的主入口点。
|
||||
|
||||
@@ -245,7 +245,7 @@ public abstract class CommandLineHost : IDisposable
|
||||
// -clt steam -account
|
||||
var steamuser = new Command("steam", "Steam 相关操作");
|
||||
steamuser.AddOption(new Option<string>("-account", "指定对应 Steam 用户名"));
|
||||
steamuser.Handler = CommandHandler.Create(async (string account) =>
|
||||
steamuser.Handler = CommandHandler.Create((string account) =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(account))
|
||||
{
|
||||
@@ -257,7 +257,7 @@ public abstract class CommandLineHost : IDisposable
|
||||
|
||||
var currentuser = users.Where(s => s.AccountName == account).FirstOrDefault();
|
||||
|
||||
await steamService.ShutdownSteamAsync();
|
||||
steamService.TryKillSteamProcess();
|
||||
|
||||
if (currentuser != null)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<Identity
|
||||
Name="4651ED44255E.47979655102CE"
|
||||
Publisher="CN=A90E406B-B2D3-4A23-B061-0FA1D65C4F66"
|
||||
Version="2.8.5.0" />
|
||||
Version="2.8.6.0" />
|
||||
|
||||
<Properties>
|
||||
<DisplayName>Watt Toolkit</DisplayName>
|
||||
|
||||
@@ -10,6 +10,7 @@ using NLog;
|
||||
using Avalonia;
|
||||
using Avalonia.ReactiveUI;
|
||||
using Avalonia.Controls;
|
||||
using System.Net.Http;
|
||||
|
||||
#if WINDOWS || WINDOWS_DESKTOP_BRIDGE
|
||||
using WPFMessageBox = System.Windows.MessageBox;
|
||||
@@ -47,6 +48,10 @@ namespace System.Application.UI
|
||||
// fix The request was aborted: Could not create SSL/TLS secure channel
|
||||
TrySetSecurityProtocol();
|
||||
|
||||
#if WINDOWS || WINDOWS_DESKTOP_BRIDGE
|
||||
HttpClient.DefaultProxy = DynamicHttpWindowsProxy.Instance;
|
||||
#endif
|
||||
|
||||
#if WINDOWS_DESKTOP_BRIDGE
|
||||
if (!DesktopBridgeHelper.Init()) return 0;
|
||||
InitWithUWP(ref args);
|
||||
|
||||
+2
-2
@@ -34,7 +34,7 @@ namespace System.Application.UI.Views.Pages
|
||||
EnableNullSplitting = false,
|
||||
DataLabelsSize = 12,
|
||||
Stroke = LiveChartsSkiaSharp.DefaultPaint,
|
||||
TooltipLabelFormatter = (e) => $"{AppResources.Upload} {IOPath.GetDisplayFileSizeString(e.PrimaryValue)}/s",
|
||||
TooltipLabelFormatter = (e) => $"Upload {IOPath.GetDisplayFileSizeString(e.PrimaryValue)}/s",
|
||||
Mapping = (rate, point) =>
|
||||
{
|
||||
point.PrimaryValue = rate.Rate;
|
||||
@@ -51,7 +51,7 @@ namespace System.Application.UI.Views.Pages
|
||||
EnableNullSplitting = false,
|
||||
DataLabelsSize = 12,
|
||||
Stroke = LiveChartsSkiaSharp.DefaultPaint,
|
||||
TooltipLabelFormatter = (e) => $"{AppResources.Download} {IOPath.GetDisplayFileSizeString(e.PrimaryValue)}/s",
|
||||
TooltipLabelFormatter = (e) => $"Download {IOPath.GetDisplayFileSizeString(e.PrimaryValue)}/s",
|
||||
Mapping = (rate, point) =>
|
||||
{
|
||||
point.PrimaryValue = rate.Rate;
|
||||
|
||||
+7
@@ -39,6 +39,13 @@
|
||||
</DockPanel>
|
||||
</Border>
|
||||
|
||||
<Border Classes="Item">
|
||||
<DockPanel>
|
||||
<TextBlock Text="{ReflectionBinding Path=Res.Settings_Steam_RunSteamChina,Mode=OneWay,Source={x:Static resx:R.Current}}"/>
|
||||
<ToggleSwitch IsChecked="{ReflectionBinding Source={x:Static ms:SteamSettings.IsRunSteamChina},Path=Value, Mode=TwoWay}"/>
|
||||
</DockPanel>
|
||||
</Border>
|
||||
|
||||
<Border Classes="Item">
|
||||
<DockPanel>
|
||||
<TextBlock Text="{ReflectionBinding Path=Res.Settings_Steam_CheckSteamRuningNotification,Mode=OneWay,Source={x:Static resx:R.Current}}"/>
|
||||
|
||||
@@ -94,13 +94,13 @@
|
||||
<Border.ContextFlyout>
|
||||
<MenuFlyout>
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding #u.DataContext.SteamId_Click}"
|
||||
Command="{ReflectionBinding #u.DataContext.SteamId_ClickCommand}"
|
||||
CommandParameter="{Binding}"
|
||||
Header="{ReflectionBinding Path=Res.UserChange_BtnText,
|
||||
Mode=OneWay,
|
||||
Source={x:Static resx:R.Current}}" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding #u.DataContext.OfflineModeButton_Click}"
|
||||
Command="{ReflectionBinding #u.DataContext.OfflineModeButton_ClickCommand}"
|
||||
CommandParameter="{Binding}"
|
||||
Header="{ReflectionBinding Path=Res.UserChange_OfflineBtn,
|
||||
Mode=OneWay,
|
||||
@@ -231,7 +231,7 @@
|
||||
Source={x:Static resx:R.Current}}">
|
||||
<i:Interaction.Behaviors>
|
||||
<ia:EventTriggerBehavior EventName="Tapped" SourceObject="{ReflectionBinding #nickname}">
|
||||
<ia:InvokeCommandAction Command="{ReflectionBinding #u.DataContext.SteamId_Click}" CommandParameter="{Binding}" />
|
||||
<ia:InvokeCommandAction Command="{ReflectionBinding #u.DataContext.SteamId_ClickCommand}" CommandParameter="{Binding}" />
|
||||
</ia:EventTriggerBehavior>
|
||||
</i:Interaction.Behaviors>
|
||||
</controls:ScrollingTextBlock>
|
||||
@@ -343,7 +343,7 @@
|
||||
Mode=OneWay,
|
||||
Source={x:Static resx:R.Current}}"
|
||||
Classes="flatbutton"
|
||||
Command="{ReflectionBinding #u.DataContext.OfflineModeButton_Click}"
|
||||
Command="{ReflectionBinding #u.DataContext.OfflineModeButton_ClickCommand}"
|
||||
CommandParameter="{Binding}"
|
||||
Cursor="Hand">
|
||||
<controls:ScrollingTextBlock Text="{ReflectionBinding Path=Res.UserChange_OfflineBtn, Mode=OneWay, Source={x:Static resx:R.Current}}" />
|
||||
@@ -359,7 +359,7 @@
|
||||
MaxWidth="250"
|
||||
HorizontalAlignment="Stretch"
|
||||
Classes="flatbutton"
|
||||
Command="{ReflectionBinding #u.DataContext.SteamId_Click}"
|
||||
Command="{ReflectionBinding #u.DataContext.SteamId_ClickCommand}"
|
||||
CommandParameter="{Binding}"
|
||||
Cursor="Hand">
|
||||
<controls:ScrollingTextBlock Text="{ReflectionBinding Path=Res.UserChange_BtnText, Mode=OneWay, Source={x:Static resx:R.Current}}" />
|
||||
|
||||
+26
-8
@@ -1,19 +1,37 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.LogicalTree;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using System.Application.Services;
|
||||
|
||||
namespace System.Application.UI.Views.Pages
|
||||
namespace System.Application.UI.Views.Pages;
|
||||
|
||||
public partial class UserItem : UserControl
|
||||
{
|
||||
public partial class UserItem : UserControl
|
||||
public UserItem()
|
||||
{
|
||||
public UserItem()
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
|
||||
{
|
||||
if (UserService.Current.User != null)
|
||||
{
|
||||
InitializeComponent();
|
||||
var lastSignInTime = UserService.Current.LastSignInTime;
|
||||
if (lastSignInTime.HasValue)
|
||||
{
|
||||
if (DateTimeOffset.Now - lastSignInTime.Value >= TimeSpan.FromDays(1))
|
||||
{
|
||||
UserService.Current.User.IsSignIn = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
base.OnAttachedToLogicalTree(e);
|
||||
}
|
||||
}
|
||||
|
||||
+16
-6
@@ -48,6 +48,12 @@
|
||||
Maximum="65535"/>
|
||||
</DockPanel>-->
|
||||
|
||||
<!--<DockPanel>
|
||||
<TextBlock Text="IPV6支持:" />
|
||||
<TextBlock Text="IPV6地址" ></TextBlock>
|
||||
<Button Content="{ReflectionBinding Path=Res.Refresh,Mode=OneWay,Source={x:Static resx:R.Current}}"></Button>
|
||||
</DockPanel>-->
|
||||
|
||||
<DockPanel>
|
||||
<TextBlock Text="{ReflectionBinding Path=Res.CommunityFix_AutoRunProxy,Mode=OneWay,Source={x:Static resx:R.Current}}" ></TextBlock>
|
||||
<ToggleSwitch
|
||||
@@ -59,13 +65,13 @@
|
||||
<ToggleSwitch
|
||||
IsChecked="{ReflectionBinding Source={x:Static ms:ProxySettings.OnlyEnableProxyScript},Path=Value, Mode=TwoWay}"/>
|
||||
</DockPanel>
|
||||
|
||||
|
||||
<DockPanel>
|
||||
<TextBlock Text="{ReflectionBinding Path=Res.CommunityFix_EnableHttpProxyToHttps,Mode=OneWay,Source={x:Static resx:R.Current}}" ></TextBlock>
|
||||
<ToggleSwitch
|
||||
IsChecked="{ReflectionBinding Source={x:Static ms:ProxySettings.EnableHttpProxyToHttps},Path=Value, Mode=TwoWay}"/>
|
||||
</DockPanel>
|
||||
|
||||
|
||||
<!--<DockPanel>
|
||||
<Label Content="自定义根证书密码"></Label>
|
||||
<TextBox></TextBox>
|
||||
@@ -86,11 +92,13 @@
|
||||
</DockPanel>
|
||||
</Expander.Header>
|
||||
<StackPanel Spacing="10">
|
||||
--><!--<DockPanel>
|
||||
-->
|
||||
<!--<DockPanel>
|
||||
<TextBlock Text="启用" ></TextBlock>
|
||||
<ToggleSwitch
|
||||
IsChecked="{ReflectionBinding Source={x:Static ms:ProxySettings.Socks5ProxyEnable},Path=Value, Mode=TwoWay}"/>
|
||||
</DockPanel>--><!--
|
||||
</DockPanel>-->
|
||||
<!--
|
||||
<DockPanel>
|
||||
<Label Content="{ReflectionBinding Path=Res.Settings_Proxy_ProxyPort,Mode=OneWay,Source={x:Static resx:R.Current}}"></Label>
|
||||
<NumericUpDown Maximum="65535"
|
||||
@@ -109,11 +117,13 @@
|
||||
</DockPanel>
|
||||
</Expander.Header>
|
||||
<StackPanel Spacing="10">
|
||||
--><!--<DockPanel>
|
||||
-->
|
||||
<!--<DockPanel>
|
||||
<TextBlock Text="启用" ></TextBlock>
|
||||
<ToggleSwitch
|
||||
IsChecked="{ReflectionBinding Source={x:Static ms:ProxySettings.TwoLevelAgentEnable},Path=Value, Mode=TwoWay}"/>
|
||||
</DockPanel>--><!--
|
||||
</DockPanel>-->
|
||||
<!--
|
||||
|
||||
<DockPanel>
|
||||
<Label Content="{ReflectionBinding Path=Res.Settings_Proxy_ProxyType,Mode=OneWay,Source={x:Static resx:R.Current}}"></Label>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
using DnsClient;
|
||||
using DnsClient.Protocol;
|
||||
using DynamicData;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using System.Application.Services;
|
||||
using System.Application.Services.Implementation;
|
||||
@@ -15,6 +16,11 @@ namespace System.Application.Services.Implementation
|
||||
{
|
||||
internal sealed class DnsAnalysisServiceImpl : IDnsAnalysisService
|
||||
{
|
||||
public DnsAnalysisServiceImpl()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static readonly LookupClient lookupClient = new();
|
||||
|
||||
public async Task<int> AnalysisHostnameTime(string url, CancellationToken cancellationToken = default)
|
||||
@@ -141,6 +147,11 @@ namespace System.Application.Services.Implementation
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<IPAddress?> GetHostIpv6Addres()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,10 +8,14 @@ using System.Application.Settings;
|
||||
using System.Application.UI;
|
||||
using System.Application.UI.Resx;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
#if WINDOWS
|
||||
using System.Management;
|
||||
#endif
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Runtime.Versioning;
|
||||
@@ -143,6 +147,41 @@ namespace System.Application.Services.Implementation
|
||||
/// <returns></returns>
|
||||
private Process? GetSteamProces() => GetSteamProcesses().FirstOrDefault();
|
||||
|
||||
public bool IsSteamChinaLauncher()
|
||||
{
|
||||
#if WINDOWS
|
||||
var process = GetSteamProces();
|
||||
if (process != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return GetCommandLineArgsCore().Contains("-steamchina", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
catch (Win32Exception ex) when ((uint)ex.ErrorCode == 0x80004005)
|
||||
{
|
||||
// 没有对该进程的安全访问权限。
|
||||
return false;
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
// 进程已退出。
|
||||
return false;
|
||||
}
|
||||
}
|
||||
string GetCommandLineArgsCore()
|
||||
{
|
||||
using (var searcher = new ManagementObjectSearcher(
|
||||
"SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + process.Id))
|
||||
using (var objects = searcher.Get())
|
||||
{
|
||||
var @object = objects.Cast<ManagementBaseObject>().SingleOrDefault();
|
||||
return @object?["CommandLine"]?.ToString() ?? "";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
public void StartSteam(string? arguments = null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(SteamProgramPath) && File.Exists(SteamProgramPath))
|
||||
@@ -497,6 +536,8 @@ namespace System.Application.Services.Implementation
|
||||
private const uint MagicNumber = 123094055U;
|
||||
private const uint MagicNumberV2 = 123094056U;
|
||||
|
||||
private static readonly Lazy<uint[]> MagicNumbers = new(new uint[] { MagicNumber, MagicNumberV2 });
|
||||
|
||||
/// <summary>
|
||||
/// 从steam本地客户端缓存文件中读取游戏数据
|
||||
/// </summary>
|
||||
@@ -517,15 +558,17 @@ namespace System.Application.Services.Implementation
|
||||
}
|
||||
using BinaryReader binaryReader = new(stream);
|
||||
uint num = binaryReader.ReadUInt32();
|
||||
if (num != MagicNumberV2 && num != MagicNumber)
|
||||
if (!MagicNumbers.Value.Contains(num))
|
||||
{
|
||||
Log.Error(nameof(GetAppInfos), string.Format("\"{0}\" magic code is not supported: 0x{1:X8}", Path.GetFileName(AppInfoPath), num));
|
||||
var msg = string.Format("\"{0}\" magic code is not supported: 0x{1:X8}", Path.GetFileName(AppInfoPath), num);
|
||||
Log.Error(nameof(GetAppInfos), msg);
|
||||
Toast.Show(msg, ToastLength.Long);
|
||||
return apps;
|
||||
}
|
||||
SteamApp? app = new();
|
||||
univeseNumber = binaryReader.ReadUInt32();
|
||||
var installAppIds = GetInstalledAppIds();
|
||||
while ((app = SteamApp.FromReader(binaryReader, installAppIds, isSaveProperties)) != null)
|
||||
while ((app = SteamApp.FromReader(binaryReader, installAppIds, isSaveProperties, num == MagicNumberV2)) != null)
|
||||
{
|
||||
if (app.AppId > 0)
|
||||
{
|
||||
|
||||
+15
@@ -106,6 +106,21 @@ namespace System.Application.Services.Implementation
|
||||
return SteamClient.SteamUtils.IsSteamChinaLauncher();
|
||||
}
|
||||
|
||||
public bool IsSteamInBigPictureMode()
|
||||
{
|
||||
return SteamClient.SteamUtils.IsSteamInBigPictureMode();
|
||||
}
|
||||
|
||||
public uint GetSecondsSinceAppActive()
|
||||
{
|
||||
return SteamClient.SteamUtils.GetSecondsSinceAppActive();
|
||||
}
|
||||
|
||||
public uint GetServerRealTime()
|
||||
{
|
||||
return SteamClient.SteamUtils.GetServerRealTime();
|
||||
}
|
||||
|
||||
public bool IsAppInstalled(uint appid)
|
||||
{
|
||||
return SteamClient.SteamApps008.IsAppInstalled(appid);
|
||||
|
||||
+65
-3
@@ -11,6 +11,8 @@ using System.Linq;
|
||||
using System.Management;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using _SR = System.Application.Properties.SR;
|
||||
|
||||
namespace System.Application.Services.Implementation;
|
||||
@@ -199,15 +201,71 @@ internal sealed partial class WindowsPlatformServiceImpl : IPlatformService
|
||||
/// <returns></returns>
|
||||
static Process? StartProcessRegedit(string? args) => Process2.Start(Regedit, args, workingDirectory: _windir.Value);
|
||||
|
||||
/// <summary>
|
||||
/// 使用 Explorer 降权运行进程
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="arguments"></param>
|
||||
/// <returns></returns>
|
||||
static Process? StartAsInvokerByExplorer(string fileName, string? arguments = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(arguments))
|
||||
return StartProcessExplorer($"\"{fileName}\"");
|
||||
//var processName = Path.GetFileNameWithoutExtension(fileName);
|
||||
var cacheCmdFile = IOPath.GetCacheFilePath(CacheTempDirName, "StartAsInvokerByExplorer", FileEx.CMD);
|
||||
File.WriteAllText(cacheCmdFile, $"@echo {Constants.HARDCODED_APP_NAME} StartAsInvokerByExplorer{Environment.NewLine}start \"\" \"{fileName}\" {arguments}{Environment.NewLine}exit 0");
|
||||
File.WriteAllText(cacheCmdFile, $"@echo {Constants.HARDCODED_APP_NAME} StartAsInvokerByExplorer{Environment.NewLine}start \"\" \"{fileName}\" {arguments}{Environment.NewLine}del %0");
|
||||
var process = StartProcessExplorer($"\"{cacheCmdFile}\"");
|
||||
IOPath.TryDeleteInDelay(process, cacheCmdFile);
|
||||
//if (process != null)
|
||||
//{
|
||||
// TryDeleteInDelay(process, cacheCmdFile, processName);
|
||||
//}
|
||||
return process;
|
||||
|
||||
//static async void TryDeleteInDelay(Process process, string filePath, string processName, int millisecondsDelay = 9000, int processWaitMillisecondsDelay = 9000)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// var waitForExitResult = process.WaitForExit(processWaitMillisecondsDelay);
|
||||
// if (!waitForExitResult)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// process.KillEntireProcessTree();
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// millisecondsDelay = 0;
|
||||
// }
|
||||
// if (millisecondsDelay > 0)
|
||||
// {
|
||||
// var token = new CancellationTokenSource(millisecondsDelay);
|
||||
// try
|
||||
// {
|
||||
// await Task.Run(async () =>
|
||||
// {
|
||||
// while (true)
|
||||
// {
|
||||
// await Task.Delay(100, token.Token);
|
||||
// if (Process.GetProcessesByName(processName).Any())
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }, token.Token);
|
||||
// }
|
||||
// catch (TaskCanceledException)
|
||||
// {
|
||||
|
||||
// }
|
||||
// }
|
||||
// IOPath.FileTryDelete(filePath);
|
||||
//}
|
||||
}
|
||||
|
||||
public Process? StartAsInvoker(string fileName, string? arguments = null)
|
||||
@@ -216,7 +274,11 @@ internal sealed partial class WindowsPlatformServiceImpl : IPlatformService
|
||||
{
|
||||
// runas /trustlevel:0x20000 没有真正的降权,只是作为具有限制特权,使用 explorer 最好,但不接受参数,可以创建一个临时cmd脚本启动
|
||||
//return StartAsInvokerByRunas(fileName, arguments);
|
||||
return StartAsInvokerByExplorer(fileName, arguments);
|
||||
//return StartAsInvokerByExplorer(fileName, arguments);
|
||||
var currentDirectory = Path.GetDirectoryName(fileName) ?? "";
|
||||
Microsoft.NodejsTools.SharedProject.SystemUtility.
|
||||
ExecuteProcessUnElevated(fileName, arguments ?? "", currentDirectory);
|
||||
return null;
|
||||
|
||||
}
|
||||
else
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
// https://github.com/microsoft/nodejstools/blob/main/Nodejs/Product/Nodejs/SharedProject/SystemUtilities.cs
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.NodejsTools.SharedProject;
|
||||
|
||||
/// <summary>
|
||||
/// Utility for accessing window IShell* interfaces in order to use them to launch a process unelevated
|
||||
/// </summary>
|
||||
internal static class SystemUtility
|
||||
{
|
||||
/// <summary>
|
||||
/// We are elevated and should launch the process unelevated. We can't create the
|
||||
/// process directly without it becoming elevated. So to workaround this, we have
|
||||
/// explorer do the process creation (explorer is typically running unelevated).
|
||||
/// </summary>
|
||||
internal static void ExecuteProcessUnElevated(string process, string args, string currentDirectory = "")
|
||||
{
|
||||
var shellWindows = (IShellWindows)new CShellWindows();
|
||||
|
||||
// Get the desktop window
|
||||
object loc = CSIDL_Desktop;
|
||||
object unused = new object();
|
||||
var serviceProvider = (IServiceProvider)shellWindows.FindWindowSW(ref loc, ref unused, SWC_DESKTOP, out var _, SWFO_NEEDDISPATCH);
|
||||
|
||||
// Get the shell browser
|
||||
var serviceGuid = SID_STopLevelBrowser;
|
||||
var interfaceGuid = typeof(IShellBrowser).GUID;
|
||||
var shellBrowser = (IShellBrowser)serviceProvider.QueryService(ref serviceGuid, ref interfaceGuid);
|
||||
|
||||
// Get the shell dispatch
|
||||
var dispatch = typeof(IDispatch).GUID;
|
||||
var folderView = (IShellFolderViewDual)shellBrowser.QueryActiveShellView().GetItemObject(SVGIO_BACKGROUND, ref dispatch);
|
||||
var shellDispatch = (IShellDispatch2)folderView.Application;
|
||||
|
||||
// Use the dispatch (which is unelevated) to launch the process for us
|
||||
shellDispatch.ShellExecute(process, args, currentDirectory, string.Empty, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interop definitions
|
||||
/// </summary>
|
||||
private const int CSIDL_Desktop = 0;
|
||||
private const int SWC_DESKTOP = 8;
|
||||
private const int SWFO_NEEDDISPATCH = 1;
|
||||
private const int SW_SHOWNORMAL = 1;
|
||||
private const int SVGIO_BACKGROUND = 0;
|
||||
private static readonly Guid SID_STopLevelBrowser = new("4C96BE40-915C-11CF-99D3-00AA004AE837");
|
||||
|
||||
[ComImport]
|
||||
[Guid("9BA05972-F6A8-11CF-A442-00A0C90A8F39")]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
private class CShellWindows
|
||||
{
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[Guid("85CB6900-4D95-11CF-960C-0080C7F4EE85")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
|
||||
private interface IShellWindows
|
||||
{
|
||||
[return: MarshalAs(UnmanagedType.IDispatch)]
|
||||
object FindWindowSW([MarshalAs(UnmanagedType.Struct)] ref object pvarloc, [MarshalAs(UnmanagedType.Struct)] ref object pvarlocRoot, int swClass, out int pHWND, int swfwOptions);
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
private interface IServiceProvider
|
||||
{
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
object QueryService(ref Guid guidService, ref Guid riid);
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[Guid("000214E2-0000-0000-C000-000000000046")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
private interface IShellBrowser
|
||||
{
|
||||
void VTableGap01(); // GetWindow
|
||||
|
||||
void VTableGap02(); // ContextSensitiveHelp
|
||||
|
||||
void VTableGap03(); // InsertMenusSB
|
||||
|
||||
void VTableGap04(); // SetMenuSB
|
||||
|
||||
void VTableGap05(); // RemoveMenusSB
|
||||
|
||||
void VTableGap06(); // SetStatusTextSB
|
||||
|
||||
void VTableGap07(); // EnableModelessSB
|
||||
|
||||
void VTableGap08(); // TranslateAcceleratorSB
|
||||
|
||||
void VTableGap09(); // BrowseObject
|
||||
|
||||
void VTableGap10(); // GetViewStateStream
|
||||
|
||||
void VTableGap11(); // GetControlWindow
|
||||
|
||||
void VTableGap12(); // SendControlMsg
|
||||
|
||||
IShellView QueryActiveShellView();
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[Guid("000214E3-0000-0000-C000-000000000046")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
private interface IShellView
|
||||
{
|
||||
void VTableGap01(); // GetWindow
|
||||
|
||||
void VTableGap02(); // ContextSensitiveHelp
|
||||
|
||||
void VTableGap03(); // TranslateAcceleratorA
|
||||
|
||||
void VTableGap04(); // EnableModeless
|
||||
|
||||
void VTableGap05(); // UIActivate
|
||||
|
||||
void VTableGap06(); // Refresh
|
||||
|
||||
void VTableGap07(); // CreateViewWindow
|
||||
|
||||
void VTableGap08(); // DestroyViewWindow
|
||||
|
||||
void VTableGap09(); // GetCurrentInfo
|
||||
|
||||
void VTableGap10(); // AddPropertySheetPages
|
||||
|
||||
void VTableGap11(); // SaveViewState
|
||||
|
||||
void VTableGap12(); // SelectItem
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
object GetItemObject(uint aspectOfView, ref Guid riid);
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[Guid("00020400-0000-0000-C000-000000000046")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
|
||||
private interface IDispatch
|
||||
{
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[Guid("E7A1AF80-4D96-11CF-960C-0080C7F4EE85")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
|
||||
private interface IShellFolderViewDual
|
||||
{
|
||||
object Application
|
||||
{
|
||||
[return: MarshalAs(UnmanagedType.IDispatch)]
|
||||
get;
|
||||
}
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[Guid("A4C6892C-3BA9-11D2-9DEA-00C04FB16162")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
|
||||
public interface IShellDispatch2
|
||||
{
|
||||
void ShellExecute([MarshalAs(UnmanagedType.BStr)] string file, [MarshalAs(UnmanagedType.Struct)] object vArgs, [MarshalAs(UnmanagedType.Struct)] object vDir, [MarshalAs(UnmanagedType.Struct)] object vOperation, [MarshalAs(UnmanagedType.Struct)] object vShow);
|
||||
}
|
||||
}
|
||||
@@ -805,7 +805,7 @@ namespace System.Application.Models
|
||||
return this;
|
||||
}
|
||||
|
||||
public static SteamApp? FromReader(BinaryReader reader, uint[]? installedAppIds = null, bool isSaveProperties = false)
|
||||
public static SteamApp? FromReader(BinaryReader reader, uint[]? installedAppIds = null, bool isSaveProperties = false, bool is0x07564428 = true)
|
||||
{
|
||||
uint id = reader.ReadUInt32();
|
||||
if (id == 0)
|
||||
@@ -825,6 +825,9 @@ namespace System.Application.Models
|
||||
binaryReader.ReadBytes(20);
|
||||
app._changeNumber = binaryReader.ReadUInt32();
|
||||
|
||||
if (is0x07564428)
|
||||
binaryReader.ReadBytes(20);
|
||||
|
||||
var properties = SteamAppPropertyHelper.ReadPropertyTable(binaryReader);
|
||||
|
||||
if (properties == null)
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace System.Application.Services
|
||||
/// <param name="isIPv6"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
IAsyncEnumerable<IPAddress>? DohAnalysisDomainIpAsync(string hostNameOrAddress, string? dnsServers, bool isIPv6, CancellationToken cancellationToken = default)
|
||||
IAsyncEnumerable<IPAddress>? DohAnalysisDomainIpAsync(string hostNameOrAddress, string? dnsServers, bool isIPv6, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -146,5 +146,7 @@ namespace System.Application.Services
|
||||
}
|
||||
|
||||
Task<bool> GetIsIpv6Support() => Task.FromResult(false);
|
||||
|
||||
Task<IPAddress?> GetHostIpv6Addres() => Task.FromResult(default(IPAddress));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,8 @@ namespace System.Application.Services
|
||||
/// <returns></returns>
|
||||
int GetSteamProcessPid();
|
||||
|
||||
bool IsSteamChinaLauncher();
|
||||
|
||||
/// <summary>
|
||||
/// 启动 Steam
|
||||
/// </summary>
|
||||
|
||||
@@ -33,6 +33,12 @@ namespace System.Application.Services
|
||||
|
||||
bool IsSteamChinaLauncher();
|
||||
|
||||
bool IsSteamInBigPictureMode();
|
||||
|
||||
uint GetSecondsSinceAppActive();
|
||||
|
||||
uint GetServerRealTime();
|
||||
|
||||
bool IsAppInstalled(uint appid);
|
||||
|
||||
string GetAppInstallDir(uint appid);
|
||||
|
||||
@@ -24,6 +24,12 @@ namespace System.Application.Services.Implementation
|
||||
|
||||
public bool IsSteamChinaLauncher() => default;
|
||||
|
||||
public bool IsSteamInBigPictureMode() => default;
|
||||
|
||||
public uint GetSecondsSinceAppActive() => default;
|
||||
|
||||
public uint GetServerRealTime() => default;
|
||||
|
||||
public bool IsAppInstalled(uint appid) => default;
|
||||
|
||||
public string GetAppInstallDir(uint appid) => string.Empty;
|
||||
|
||||
@@ -96,6 +96,12 @@ namespace System.Application.Services
|
||||
|
||||
IsASFRunOrStoping = true;
|
||||
|
||||
//if (ASF.GlobalConfig?.SteamOwnerID is null or 0)
|
||||
//{
|
||||
// Toast.Show(AppResources.ASF_Starting, ToastLength.Long);
|
||||
// return;
|
||||
//}
|
||||
|
||||
var isOk = await archiSteamFarmService.Start();
|
||||
if (!isOk)
|
||||
{
|
||||
|
||||
@@ -274,15 +274,16 @@ namespace System.Application.Services
|
||||
CurrentSteamUser = await swWebService.GetUserInfo(id);
|
||||
CurrentSteamUser.AvatarStream = httpService.GetImageAsync(CurrentSteamUser.AvatarFull, ImageChannelType.SteamAvatars);
|
||||
//AvatarPath = ImageSouce.TryParse(await CurrentSteamUser.AvatarStream, isCircle: true);
|
||||
|
||||
CurrentSteamUser.IPCountry = swLocalService.GetIPCountry();
|
||||
|
||||
IsSteamChinaLauncher = swLocalService.IsSteamChinaLauncher();
|
||||
IsSteamChinaLauncher = stmService.IsSteamChinaLauncher();
|
||||
var steamServerTime = ((long)swLocalService.GetServerRealTime()).ToDateTimeOffsetS();
|
||||
//var steamRunTime = swLocalService.GetSecondsSinceAppActive();
|
||||
|
||||
#region 初始化需要steam启动才能使用的功能
|
||||
if (SteamSettings.IsEnableSteamLaunchNotification.Value)
|
||||
{
|
||||
INotificationService.Instance.Notify($"{AppResources.Steam_CheckStarted}{(IsSteamChinaLauncher ? AppResources.Steam_SteamChina : AppResources.Steam_SteamWorld)}{Environment.NewLine}{AppResources.Steam_CurrentUser}{CurrentSteamUser.SteamNickName}{Environment.NewLine}{AppResources.Steam_CurrentIPCountry}{CurrentSteamUser.IPCountry}", NotificationType.Message);
|
||||
INotificationService.Instance.Notify($"{AppResources.Steam_CheckStarted}{(IsSteamChinaLauncher ? AppResources.Steam_SteamChina : AppResources.Steam_SteamWorld)}{Environment.NewLine}{AppResources.Steam_CurrentUser}{CurrentSteamUser.SteamNickName}{Environment.NewLine}{AppResources.Steam_CurrentIPCountry}{CurrentSteamUser.IPCountry}{Environment.NewLine}{AppResources.Steam_ServerTime}{steamServerTime:yyyy-MM-dd HH:mm:ss}", NotificationType.Message);
|
||||
}
|
||||
|
||||
if (GameLibrarySettings.IsAutoAFKApps.Value)
|
||||
|
||||
@@ -90,6 +90,8 @@ namespace System.Application.Services
|
||||
}
|
||||
}
|
||||
|
||||
public DateTimeOffset? LastSignInTime { get; set; }
|
||||
|
||||
public async Task SignIn()
|
||||
{
|
||||
if (User == null)
|
||||
@@ -101,16 +103,12 @@ namespace System.Application.Services
|
||||
var state = await csc.AccountClockIn();
|
||||
if (state.IsSuccess)
|
||||
{
|
||||
LastSignInTime = DateTimeOffset.Now;
|
||||
User.Experience = state.Content!.Experience;
|
||||
User.NextExperience = state.Content!.NextExperience;
|
||||
User.Level = state.Content!.Level;
|
||||
User.EngineOil = state.Content!.Strength;
|
||||
User.IsSignIn = true;
|
||||
//_ = Task.Run(async () =>
|
||||
//{
|
||||
// await Task.Delay(DateTime.Now.Date.AddDays(1).Subtract(DateTime.Now));
|
||||
// IsSignedIn = false;
|
||||
//});
|
||||
Toast.Show(AppResources.User_SignIn_Ok);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -14,6 +14,7 @@ public sealed class SteamSettings : SettingsHost2<SteamSettings>
|
||||
if (!IApplication.IsDesktopPlatform) return;
|
||||
IsRunSteamMinimized.ValueChanged += IsRunSteamMinimized_ValueChanged;
|
||||
IsRunSteamNoCheckUpdate.ValueChanged += IsRunSteamNoCheckUpdate_ValueChanged;
|
||||
IsRunSteamChina.ValueChanged += IsRunSteamChina_ValueChanged;
|
||||
}
|
||||
|
||||
static void IsRunSteamNoCheckUpdate_ValueChanged(object? sender, ValueChangedEventArgs<bool> e)
|
||||
@@ -32,6 +33,14 @@ public sealed class SteamSettings : SettingsHost2<SteamSettings>
|
||||
SteamStratParameter.Value = SteamStratParameter.Value.Replace("-silent", "").Trim();
|
||||
}
|
||||
|
||||
static void IsRunSteamChina_ValueChanged(object? sender, ValueChangedEventArgs<bool> e)
|
||||
{
|
||||
if (e.NewValue)
|
||||
SteamStratParameter.Value += " -steamchina";
|
||||
else if (SteamStratParameter.Value != null)
|
||||
SteamStratParameter.Value = SteamStratParameter.Value.Replace("-steamchina", "").Trim();
|
||||
}
|
||||
|
||||
static readonly SerializableProperty<string?>? _SteamStratParameter = IApplication.IsDesktopPlatform ?
|
||||
GetProperty<string?>(defaultValue: null) : null;
|
||||
|
||||
@@ -82,6 +91,16 @@ public sealed class SteamSettings : SettingsHost2<SteamSettings>
|
||||
[SupportedOSPlatform("Linux")]
|
||||
public static SerializableProperty<bool> IsRunSteamNoCheckUpdate => _IsRunSteamNoCheckUpdate ?? throw new PlatformNotSupportedException();
|
||||
|
||||
static readonly SerializableProperty<bool>? _IsRunSteamChina = IApplication.IsDesktopPlatform ? GetProperty(defaultValue: false) : null;
|
||||
|
||||
/// <summary>
|
||||
/// Steam 启动时模拟为蒸汽平台(Steam国服)启动
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("Windows7.0")]
|
||||
[SupportedOSPlatform("macOS")]
|
||||
[SupportedOSPlatform("Linux")]
|
||||
public static SerializableProperty<bool> IsRunSteamChina => _IsRunSteamChina ?? throw new PlatformNotSupportedException();
|
||||
|
||||
static readonly SerializableProperty<bool>? _IsEnableSteamLaunchNotification = IApplication.IsDesktopPlatform ? GetProperty(defaultValue: true) : null;
|
||||
|
||||
/// <summary>
|
||||
@@ -100,7 +119,7 @@ public sealed class SteamSettings : SettingsHost2<SteamSettings>
|
||||
[SupportedOSPlatform("Linux")]
|
||||
public static SerializableProperty<SystemEndMode>? DownloadCompleteSystemEndMode = IApplication.IsDesktopPlatform ? GetProperty(defaultValue: SystemEndMode.Sleep) : null;
|
||||
|
||||
static readonly SerializableProperty<bool>? _IsRunSteamAdministrator = IApplication.IsDesktopPlatform ? GetProperty(defaultValue: false) : null;
|
||||
static readonly SerializableProperty<bool>? _IsRunSteamAdministrator = IApplication.IsDesktopPlatform ? GetProperty(defaultValue: true) : null;
|
||||
|
||||
/// <summary>
|
||||
/// 以管理员权限运行 Steam
|
||||
|
||||
+18
@@ -5356,6 +5356,15 @@ namespace System.Application.UI.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Steam 启动时模拟为蒸汽平台(Steam国服)启动 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string Settings_Steam_RunSteamChina {
|
||||
get {
|
||||
return ResourceManager.GetString("Settings_Steam_RunSteamChina", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Steam 启动参数 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -5672,6 +5681,15 @@ namespace System.Application.UI.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Steam 服务端时间: 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string Steam_ServerTime {
|
||||
get {
|
||||
return ResourceManager.GetString("Steam_ServerTime", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 是否删除此家庭库共享。 的本地化字符串。
|
||||
/// </summary>
|
||||
|
||||
@@ -1230,6 +1230,9 @@ AAAAA-BBBBB-CCCC3</value>
|
||||
<data name="Settings_Steam_RuningMinimize" xml:space="preserve">
|
||||
<value>Steam 启动时最小化到托盘</value>
|
||||
</data>
|
||||
<data name="Settings_Steam_RunSteamChina" xml:space="preserve">
|
||||
<value>Steam 启动时模拟为蒸汽平台(Steam国服)启动</value>
|
||||
</data>
|
||||
<data name="Settings_Steam_RuningAdmin" xml:space="preserve">
|
||||
<value>以管理员权限运行 Steam</value>
|
||||
</data>
|
||||
@@ -1723,6 +1726,9 @@ AAAAA-BBBBB-CCCC3</value>
|
||||
<data name="Steam_CurrentUser" xml:space="preserve">
|
||||
<value>Steam 登录用户:</value>
|
||||
</data>
|
||||
<data name="Steam_ServerTime" xml:space="preserve">
|
||||
<value>Steam 服务端时间:</value>
|
||||
</data>
|
||||
<data name="Steam_SteamChina" xml:space="preserve">
|
||||
<value>Steam 国服</value>
|
||||
</data>
|
||||
|
||||
@@ -126,9 +126,6 @@ namespace System.Application.UI.ViewModels
|
||||
this.RaisePropertyChanged(nameof(TypeFilterString));
|
||||
}));
|
||||
|
||||
SteamConnectService.Current.WhenAnyValue(x => x.IsLoadingGameList)
|
||||
.Subscribe(_ => this.RaisePropertyChanged(nameof(IsSteamAppsEmpty)));
|
||||
|
||||
SteamConnectService.Current.SteamApps
|
||||
.Connect()
|
||||
.Filter(nameFilter)
|
||||
@@ -144,6 +141,9 @@ namespace System.Application.UI.ViewModels
|
||||
CalcTypeCount();
|
||||
});
|
||||
|
||||
SteamConnectService.Current.WhenAnyValue(x => x.IsLoadingGameList)
|
||||
.Subscribe(_ => this.RaisePropertyChanged(nameof(IsSteamAppsEmpty)));
|
||||
|
||||
HideAppCommand = ReactiveCommand.Create(() =>
|
||||
{
|
||||
IWindowManager.Instance.Show(CustomWindow.HideApp, resizeMode: ResizeMode.CanResize);
|
||||
@@ -217,7 +217,7 @@ namespace System.Application.UI.ViewModels
|
||||
[Reactive]
|
||||
public string? SearchText { get; set; }
|
||||
|
||||
public bool IsSteamAppsEmpty => !SteamApps.Any_Nullable() && !SteamConnectService.Current.IsLoadingGameList;
|
||||
public bool IsSteamAppsEmpty => !SteamConnectService.Current.SteamApps.Items.Any_Nullable() && !SteamConnectService.Current.IsLoadingGameList;
|
||||
|
||||
[Reactive]
|
||||
public ObservableCollection<EnumModel<SteamAppType>>? AppTypeFiltres { get; set; }
|
||||
|
||||
@@ -29,9 +29,12 @@ namespace System.Application.UI.ViewModels
|
||||
{
|
||||
this.WhenAnyValue(x => x.SteamUsers)
|
||||
.Subscribe(s => this.RaisePropertyChanged(nameof(IsUserEmpty)));
|
||||
LoginAccountCommand = ReactiveCommand.Create(LoginNewSteamAccount);
|
||||
LoginAccountCommand = ReactiveCommand.CreateFromTask(LoginNewSteamAccount);
|
||||
RefreshCommand = ReactiveCommand.Create(SteamConnectService.Current.RefreshSteamUsers);
|
||||
|
||||
SteamId_ClickCommand = ReactiveCommand.CreateFromTask<SteamUser>(SteamId_Click);
|
||||
OfflineModeButton_ClickCommand = ReactiveCommand.CreateFromTask<SteamUser>(OfflineModeButton_Click);
|
||||
|
||||
ShareManageCommand = ReactiveCommand.Create(OpenShareManageWindow);
|
||||
OpenBrowserCommand = ReactiveCommand.CreateFromTask<string>(x => Browser2.OpenAsync(x));
|
||||
|
||||
@@ -61,6 +64,10 @@ namespace System.Application.UI.ViewModels
|
||||
|
||||
public ReactiveCommand<Unit, Unit> LoginAccountCommand { get; }
|
||||
|
||||
public ReactiveCommand<SteamUser, Unit> SteamId_ClickCommand { get; }
|
||||
|
||||
public ReactiveCommand<SteamUser, Unit> OfflineModeButton_ClickCommand { get; }
|
||||
|
||||
public ReactiveCommand<Unit, Unit> RefreshCommand { get; }
|
||||
|
||||
public ReactiveCommand<Unit, Unit> ShareManageCommand { get; }
|
||||
@@ -99,9 +106,9 @@ namespace System.Application.UI.ViewModels
|
||||
|
||||
menus.Add(new MenuItemCustomName(title, AppResources.UserChange_BtnTootlip)
|
||||
{
|
||||
Command = ReactiveCommand.Create(() =>
|
||||
Command = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
SteamId_Click(user);
|
||||
await ReStartSteamByUser(user);
|
||||
|
||||
INotificationService.Instance.Notify(string.Format(AppResources.UserChange_ChangeUserTip, title), NotificationType.Message);
|
||||
}),
|
||||
@@ -114,24 +121,24 @@ namespace System.Application.UI.ViewModels
|
||||
#endregion
|
||||
}
|
||||
|
||||
public void SteamId_Click(SteamUser user)
|
||||
public async Task SteamId_Click(SteamUser user)
|
||||
{
|
||||
user.WantsOfflineMode = false;
|
||||
ReStartSteamByUser(user);
|
||||
await ReStartSteamByUser(user);
|
||||
}
|
||||
|
||||
public void OfflineModeButton_Click(SteamUser user)
|
||||
public async Task OfflineModeButton_Click(SteamUser user)
|
||||
{
|
||||
user.WantsOfflineMode = true;
|
||||
ReStartSteamByUser(user);
|
||||
await ReStartSteamByUser(user);
|
||||
}
|
||||
|
||||
private async void ReStartSteamByUser(SteamUser? user = null)
|
||||
private async Task ReStartSteamByUser(SteamUser? user = null)
|
||||
{
|
||||
foreach (var item in SteamUsers.Where(x => x.MostRecent))
|
||||
item.MostRecent = false;
|
||||
|
||||
await steamService.ShutdownSteamAsync();
|
||||
steamService.TryKillSteamProcess();
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
@@ -144,7 +151,7 @@ namespace System.Application.UI.ViewModels
|
||||
steamService.SetCurrentUser(string.Empty);
|
||||
}
|
||||
|
||||
steamService.StartSteamWithParameter();
|
||||
await Task.Run(steamService.StartSteamWithParameter);
|
||||
}
|
||||
|
||||
public async void DeleteUserButton_Click(SteamUser user)
|
||||
@@ -175,15 +182,14 @@ namespace System.Application.UI.ViewModels
|
||||
IPlatformService.Instance.OpenFolder(Path.Combine(ISteamService.Instance.SteamDirPath, user.UserdataPath));
|
||||
}
|
||||
|
||||
public void LoginNewSteamAccount()
|
||||
public async Task LoginNewSteamAccount()
|
||||
{
|
||||
var result = MessageBox.ShowAsync(AppResources.UserChange_LoginNewAccountTip, button: MessageBox.Button.OKCancel).ContinueWith(s =>
|
||||
var result = await MessageBox.ShowAsync(AppResources.UserChange_LoginNewAccountTip, button: MessageBox.Button.OKCancel);
|
||||
|
||||
if (result == MessageBox.Result.OK)
|
||||
{
|
||||
if (s.Result == MessageBox.Result.OK)
|
||||
{
|
||||
ReStartSteamByUser();
|
||||
}
|
||||
});
|
||||
await ReStartSteamByUser();
|
||||
}
|
||||
}
|
||||
|
||||
public async void EditRemarkAsync(SteamUser user)
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace System.Application.UI.ViewModels
|
||||
{
|
||||
if (await MessageBox.ShowAsync(AppResources.SaveEditedAppInfo_RestartSteamTip, ThisAssembly.AssemblyTrademark, MessageBox.Button.OKCancel) == MessageBox.Result.OK)
|
||||
{
|
||||
await stmService.ShutdownSteamAsync();
|
||||
stmService.TryKillSteamProcess();
|
||||
stmService.StartSteamWithParameter();
|
||||
}
|
||||
Toast.Show(AppResources.SaveEditedAppInfo_SaveToSteamSuccess);
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
using System.Application;
|
||||
using System.Application.Models;
|
||||
|
||||
return _(args, "客户端发布命令行工具(Command Line Tools/CLT)", init: () =>
|
||||
try
|
||||
{
|
||||
if (args.FirstOrDefault() == "apphostpatcher")
|
||||
return _(args, "客户端发布命令行工具(Command Line Tools/CLT)", init: () =>
|
||||
{
|
||||
var args_ = args.Skip(1).ToArray();
|
||||
return AppHostPatcher.Program.M(args_);
|
||||
}
|
||||
if (args.FirstOrDefault() == "apphostpatcher")
|
||||
{
|
||||
var args_ = args.Skip(1).ToArray();
|
||||
return AppHostPatcher.Program.M(args_);
|
||||
}
|
||||
|
||||
FileSystem2.InitFileSystem();
|
||||
return null;
|
||||
}, action: ToolConfig.AddInitCommand);
|
||||
FileSystem2.InitFileSystem();
|
||||
return null;
|
||||
}, action: ToolConfig.AddInitCommand);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
return 500;
|
||||
}
|
||||
@@ -109,7 +109,7 @@ namespace System.Application.Steps
|
||||
#endif
|
||||
}
|
||||
|
||||
static async Task VerHandlerAsync(string token, bool use_last_skey, bool dev)
|
||||
public static async Task VerHandlerAsync(string token, bool use_last_skey, bool dev)
|
||||
{
|
||||
var desc = ReadVersionDesc();
|
||||
var request = new CreateVersionRequest
|
||||
@@ -505,7 +505,7 @@ namespace System.Application.Steps
|
||||
//content.Headers.ContentType = new(MediaTypeNames.MessagePack);
|
||||
//return content;
|
||||
|
||||
var json = Serializable.SJSON_Original(request);
|
||||
var json = Serializable.SJSON(request);
|
||||
var content = new StringContent(json, Encoding.UTF8, MediaTypeNames.JSON);
|
||||
return content;
|
||||
}
|
||||
@@ -516,7 +516,7 @@ namespace System.Application.Steps
|
||||
//return await ApiResponse.DeserializeAsync<T>(stream, default);
|
||||
|
||||
var json = await responseMessage.Content.ReadAsStringAsync();
|
||||
return Serializable.DJSON_Original<ApiRsp<T>>(json)!;
|
||||
return Serializable.DJSON<ApiRsp<T>>(json)!;
|
||||
}
|
||||
|
||||
static async Task<IApiResponse> GetResponseAsync(HttpResponseMessage responseMessage)
|
||||
@@ -525,11 +525,11 @@ namespace System.Application.Steps
|
||||
//return await ApiResponse.DeserializeAsync<object>(stream, default);
|
||||
|
||||
var json = await responseMessage.Content.ReadAsStringAsync();
|
||||
return Serializable.DJSON_Original<ApiRsp>(json)!;
|
||||
return Serializable.DJSON<ApiRsp>(json)!;
|
||||
}
|
||||
|
||||
const string dev_api_base_url = "https://pan.mossimo.net:9911";
|
||||
const string api_base_url = "https://cycyadmin.steampp.net:11002";
|
||||
const string api_base_url = "https://adminapi.steampp.net";
|
||||
const string api_version_create = "/api/version";
|
||||
|
||||
static string GetFullVersion(bool dev)
|
||||
|
||||
Reference in New Issue
Block a user