Compare commits

..
138 Commits
Author SHA1 Message Date
RMBGAME 6a5f8db69f fix 2022-12-19 18:50:34 +08:00
RMBGAME 3d3d126c64 Update release-template.md 2022-12-19 18:33:40 +08:00
Aigio Liu 8e32b428bd Revert "revert winauth"
This reverts commit 8193c6267a.
2022-12-18 22:41:19 +08:00
Aigio Liu 8193c6267a revert winauth 2022-12-18 22:40:25 +08:00
Aigio Liu c845601863 Revert "Bump references/WinAuth from 3942d43 to 48d27a6 (#2330)"
This reverts commit b89430e4cf.
2022-12-18 22:39:49 +08:00
Aigio Liu 1309d63389 fix SignIn 2022-12-18 21:23:58 +08:00
RMBGAME fff5c293c8 task command 2022-12-18 21:03:21 +08:00
Aigio Liu e9136e7245 async Task
SteamId_Click
OfflineModeButton_Click
2022-12-18 20:37:17 +08:00
Aigio Liu 66b47e9042 新的 StartAsInvoker 实现 & _IsRunSteamAdministrator defaultValue: true 2022-12-18 20:24:42 +08:00
RMBGAME 5144b1d1b0 Misc 2022-12-18 20:03:12 +08:00
Aigio Liu 8213f8a776 Misc 2022-12-18 19:38:01 +08:00
Aigio Liu 799185d870 ASF V5.3.2.4 2022-12-18 19:34:43 +08:00
Aigio Liu 4796bc0b71 修复 未使用管理员权限带参数运行 Steam 无效 & v2.8.6 2022-12-18 19:31:44 +08:00
RMBGAME a5c49c470b Misc 2022-12-18 18:37:28 +08:00
dependabot[bot]andRMBGAME c3affdde7e Bump MessagePack from 2.4.35 to 2.4.59 (#2278)
Bumps [MessagePack](https://github.com/neuecc/MessagePack-CSharp) from 2.4.35 to 2.4.59.
- [Release notes](https://github.com/neuecc/MessagePack-CSharp/releases)
- [Changelog](https://github.com/neuecc/MessagePack-CSharp/blob/master/prepare_release.ps1)
- [Commits](https://github.com/neuecc/MessagePack-CSharp/compare/v2.4.35...v2.4.59)

---
updated-dependencies:
- dependency-name: MessagePack
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: RMBGAME <12234359+rmbadmin@users.noreply.github.com>
2022-12-18 18:00:54 +08:00
dependabot[bot] 066cfa66c5 Bump JustArchiNET.Madness from 3.8.0 to 3.9.0 (#2367)
Bumps [JustArchiNET.Madness](https://github.com/JustArchiNET/Madness) from 3.8.0 to 3.9.0.
- [Release notes](https://github.com/JustArchiNET/Madness/releases)
- [Commits](https://github.com/JustArchiNET/Madness/compare/3.8.0...3.9.0)

---
updated-dependencies:
- dependency-name: JustArchiNET.Madness
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-18 18:00:13 +08:00
dependabot[bot] b89430e4cf Bump references/WinAuth from 3942d43 to 48d27a6 (#2330)
Bumps [references/WinAuth](https://github.com/SteamTools-Team/WinAuth) from `3942d43` to `48d27a6`.
- [Release notes](https://github.com/SteamTools-Team/WinAuth/releases)
- [Commits](https://github.com/SteamTools-Team/WinAuth/compare/3942d43ce8df3046ed37156567ff8325c517110b...48d27a626be39329cda226271b2c944df6416c29)

---
updated-dependencies:
- dependency-name: references/WinAuth
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-18 17:59:58 +08:00
dependabot[bot] 729c7373fd Bump references/ArchiSteamFarm from a427f62 to 1d900cc (#2341)
Bumps [references/ArchiSteamFarm](https://github.com/SteamTools-Team/ArchiSteamFarm) from `a427f62` to `1d900cc`.
- [Release notes](https://github.com/SteamTools-Team/ArchiSteamFarm/releases)
- [Commits](https://github.com/SteamTools-Team/ArchiSteamFarm/compare/a427f628e1b1d8b5ecfd66a16fd8ae3518934b53...1d900cc7b7623d5be619f90696cc72a01afbd31d)

---
updated-dependencies:
- dependency-name: references/ArchiSteamFarm
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-18 17:59:49 +08:00
dependabot[bot]andRMBGAME 6f843c3939 Bump DynamicData from 7.12.1 to 7.12.11 (#2302)
Bumps [DynamicData](https://github.com/reactiveui/DynamicData) from 7.12.1 to 7.12.11.
- [Release notes](https://github.com/reactiveui/DynamicData/releases)
- [Changelog](https://github.com/reactivemarbles/DynamicData/blob/main/ReleaseNotes.md)
- [Commits](https://github.com/reactiveui/DynamicData/compare/7.12.1...7.12.11)

---
updated-dependencies:
- dependency-name: DynamicData
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: RMBGAME <12234359+rmbadmin@users.noreply.github.com>
2022-12-18 17:59:21 +08:00
dependabot[bot] 64099cf274 Bump LiveChartsCore.SkiaSharpView.Avalonia (#2310)
Bumps [LiveChartsCore.SkiaSharpView.Avalonia](https://github.com/beto-rodriguez/LiveCharts2) from 2.0.0-beta.514 to 2.0.0-beta.603.
- [Release notes](https://github.com/beto-rodriguez/LiveCharts2/releases)
- [Commits](https://github.com/beto-rodriguez/LiveCharts2/commits)

---
updated-dependencies:
- dependency-name: LiveChartsCore.SkiaSharpView.Avalonia
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-18 17:58:03 +08:00
dependabot[bot] a33acc16b6 Bump SharpZipLib from 1.4.0 to 1.4.1 (#2213)
Bumps [SharpZipLib](https://github.com/icsharpcode/SharpZipLib) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/icsharpcode/SharpZipLib/releases)
- [Changelog](https://github.com/icsharpcode/SharpZipLib/blob/master/docs/Changes.txt)
- [Commits](https://github.com/icsharpcode/SharpZipLib/compare/v1.4.0...v1.4.1)

---
updated-dependencies:
- dependency-name: SharpZipLib
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-18 17:57:48 +08:00
dependabot[bot] 90d0291640 Bump HtmlAgilityPack from 1.11.45 to 1.11.46 (#2031)
Bumps [HtmlAgilityPack](https://github.com/zzzprojects/html-agility-pack) from 1.11.45 to 1.11.46.
- [Release notes](https://github.com/zzzprojects/html-agility-pack/releases)
- [Commits](https://github.com/zzzprojects/html-agility-pack/compare/v1.11.45...v1.11.46)

---
updated-dependencies:
- dependency-name: HtmlAgilityPack
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-18 17:57:28 +08:00
dependabot[bot] fa45e92d2f Bump Avalonia.Xaml.Behaviors from 0.10.17 to 0.10.18 (#1929)
Bumps [Avalonia.Xaml.Behaviors](https://github.com/wieslawsoltes/AvaloniaBehaviors) from 0.10.17 to 0.10.18.
- [Release notes](https://github.com/wieslawsoltes/AvaloniaBehaviors/releases)
- [Commits](https://github.com/wieslawsoltes/AvaloniaBehaviors/compare/0.10.17...0.10.18)

---
updated-dependencies:
- dependency-name: Avalonia.Xaml.Behaviors
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-18 17:57:17 +08:00
dependabot[bot] 7aedb5dcef Bump gfoidl.Base64 from 1.1.1 to 1.1.2 (#2068)
Bumps [gfoidl.Base64](https://github.com/gfoidl/Base64) from 1.1.1 to 1.1.2.
- [Release notes](https://github.com/gfoidl/Base64/releases)
- [Commits](https://github.com/gfoidl/Base64/compare/v1.1.1...v1.1.2)

---
updated-dependencies:
- dependency-name: gfoidl.Base64
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-18 17:57:02 +08:00
RMBGAME 5509004c64 修复Steam Beta版库存游戏加载不出游戏详情和名称
修复成就管理无法打开
修复库存游戏首次加载后,游戏加载失败提示文本依然存在
2022-12-18 17:50:10 +08:00
Aigio Liu 40b46966dc Misc 2022-12-14 03:19:44 +08:00
Aigio Liu f2a3d9cab1 Update .NET 6.0.12 2022-12-14 02:37:28 +08:00
Aigio Liu b68e4e062e PropertyNameCaseInsensitive = true 2022-12-14 01:25:40 +08:00
Aigio Liu 4f9e6591dc Add DynamicHttpWindowsProxy 2022-12-14 00:50:22 +08:00
RMBGAME b9e03e7ed1 fix 2022-12-14 00:35:46 +08:00
RMBGAME b7606b2ec0 fix 2022-12-13 23:28:51 +08:00
RMBGAME de01020f8b Update release-template.md 2022-12-13 23:20:14 +08:00
RMBGAME b9742c0514 添加steam国服启动设置 2022-12-13 23:10:54 +08:00
RMBGAME 4e1830bd75 ref 2022-12-13 22:49:12 +08:00
RMBGAME d6bbb1bd3d fix #2346 2022-12-13 22:49:12 +08:00
Aigio Liu 22dd40d43b fix pub tool 2022-12-13 22:09:15 +08:00
Aigio Liu 1d09ed185d Misc 2022-12-13 19:30:40 +08:00
Aigio Liu 81467c0a4f fix pubtool 2022-12-13 02:52:38 +08:00
Aigio Liu 79982d7ee9 V2.8.5 2022-12-13 00:07:06 +08:00
RMBGAME c97171cebb Update release-template.md 2022-12-13 00:04:50 +08:00
Aigio Liu db66950499 Update rel 2022-12-12 23:56:21 +08:00
Aigio Liu 8bbfd1dbc3 fix 2022-12-12 22:58:25 +08:00
Aigio Liu c9ae6f4fdf Remove Mobile projects 2022-12-12 21:38:29 +08:00
Aigio Liu 157319b69e Update ASF-UI 2022-12-12 21:33:48 +08:00
Aigio Liu 456f9c13f5 v2.8.5 rev.0 2022-12-12 21:28:29 +08:00
RMBGAME 055fe2a4d7 Misc 2022-12-12 20:32:53 +08:00
RMBGAME 15c6f575bc Misc 2022-12-12 20:21:04 +08:00
RMBGAME 5b5e5b031a 修复加载游戏数据失败问题 2022-12-11 22:54:26 +08:00
RMBGAME faa981eb87 fix 2022-12-11 22:54:26 +08:00
RMBGAME 648300328c 修改证书安装路径为本地计算机 2022-12-11 22:54:26 +08:00
RMBGAME 57d1c62770 Misc 2022-12-11 22:54:26 +08:00
RMBGAME 14b1e19246 doh Impl 2022-12-11 22:54:26 +08:00
Aigio Liu 5478e1a31e fix Mac TrustRootCertificate 2022-12-11 22:51:26 +08:00
RMBGAME a81f1d54f1 fix #2269 2022-11-16 17:17:35 +08:00
RMBGAME f9542f87b7 Misc 2022-11-16 17:17:35 +08:00
Aigio Liu a7ce44495a Misc 2022-11-16 16:48:11 +08:00
RMBGAME d5650f77df Misc 2022-10-26 19:35:21 +08:00
RMBGAME 0041ea7c23 fix #2174 2022-10-26 19:30:07 +08:00
RMBGAME dab382441f fix #2133 2022-10-26 18:02:26 +08:00
RMBGAME 28fc2ee466 SupportedImageFormats 2022-10-25 14:56:14 +08:00
Aigio Liu fe056c8e27 Misc 2022-10-19 22:55:18 +08:00
RMBGAME cbd2575ad5 bump packages to latest 2022-10-19 19:08:47 +08:00
dependabot[bot] 04c2276c73 Bump nttld/setup-ndk from 1.0.6 to 1.2.0 (#2130)
Bumps [nttld/setup-ndk](https://github.com/nttld/setup-ndk) from 1.0.6 to 1.2.0.
- [Release notes](https://github.com/nttld/setup-ndk/releases)
- [Commits](https://github.com/nttld/setup-ndk/compare/v1.0.6...v1.2.0)

---
updated-dependencies:
- dependency-name: nttld/setup-ndk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-19 18:40:32 +08:00
dependabot[bot] ea9ee6bda3 Bump DynamicData from 7.9.14 to 7.12.1 (#2135)
Bumps [DynamicData](https://github.com/reactiveui/DynamicData) from 7.9.14 to 7.12.1.
- [Release notes](https://github.com/reactiveui/DynamicData/releases)
- [Changelog](https://github.com/reactivemarbles/DynamicData/blob/main/ReleaseNotes.md)
- [Commits](https://github.com/reactiveui/DynamicData/compare/7.9.14...7.12.1)

---
updated-dependencies:
- dependency-name: DynamicData
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-19 18:40:14 +08:00
dependabot[bot] a0c7d26ee7 Bump actions/setup-dotnet from 3.0.0 to 3.0.2 (#2119)
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 3.0.0 to 3.0.2.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v3.0.0...v3.0.2)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-19 18:39:55 +08:00
Mossimo 9002127836 命令多显示了\ 2022-10-16 14:32:34 +08:00
RMBGAME 42457873ee Misc 2022-10-07 18:12:14 +08:00
Mossimo 884b2f7244 提示修改 2022-10-02 16:45:55 +08:00
dependabot[bot] 4bedc0f702 Bump LiveChartsCore.SkiaSharpView.Avalonia (#2054)
Bumps [LiveChartsCore.SkiaSharpView.Avalonia](https://github.com/beto-rodriguez/LiveCharts2) from 2.0.0-beta.350 to 2.0.0-beta.401.
- [Release notes](https://github.com/beto-rodriguez/LiveCharts2/releases)
- [Commits](https://github.com/beto-rodriguez/LiveCharts2/commits)

---
updated-dependencies:
- dependency-name: LiveChartsCore.SkiaSharpView.Avalonia
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-30 15:05:08 +08:00
dependabot[bot] 505ef59c23 Bump actions/setup-dotnet from 2 to 3.0.0 (#2053)
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 2 to 3.0.0.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v2...v3.0.0)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-30 15:04:12 +08:00
Aigio L b1c41f9421 #1992 (#1995) 2022-09-22 19:30:04 +08:00
Aigio Liu 07385d0040 ISteamService 添加 StartSteamWithParameter 函数替换 StartSteam(SteamSettings.SteamStratParameter.Value)
改进 SaveEditedAppInfoWindowViewModel.SaveSteamEditedApps
2022-09-08 23:55:19 +08:00
dependabot[bot]andAigio L c9000b1653 Bump AspNet.Security.OAuth.QQ from 6.0.10 to 6.0.11 (#1985)
Bumps [AspNet.Security.OAuth.QQ](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers) from 6.0.10 to 6.0.11.
- [Release notes](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/releases)
- [Commits](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/compare/6.0.10...6.0.11)

---
updated-dependencies:
- dependency-name: AspNet.Security.OAuth.QQ
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aigio L <24450093+AigioL@users.noreply.github.com>
2022-09-06 09:30:04 +08:00
dependabot[bot] 09bd0f6b5b Bump AspNet.Security.OAuth.Apple from 6.0.10 to 6.0.11 (#1984)
Bumps [AspNet.Security.OAuth.Apple](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers) from 6.0.10 to 6.0.11.
- [Release notes](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/releases)
- [Commits](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/compare/6.0.10...6.0.11)

---
updated-dependencies:
- dependency-name: AspNet.Security.OAuth.Apple
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-06 09:29:23 +08:00
dependabot[bot]andAigio L 6a90230dbb Bump NLog.Web.AspNetCore from 5.1.1 to 5.1.4 (#1972)
Bumps [NLog.Web.AspNetCore](https://github.com/NLog/NLog.Web) from 5.1.1 to 5.1.4.
- [Release notes](https://github.com/NLog/NLog.Web/releases)
- [Changelog](https://github.com/NLog/NLog.Web/blob/master/CHANGELOG.MD)
- [Commits](https://github.com/NLog/NLog.Web/compare/v5.1.1...v5.1.4)

---
updated-dependencies:
- dependency-name: NLog.Web.AspNetCore
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aigio L <24450093+AigioL@users.noreply.github.com>
2022-09-02 20:45:06 +08:00
dependabot[bot]andAigio L ec70128239 Bump NLog.Extensions.Logging from 5.0.2 to 5.0.4 (#1971)
Bumps [NLog.Extensions.Logging](https://github.com/NLog/NLog.Extensions.Logging) from 5.0.2 to 5.0.4.
- [Release notes](https://github.com/NLog/NLog.Extensions.Logging/releases)
- [Changelog](https://github.com/NLog/NLog.Extensions.Logging/blob/master/CHANGELOG.MD)
- [Commits](https://github.com/NLog/NLog.Extensions.Logging/compare/v5.0.2...v5.0.4)

---
updated-dependencies:
- dependency-name: NLog.Extensions.Logging
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aigio L <24450093+AigioL@users.noreply.github.com>
2022-09-02 20:44:38 +08:00
dependabot[bot] f2048bc3e5 Bump NLog from 5.0.2 to 5.0.4 (#1969)
Bumps [NLog](https://github.com/NLog/NLog) from 5.0.2 to 5.0.4.
- [Release notes](https://github.com/NLog/NLog/releases)
- [Changelog](https://github.com/NLog/NLog/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/NLog/NLog/compare/v5.0.2...v5.0.4)

---
updated-dependencies:
- dependency-name: NLog
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-02 20:43:59 +08:00
dependabot[bot]andAigio L 9000c3bf2a Bump AspNet.Security.OAuth.Apple from 6.0.9 to 6.0.10 (#1966)
Bumps [AspNet.Security.OAuth.Apple](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers) from 6.0.9 to 6.0.10.
- [Release notes](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/releases)
- [Commits](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/compare/6.0.9...6.0.10)

---
updated-dependencies:
- dependency-name: AspNet.Security.OAuth.Apple
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aigio L <24450093+AigioL@users.noreply.github.com>
2022-09-02 20:43:50 +08:00
dependabot[bot] 3725f9b62f Bump AspNet.Security.OAuth.QQ from 6.0.9 to 6.0.10 (#1964)
Bumps [AspNet.Security.OAuth.QQ](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers) from 6.0.9 to 6.0.10.
- [Release notes](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/releases)
- [Commits](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/compare/6.0.9...6.0.10)

---
updated-dependencies:
- dependency-name: AspNet.Security.OAuth.QQ
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-02 20:43:15 +08:00
dependabot[bot] 2c92e3e6f8 Bump Microsoft.NET.Test.Sdk from 17.3.0 to 17.3.1 (#1961)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.3.0 to 17.3.1.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v17.3.0...v17.3.1)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-02 20:43:06 +08:00
dependabot[bot]andAigio L f78271c2f5 Bump AspNet.Security.OAuth.QQ from 6.0.6 to 6.0.9 (#1943)
Bumps [AspNet.Security.OAuth.QQ](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers) from 6.0.6 to 6.0.9.
- [Release notes](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/releases)
- [Commits](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/compare/6.0.6...6.0.9)

---
updated-dependencies:
- dependency-name: AspNet.Security.OAuth.QQ
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aigio L <24450093+AigioL@users.noreply.github.com>
2022-08-26 15:00:42 +08:00
dependabot[bot] f2bdc19d74 Bump AspNet.Security.OAuth.Apple from 6.0.6 to 6.0.9 (#1942)
Bumps [AspNet.Security.OAuth.Apple](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers) from 6.0.6 to 6.0.9.
- [Release notes](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/releases)
- [Commits](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/compare/6.0.6...6.0.9)

---
updated-dependencies:
- dependency-name: AspNet.Security.OAuth.Apple
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-26 14:59:54 +08:00
dependabot[bot] 0fde0eccba Bump Moq from 4.18.1 to 4.18.2 (#1817)
Bumps [Moq](https://github.com/moq/moq4) from 4.18.1 to 4.18.2.
- [Release notes](https://github.com/moq/moq4/releases)
- [Changelog](https://github.com/moq/moq4/blob/main/CHANGELOG.md)
- [Commits](https://github.com/moq/moq4/compare/v4.18.1...v4.18.2)

---
updated-dependencies:
- dependency-name: Moq
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-26 14:59:30 +08:00
dependabot[bot]andAigio L 5c55fa97e7 Bump NLog.Web.AspNetCore from 5.1.0 to 5.1.1 (#1927)
Bumps [NLog.Web.AspNetCore](https://github.com/NLog/NLog.Web) from 5.1.0 to 5.1.1.
- [Release notes](https://github.com/NLog/NLog.Web/releases)
- [Changelog](https://github.com/NLog/NLog.Web/blob/master/CHANGELOG.MD)
- [Commits](https://github.com/NLog/NLog.Web/compare/v5.1.0...v5.1.1)

---
updated-dependencies:
- dependency-name: NLog.Web.AspNetCore
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aigio L <24450093+AigioL@users.noreply.github.com>
2022-08-26 14:59:01 +08:00
dependabot[bot] 323c7eb6c3 Bump DynamicData from 7.9.7 to 7.9.14 (#1925)
Bumps [DynamicData](https://github.com/reactiveui/DynamicData) from 7.9.7 to 7.9.14.
- [Release notes](https://github.com/reactiveui/DynamicData/releases)
- [Changelog](https://github.com/reactivemarbles/DynamicData/blob/main/ReleaseNotes.md)
- [Commits](https://github.com/reactiveui/DynamicData/compare/7.9.7...7.9.14)

---
updated-dependencies:
- dependency-name: DynamicData
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-26 14:58:22 +08:00
dependabot[bot] 42dea46260 Bump Z.EntityFramework.Plus.EFCore from 6.14.3 to 6.14.4 (#1915)
Bumps [Z.EntityFramework.Plus.EFCore](https://github.com/zzzprojects/EntityFramework-Plus) from 6.14.3 to 6.14.4.
- [Release notes](https://github.com/zzzprojects/EntityFramework-Plus/releases)
- [Commits](https://github.com/zzzprojects/EntityFramework-Plus/compare/6.14.3...6.14.4)

---
updated-dependencies:
- dependency-name: Z.EntityFramework.Plus.EFCore
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-26 14:58:08 +08:00
dependabot[bot]andAigio L 1bf65820c0 Bump NLog.Extensions.Logging from 5.0.1 to 5.0.2 (#1894)
Bumps [NLog.Extensions.Logging](https://github.com/NLog/NLog.Extensions.Logging) from 5.0.1 to 5.0.2.
- [Release notes](https://github.com/NLog/NLog.Extensions.Logging/releases)
- [Changelog](https://github.com/NLog/NLog.Extensions.Logging/blob/master/CHANGELOG.MD)
- [Commits](https://github.com/NLog/NLog.Extensions.Logging/compare/v5.0.1...v5.0.2)

---
updated-dependencies:
- dependency-name: NLog.Extensions.Logging
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aigio L <24450093+AigioL@users.noreply.github.com>
2022-08-26 14:57:28 +08:00
dependabot[bot] ba1c5b6c8b Bump Microsoft.NET.Test.Sdk from 17.2.0 to 17.3.0 (#1870)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.2.0 to 17.3.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v17.2.0...v17.3.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-26 14:56:03 +08:00
dependabot[bot] deb6c4eaa1 Bump Microsoft.Extensions.Logging.AzureAppServices from 6.0.7 to 6.0.8 (#1857)
Bumps [Microsoft.Extensions.Logging.AzureAppServices](https://github.com/dotnet/aspnetcore) from 6.0.7 to 6.0.8.
- [Release notes](https://github.com/dotnet/aspnetcore/releases)
- [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md)
- [Commits](https://github.com/dotnet/aspnetcore/compare/v6.0.7...v6.0.8)

---
updated-dependencies:
- dependency-name: Microsoft.Extensions.Logging.AzureAppServices
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-26 14:55:27 +08:00
dependabot[bot] af337a8fbd Bump Octokit from 2.0.0 to 2.0.1 (#1892)
Bumps [Octokit](https://github.com/octokit/octokit.net) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/octokit/octokit.net/releases)
- [Changelog](https://github.com/octokit/octokit.net/blob/main/docs/releases.md)
- [Commits](https://github.com/octokit/octokit.net/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: Octokit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-26 14:54:46 +08:00
dependabot[bot] 80d14c6c24 Bump Microsoft.WindowsAppSDK from 1.1.3 to 1.1.4 (#1877)
Bumps [Microsoft.WindowsAppSDK](https://github.com/microsoft/windowsappsdk) from 1.1.3 to 1.1.4.
- [Release notes](https://github.com/microsoft/windowsappsdk/releases)
- [Commits](https://github.com/microsoft/windowsappsdk/commits)

---
updated-dependencies:
- dependency-name: Microsoft.WindowsAppSDK
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-26 14:54:24 +08:00
dependabot[bot] 07d82be4c7 Bump NLog from 5.0.1 to 5.0.2 (#1891)
Bumps [NLog](https://github.com/NLog/NLog) from 5.0.1 to 5.0.2.
- [Release notes](https://github.com/NLog/NLog/releases)
- [Changelog](https://github.com/NLog/NLog/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/NLog/NLog/compare/v5.0.1...v5.0.2)

---
updated-dependencies:
- dependency-name: NLog
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-26 14:53:59 +08:00
dependabot[bot] 1e261f1125 Bump HtmlAgilityPack from 1.11.43 to 1.11.45 (#1940)
Bumps [HtmlAgilityPack](https://github.com/zzzprojects/html-agility-pack) from 1.11.43 to 1.11.45.
- [Release notes](https://github.com/zzzprojects/html-agility-pack/releases)
- [Commits](https://github.com/zzzprojects/html-agility-pack/compare/v1.11.43...v1.11.45)

---
updated-dependencies:
- dependency-name: HtmlAgilityPack
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-26 14:52:55 +08:00
Aigio Liu 8a1bde0773 Fix
System.ComponentModel.Win32Exception: An error occurred trying to start process 'C:\WINDOWS\explorer.exe' with working directory 'AppContext.BaseDirectory'. 拒绝访问。
https://appcenter.ms/orgs/BeyondDimension/apps/Steam/crashes/errors/180265099u/overview
https://appcenter.ms/orgs/BeyondDimension/apps/Steam/crashes/errors/3342720977u/overview
https://appcenter.ms/orgs/BeyondDimension/apps/Steam/crashes/errors/799855238u/overview
https://appcenter.ms/orgs/BeyondDimension/apps/Steam/crashes/errors/18523660u/overview
https://appcenter.ms/orgs/BeyondDimension/apps/Steam/crashes/errors/118999695u/overview

Try Fix
System.IO.IOException: The process cannot access the file 'C:\Users\***\AppData\Local\Packages\4651ED44255E.47979655102CE_k6txddmbb6c52\LocalState\Config.mpo' because it is being used by another process.
https://appcenter.ms/orgs/BeyondDimension/apps/Steam/crashes/errors/2552968077u/overview

Try Fix
System.Runtime.InteropServices.COMException: 无法在设置线程模式后对其加以更改。 (0x80010106 (RPC_E_CHANGED_MODE))
https://appcenter.ms/orgs/BeyondDimension/apps/Steam/crashes/errors/1550045210u/overview
2022-08-24 14:28:20 +08:00
Aigio Liu 617b99c39d MSStore 2.8.4 2022-08-18 10:27:41 +08:00
RMBGAME 8b4680fcee ReverseProxyHttpClientHandler in Server fix 2022-08-17 23:14:50 +08:00
RMBGAME e27ae2b202 Update bug-report.md 2022-08-16 20:15:48 +08:00
Aigio Liu 5419530031 Bump v2.8.4 2022-08-16 17:49:12 +08:00
RMBGAME 415fd30cc5 Bump Avalonia to 0.10.18 2022-08-16 12:27:40 +08:00
Aigio Liu ef627692ef v2.8.3 rev.1
fix SettingsHost.Load
2022-08-15 12:32:18 +08:00
Aigio Liu 6f28ce0993 Get_Nullable remove throw 2022-08-15 12:17:07 +08:00
RMBGAME 2dbb13db87 #1888 #1897 2022-08-15 12:12:20 +08:00
Aigio Liu 40d3c0e669 Build Android versionCode="20220814" 2022-08-14 21:58:22 +08:00
RMBGAME 6be424dc5f ReverseProxyHttpClientHandler in Server 2022-08-14 16:57:49 +08:00
Aigio Liu 6babd615cd Use ReverseProxyHttpClientHandler in Server 2022-08-14 16:41:10 +08:00
Aigio Liu d1f266465b v2.8.3 rev.0 2022-08-14 16:01:31 +08:00
RMBGAME fccd8da9f6 添加asynclock尝试修复 asf启动时接收令牌输入卡死问题 2022-08-14 15:30:48 +08:00
Aigio Liu df2f84ff99 Remove ReverseProxyHttpClient userAgent 2022-08-14 15:06:28 +08:00
Aigio Liu d0bfbdbc77 Update ASF v5.2.8.4 2022-08-14 14:27:41 +08:00
RMBGAME 51e19bae95 Update Package 2022-08-14 04:54:54 +08:00
RMBGAME 5673bf2150 config bak 2022-08-14 04:49:57 +08:00
RMBGAME f5c66a353e PNA Support 2022-08-12 19:33:18 +08:00
RMBGAME 09dd6fe47e Misc 2022-08-11 18:43:28 +08:00
Aigio Liu 96471ccf27 #1875 explorer.exe full path 2022-08-11 14:26:22 +08:00
Aigio Liu 7b3f40da3b Update .NET Runtime 6.0.8/SDK 6.0.400 & VS 17.3 | Bump v2.8.3 2022-08-10 10:32:13 +08:00
Aigio Liu e369c6aa10 非简中默认隐藏加速与脚本仅在 Windows 上生效 2022-08-10 00:46:53 +08:00
Aigio Liu 5b4fcc2b8b revoke DBreeze 2022-08-10 00:36:57 +08:00
Aigio Liu 33c6f0d5f9 fix 2022-08-10 00:08:49 +08:00
RMBGAME 6abdb6dc11 Misc 2022-08-10 00:09:27 +08:00
RMBGAME a981d31ec4 修复可能导致内存泄漏的问题 2022-08-07 00:34:15 +08:00
Aigio Liu 8a0dd49e39 改进 查找脚本注入位置 2022-08-06 10:07:46 +08:00
Aigio Liu dc005a1a47 fix Release 2022-08-04 22:09:00 +08:00
Aigio Liu 5d69679073 fix Preferences 2022-08-04 19:20:08 +08:00
Aigio Liu 1030e15d8e 改进 InitTabItems,减少启动时间 2022-08-04 18:19:57 +08:00
Aigio Liu 48083a90d2 Use DBreeze Impl Preferences/SettingsHost
fix StringExtensions.Trim
2022-08-04 14:11:29 +08:00
Aigio Liu aab89668a9 fix nuget.config unix path 2022-08-03 18:50:17 +08:00
Aigio Liu a4a6f0e61d add nupkg 2022-08-03 18:19:19 +08:00
Aigio Liu a103ec141b fix Android Microsoft.Extensions.Primitives 6.X 2022-08-03 17:52:25 +08:00
ff m c23dc29e1c Mac证书安装 同步等待 2022-08-02 19:25:23 +08:00
Aigio Liu ddda4c0273 fix appcenter crashes 2022-08-02 19:17:56 +08:00
ff m cd1c1b91d7 CookieHttpClient.CookieContainer.Add Cookie
UserAgent.ParseAdd(context.Request.Headers.UserAgent)
2022-07-31 14:15:01 +08:00
Aigio Liu ce09385a52 Add CookieHttpClient(HttpLocalRequestMiddleware) 2022-07-31 13:09:20 +08:00
RMBGAME 8d6e83a42b Misc 2022-07-29 15:45:36 +08:00
RMBGAME b0a72ab23a 调整代理模式顺序 2022-07-29 15:44:38 +08:00
Aigio Liu b5f8910e2e fix SettingsHost.Load catch 2022-07-29 15:40:59 +08:00
Aigio Liu 881ff3fba9 Misc 2022-07-29 08:45:23 +08:00
Aigio Liu 8878d183a7 fix #1781 2022-07-29 07:57:20 +08:00
Aigio Liu 46f95574d1 fix Bridge & Release Windows Desktop Bridge v2.8.2 2022-07-28 13:37:48 +08:00
158 changed files with 6368 additions and 2458 deletions
+2 -2
View File
@@ -8,10 +8,10 @@ assignees: ''
---
<!--
发布前请先尝试在 Issuse 内搜索一下你的问题是否已经被提出过,
发布前请先尝试在 Issues 内搜索一下你的问题是否已经被提出过,
详细地描述 bug,让大家都能理解,请一定确定你所要发布的内容是一个 Bug,如果不确定请发 Question
别忘了填写标题,标题要简短的描述问题
Before posting, please try searching in Issuse to see if your question has already been asked,
Before posting, please try searching in Issues to see if your question has already been asked,
Describe the bug in detail so that everyone can understand it
Don't forget to fill in the title, which should briefly describe the problem
-->
+1 -1
View File
@@ -29,7 +29,7 @@ jobs:
submodules: recursive
- name: Setup .NET 6
uses: actions/setup-dotnet@v2
uses: actions/setup-dotnet@v3.0.2
with:
dotnet-version: 6.0.x
+2 -2
View File
@@ -28,7 +28,7 @@ jobs:
submodules: recursive
- name: Setup .NET 6
uses: actions/setup-dotnet@v2
uses: actions/setup-dotnet@v3.0.2
with:
dotnet-version: 6.0.x
@@ -321,7 +321,7 @@ jobs:
submodules: recursive
- name: Setup .NET 6
uses: actions/setup-dotnet@v2
uses: actions/setup-dotnet@v3.0.2
with:
dotnet-version: 6.0.x
+2 -2
View File
@@ -24,7 +24,7 @@ jobs:
submodules: recursive
- name: Setup .NET 6
uses: actions/setup-dotnet@v2
uses: actions/setup-dotnet@v3.0.2
with:
dotnet-version: 6.0.x
@@ -63,7 +63,7 @@ jobs:
# xcode-version: '12.x' # set the latest available Xcode 12
- name: Setup Android NDK
uses: nttld/setup-ndk@v1.0.6
uses: nttld/setup-ndk@v1.2.0
id: setup-ndk
with:
ndk-version: r21e
+86 -79
View File
@@ -5,18 +5,18 @@
<PackageVersion Include="Microsoft.Extensions.Http" Version="6.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.AzureAppServices" Version="6.0.7" />
<PackageVersion Include="Microsoft.Extensions.Logging.AzureAppServices" Version="6.0.10" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="6.0.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.7" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="6.0.7" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.7" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.7" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.7" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.7" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.7" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="6.0.7" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="6.0.7" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.7" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.10" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="6.0.10" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.10" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.10" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.10" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.10" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.10" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="6.0.10" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="6.0.10" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.10" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard')) Or $(TargetFramework.StartsWith('netcoreapp3.1'))">
<!-- Microsoft.Extensions.* & AspNetCore & EntityFrameworkCore(NETCOREAPP31) -->
@@ -24,7 +24,7 @@
<PackageVersion Include="Microsoft.Extensions.Http" Version="3.1.27" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="3.1.27" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.27" />
<PackageVersion Include="Microsoft.Extensions.Logging.AzureAppServices" Version="3.1.27" />
<PackageVersion Include="Microsoft.Extensions.Logging.AzureAppServices" Version="6.0.10" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="3.1.27" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.27" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="3.1.27" />
@@ -40,12 +40,12 @@
<ItemGroup Condition=" $(TargetFramework.StartsWith('net6.0')) ">
<!-- Entity Framework Plus -->
<!-- A FREE & Open Source library to enhance EF6 and EF Core -->
<PackageVersion Include="Z.EntityFramework.Plus.EFCore" Version="6.14.3" />
<PackageVersion Include="Z.EntityFramework.Plus.EFCore" Version="6.15.2" />
<!-- AspNetCore 6 OpenId/OAuth -->
<PackageVersion Include="AspNet.Security.OpenId.Steam" Version="6.0.0" />
<PackageVersion Include="AspNet.Security.OAuth.QQ" Version="6.0.6" />
<PackageVersion Include="AspNet.Security.OAuth.Apple" Version="6.0.6" />
<PackageVersion Include="AspNet.Security.OAuth.QQ" Version="6.0.12" />
<PackageVersion Include="AspNet.Security.OAuth.Apple" Version="6.0.12" />
</ItemGroup>
<ItemGroup>
</ItemGroup>
@@ -74,22 +74,23 @@
</ItemGroup>
<ItemGroup>
<!-- Microsoft.* -->
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
<!--<PackageVersion Include="Microsoft.Windows.CsWinRT" Version="1.4.1" />-->
<!--<PackageVersion Include="Microsoft.Windows.SDK.NET.Ref" Version="10.0.19041.22" />-->
<!--<PackageVersion Include="Microsoft.Windows.SDK.Contracts" Version="10.0.19041.1" />-->
<PackageVersion Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.1" />
<PackageVersion Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.755" />
<PackageVersion Include="Microsoft.Extensions.Primitives" Version="6.0.0" />
<PackageVersion Include="Microsoft.Net.Http.Headers" Version="2.2.255.255" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<!--<PackageVersion Include="CommunityToolkit.Mvvm" Version="7.1.2" />-->
<PackageVersion Include="System.Text.Encoding.CodePages" Version="6.0.0" />
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="6.0.1" />
<PackageVersion Include="System.Net.Http.WinHttpHandler" Version="6.0.1" />
<!-- AppCenter.* -->
<PackageVersion Include="Microsoft.AppCenter" Version="4.5.3" />
<PackageVersion Include="Microsoft.AppCenter.Analytics" Version="4.5.3" />
<PackageVersion Include="Microsoft.AppCenter.Crashes" Version="4.5.3" />
<PackageVersion Include="Microsoft.AppCenter" Version="5.0.1" />
<PackageVersion Include="Microsoft.AppCenter.Analytics" Version="5.0.1" />
<PackageVersion Include="Microsoft.AppCenter.Crashes" Version="5.0.1" />
<PackageVersion Include="Aigio.Avalonia.AppCenter" Version="4.5.3" />
<PackageVersion Include="Aigio.Avalonia.AppCenter.Analytics" Version="4.5.3" />
<PackageVersion Include="Aigio.Avalonia.AppCenter.Crashes" Version="4.5.3" />
@@ -107,43 +108,44 @@
<PackageVersion Include="Xamarin.Forms" Version="5.0.0.2478" />
<PackageVersion Include="Xamarin.Forms.Visual.Material" Version="5.0.0.2478" />
<PackageVersion Include="Xam.Plugins.Forms.ImageCircle" Version="3.1.1.1-beta" />
<!-- NUnit & NUnit.Xamarin & Moq -->
<PackageVersion Include="NUnit" Version="3.13.3" />
<PackageVersion Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageVersion Include="NUnit3TestAdapter" Version="4.3.1" />
<PackageVersion Include="nunit.xamarin" Version="3.6.1" />
<PackageVersion Include="PCLStorage" Version="1.0.2" />
<PackageVersion Include="Moq" Version="4.18.1" />
<PackageVersion Include="Moq" Version="4.18.3" />
<!-- NLog -->
<PackageVersion Include="NLog" Version="5.0.1" />
<PackageVersion Include="NLog.Extensions.Logging" Version="5.0.1" />
<PackageVersion Include="NLog.Web.AspNetCore" Version="5.1.0" />
<PackageVersion Include="NLog" Version="5.1.0" />
<PackageVersion Include="NLog.Extensions.Logging" Version="5.2.0" />
<PackageVersion Include="NLog.Web.AspNetCore" Version="5.2.0" />
<PackageVersion Include="AspNetCore2.NETStandard.NLog.Web.AspNetCore" Version="5.0.0" />
<!-- ReactiveUI -->
<PackageVersion Include="System.Reactive" Version="5.0.0" />
<PackageVersion Include="Splat" Version="14.4.1" />
<PackageVersion Include="DynamicData" Version="7.9.7" />
<PackageVersion Include="ReactiveUI" Version="18.3.1" />
<PackageVersion Include="ReactiveUI.Fody" Version="18.3.1" />
<PackageVersion Include="ReactiveUI.XamForms" Version="18.3.1" />
<PackageVersion Include="ReactiveUI.AndroidX" Version="18.3.1" />
<PackageVersion Include="ReactiveUI.Maui" Version="18.3.1" />
<PackageVersion Include="Splat" Version="14.6.1" />
<PackageVersion Include="DynamicData" Version="7.12.11" />
<PackageVersion Include="ReactiveUI" Version="18.4.1" />
<PackageVersion Include="ReactiveUI.Fody" Version="18.4.1" />
<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.1-preview.91" />
<PackageVersion Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.8.2.1-preview.91" />
<PackageVersion Include="HarfBuzzSharp" Version="2.8.2.3" />
<PackageVersion Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.8.2.3" />
<!-- https://github.com/AvaloniaUI/Avalonia/blob/master/build/SkiaSharp.props -->
<PackageVersion Include="SkiaSharp" Version="2.88.1-preview.91" />
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.1-preview.91" />
<PackageVersion Include="SkiaSharp" Version="2.88.3" />
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.3" />
<!-- AutoMapper -->
<PackageVersion Include="AutoMapper" Version="11.0.1" />
<PackageVersion Include="AutoMapper.Collection" Version="8.0.0" />
<PackageVersion Include="AutoMapper" Version="12.0.0" />
<PackageVersion Include="AutoMapper.Collection" Version="9.0.0" />
<PackageVersion Include="AutoMapper.Collection.EntityFrameworkCore" Version="8.0.0" />
<PackageVersion Include="AutoMapper.Extensions.ExpressionMapping" Version="5.1.0" />
<PackageVersion Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
<PackageVersion Include="AutoMapper.Extensions.ExpressionMapping" Version="6.0.2" />
<PackageVersion Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.0" />
<!-- QRCode -->
<!--<PackageVersion Include="QRCoder" Version="1.4.2" />-->
@@ -157,14 +159,14 @@
<!--<PackageVersion Include="GtkSharp" Version="3.24.24.38" />-->
<!-- Compression -->
<PackageVersion Include="SharpZipLib" Version="1.3.3" />
<PackageVersion Include="SharpZipLib" Version="1.4.1" />
<PackageVersion Include="Squid-Box.SevenZipSharp.Lite" Version="1.5.0.366" />
<PackageVersion Include="7-Zip.NativeAssets.Win32" Version="21.7.0-preview.1" />
<PackageVersion Include="ZstdNet" Version="1.4.5" />
<!-- Algorithm -->
<PackageVersion Include="Crc32.NET" Version="1.2.0" />
<PackageVersion Include="gfoidl.Base64" Version="1.1.1" />
<PackageVersion Include="gfoidl.Base64" Version="1.1.2" />
<!--Command Line Tools-->
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
@@ -189,31 +191,31 @@
<!--<PackageVersion Include="AlipaySDKNet.Standard" Version="4.6.109" />-->
<!-- Excel -->
<PackageVersion Include="NPOI" Version="2.5.6" />
<PackageVersion Include="NPOI" Version="2.6.0" />
<!-- Github API -->
<PackageVersion Include="Octokit" Version="1.0.0" />
<PackageVersion Include="Octokit" Version="4.0.3" />
<!-- ORM -->
<PackageVersion Include="sqlite-net-pcl" Version="1.8.116" />
<PackageVersion Include="SQLitePCLRaw.bundle_green" Version="2.1.0" />
<PackageVersion Include="SQLitePCLRaw.bundle_green" Version="2.1.3" />
<!-- MonoMac(NETSTANDARD) -->
<PackageVersion Include="MonoMac.NetStandard" Version="0.0.4" />
<!-- .NET Compat -->
<PackageVersion Include="OperatingSystem2" Version="2.0.0" />
<PackageVersion Include="JustArchiNET.Madness" Version="3.7.0" />
<PackageVersion Include="JustArchiNET.Madness" Version="3.9.0" />
<!-- Serialize -->
<PackageVersion Include="MessagePack" Version="2.4.35" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.1" />
<PackageVersion Include="MessagePack" Version="2.4.59" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.2" />
<!-- Html Parser -->
<PackageVersion Include="HtmlAgilityPack" Version="1.11.43" />
<PackageVersion Include="HtmlAgilityPack" Version="1.11.46" />
<!-- Clipboard -->
<PackageVersion Include="TextCopy" Version="6.1.0" />
<PackageVersion Include="TextCopy" Version="6.2.0" />
<!-- Nito.* -->
<PackageVersion Include="Nito.Comparers" Version="6.2.2" />
@@ -228,7 +230,9 @@
<PackageVersion Include="Fleck" Version="1.2.0" />
<!-- DNS -->
<PackageVersion Include="DnsClient" Version="1.6.1" />
<PackageVersion Include="Ae.DNS.Client" Version="0.0.16" />
<!--<PackageVersion Include="Ae.Dns.Protocol" Version="0.0.16" />-->
<PackageVersion Include="DnsClient" Version="1.7.0" />
<PackageVersion Include="DNS" Version="7.0.0" />
<!-- Cryptographic Algorithms & Protocols -->
@@ -238,34 +242,34 @@
<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.Xaml.Behaviors" Version="0.10.17" />
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="0.10.18" />
<PackageVersion Include="Avalonia.Xaml.Behaviors" Version="0.10.18" />
<!--<PackageVersion Include="Avalonia.AvaloniaEdit" Version="0.10.12.2" />-->
<!--<PackageVersion Include="CefNet.Avalonia" Version="93.1.21240.857" />-->
<!--<PackageVersion Include="LibVLCSharp.Avalonia" Version="3.5.1" />-->
<!--<PackageVersion Include="FluentAvaloniaUI" Version="1.4.1" />-->
<PackageVersion Include="LiveChartsCore.SkiaSharpView.Avalonia" Version="2.0.0-beta.330" />
<!--<PackageVersion Include="FluentAvaloniaUI" Version="1.4.4" />-->
<PackageVersion Include="LiveChartsCore.SkiaSharpView.Avalonia" Version="2.0.0-beta.603" />
<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-->
<!-- Xamarin.Android -->
<PackageVersion Include="Xamarin.Build.Download" Version="0.11.2" />
<PackageVersion Include="Xamarin.Build.Download" Version="0.11.4" />
<PackageVersion Include="Xamarin.Google.Dagger" Version="2.40.5" />
<PackageVersion Include="Xamarin.Google.MLKit.BarcodeScanning" Version="116.1.2.5" />
<PackageVersion Include="Plugin.CurrentActivity" Version="2.1.0.4" />
<PackageVersion Include="de.hdodenhof.circleimageview" Version="3.1.0.4" />
<PackageVersion Include="Square.OkHttp3" Version="4.9.3" />
<PackageVersion Include="Square.OkHttp3" Version="4.9.3.2" />
<PackageVersion Include="Square.Picasso" Version="2.71828.0" />
<!--<PackageVersion Include="LeakCanaryBinding" Version="1.5.1.1" />-->
<!--<PackageVersion Include="TencentOpenApiSDK.Android" Version="3.5.4.11" />-->
@@ -274,29 +278,29 @@
<!-- V2Ray -->
<PackageVersion Include="XAB.AndroidLibV2rayLite" Version="1.0.0.1" />
<!--<PackageVersion Include="Karamunting.KotlinX.Coroutines.Core" Version="1.4.2" />-->
<PackageVersion Include="Xamarin.KotlinX.Coroutines.Core" Version="1.6.2.1" />
<PackageVersion Include="Xamarin.KotlinX.Coroutines.Android" Version="1.6.2.1" />
<PackageVersion Include="Xamarin.KotlinX.Coroutines.Core" Version="1.6.4" />
<PackageVersion Include="Xamarin.KotlinX.Coroutines.Android" Version="1.6.4" />
<PackageVersion Include="Xamarin.Android.ReactiveX.RxJava3.RxJava" Version="3.1.5.1" />
<!-- Xamarin.AndroidX -->
<PackageVersion Include="Xamarin.AndroidX.Migration" Version="1.0.10" />
<PackageVersion Include="Xamarin.AndroidX.AppCompat" Version="1.4.2.1" />
<PackageVersion Include="Xamarin.AndroidX.Emoji.AppCompat" Version="1.1.0.9" />
<PackageVersion Include="Xamarin.AndroidX.Fragment" Version="1.4.1.2" />
<PackageVersion Include="Xamarin.AndroidX.Fragment" Version="1.5.1" />
<PackageVersion Include="Xamarin.AndroidX.RecyclerView" Version="1.2.1.7" />
<PackageVersion Include="Xamarin.Google.Android.Material" Version="1.6.1.1" />
<PackageVersion Include="Xamarin.AndroidX.SwipeRefreshLayout" Version="1.1.0.9" />
<PackageVersion Include="Xamarin.AndroidX.ConstraintLayout" Version="2.1.4.1" />
<PackageVersion Include="Xamarin.AndroidX.Navigation.UI" Version="2.4.2.1" />
<PackageVersion Include="Xamarin.AndroidX.Navigation.Fragment" Version="2.4.2.1" />
<PackageVersion Include="Xamarin.AndroidX.Navigation.UI" Version="2.5.1" />
<PackageVersion Include="Xamarin.AndroidX.Navigation.Fragment" Version="2.5.1" />
<PackageVersion Include="Xamarin.AndroidX.ViewPager2" Version="1.0.0.16" />
<PackageVersion Include="Xamarin.AndroidX.Activity" Version="1.4.0.4" />
<PackageVersion Include="Xamarin.AndroidX.Activity" Version="1.5.1" />
<PackageVersion Include="Xamarin.AndroidX.Biometric" Version="1.1.0.10" />
<PackageVersion Include="Xamarin.AndroidX.ExifInterface" Version="1.3.3.6" />
<PackageVersion Include="Xamarin.AndroidX.Legacy.Support.Core.UI" Version="1.0.0.15" />
<PackageVersion Include="Xamarin.AndroidX.Lifecycle.LiveData" Version="2.4.1.2" />
<PackageVersion Include="Xamarin.AndroidX.Camera.Camera2" Version="1.1.0-beta02" />
<PackageVersion Include="Xamarin.AndroidX.Camera.Lifecycle" Version="1.1.0-beta02" />
<PackageVersion Include="Xamarin.AndroidX.Lifecycle.LiveData" Version="2.5.1" />
<PackageVersion Include="Xamarin.AndroidX.Camera.Camera2" Version="1.1.0" />
<PackageVersion Include="Xamarin.AndroidX.Camera.Lifecycle" Version="1.1.0" />
<PackageVersion Include="Xamarin.AndroidX.Camera.View" Version="1.1.0-beta02" />
<!--<PackageVersion Include="Xamarin.AndroidX.Window" Version="1.0.0.9" />-->
<PackageVersion Include="Xamarin.AndroidX.WebKit" Version="1.4.0.8" />
@@ -305,14 +309,14 @@
<PackageVersion Include="Toast.iOS" Version="1.2.0" />
<!-- UWP -->
<PackageVersion Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.2" />
<PackageVersion Include="Microsoft.WindowsAppSDK" Version="1.1.3" />
<PackageVersion Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
<PackageVersion Include="Microsoft.WindowsAppSDK" Version="1.2.221116.1" />
<!-- Code Style -->
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.435" />
<!-- Quartz -->
<PackageVersion Include="Quartz.AspNetCore" Version="3.4.0" />
<PackageVersion Include="Quartz.AspNetCore" Version="3.5.0" />
<!-- Yet Another Reverse Proxy -->
<PackageVersion Include="Yarp.ReverseProxy" Version="1.1.1" />
@@ -322,5 +326,8 @@
<!-- ArchiSteamFarm -->
<PackageVersion Include="ArchiSteamFarm.Library" Version="5.2.6.3-preview.220608" />
<!-- DBreeze(key value store embedded) -->
<PackageVersion Include="DBreeze" Version="1.107.0" />
</ItemGroup>
</Project>
+5
View File
@@ -0,0 +1,5 @@
<configuration>
<packageSources>
<add key="LocalNuGetPackages" value="./references/NuGetPackages" />
</packageSources>
</configuration>
-8
View File
@@ -24,13 +24,9 @@
"src\\Common.PinyinLib\\Common.PinyinLib.csproj",
"src\\Common.PinyinLib.CFStringTransform\\Common.PinyinLib.CFStringTransform.csproj",
"src\\Repositories.sqlite-net-pcl\\Repositories.sqlite-net-pcl.csproj",
"src\\ST.Client.Android\\ST.Client.Android.csproj",
"src\\ST.Client.Desktop.Mac\\ST.Client.Mac.csproj",
"src\\ST.Client.Mobile.Droid.App\\ST.Client.Android.App.csproj",
"src\\ST.Client.XamarinForms\\ST.Client.XamarinForms.csproj",
"src\\ST.Client.Desktop.Avalonia\\ST.Client.Avalonia.csproj",
"src\\ST.Client.Desktop.Avalonia.App\\ST.Client.Avalonia.App.csproj",
"src\\ST.Client.iOS\\ST.Client.iOS.csproj",
"src\\ST.Client\\ST.Client.csproj",
"src\\ST.Services.CloudService.Models\\ST.Services.CloudService.Models.csproj",
"src\\ST.Services.CloudService.ViewModels\\ST.Services.CloudService.ViewModels.csproj",
@@ -42,11 +38,7 @@
"src\\ST.Tools.Translate\\ST.Tools.Translate.csproj",
"src\\ST\\ST.csproj",
"src\\ST.Client.ResSecrets\\ST.Client.ResSecrets.csproj",
"src\\ST.Client.iOS.ResSecrets\\ST.Client.iOS.ResSecrets.csproj",
"src\\ST.Client.Android.ResSecrets\\ST.Client.Android.ResSecrets.csproj",
"src\\ST.Client.Mac.ResSecrets\\ST.Client.Mac.ResSecrets.csproj",
"tests\\Common.UnitTest.Droid.App\\ST.Client.UnitTest.Droid.App.csproj",
"tests\\Common.UnitTest.Droid\\ST.Client.UnitTest.Droid.csproj",
"tests\\Common.UnitTest\\Common.UnitTest.csproj",
"tests\\ST.Client.Desktop.UnitTest\\ST.Client.Desktop.UnitTest.csproj",
"tests\\ST.Client.UnitTest\\ST.Client.UnitTest.csproj"
+2 -415
View File
@@ -14,6 +14,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Root", "_Root", "{66839CD8
download-guide.md = download-guide.md
global.json = global.json
packaging\Info.plist = packaging\Info.plist
NuGet.Config = NuGet.Config
packaging\package.net472.ps1 = packaging\package.net472.ps1
README.en.md = README.en.md
README.md = README.md
@@ -114,14 +115,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UI Framework", "UI Framewor
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web API", "Web API", "{4E7DF449-F136-4B90-82CE-D1418CD5123C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Android", "src\ST.Client.Android\ST.Client.Android.csproj", "{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.iOS", "src\ST.Client.iOS\ST.Client.iOS.csproj", "{7EE23547-B2AC-409D-991C-1FDAE122657C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.XamarinForms", "src\ST.Client.XamarinForms\ST.Client.XamarinForms.csproj", "{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ST.Client.Android.App", "src\ST.Client.Mobile.Droid.App\ST.Client.Android.App.csproj", "{B355E372-27D2-4217-A129-D3355573681F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Avalonia.Ref", "Avalonia.Ref", "{910D6A0F-42AB-4B65-B532-852E864EC006}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Native", "src\Avalonia.Native\Avalonia.Native.csproj", "{17FBD44D-D9AA-48C2-9A06-214E8405CF88}"
@@ -153,10 +146,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Github", "_Github", "{B114
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.ClientLib.iOS", "src\Common.ClientLib.iOS\Common.ClientLib.iOS.csproj", "{4658B02A-CB1A-4561-AD9C-3B3FF969D7F0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.UnitTest.Droid", "tests\Common.UnitTest.Droid\ST.Client.UnitTest.Droid.csproj", "{80E6762E-AB43-41E2-BDB4-7A3E24713977}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ST.Client.UnitTest.Droid.App", "tests\Common.UnitTest.Droid.App\ST.Client.UnitTest.Droid.App.csproj", "{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Desktop.UnitTest", "tests\ST.Client.Desktop.UnitTest\ST.Client.Desktop.UnitTest.csproj", "{5D9E0EAA-2419-426B-BAB4-EA496C1FF7E9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.UnitTest.Resources", "tests\ST.Client.UnitTest.Resources\ST.Client.UnitTest.Resources.csproj", "{FB2CA9B4-71F1-48E8-B9AE-FF4375F4FE43}"
@@ -167,14 +156,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.Internals", "
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Bindings", "Bindings", "{80EBD601-28AC-4840-B9B8-E6064816A443}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Android.V2Ray", "src\ST.Client.Android.V2Ray\ST.Client.Android.V2Ray.csproj", "{4A79264D-5BF5-4F89-8066-44E154BF557F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gameloop.Vdf", "references\Gameloop.Vdf\Gameloop.Vdf\Gameloop.Vdf.csproj", "{DFC341E8-5290-428C-8D2B-6DE2AA163FFE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Android.Shadowsocks", "src\ST.Client.Android.Shadowsocks\ST.Client.Android.Shadowsocks.csproj", "{920EF29F-406F-43A9-B002-29DD6B0B4FBF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Android.App.Modern", "src\ST.Client.Android.App.Modern\ST.Client.Android.App.Modern.csproj", "{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ResSecrets", "ResSecrets", "{17667B53-1A09-45A6-855A-0F07F9AE044F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Android.ResSecrets", "src\ST.Client.Android.ResSecrets\ST.Client.Android.ResSecrets.csproj", "{68DD3E9C-A96C-4128-8D95-DCD65D1FA277}"
@@ -189,16 +172,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Windows.ResSecret
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Desktop", "src\Avalonia.Desktop\Avalonia.Desktop.csproj", "{FA9F0E89-E410-400A-86F3-C603E51E62A8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Avalonia.App.MsixPackage", "src\ST.Client.Desktop.Avalonia.App.Bridge2\ST.Client.Avalonia.App.MsixPackage.csproj", "{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FDELauncher", "src\FDELauncher\FDELauncher.csproj", "{7AAA8A01-A4FE-49AD-9664-AC53C4C8EAC6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Net.Http.Headers", "src\Microsoft.Net.Http.Headers\Microsoft.Net.Http.Headers.csproj", "{C7F109B9-EA88-4B7E-ADB5-D6407686ADE0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Maui.App", "src\ST.Client.Maui.App\ST.Client.Maui.App.csproj", "{73A9AB65-AF95-4F27-98E2-B3296F9BC198}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Maui", "src\ST.Client.Maui\ST.Client.Maui.csproj", "{48417EE3-BACB-4E04-B48D-B3781862AD81}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.Essentials", "src\Common.Essentials\Common.Essentials.csproj", "{41434AB5-48C3-47D4-8721-D118D87F472B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.Essentials.Xamarin", "src\Common.Essentials.Xamarin\Common.Essentials.Xamarin.csproj", "{07C9AC06-5D84-41AB-A3C9-5C5B1A27F526}"
@@ -1321,132 +1298,6 @@ Global
{D30203AC-97AB-4A51-BFA5-826251C9A28E}.Release|x64.Build.0 = Release|Any CPU
{D30203AC-97AB-4A51-BFA5-826251C9A28E}.Release|x86.ActiveCfg = Release|Any CPU
{D30203AC-97AB-4A51-BFA5-826251C9A28E}.Release|x86.Build.0 = Release|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Debug|ARM.ActiveCfg = Debug|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Debug|ARM.Build.0 = Debug|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Debug|ARM64.Build.0 = Debug|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Debug|iPhone.Build.0 = Debug|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Debug|x64.ActiveCfg = Debug|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Debug|x64.Build.0 = Debug|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Debug|x86.ActiveCfg = Debug|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Debug|x86.Build.0 = Debug|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Release|Any CPU.Build.0 = Release|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Release|ARM.ActiveCfg = Release|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Release|ARM.Build.0 = Release|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Release|ARM64.ActiveCfg = Release|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Release|ARM64.Build.0 = Release|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Release|iPhone.ActiveCfg = Release|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Release|iPhone.Build.0 = Release|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Release|x64.ActiveCfg = Release|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Release|x64.Build.0 = Release|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Release|x86.ActiveCfg = Release|Any CPU
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B}.Release|x86.Build.0 = Release|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Debug|ARM.ActiveCfg = Debug|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Debug|ARM.Build.0 = Debug|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Debug|ARM64.Build.0 = Debug|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Debug|iPhone.Build.0 = Debug|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Debug|x64.ActiveCfg = Debug|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Debug|x64.Build.0 = Debug|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Debug|x86.ActiveCfg = Debug|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Debug|x86.Build.0 = Debug|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Release|Any CPU.Build.0 = Release|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Release|ARM.ActiveCfg = Release|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Release|ARM.Build.0 = Release|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Release|ARM64.ActiveCfg = Release|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Release|ARM64.Build.0 = Release|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Release|iPhone.ActiveCfg = Release|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Release|iPhone.Build.0 = Release|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Release|x64.ActiveCfg = Release|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Release|x64.Build.0 = Release|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Release|x86.ActiveCfg = Release|Any CPU
{7EE23547-B2AC-409D-991C-1FDAE122657C}.Release|x86.Build.0 = Release|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Debug|ARM.ActiveCfg = Debug|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Debug|ARM.Build.0 = Debug|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Debug|ARM64.Build.0 = Debug|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Debug|iPhone.Build.0 = Debug|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Debug|x64.ActiveCfg = Debug|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Debug|x64.Build.0 = Debug|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Debug|x86.ActiveCfg = Debug|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Debug|x86.Build.0 = Debug|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Release|Any CPU.Build.0 = Release|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Release|ARM.ActiveCfg = Release|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Release|ARM.Build.0 = Release|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Release|ARM64.ActiveCfg = Release|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Release|ARM64.Build.0 = Release|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Release|iPhone.ActiveCfg = Release|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Release|iPhone.Build.0 = Release|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Release|x64.ActiveCfg = Release|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Release|x64.Build.0 = Release|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Release|x86.ActiveCfg = Release|Any CPU
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6}.Release|x86.Build.0 = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|ARM.ActiveCfg = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|ARM.Build.0 = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|ARM.Deploy.0 = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|ARM64.Build.0 = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|ARM64.Deploy.0 = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|iPhone.Build.0 = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|iPhone.Deploy.0 = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|x64.ActiveCfg = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|x64.Build.0 = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|x64.Deploy.0 = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|x86.ActiveCfg = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|x86.Build.0 = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Debug|x86.Deploy.0 = Debug|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|Any CPU.Build.0 = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|Any CPU.Deploy.0 = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|ARM.ActiveCfg = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|ARM.Build.0 = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|ARM.Deploy.0 = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|ARM64.ActiveCfg = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|ARM64.Build.0 = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|ARM64.Deploy.0 = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|iPhone.ActiveCfg = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|iPhone.Build.0 = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|iPhone.Deploy.0 = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|x64.ActiveCfg = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|x64.Build.0 = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|x64.Deploy.0 = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|x86.ActiveCfg = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|x86.Build.0 = Release|Any CPU
{B355E372-27D2-4217-A129-D3355573681F}.Release|x86.Deploy.0 = Release|Any CPU
{17FBD44D-D9AA-48C2-9A06-214E8405CF88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{17FBD44D-D9AA-48C2-9A06-214E8405CF88}.Debug|Any CPU.Build.0 = Debug|Any CPU
{17FBD44D-D9AA-48C2-9A06-214E8405CF88}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -1671,76 +1522,6 @@ Global
{4658B02A-CB1A-4561-AD9C-3B3FF969D7F0}.Release|x64.Build.0 = Release|Any CPU
{4658B02A-CB1A-4561-AD9C-3B3FF969D7F0}.Release|x86.ActiveCfg = Release|Any CPU
{4658B02A-CB1A-4561-AD9C-3B3FF969D7F0}.Release|x86.Build.0 = Release|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Debug|Any CPU.Build.0 = Debug|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Debug|ARM.ActiveCfg = Debug|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Debug|ARM.Build.0 = Debug|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Debug|ARM64.Build.0 = Debug|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Debug|iPhone.Build.0 = Debug|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Debug|x64.ActiveCfg = Debug|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Debug|x64.Build.0 = Debug|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Debug|x86.ActiveCfg = Debug|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Debug|x86.Build.0 = Debug|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Release|Any CPU.ActiveCfg = Release|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Release|Any CPU.Build.0 = Release|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Release|ARM.ActiveCfg = Release|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Release|ARM.Build.0 = Release|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Release|ARM64.ActiveCfg = Release|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Release|ARM64.Build.0 = Release|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Release|iPhone.ActiveCfg = Release|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Release|iPhone.Build.0 = Release|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Release|x64.ActiveCfg = Release|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Release|x64.Build.0 = Release|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Release|x86.ActiveCfg = Release|Any CPU
{80E6762E-AB43-41E2-BDB4-7A3E24713977}.Release|x86.Build.0 = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|ARM.ActiveCfg = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|ARM.Build.0 = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|ARM.Deploy.0 = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|ARM64.Build.0 = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|ARM64.Deploy.0 = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|iPhone.Build.0 = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|iPhone.Deploy.0 = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|x64.ActiveCfg = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|x64.Build.0 = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|x64.Deploy.0 = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|x86.ActiveCfg = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|x86.Build.0 = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|x86.Deploy.0 = Debug|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|Any CPU.Build.0 = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|Any CPU.Deploy.0 = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|ARM.ActiveCfg = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|ARM.Build.0 = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|ARM.Deploy.0 = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|ARM64.ActiveCfg = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|ARM64.Build.0 = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|ARM64.Deploy.0 = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|iPhone.ActiveCfg = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|iPhone.Build.0 = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|iPhone.Deploy.0 = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|x64.ActiveCfg = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|x64.Build.0 = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|x64.Deploy.0 = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|x86.ActiveCfg = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|x86.Build.0 = Release|Any CPU
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|x86.Deploy.0 = Release|Any CPU
{5D9E0EAA-2419-426B-BAB4-EA496C1FF7E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D9E0EAA-2419-426B-BAB4-EA496C1FF7E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5D9E0EAA-2419-426B-BAB4-EA496C1FF7E9}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -1853,34 +1634,6 @@ Global
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Release|x64.Build.0 = Release|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Release|x86.ActiveCfg = Release|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Release|x86.Build.0 = Release|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Debug|ARM.ActiveCfg = Debug|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Debug|ARM.Build.0 = Debug|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Debug|ARM64.Build.0 = Debug|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Debug|iPhone.Build.0 = Debug|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Debug|x64.ActiveCfg = Debug|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Debug|x64.Build.0 = Debug|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Debug|x86.ActiveCfg = Debug|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Debug|x86.Build.0 = Debug|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Release|Any CPU.Build.0 = Release|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Release|ARM.ActiveCfg = Release|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Release|ARM.Build.0 = Release|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Release|ARM64.ActiveCfg = Release|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Release|ARM64.Build.0 = Release|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Release|iPhone.ActiveCfg = Release|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Release|iPhone.Build.0 = Release|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Release|x64.ActiveCfg = Release|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Release|x64.Build.0 = Release|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Release|x86.ActiveCfg = Release|Any CPU
{4A79264D-5BF5-4F89-8066-44E154BF557F}.Release|x86.Build.0 = Release|Any CPU
{DFC341E8-5290-428C-8D2B-6DE2AA163FFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DFC341E8-5290-428C-8D2B-6DE2AA163FFE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DFC341E8-5290-428C-8D2B-6DE2AA163FFE}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -1909,64 +1662,6 @@ Global
{DFC341E8-5290-428C-8D2B-6DE2AA163FFE}.Release|x64.Build.0 = Release|Any CPU
{DFC341E8-5290-428C-8D2B-6DE2AA163FFE}.Release|x86.ActiveCfg = Release|Any CPU
{DFC341E8-5290-428C-8D2B-6DE2AA163FFE}.Release|x86.Build.0 = Release|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Debug|ARM.ActiveCfg = Debug|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Debug|ARM.Build.0 = Debug|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Debug|ARM64.Build.0 = Debug|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Debug|iPhone.Build.0 = Debug|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Debug|x64.ActiveCfg = Debug|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Debug|x64.Build.0 = Debug|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Debug|x86.ActiveCfg = Debug|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Debug|x86.Build.0 = Debug|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Release|Any CPU.Build.0 = Release|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Release|ARM.ActiveCfg = Release|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Release|ARM.Build.0 = Release|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Release|ARM64.ActiveCfg = Release|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Release|ARM64.Build.0 = Release|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Release|iPhone.ActiveCfg = Release|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Release|iPhone.Build.0 = Release|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Release|x64.ActiveCfg = Release|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Release|x64.Build.0 = Release|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Release|x86.ActiveCfg = Release|Any CPU
{920EF29F-406F-43A9-B002-29DD6B0B4FBF}.Release|x86.Build.0 = Release|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Debug|ARM.ActiveCfg = Debug|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Debug|ARM.Build.0 = Debug|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Debug|ARM64.Build.0 = Debug|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Debug|iPhone.Build.0 = Debug|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Debug|x64.ActiveCfg = Debug|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Debug|x64.Build.0 = Debug|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Debug|x86.ActiveCfg = Debug|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Debug|x86.Build.0 = Debug|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Release|Any CPU.Build.0 = Release|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Release|Any CPU.Deploy.0 = Release|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Release|ARM.ActiveCfg = Release|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Release|ARM.Build.0 = Release|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Release|ARM64.ActiveCfg = Release|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Release|ARM64.Build.0 = Release|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Release|iPhone.ActiveCfg = Release|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Release|iPhone.Build.0 = Release|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Release|x64.ActiveCfg = Release|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Release|x64.Build.0 = Release|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Release|x86.ActiveCfg = Release|Any CPU
{5E2ABB4A-FDD6-47B0-946D-FAAD31301B82}.Release|x86.Build.0 = Release|Any CPU
{68DD3E9C-A96C-4128-8D95-DCD65D1FA277}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{68DD3E9C-A96C-4128-8D95-DCD65D1FA277}.Debug|Any CPU.Build.0 = Debug|Any CPU
{68DD3E9C-A96C-4128-8D95-DCD65D1FA277}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -2135,36 +1830,6 @@ Global
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Release|x64.Build.0 = Release|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Release|x86.ActiveCfg = Release|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Release|x86.Build.0 = Release|Any CPU
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Debug|Any CPU.ActiveCfg = Debug|x64
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Debug|Any CPU.Build.0 = Debug|x64
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Debug|ARM.ActiveCfg = Debug|Any CPU
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Debug|ARM.Build.0 = Debug|Any CPU
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Debug|ARM64.ActiveCfg = Debug|arm64
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Debug|ARM64.Build.0 = Debug|arm64
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Debug|iPhone.Build.0 = Debug|Any CPU
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Debug|x64.ActiveCfg = Debug|x64
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Debug|x64.Build.0 = Debug|x64
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Debug|x64.Deploy.0 = Debug|x64
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Debug|x86.ActiveCfg = Debug|x86
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Debug|x86.Build.0 = Debug|x86
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Release|Any CPU.ActiveCfg = Release|x64
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Release|Any CPU.Build.0 = Release|x64
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Release|ARM.ActiveCfg = Release|Any CPU
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Release|ARM.Build.0 = Release|Any CPU
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Release|ARM64.ActiveCfg = Release|arm64
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Release|ARM64.Build.0 = Release|arm64
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Release|iPhone.ActiveCfg = Release|Any CPU
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Release|iPhone.Build.0 = Release|Any CPU
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Release|x64.ActiveCfg = Release|x64
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Release|x64.Build.0 = Release|x64
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Release|x64.Deploy.0 = Release|x64
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Release|x86.ActiveCfg = Release|x86
{7E7C34F0-1391-473C-8A1C-CE3EAF5D66DB}.Release|x86.Build.0 = Release|x86
{7AAA8A01-A4FE-49AD-9664-AC53C4C8EAC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7AAA8A01-A4FE-49AD-9664-AC53C4C8EAC6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7AAA8A01-A4FE-49AD-9664-AC53C4C8EAC6}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -2221,76 +1886,6 @@ Global
{C7F109B9-EA88-4B7E-ADB5-D6407686ADE0}.Release|x64.Build.0 = Release|Any CPU
{C7F109B9-EA88-4B7E-ADB5-D6407686ADE0}.Release|x86.ActiveCfg = Release|Any CPU
{C7F109B9-EA88-4B7E-ADB5-D6407686ADE0}.Release|x86.Build.0 = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|Any CPU.Build.0 = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|ARM.ActiveCfg = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|ARM.Build.0 = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|ARM.Deploy.0 = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|ARM64.Build.0 = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|ARM64.Deploy.0 = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|iPhone.Build.0 = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|iPhone.Deploy.0 = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|x64.ActiveCfg = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|x64.Build.0 = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|x64.Deploy.0 = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|x86.ActiveCfg = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|x86.Build.0 = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Debug|x86.Deploy.0 = Debug|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|Any CPU.ActiveCfg = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|Any CPU.Build.0 = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|Any CPU.Deploy.0 = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|ARM.ActiveCfg = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|ARM.Build.0 = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|ARM.Deploy.0 = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|ARM64.ActiveCfg = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|ARM64.Build.0 = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|ARM64.Deploy.0 = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|iPhone.ActiveCfg = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|iPhone.Build.0 = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|iPhone.Deploy.0 = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|x64.ActiveCfg = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|x64.Build.0 = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|x64.Deploy.0 = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|x86.ActiveCfg = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|x86.Build.0 = Release|Any CPU
{73A9AB65-AF95-4F27-98E2-B3296F9BC198}.Release|x86.Deploy.0 = Release|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Debug|Any CPU.Build.0 = Debug|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Debug|ARM.ActiveCfg = Debug|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Debug|ARM.Build.0 = Debug|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Debug|ARM64.Build.0 = Debug|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Debug|iPhone.Build.0 = Debug|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Debug|x64.ActiveCfg = Debug|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Debug|x64.Build.0 = Debug|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Debug|x86.ActiveCfg = Debug|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Debug|x86.Build.0 = Debug|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Release|Any CPU.ActiveCfg = Release|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Release|Any CPU.Build.0 = Release|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Release|ARM.ActiveCfg = Release|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Release|ARM.Build.0 = Release|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Release|ARM64.ActiveCfg = Release|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Release|ARM64.Build.0 = Release|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Release|iPhone.ActiveCfg = Release|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Release|iPhone.Build.0 = Release|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Release|x64.ActiveCfg = Release|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Release|x64.Build.0 = Release|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Release|x86.ActiveCfg = Release|Any CPU
{48417EE3-BACB-4E04-B48D-B3781862AD81}.Release|x86.Build.0 = Release|Any CPU
{41434AB5-48C3-47D4-8721-D118D87F472B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{41434AB5-48C3-47D4-8721-D118D87F472B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{41434AB5-48C3-47D4-8721-D118D87F472B}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -2700,9 +2295,6 @@ Global
{E50441E8-75F3-406E-9921-30BFC211B5CE} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F}
{8E38AAF2-8C7D-4B0D-AB25-AB37EECB4029} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F}
{4E7DF449-F136-4B90-82CE-D1418CD5123C} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F}
{DEF239E4-AC40-4BD8-8D36-5AA6B36AB86B} = {E50441E8-75F3-406E-9921-30BFC211B5CE}
{7EE23547-B2AC-409D-991C-1FDAE122657C} = {E50441E8-75F3-406E-9921-30BFC211B5CE}
{3763D6C4-82B7-4C13-9BB8-886FC1BD83B6} = {8E38AAF2-8C7D-4B0D-AB25-AB37EECB4029}
{910D6A0F-42AB-4B65-B532-852E864EC006} = {E50441E8-75F3-406E-9921-30BFC211B5CE}
{17FBD44D-D9AA-48C2-9A06-214E8405CF88} = {910D6A0F-42AB-4B65-B532-852E864EC006}
{650572DD-E958-4E42-9B46-1510BA15E571} = {910D6A0F-42AB-4B65-B532-852E864EC006}
@@ -2712,16 +2304,12 @@ Global
{21C392C5-AE41-421A-A127-1A03C4ACA2AD} = {673FF8CD-9E85-4FA1-ABFC-D1149675E138}
{29DE5086-0690-4AE7-9BA9-840F54B249DC} = {E448F863-4C9D-47A4-BC4A-4A1381B54DA4}
{4658B02A-CB1A-4561-AD9C-3B3FF969D7F0} = {83186945-EC14-4B3F-8C6F-B205AA184CA4}
{80E6762E-AB43-41E2-BDB4-7A3E24713977} = {CC46B486-00D7-49E6-ABA3-FDF8F4868D2B}
{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA} = {CC46B486-00D7-49E6-ABA3-FDF8F4868D2B}
{5D9E0EAA-2419-426B-BAB4-EA496C1FF7E9} = {CC46B486-00D7-49E6-ABA3-FDF8F4868D2B}
{FB2CA9B4-71F1-48E8-B9AE-FF4375F4FE43} = {CC46B486-00D7-49E6-ABA3-FDF8F4868D2B}
{E84FF7BC-FC2A-424E-8780-7DA9B487E23F} = {910D6A0F-42AB-4B65-B532-852E864EC006}
{47C151DA-D2B1-43F4-A04E-B454E2134852} = {910D6A0F-42AB-4B65-B532-852E864EC006}
{80EBD601-28AC-4840-B9B8-E6064816A443} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F}
{4A79264D-5BF5-4F89-8066-44E154BF557F} = {80EBD601-28AC-4840-B9B8-E6064816A443}
{DFC341E8-5290-428C-8D2B-6DE2AA163FFE} = {673FF8CD-9E85-4FA1-ABFC-D1149675E138}
{920EF29F-406F-43A9-B002-29DD6B0B4FBF} = {80EBD601-28AC-4840-B9B8-E6064816A443}
{17667B53-1A09-45A6-855A-0F07F9AE044F} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F}
{68DD3E9C-A96C-4128-8D95-DCD65D1FA277} = {17667B53-1A09-45A6-855A-0F07F9AE044F}
{089D4418-975B-455D-9AE1-B9DEC20FF4B1} = {17667B53-1A09-45A6-855A-0F07F9AE044F}
@@ -2730,7 +2318,6 @@ Global
{058F9955-8EFE-4BF3-A8F9-44C57B1F812E} = {17667B53-1A09-45A6-855A-0F07F9AE044F}
{FA9F0E89-E410-400A-86F3-C603E51E62A8} = {910D6A0F-42AB-4B65-B532-852E864EC006}
{C7F109B9-EA88-4B7E-ADB5-D6407686ADE0} = {673FF8CD-9E85-4FA1-ABFC-D1149675E138}
{48417EE3-BACB-4E04-B48D-B3781862AD81} = {8E38AAF2-8C7D-4B0D-AB25-AB37EECB4029}
{41434AB5-48C3-47D4-8721-D118D87F472B} = {83186945-EC14-4B3F-8C6F-B205AA184CA4}
{07C9AC06-5D84-41AB-A3C9-5C5B1A27F526} = {83186945-EC14-4B3F-8C6F-B205AA184CA4}
{5C440EC2-9251-4DB5-A14E-68FF37814F12} = {83186945-EC14-4B3F-8C6F-B205AA184CA4}
@@ -2746,7 +2333,7 @@ Global
{8C996C50-B29F-4CB6-90A7-77C9CD3B0B70} = {910D6A0F-42AB-4B65-B532-852E864EC006}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
RESX_NeutralResourcesLanguage = zh-Hans
SolutionGuid = {9313F2B4-10DA-43AA-A481-CAA7571C740C}
RESX_NeutralResourcesLanguage = zh-Hans
EndGlobalSection
EndGlobal
+2 -2
View File
@@ -7,9 +7,9 @@
<key>CFBundleIdentifier</key>
<string>net.steampp.app</string>
<key>CFBundleShortVersionString</key>
<string>2.8.2</string>
<string>2.8.3</string>
<key>CFBundleVersion</key>
<string>2.8.2.0</string>
<string>2.8.3.0</string>
<key>LSMinimumSystemVersion</key>
<string>10.15</string>
<key>CFBundleDevelopmentRegion</key>
Binary file not shown.
+43 -38
View File
@@ -1,28 +1,33 @@
### 公告
1. 非简中语言将默认隐藏加速和脚本功能,仅能通过切换语言并重启程序的方式还原被隐藏的功能
2. 因经济状况原因,现已停止短信服务节约开销,后续会推出邮箱注册登录,对于仅使用手机号登录的用户请绑定第三方快速登录,否则注销后将无法再次登录,需要等待至邮箱服务推出后支持会暂时在开放短信服务提供换绑邮箱。
3. 自动更新目前仅 Windows 端可用,且由于下载渠道限速可能导致无法更新成功,推荐在官网链接的网盘或群文件中下载压缩包解压覆盖更新(应用商店版由商店更新不受此影响)
4. 在 Android 上因系统限制,目前的加速功能无法正常使用,所以此功能已放弃继续开发,如仍想使用需要自行导入证书到系统目录,使用 adb 工具或 Magisk 之类的软件操作,未来会使用不需要证书的加速功能替换此功能
5. fde 版本需要安装 [ASP.NET Core 运行时 6.0.7 (x64) 与 .NET Core 运行时 6.0.7 (x64)](https://dotnet.microsoft.com/zh-cn/download/dotnet/6.0)
6. Windows x86 与 x64 版本令牌本机加密互不兼容,使用两者版本时注意令牌加密后的文件不能共用。
7. 由于新版本加速功能重构,调整了部分加速项目,这会影响旧版本程序使用加速功能
8. 为了能继续维持开发,从此版本开始将会添加程序内广告,赞助用户可以在设置中关闭所有广告
这是一个修复目前累积问题的版本,也是最后一个.NET 6 的版本,
之后桌面端程序将使用.NET 7 + Avalonia 11.0 重构发布新版本。
届时也会放弃继续对 Win7/8.1 系统的支持,所以这也意味着这是最后一个支持 Win7/8.1 的版本。
也请各位敬请期待之后的 3.0 版本吧~
<!--
### 版本亮点
1. 修复与改进一些已知问题
1. .NET 运行时升级至 6.0.12,使用 fde 版本需要升级运行时
2. ASF 升级至 V5.3.2.4
-->
### 修复问题
1. 修复 Windows FDE 版在 Windows 8.1/10 上错误识别成 Windows 8
2. 修复 网络加速 DNS 设置无效
3. 修复 网络加速 PAC 代理模式不能正常工作
4. 修复 Windows 7 上的一些兼容性问题导致加速失效
5. 改进 Windows Desktop Bridge 版本中不再弹出防火墙规则授权弹窗
6. 修复 Windows Desktop Bridge 版本开机自启静默失效
7. 改进 DNS 驱动拦截模式停止后不再占用 sys 文件
8. 改进 通知 UI 列表项中仅显示两行文字
9. 修复 第三方快速登录失败
10. 改进 关闭代理时仅根据当前代理模式进行清理
1. 改进 Mac 安装证书的提示,显示执行命令
2. 修复 Steam 启动参数在一些场景下无效
3. 修复 网络加速 关闭 http 重定向到 https 依然监听 80 端口错误
4. 修复 网络加速 仅启用脚本功能 导致代理网站无法访问的错误
5. 修复 网络加速 开启系统代理和 PAC 代理后,非代理网站无法正常访问的错误
6. 修改 证书安装路径 为本地计算机 而不在是 当前用户 以支持跨用户访问,这项改动可能导致大家需要重新安装一次证书
7. 修复 库存游戏 因 Steam 客户端更新导致的加载游戏数据失败问题
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. 修复 库存游戏 首次加载后,游戏加载失败提示文本依然存在
<!--
### 已知问题
@@ -58,7 +63,7 @@
[![WebSite steampp.net](https://img.shields.io/badge/WebSite-steampp.net-brightgreen.svg?style=flat-square&color=61dafb)](https://steampp.net)
[![Steam++ v2.8.2](https://img.shields.io/badge/Steam++-v2.8.2-brightgreen.svg?style=flat-square&color=512bd4)]()
[![Steam++ v2.8.5](https://img.shields.io/badge/Steam++-v2.8.5-brightgreen.svg?style=flat-square&color=512bd4)]()
##### [不知道该下载哪个文件?](./download-guide.md)
@@ -67,28 +72,28 @@
### 文件校验
| File | Checksum (SHA256) |
| ---- | ---- |
| Steam++_win_x64_v2.8.2.7z | SHA256 |
| Steam++_win_x64_fde_v2.8.2.7z | SHA256 |
| Steam++_win_x64_v2.8.5.7z | SHA256 |
| Steam++_win_x64_fde_v2.8.5.7z | SHA256 |
| | |
| Steam++_win_x64_v2.8.2.exe | SHA256 |
| Steam++_win_x64_fde_v2.8.2.exe | SHA256 |
| Steam++_win_x64_v2.8.5.exe | SHA256 |
| Steam++_win_x64_fde_v2.8.5.exe | SHA256 |
| | |
| Steam++_win_x86_v2.8.2.7z | SHA256 |
| Steam++_win_x86_fde_v2.8.2.7z | SHA256 |
| Steam++_win_x86_v2.8.5.7z | SHA256 |
| Steam++_win_x86_fde_v2.8.5.7z | SHA256 |
| | |
| Steam++_win_x86_v2.8.2.exe | SHA256 |
| Steam++_win_x86_fde_v2.8.2.exe | SHA256 |
| Steam++_win_x86_v2.8.5.exe | SHA256 |
| Steam++_win_x86_fde_v2.8.5.exe | SHA256 |
| | |
| Steam++_linux_x64_v2.8.2.7z | SHA256 |
| Steam++_linux_arm64_v2.8.2.7z | SHA256 |
| Steam++_linux_x64_v2.8.5.7z | SHA256 |
| Steam++_linux_arm64_v2.8.5.7z | SHA256 |
| | |
| Steam++_linux_x64_v2.8.2.deb | SHA256 |
| Steam++_linux_arm64_v2.8.2.deb | SHA256 |
| Steam++_linux_x64_v2.8.5.deb | SHA256 |
| Steam++_linux_arm64_v2.8.5.deb | SHA256 |
| | |
| Steam++_linux_x64_v2.8.2.rpm | SHA256 |
| Steam++_linux_arm64_v2.8.2.rpm | SHA256 |
| Steam++_linux_x64_v2.8.5.rpm | SHA256 |
| Steam++_linux_arm64_v2.8.5.rpm | SHA256 |
| | |
| Steam++_macos_x64_v2.8.2.dmg | SHA256 |
| Steam++_macos_arm64_v2.8.2.dmg | SHA256 |
| Steam++_macos_x64_v2.8.5.dmg | SHA256 |
| Steam++_macos_arm64_v2.8.5.dmg | SHA256 |
| | |
| Steam++_android_v2.8.2.apk | SHA256 |
| Steam++_android_v2.8.5.apk | SHA256 |
@@ -0,0 +1,219 @@
// https://github.com/AvaloniaUI/Avalonia/blob/0.10.17/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Interactivity;
using Avalonia.Platform;
using Avalonia.Threading;
namespace Avalonia.Controls.ApplicationLifetimes
{
sealed class ClassicDesktopStyleApplicationLifetime2 : IClassicDesktopStyleApplicationLifetime, IDisposable
{
private int _exitCode;
private CancellationTokenSource? _cts;
private bool _isShuttingDown;
private HashSet<Window> _windows = new();
private static ClassicDesktopStyleApplicationLifetime2? _activeLifetime;
static ClassicDesktopStyleApplicationLifetime2()
{
Window.WindowOpenedEvent.AddClassHandler(typeof(Window), OnWindowOpened);
Window.WindowClosedEvent.AddClassHandler(typeof(Window), WindowClosedEvent);
}
private static void WindowClosedEvent(object sender, RoutedEventArgs e)
{
_activeLifetime?._windows.Remove((Window)sender);
_activeLifetime?.HandleWindowClosed((Window)sender);
}
private static void OnWindowOpened(object sender, RoutedEventArgs e)
{
_activeLifetime?._windows.Add((Window)sender);
}
public ClassicDesktopStyleApplicationLifetime2()
{
if (_activeLifetime != null)
throw new InvalidOperationException(
"Can not have multiple active ClassicDesktopStyleApplicationLifetime instances and the previously created one was not disposed");
_activeLifetime = this;
}
/// <inheritdoc/>
public event EventHandler<ControlledApplicationLifetimeStartupEventArgs>? Startup;
/// <inheritdoc/>
public event EventHandler<ShutdownRequestedEventArgs>? ShutdownRequested;
/// <inheritdoc/>
public event EventHandler<ControlledApplicationLifetimeExitEventArgs>? Exit;
/// <summary>
/// Gets the arguments passed to the AppBuilder Start method.
/// </summary>
public string[]? Args { get; set; }
/// <inheritdoc/>
public ShutdownMode ShutdownMode { get; set; }
/// <inheritdoc/>
public Window? MainWindow { get; set; }
public IReadOnlyList<Window> Windows => _windows.ToList();
private void HandleWindowClosed(Window window)
{
if (window == null)
return;
if (_isShuttingDown)
return;
if (ShutdownMode == ShutdownMode.OnLastWindowClose && _windows.Count == 0)
TryShutdown();
else if (ShutdownMode == ShutdownMode.OnMainWindowClose && ReferenceEquals(window, MainWindow))
TryShutdown();
}
public void Shutdown(int exitCode = 0)
{
DoShutdown(new ShutdownRequestedEventArgs(), true, exitCode);
}
public bool TryShutdown(int exitCode = 0)
{
return DoShutdown(new ShutdownRequestedEventArgs(), false, exitCode);
}
public int Start(string[] args)
{
Startup?.Invoke(this, new ControlledApplicationLifetimeStartupEventArgs(args));
var options = AvaloniaLocator.Current.GetService<ClassicDesktopStyleApplicationLifetimeOptions>();
if (options != null && options.ProcessUrlActivationCommandLine && args.Length > 0)
{
if (Application.Current is IApplicationPlatformEvents events)
{
events.RaiseUrlsOpened(args);
}
}
var lifetimeEvents = AvaloniaLocator.Current.GetService<IPlatformLifetimeEventsImpl>();
if (lifetimeEvents != null)
lifetimeEvents.ShutdownRequested += OnShutdownRequested;
_cts = new CancellationTokenSource();
// Note due to a bug in the JIT we wrap this in a method, otherwise MainWindow
// gets stuffed into a local var and can not be GCed until after the program stops.
// this method never exits until program end.
ShowMainWindow();
Dispatcher.UIThread.MainLoop(_cts.Token);
Environment.ExitCode = _exitCode;
return _exitCode;
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void ShowMainWindow()
{
MainWindow?.Show();
}
public void Dispose()
{
if (_activeLifetime == this)
_activeLifetime = null;
}
private bool DoShutdown(ShutdownRequestedEventArgs e, bool force = false, int exitCode = 0)
{
if (!force)
{
ShutdownRequested?.Invoke(this, e);
if (e.Cancel)
return false;
// https://appcenter.ms/orgs/BeyondDimension/apps/Steam/crashes/errors/3780037517u/overview
// ClassicDesktopStyleApplicationLifetime.DoShutdown (ShutdownRequestedEventArgs e, Boolean force, Int32 exitCode) /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs, line 147
// System.InvalidOperationException: Application is already shutting down.
// v2.8.2 | 73 users | 76 reports
// Exception Stack:
// System.InvalidOperationException: Application is already shutting down.
// at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.DoShutdown(ShutdownRequestedEventArgs e, Boolean force, Int32 exitCode) in /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 147
// at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.OnShutdownRequested(Object sender, ShutdownRequestedEventArgs e) in /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 186
// at Avalonia.Win32.Win32Platform.WndProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam) in /_/src/Windows/Avalonia.Win32/Win32Platform.cs:line 283
if (_isShuttingDown)
// throw new InvalidOperationException("Application is already shutting down.");
return true;
}
_exitCode = exitCode;
_isShuttingDown = true;
try
{
// When an OS shutdown request is received, try to close all non-owned windows. Windows can cancel
// shutdown by setting e.Cancel = true in the Closing event. Owned windows will be shutdown by their
// owners.
foreach (var w in Windows)
{
if (w.Owner is null)
{
w.Close();
}
}
if (!force && Windows.Count > 0)
{
e.Cancel = true;
return false;
}
var args = new ControlledApplicationLifetimeExitEventArgs(exitCode);
Exit?.Invoke(this, args);
_exitCode = args.ApplicationExitCode;
}
finally
{
_cts?.Cancel();
_cts = null;
_isShuttingDown = false;
}
return true;
}
private void OnShutdownRequested(object sender, ShutdownRequestedEventArgs e) => DoShutdown(e);
}
}
namespace Avalonia
{
public static class ClassicDesktopStyleApplicationLifetimeExtensions
{
public static int StartWithClassicDesktopLifetime2<T>(
this T builder, string[] args, ShutdownMode shutdownMode = ShutdownMode.OnLastWindowClose)
where T : AppBuilderBase<T>, new()
{
var lifetime = new ClassicDesktopStyleApplicationLifetime2()
{
Args = args,
ShutdownMode = shutdownMode,
};
builder.SetupWithLifetime(lifetime);
return lifetime.Start(args);
}
}
}
@@ -11,11 +11,22 @@ namespace System.Application;
/// </summary>
public static class MainThread2
{
static IMainThreadPlatformService? mInterface;
static IMainThreadPlatformService Interface
{
get
{
if (mInterface == null) mInterface = IMainThreadPlatformService.Instance;
return mInterface;
}
}
/// <summary>
/// 获取当前是否为主线程。
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsMainThread() => IMainThreadPlatformService.Instance.PlatformIsMainThread;
public static bool IsMainThread() => Interface.PlatformIsMainThread;
/// <summary>
/// 调用应用程序主线程上的操作。
@@ -33,7 +44,7 @@ public static class MainThread2
{
try
{
IMainThreadPlatformService.Instance.PlatformBeginInvokeOnMainThread(action, priority);
Interface.PlatformBeginInvokeOnMainThread(action, priority);
}
catch (InvalidOperationException)
{
@@ -1,6 +1,7 @@
using SQLite;
using System.Application.Entities;
using System.Application.Repositories;
using System.Application.Settings;
using System.Diagnostics;
using System.Globalization;
using SQLiteNotNull = SQLite.NotNullAttribute;
@@ -8,8 +9,13 @@ using SQLiteTable = SQLite.TableAttribute;
namespace System.Application.Services.Implementation;
internal sealed class PreferencesPlatformServiceImpl : IPreferencesGenericPlatformService
#if DBREEZE
partial class PreferencesPlatformServiceImplV2
#else
sealed class PreferencesPlatformServiceImpl : IPreferencesGenericPlatformService
#endif
{
#if !DBREEZE
readonly SQLiteConnection conn;
public PreferencesPlatformServiceImpl()
@@ -17,9 +23,9 @@ internal sealed class PreferencesPlatformServiceImpl : IPreferencesGenericPlatfo
conn = Repository.GetDbConnectionSync<Entity>();
}
static string GetId(string key) => $"{key}_K";
internal static string GetId(string key) => $"{key}_K";
static string GetId(string key, string? sharedName)
internal static string GetId(string key, string? sharedName)
{
if (sharedName == null) return GetId(key);
return $"{key}_{sharedName}_S";
@@ -75,12 +81,14 @@ internal sealed class PreferencesPlatformServiceImpl : IPreferencesGenericPlatfo
});
}
}
#endif
const string TableName = "1984415E";
const string ColumnName_Id = "0F5E4BAA";
const string ColumnName_Value = "4FC331D7";
const string ColumnName_SharedName = "F6A739AA";
#if !DBREEZE
const string Sql_Delete_Where_SharedName_Equals =
$"DELETE FROM \"{TableName}\" WHERE \"{ColumnName_SharedName}\" = ?";
@@ -101,12 +109,12 @@ internal sealed class PreferencesPlatformServiceImpl : IPreferencesGenericPlatfo
//const string Sql_Select_Value_Where_Key_Equals_And_SharedName_Equals =
// $"SELECT \"{ColumnName_Value}\" FROM \"{TableName}\" WHERE \"{ColumnName_Id}\" = ? AND \"{ColumnName_SharedName}\" = ?";
#endif
[SQLiteTable(TableName)]
[DebuggerDisplay("{DebuggerDisplay(),nq}")]
public sealed class Entity : IEntity<string>
{
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
[Column(ColumnName_Id)]
[PrimaryKey]
[SQLiteNotNull]
@@ -115,7 +123,6 @@ internal sealed class PreferencesPlatformServiceImpl : IPreferencesGenericPlatfo
[Column(ColumnName_Value)]
[SQLiteNotNull]
public string Value { get; set; } = string.Empty;
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
[Column(ColumnName_SharedName)]
[SQLiteNotNull]
@@ -124,3 +131,121 @@ internal sealed class PreferencesPlatformServiceImpl : IPreferencesGenericPlatfo
string DebuggerDisplay() => SharedName == string.Empty ? $"{Id}, {Value}" : $"{Id}, {Value}, {SharedName}";
}
}
#if DBREEZE
public sealed partial class PreferencesPlatformServiceImplV2 : IPreferencesGenericPlatformService
{
static string GetTableName(string? sharedName) => $"Preferences.{sharedName}";
public void PlatformSet<T>(string key, T? value, string? sharedName) where T : notnull, IConvertible
{
if (value == null)
{
PlatformRemove(key, sharedName);
}
else
{
using var t = SettingsProviderV3.Provider.GetTransaction();
t.Insert(GetTableName(sharedName), key, value.ToString(CultureInfo.InvariantCulture));
t.Commit();
}
}
public void PlatformClear(string? sharedName)
{
using var t = SettingsProviderV3.Provider.GetTransaction();
t.RemoveAllKeys(GetTableName(sharedName), true);
t.Commit();
}
public bool PlatformContainsKey(string key, string? sharedName)
{
using var t = SettingsProviderV3.Provider.GetTransaction();
var row = t.Select<string, string>(GetTableName(sharedName), key);
if (row == null) return false;
return row.Exists;
}
public T? PlatformGet<T>(string key, T? defaultValue, string? sharedName) where T : notnull, IConvertible
{
using var t = SettingsProviderV3.Provider.GetTransaction();
var row = t.Select<string, string>(GetTableName(sharedName), key);
if (row == null || !row.Exists) return defaultValue;
var value = ConvertibleHelper.Convert<T>(row.Value);
return value;
}
public void PlatformRemove(string key, string? sharedName)
{
using var t = SettingsProviderV3.Provider.GetTransaction();
t.RemoveKey(GetTableName(sharedName), key);
t.Commit();
}
/// <summary>
/// 将数据从
/// <para>使用 SQLiteConnection 的 PreferencesPlatformServiceImpl</para>
/// <para>迁移到</para>
/// <para>使用 DBreeze 的 PreferencesPlatformServiceImplV2</para>
/// </summary>
public static void Migrate()
{
var dbPath = Repository.DataBaseDirectory;
bool isOK = false;
bool exists = false;
try
{
var dbFilePath = Path.Combine(dbPath, "application2.dbf");
try
{
exists = File.Exists(dbFilePath);
}
catch
{
}
if (!exists) return;
var conn = new SQLiteConnection(dbPath, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create | SQLiteOpenFlags.SharedCache);
var items = conn.Table<Entity>().ToArray();
if (items.Any())
{
var itemGroups = items.GroupBy(x => x.SharedName).ToArray();
foreach (var itemGroup in itemGroups)
{
using var t = SettingsProviderV3.Provider.GetTransaction();
foreach (var item in itemGroup)
{
if (item.Value != null)
{
string key;
if (string.IsNullOrEmpty(item.SharedName)) key = item.Id.TrimEnd("_K");
else key = item.Id.TrimEnd($"_{item.SharedName}_S");
var tableName = GetTableName(item.SharedName);
t.Insert(tableName, key, item.Value.ToString(CultureInfo.InvariantCulture));
}
}
t.Commit();
}
}
conn.Close();
conn.Dispose();
isOK = true;
}
catch
{
}
finally
{
if (isOK)
{
var files = Directory.GetFiles(dbPath, "application2*");
foreach (var item in files)
{
IOPath.FileTryDelete(item);
}
}
}
}
}
#endif
@@ -62,7 +62,11 @@ public static class ServiceCollectionExtensions
/// <returns></returns>
public static IServiceCollection AddRepositoryPreferences(this IServiceCollection services)
{
#if DBREEZE
services.AddSingleton<IPreferencesPlatformService, PreferencesPlatformServiceImplV2>();
#else
services.AddSingleton<IPreferencesPlatformService, PreferencesPlatformServiceImpl>();
#endif
return services;
}
}
@@ -1,3 +1,4 @@
#if !DBREEZE
using System.Diagnostics.CodeAnalysis;
namespace System.Application.Settings;
@@ -60,7 +61,7 @@ public sealed class FileSettingsProvider : ISerializationProvider
lock (_sync)
{
using var stream = new FileStream(_path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete);
using var stream = OpenReadWrite(_path);
if (stream.Position > 0)
{
stream.Position = 0;
@@ -71,6 +72,28 @@ public sealed class FileSettingsProvider : ISerializationProvider
}
}
static FileStream OpenReadWrite(string path)
{
try
{
return OpenReadWrite();
}
catch (Exception)
{
if (File.Exists(path))
{
if (IOPath.FileTryDelete(path))
{
// 直接打开文件流失败,尝试删除后再打开一次
return OpenReadWrite();
}
}
throw;
}
FileStream OpenReadWrite() => new(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete);
}
public void Load()
{
if (File.Exists(_path))
@@ -82,7 +105,7 @@ public sealed class FileSettingsProvider : ISerializationProvider
{
stream.Position = 0;
}
var source = Serializable.DMP<IDictionary<string, object?>>(stream);
var source = stream.Length == 0 ? null : Serializable.DMP<IDictionary<string, object?>>(stream);
//var source = XamlServices.Load(stream) as IDictionary<string, object>;
_settings = source == null
? new SortedDictionary<string, object?>()
@@ -107,4 +130,5 @@ public sealed class FileSettingsProvider : ISerializationProvider
add { }
remove { }
}
}
}
#endif
@@ -1,3 +1,4 @@
#if !DBREEZE
using System.Diagnostics.CodeAnalysis;
namespace System.Application.Settings;
@@ -22,4 +23,5 @@ public interface ISerializationProvider
bool RemoveValue(string key);
string ToJsonString();
}
}
#endif
@@ -1,3 +1,4 @@
#if !DBREEZE
using System.ComponentModel;
using System.Diagnostics;
@@ -194,4 +195,5 @@ public class SerializableProperty<T> : INotifyPropertyChanged
}
#endregion
}
}
#endif
@@ -1,3 +1,4 @@
#if !DBREEZE
using System.Runtime.CompilerServices;
namespace System.Application.Settings;
@@ -43,23 +44,96 @@ public static class SettingsHost
}
catch (Exception ex)
{
Log.Error(nameof(SettingsHost), "Config Save", ex);
Log.Error(nameof(SettingsHost), ex, "Config Save");
throw;
}
}
/// <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;
TryBackup(bakLocalFilePath);
}
catch (Exception ex)
{
Log.Error(nameof(SettingsHost), "Config Load", ex);
if (!TryRestoreBackup(bakLocalFilePath))
{
// 还原备份文件失败,删除当前配置
TryDelete();
}
File.Delete(SettingsHostBase.LocalFilePath);
SettingsHostBase.Local.Load();
Log.Error(nameof(SettingsHost), ex, $"Config Load, isLoad: {isLoad}");
if (!isLoad) SettingsHostBase.Local.Load();
}
}
}
@@ -85,5 +159,6 @@ public abstract class SettingsHost2<TSettings> : SettingsHostBase where TSetting
static string GetKey(string propertyName) => $"{CategoryName}.{propertyName}";
public static SerializableProperty<T> GetProperty<T>(T? defaultValue, bool autoSave, [CallerMemberName] string propertyName = "") => GetProperty(GetKey, Local, defaultValue, autoSave, propertyName);
}
public static SerializableProperty<T> GetProperty<T>(T? defaultValue, bool autoSave = true, [CallerMemberName] string propertyName = "") => GetProperty(GetKey, Local, defaultValue, autoSave, propertyName);
}
#endif
@@ -0,0 +1,168 @@
#if DBREEZE
using DBreeze;
using System.ComponentModel;
using System.Diagnostics;
using static System.Application.Settings.ISerializableProperty;
namespace System.Application.Settings;
public interface ISerializableProperty : INotifyPropertyChanged
{
public const string tableName = "SerializableProperty";
}
[DebuggerDisplay("Value={Value}, Key={Key}, Default={Default}")]
public sealed class SerializableProperty<T> : ISerializableProperty, INotifyPropertyChanged
{
T? _value;
bool _cached;
DBreezeEngine? _Provider;
public string Key { get; }
public DBreezeEngine Provider { get => _Provider ?? throw new ArgumentNullException(nameof(_Provider)); set => _Provider = value; }
public T? Default { get; }
public T? Value
{
get
{
if (!_cached)
{
{
using var t = Provider.GetTransaction();
var row = t.Select<string, byte[]>(tableName, Key);
if (row?.Value == null)
{
_value = Default;
}
else
{
try
{
_value = Serializable.DMP<T>(row.Value);
}
catch
{
_value = Default;
}
}
}
_cached = true;
}
return _value;
}
set
{
var comparer = EqualityComparer<T?>.Default;
if (_cached && comparer.Equals(_value, value)) return;
var old = _value;
_value = value;
_cached = true;
SetValue(comparer, old, value);
}
}
void SetValue(EqualityComparer<T?> comparer, T? oldValue, T? newValue)
{
{
using var t = Provider.GetTransaction();
if (comparer.Equals(newValue, Default))
t.RemoveKey(tableName, Key);
else
t.Insert(tableName, Key, Serializable.SMP(newValue));
t.Commit();
}
OnValueChanged(oldValue, newValue);
}
public override string ToString() => Value?.ToString() ?? string.Empty;
public void RaiseValueChanged()
{
var comparer = EqualityComparer<T?>.Default;
SetValue(comparer, _value, _value);
}
public SerializableProperty(string key, DBreezeEngine provider) : this(key, provider, default)
{
}
public SerializableProperty(string key, DBreezeEngine provider, T? defaultValue)
{
Key = key;
Provider = provider;
Default = defaultValue;
}
public IDisposable Subscribe(Action<T?> listener, bool notifyOnInitialValue = true)
{
if (notifyOnInitialValue)
listener(Value);
return new ValueChangedEventListener(this, listener);
}
public void Reset()
{
var comparer = EqualityComparer<T?>.Default;
SetValue(comparer, _value, Default);
}
sealed class ValueChangedEventListener : IDisposable
{
private readonly Action<T?> _listener;
private readonly SerializableProperty<T> _source;
public ValueChangedEventListener(SerializableProperty<T> property, Action<T?> listener)
{
_listener = listener;
_source = property;
_source.ValueChanged += HandleValueChanged;
}
private void HandleValueChanged(object? sender, ValueChangedEventArgs<T?> args)
{
_listener(args.NewValue);
}
public void Dispose()
{
_source.ValueChanged -= HandleValueChanged;
}
}
public static implicit operator T?(SerializableProperty<T> property) => property.Value;
#region events
public event EventHandler<ValueChangedEventArgs<T?>>? ValueChanged;
void OnValueChanged(T? oldValue, T? newValue) => ValueChanged?.Invoke(this, new ValueChangedEventArgs<T?>(oldValue, newValue));
readonly Dictionary<PropertyChangedEventHandler, EventHandler<ValueChangedEventArgs<T>>> _handlers = new();
event PropertyChangedEventHandler? INotifyPropertyChanged.PropertyChanged
{
add
{
if (value == null) return;
ValueChanged += _handlers[value] = (sender, args) => value(sender, new PropertyChangedEventArgs(nameof(Value)));
}
remove
{
if (value == null) return;
if (_handlers.TryGetValue(value, out var handler))
{
ValueChanged -= handler;
_handlers.Remove(value);
}
}
}
#endregion
}
#endif
@@ -0,0 +1,28 @@
#if DBREEZE
using System.Runtime.CompilerServices;
namespace System.Application.Settings;
public static class SettingsHost
{
public static void Load() => SettingsProviderV3.Load();
[Obsolete]
public static void Save()
{
}
}
public abstract class SettingsHost2<TSettings> where TSettings : SettingsHost2<TSettings>, new()
{
static readonly string CategoryName = typeof(TSettings).Name;
static string GetKey(string propertyName) => $"{CategoryName}.{propertyName}";
public static SerializableProperty<T> GetProperty<T>(T? defaultValue, [CallerMemberName] string propertyName = "") => new(GetKey(propertyName), SettingsProviderV3.Provider, defaultValue);
[Obsolete("autoSave N/A")]
public static SerializableProperty<T> GetProperty<T>(T? defaultValue, bool autoSave, [CallerMemberName] string propertyName = "") => new(GetKey(propertyName), SettingsProviderV3.Provider, defaultValue);
}
#endif
@@ -0,0 +1,90 @@
#if DBREEZE
using DBreeze;
using DBreeze.Utils;
namespace System.Application.Settings;
public static class SettingsProviderV3
{
static DBreezeEngine? _Provider;
static readonly object lock_load = new();
public static DBreezeEngine Provider
{
get
{
if (_Provider == null) Load();
return _Provider ?? throw new ArgumentNullException(nameof(_Provider));
}
set => _Provider = value;
}
public static void Load()
{
lock (lock_load)
{
if (_Provider == null)
{
_Provider = new(Path.Combine(IOPath.AppDataDirectory, "Config"));
//Setting up NetJSON serializer (from NuGet) to be used by DBreeze
CustomSerializator.ByteArraySerializator = value => Serializable.SMP(value == null ? typeof(object) : value.GetType(), value!);
CustomSerializator.ByteArrayDeSerializator = (buffer, type) => Serializable.DMP(type, buffer);
}
}
}
/// <summary>
/// 将数据从
/// <para>使用 <see cref="IDictionary{TKey, TValue}"/> + <see cref="MessagePack"/> 单文件 的 FileSettingsProvider</para>
/// <para>迁移到</para>
/// <para>使用 DBreeze 的 SettingsProviderV3</para>
/// </summary>
public static void Migrate()
{
var filePath = Path.Combine(IOPath.AppDataDirectory, "Config" + FileEx.MPO);
bool exists = false;
try
{
exists = File.Exists(filePath);
}
catch
{
}
if (exists)
{
try
{
using var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
if (stream.Position > 0)
{
stream.Position = 0;
}
var source = stream.Length == 0 ? null : Serializable.DMP<IDictionary<string, object?>>(stream);
if (source.Any_Nullable())
{
if (_Provider == null) Load();
using var t = Provider.GetTransaction();
foreach (var item in source)
{
if (item.Value == null) continue;
var valueType = item.Value.GetType();
var value = Serializable.SMP(valueType, item.Value);
t.Insert(ISerializableProperty.tableName, item.Key, value);
}
t.Commit();
}
}
catch
{
}
finally
{
IOPath.FileTryDelete(filePath);
}
}
}
}
#endif
@@ -1,6 +1,6 @@
namespace System.Application.Settings;
public sealed class ValueChangedEventArgs<T> : EventArgs where T : notnull
public sealed class ValueChangedEventArgs<T> : EventArgs
{
public T? OldValue { get; }
+1
View File
@@ -20,6 +20,7 @@
<PackageReference Include="gfoidl.Base64" />
<PackageReference Include="MessagePack" />
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="DBreeze" Condition=" $(DefineConstants.Contains('DBREEZE')) " />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard')) ">
+2 -8
View File
@@ -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);
}
@@ -8,10 +8,16 @@ public static partial class EnumExtensions
/// <summary>
/// 返回一个布尔值,该值指示给定的整数值或其名称字符串是否存在于指定的枚举中
/// </summary>
/// <typeparam name="TEnum"></typeparam>
/// <param name="value"></param>
/// <returns>如果 enumType 中的某个常量的值等于 value,则为 <see langword="true"/>;否则为 <see langword="false"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsDefined(this Enum value) => Enum.IsDefined(value.GetType(), value);
public static bool IsDefined<TEnum>(this TEnum value) where TEnum : struct, Enum
#if NET5_0_OR_GREATER
=> Enum.IsDefined(value);
#else
=> Enum.IsDefined(typeof(TEnum), value);
#endif
public static TEnum ConvertToEnum<TEnum>(this sbyte value)
where TEnum : Enum
@@ -34,4 +34,23 @@ public static class ProcessExtensions
process.Kill();
#endif
}
/// <summary>
/// 尝试 Process 组件在指定的毫秒数内等待关联进程退出。
/// </summary>
/// <param name="process"></param>
/// <param name="milliseconds"></param>
/// <returns></returns>
public static bool TryWaitForExit(this Process process, int milliseconds = 9000)
{
try
{
return process.WaitForExit(milliseconds);
}
catch
{
}
return false;
}
}
@@ -3,11 +3,11 @@ namespace System;
public static partial class StringExtensions
{
public static string TrimStart(this string s, string trimString)
public static string TrimStart(this string s, string value)
{
if (trimString.StartsWith(trimString))
if (s.StartsWith(value))
{
return s[trimString.Length..];
return s[value.Length..];
}
else
{
@@ -15,11 +15,11 @@ public static partial class StringExtensions
}
}
public static string TrimEnd(this string s, string trimString)
public static string TrimEnd(this string s, string value)
{
if (trimString.EndsWith(trimString))
if (s.EndsWith(value))
{
return s[..^trimString.Length];
return s[..^value.Length];
}
else
{
@@ -27,11 +27,11 @@ public static partial class StringExtensions
}
}
public static string TrimStart(this string s, string trimString, StringComparison comparisonType)
public static string TrimStart(this string s, string value, StringComparison comparisonType)
{
if (trimString.StartsWith(trimString, comparisonType))
if (s.StartsWith(value, comparisonType))
{
return s[trimString.Length..];
return s[value.Length..];
}
else
{
@@ -39,11 +39,11 @@ public static partial class StringExtensions
}
}
public static string TrimEnd(this string s, string trimString, StringComparison comparisonType)
public static string TrimEnd(this string s, string value, StringComparison comparisonType)
{
if (trimString.EndsWith(trimString, comparisonType))
if (s.EndsWith(value, comparisonType))
{
return s[..^trimString.Length];
return s[..^value.Length];
}
else
{
+5
View File
@@ -132,6 +132,11 @@ public static class FileEx
public const string Qt = ".qt";
public const string Wmv = ".wmv";
/// <summary>
/// 导入注册条目 (.reg) 文件是 Regedit.exe 的功能,Regedt32.exe 不支持。您可以使用 Regedit.exe 对基于 Windows NT 4.0 或基于 Windows 2000 的计算机上注册表进行一些更改,但某些更改需要 Regedt32.exe。
/// </summary>
public const string Reg = ".reg";
public static readonly string[] ImageFileExtensions = new string[]
{
PNG,
+87
View File
@@ -153,6 +153,89 @@ public static class IOPath
}
}
static readonly object lock_GetCacheFilePath = new();
/// <summary>
/// 根据缓存子文件夹名称与文件扩展名获取一个缓存文件路径
/// </summary>
/// <param name="dirName">缓存子文件夹名称</param>
/// <param name="fileNamePrefix">文件名前缀</param>
/// <param name="fileEx">文件扩展名</param>
public static string GetCacheFilePath(string dirName, string fileNamePrefix, string fileEx)
{
lock (lock_GetCacheFilePath)
{
var cacheDirPath = Path.Combine(CacheDirectory, dirName);
if (!Directory.Exists(cacheDirPath))
{
Directory.CreateDirectory(cacheDirPath);
return GetCacheFilePath();
}
else
{
string cacheFilePath;
do
{
cacheFilePath = GetCacheFilePath();
} while (File.Exists(cacheFilePath));
return cacheFilePath;
}
string GetCacheFilePath() => Path.Combine(cacheDirPath, GetCacheFileName());
string GetCacheFileName() => $"{fileNamePrefix}_{DateTimeOffset.Now.Ticks}{Random2.GenerateRandomString(4)}{fileEx}";
}
}
/// <summary>
/// 尝试延时一段时间后删除文件
/// </summary>
/// <param name="filePath">要删除的文件路径</param>
/// <param name="millisecondsDelay">延时等待的毫秒数</param>
public static async void TryDeleteInDelay(string filePath, int millisecondsDelay = 9000)
{
await Task.Delay(millisecondsDelay);
FileTryDelete(filePath);
}
/// <summary>
/// 启动进程后尝试延时一段时间后删除文件
/// </summary>
/// <param name="process">启动的进程</param>
/// <param name="filePath">要删除的文件路径</param>
/// <param name="millisecondsDelay">延时等待的毫秒数</param>
/// <param name="processWaitMillisecondsDelay">启动的进程等待退出的毫秒数</param>
public static void TryDeleteInDelay(Process? process, string filePath, int millisecondsDelay = 9000, int processWaitMillisecondsDelay = 9000)
{
if (process != null)
{
var waitForExitResult = process.TryWaitForExit(processWaitMillisecondsDelay);
if (!waitForExitResult)
{
try
{
process.KillEntireProcessTree();
}
catch
{
}
TryDeleteInDelay(filePath, millisecondsDelay);
return;
}
}
FileTryDelete(filePath);
}
/// <summary>
/// 尝试根据缓存子文件夹名称删除整个缓存子文件夹
/// </summary>
/// <param name="dirName">缓存子文件夹名称</param>
public static void TryDeleteCacheSubDir(string dirName)
{
var cacheDirPath = Path.Combine(CacheDirectory, dirName);
DirTryDelete(cacheDirPath);
}
public abstract class FileSystemBase
{
protected FileSystemBase()
@@ -291,6 +374,10 @@ public static class IOPath
{
paths[i] = item;
}
else
{
DirCreateByNotExists(paths[i]);
}
}
InitFileSystem(GetAppDataDirectory, GetCacheDirectory);
+1 -1
View File
@@ -15,7 +15,7 @@ public static class Log
static ILoggerFactory? factory;
public static ILoggerFactory Factory => factory ??= DI.Get_Nullable<ILoggerFactory>() ?? LoggerFactory?.Invoke() ?? throw new ArgumentNullException(nameof(LoggerFactory));
public static ILoggerFactory Factory => factory ??= (DI.IsConfigured ? DI.Get<ILoggerFactory>() : null) ?? LoggerFactory?.Invoke() ?? throw new ArgumentNullException(nameof(LoggerFactory));
public static ILogger CreateLogger(string tag) => Factory.CreateLogger(tag);
@@ -58,7 +58,7 @@ partial class GeneralHttpClientFactory
/// <summary>
/// https://github.com/dotnet/runtime/blob/v6.0.0/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpNoProxy.cs
/// </summary>
sealed class HttpNoProxy : IWebProxy
public sealed class HttpNoProxy : IWebProxy
{
public static readonly HttpNoProxy Instance = new();
@@ -19,6 +19,9 @@ public abstract class HttpPlatformHelperService : IHttpPlatformHelperService
ImageFormat.JPEG,
ImageFormat.PNG,
ImageFormat.GIF,
ImageFormat.WebP,
ImageFormat.BMP,
ImageFormat.ICO,
});
public virtual ImageFormat[] SupportedImageFormats => mSupportedImageFormats.Value;
@@ -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 &lt;CFBundleVersion&gt; &lt;CFBundleShortVersionString&gt; </item>
/// <item> Android:\src\ST.Client.Mobile.Droid.App\Properties\AndroidManifest.xml &lt;manifest ... android:versionCode(long递增) android:versionName </item>
/// <item> UWP(DesktopBridge):\src\ST.Client.Desktop.Avalonia.App.Bridge.Package\Package.appxmanifest &lt;Identity ... Version </item>
/// <item> macOS:\packaging\build-osx-app.sh &lt;CFBundleVersion&gt; &lt;CFBundleShortVersionString&gt; </item>
/// </list>
/// </summary>
public const string Version = "2.8.2";
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 &lt;CFBundleVersion&gt; &lt;CFBundleShortVersionString&gt; </item>
/// <item> Android:\src\ST.Client.Mobile.Droid.App\Properties\AndroidManifest.xml &lt;manifest ... android:versionCode(long递增) android:versionName </item>
/// <item> UWP(DesktopBridge):\src\ST.Client.Desktop.Avalonia.App.Bridge.Package\Package.appxmanifest &lt;Identity ... Version </item>
/// <item> macOS:\packaging\build-osx-app.sh &lt;CFBundleVersion&gt; &lt;CFBundleShortVersionString&gt; </item>
/// </list>
/// </summary>
public const string Version = "2.8.6";
//public const string InfoVersion = Version + "-beta";
}
+8 -1
View File
@@ -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(),
@@ -2,7 +2,7 @@
<PropertyGroup>
<!--<TargetFrameworks>MonoAndroid12.0;netstandard2.1;net6.0-android</TargetFrameworks>-->
<TargetFrameworks>MonoAndroid12.0;netstandard2.1</TargetFrameworks>
<TargetFrameworks>netstandard2.1</TargetFrameworks>
<RootNamespace>System</RootNamespace>
<AssemblyName>System.Common.PinyinLib.TinyPinyin</AssemblyName>
<ImplicitUsings>enable</ImplicitUsings>
@@ -0,0 +1,105 @@
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="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var uri = request.RequestUri;
if (uri == null)
{
throw new ApplicationException("The requested URI must be specified.");
}
// 设置请求头 host,修改协议为 http
request.Headers.Host = uri.Host;
request.RequestUri = new UriBuilder(uri) { Scheme = Uri.UriSchemeHttp }.Uri;
return await base.SendAsync(request, cancellationToken);
}
/// <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;
}
}
+12 -5
View File
@@ -17,8 +17,10 @@ internal static class Program
{
const string ExecutiveName = "Steam++";
static BundleArch matchArch;
static readonly SemanticVersion runtimeVersion = new(6, 0, 7);
static readonly SemanticVersion sdkVersion = new(6, 0, 107);
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>
/// 应用程序的主入口点。
@@ -56,7 +58,7 @@ internal static class Program
if (RuntimeInformation2.OSArchitecture != Architecture.Arm64) throw new PlatformNotSupportedException();
break;
}
if (IsRuntimeInstalled(matchArch, runtimeVersion, sdkVersion))
if (IsRuntimeInstalled(matchArch, runtimeVersion, sdkVersion1, sdkVersion3, sdkVersion4))
{
Run();
}
@@ -193,7 +195,7 @@ internal static class Program
/// 是否已安装运行时或 SDK
/// </summary>
/// <returns></returns>
static bool IsRuntimeInstalled(BundleArch matchArch, SemanticVersion runtimeVersion, SemanticVersion sdkVersion)
static bool IsRuntimeInstalled(BundleArch matchArch, SemanticVersion runtimeVersion, SemanticVersion sdkVersion1, SemanticVersion sdkVersion3, SemanticVersion sdkVersion4)
{
// ArchiSteamFarm 依赖 ASP.NET Core
// ASP.NET Core 运行时安装程序除 Hosting Bundle 不包含 .NET 运行时 缺少文件 C:\Program Files\dotnet\host\fxr\{version}\hostfxr.dll
@@ -202,7 +204,12 @@ internal static class Program
// https://github.com/dotnet/runtime/blob/v6.0.5/src/native/corehost/apphost/apphost.windows.cpp#L106-L113
var installed = RegistryQuery.GetAllInstalledBundles().Where(m => m.Arch.HasFlags(matchArch)).ToArray();
var query_sdk = installed.Where(m => m.Version.Type == BundleType.Sdk && m.Version.SemVer >= sdkVersion);
var query_sdk = installed.Where(m => m.Version.Type == BundleType.Sdk &&
(
(m.Version.SemVer >= sdkVersion1 && m.Version.SemVer < new SemanticVersion(sdkVersion1.Major, sdkVersion1.Minor, 199)) ||
(m.Version.SemVer >= sdkVersion3 && m.Version.SemVer < new SemanticVersion(sdkVersion3.Major, sdkVersion3.Minor, 399)) ||
(m.Version.SemVer >= sdkVersion4 && m.Version.SemVer < new SemanticVersion(sdkVersion4.Major, sdkVersion4.Minor, 499))
));
if (query_sdk.Any()) return true;
var query_runtime = installed.Where(m => (m.Version.Type == BundleType.Runtime || m.Version.Type == BundleType.WindowsDesktopRuntime) && m.Version.SemVer >= runtimeVersion);
@@ -5,6 +5,6 @@ namespace System.Properties
/// <summary>
/// 版本号
/// </summary>
public const string Version = "1.1.0";
public const string Version = "1.1.11";
}
}
@@ -1,15 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<SignAssembly>true</SignAssembly>
<DelaySign>false</DelaySign>
<AssemblyOriginatorKeyFile>$(MSBuildProjectDirectory)\..\..\avalonia.snk</AssemblyOriginatorKeyFile>
<Version>2.2.255.255</Version>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\AssemblyInfo.Version.Max.cs">
<LinkBase>Properties</LinkBase>
</Compile>
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Primitives" />
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="20220725" android:versionName="2.8.2" package="net.steampp.app" android:installLocation="auto">
<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">
<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.-->
@@ -19,7 +19,8 @@
<AotAssemblies>false</AotAssemblies>
<EnableLLVM>false</EnableLLVM>
<AndroidEnableProfiledAot>false</AndroidEnableProfiledAot>
<AndroidLinkMode>None</AndroidLinkMode>
<AndroidLinkMode>Full</AndroidLinkMode>
<AndroidLinkTool>r8</AndroidLinkTool>
<PublishTrimmed>false</PublishTrimmed>
<AndroidFragmentType>AndroidX.Fragment.App.Fragment</AndroidFragmentType>
</PropertyGroup>
@@ -187,7 +188,7 @@
<PackageReference Include="Xamarin.Build.Download" />
<!--<PackageReference Include="Xamarin.AndroidX.Window" />-->
</ItemGroup>
<ItemGroup>
<AndroidAsset Include="..\..\references\Android Assets\cncity.txt" Link="Assets\cncity.txt" />
</ItemGroup>
@@ -553,6 +554,9 @@
<AndroidResource Include="..\ST.Client.Mobile.Droid.Design\ui\src\main\res\layout\activity_toolbar_tablayout_viewpager2.xml">
<Link>Resources\layout\activity_toolbar_tablayout_viewpager2.xml</Link>
</AndroidResource>
<AndroidResource Include="..\ST.Client.Mobile.Droid.Design\ui\src\main\res\layout\activity_toolbar_webview.xml">
<Link>Resources\layout\activity_toolbar_webview.xml</Link>
</AndroidResource>
<AndroidResource Include="..\ST.Client.Mobile.Droid.Design\ui\src\main\res\layout\fragment_about.xml">
<Link>Resources\layout\fragment_about.xml</Link>
</AndroidResource>
@@ -149,6 +149,7 @@
<PackageReference Include="Xamarin.Google.MLKit.BarcodeScanning" />
<PackageReference Include="Xamarin.Build.Download" />
<!--<PackageReference Include="Xamarin.AndroidX.Window" />-->
<PackageReference Include="Microsoft.Net.Http.Headers" />
</ItemGroup>
<!--<ItemGroup Condition="'$(Configuration)'=='Debug'">
@@ -25,7 +25,7 @@ namespace System.Application.UI
VisualStudioAppCenterSDK.Init();
}
void IApplication.IProgramHost.ConfigureServices(DILevel level) => ConfigureServices(this, level);
void IApplication.IProgramHost.ConfigureServices(DILevel level, bool isTrace) => ConfigureServices(this, level, isTrace: isTrace);
void IApplication.IProgramHost.OnStartup() => OnStartup(this);
+1 -5
View File
@@ -102,7 +102,7 @@ namespace System.Application.UI
var level = DILevel.Min;
if (IsMainProcess) level = DILevel.MainProcess;
IApplication.IProgramHost host = this;
host.ConfigureServices(level);
host.ConfigureServices(level, isTrace);
if (isTrace) StartWatchTrace.Record("Startup");
if (IsMainProcess)
@@ -125,8 +125,6 @@ namespace System.Application.UI
if (IsMainProcess)
{
var vmService = IViewModelManager.Instance;
#if __XAMARIN_FORMS__
Forms.Init(this, null);
FormsMaterial.Init(this, null);
@@ -136,8 +134,6 @@ namespace System.Application.UI
_Current = new(RealTheme);
if (isTrace) StartWatchTrace.Record("XFApp");
#endif
vmService.MainWindow!.Initialize();
if (isTrace) StartWatchTrace.Record("MainVM.Init");
}
StartupTrack = StartWatchTrace.ToString();
@@ -2,7 +2,8 @@
<PropertyGroup>
<!--<TargetFrameworks>MonoAndroid12.0;Xamarin.iOS10;net6.0-android;net6.0-windows</TargetFrameworks>-->
<TargetFrameworks>MonoAndroid12.0;Xamarin.iOS10;net6.0-windows</TargetFrameworks>
<!--<TargetFrameworks>MonoAndroid12.0;Xamarin.iOS10;net6.0-windows</TargetFrameworks>-->
<TargetFrameworks>net6.0-windows</TargetFrameworks>
<RootNamespace>System.Application.AppCenter</RootNamespace>
<AssemblyName>System.Application.SteamTools.Client.AppCenter</AssemblyName>
<ImplicitUsings>enable</ImplicitUsings>
+44 -30
View File
@@ -23,7 +23,7 @@ public abstract class CommandLineHost : IDisposable
protected abstract IApplication.IDesktopProgramHost Host { get; }
protected abstract void ConfigureServices(DILevel level);
protected abstract void ConfigureServices(DILevel level, bool isTrace = false);
#if StartWatchTrace
protected abstract void StartWatchTraceRecord(string? mark = null, bool dispose = false);
@@ -136,15 +136,22 @@ public abstract class CommandLineHost : IDisposable
void ProxyMessageReceived()
{
var value = Enum.TryParse<EOnOff>(args[1], out var value_) ? value_ : default;
MainThread2.BeginInvokeOnMainThread(() =>
try
{
ProxyService.Current.ProxyStatus = value switch
MainThread2.BeginInvokeOnMainThread(() =>
{
EOnOff.On => true,
EOnOff.Off => false,
_ => !ProxyService.Current.ProxyStatus,
};
});
ProxyService.Current.ProxyStatus = value switch
{
EOnOff.On => true,
EOnOff.Off => false,
_ => !ProxyService.Current.ProxyStatus,
};
});
}
catch
{
}
}
break;
}
@@ -152,8 +159,15 @@ public abstract class CommandLineHost : IDisposable
break;
}
}
var app = await WaitForApplicationAsync();
MainThread2.BeginInvokeOnMainThread(app.RestoreMainWindow);
try
{
var app = await WaitForApplicationAsync();
MainThread2.BeginInvokeOnMainThread(app.RestoreMainWindow);
}
catch
{
}
};
}
//#if StartWatchTrace
@@ -231,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))
{
@@ -243,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)
{
@@ -252,7 +266,7 @@ public abstract class CommandLineHost : IDisposable
steamService.SetCurrentUser(account);
}
steamService.StartSteam();
steamService.StartSteamWithParameter();
}
});
rootCommand.AddCommand(steamuser);
@@ -297,27 +311,27 @@ public abstract class CommandLineHost : IDisposable
// -clt show -config -cert
var show = new Command("show", "显示信息");
show.AddOption(new Option<bool>("-config", "显示 Config.mpo 值"));
//show.AddOption(new Option<bool>("-config", "显示 Config.mpo 值"));
show.AddOption(new Option<bool>("-cert", "显示当前根证书信息"));
show.Handler = CommandHandler.Create((bool config, bool cert) =>
show.Handler = CommandHandler.Create((/*bool config,*/ bool cert) =>
{
if (OperatingSystem.IsWindows()) if (!AttachConsole()) AllocConsole();
if (config)
{
Console.WriteLine("Config: ");
try
{
SettingsHost.Load();
var configValue = SettingsHostBase.Local.ToJsonString();
Console.WriteLine(configValue);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine();
}
//if (config)
//{
// Console.WriteLine("Config: ");
// try
// {
// SettingsHost.Load();
// var configValue = SettingsHostBase.Local.ToJsonString();
// Console.WriteLine(configValue);
// }
// catch (Exception e)
// {
// Console.WriteLine(e.ToString());
// }
// Console.WriteLine();
//}
if (cert)
{
@@ -11,7 +11,7 @@
<Identity
Name="4651ED44255E.47979655102CE"
Publisher="CN=A90E406B-B2D3-4A23-B061-0FA1D65C4F66"
Version="2.8.1.0" />
Version="2.8.6.0" />
<Properties>
<DisplayName>Watt Toolkit</DisplayName>
+44 -6
View File
@@ -1,13 +1,22 @@
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Runtime.Versioning;
using System.Application.Settings;
using System.Application.CommandLine;
using System.Application.UI.Resx;
using NLog;
using Avalonia;
using Avalonia.ReactiveUI;
using Avalonia.Controls;
using System.Net.Http;
#if WINDOWS || WINDOWS_DESKTOP_BRIDGE
using WPFMessageBox = System.Windows.MessageBox;
using WPFMessageBoxButton = System.Windows.MessageBoxButton;
using WPFMessageBoxImage = System.Windows.MessageBoxImage;
#endif
#if MAC
[assembly: SupportedOSPlatform("macOS")]
@@ -39,17 +48,46 @@ namespace System.Application.UI
// fix The request was aborted: Could not create SSL/TLS secure channel
TrySetSecurityProtocol();
var host = ProgramHost.Instance;
host.IsMainProcess = args.Length == 0;
host.IsCLTProcess = !host.IsMainProcess && args.FirstOrDefault() == "-clt";
#if WINDOWS || WINDOWS_DESKTOP_BRIDGE
HttpClient.DefaultProxy = DynamicHttpWindowsProxy.Instance;
#endif
#if WINDOWS_DESKTOP_BRIDGE
if (!DesktopBridgeHelper.Init()) return 0;
InitWithUWP(ref args);
#elif WINDOWS
//#if NET7_0_OR_GREATER
// if (/*Environment.Version >= new Version(7, 0) && */!OperatingSystem2.IsWindows10AtLeast())
// {
// // [TBD] .NET 7 中考虑弃用对 Windows 7/2008 R2/8.1/2012 R2 的支持
// WPFMessageBox.Show("TBD", AppResources.Error, WPFMessageBoxButton.OK, WPFMessageBoxImage.Error);
// return 0;
// }
//#endif
if (OperatingSystem2.IsWindows10AtLeast() &&
!OperatingSystem.IsWindowsVersionAtLeast(10, 0, 14393))
{
// Win10 最低需要 1607,低于此版本则弹窗错误中止运行
// appcenter.ms 上有 10240,10586 的 crash 报告
WPFMessageBox.Show(AppResources.Error_Lower_Than_Windows10_1607, AppResources.Error, WPFMessageBoxButton.OK, WPFMessageBoxImage.Error);
return 0;
}
if (AppContext.BaseDirectory.StartsWith(Path.GetTempPath(), StringComparison.OrdinalIgnoreCase))
{
// 检测当前目录 Temp\Rar$ 这类目录,可能是在压缩包中直接启动程序导致的,还有一堆 文件找不到/加载失败的异常
// System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Users\USER\AppData\Local\Temp\Rar$EXa15528.13350\Cache\switchproxy.reg'.
// System.IO.FileLoadException ...
// System.IO.FileNotFoundException: Could not load file or assembly ...
WPFMessageBox.Show(AppResources.Error_BaseDir_StartsWith_Temp, AppResources.Error, WPFMessageBoxButton.OK, WPFMessageBoxImage.Error);
return 0;
}
#elif MAC
InitWithMAC(args);
#endif
var host = ProgramHost.Instance;
host.IsMainProcess = args.Length == 0;
host.IsCLTProcess = !host.IsMainProcess && args.FirstOrDefault() == "-clt";
OnCreateAppExecuting();
// InitCefNetApp(args);
@@ -87,7 +125,7 @@ namespace System.Application.UI
{
ServicePointManager.SecurityProtocol = type;
}
catch (NotSupportedException)
catch
{
}
@@ -205,7 +243,7 @@ namespace System.Application.UI
static void StartAvaloniaApp(string[] args, ShutdownMode shutdownMode = ShutdownMode.OnLastWindowClose)
{
var builder = BuildAvaloniaApp();
builder.StartWithClassicDesktopLifetime(args, shutdownMode);
builder.StartWithClassicDesktopLifetime2(args, shutdownMode);
}
}
}
@@ -37,7 +37,7 @@ static partial class
public EOnOff ProxyStatus { get; set; }
void IApplication.IProgramHost.ConfigureServices(DILevel level) => ConfigureServices(level);
void IApplication.IProgramHost.ConfigureServices(DILevel level, bool isTrace) => ConfigureServices(level, isTrace);
public void InitVisualStudioAppCenterSDK()
{
@@ -55,6 +55,14 @@ static partial class
IApplication IApplication.IProgramHost.Application => App.Instance;
void IApplication.IDesktopProgramHost.OnCreateAppExecuted(Action<IViewModelManager>? handlerViewModelManager, bool isTrace) => Program.OnCreateAppExecuted(this, handlerViewModelManager, isTrace);
DeploymentMode IApplication.IDesktopProgramHost.DeploymentMode => DeploymentMode.
#if FRAMEWORK_DEPENDENT || !PUBLISH
FDE
#else
SCD
#endif
;
}
partial class ProgramHost : CommandLineHost
@@ -63,7 +71,7 @@ static partial class
public Action<DILevel>? ConfigureServicesDelegate { get; set; }
protected override void ConfigureServices(DILevel level)
protected override void ConfigureServices(DILevel level, bool isTrace = false)
{
if (ConfigureServicesDelegate != null)
{
@@ -71,7 +79,7 @@ static partial class
}
else
{
Program.ConfigureServices(this, level);
Program.ConfigureServices(this, level, isTrace: isTrace);
}
}
@@ -32,14 +32,22 @@
<DefineConstants>MAC;PUBLISH;$(DefineConstants)</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(ExtraDefineConstants)' == 'win-x64' Or '$(ExtraDefineConstants)' == 'dev-win-x64' ">
<PropertyGroup Condition=" '$(ExtraDefineConstants)' == 'win-x64' Or '$(ExtraDefineConstants)' == 'dev-win-x64' Or '$(ExtraDefineConstants)' == 'win-x86' Or '$(ExtraDefineConstants)' == 'dev-win-x86' ">
<DefineConstants>PUBLISH;PUBLISH_WIN7;WINDOWS;$(DefineConstants)</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(ExtraDefineConstants)' == 'fd-win-x64' Or '$(ExtraDefineConstants)' == 'dev-fd-win-x64' ">
<PropertyGroup Condition=" '$(ExtraDefineConstants)' == 'win-arm64' Or '$(ExtraDefineConstants)' == 'dev-arm64' ">
<DefineConstants>PUBLISH;WINDOWS;$(DefineConstants)</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(ExtraDefineConstants)' == 'fd-win-x64' Or '$(ExtraDefineConstants)' == 'dev-fd-win-x64' Or '$(ExtraDefineConstants)' == 'fd-win-x86' Or '$(ExtraDefineConstants)' == 'dev-fd-win-x86' ">
<DefineConstants>FRAMEWORK_DEPENDENT;PUBLISH;PUBLISH_WIN7;WINDOWS;$(DefineConstants)</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(ExtraDefineConstants)' == 'fd-win-arm64' Or '$(ExtraDefineConstants)' == 'dev-fd-arm64' ">
<DefineConstants>FRAMEWORK_DEPENDENT;PUBLISH;WINDOWS;$(DefineConstants)</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" $(RuntimeIdentifier.Contains(`win`)) Or $(ExtraDefineConstants.Contains(`win`)) Or ('$(OS)' == 'Windows_NT' And !$(DefineConstants.Contains(`PUBLISH`))) ">
<DefineConstants>WINDOWS;$(DefineConstants)</DefineConstants>
<ApplicationIcon>..\ST.Client.Desktop.Avalonia\Application\UI\Assets\Icon.ico</ApplicationIcon>
@@ -482,7 +482,15 @@ namespace System.Application.UI
#endif
//AppHelper.TryShutdown();
INotificationService.ILifeCycle.Instance?.OnShutdown();
try
{
// https://appcenter.ms/orgs/BeyondDimension/apps/Steam/crashes/errors/952960442u/overview
INotificationService.ILifeCycle.Instance?.OnShutdown();
}
catch (ObjectDisposedException)
{
}
}
internal void NotifyIcon_Click(object? sender, EventArgs e)
@@ -667,12 +675,6 @@ namespace System.Application.UI
object IApplication.CurrentPlatformUIHost => MainWindow!;
DeploymentMode IApplication.DeploymentMode => DeploymentMode.
#if FRAMEWORK_DEPENDENT || !PUBLISH
FDE
#else
SCD
#endif
;
DeploymentMode IApplication.DeploymentMode => ProgramHost.DeploymentMode;
}
}
@@ -253,7 +253,7 @@ namespace System.Application.UI
//#endif
// }
static NativeMenuItem? exitMenuItem;
static Dictionary<TabItemViewModel, NativeMenuItem>? tabItems;
static Dictionary<TabItemViewModel.TabItemId, NativeMenuItem>? tabItems;
static IDisposable? InitMenuItems(NativeMenu menu)
{
@@ -262,19 +262,15 @@ namespace System.Application.UI
#else
MainWindowViewModel main = new();
#endif
var query = from x in main.AllTabItems
let tabItem = x is TabItemViewModel item ? item : null
where tabItem != null
select tabItem;
tabItems = new();
foreach (var item in query)
foreach (var item in main.AllTabIdItems)
{
var menuItem = new NativeMenuItem
{
Header = item.Name,
Header = TabItemViewModel.GetName(item),
Command = ReactiveCommand.Create(() =>
{
OnMenuClick(item.Id);
OnMenuClick(item);
}),
};
tabItems.Add(item, menuItem);
@@ -299,7 +295,7 @@ namespace System.Application.UI
}
foreach (var item in tabItems)
{
item.Value.Header = item.Key.Name;
item.Value.Header = TabItemViewModel.GetName(item.Key);
}
});
#else
@@ -193,15 +193,15 @@
Margin="10">
<controls:ScrollingTextBlock Text="{Binding Name}" Classes="h6 semibold"/>
<!--Foreground="#D22222"-->
<!--<controls:ScrollingTextBlock Text="{Binding Amount,Converter={StaticResource StringFormatConverter},ConverterParameter={ReflectionBinding CurrencyCode}}"/>-->
<controls:ScrollingTextBlock>
<controls:ScrollingTextBlock Text="{Binding Amount,Converter={StaticResource StringFormatConverter},ConverterParameter={ReflectionBinding CurrencyCode}}"/>
<!--<controls:ScrollingTextBlock>
<controls:ScrollingTextBlock.Text>
<MultiBinding Converter="{StaticResource StringFormatConverter}" ConverterParameter="money">
<Binding Path="Amount"/>
<Binding Path="CurrencyCode"/>
</MultiBinding>
</controls:ScrollingTextBlock.Text>
</controls:ScrollingTextBlock>
</controls:ScrollingTextBlock>-->
</StackPanel>
</DockPanel>
</Border>
@@ -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;
@@ -160,7 +160,7 @@ namespace System.Application.UI.Views.Pages
chart.Series = new ISeries[] { readSeries, writeSeries };
});
}
catch (Exception)
catch
{
}
finally
@@ -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}}" />
@@ -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);
}
}
@@ -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>
@@ -89,6 +89,27 @@ namespace System.Application.Services.Implementation
ValueTask IPlatformService.RunShellAsync(string script, bool admin) => RunShellAsync(script, admin);
async ValueTask<bool?> IPlatformService.TrustRootCertificate(string filePath)
{
var script = $"security add-trusted-cert -d -r trustRoot -k /Users/{Environment.UserName}/Library/Keychains/login.keychain-db";
TextBoxWindowViewModel vm = new()
{
Title = AppResources.MacTrustRootCertificateTips,
InputType = TextBoxWindowViewModel.TextBoxInputType.Password,
Description = AppResources.MacSudoPasswordTips + $"\r\n sudo {script} \"{filePath}\"",
};
var scriptContent = $"osascript -e 'tell app \"Terminal\" to do script \"sudo -S {script} \\\"{filePath}\\\"\"'";
var msg = UnixHelper.RunShell(scriptContent.ToString());
if (await TextBoxWindowViewModel.ShowDialogAsync(vm) == null)
return null;
if (!string.IsNullOrWhiteSpace(msg))
{
Toast.Show(msg);
return false;
}
return true;
}
/// <summary>
/// 尝试删除证书
/// </summary>
@@ -0,0 +1,19 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// https://github.com/dotnet/wpf/blob/v6.0.6/src/Microsoft.DotNet.Wpf/src/PresentationCore/SR.cs
#if !NETFRAMEWORK && WINDOWS
namespace MS.Internal.PresentationCore;
internal static class SR
{
public static string Get(string name) => name switch
{
SRID.CantShowMBServiceWithOwner => "Cannot show MessageBox Service with Owner.",
_ => "",
};
}
#endif
@@ -0,0 +1,13 @@
#if !NETFRAMEWORK && WINDOWS
namespace MS.Internal.PresentationCore;
static class SRID
{
/// <summary>
/// https://github.com/dotnet/wpf/blob/v6.0.6/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/Strings.resx#L510
/// </summary>
public const string CantShowMBServiceWithOwner = "CantShowMBServiceWithOwner";
}
#endif
@@ -0,0 +1,57 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// https://github.com/dotnet/wpf/blob/v6.0.6/src/Microsoft.DotNet.Wpf/src/Shared/MS/Win32/ExternDll.cs
#if !NETFRAMEWORK && WINDOWS
namespace MS.Win32;
internal static class ExternDll
{
//public const string Activeds = "activeds.dll";
//public const string Advapi32 = "advapi32.dll";
//public const string Comctl32 = "comctl32.dll";
//public const string Comdlg32 = "comdlg32.dll";
//public const string DwmAPI = "dwmapi.dll";
//public const string Gdi32 = "gdi32.dll";
//public const string Gdiplus = "gdiplus.dll";
//public const string Hhctrl = "hhctrl.ocx";
//public const string Imm32 = "imm32.dll";
//public const string Kernel32 = "kernel32.dll";
//public const string Loadperf = "Loadperf.dll";
//public const string Mqrt = "mqrt.dll";
//public const string Mscoree = "mscoree.dll";
//public const string MsDrm = "msdrm.dll";
//public const string Mshwgst = "mshwgst.dll";
//public const string Msi = "msi.dll";
//public const string NaturalLanguage6 = "naturallanguage6.dll";
//public const string Ntdll = "ntdll.dll";
//public const string Ole32 = "ole32.dll";
//public const string Oleacc = "oleacc.dll";
//public const string Oleaut32 = "oleaut32.dll";
//public const string Olepro32 = "olepro32.dll";
//public const string Penimc = "PenIMC_cor3.dll";
//public const string PresentationCore = "PresentationCore.dll";
//public const string PresentationFramework = "PresentationFramework.dll";
//public const string PresentationHostDll = "PresentationHost_cor3.dll";
//public const string PresentationNativeDll = "PresentationNative_cor3.dll";
//public const string Psapi = "psapi.dll";
//public const string Shcore = "shcore.dll";
//public const string Shell32 = "shell32.dll";
//public const string Shfolder = "shfolder.dll";
//public const string Urlmon = "urlmon.dll";
public const string User32 = "user32.dll";
//public const string Uxtheme = "uxtheme.dll";
//public const string Version = "version.dll";
//public const string Vsassert = "vsassert.dll";
//public const string WindowsBase = "windowsbase.dll";
//public const string Wininet = "wininet.dll";
//public const string Winmm = "winmm.dll";
//public const string Winspool = "winspool.drv";
//public const string Wldp = "wldp.dll";
//public const string WpfGfx = "WpfGfx_cor3.dll";
//public const string WtsApi32 = "wtsapi32.dll";
}
#endif
@@ -0,0 +1,22 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// https://github.com/dotnet/wpf/blob/v6.0.6/src/Microsoft.DotNet.Wpf/src/Shared/MS/Win32/UnsafeNativeMethodsCLR.cs
#if !NETFRAMEWORK && WINDOWS
using System;
using System.Runtime.InteropServices;
namespace MS.Win32;
internal static class UnsafeNativeMethods
{
[DllImport(ExternDll.User32, ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern IntPtr GetActiveWindow();
[DllImport(ExternDll.User32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
public static extern int MessageBox(HandleRef hWnd, string text, string caption, int type);
}
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,248 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// https://github.com/dotnet/wpf/blob/v6.0.6/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/MessageBox.cs
#if !NETFRAMEWORK && WINDOWS
using MS.Win32;
using System.ComponentModel;
using System.Runtime.InteropServices;
using SR_ = MS.Internal.PresentationCore.SR;
using SRID = MS.Internal.PresentationCore.SRID;
namespace System.Windows;
public static class MessageBox
{
const int IDOK = 1;
const int IDCANCEL = 2;
const int IDYES = 6;
const int IDNO = 7;
const int DEFAULT_BUTTON1 = 0x00000000;
const int DEFAULT_BUTTON2 = 0x00000100;
const int DEFAULT_BUTTON3 = 0x00000200;
static MessageBoxResult Win32ToMessageBoxResult(int value) => value switch
{
IDOK => MessageBoxResult.OK,
IDCANCEL => MessageBoxResult.Cancel,
IDYES => MessageBoxResult.Yes,
IDNO => MessageBoxResult.No,
_ => MessageBoxResult.No,
};
public static MessageBoxResult Show(
string messageBoxText,
string caption,
MessageBoxButton button,
MessageBoxImage icon,
MessageBoxResult defaultResult,
MessageBoxOptions options) => ShowCore(IntPtr.Zero, messageBoxText, caption, button, icon, defaultResult, options);
public static MessageBoxResult Show(
string messageBoxText,
string caption,
MessageBoxButton button,
MessageBoxImage icon,
MessageBoxResult defaultResult) => ShowCore(IntPtr.Zero, messageBoxText, caption, button, icon, defaultResult, 0);
public static MessageBoxResult Show(
string messageBoxText,
string caption,
MessageBoxButton button,
MessageBoxImage icon) => ShowCore(IntPtr.Zero, messageBoxText, caption, button, icon, 0, 0);
public static MessageBoxResult Show(
string messageBoxText,
string caption,
MessageBoxButton button) => ShowCore(IntPtr.Zero, messageBoxText, caption, button, MessageBoxImage.None, 0, 0);
public static MessageBoxResult Show(string messageBoxText, string caption) => ShowCore(IntPtr.Zero, messageBoxText, caption, MessageBoxButton.OK, MessageBoxImage.None, 0, 0);
public static MessageBoxResult Show(string messageBoxText) => ShowCore(IntPtr.Zero, messageBoxText, string.Empty, MessageBoxButton.OK, MessageBoxImage.None, 0, 0);
static int DefaultResultToButtonNumber(MessageBoxResult result, MessageBoxButton button)
{
if (result == 0) return DEFAULT_BUTTON1;
switch (button)
{
case MessageBoxButton.OK:
return DEFAULT_BUTTON1;
case MessageBoxButton.OKCancel:
if (result == MessageBoxResult.Cancel) return DEFAULT_BUTTON2;
return DEFAULT_BUTTON1;
case MessageBoxButton.YesNo:
if (result == MessageBoxResult.No) return DEFAULT_BUTTON2;
return DEFAULT_BUTTON1;
case MessageBoxButton.YesNoCancel:
if (result == MessageBoxResult.No) return DEFAULT_BUTTON2;
if (result == MessageBoxResult.Cancel) return DEFAULT_BUTTON3;
return DEFAULT_BUTTON1;
default:
return DEFAULT_BUTTON1;
}
}
internal static MessageBoxResult ShowCore(
IntPtr owner,
string messageBoxText,
string caption,
MessageBoxButton button,
MessageBoxImage icon,
MessageBoxResult defaultResult,
MessageBoxOptions options)
{
if (!IsValidMessageBoxButton(button))
{
throw new InvalidEnumArgumentException("button", (int)button, typeof(MessageBoxButton));
}
if (!IsValidMessageBoxImage(icon))
{
throw new InvalidEnumArgumentException("icon", (int)icon, typeof(MessageBoxImage));
}
if (!IsValidMessageBoxResult(defaultResult))
{
throw new InvalidEnumArgumentException("defaultResult", (int)defaultResult, typeof(MessageBoxResult));
}
if (!IsValidMessageBoxOptions(options))
{
throw new InvalidEnumArgumentException("options", (int)options, typeof(MessageBoxOptions));
}
// UserInteractive??
//
/*if (!SystemInformation.UserInteractive && (options & (MessageBoxOptions.ServiceNotification | MessageBoxOptions.DefaultDesktopOnly)) == 0) {
throw new InvalidOperationException("UNDONE: SR.GetString(SR.CantShowModalOnNonInteractive)");
}*/
if ((options & (MessageBoxOptions.ServiceNotification | MessageBoxOptions.DefaultDesktopOnly)) != 0)
{
if (owner != IntPtr.Zero)
{
throw new ArgumentException(SR_.Get(SRID.CantShowMBServiceWithOwner));
}
}
else
{
if (owner == IntPtr.Zero)
{
owner = UnsafeNativeMethods.GetActiveWindow();
}
}
int style = (int)button | (int)icon | (int)DefaultResultToButtonNumber(defaultResult, button) | (int)options;
// modal dialog notification?
//
//Application.BeginModalMessageLoop();
//MessageBoxResult result = Win32ToMessageBoxResult(SafeNativeMethods.MessageBox(new HandleRef(owner, handle), messageBoxText, caption, style));
MessageBoxResult result = Win32ToMessageBoxResult(UnsafeNativeMethods.MessageBox(new HandleRef(null, owner), messageBoxText, caption, style));
// modal dialog notification?
//
//Application.EndModalMessageLoop();
return result;
}
static bool IsValidMessageBoxButton(MessageBoxButton value) => value == MessageBoxButton.OK
|| value == MessageBoxButton.OKCancel
|| value == MessageBoxButton.YesNo
|| value == MessageBoxButton.YesNoCancel;
static bool IsValidMessageBoxImage(MessageBoxImage value) => value == MessageBoxImage.Asterisk
|| value == MessageBoxImage.Error
|| value == MessageBoxImage.Exclamation
|| value == MessageBoxImage.Hand
|| value == MessageBoxImage.Information
|| value == MessageBoxImage.None
|| value == MessageBoxImage.Question
|| value == MessageBoxImage.Stop
|| value == MessageBoxImage.Warning;
static bool IsValidMessageBoxResult(MessageBoxResult value) => value == MessageBoxResult.Cancel
|| value == MessageBoxResult.No
|| value == MessageBoxResult.None
|| value == MessageBoxResult.OK
|| value == MessageBoxResult.Yes;
static bool IsValidMessageBoxOptions(MessageBoxOptions value)
{
int mask = ~((int)MessageBoxOptions.ServiceNotification |
(int)MessageBoxOptions.DefaultDesktopOnly |
(int)MessageBoxOptions.RightAlign |
(int)MessageBoxOptions.RtlReading);
if (((int)value & mask) == 0)
return true;
return false;
}
}
public enum MessageBoxResult
{
None = 0,
OK = 1,
Cancel = 2,
Yes = 6,
No = 7,
// NOTE: if you add or remove any values in this enum, be sure to update MessageBox.IsValidMessageBoxResult()
}
[Flags]
public enum MessageBoxOptions
{
None = 0x00000000,
ServiceNotification = 0x00200000,
DefaultDesktopOnly = 0x00020000,
RightAlign = 0x00080000,
RtlReading = 0x00100000,
}
public enum MessageBoxImage
{
None = 0,
Hand = 0x00000010,
Question = 0x00000020,
Exclamation = 0x00000030,
Asterisk = 0x00000040,
Stop = Hand,
Error = Hand,
Warning = Exclamation,
Information = Asterisk,
// NOTE: if you add or remove any values in this enum, be sure to update MessageBox.IsValidMessageBoxIcon()
}
public enum MessageBoxButton
{
OK = 0x00000000,
OKCancel = 0x00000001,
YesNoCancel = 0x00000003,
YesNo = 0x00000004,
// NOTE: if you add or remove any values in this enum, be sure to update MessageBox.IsValidMessageBoxButton()
}
#endif
@@ -1,5 +1,7 @@
using DnsClient;
using DnsClient.Protocol;
using DynamicData;
using Microsoft.Extensions.DependencyInjection.Extensions;
using System.Application.Services;
using System.Application.Services.Implementation;
using System.Collections.Generic;
@@ -14,18 +16,23 @@ namespace System.Application.Services.Implementation
{
internal sealed class DnsAnalysisServiceImpl : IDnsAnalysisService
{
public DnsAnalysisServiceImpl()
{
}
private static readonly LookupClient lookupClient = new();
public int AnalysisHostnameTime(string url)
public async Task<int> AnalysisHostnameTime(string url, CancellationToken cancellationToken = default)
{
if (!string.IsNullOrEmpty(url))
{
var client = lookupClient;
var result = client.Query(url, QueryType.A);
var result = await client.QueryAsync(url, QueryType.A, QueryClass.IN, cancellationToken);
if (result.Answers.Count > 0)
{
var value = result.Answers.ARecords().FirstOrDefault()?.InitialTimeToLive;
if (value.HasValue) return value.Value;
return value ?? 0;
}
}
return 0;
@@ -140,6 +147,11 @@ namespace System.Application.Services.Implementation
}
return false;
}
public async Task<IPAddress?> GetHostIpv6Addres()
{
return null;
}
}
}
@@ -150,6 +162,7 @@ namespace Microsoft.Extensions.DependencyInjection
{
public static IServiceCollection AddDnsAnalysisService(this IServiceCollection services)
{
//services.AddSingleton<IDnsAnalysisService, DnsDohAnalysisService>();
services.AddSingleton<IDnsAnalysisService, DnsAnalysisServiceImpl>();
return services;
}
@@ -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))
@@ -495,6 +534,9 @@ namespace System.Application.Services.Implementation
private uint univeseNumber;
private const uint MagicNumber = 123094055U;
private const uint MagicNumberV2 = 123094056U;
private static readonly Lazy<uint[]> MagicNumbers = new(new uint[] { MagicNumber, MagicNumberV2 });
/// <summary>
/// 从steam本地客户端缓存文件中读取游戏数据
@@ -516,15 +558,17 @@ namespace System.Application.Services.Implementation
}
using BinaryReader binaryReader = new(stream);
uint num = binaryReader.ReadUInt32();
if (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)
{
@@ -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);
@@ -31,11 +31,24 @@ namespace System.Application.Services.Implementation
}
public async Task<byte[]> ProtectAsync(byte[] data)
{
try
{
return await ProtectCoreAsync(data);
}
catch
{
return await ProtectCore2Async(data);
}
}
static async Task<byte[]> ProtectCoreAsync(byte[] data)
{
// LOCAL=user and LOCAL=machine do not require enterprise auth capability
var provider = GetDataProtectionProvider("LOCAL=user");
// https://appcenter.ms/orgs/BeyondDimension/apps/Steam/crashes/errors/842356268u/overview
// https://appcenter.ms/orgs/BeyondDimension/apps/Steam/crashes/errors/1550045210u/overview
// System.Runtime.InteropServices.COMException: 无法在设置线程模式后对其加以更改。 (0x80010106 (RPC_E_CHANGED_MODE))
var buffer = await provider.ProtectAsync(data.AsBuffer());
@@ -45,7 +58,9 @@ namespace System.Application.Services.Implementation
return encBytes;
}
public async Task<byte[]> UnprotectAsync(byte[] data)
static async Task<byte[]> ProtectCore2Async(byte[] data) => await await Task.Factory.StartNew(async () => await ProtectCoreAsync(data));
static async Task<byte[]> UnprotectCoreAsync(byte[] data)
{
var provider = GetDataProtectionProvider();
@@ -53,5 +68,19 @@ namespace System.Application.Services.Implementation
return buffer.ToArray();
}
static async Task<byte[]> UnprotectCore2Async(byte[] data) => await await Task.Factory.StartNew(async () => await UnprotectCoreAsync(data));
public async Task<byte[]> UnprotectAsync(byte[] data)
{
try
{
return await UnprotectCoreAsync(data);
}
catch
{
return await UnprotectCore2Async(data);
}
}
}
}
@@ -2,6 +2,11 @@ namespace System.Application.Services.Implementation
{
partial class WindowsPlatformServiceImpl : IDisposable
{
/// <summary>
/// 用于 <see cref="IOPath.GetCacheFilePath(string, string, string)"/> 中 dirName,临时文件夹名称,在程序退出时将删除整个文件夹
/// </summary>
const string CacheTempDirName = "Temporary";
bool disposedValue;
private void Dispose(bool disposing)
@@ -12,6 +17,8 @@ namespace System.Application.Services.Implementation
{
// TODO: 释放托管状态(托管对象)
isLightOrDarkThemeWatch?.Dispose();
IOPath.TryDeleteCacheSubDir(CacheTempDirName);
}
// TODO: 释放未托管的资源(未托管的对象)并重写终结器
@@ -1,6 +1,5 @@
using Microsoft.Win32;
using System.Application.Models;
using System.Application.UI;
using System.Application.UI.Resx;
using System.Collections.Generic;
using System.ComponentModel;
@@ -11,326 +10,416 @@ using System.IO;
using System.Linq;
using System.Management;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Versioning;
using System.Runtime.InteropServices;
using System.Security.Principal;
using Windows.ApplicationModel;
using System.Application.Properties;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using _SR = System.Application.Properties.SR;
namespace System.Application.Services.Implementation
namespace System.Application.Services.Implementation;
internal sealed partial class WindowsPlatformServiceImpl : IPlatformService
{
internal sealed partial class WindowsPlatformServiceImpl : IPlatformService
const string TAG = "WindowsPlatformS";
const string SteamRegistryPath = @"SOFTWARE\Valve\Steam";
public string? GetRegistryVdfPath() { return null; }
public string GetCommandLineArgs(Process process)
{
const string TAG = "WindowsPlatformS";
const string SteamRegistryPath = @"SOFTWARE\Valve\Steam";
public string? GetRegistryVdfPath() { return null; }
public string GetCommandLineArgs(Process process)
try
{
try
{
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() ?? "";
}
catch (Win32Exception ex) when ((uint)ex.ErrorCode == 0x80004005)
{
// 没有对该进程的安全访问权限。
return string.Empty;
}
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() ?? "";
}
static readonly Lazy<string> mHostsFilePath = new(() =>
catch (Win32Exception ex) when ((uint)ex.ErrorCode == 0x80004005)
{
return Path.Combine(Environment.SystemDirectory, "drivers", "etc", "hosts");
});
// 没有对该进程的安全访问权限。
return string.Empty;
}
}
public string HostsFilePath => mHostsFilePath.Value;
static readonly Lazy<string> mHostsFilePath = new(() =>
{
return Path.Combine(Environment.SystemDirectory, "drivers", "etc", "hosts");
});
public string DefaultHostsContent => _SR.hosts;
public string HostsFilePath => mHostsFilePath.Value;
static string GetFolderPath(Environment.SpecialFolder folder)
public string DefaultHostsContent => _SR.hosts;
static string GetFolderPath(Environment.SpecialFolder folder)
{
switch (folder)
{
switch (folder)
{
case Environment.SpecialFolder.ProgramFiles:
var trimEndMark = " (x86)";
var value = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
if (value.EndsWith(trimEndMark, StringComparison.OrdinalIgnoreCase))
case Environment.SpecialFolder.ProgramFiles:
var trimEndMark = " (x86)";
var value = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
if (value.EndsWith(trimEndMark, StringComparison.OrdinalIgnoreCase))
{
var value2 = value[..^trimEndMark.Length];
if (Directory.Exists(value2))
{
var value2 = value.Substring(0, value.Length - trimEndMark.Length);
if (Directory.Exists(value2))
{
return value2;
}
return value2;
}
return value;
default:
return Environment.GetFolderPath(folder);
}
}
return value;
default:
return Environment.GetFolderPath(folder);
}
}
const string explorer = "explorer.exe";
public void OpenFolderByDirectoryPath(DirectoryInfo info)
{
StartProcessExplorer($"\"{info.FullName}\"");
}
static string Explorer => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), explorer);
public void OpenFolderSelectFilePath(FileInfo info)
{
StartProcessExplorer($"/select,\"{info.FullName}\"");
}
public void OpenFolderByDirectoryPath(DirectoryInfo info)
public string? GetFileName(TextReaderProvider provider)
{
switch (provider)
{
Process.Start(new ProcessStartInfo
{
FileName = Explorer,
Arguments = $"\"{info.FullName}\"",
UseShellExecute = false,
});
}
case TextReaderProvider.VSCode:
var vsCodePaths = new[] {
GetFolderPath(Environment.SpecialFolder.ProgramFiles),
GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)
}.Distinct().Select(x => Path.Combine(x, "Microsoft VS Code", "Code.exe"));
public void OpenFolderSelectFilePath(FileInfo info)
{
Process.Start(new ProcessStartInfo
{
FileName = Explorer,
Arguments = $"/select,\"{info.FullName}\"",
UseShellExecute = false,
});
}
public string? GetFileName(TextReaderProvider provider)
{
switch (provider)
{
case TextReaderProvider.VSCode:
var vsCodePaths = new[] {
GetFolderPath(Environment.SpecialFolder.ProgramFiles),
GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)
}.Distinct().Select(x => Path.Combine(x, "Microsoft VS Code", "Code.exe"));
foreach (var vsCodePath in vsCodePaths)
foreach (var vsCodePath in vsCodePaths)
{
if (File.Exists(vsCodePath))
{
if (File.Exists(vsCodePath))
{
return vsCodePath;
}
return vsCodePath;
}
}
return null;
case TextReaderProvider.Notepad:
return "notepad";
default:
return null;
}
return null;
case TextReaderProvider.Notepad:
return "notepad";
default:
return null;
}
}
public void SetSystemSessionEnding(Action action)
public void SetSystemSessionEnding(Action action)
{
SystemEvents.SessionEnding += (sender, e) =>
{
SystemEvents.SessionEnding += (sender, e) =>
{
//IDesktopAppService.Instance.CompositeDisposable.Dispose();
action.Invoke();
};
//IDesktopAppService.Instance.CompositeDisposable.Dispose();
action.Invoke();
};
}
static string? GetFullPath(string s)
{
if (!string.IsNullOrWhiteSpace(s))
{
return Path.GetFullPath(s);
}
return null;
}
static string? GetFullPath(string s)
public string? GetSteamDirPath()
=> GetFullPath(Registry.CurrentUser.Read(SteamRegistryPath, "SteamPath"));
public string? GetSteamProgramPath()
=> GetFullPath(Registry.CurrentUser.Read(SteamRegistryPath, "SteamExe"));
public string GetLastSteamLoginUserName()
=> Registry.CurrentUser.Read(SteamRegistryPath, "AutoLoginUser");
public void SetCurrentUser(string userName)
{
if (DesktopBridge.IsRunningAsUwp)
{
if (!string.IsNullOrWhiteSpace(s))
{
return Path.GetFullPath(s);
}
var reg = $"Windows Registry Editor Version 5.00{Environment.NewLine}[HKEY_CURRENT_USER\\Software\\Valve\\Steam]{Environment.NewLine}\"AutoLoginUser\"=\"{userName}\"";
var path = IOPath.GetCacheFilePath(CacheTempDirName, "SwitchSteamUser", FileEx.Reg);
File.WriteAllText(path, reg, Encoding.UTF8);
var p = StartProcessRegedit($"/s \"{path}\"");
IOPath.TryDeleteInDelay(p, path);
}
else
{
Registry.CurrentUser.AddOrUpdate(SteamRegistryPath, "AutoLoginUser", userName, RegistryValueKind.String);
}
}
static string GetMachineSecretKey()
=> Registry.LocalMachine.Read(@"SOFTWARE\Microsoft\Cryptography", "MachineGuid");
static readonly Lazy<(byte[] key, byte[] iv)> mMachineSecretKey = IPlatformService.GetMachineSecretKey(GetMachineSecretKey);
public (byte[] key, byte[] iv) MachineSecretKey => mMachineSecretKey.Value;
/// <summary>
/// %windir%
/// </summary>
static readonly Lazy<string> _windir = new(() => Environment.GetFolderPath(Environment.SpecialFolder.Windows));
//const string runas_exe = "runas.exe";
//static Process? StartAsInvokerByRunas(string fileName, string? arguments = null)
//{
// // https://blog.lindexi.com/post/%E5%A6%82%E4%BD%95%E5%9C%A8-RunAs-%E5%90%AF%E5%8A%A8%E7%9A%84%E8%BD%AF%E4%BB%B6%E4%BC%A0%E5%85%A5%E5%B8%A6%E7%A9%BA%E6%A0%BC%E7%9A%84%E8%B7%AF%E5%BE%84%E5%B8%A6%E7%A9%BA%E6%A0%BC%E5%8F%82%E6%95%B0.html
// string arguments_;
// if (string.IsNullOrEmpty(arguments))
// arguments_ = $"/trustlevel:0x20000 \"{fileName}\"";
// else arguments_ = $"/trustlevel:0x20000 \"{fileName} \"{arguments}\"\"";
// return Process.Start(runas_exe, arguments_);
//}
static readonly Lazy<string> _explorer_exe = new(() => Path.Combine(_windir.Value, "explorer.exe"));
/// <summary>
/// %windir%\explorer.exe
/// </summary>
static string Explorer => _explorer_exe.Value;
/// <summary>
/// 带参数(可选/null)启动 %windir%\explorer.exe
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
static Process? StartProcessExplorer(string args) => Process2.Start(Explorer, args, workingDirectory: _windir.Value);
static readonly Lazy<string> _regedit_exe = new(() => Path.Combine(_windir.Value, "regedit.exe"));
/// <summary>
/// %windir%\regedit.exe
/// </summary>
static string Regedit => _regedit_exe.Value;
/// <summary>
/// 带参数(可选/null)启动 %windir%\regedit.exe
/// </summary>
/// <param name="args"></param>
/// <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}del %0");
var process = StartProcessExplorer($"\"{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)
{
if (((IPlatformService)this).IsAdministrator)
{
// runas /trustlevel:0x20000 没有真正的降权,只是作为具有限制特权,使用 explorer 最好,但不接受参数,可以创建一个临时cmd脚本启动
//return StartAsInvokerByRunas(fileName, arguments);
//return StartAsInvokerByExplorer(fileName, arguments);
var currentDirectory = Path.GetDirectoryName(fileName) ?? "";
Microsoft.NodejsTools.SharedProject.SystemUtility.
ExecuteProcessUnElevated(fileName, arguments ?? "", currentDirectory);
return null;
}
public string? GetSteamDirPath()
=> GetFullPath(Registry.CurrentUser.Read(SteamRegistryPath, "SteamPath"));
public string? GetSteamProgramPath()
=> GetFullPath(Registry.CurrentUser.Read(SteamRegistryPath, "SteamExe"));
public string GetLastSteamLoginUserName()
=> Registry.CurrentUser.Read(SteamRegistryPath, "AutoLoginUser");
public void SetCurrentUser(string userName)
else
{
if (DesktopBridge.IsRunningAsUwp)
{
var reg = $"Windows Registry Editor Version 5.00{Environment.NewLine}[HKEY_CURRENT_USER\\Software\\Valve\\Steam]{Environment.NewLine}\"AutoLoginUser\"=\"{userName}\"";
var path = Path.Combine(IOPath.CacheDirectory, "switchuser.reg");
File.WriteAllText(path, reg, Text.Encoding.UTF8);
var p = Process2.Start("regedit", $"/s \"{path}\"", true);
p?.WaitForExit();
}
else
{
Registry.CurrentUser.AddOrUpdate(SteamRegistryPath, "AutoLoginUser", userName, RegistryValueKind.String);
}
return Process2.Start(fileName, arguments);
}
}
static string GetMachineSecretKey()
=> Registry.LocalMachine.Read(@"SOFTWARE\Microsoft\Cryptography", "MachineGuid");
//public Process? StartAsInvoker(ProcessStartInfo startInfo)
//{
// startInfo.FileName = runas_exe;
// startInfo.Arguments = $"/trustlevel:0x20000 \"{startInfo.FileName}\"";
// return Process.Start(startInfo);
//}
static readonly Lazy<(byte[] key, byte[] iv)> mMachineSecretKey = IPlatformService.GetMachineSecretKey(GetMachineSecretKey);
//public Process? GetProcessByPortOccupy(ushort port, bool isTCPorUDP = true)
//{
// if (isTCPorUDP)
// {
// return SocketHelper.GetProcessByTcpPort(port);
// }
// else
// {
// throw new NotSupportedException();
// }
// //try
// //{
// // using var p = new Process
// // {
// // StartInfo = new ProcessStartInfo
// // {
// // FileName = "cmd",
// // UseShellExecute = false,
// // RedirectStandardInput = true,
// // RedirectStandardOutput = true,
// // CreateNoWindow = true,
// // },
// // };
// // p.Start();
// // p.StandardInput.WriteLine($"netstat -ano|findstr \"{port}\"&exit");
// // p.StandardInput.AutoFlush = true;
// // var reader = p.StandardOutput;
// // while (!reader.EndOfStream)
// // {
// // var line = reader.ReadLine();
// // if (line == null) break;
// // var lineArray = line.Split(' ', StringSplitOptions.RemoveEmptyEntries);
// // if (lineArray.Length != 5) continue;
// // if (!lineArray[0].Equals(isTCPorUDP ? "TCP" : "UDP", StringComparison.OrdinalIgnoreCase)) continue;
// // if (!lineArray[3].Equals("LISTENING", StringComparison.OrdinalIgnoreCase)) continue;
// // if (!lineArray[1].EndsWith($":{port}")) continue;
// // if (!ushort.TryParse(lineArray[4], out var pid)) continue;
// // p.Close();
// // return Process.GetProcessById(pid);
// // }
// // _ = p.WaitForExit(550);
// //}
// //catch
// //{
// //}
// //return default;
//}
public (byte[] key, byte[] iv) MachineSecretKey => mMachineSecretKey.Value;
const string ProxyOverride = "\"ProxyOverride\"=\"localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*\"";
//const string runas_exe = "runas.exe";
//static Process? StartAsInvokerByRunas(string fileName, string? arguments = null)
//{
// // https://blog.lindexi.com/post/%E5%A6%82%E4%BD%95%E5%9C%A8-RunAs-%E5%90%AF%E5%8A%A8%E7%9A%84%E8%BD%AF%E4%BB%B6%E4%BC%A0%E5%85%A5%E5%B8%A6%E7%A9%BA%E6%A0%BC%E7%9A%84%E8%B7%AF%E5%BE%84%E5%B8%A6%E7%A9%BA%E6%A0%BC%E5%8F%82%E6%95%B0.html
// string arguments_;
// if (string.IsNullOrEmpty(arguments))
// arguments_ = $"/trustlevel:0x20000 \"{fileName}\"";
// else arguments_ = $"/trustlevel:0x20000 \"{fileName} \"{arguments}\"\"";
// return Process.Start(runas_exe, arguments_);
//}
const string explorer_exe = "explorer.exe";
static Process? StartAsInvokerByExplorer(string fileName, string? arguments = null)
{
if (string.IsNullOrEmpty(arguments))
return Process.Start(explorer_exe, $"\"{fileName}\"");
var cacheCmdFile = Path.Combine(IOPath.CacheDirectory, "StartAsInvokerByExplorer" + FileEx.CMD);
if (File.Exists(cacheCmdFile)) File.Delete(cacheCmdFile);
File.WriteAllText(cacheCmdFile, $"@echo {Constants.HARDCODED_APP_NAME} StartAsInvokerByExplorer{Environment.NewLine}start \"\" \"{fileName}\" {arguments}{Environment.NewLine}exit 0");
return Process.Start(explorer_exe, $"\"{cacheCmdFile}\"");
}
public Process? StartAsInvoker(string fileName, string? arguments = null)
{
if (((IPlatformService)this).IsAdministrator)
{
// runas /trustlevel:0x20000 没有真正的降权,只是作为具有限制特权,使用 explorer 最好,但不接受参数,可以创建一个临时cmd脚本启动
//return StartAsInvokerByRunas(fileName, arguments);
return StartAsInvokerByExplorer(fileName, arguments);
}
else
{
return Process2.Start(fileName, arguments);
}
}
//public Process? StartAsInvoker(ProcessStartInfo startInfo)
//{
// startInfo.FileName = runas_exe;
// startInfo.Arguments = $"/trustlevel:0x20000 \"{startInfo.FileName}\"";
// return Process.Start(startInfo);
//}
//public Process? GetProcessByPortOccupy(ushort port, bool isTCPorUDP = true)
//{
// if (isTCPorUDP)
// {
// return SocketHelper.GetProcessByTcpPort(port);
// }
// else
// {
// throw new NotSupportedException();
// }
// //try
// //{
// // using var p = new Process
// // {
// // StartInfo = new ProcessStartInfo
// // {
// // FileName = "cmd",
// // UseShellExecute = false,
// // RedirectStandardInput = true,
// // RedirectStandardOutput = true,
// // CreateNoWindow = true,
// // },
// // };
// // p.Start();
// // p.StandardInput.WriteLine($"netstat -ano|findstr \"{port}\"&exit");
// // p.StandardInput.AutoFlush = true;
// // var reader = p.StandardOutput;
// // while (!reader.EndOfStream)
// // {
// // var line = reader.ReadLine();
// // if (line == null) break;
// // var lineArray = line.Split(' ', StringSplitOptions.RemoveEmptyEntries);
// // if (lineArray.Length != 5) continue;
// // if (!lineArray[0].Equals(isTCPorUDP ? "TCP" : "UDP", StringComparison.OrdinalIgnoreCase)) continue;
// // if (!lineArray[3].Equals("LISTENING", StringComparison.OrdinalIgnoreCase)) continue;
// // if (!lineArray[1].EndsWith($":{port}")) continue;
// // if (!ushort.TryParse(lineArray[4], out var pid)) continue;
// // p.Close();
// // return Process.GetProcessById(pid);
// // }
// // _ = p.WaitForExit(550);
// //}
// //catch
// //{
// //}
// //return default;
//}
const string ProxyOverride = "\"ProxyOverride\"=\"localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*\"";
/// <summary>
/// 设置启用或关闭系统代理
/// </summary>
/// <param name="state"></param>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <returns></returns>
public bool SetAsSystemProxy(bool state, IPAddress? ip, int port)
/// <summary>
/// 设置启用或关闭系统代理
/// </summary>
/// <param name="state"></param>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <returns></returns>
public bool SetAsSystemProxy(bool state, IPAddress? ip, int port)
{
try
{
var proxyEnable = $"\"ProxyEnable\"=dword:{(state ? "00000001" : "00000000")}";
var hasIpAndProt = ip != null && port >= 0;
var proxyServer = hasIpAndProt ? $"\"proxyServer\"=\"{ip}:{port}\"" : "";
var reg = $"Windows Registry Editor Version 5.00{Environment.NewLine}[HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings]{Environment.NewLine}{proxyEnable}{Environment.NewLine}{(state ? $"{ProxyOverride}{Environment.NewLine}" : "")}{proxyServer}";
var path = Path.Combine(IOPath.CacheDirectory, "switchproxy.reg");
File.WriteAllText(path, reg, Text.Encoding.UTF8);
var p = Process2.Start("regedit", $"/s \"{path}\"", true);
p?.WaitForExit();
var path = IOPath.GetCacheFilePath(CacheTempDirName, "SwitchProxy", FileEx.Reg);
File.WriteAllText(path, reg, Encoding.UTF8);
var p = StartProcessRegedit($"/s \"{path}\"");
IOPath.TryDeleteInDelay(p, path);
return true;
}
catch (Exception ex)
{
Toast.LogAndShowT(ex, TAG);
return false;
}
}
/// <summary>
/// 设置启用或关闭PAC代理
/// </summary>
/// <param name="state"></param>
/// <param name="url"></param>
/// <returns></returns>
public bool SetAsSystemPACProxy(bool state, string? url = null)
/// <summary>
/// 设置启用或关闭PAC代理
/// </summary>
/// <param name="state"></param>
/// <param name="url"></param>
/// <returns></returns>
public bool SetAsSystemPACProxy(bool state, string? url = null)
{
try
{
var regAutoConfigUrl = state ? $"\"AutoConfigURL\"=\"{url}\"" : "\"AutoConfigURL\"=\"\"";
var reg = $"Windows Registry Editor Version 5.00{Environment.NewLine}[HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings]{Environment.NewLine}{regAutoConfigUrl}";
var path = Path.Combine(IOPath.CacheDirectory, "switchpacproxy.reg");
File.WriteAllText(path, reg, Text.Encoding.UTF8);
var p = Process2.Start("regedit", $"/s \"{path}\"", true);
p?.WaitForExit();
var path = IOPath.GetCacheFilePath(CacheTempDirName, "SwitchPacProxy", FileEx.Reg);
File.WriteAllText(path, reg, Encoding.UTF8);
var p = StartProcessRegedit($"/s \"{path}\"");
IOPath.TryDeleteInDelay(p, path);
return true;
}
public IReadOnlyCollection<KeyValuePair<string, string>> GetFontsByGdiPlus()
catch (Exception ex)
{
// https://docs.microsoft.com/zh-cn/typography/font-list
var culture = R.Culture;
InstalledFontCollection ifc = new();
var list = ifc.Families.Where(x => x.IsStyleAvailable(FontStyle.Regular)).Select(x => KeyValuePair.Create(x.GetName(culture.LCID), x.GetName(1033))).ToList();
list.Insert(0, IFontManager.Default);
return list;
Toast.LogAndShowT(ex, TAG);
return false;
}
#region IsInstall
static readonly Lazy<bool> _IsInstall = new(() =>
{
using var reg32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
var value = reg32.Read(@"SOFTWARE\Steam++", "InstPath").TrimEnd(Path.DirectorySeparatorChar);
return string.Equals(IOPath.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar), value, StringComparison.OrdinalIgnoreCase);
});
/// <inheritdoc cref="IPlatformService.IsInstall"/>
public static bool IsInstall => _IsInstall.Value;
bool IPlatformService.IsInstall => IsInstall;
#endregion
}
public IReadOnlyCollection<KeyValuePair<string, string>> GetFontsByGdiPlus()
{
// https://docs.microsoft.com/zh-cn/typography/font-list
var culture = R.Culture;
InstalledFontCollection ifc = new();
var list = ifc.Families.Where(x => x.IsStyleAvailable(FontStyle.Regular)).Select(x => KeyValuePair.Create(x.GetName(culture.LCID), x.GetName(1033))).ToList();
list.Insert(0, IFontManager.Default);
return list;
}
#region IsInstall
static readonly Lazy<bool> _IsInstall = new(() =>
{
using var reg32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
var value = reg32.Read(@"SOFTWARE\Steam++", "InstPath").TrimEnd(Path.DirectorySeparatorChar);
return string.Equals(IOPath.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar), value, StringComparison.OrdinalIgnoreCase);
});
/// <inheritdoc cref="IPlatformService.IsInstall"/>
public static bool IsInstall => _IsInstall.Value;
bool IPlatformService.IsInstall => IsInstall;
#endregion
}
@@ -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);
}
}
@@ -71,6 +71,7 @@
<ProjectReference Include="..\Common.CoreLib\Common.CoreLib.csproj" />
<ProjectReference Include="..\ST.Client.CommandLine\ST.Client.CommandLine.csproj" />
<ProjectReference Include="..\ST.Client.Maui\ST.Client.Maui.csproj" />
<ProjectReference Include="..\ST.Client.ReverseProxy.Yarp\ST.Client.ReverseProxy.Yarp.csproj" />
</ItemGroup>
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">
+1 -1
View File
@@ -86,7 +86,7 @@ public partial class AppShell : Shell, IViewFor<MainWindowViewModel>
void InitTabItems(MainWindowViewModel mainWindow, IEnumerable<TabItemId>? topTabs = null)
{
var tabItems = mainWindow.AllTabItems.Where(x => x.Id != TabItemId.GameList);
var tabItems = mainWindow.TabItems.Where(x => x.Id != TabItemId.GameList);
if (topTabs.Any_Nullable())
{
tabItems = tabItems.Where(x => topTabs.Contains(x.Id)).Concat(tabItems.Where(x => !topTabs.Contains(x.Id)));
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="20220725" android:versionName="2.8.2" 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.-->
@@ -145,7 +145,7 @@
<Import Condition=" Exists('$(MSBuildProjectDirectory)\..\..\Xamarin.Android.KeyStore.props') " Project="..\..\Xamarin.Android.KeyStore.props" />
<ProjectExtensions>
<VisualStudio>
<UserProperties XamarinHotReloadWrongLinkerErrorInfoBarSTClientMobileDroidAppHideInfoBar="True" XamarinHotReloadDebuggerTimeoutExceptionSTClientAndroidAppHideInfoBar="True" />
<UserProperties XamarinHotReloadDebuggerTimeoutExceptionSTClientAndroidAppHideInfoBar="True" XamarinHotReloadWrongLinkerErrorInfoBarSTClientMobileDroidAppHideInfoBar="True" />
</VisualStudio>
</ProjectExtensions>
</Project>
@@ -56,8 +56,8 @@ sealed partial class TitaniumCertificateManagerImpl : CertificateManagerImpl, IC
=> manager.CreateRootCertificate(true);
protected override void SharedRemoveTrustedRootCertificate()
=> manager.RemoveTrustedRootCertificate(false);
=> manager.RemoveTrustedRootCertificate(true);
protected override void SharedTrustRootCertificate()
=> manager.TrustRootCertificate(false);
=> manager.TrustRootCertificate(true);
}
@@ -75,6 +75,9 @@ public static partial class ServiceCollectionExtensions
internal static IServiceCollection AddReverseProxyServer(this IServiceCollection services)
{
// https://github.com/dotnetcore/FastGithub/blob/2.1.4/FastGithub.HttpServer/ServiceCollectionExtensions.cs#L15
CookieHttpClient.AddHttpClient(services);
return services
.AddMemoryCache()
.AddHttpForwarder()
@@ -0,0 +1,33 @@
using Microsoft.Extensions.DependencyInjection;
using System.Net;
namespace System.Application.Services.Implementation;
sealed class CookieHttpClient
{
public static readonly CookieContainer CookieContainer = new();
public const string HttpClientName = "CookieHttpClient";
readonly IHttpClientFactory httpClientFactory;
public CookieHttpClient(IHttpClientFactory httpClientFactory)
{
this.httpClientFactory = httpClientFactory;
}
public HttpClient HttpClient => httpClientFactory.CreateClient(HttpClientName);
public static void AddHttpClient(IServiceCollection services)
{
services.AddSingleton<CookieHttpClient>();
services.AddHttpClient(HttpClientName, (s, c) =>
{
c.Timeout = GeneralHttpClientFactory.DefaultTimeout;
}).ConfigurePrimaryHttpMessageHandler(() => GeneralHttpClientFactory.CreateSocketsHttpHandler(new()
{
UseCookies = true,
CookieContainer = CookieContainer,
}));
}
}
@@ -11,11 +11,11 @@ namespace System.Application.Services.Implementation.Http;
/// </summary>
public class ReverseProxyHttpClient : HttpMessageInvoker
{
/// <summary>
/// 插入的 UserAgent 标记
/// </summary>
static readonly ProductInfoHeaderValue userAgent
= new(new ProductHeaderValue(Constants.HARDCODED_APP_NAME_NEW, ThisAssembly.Version));
///// <summary>
///// 插入的 UserAgent 标记
///// </summary>
//static readonly ProductInfoHeaderValue userAgent
// = new(new ProductHeaderValue(Constants.HARDCODED_APP_NAME_NEW + "_" + DateTimeOffset.UtcNow.Ticks, ThisAssembly.Version));
public ReverseProxyHttpClient(IDomainConfig domainConfig, IDomainResolver domainResolver)
: this(new ReverseProxyHttpClientHandler(domainConfig, domainResolver), disposeHandler: true)
@@ -36,14 +36,14 @@ public class ReverseProxyHttpClient : HttpMessageInvoker
/// <exception cref="Exception"></exception>
public override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request.Headers.UserAgent.Contains(userAgent))
{
const string message =
$"Because {{0}} actually points to {Constants.HARDCODED_APP_NAME_NEW} itself, " +
$"{Constants.HARDCODED_APP_NAME_NEW} has interrupted this forwarding";
throw new ApplicationException(string.Format(message, request.RequestUri));
}
request.Headers.UserAgent.Add(userAgent);
//if (request.Headers.UserAgent.Contains(userAgent))
//{
// const string message =
// $"Because {{0}} actually points to {Constants.HARDCODED_APP_NAME_NEW} itself, " +
// $"{Constants.HARDCODED_APP_NAME_NEW} has interrupted this forwarding";
// throw new ApplicationException(string.Format(message, request.RequestUri));
//}
//request.Headers.UserAgent.Add(userAgent);
var response = await base.SendAsync(request, cancellationToken);
response.Headers.Server.TryParseAdd(Constants.HARDCODED_APP_NAME_NEW);
return response;
@@ -62,7 +62,7 @@ sealed class ReverseProxyHttpClientHandler : DelegatingHandler
/// <returns></returns>
SocketsHttpHandler CreateSocketsHttpHandler() => GeneralHttpClientFactory.CreateSocketsHttpHandler(new()
{
Proxy = null,
Proxy = GeneralHttpClientFactory.HttpNoProxy.Instance,
UseProxy = false,
UseCookies = false,
AllowAutoRedirect = false,
@@ -3,6 +3,7 @@ using System.Application.Models;
using Microsoft.AspNetCore.Http;
using System.Net.Http.Headers;
using Microsoft.AspNetCore.Http.Extensions;
using System.Net;
namespace System.Application.Services.Implementation.HttpServer.Middleware;
@@ -12,10 +13,16 @@ namespace System.Application.Services.Implementation.HttpServer.Middleware;
sealed class HttpLocalRequestMiddleware
{
readonly IReverseProxyConfig reverseProxyConfig;
readonly CookieHttpClient cookieHttpClient;
public HttpLocalRequestMiddleware(IReverseProxyConfig reverseProxyConfig)
HttpClient HttpClient => cookieHttpClient.HttpClient;
public HttpLocalRequestMiddleware(
IReverseProxyConfig reverseProxyConfig,
CookieHttpClient cookieHttpClient)
{
this.reverseProxyConfig = reverseProxyConfig;
this.cookieHttpClient = cookieHttpClient;
}
/// <summary>
@@ -26,9 +33,15 @@ sealed class HttpLocalRequestMiddleware
/// <returns></returns>
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
if (HttpMethods.IsOptions(context.Request.Method) && context.Request.Headers.ContainsKey("Access-Control-Request-Private-Network"))
{
// https://wicg.github.io/private-network-access/
context.Response.Headers["Access-Control-Allow-Private-Network"] = "true";
}
if (context.Request.Host.Host.Equals(IReverseProxyService.LocalDomain, StringComparison.OrdinalIgnoreCase))
{
if (context.Request.Method.Equals("OPTIONS", StringComparison.OrdinalIgnoreCase))
if (HttpMethods.IsOptions(context.Request.Method))
{
context.Response.Headers.AccessControlAllowOrigin = context.Request.Headers.Origin.Count == 0 ? "*" : context.Request.Headers.Origin;
context.Response.Headers.AccessControlAllowHeaders = "*";
@@ -66,6 +79,7 @@ sealed class HttpLocalRequestMiddleware
return;
}
}
await next(context);
}
@@ -74,81 +88,98 @@ sealed class HttpLocalRequestMiddleware
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
static async Task HandleHttpRequestAsync(HttpContext context)
async Task HandleHttpRequestAsync(HttpContext context)
{
if (string.IsNullOrEmpty(context.Request.QueryString.Value))
return;
var url = Web.HttpUtility.UrlDecode(context.Request.QueryString.Value.Replace("?request=", ""));
string? cookie = context.Request.Headers["cookie-steamTool"];
if (string.IsNullOrEmpty(cookie))
cookie = context.Request.Headers["Cookie"];
string? referer = context.Request.Headers["Referer-steamTool"];
context.Response.Headers.AccessControlAllowOrigin = context.Request.Headers.Origin.Count == 0 ? "*" : context.Request.Headers.Origin;
context.Response.Headers.AccessControlAllowHeaders = "*";
context.Response.Headers.AccessControlAllowMethods = "*";
context.Response.Headers.AccessControlAllowCredentials = "true";
//if (cookie != null)
// context.Response.Cookies.Append(cookie);
if (context.Request.ContentType != null)
context.Response.Headers.ContentType = context.Request.ContentType;
if (context.Request.Method == HttpMethods.Get)
try
{
var body = await IHttpService.Instance.GetAsync<string>(url, cookie: cookie);
if (string.IsNullOrEmpty(body))
if (string.IsNullOrEmpty(context.Request.QueryString.Value))
return;
var url = Web.HttpUtility.UrlDecode(context.Request.QueryString.Value.Replace("?request=", ""));
string? cookie = context.Request.Headers["cookie-steamTool"];
if (string.IsNullOrEmpty(cookie))
cookie = context.Request.Headers["Cookie"];
string? referer = context.Request.Headers["Referer-steamTool"];
context.Response.Headers.AccessControlAllowOrigin = context.Request.Headers.Origin.Count == 0 ? "*" : context.Request.Headers.Origin;
context.Response.Headers.AccessControlAllowHeaders = "*";
context.Response.Headers.AccessControlAllowMethods = "*";
context.Response.Headers.AccessControlAllowCredentials = "true";
//if (cookie != null)
// context.Response.Cookies.Append(cookie);
if (context.Request.ContentType != null)
context.Response.Headers.ContentType = context.Request.ContentType;
async Task SendAsync()
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
}
await context.Response.WriteAsync(body);
}
else if (context.Request.Method == HttpMethods.Post)
{
try
{
if (context.Request.ContentLength > 0)
var method = context.Request.Method;
var hasContent = method != HttpMethods.Get && context.Request.ContentLength > 0;
var req = new HttpRequestMessage
{
var conext = await IHttpService.Instance.SendAsync<string>(url, () =>
RequestUri = new Uri(url),
Method = new(method),
Content = hasContent ? new StreamContent(context.Request.Body) : null,
};
req.Headers.UserAgent.ParseAdd(context.Request.Headers.UserAgent);
if (cookie != null)
{
CookieHttpClient.CookieContainer.Add(new Cookie
{
var req = new HttpRequestMessage
{
RequestUri = new Uri(url),
Method = HttpMethod.Post,
Content = new StreamContent(context.Request.Body),
};
if (cookie != null)
{
req.Headers.Add("Cookie", cookie);
}
if (referer != null)
req.Headers.Referrer = new Uri(referer);
req.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(context.Request.ContentType);
req.Content.Headers.ContentLength = context.Request.ContentLength;
return req;
}, null/*, false*/, default);
if (string.IsNullOrEmpty(conext))
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
return;
}
await context.Response.WriteAsync(conext);
CommentUri = req.RequestUri,
Domain = req.RequestUri.Host,
Value = cookie
});
// req.Headers.Add("Cookie", cookie);
}
if (referer != null) req.Headers.Referrer = new Uri(referer);
if (hasContent)
{
req.Content!.Headers.ContentType = MediaTypeHeaderValue.Parse(context.Request.ContentType);
req.Content.Headers.ContentLength = context.Request.ContentLength;
}
var rsp = await HttpClient.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted).ConfigureAwait(false);
if (rsp.IsSuccessStatusCode && rsp.Content != null)
{
context.Response.StatusCode = StatusCodes.Status200OK;
using var body = await rsp.Content.ReadAsStreamAsync(context.RequestAborted);
await body.CopyToAsync(context.Response.BodyWriter.AsStream(), context.RequestAborted);
}
else
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
return;
}
}
catch (Exception error)
if (context.Request.Method == HttpMethods.Get)
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
await context.Response.WriteAsync(error.Message);
await SendAsync();
return;
}
else if (context.Request.Method == HttpMethods.Post)
{
if (context.Request.ContentLength > 0)
{
await SendAsync();
return;
}
}
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
}
catch (Exception error)
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
await context.Response.WriteAsync(error.Message, context.RequestAborted);
}
}
static async Task HandleStatusCodeAsync(HttpContext context, int statusCode)
{
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync(string.Empty, context.RequestAborted);
}
/// <summary>
@@ -156,9 +187,6 @@ sealed class HttpLocalRequestMiddleware
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
static async Task Handle404NotFoundAsync(HttpContext context)
{
context.Response.StatusCode = StatusCodes.Status404NotFound;
await context.Response.WriteAsync(string.Empty);
}
static Task Handle404NotFoundAsync(HttpContext context)
=> HandleStatusCodeAsync(context, StatusCodes.Status404NotFound);
}
@@ -1,5 +1,6 @@
// https://github.com/dotnetcore/FastGithub/blob/2.1.4/FastGithub.HttpServer/HttpReverseProxyMiddleware.cs
using DynamicData.Kernel;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Extensions.Logging;
@@ -60,17 +61,28 @@ sealed class HttpReverseProxyMiddleware
if (TryGetDomainConfig(url, out var domainConfig) == false)
{
await next(context);
if (isScriptInject)
await HandleScriptInject(context, scriptConfigs, memoryStream!, originalBody!);
return;
}
if (domainConfig == defaultDomainConfig &&
!reverseProxyConfig.Service.OnlyEnableProxyScript)
{
//部分运营商将奇怪的域名解析到127.0.0.1 再此排除这些不支持的代理域名
var ip = await reverseProxyConfig.DnsAnalysis.AnalysisDomainIpAsync(context.Request.Host.Value, IDnsAnalysisService.DNS_Dnspods).FirstOrDefaultAsync();
if (ip == null || IPAddress.IsLoopback(ip))
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
await context.Response.WriteAsync($"域名 {context.Request.Host.Host} 可能已经被 DNS 污染,如果域名为本机域名,请解析为非回环 IP。", Encoding.UTF8);
return;
}
}
if (domainConfig.Items.Any_Nullable())
domainConfig = RecursionMatchDomainConfig(url, domainConfig);
if (domainConfig.Response == null)
{
if (IReverseProxyService.Instance.EnableHttpProxyToHttps && context.Request.Scheme == Uri.UriSchemeHttp)
if (reverseProxyConfig.Service.EnableHttpProxyToHttps && context.Request.Scheme == Uri.UriSchemeHttp)
{
context.Response.Redirect(Uri.UriSchemeHttps + "://" + context.Request.Host.Host + context.Request.RawUrl());
return;
@@ -126,7 +138,7 @@ sealed class HttpReverseProxyMiddleware
{
domainConfig = null;
if (!IReverseProxyService.Instance.OnlyEnableProxyScript && reverseProxyConfig.TryGetDomainConfig(uri, out domainConfig) == true)
if (!reverseProxyConfig.Service.OnlyEnableProxyScript && reverseProxyConfig.TryGetDomainConfig(uri, out domainConfig) == true)
{
return true;
}
@@ -135,9 +147,8 @@ sealed class HttpReverseProxyMiddleware
// 未配置的域名,但仍然被解析到本机 IP 的域名
if (IsDomain(host))
{
if (IReverseProxyService.Instance.ProxyMode != ProxyMode.System)
logger.LogWarning(
$"域名 {host} 可能已经被 DNS 污染,如果域名为本机域名,请解析为非回环 IP。");
logger.LogWarning(
$"域名 {host} 可能已经被 DNS 污染,如果域名为本机域名,请解析为非回环 IP。");
domainConfig = defaultDomainConfig;
return true;
}
@@ -180,11 +191,7 @@ sealed class HttpReverseProxyMiddleware
/// <returns></returns>
static async Task HandleErrorAsync(HttpContext context, ForwarderError error)
{
await context.Response.WriteAsJsonAsync(new
{
error = error.ToString(),
message = context.GetForwarderErrorFeature()?.Exception?.Message,
});
await context.Response.WriteAsync($"{error}:{context.GetForwarderErrorFeature()?.Exception?.Message}");
}
/// <summary>
@@ -487,18 +494,24 @@ sealed class HttpReverseProxyMiddleware
match_mark_start_index++;
if (match_mark_start_index >= mark_start.Length)
{
const int matchCharCount = 4;
var index_name_start = i + mark_start.Length;
var name = encoding.GetString(buffer.Span[index_name_start..index_name_end]);
if (name.Equals("body", StringComparison.OrdinalIgnoreCase) ||
name.Equals("head", StringComparison.OrdinalIgnoreCase))
//if (encoding.GetMaxCharCount(index_name_end - index_name_start) >= matchCharCount)
//{
var bytes = buffer.Span[index_name_start..index_name_end];
var charCount = encoding.GetCharCount(bytes);
if (charCount == matchCharCount)
{
insertPosition = index_name_start - mark_start.Length;
return true;
}
else
{
goto reset;
var name = encoding.GetString(bytes);
if (name.Equals("body", StringComparison.OrdinalIgnoreCase) ||
name.Equals("head", StringComparison.OrdinalIgnoreCase))
{
insertPosition = index_name_start - mark_start.Length;
return true;
}
}
//}
goto reset;
}
}
}
@@ -78,7 +78,7 @@ sealed partial class YarpCertificateManagerImpl : CertificateManagerImpl, ICerti
"Could not remove certificate as it is null or empty.");
}
using var x509Store = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
using var x509Store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
try
{
@@ -96,7 +96,7 @@ sealed partial class YarpCertificateManagerImpl : CertificateManagerImpl, ICerti
catch (Exception e)
{
Log.Error(TAG, new ApplicationException(
"Failed to remove root certificate trust for CurrentUser store location. You may need admin rights.", e), nameof(SharedRemoveTrustedRootCertificate));
"Failed to remove root certificate trust for LocalMachine store location. You may need admin rights.", e), nameof(SharedRemoveTrustedRootCertificate));
}
finally
{
@@ -112,7 +112,7 @@ sealed partial class YarpCertificateManagerImpl : CertificateManagerImpl, ICerti
"Could not install certificate as it is null or empty.");
}
using var store = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
using var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
try
{
store.Open(OpenFlags.ReadWrite);
@@ -68,7 +68,8 @@ sealed partial class YarpReverseProxyServiceImpl : ReverseProxyServiceImpl, IRev
else
{
options.ListenHttpsReverseProxy();
options.ListenHttpReverseProxy();
if (EnableHttpProxyToHttps)
options.ListenHttpReverseProxy();
}
});
@@ -78,13 +78,13 @@ public interface ICertificateManager
/// <summary>
/// 由平台实现的信任根证书引导,有 Root 权限将尝试执行信任,否则则 UI 引导,跳转网页或弹窗
/// </summary>
void PlatformTrustRootCertificateGuide();
ValueTask PlatformTrustRootCertificateGuide();
/// <summary>
/// 安装根证书,如果没有证书将生成一个新的
/// </summary>
/// <returns>返回根证书是否受信任</returns>
bool SetupRootCertificate();
ValueTask<bool> SetupRootCertificate();
/// <summary>
/// 删除根证书,如果没有证书将返回 <see langword="true"/>
@@ -117,7 +117,7 @@ public interface IReverseProxyService : IDisposable
/// <returns></returns>
bool PortInUse(int port);
Task<bool> StartProxy();
ValueTask<bool> StartProxy();
Task StopProxy();
@@ -87,7 +87,7 @@ abstract partial class CertificateManagerImpl
}
}
void TrustRootCertificate()
async ValueTask TrustRootCertificate()
{
try
{
@@ -102,17 +102,17 @@ abstract partial class CertificateManagerImpl
catch { }
#endif
PlatformTrustRootCertificateGuide();
await PlatformTrustRootCertificateGuide();
}
/// <inheritdoc cref="ICertificateManager.PlatformTrustRootCertificateGuide"/>
public void PlatformTrustRootCertificateGuide()
public async ValueTask PlatformTrustRootCertificateGuide()
{
try
{
if (OperatingSystem2.IsMacOS())
{
TrustRootCertificateMacOS();
await TrustRootCertificateMacOS();
}
else if (OperatingSystem2.IsLinux() && !OperatingSystem2.IsAndroid())
{
@@ -130,11 +130,14 @@ abstract partial class CertificateManagerImpl
}
[SupportedOSPlatform("macOS")]
void TrustRootCertificateMacOS()
async ValueTask TrustRootCertificateMacOS()
{
var filePath = GetCerFilePathGeneratedWhenNoFileExists();
if (filePath == null) return;
platformService.RunShell($"security add-trusted-cert -d -r trustRoot -k /Users/{Environment.UserName}/Library/Keychains/login.keychain-db \\\"{filePath}\\\"", true);
var state = await platformService.TrustRootCertificate(filePath);
//await platformService.RunShellAsync($"security add-trusted-cert -d -r trustRoot -k /Users/{Environment.UserName}/Library/Keychains/login.keychain-db \\\"{filePath}\\\"", true);
if (state != null && !IsRootCertificateInstalled)
await TrustRootCertificateMacOS();
}
[SupportedOSPlatform("Linux")]
@@ -152,12 +155,12 @@ abstract partial class CertificateManagerImpl
}
/// <inheritdoc cref="ICertificateManager.SetupRootCertificate"/>
public bool SetupRootCertificate()
public async ValueTask<bool> SetupRootCertificate()
{
if (!GenerateCertificate()) return false;
if (!IsRootCertificateInstalled)
{
TrustRootCertificate();
await TrustRootCertificate();
return IsRootCertificateInstalled;
}
return true;
@@ -207,7 +210,7 @@ abstract partial class CertificateManagerImpl
[SupportedOSPlatform("Linux")]
void DeleteRootCertificateLinux()
{
using var store = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
using var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var collection = store.Certificates.Find(X509FindType.FindByIssuerName, IReverseProxyService.RootCertificateName, false);
foreach (var item in collection)
@@ -230,7 +233,7 @@ abstract partial class CertificateManagerImpl
[SupportedOSPlatform("macOS")]
async void DeleteRootCertificateMacOS()
{
using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
using var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var collection = store.Certificates.Find(X509FindType.FindByIssuerName, IReverseProxyService.RootCertificateName, false);
foreach (var item in collection)
@@ -284,7 +287,7 @@ abstract partial class CertificateManagerImpl
}
else
{
using var store = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
using var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
return store.Certificates.Contains(certificate2);
}
@@ -12,13 +12,13 @@ abstract class ReverseProxyServiceImpl
public ReverseProxyServiceImpl(
IPlatformService platformService,
IDnsAnalysisService dnsAnalysis)
IDnsAnalysisService dnsAnalyses)
{
this.platformService = platformService;
DnsAnalysis = dnsAnalysis;
DnsAnalysis = dnsAnalyses;
}
public IDnsAnalysisService DnsAnalysis { get; }
public IDnsAnalysisService? DnsAnalysis { get; }
public abstract ICertificateManager CertificateManager { get; }
@@ -153,14 +153,15 @@ abstract class ReverseProxyServiceImpl
public abstract EReverseProxyEngine ReverseProxyEngine { get; }
public async Task<bool> StartProxy()
public async ValueTask<bool> StartProxy()
{
if (!CertificateManager.IsRootCertificateInstalled)
{
//CertificateManager.DeleteRootCertificate();
var isOk = CertificateManager.SetupRootCertificate();
var isOk = await CertificateManager.SetupRootCertificate();
if (!isOk)
{
Log.Error("StartProxy", "证书安装失败,或未信任。");
return false;
}
}
+4 -1
View File
@@ -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)
+11 -1
View File
@@ -7,6 +7,10 @@
<AssemblyName>System.Application.SteamTools.Client</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" $(TargetFramework.Contains('-android')) ">
<DefineConstants>EXCLUDE_ASF;$(DefineConstants)</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Common.CoreLib\Properties\AssemblyInfo.cs">
<Link>Properties\AssemblyInfo.cs</Link>
@@ -37,13 +41,18 @@
<!--<PackageReference Include="CommunityToolkit.Mvvm"/>-->
<PackageReference Include="ReactiveUI.Fody" />
<!--<PackageReference Include="ArchiSteamFarm.Library" />-->
<PackageReference Include="Ae.DNS.Client" />
<!--<PackageReference Include="Ae.Dns.Protocol" />-->
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard')) ">
<PackageReference Include="JustArchiNET.Madness" />
</ItemGroup>
<ItemGroup>
<ItemGroup Condition=" !$(TargetFramework.Contains('-android')) ">
<ProjectReference Include="..\..\references\ArchiSteamFarm\ArchiSteamFarm.Library\ArchiSteamFarm.Library.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Common.PinyinLib\Common.PinyinLib.csproj" />
<ProjectReference Include="..\Repositories.sqlite-net-pcl\Repositories.sqlite-net-pcl.csproj" />
<ProjectReference Include="..\ST.Client.ReverseProxy\ST.Client.ReverseProxy.csproj" />
@@ -84,4 +93,5 @@
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" PrivateAssets="All" />
</ItemGroup>
</Project>
@@ -1,3 +1,4 @@
#if !EXCLUDE_ASF
using ArchiSteamFarm;
using ArchiSteamFarm.Steam;
using ArchiSteamFarm.Storage;
@@ -79,4 +80,5 @@ namespace System.Application.Services
}
}
}
}
}
#endif
@@ -1,3 +1,4 @@
#if !EXCLUDE_ASF
using ArchiSteamFarm;
using System.Application.Settings;
using System.Collections.Generic;
@@ -30,3 +31,4 @@ partial interface IArchiSteamFarmService : IArchiSteamFarmHelperService
}
}
}
#endif
+23 -1
View File
@@ -12,9 +12,16 @@ namespace System.Application.Services
/// </summary>
public interface IDnsAnalysisService
{
protected const string TAG = "DnsAnalysisService";
static IDnsAnalysisService Instance => DI.Get<IDnsAnalysisService>();
#region DNS常量
const string DNS_Ali_DohAddres = "https://dns.alidns.com";
const string Dnspod_DohAddres = "https://1.12.12.12";
const string Google_DohAddres = "https://dns.google";
const string Cloudflare_DohAddres = "https://cloudflare-dns.com";
protected const string PrimaryDNS_IPV6_Ali = "2400:3200::1";
const string PrimaryDNS_Ali = "223.5.5.5";
@@ -66,7 +73,7 @@ namespace System.Application.Services
return r.RoundtripTime;
}
int AnalysisHostnameTime(string url);
Task<int> AnalysisHostnameTime(string url, CancellationToken cancellationToken = default);
/// <summary>
/// 解析域名 IP 地址
@@ -119,6 +126,19 @@ namespace System.Application.Services
}
}
/// <summary>
/// DOH 解析域名 IP 地址
/// </summary>
/// <param name="hostNameOrAddress">要解析的主机名或 IP 地址</param>
/// <param name="dnsServers">自定义 DNS 服务器,可选的值有 <see cref="DNS_Alis"/>, <see cref="DNS_114s"/>, <see cref="DNS_Cloudflares"/>, <see cref="DNS_Dnspods"/>, <see cref="DNS_Googles"/></param>
/// <param name="isIPv6"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
IAsyncEnumerable<IPAddress>? DohAnalysisDomainIpAsync(string hostNameOrAddress, string? dnsServers, bool isIPv6, CancellationToken cancellationToken = default)
{
return null;
}
async Task<string?> GetHostByIPAddress(IPAddress ip)
{
var hostEntry = await Dns.GetHostEntryAsync(ip);
@@ -126,5 +146,7 @@ namespace System.Application.Services
}
Task<bool> GetIsIpv6Support() => Task.FromResult(false);
Task<IPAddress?> GetHostIpv6Addres() => Task.FromResult(default(IPAddress));
}
}
@@ -0,0 +1,72 @@
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace System.Application.Services
{
/// <summary>
/// DNS 解析服务
/// </summary>
public interface IDnsDohAnalysisService
{
protected const string TAG = "DnsDohAnalysisService";
static IDnsDohAnalysisService Instance => DI.Get<IDnsDohAnalysisService>();
#region DNS常量
const string DNS_Ali_DohAddres = "https://dns.alidns.com/dns-query";
const string Dnspod_DohAddres = "https://1.12.12.12/dns-query";
const string Google_DohAddres = "https://dns.google/dns-query";
const string Cloudflare_DohAddres = "https://cloudflare-dns.com/dns-query";
#endregion
protected const string IPV6_TESTDOMAIN = "ipv6.rmbgame.net";
/// <summary>
/// 解析域名 IP 地址
/// </summary>
/// <param name="hostNameOrAddress">要解析的主机名或 IP 地址</param>
/// <param name="isIPv6"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
IAsyncEnumerable<IPAddress> AnalysisDomainIpAsync(string hostNameOrAddress, bool isIPv6, CancellationToken cancellationToken = default)
=> AnalysisDomainIpAsync(hostNameOrAddress, default, isIPv6, cancellationToken);
/// <summary>
/// 解析域名 IP 地址
/// </summary>
/// <param name="hostNameOrAddress">要解析的主机名或 IP 地址</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
IAsyncEnumerable<IPAddress> AnalysisDomainIpAsync(string hostNameOrAddress, CancellationToken cancellationToken = default)
=> AnalysisDomainIpAsync(hostNameOrAddress, default, default, cancellationToken);
/// <summary>
/// 解析域名 IP 地址
/// </summary>
/// <param name="hostNameOrAddress">要解析的主机名或 IP 地址</param>
/// <param name="dnsServers">自定义 DNS 服务器,可选的值有 <see cref="DNS_Alis"/>, <see cref="DNS_114s"/>, <see cref="DNS_Cloudflares"/>, <see cref="DNS_Dnspods"/>, <see cref="DNS_Googles"/></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
IAsyncEnumerable<IPAddress> AnalysisDomainIpAsync(string hostNameOrAddress, string? dnsServers, CancellationToken cancellationToken = default)
=> AnalysisDomainIpAsync(hostNameOrAddress, dnsServers, default, cancellationToken);
/// <summary>
/// 解析域名 IP 地址
/// </summary>
/// <param name="hostNameOrAddress">要解析的主机名或 IP 地址</param>
/// <param name="dnsServers">自定义 DNS 服务器,可选的值有 <see cref="DNS_Alis"/>, <see cref="DNS_114s"/>, <see cref="DNS_Cloudflares"/>, <see cref="DNS_Dnspods"/>, <see cref="DNS_Googles"/></param>
/// <param name="isIPv6"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
IAsyncEnumerable<IPAddress> AnalysisDomainIpAsync(string hostNameOrAddress, string? dnsServers, bool isIPv6, CancellationToken cancellationToken = default);
Task<bool> GetIsIpv6Support() => Task.FromResult(false);
}
}

Some files were not shown because too many files have changed in this diff Show More