Compare commits

..
31 Commits
Author SHA1 Message Date
Aigio Liu a021462411 v2.7.1 rev.3 2022-04-28 12:41:39 +08:00
RMBGAME f55f6bf95c fix 2022-04-28 12:10:33 +08:00
Aigio Liu e7a254c377 fix slnf 2022-04-28 12:09:07 +08:00
Aigio Liu 59a35e45e4 v2.7.1 rev.2 2022-04-28 11:59:57 +08:00
Aigio Liu 6adce8e71d v2.7.1 rev.1 2022-04-28 09:36:17 +08:00
dependabot[bot] f620722113 Bump JustArchiNET.Madness from 3.5.1 to 3.5.2 (#1288)
Bumps [JustArchiNET.Madness](https://github.com/JustArchiNET/Madness) from 3.5.1 to 3.5.2.
- [Release notes](https://github.com/JustArchiNET/Madness/releases)
- [Commits](https://github.com/JustArchiNET/Madness/compare/3.5.1...3.5.2)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-28 09:32:53 +08:00
dependabot[bot]andAigio L 6c3f3b33ae Bump ReactiveUI.XamForms from 18.0.7 to 18.0.10 (#1304)
Bumps [ReactiveUI.XamForms](https://github.com/reactiveui/reactiveui) from 18.0.7 to 18.0.10.
- [Release notes](https://github.com/reactiveui/reactiveui/releases)
- [Commits](https://github.com/reactiveui/reactiveui/compare/18.0.7...18.0.10)

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

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-04-28 09:31:52 +08:00
dependabot[bot] e23c0a901d Bump ReactiveUI.AndroidX from 18.0.7 to 18.0.10 (#1311)
Bumps [ReactiveUI.AndroidX](https://github.com/reactiveui/reactiveui) from 18.0.7 to 18.0.10.
- [Release notes](https://github.com/reactiveui/reactiveui/releases)
- [Commits](https://github.com/reactiveui/reactiveui/compare/18.0.7...18.0.10)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-28 09:31:17 +08:00
dependabot[bot]andAigio L 832c115e79 Bump ReactiveUI from 18.0.7 to 18.0.10 (#1306)
Bumps [ReactiveUI](https://github.com/reactiveui/reactiveui) from 18.0.7 to 18.0.10.
- [Release notes](https://github.com/reactiveui/reactiveui/releases)
- [Commits](https://github.com/reactiveui/reactiveui/compare/18.0.7...18.0.10)

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

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-04-28 09:31:08 +08:00
dependabot[bot] 7b510f1536 Bump SQLitePCLRaw.bundle_green (#1305)
Bumps [SQLitePCLRaw.bundle_green](https://github.com/ericsink/SQLitePCL.raw) from 2.1.0-pre20220318192836 to 2.1.0-pre20220427180151.
- [Release notes](https://github.com/ericsink/SQLitePCL.raw/releases)
- [Commits](https://github.com/ericsink/SQLitePCL.raw/commits)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-28 09:27:19 +08:00
dependabot[bot] de7ed70517 Bump Octokit from 0.50.0 to 0.51.0 (#1310)
Bumps [Octokit](https://github.com/octokit/octokit.net) from 0.50.0 to 0.51.0.
- [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/v0.50.0...v0.51.0)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-28 09:26:55 +08:00
dependabot[bot] b438164b52 Bump DynamicData from 7.6.7 to 7.7.1 (#1312)
Bumps [DynamicData](https://github.com/reactiveui/DynamicData) from 7.6.7 to 7.7.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.6.7...7.7.1)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-28 09:26:40 +08:00
Aigio Liu f962d36894 优化 Skia ImmutableBitmap 构建 2022-04-28 02:11:06 +08:00
Aigio Liu 162a809840 Custom Skia ImmutableBitmap 2022-04-27 22:58:27 +08:00
Aigio Liu c1016614db fix
// System.ArgumentNullException:“Value cannot be null. Arg_ParamName_Name”
                // 在 SkiaSharp.SKManagedStream.OnReadManagedStream(IntPtr buffer, IntPtr size)
                // 在 SkiaSharp.SKManagedStream.OnRead(IntPtr buffer, IntPtr size)
                // 在 SkiaSharp.SKAbstractManagedStream.ReadInternal(IntPtr s, Void* context, Void* buffer, IntPtr size)
                // 在 SkiaSharp.SkiaApi.sk_codec_new_from_stream(IntPtr stream, SKCodecResult* result)
                // 在 SkiaSharp.SKCodec.Create(SKStream stream, SKCodecResult& result)
                // 在 SkiaSharp.SKCodec.Create(SKStream stream)
2022-04-27 22:03:52 +08:00
RMBGAME cad5ef60a9 Misc 2022-04-27 20:27:17 +08:00
Aigio Liu cb9d4b31e9 fix Android 两个退出登录按钮 & 第三方快速登录使用外部浏览器处理,删除 Microsoft.IdentityModel.Protocols 2022-04-27 19:52:20 +08:00
RMBGAME ff87958dc0 try fix mac crash 2022-04-27 19:20:14 +08:00
Mossimo 0306732eea Revert 2022-04-27 18:37:30 +08:00
Mossimo 727d429ca7 Revert "v2.7.0 rev.2"
This reverts commit 31f6c4c32c.
2022-04-27 18:22:25 +08:00
Aigio Liu 3a41b36bda Android Misc & SkiaSharp & HarfBuzzSharp preview.178 2022-04-27 18:09:45 +08:00
Aigio Liu 7776192c5a v2.7.1 rev.0 2022-04-27 17:13:25 +08:00
RMBGAME 97e3ebfc20 修复steam库存游戏在steam账号切换后自动刷新失败的问题
修复steam库存游戏编辑带有本地化名称的游戏无效的问题
2022-04-27 14:09:16 +08:00
dependabot[bot] 453334ded8 Bump Z.EntityFramework.Plus.EFCore from 6.13.17 to 6.13.18 (#1297)
Bumps [Z.EntityFramework.Plus.EFCore](https://github.com/zzzprojects/EntityFramework-Plus) from 6.13.17 to 6.13.18.
- [Release notes](https://github.com/zzzprojects/EntityFramework-Plus/releases)
- [Commits](https://github.com/zzzprojects/EntityFramework-Plus/commits)

---
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>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-27 09:25:19 +08:00
dependabot[bot]andAigio L b5d5bd0b53 Bump HarfBuzzSharp.NativeAssets.Linux (#1300)
Bumps [HarfBuzzSharp.NativeAssets.Linux](https://github.com/mono/SkiaSharp) from 2.8.2-preview.254 to 2.8.2-preview.256.
- [Release notes](https://github.com/mono/SkiaSharp/releases)
- [Commits](https://github.com/mono/SkiaSharp/commits)

---
updated-dependencies:
- dependency-name: HarfBuzzSharp.NativeAssets.Linux
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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-04-27 09:25:10 +08:00
dependabot[bot] 7b5a06ba24 Bump HarfBuzzSharp from 2.8.2-preview.254 to 2.8.2-preview.256 (#1298)
Bumps [HarfBuzzSharp](https://github.com/mono/SkiaSharp) from 2.8.2-preview.254 to 2.8.2-preview.256.
- [Release notes](https://github.com/mono/SkiaSharp/releases)
- [Commits](https://github.com/mono/SkiaSharp/commits)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-27 09:24:26 +08:00
dependabot[bot]andAigio L a65bd810a5 Bump SkiaSharp.NativeAssets.Linux (#1299)
Bumps [SkiaSharp.NativeAssets.Linux](https://github.com/mono/SkiaSharp) from 2.88.0-preview.254 to 2.88.0-preview.256.
- [Release notes](https://github.com/mono/SkiaSharp/releases)
- [Commits](https://github.com/mono/SkiaSharp/commits)

---
updated-dependencies:
- dependency-name: SkiaSharp.NativeAssets.Linux
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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-04-27 09:24:16 +08:00
dependabot[bot] 6b01cffc29 Bump SkiaSharp from 2.88.0-preview.254 to 2.88.0-preview.256 (#1302)
Bumps [SkiaSharp](https://github.com/mono/SkiaSharp) from 2.88.0-preview.254 to 2.88.0-preview.256.
- [Release notes](https://github.com/mono/SkiaSharp/releases)
- [Commits](https://github.com/mono/SkiaSharp/commits)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-27 09:23:37 +08:00
dependabot[bot] d10fc62a00 Bump NPOI from 2.5.5 to 2.5.6 (#1301)
Bumps [NPOI](https://github.com/nissl-lab/npoi) from 2.5.5 to 2.5.6.
- [Release notes](https://github.com/nissl-lab/npoi/releases)
- [Commits](https://github.com/nissl-lab/npoi/commits)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-27 09:22:45 +08:00
Aigio Liu 858af3f8b6 修复库存游戏中挂时长失效 2022-04-27 09:00:54 +08:00
Aigio Liu 3e8cb72c55 misc 2022-04-26 16:31:51 +08:00
53 changed files with 920 additions and 175 deletions
+13 -9
View File
@@ -56,10 +56,9 @@
<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.13.17" />
<PackageVersion Include="Z.EntityFramework.Plus.EFCore" Version="6.13.18" />
<!-- AspNetCore 6 OpenId/OAuth -->
<PackageVersion Include="Microsoft.IdentityModel.Protocols" Version="6.17.0" />
<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" />
@@ -134,15 +133,17 @@
<!-- ReactiveUI -->
<PackageVersion Include="System.Reactive" Version="5.0.0" />
<PackageVersion Include="Splat" Version="14.2.8" />
<PackageVersion Include="DynamicData" Version="7.6.7" />
<PackageVersion Include="ReactiveUI" Version="18.0.7" />
<PackageVersion Include="DynamicData" Version="7.7.1" />
<PackageVersion Include="ReactiveUI" Version="18.0.10" />
<!--<PackageVersion Include="ReactiveUI.Fody" Version="17.1.50" /> -->
<PackageVersion Include="ReactiveUI.XamForms" Version="18.0.7" />
<PackageVersion Include="ReactiveUI.AndroidX" Version="18.0.7" />
<PackageVersion Include="ReactiveUI.XamForms" Version="18.0.10" />
<PackageVersion Include="ReactiveUI.AndroidX" Version="18.0.10" />
<!-- SkiaSharp & HarfBuzzSharp -->
<!-- https://github.com/AvaloniaUI/Avalonia/blob/master/build/HarfBuzzSharp.props -->
<PackageVersion Include="HarfBuzzSharp" Version="2.8.2-preview.254" />
<PackageVersion Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.8.2-preview.254" />
<!-- https://github.com/AvaloniaUI/Avalonia/blob/master/build/SkiaSharp.props -->
<PackageVersion Include="SkiaSharp" Version="2.88.0-preview.254" />
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.0-preview.254" />
@@ -196,14 +197,14 @@
<!--<PackageVersion Include="AlipaySDKNet.Standard" Version="4.6.109" />-->
<!-- Excel -->
<PackageVersion Include="NPOI" Version="2.5.5" />
<PackageVersion Include="NPOI" Version="2.5.6" />
<!-- Github API -->
<PackageVersion Include="Octokit" Version="0.50.0" />
<PackageVersion Include="Octokit" Version="0.51.0" />
<!-- ORM -->
<PackageVersion Include="sqlite-net-pcl" Version="1.8.116" />
<PackageVersion Include="SQLitePCLRaw.bundle_green" Version="2.1.0-pre20220318192836" />
<PackageVersion Include="SQLitePCLRaw.bundle_green" Version="2.1.0-pre20220427180151" />
<!-- MonoMac(NETSTANDARD) -->
<PackageVersion Include="MonoMac.NetStandard" Version="0.0.4" />
@@ -257,6 +258,9 @@
<!--<PackageVersion Include="LibVLCSharp.Avalonia" Version="3.5.1" />-->
<!--<PackageVersion Include="FluentAvaloniaUI" Version="1.3.0" />-->
<PackageVersion Include="JumpLists.Win32.Avalonia" Version="1.0.0" />
<PackageVersion Include="Avalonia.Native" Version="0.10.13" />
<PackageVersion Include="Avalonia.Win32" Version="0.10.13" />
<PackageVersion Include="Avalonia.X11" Version="0.10.13" />
<!--Avalonia End-->
<!-- Xamarin.Android -->
+2
View File
@@ -15,6 +15,8 @@
"src\\Avalonia.Themes.Fluent\\Avalonia.Themes.Fluent.csproj",
"src\\Avalonia.Win32\\Avalonia.Win32.csproj",
"src\\Avalonia.X11\\Avalonia.X11.csproj",
"src\\Avalonia.Desktop\\Avalonia.Desktop.csproj",
"src\\Avalonia.Skia.Internals\\Avalonia.Skia.Internals.csproj",
"src\\Common.AreaLib\\Common.AreaLib.csproj",
"src\\Common.ClientLib\\Common.ClientLib.csproj",
"src\\Common.CoreLib\\Common.CoreLib.csproj",
+2
View File
@@ -15,6 +15,8 @@
"src\\Avalonia.Themes.Fluent\\Avalonia.Themes.Fluent.csproj",
"src\\Avalonia.Win32\\Avalonia.Win32.csproj",
"src\\Avalonia.X11\\Avalonia.X11.csproj",
"src\\Avalonia.Desktop\\Avalonia.Desktop.csproj",
"src\\Avalonia.Skia.Internals\\Avalonia.Skia.Internals.csproj",
"src\\Common.AreaLib\\Common.AreaLib.csproj",
"src\\Common.ClientLib.iOS\\Common.ClientLib.iOS.csproj",
"src\\Common.ClientLib\\Common.ClientLib.csproj",
+35 -4
View File
@@ -182,11 +182,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Android.ResSecret
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.ResSecrets", "src\ST.Client.ResSecrets\ST.Client.ResSecrets.csproj", "{089D4418-975B-455D-9AE1-B9DEC20FF4B1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ST.Client.iOS.ResSecrets", "src\ST.Client.iOS.ResSecrets\ST.Client.iOS.ResSecrets.csproj", "{872B65EB-E9DF-4357-B541-DD4A39B281A0}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.iOS.ResSecrets", "src\ST.Client.iOS.ResSecrets\ST.Client.iOS.ResSecrets.csproj", "{872B65EB-E9DF-4357-B541-DD4A39B281A0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ST.Client.Mac.ResSecrets", "src\ST.Client.Mac.ResSecrets\ST.Client.Mac.ResSecrets.csproj", "{3950554F-7219-4AB9-9BE8-9B5EBDBCA88C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Mac.ResSecrets", "src\ST.Client.Mac.ResSecrets\ST.Client.Mac.ResSecrets.csproj", "{3950554F-7219-4AB9-9BE8-9B5EBDBCA88C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ST.Client.Windows.ResSecrets", "src\ST.Client.Windows.ResSecrets\ST.Client.Windows.ResSecrets.csproj", "{058F9955-8EFE-4BF3-A8F9-44C57B1F812E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Windows.ResSecrets", "src\ST.Client.Windows.ResSecrets\ST.Client.Windows.ResSecrets.csproj", "{058F9955-8EFE-4BF3-A8F9-44C57B1F812E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Desktop", "src\Avalonia.Desktop\Avalonia.Desktop.csproj", "{FA9F0E89-E410-400A-86F3-C603E51E62A8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -2068,6 +2070,34 @@ Global
{058F9955-8EFE-4BF3-A8F9-44C57B1F812E}.Release|x64.Build.0 = Release|Any CPU
{058F9955-8EFE-4BF3-A8F9-44C57B1F812E}.Release|x86.ActiveCfg = Release|Any CPU
{058F9955-8EFE-4BF3-A8F9-44C57B1F812E}.Release|x86.Build.0 = Release|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Debug|ARM.ActiveCfg = Debug|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Debug|ARM.Build.0 = Debug|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Debug|ARM64.Build.0 = Debug|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Debug|iPhone.Build.0 = Debug|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Debug|x64.ActiveCfg = Debug|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Debug|x64.Build.0 = Debug|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Debug|x86.ActiveCfg = Debug|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Debug|x86.Build.0 = Debug|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Release|Any CPU.Build.0 = Release|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Release|ARM.ActiveCfg = Release|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Release|ARM.Build.0 = Release|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Release|ARM64.ActiveCfg = Release|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Release|ARM64.Build.0 = Release|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Release|iPhone.ActiveCfg = Release|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Release|iPhone.Build.0 = Release|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{FA9F0E89-E410-400A-86F3-C603E51E62A8}.Release|x64.ActiveCfg = Release|Any CPU
{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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -2141,9 +2171,10 @@ Global
{872B65EB-E9DF-4357-B541-DD4A39B281A0} = {17667B53-1A09-45A6-855A-0F07F9AE044F}
{3950554F-7219-4AB9-9BE8-9B5EBDBCA88C} = {17667B53-1A09-45A6-855A-0F07F9AE044F}
{058F9955-8EFE-4BF3-A8F9-44C57B1F812E} = {17667B53-1A09-45A6-855A-0F07F9AE044F}
{FA9F0E89-E410-400A-86F3-C603E51E62A8} = {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.7.0</string>
<string>2.7.1</string>
<key>CFBundleVersion</key>
<string>2.7.0.0</string>
<string>2.7.1.0</string>
<key>LSMinimumSystemVersion</key>
<string>10.15</string>
<key>CFBundleDevelopmentRegion</key>
+26 -15
View File
@@ -1,4 +1,6 @@
### 版本亮点
<!--
1. Android 支持 VPN 模式(推荐) 进行本地加速
2. 新增 Steam 游戏信息编辑功能,可修改游戏名称、图片、启动项等数据并同步至 Steam 客户端生效
3. ASF 升级至 V5.2.5.4
@@ -8,11 +10,19 @@
7. 网络加速新增 MEGA 网盘反代服务
8. macOS 支持 Arm64(Apple Silicon)
<!--
. ~~Windows 支持 DNS 驱动拦截模式(推荐) 进行本地加速~~
-->
### 修复问题
1. 修复 库存游戏中挂时长失效
2. 修复 Steam 库存游戏在 Steam 账号切换后自动刷新失败的问题
3. 修复 Steam 库存游戏编辑带有本地化名称的游戏无效的问题
4. 修复 Android 上登录后出现两个退出登录按钮
5. 改进 Android 上第三方快速登录使用系统默认浏览器
6. 修复 一些图片加载失败不显示的问题
7. 改进 从本地加载图片减少不必要的内存分配
<!--
1. 修复 本地令牌 无令牌刷新时提示密码错误
2. 改进 Android 端 本地令牌 列表样式第一条与最后一条的上下外边距
3. 改进 俄语翻译,由 vanja-san 提供
@@ -29,6 +39,7 @@
14. 修复 消息框不再提醒复选框勾上可能不生效的问题
15. 修复 Windows 端, JumpList 切换 Steam Beta 账号失效的问题
16. 修复 ASF,当使用 IPC.config 时,程序内打开网页端口号值不正确
-->
### 已知问题
- 除 Windows 之外的平台此软件自动更新尚不可用
@@ -61,7 +72,7 @@
[![steampp.net](https://img.shields.io/badge/WebSite-steampp.net-brightgreen.svg?style=flat-square&color=61dafb)](https://steampp.net)
[![Steam++ v2.7.0](https://img.shields.io/badge/Steam++-v2.7.0-brightgreen.svg?style=flat-square&color=512bd4)]()
[![Steam++ v2.7.1](https://img.shields.io/badge/Steam++-v2.7.1-brightgreen.svg?style=flat-square&color=512bd4)]()
##### [不知道该下载哪个文件?](./download-guide.md)
@@ -70,22 +81,22 @@
### 文件校验
| File | Checksum (SHA256) |
| ---- | ---- |
| Steam++_win_x64_v2.7.0.7z | SHA256 |
| Steam++_win_x64_fde_v2.7.0.7z | SHA256 |
| Steam++_win_x64_v2.7.1.7z | SHA256 |
| Steam++_win_x64_fde_v2.7.1.7z | SHA256 |
| | |
| Steam++_win_x64_v2.7.0.exe | SHA256 |
| Steam++_win_x64_fde_v2.7.0.exe | SHA256 |
| Steam++_win_x64_v2.7.1.exe | SHA256 |
| Steam++_win_x64_fde_v2.7.1.exe | SHA256 |
| | |
| Steam++_linux_x64_v2.7.0.7z | SHA256 |
| Steam++_linux_arm64_v2.7.0.7z | SHA256 |
| Steam++_linux_x64_v2.7.1.7z | SHA256 |
| Steam++_linux_arm64_v2.7.1.7z | SHA256 |
| | |
| Steam++_linux_x64_v2.7.0.deb | SHA256 |
| Steam++_linux_arm64_v2.7.0.deb | SHA256 |
| Steam++_linux_x64_v2.7.1.deb | SHA256 |
| Steam++_linux_arm64_v2.7.1.deb | SHA256 |
| | |
| Steam++_linux_x64_v2.7.0.rpm | SHA256 |
| Steam++_linux_arm64_v2.7.0.rpm | SHA256 |
| Steam++_linux_x64_v2.7.1.rpm | SHA256 |
| Steam++_linux_arm64_v2.7.1.rpm | SHA256 |
| | |
| Steam++_macos_x64_v2.7.0.dmg | SHA256 |
| Steam++_macos_arm64_v2.7.0.dmg | SHA256 |
| Steam++_macos_x64_v2.7.1.dmg | SHA256 |
| Steam++_macos_arm64_v2.7.1.dmg | SHA256 |
| | |
| Steam++_android_v2.7.0.apk | SHA256 |
| Steam++_android_v2.7.1.apk | SHA256 |
@@ -0,0 +1,42 @@
using Avalonia.Controls;
using Avalonia.Platform;
// https://github.com/AvaloniaUI/Avalonia/blob/0.10.13/src/Avalonia.Desktop/AppBuilderDesktopExtensions.cs
namespace Avalonia
{
public static class AppBuilderDesktopExtensions
{
public static TAppBuilder UsePlatformDetect<TAppBuilder>(this TAppBuilder builder)
where TAppBuilder : AppBuilderBase<TAppBuilder>, new()
{
#if WINDOWS
builder.UseWin32();
#else
var os = builder.RuntimePlatform.GetRuntimeInfo().OperatingSystem;
// We don't have the ability to load every assembly right now, so we are
// stuck with manual configuration here
// Helpers are extracted to separate methods to take the advantage of the fact
// that CLR doesn't try to load dependencies before referencing method is jitted
// Additionally, by having a hard reference to each assembly,
// we verify that the assemblies are in the final .deps.json file
// so .NET Core knows where to load the assemblies from,.
switch (os)
{
case OperatingSystemType.WinNT:
builder.UseWin32();
break;
case OperatingSystemType.OSX:
builder.UseAvaloniaNative();
break;
default:
builder.UseX11();
break;
}
#endif
builder.UseSkia();
return builder;
}
}
}
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.1;net6.0-windows</TargetFrameworks>
<SignAssembly>true</SignAssembly>
<DelaySign>false</DelaySign>
<AssemblyOriginatorKeyFile>$(MSBuildProjectDirectory)\..\..\avalonia.snk</AssemblyOriginatorKeyFile>
<!--https://github.com/AvaloniaUI/Avalonia/blob/0.10.10/build/SharedVersion.props#L18-->
</PropertyGroup>
<ItemGroup>
<Compile Include="..\AssemblyInfo.Version.Max.cs">
<LinkBase>Properties</LinkBase>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Avalonia.Skia.Internals\Avalonia.Skia.Internals.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia.Win32" />
</ItemGroup>
<ItemGroup Condition=" !$(TargetFramework.Contains('-windows')) ">
<PackageReference Include="Avalonia.X11" />
<PackageReference Include="Avalonia.Native" />
</ItemGroup>
</Project>
@@ -14,4 +14,8 @@
</Compile>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" />
</ItemGroup>
</Project>
@@ -0,0 +1,13 @@
using System;
using Avalonia.Controls;
namespace Avalonia
{
public static class AvaloniaNativePlatformExtensions
{
public static T UseAvaloniaNative<T>(this T builder) where T : AppBuilderBase<T>, new()
{
throw new PlatformNotSupportedException();
}
}
}
@@ -18,4 +18,8 @@
<PackageReference Include="StyleCop.Analyzers" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Common.CoreLib\Common.CoreLib.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,187 @@
extern alias AvaloniaSkia;
using System;
using System.IO;
using Avalonia.Platform;
using AvaloniaSkia::Avalonia.Skia.Helpers;
using Avalonia.Visuals.Media.Imaging;
using SkiaSharp;
using AvaloniaSkia::Avalonia.Skia;
using DrawingContextImpl = AvaloniaSkia::Avalonia.Skia.DrawingContextImpl;
using IDrawableBitmapImpl = AvaloniaSkia::Avalonia.Skia.IDrawableBitmapImpl;
// https://github.com/AvaloniaUI/Avalonia/blob/0.10.13/src/Skia/Avalonia.Skia/ImmutableBitmap.cs
namespace Avalonia.Skia
{
/// <summary>
/// Immutable Skia bitmap.
/// </summary>
internal class ImmutableBitmap : IDrawableBitmapImpl
{
private readonly SKImage _image;
public ImmutableBitmap(SKImage image)
{
_image = image;
if (_image == null)
{
throw new ArgumentException("Unable to load bitmap from provided data");
}
PixelSize = new PixelSize(_image.Width, _image.Height);
// TODO: Skia doesn't have an API for DPI.
Dpi = new Vector(96, 96);
}
/// <summary>
/// Create immutable bitmap from given stream.
/// </summary>
/// <param name="stream">Stream containing encoded data.</param>
public ImmutableBitmap(Stream stream) : this(SkiaSharpHelpers.FromEncodedData(stream))
{
}
public ImmutableBitmap(ImmutableBitmap src, PixelSize destinationSize, BitmapInterpolationMode interpolationMode)
{
SKImageInfo info = new SKImageInfo(destinationSize.Width, destinationSize.Height, SKColorType.Bgra8888);
SKImage output = SKImage.Create(info);
src._image.ScalePixels(output.PeekPixels(), interpolationMode.ToSKFilterQuality());
_image = output;
PixelSize = new PixelSize(_image.Width, _image.Height);
// TODO: Skia doesn't have an API for DPI.
Dpi = new Vector(96, 96);
}
public ImmutableBitmap(Stream stream, int decodeSize, bool horizontal, BitmapInterpolationMode interpolationMode) : this(SkiaSharpHelpers.Create(stream), decodeSize, horizontal, interpolationMode)
{
}
public ImmutableBitmap(SKBitmap bmp, int decodeSize, bool horizontal, BitmapInterpolationMode interpolationMode)
{
var info = bmp.Info;
// now scale that to the size that we want
var realScale = horizontal ? ((double)info.Height / info.Width) : ((double)info.Width / info.Height);
SKImageInfo desired;
if (horizontal)
{
desired = new SKImageInfo(decodeSize, (int)(realScale * decodeSize));
}
else
{
desired = new SKImageInfo((int)(realScale * decodeSize), decodeSize);
}
if (bmp.Width != desired.Width || bmp.Height != desired.Height)
{
var scaledBmp = bmp.Resize(desired, interpolationMode.ToSKFilterQuality());
bmp.Dispose();
bmp = scaledBmp;
}
_image = SKImage.FromBitmap(bmp);
bmp.Dispose();
if (_image == null)
{
throw new ArgumentException("Unable to load bitmap from provided data");
}
PixelSize = new PixelSize(_image.Width, _image.Height);
// TODO: Skia doesn't have an API for DPI.
Dpi = new Vector(96, 96);
}
static SKBitmap Decode(SKCodec codec, int decodeSize, bool horizontal, bool leaveOpen)
{
try
{
var info = codec.Info;
// get the scale that is nearest to what we want (eg: jpg returned 512)
var supportedScale = codec.GetScaledDimensions(horizontal ? ((float)decodeSize / info.Width) : ((float)decodeSize / info.Height));
// decode the bitmap at the nearest size
var nearest = new SKImageInfo(supportedScale.Width, supportedScale.Height);
var bmp = SKBitmap.Decode(codec, nearest);
return bmp;
}
finally
{
if (!leaveOpen) codec.Dispose();
}
}
public ImmutableBitmap(SKCodec codec, int decodeSize, bool horizontal, BitmapInterpolationMode interpolationMode, bool leaveOpen = false)
: this(Decode(codec, decodeSize, horizontal, leaveOpen), decodeSize, horizontal, interpolationMode)
{
}
/// <summary>
/// Create immutable bitmap from given pixel data copy.
/// </summary>
/// <param name="size">Size of the bitmap.</param>
/// <param name="dpi">DPI of the bitmap.</param>
/// <param name="stride">Stride of data pixels.</param>
/// <param name="format">Format of data pixels.</param>
/// <param name="alphaFormat">Alpha format of data pixels.</param>
/// <param name="data">Data pixels.</param>
public ImmutableBitmap(PixelSize size, Vector dpi, int stride, PixelFormat format, AlphaFormat alphaFormat, IntPtr data)
{
var imageInfo = new SKImageInfo(size.Width, size.Height, format.ToSkColorType(), alphaFormat.ToSkAlphaType());
_image = SKImage.FromPixelCopy(imageInfo, data, stride);
if (_image == null)
{
throw new ArgumentException("Unable to create bitmap from provided data");
}
PixelSize = size;
Dpi = dpi;
}
public Vector Dpi { get; }
public PixelSize PixelSize { get; }
public int Version { get; } = 1;
/// <inheritdoc />
public void Dispose()
{
_image.Dispose();
}
/// <inheritdoc />
public void Save(string fileName)
{
ImageSavingHelper.SaveImage(_image, fileName);
}
/// <inheritdoc />
public void Save(Stream stream)
{
ImageSavingHelper.SaveImage(_image, stream);
}
/// <inheritdoc />
public void Draw(DrawingContextImpl context, SKRect sourceRect, SKRect destRect, SKPaint paint)
{
context.Canvas.DrawImage(_image, sourceRect, destRect, paint);
}
}
}
@@ -0,0 +1,52 @@
extern alias AvaloniaSkia;
using Avalonia.Platform;
using Avalonia.Visuals.Media.Imaging;
using System;
using System.IO;
using ISkiaGpu = AvaloniaSkia::Avalonia.Skia.ISkiaGpu;
using @this = AvaloniaSkia::Avalonia.Skia.PlatformRenderInterface;
// https://github.com/AvaloniaUI/Avalonia/blob/0.10.13/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
namespace Avalonia.Skia
{
sealed class PlatformRenderInterface : @this, IPlatformRenderInterface
{
public PlatformRenderInterface(ISkiaGpu? skiaGpu, long? maxResourceBytes = null) : base(skiaGpu, maxResourceBytes)
{
}
IBitmapImpl IPlatformRenderInterface.LoadBitmap(Stream stream)
{
return new ImmutableBitmap(stream);
}
IBitmapImpl IPlatformRenderInterface.LoadBitmap(PixelFormat format, AlphaFormat alphaFormat, IntPtr data, PixelSize size, Vector dpi, int stride)
{
return new ImmutableBitmap(size, dpi, stride, format, alphaFormat, data);
}
IBitmapImpl IPlatformRenderInterface.LoadBitmapToWidth(Stream stream, int width, BitmapInterpolationMode interpolationMode)
{
return new ImmutableBitmap(stream, width, true, interpolationMode);
}
IBitmapImpl IPlatformRenderInterface.LoadBitmapToHeight(Stream stream, int height, BitmapInterpolationMode interpolationMode)
{
return new ImmutableBitmap(stream, height, false, interpolationMode);
}
IBitmapImpl IPlatformRenderInterface.ResizeBitmap(IBitmapImpl bitmapImpl, PixelSize destinationSize, BitmapInterpolationMode interpolationMode)
{
if (bitmapImpl is ImmutableBitmap ibmp)
{
return new ImmutableBitmap(ibmp, destinationSize, interpolationMode);
}
else
{
throw new Exception("Invalid source bitmap type.");
}
}
}
}
@@ -0,0 +1,22 @@
extern alias AvaloniaSkia;
using Avalonia.Platform;
using SkiaOptions = AvaloniaSkia::Avalonia.SkiaOptions;
// https://github.com/AvaloniaUI/Avalonia/blob/0.10.13/src/Skia/Avalonia.Skia/SkiaPlatform.cs#L18-L27
namespace Avalonia.Skia
{
public static class SkiaPlatform2
{
public static readonly IPlatformRenderInterface PlatformRenderInterface = GetPlatformRenderInterface();
static IPlatformRenderInterface GetPlatformRenderInterface()
{
var options = AvaloniaLocator.Current.GetService<SkiaOptions>() ?? new();
var customGpu = options.CustomGpuFactory?.Invoke();
var renderInterface = new PlatformRenderInterface(customGpu, options.MaxGpuResourceSizeBytes);
return renderInterface;
}
}
}
@@ -0,0 +1,62 @@
extern alias AvaloniaSkia;
using System.IO;
using SkiaSharp;
using Avalonia.Media.Imaging;
using Avalonia.Utilities;
using Avalonia.Visuals.Media.Imaging;
namespace Avalonia.Skia
{
public static class SkiaSharpHelpers
{
public static SKCodec Create(Stream stream)
{
if (stream is IFileStreamWrapper fileStreamWrapper)
{
return SKCodec.Create(fileStreamWrapper.Name);
}
else if (stream is FileStream fileStream)
{
var filename = fileStream.Name;
return SKCodec.Create(filename);
}
else
{
using var skStream = new SKManagedStream(stream);
return SKCodec.Create(skStream);
}
}
public static SKImage FromEncodedData(Stream stream)
{
if (stream is IFileStreamWrapper fileStreamWrapper)
{
return SKImage.FromEncodedData(fileStreamWrapper.Name);
}
else if (stream is FileStream fileStream)
{
var filename = fileStream.Name;
return SKImage.FromEncodedData(filename);
}
else
{
using var skStream = new SKManagedStream(stream);
using var data = SKData.Create(skStream);
return SKImage.FromEncodedData(data);
}
}
static Bitmap GetBitmap(this ImmutableBitmap bitmap) => new(RefCountable.Create(bitmap));
public static Bitmap GetBitmap(SKImage image) => new ImmutableBitmap(image).GetBitmap();
public static Bitmap GetBitmap(SKBitmap bitmap)
{
var image = SKImage.FromBitmap(bitmap);
return GetBitmap(image);
}
public static Bitmap DecodeToWidth(SKBitmap bitmap, int width, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) => new ImmutableBitmap(bitmap, width, true, interpolationMode).GetBitmap();
}
}
+4
View File
@@ -14,4 +14,8 @@
</Compile>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" />
</ItemGroup>
</Project>
@@ -0,0 +1,13 @@
using System;
using Avalonia.Controls;
namespace Avalonia
{
public static class Win32ApplicationExtensions
{
public static T UseWin32<T>(this T builder) where T : AppBuilderBase<T>, new()
{
throw new PlatformNotSupportedException();
}
}
}
+4
View File
@@ -14,4 +14,8 @@
</Compile>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" />
</ItemGroup>
</Project>
@@ -0,0 +1,13 @@
using System;
using Avalonia.Controls;
namespace Avalonia
{
public static class AvaloniaX11PlatformExtensions
{
public static T UseX11<T>(this T builder) where T : AppBuilderBase<T>, new()
{
throw new PlatformNotSupportedException();
}
}
}
@@ -10,7 +10,7 @@ namespace System.Application
public const string Prefix_HTTP = "http://";
public const string Prefix_MSStore = "ms-windows-store://";
public const string Prefix_Email = "mailto:";
/// <summary>
@@ -0,0 +1,50 @@
namespace System.IO
{
public sealed class FileStreamWrapper : Stream, IFileStreamWrapper
{
FileStreamWrapper(string path)
{
Name = path;
}
public string Name { get; set; }
public override bool CanRead => throw new NotImplementedException();
public override bool CanSeek => throw new NotImplementedException();
public override bool CanWrite => throw new NotImplementedException();
public override long Length => throw new NotImplementedException();
public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public override void Flush()
{
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
public static FileStreamWrapper? Parse(string? filePath) => filePath == null ? null : new(filePath);
public static implicit operator FileStreamWrapper?(string? filePath) => Parse(filePath);
}
}
@@ -0,0 +1,25 @@
namespace System.IO
{
public interface IFileStreamWrapper
{
/// <inheritdoc cref="FileStream.Name"/>
string? Name { get; }
FileStream? FileStream => IOPath.OpenRead(Name);
/// <inheritdoc cref="FileStream(string, FileMode)"/>
FileStream GetFileStream(FileMode mode) => new(Name, mode);
/// <inheritdoc cref="FileStream(string, FileMode, FileAccess)"/>
FileStream GetFileStream(FileMode mode, FileAccess access) => new(Name, mode, access);
/// <inheritdoc cref="FileStream(string, FileMode, FileAccess, FileShare)"/>
FileStream GetFileStream(FileMode mode, FileAccess access, FileShare share) => new(Name, mode, access, share);
/// <inheritdoc cref="FileStream(string, FileMode, FileAccess, FileShare, int)"/>
FileStream GetFileStream(FileMode mode, FileAccess access, FileShare share, int bufferSize) => new(Name, mode, access, share, bufferSize);
/// <inheritdoc cref="FileStream(string, FileMode, FileAccess, FileShare, int, FileOptions)"/>
FileStream GetFileStream(FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options) => new(Name, mode, access, share, bufferSize, options);
}
}
-1
View File
@@ -437,7 +437,6 @@ namespace System
public static FileStream? OpenRead(string? filePath)
{
if (filePath == null) return null;
//var fileStream = OpenReadCore(filePath);
TryOpenRead(filePath, out var stream, out var ex);
if (ex != null)
Log.Error(nameof(OpenRead), ex, "OpenRead Error");
@@ -12,7 +12,7 @@ namespace System.Properties
/// <item> macOS:\packaging\build-osx-app.sh &lt;CFBundleVersion&gt; &lt;CFBundleShortVersionString&gt; </item>
/// </list>
/// </summary>
public const string Version = "2.7.0";
public const string Version = "2.7.1";
//public const string InfoVersion = Version + "-beta";
}
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="20220424" android:versionName="2.7.0" package="net.steampp.app" android:installLocation="auto">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="20220427" android:versionName="2.7.1" 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.-->
@@ -83,5 +83,12 @@ namespace System.Application.UI.Activities
}), length, str.Length, SpanTypes.ExclusiveExclusive));
return str;
});
protected override void OnDestroy()
{
ThirdPartyLoginHelper.DisposeServer();
base.OnDestroy();
}
}
}
@@ -93,5 +93,12 @@ namespace System.Application.UI.Activities
binding!.pager.SetCurrentItem((int)position, false);
}
}
protected override void OnDestroy()
{
ThirdPartyLoginHelper.DisposeServer();
base.OnDestroy();
}
}
}
@@ -17,13 +17,13 @@ using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using static System.Application.UI.ViewModels.CommunityProxyPageViewModel;
using System.Application.Services.Implementation;
using Android.Net;
using static AndroidX.Activity.Result.ActivityResultTask;
using Android.Content;
using System.Application.UI.Activities;
using Android.App;
using static AndroidX.Activity.Result.ActivityResultTask;
using static System.Application.UI.ViewModels.CommunityProxyPageViewModel;
namespace System.Application.UI.Fragments
{
@@ -179,7 +179,7 @@ namespace System.Application.UI.Fragments
"因 Android 7(Nougat API 24) 之后的版本不在信任用户证书,所以此功能已放弃继续开发," +
"如仍想使用需要自行导入证书到系统目录,使用 adb 工具或 Magisk 之类的软件操作," +
"未来会使用不需要证书的加速功能替换此功能";
MessageBox.Show(textCertificateTrustTip, "已知问题",
await MessageBox.ShowAsync(textCertificateTrustTip, "已知问题",
rememberChooseKey: MessageBox.DontPromptType.AndroidCertificateTrustTip);
}
@@ -138,8 +138,9 @@ namespace System.Application.UI.Fragments
async void OnCreateViewAsync()
{
var value = await ITelephonyService.GetAutoFillPhoneNumberAsync(binding!.tbPhoneNumber.Text);
if (value != IUserManager.Instance.GetCurrentUser()?.PhoneNumber)
var value = await ITelephonyService.GetAutoFillPhoneNumberAsync(null);
var currentValue = IUserManager.Instance.GetCurrentUser()?.PhoneNumber;
if (value != currentValue)
{
binding!.tbNewPhoneNumber.Text = value;
}
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
@@ -10,7 +10,7 @@
<Identity
Name="4651ED44255E.47979655102CE"
Publisher="CN=A90E406B-B2D3-4A23-B061-0FA1D65C4F66"
Version="2.7.0.0" />
Version="2.7.1.0" />
<Properties>
<DisplayName>Steam++</DisplayName>
@@ -63,7 +63,7 @@
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
<AppxSymbolPackageEnabled>True</AppxSymbolPackageEnabled>
<EntryPointProjectUniqueName>..\ST.Client.Desktop.Avalonia.App.Bridge\Steam++.csproj</EntryPointProjectUniqueName>
<PackageCertificateThumbprint>96028D399EC2DDDA358B18CD2A2669C4A0D6A862</PackageCertificateThumbprint>
<PackageCertificateKeyFile>ST.Client.Avalonia.App.Bridge.Package_TemporaryKey.pfx</PackageCertificateKeyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<AppxBundle>Always</AppxBundle>
@@ -5,6 +5,7 @@ using Avalonia.Markup.Xaml;
using Avalonia.Markup.Xaml.Styling;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.Skia;
using FluentAvalonia.Styling;
using System.Application.Models;
using System.Application.Mvvm;
@@ -294,12 +295,12 @@ namespace System.Application.UI
#if WINDOWS
if (!ViewModelBase.IsInDesignMode && OperatingSystem2.IsWindows10AtLeast)
{
#pragma warning disable CA1416 // 验证平台兼容性
AvaloniaLocator.CurrentMutable.Bind<IWindowingPlatform>().ToConstant(new AvaloniaWin32WindowingPlatformImpl());
#pragma warning restore CA1416 // 验证平台兼容性
}
#endif
AvaloniaLocator.CurrentMutable.Bind<IPlatformRenderInterface>().ToConstant(SkiaPlatform2.PlatformRenderInterface);
base.RegisterServices();
}
@@ -155,19 +155,21 @@ namespace System.Application.UI
{
Startup.Init(DILevel.Steam);
var users = ISteamService.Instance.GetRememberUserList();
var steamService = ISteamService.Instance;
var users = steamService.GetRememberUserList();
var currentuser = users.Where(s => s.AccountName == account).FirstOrDefault();
if (currentuser != null)
{
currentuser.MostRecent = true;
ISteamService.Instance.UpdateLocalUserData(users);
ISteamService.Instance.SetCurrentUser(account);
steamService.UpdateLocalUserData(users);
steamService.SetCurrentUser(account);
}
ISteamService.Instance.TryKillSteamProcess();
ISteamService.Instance.StartSteam();
steamService.TryKillSteamProcess();
steamService.StartSteam();
}
});
rootCommand.AddCommand(steamuser);
@@ -1,6 +1,6 @@
using Avalonia;
using Avalonia.Skia;
using Avalonia.ReactiveUI;
using Avalonia.Rendering;
using System.Application.Settings;
using System.Reflection;
@@ -48,16 +48,19 @@ namespace System.Application.UI
};
builder.With(options);
builder.With(new SkiaOptions
var skiaOptions = new SkiaOptions
{
MaxGpuResourceSizeBytes = 1024000000,
});
};
builder.With(skiaOptions);
#else
throw new PlatformNotSupportedException();
#endif
RenderingSubsystemName = builder.RenderingSubsystemName;
//AvaloniaLocator.CurrentMutable.Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60));
return builder;
}
@@ -28,8 +28,8 @@ namespace System.Application.Converters
{
return GetDecodeBitmap(rawUri, width);
}
//在列表中使用此方法性能极差
else if (rawUri.StartsWith("http://") || rawUri.StartsWith("https://"))
// 在列表中使用此方法性能极差
else if (Browser2.IsHttpUrl(rawUri))
{
return DownloadImage(rawUri, width);
}
@@ -55,7 +55,7 @@ namespace System.Application.Converters
}
else if (value is Guid imageid)
{
if (Guid.Empty == imageid)
if (imageid == default)
{
return null;
}
@@ -3,23 +3,26 @@ using Avalonia.Data;
using Avalonia.Data.Converters;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using Avalonia.Skia;
using SkiaSharp;
using System.Application.Models;
using System.Application.Services;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;
using BitmapInterpolationMode = Avalonia.Visuals.Media.Imaging.BitmapInterpolationMode;
namespace System.Application.Converters
{
public abstract class ImageValueConverter : IValueConverter
{
public abstract object? Convert(object value, Type targetType, object parameter, CultureInfo culture);
public abstract object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture);
public virtual object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
public virtual object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
return BindingOperations.DoNothing;
}
@@ -47,15 +50,47 @@ namespace System.Application.Converters
}
}
protected static Bitmap? GetBitmap(ImageSouce.ClipStream clipStream, int width = 0)
/// <summary>
/// 将 图片源(流) 转换为 <see cref="SKBitmap"/>(Skia)
/// </summary>
/// <param name="clipStream"></param>
/// <param name="bitmap"></param>
/// <returns></returns>
static bool TryGetBitmap([NotNullWhen(true)] ImageSouce.ClipStream? clipStream, [NotNullWhen(true)] out SKBitmap? bitmap)
{
if (clipStream.Stream == null)
return null;
TryReset(clipStream.Stream);
using var ms = new MemoryStream();
clipStream.Stream.CopyTo(ms);
TryReset(ms);
using var bitmapSource = SKBitmap.Decode(ms);
if (clipStream?.Stream == null)
{
bitmap = null;
return false;
}
var filename = clipStream.Name;
if (filename != null)
{
bitmap = SKBitmap.Decode(filename);
}
else
{
TryReset(clipStream.Stream);
using var ms = new MemoryStream();
clipStream.Stream.CopyTo(ms);
TryReset(ms);
bitmap = SKBitmap.Decode(ms);
}
return true;
}
/// <summary>
/// 将 图片源(流) 根据预设参数处理并转换为 <see cref="Bitmap"/>(Avalonia)
/// </summary>
/// <param name="clipStream"></param>
/// <param name="width"></param>
/// <returns></returns>
protected static Bitmap? GetBitmap(ImageSouce.ClipStream? clipStream, int width = 0)
{
if (!TryGetBitmap(clipStream, out var bitmap)) return null;
using var bitmapSource = bitmap;
using var bitmapDest = new SKBitmap(bitmapSource.Width, bitmapSource.Height, SKColorType.Bgra8888, SKAlphaType.Unpremul);
using var canvas = new SKCanvas(bitmapDest);
@@ -70,20 +105,57 @@ namespace System.Application.Converters
canvas.DrawBitmap(bitmapSource, 0, 0);
var stream = bitmapDest.Encode(SKEncodedImageFormat.Png, 100).AsStream();
TryReset(stream);
#region Obsolete
//var tempFilePath = Path.Combine(IOPath.CacheDirectory, Path.GetFileName(Path.GetTempFileName() + ".png"));
//using (var fs = File.Create(tempFilePath))
//{
// stream.CopyTo(fs);
// TryReset(stream);
//}
//var stream = bitmapDest.Encode(SKEncodedImageFormat.Png, 100).AsStream();
//TryReset(stream);
return GetDecodeBitmap(stream, width);
////var tempFilePath = Path.Combine(IOPath.CacheDirectory, Path.GetFileName(Path.GetTempFileName() + ".png"));
////using (var fs = File.Create(tempFilePath))
////{
//// stream.CopyTo(fs);
//// TryReset(stream);
////}
//return GetDecodeBitmap(stream, width);
#endregion
#region New Code
return GetDecodeBitmap(bitmapDest, width);
#endregion
}
protected static Bitmap? GetDecodeBitmap(Stream s, int width)
/// <summary>
/// 将 <see cref="SKBitmap"/>(Skia) 转换为 <see cref="Bitmap"/>(Avalonia)
/// </summary>
/// <param name="s"></param>
/// <param name="width"></param>
/// <returns></returns>
[return: NotNullIfNotNull("s")]
protected static Bitmap? GetDecodeBitmap(SKBitmap? s, int width)
{
if (s == null)
{
return null;
}
if (width < 1)
{
return SkiaSharpHelpers.GetBitmap(s);
}
return SkiaSharpHelpers.DecodeToWidth(s, width, BitmapInterpolationMode.MediumQuality);
}
/// <summary>
/// 将 <see cref="Stream"/> 转换为 <see cref="Bitmap"/>(Avalonia)
/// </summary>
/// <param name="s"></param>
/// <param name="width"></param>
/// <returns></returns>
[return: NotNullIfNotNull("s")]
protected static Bitmap? GetDecodeBitmap(Stream? s, int width)
{
if (s == null)
{
@@ -93,24 +165,50 @@ namespace System.Application.Converters
{
return new Bitmap(s);
}
return Bitmap.DecodeToWidth(s, width, Avalonia.Visuals.Media.Imaging.BitmapInterpolationMode.MediumQuality);
return Bitmap.DecodeToWidth(s, width, BitmapInterpolationMode.MediumQuality);
}
protected static Bitmap? GetDecodeBitmap(string s, int width)
/// <summary>
/// 将 <see cref="string"/>(filePath) 转换为 <see cref="Bitmap"/>(Avalonia)
/// </summary>
/// <param name="s"></param>
/// <param name="width"></param>
/// <returns></returns>
[return: NotNullIfNotNull("s")]
protected static Bitmap? GetDecodeBitmap(string? s, int width)
{
if (IOPath.TryOpenRead(s, out var stream, out var ex))
return GetDecodeBitmap(stream, width);
else
#region Obsolete
//if (IOPath.TryOpenRead(s, out var stream, out var _))
// return GetDecodeBitmap(stream, width);
//else
// return null;
#endregion
#region New Code
if (s == null)
{
return null;
}
if (width < 1)
{
var image = SKImage.FromEncodedData(s);
return SkiaSharpHelpers.GetBitmap(image);
}
var bitmap = SKBitmap.Decode(s);
return SkiaSharpHelpers.DecodeToWidth(bitmap, width, BitmapInterpolationMode.MediumQuality);
#endregion
}
protected static Stream? OpenAssets(Uri uri)
{
var assets = AvaloniaLocator.Current.GetService<IAssetLoader>();
Stream? stream = null;
if (assets.Exists(uri))
stream = assets.Open(uri);
return stream;
if (assets == null) return null;
if (assets.Exists(uri)) return assets.Open(uri);
return null;
}
protected static Uri GetResUri(string relativeUri, string? assemblyName = null)
@@ -91,6 +91,7 @@
<ItemGroup>
<ProjectReference Include="..\..\references\AvaloniaGif\AvaloniaGif\AvaloniaGif.csproj" />
<ProjectReference Include="..\..\references\FluentAvalonia\FluentAvalonia\FluentAvalonia.csproj" />
<ProjectReference Include="..\Avalonia.Desktop\Avalonia.Desktop.csproj" />
<ProjectReference Include="..\Avalonia.Skia.Internals\Avalonia.Skia.Internals.csproj" />
<ProjectReference Include="..\Common.CoreLib\Common.CoreLib.csproj" />
<ProjectReference Include="..\ST.Client\ST.Client.csproj" />
@@ -377,7 +377,7 @@ namespace System.Application.Services.Implementation
}
}
public void DeleteLocalUserData(SteamUser user, bool IsDeleteUserData = false)
public void DeleteLocalUserData(SteamUser user, bool isDeleteUserData = false)
{
if (string.IsNullOrWhiteSpace(UserVdfPath) || string.IsNullOrWhiteSpace(SteamDirPath))
{
@@ -399,7 +399,7 @@ namespace System.Application.Services.Implementation
users.Remove(users[i]);
VdfHelper.Write(UserVdfPath, v);
//VdfHelper.DeleteValueByKey(UserVdfPath, user.SteamId64.ToString());
if (IsDeleteUserData)
if (isDeleteUserData)
{
var temp = Path.Combine(SteamDirPath, UserDataDirectory, user.SteamId32.ToString());
if (Directory.Exists(temp))
@@ -643,8 +643,14 @@ namespace System.Application.Services.Implementation
SteamApp.LibCacheType.Library_Grid => $"{appId}p.png",
SteamApp.LibCacheType.Library_Hero => $"{appId}_hero.png",
SteamApp.LibCacheType.Logo => $"{appId}_logo.png",
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null),
_ => null,
};
if (fileName == null)
{
return null;
}
var filePath = Path.Combine(path, fileName);
return filePath;
}
@@ -660,8 +666,14 @@ namespace System.Application.Services.Implementation
SteamApp.LibCacheType.Library_Hero => $"{appId}_library_hero.jpg",
SteamApp.LibCacheType.Library_Hero_Blur => $"{appId}_library_hero_blur.jpg",
SteamApp.LibCacheType.Logo => $"{appId}_logo.png",
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null),
_ => null,
};
if (fileName == null)
{
return null;
}
var filePath = Path.Combine(LibrarycacheDirPath, fileName);
return filePath;
}
@@ -686,7 +698,7 @@ namespace System.Application.Services.Implementation
SteamApp.LibCacheType.Library_Hero => app.LibraryHeroUrl,
SteamApp.LibCacheType.Library_Hero_Blur => app.LibraryHeroBlurUrl,
SteamApp.LibCacheType.Logo => app.LibraryLogoUrl,
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null),
_ => null,
};
if (url == null) return string.Empty;
@@ -847,6 +859,7 @@ namespace System.Application.Services.Implementation
static uint GetUInt32(dynamic value)
{
if (value is null) return 0;
if (value is VValue vvalue) return GetUInt32(vvalue.Value!);
if (value is uint value2) return value2;
if (value is IConvertible convertible)
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="20220424" android:versionName="2.7.0" package="net.steampp.app" android:installLocation="auto">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="20220427" android:versionName="2.7.1" 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.-->
+1
View File
@@ -45,6 +45,7 @@ namespace System.Application
/// 验证码图片
/// </summary>
CodeImage,
/// <summary>
/// 通知公告封面图
/// </summary>
+32 -17
View File
@@ -1,23 +1,44 @@
using System.Application.UI;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Text;
namespace System.Application
{
public static class ImageSouce
{
public sealed class ClipStream : IDisposable
public sealed class ClipStream : IDisposable, IFileStreamWrapper
{
bool disposedValue;
Stream? stream;
ClipStream(Stream stream)
{
Stream = stream;
OriginStream = this.stream = stream;
}
public Stream Stream { get; }
public Stream? Stream
{
get
{
if (stream is IFileStreamWrapper wrapper)
{
stream = wrapper.FileStream;
}
return stream;
}
}
public Stream OriginStream { get; }
/// <inheritdoc cref="FileStream.Name"/>
public string? Name
{
get
{
if (OriginStream is IFileStreamWrapper wrapper) return wrapper.Name;
else if (OriginStream is FileStream file) return file.Name;
return null;
}
}
public float Top { get; set; }
@@ -67,7 +88,8 @@ namespace System.Application
if (disposing)
{
// TODO: 释放托管状态(托管对象)
Stream.Dispose();
stream?.Dispose();
OriginStream.Dispose();
}
// TODO: 释放未托管的资源(未托管的对象)并重写终结器
@@ -88,16 +110,9 @@ namespace System.Application
public static implicit operator ClipStream?(string? filePath)
{
if (filePath == null) return null;
try
{
ClipStream? clipStream = IOPath.OpenRead(filePath);
return clipStream;
}
catch
{
return null;
}
FileStreamWrapper? wrapper = filePath;
ClipStream? clipStream = wrapper;
return clipStream;
}
}
+3 -1
View File
@@ -236,7 +236,9 @@ namespace System.Application.Models
if (propertyValue2 != null)
{
_properties.SetPropertyValue(SteamAppPropertyType.Table, propertyValue2, NodeAppInfo, "steam_edit", "base_name_localized");
_properties.RemoveProperty("name_localized");
//_properties.RemoveProperty(NodeAppInfo, NodeCommon, "name_localized");
_properties.SetPropertyValue(SteamAppPropertyType.Table, new SteamAppPropertyTable(), NodeAppInfo, NodeCommon, "name_localized");
}
_properties.SetPropertyValue(SteamAppPropertyType.String, appInfo.BaseName, NodeAppInfo, "steam_edit", "base_name");
+2 -2
View File
@@ -88,7 +88,7 @@ namespace System.Application.Services
bool UpdateAppListJson(string appsJsonStr, string filePath);
void DeleteLocalUserData(SteamUser user, bool IsDeleteUserData = false);
void DeleteLocalUserData(SteamUser user, bool isDeleteUserData = false);
void UpdateLocalUserData(IEnumerable<SteamUser> users);
@@ -98,7 +98,7 @@ namespace System.Application.Services
/// 从steam本地客户端缓存文件中读取游戏数据
/// </summary>
Task<List<SteamApp>> GetAppInfos(bool isSaveProperties = false);
List<ModifiedApp>? GetModifiedApps();
/// <summary>
@@ -20,15 +20,14 @@ namespace System.Application.Services
{
public sealed class SteamConnectService : ReactiveObject, IDisposable
{
public const int SteamAFKMaxCount = 32;
public static SteamConnectService Current { get; } = new();
readonly ISteamworksLocalApiService ApiService = ISteamworksLocalApiService.Instance;
//readonly ISteamworksWebApiService SteamworksWebApiService = ISteamworksWebApiService.Instance;
//readonly ISteamDbWebApiService steamDbApiService = ISteamDbWebApiService.Instance;
readonly ISteamworksLocalApiService swLocalService = ISteamworksLocalApiService.Instance;
readonly ISteamService stmService = ISteamService.Instance;
readonly IHttpService httpService = IHttpService.Instance;
readonly ISteamworksWebApiService webApiService = ISteamworksWebApiService.Instance;
readonly ISteamService SteamTool = ISteamService.Instance;
public const int SteamAFKMaxCount = 32;
readonly ISteamworksWebApiService swWebService = ISteamworksWebApiService.Instance;
private SteamConnectService()
{
@@ -69,7 +68,7 @@ namespace System.Application.Services
InitializeDownloadGameList();
if (OperatingSystem2.IsLinux)
IPlatformService.Instance.TryGetSystemUserPassword();
SteamTool.StartWatchSteamDownloading(app =>
stmService.StartWatchSteamDownloading(app =>
{
var optional = DownloadApps.Lookup(app.AppId);
if (!optional.HasValue)
@@ -112,7 +111,7 @@ namespace System.Application.Services
}
else
{
SteamTool.StopWatchSteamDownloading();
stmService.StopWatchSteamDownloading();
}
});
}
@@ -246,8 +245,8 @@ namespace System.Application.Services
public void Initialize()
{
if (!SteamTool.IsRunningSteamProcess && SteamSettings.IsAutoRunSteam.Value)
SteamTool.StartSteam(SteamSettings.SteamStratParameter.Value);
if (!stmService.IsRunningSteamProcess && SteamSettings.IsAutoRunSteam.Value)
stmService.StartSteam(SteamSettings.SteamStratParameter.Value);
Task.Factory.StartNew(async () =>
{
@@ -256,27 +255,29 @@ namespace System.Application.Services
{
try
{
if (SteamTool.IsRunningSteamProcess)
if (stmService.IsRunningSteamProcess)
{
if (!IsConnectToSteam && IsDisposedClient)
{
if (ApiService.Initialize())
if (swLocalService.Initialize())
{
IsDisposedClient = false;
var id = ApiService.GetSteamId64();
if (id == SteamUser.UndefinedId)
var id = swLocalService.GetSteamId64();
if (id <= 0 || id == SteamUser.UndefinedId)
{
//该64位id的steamID3等于0,是steam未获取到当前登录用户的默认返回值,所以直接重新获取
DisposeSteamClient();
continue;
}
IsConnectToSteam = true;
CurrentSteamUser = await DI.Get<ISteamworksWebApiService>().GetUserInfo(id);
CurrentSteamUser.AvatarStream = IHttpService.Instance.GetImageAsync(CurrentSteamUser.AvatarFull, ImageChannelType.SteamAvatars);
CurrentSteamUser = await swWebService.GetUserInfo(id);
CurrentSteamUser.AvatarStream = httpService.GetImageAsync(CurrentSteamUser.AvatarFull, ImageChannelType.SteamAvatars);
//AvatarPath = ImageSouce.TryParse(await CurrentSteamUser.AvatarStream, isCircle: true);
CurrentSteamUser.IPCountry = ApiService.GetIPCountry();
IsSteamChinaLauncher = ApiService.IsSteamChinaLauncher();
CurrentSteamUser.IPCountry = swLocalService.GetIPCountry();
IsSteamChinaLauncher = swLocalService.IsSteamChinaLauncher();
#region 初始化需要steam启动才能使用的功能
if (SteamSettings.IsEnableSteamLaunchNotification.Value)
@@ -292,22 +293,29 @@ namespace System.Application.Services
//仅在有游戏数据情况下加载登录用户的游戏
if (SteamApps.Items.Any())
{
var applist = ApiService.OwnsApps(await ISteamService.Instance.GetAppInfos());
var applist = swLocalService.OwnsApps(await ISteamService.Instance.GetAppInfos());
if (!applist.Any_Nullable())
{
if (!IsDisposedClient)
DisposeSteamClient();
continue;
}
LoadGames(applist);
InitializeDownloadGameList();
}
if (!SteamUsers.Lookup(id).HasValue)
{
RefreshSteamUsers();
}
//var mainViewModel = (IWindowService.Instance.MainWindow as WindowViewModel);
//await mainViewModel.SteamAppPage.Initialize();
//await mainViewModel.AccountPage.Initialize(id);
#endregion
if (!IsDisposedClient)
{
DisposeSteamClient();
}
}
}
}
@@ -328,20 +336,13 @@ namespace System.Application.Services
}
}
}, TaskCreationOptions.LongRunning).ConfigureAwait(false);
RefreshSteamUsers();
//SteamTool.WatchLocalUserDataChange(() =>
//{
// RefreshSteamUsers();
//});
}
public bool Initialize(int appid)
{
if (SteamTool.IsRunningSteamProcess)
if (stmService.IsRunningSteamProcess)
{
return IsConnectToSteam = ApiService.Initialize(appid);
return IsConnectToSteam = swLocalService.Initialize(appid);
}
return false;
}
@@ -431,7 +432,7 @@ namespace System.Application.Services
if (IsLoadingGameList == false)
{
IsLoadingGameList = true;
if (SteamTool.IsRunningSteamProcess)
if (stmService.IsRunningSteamProcess && OperatingSystem2.IsWindows)
{
await Task.Factory.StartNew(async () =>
{
@@ -439,16 +440,16 @@ namespace System.Application.Services
{
while (true)
{
if (SteamTool.IsRunningSteamProcess && IsDisposedClient)
if (stmService.IsRunningSteamProcess && IsDisposedClient)
{
if (ApiService.Initialize())
if (swLocalService.Initialize())
{
IsDisposedClient = false;
SteamApps.Clear();
var apps = await ISteamService.Instance.GetAppInfos();
if (apps.Any())
{
var temps = ApiService.OwnsApps(apps);
var temps = swLocalService.OwnsApps(apps);
LoadGames(temps);
InitializeDownloadGameList();
Toast.Show(AppResources.GameList_RefreshGamesListSucess);
@@ -468,7 +469,7 @@ namespace System.Application.Services
IsLoadingGameList = false;
DisposeSteamClient();
}
}, TaskCreationOptions.DenyChildAttach).Forget().ConfigureAwait(false);
}, TaskCreationOptions.DenyChildAttach).ConfigureAwait(false);
}
else
{
@@ -480,13 +481,13 @@ namespace System.Application.Services
public async void RefreshSteamUsers()
{
var list = SteamTool.GetRememberUserList();
var list = stmService.GetRememberUserList();
if (!list.Any_Nullable())
{
return;
}
SteamConnectService.Current.SteamUsers.AddOrUpdate(list);
SteamUsers.AddOrUpdate(list);
#region 加载备注信息和JumpList
IReadOnlyDictionary<long, string?>? accountRemarks = SteamAccountSettings.AccountRemarks.Value;
@@ -529,9 +530,9 @@ namespace System.Application.Services
#endregion
#region 通过webapi加载头像图片用户信息
foreach (var user in SteamConnectService.Current.SteamUsers.Items)
foreach (var user in SteamUsers.Items)
{
var temp = await webApiService.GetUserInfo(user.SteamId64);
var temp = await swWebService.GetUserInfo(user.SteamId64);
if (!string.IsNullOrEmpty(temp.SteamID))
{
user.SteamID = temp.SteamID;
@@ -556,7 +557,7 @@ namespace System.Application.Services
}
}
SteamConnectService.Current.SteamUsers.Refresh();
SteamUsers.Refresh();
#endregion
#region 加载动态头像头像框数据
@@ -581,8 +582,8 @@ namespace System.Application.Services
public void DisposeSteamClient()
{
ApiService.DisposeSteamClient();
IsDisposedClient = true;
swLocalService.DisposeSteamClient();
}
public void Dispose()
+2 -2
View File
@@ -25,10 +25,10 @@ namespace System.Application
HasNotifyIcon = HasMainProcessRequired;
HasGUI = level.HasFlag(DILevel.GUI);
HasServerApiClient = level.HasFlag(DILevel.ServerApiClient);
HasHttpClientFactory = level.HasFlag(DILevel.HttpClientFactory);
HasSteam = level.HasFlag(DILevel.Steam);
HasHttpClientFactory = HasSteam || level.HasFlag(DILevel.HttpClientFactory);
HasHttpProxy = level.HasFlag(DILevel.HttpProxy);
HasHosts = level.HasFlag(DILevel.Hosts);
HasSteam = level.HasFlag(DILevel.Steam);
}
static StartupOptions? mValue;
@@ -163,11 +163,16 @@ namespace System.Application.UI.ViewModels
}
});
if (IApplication.IsDesktopPlatform)
if (IApplication.IsDesktopPlatform && OperatingSystem2.IsWindows)
{
SteamConnectService.Current.Initialize();
}
if (IApplication.IsDesktopPlatform)
{
SteamConnectService.Current.RefreshSteamUsers();
}
Parallel.ForEach(TabItems, item =>
{
item.Initialize();
@@ -263,6 +263,7 @@ namespace System.Application.UI.ViewModels
public static void EditAppInfoClick(SteamApp app)
{
if (app == null) return;
IWindowManager.Instance.Show(CustomWindow.EditAppInfo, new EditAppInfoWindowViewModel(app), string.Empty, ResizeMode.CanResize);
}
@@ -71,7 +71,7 @@ namespace System.Application.UI.ViewModels
//}
var signOutItem = signOutItems.FirstOrDefault() ?? GetSignOutItem(this);
preferenceButtons.Add(signOutItem);
if (!preferenceButtons.Contains(signOutItem)) preferenceButtons.Add(signOutItem);
}
}).AddTo(this);
@@ -18,6 +18,7 @@ using System.Threading.Tasks;
using System.Windows.Input;
using static System.Application.UI.ViewModels.ThirdPartyLoginHelper;
using _ThisAssembly = System.Properties.ThisAssembly;
using BrowserLaunchMode = Xamarin.Essentials.BrowserLaunchMode;
namespace System.Application.UI.ViewModels
{
@@ -151,22 +152,38 @@ namespace System.Application.UI.ViewModels
}
}
static IDisposable? serverDisposable;
/// <summary>
/// 释放 WebSocket Server 占用资源
/// </summary>
public static void DisposeServer()
{
serverDisposable?.Dispose();
serverDisposable = null;
}
static void StartServer(IApplication app)
{
if (ws != null) return;
var ip = IPAddress.Loopback;
port = SocketHelper.GetRandomUnusedPort(ip);
ws = new($"ws://{ip}:{port}");
serverDisposable?.Dispose();
serverDisposable = Disposable.Create(() =>
{
ws?.Dispose();
ws = null;
tempAes?.Dispose();
tempAes = null;
});
if (app is IDisposableHolder dh)
{
Disposable.Create(() =>
{
ws?.Dispose();
ws = null;
tempAes?.Dispose();
tempAes = null;
}).AddTo(dh);
serverDisposable.AddTo(dh);
}
ws.Start(socket =>
{
socket.OnMessage = async message => await OnMessage(message, socket);
@@ -235,7 +252,7 @@ namespace System.Application.UI.ViewModels
//var version = csc.Settings.AppVersionStr;
var ver = _ThisAssembly.Version.Base64UrlEncode();
var url = $"{apiBaseUrl}/ExternalLoginDetection/{(int)channel}?port={port}&sKey={skey_str}&sKeyPadding={padding.OaepHashAlgorithm}&ver={ver}&isBind={isBind}&access_token_expires={access_token_expires}&access_token={access_token}";
await Browser2.OpenAsync(url);
await Browser2.OpenAsync(url, BrowserLaunchMode.External);
}
/// <summary>
@@ -52,13 +52,7 @@ namespace System.Application.UI.ViewModels
public EditAppInfoWindowViewModel(SteamApp app)
{
if (app == null)
{
this.Close();
return;
}
App = app;
_App = app;
Title = App.DisplayName;
App.RefreshEditImage();
+1 -2
View File
@@ -68,8 +68,7 @@
### 11. (云端)读取上一步上传的数据写入数据库中
- 读取 **Publish.json** 写入数据库
- 命令示例
<pre>./p wdb -v 2.0.0 -dev -dev_custom "url1;url2;url3" // 在测试环境中创建 2.0.0 版本发布数据并附加下载链接</pre>
<pre>./p wdb -v 2.0.0 -gitee "url1;url2;url3" // 在正式环境中创建 2.0.0 版本发布数据并附加码云下载链接</pre>
<pre>./p wdbw -v 2.0.0 // 在码云中发布完成后启用 Windows 版本,将从 Gitee Release 中读取更新日志与下载地址</pre>
### 12. (本地)读取 **Publish.json** 中的 SHA256 值写入 release-template.md
- 命令示例
+4 -1
View File
@@ -434,7 +434,10 @@ namespace System.Application
//#endif
var value =
(_ThisAssembly.Debuggable || !s.GetIsOfficialChannelPackage()) ?
Prefix_HTTPS + "pan.mossimo.net:8862" :
Prefix_HTTPS +
"pan.mossimo.net:8862"
/*"localhost:5001"*/
:
Prefix_HTTPS + "api.steampp.net";
s.ApiBaseUrl = value;
}