Compare commits

..
217 Commits
Author SHA1 Message Date
Aigio L a503243243 Merge pull request #980 from BeyondDimension/develop
v2.6.5 RC4
2022-02-07 11:04:36 +08:00
Aigio Liu 405352fdbf fix PreferencesPlatformServiceImpl 2022-02-07 00:04:26 +08:00
Aigio Liu 9122069317 fix Android signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdd0
optimize viewmodel
2022-02-06 23:29:53 +08:00
Aigio L 8a6ecf9a5d Merge pull request #977 from BeyondDimension/develop
v2.6.5 RC3
2022-02-06 19:10:02 +08:00
Mossimo 028769429e OriginVdfString => CurrentVdfString; 2022-02-06 17:58:11 +08:00
Mossimo 47c06f01ed fix Replace bug 2022-02-06 17:50:50 +08:00
Aigio Liu 0437294392 v2.6.5 2022-02-06 16:24:49 +08:00
Aigio L a26f58af4a Merge pull request #976 from BeyondDimension/develop
v2.6.5 RC2
2022-02-06 16:09:18 +08:00
Aigio Liu 8a2568ed82 Update ASF-UI V5.2.2.4 2022-02-06 16:08:03 +08:00
Aigio L 5b023f10a9 Merge pull request #975 from BeyondDimension/develop
v2.6.5 RC2
2022-02-06 15:47:28 +08:00
Aigio Liu 26e69e2ea5 fix 2022-02-06 15:34:29 +08:00
Aigio L 4f733a0486 Merge pull request #974 from BeyondDimension/develop
v2.6.5
2022-02-06 14:28:21 +08:00
Aigio Liu c0bab2e4db Resx Translate 2022-02-06 14:25:39 +08:00
Aigio Liu bd3dac8203 Update ArchiSteamFarm V5.2.2.4 2022-02-06 14:22:27 +08:00
Aigio Liu e47f615b70 Misc 2022-02-06 13:24:42 +08:00
Mossimo fc921f0442 fix SteamAccountChange BUG 2022-02-06 13:14:18 +08:00
Mossimo f0d1d1452c Fix Steam Bate Account Change 2022-02-06 12:55:23 +08:00
Aigio Liu f81aa40719 fix Android UserBasicInfoFragment AreaSelect & AndroidX Package Version 2022-02-05 16:47:08 +08:00
Aigio Liu 7da4381c32 fix Android UserBasicInfoFragment BirthDate 2022-02-05 12:24:21 +08:00
Aigio L d93ed5bc49 Merge pull request #969 from BeyondDimension/dependabot/nuget/HtmlAgilityPack-1.11.41
Bump HtmlAgilityPack from 1.11.40 to 1.11.41
2022-02-04 13:12:34 +08:00
dependabot[bot] eb96db599c Bump HtmlAgilityPack from 1.11.40 to 1.11.41
Bumps [HtmlAgilityPack](https://github.com/zzzprojects/html-agility-pack) from 1.11.40 to 1.11.41.
- [Release notes](https://github.com/zzzprojects/html-agility-pack/releases)
- [Commits](https://github.com/zzzprojects/html-agility-pack/compare/v1.11.40...v1.11.41)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-03 23:24:59 +00:00
Aigio L 7e5544fcb7 Merge pull request #966 from BeyondDimension/dependabot/nuget/Microsoft.Windows.SDK.BuildTools-10.0.22000.197
Bump Microsoft.Windows.SDK.BuildTools from 10.0.22000.196 to 10.0.22000.197
2022-02-03 09:34:04 +08:00
dependabot[bot] 4a0ec3b56e Bump Microsoft.Windows.SDK.BuildTools
Bumps Microsoft.Windows.SDK.BuildTools from 10.0.22000.196 to 10.0.22000.197.

---
updated-dependencies:
- dependency-name: Microsoft.Windows.SDK.BuildTools
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-02 23:25:38 +00:00
Aigio L 4dde59b9ee Merge pull request #959 from BeyondDimension/dependabot/nuget/Xamarin.AndroidX.Camera.Camera2-1.0.2.2
Bump Xamarin.AndroidX.Camera.Camera2 from 1.0.2 to 1.0.2.2
2022-02-02 11:29:50 +08:00
Aigio L d45740dd01 Merge branch 'develop' into dependabot/nuget/Xamarin.AndroidX.Camera.Camera2-1.0.2.2 2022-02-02 11:29:45 +08:00
Aigio L fbbafdc099 Merge pull request #960 from BeyondDimension/dependabot/nuget/Xamarin.AndroidX.ConstraintLayout-2.1.2.1
Bump Xamarin.AndroidX.ConstraintLayout from 2.1.1.2 to 2.1.2.1
2022-02-02 11:29:18 +08:00
Aigio L d2fce502dd Merge pull request #961 from BeyondDimension/dependabot/nuget/Xamarin.AndroidX.Camera.Lifecycle-1.0.2.2
Bump Xamarin.AndroidX.Camera.Lifecycle from 1.0.2 to 1.0.2.2
2022-02-02 11:29:12 +08:00
Aigio L 001141d86b Merge pull request #962 from BeyondDimension/dependabot/nuget/Xamarin.AndroidX.Activity-1.3.1.3
Bump Xamarin.AndroidX.Activity from 1.3.1.2 to 1.3.1.3
2022-02-02 11:29:05 +08:00
Aigio L 58c9ae051b Merge pull request #950 from BeyondDimension/dependabot/nuget/OperatingSystem2-1.4.3
Bump OperatingSystem2 from 1.4.2.1 to 1.4.3
2022-02-02 11:27:16 +08:00
Aigio L a5c22f665d Merge pull request #951 from BeyondDimension/dependabot/nuget/DnsClient-1.6.0
Bump DnsClient from 1.5.0 to 1.6.0
2022-02-02 11:26:32 +08:00
Aigio L 8f0e5e714e Merge pull request #958 from BeyondDimension/dependabot/nuget/source/SteamTool.Core/SharpZipLib-1.3.3
Bump SharpZipLib from 1.3.1 to 1.3.3 in /source/SteamTool.Core
2022-02-02 11:26:17 +08:00
Aigio L 5a03e0fee6 Merge pull request #963 from BeyondDimension/dependabot/nuget/DynamicData-7.4.11
Bump DynamicData from 7.4.9 to 7.4.11
2022-02-02 11:25:48 +08:00
Aigio L c7007566b5 Merge pull request #964 from BeyondDimension/dependabot/nuget/Z.EntityFramework.Plus.EFCore-6.13.8
Bump Z.EntityFramework.Plus.EFCore from 6.13.7 to 6.13.8
2022-02-02 11:25:35 +08:00
dependabot[bot] d4381409df Bump Z.EntityFramework.Plus.EFCore from 6.13.7 to 6.13.8
Bumps [Z.EntityFramework.Plus.EFCore](https://github.com/zzzprojects/EntityFramework-Plus) from 6.13.7 to 6.13.8.
- [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>
2022-02-01 23:22:51 +00:00
dependabot[bot] 70f5a30e53 Bump DynamicData from 7.4.9 to 7.4.11
Bumps [DynamicData](https://github.com/reactiveui/DynamicData) from 7.4.9 to 7.4.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.4.9...7.4.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-01 23:22:33 +00:00
dependabot[bot] cff0f3578a Bump Xamarin.AndroidX.Activity from 1.3.1.2 to 1.3.1.3
Bumps [Xamarin.AndroidX.Activity](https://github.com/xamarin/AndroidX) from 1.3.1.2 to 1.3.1.3.
- [Release notes](https://github.com/xamarin/AndroidX/releases)
- [Commits](https://github.com/xamarin/AndroidX/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-01 23:22:08 +00:00
dependabot[bot] e5fd44b218 Bump Xamarin.AndroidX.Camera.Lifecycle from 1.0.2 to 1.0.2.2
Bumps [Xamarin.AndroidX.Camera.Lifecycle](https://github.com/xamarin/AndroidX) from 1.0.2 to 1.0.2.2.
- [Release notes](https://github.com/xamarin/AndroidX/releases)
- [Commits](https://github.com/xamarin/AndroidX/commits)

---
updated-dependencies:
- dependency-name: Xamarin.AndroidX.Camera.Lifecycle
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-01 23:22:05 +00:00
dependabot[bot] 999e1323d8 Bump Xamarin.AndroidX.ConstraintLayout from 2.1.1.2 to 2.1.2.1
Bumps [Xamarin.AndroidX.ConstraintLayout](https://github.com/xamarin/AndroidX) from 2.1.1.2 to 2.1.2.1.
- [Release notes](https://github.com/xamarin/AndroidX/releases)
- [Commits](https://github.com/xamarin/AndroidX/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-01 23:21:52 +00:00
dependabot[bot] f8b8548185 Bump Xamarin.AndroidX.Camera.Camera2 from 1.0.2 to 1.0.2.2
Bumps [Xamarin.AndroidX.Camera.Camera2](https://github.com/xamarin/AndroidX) from 1.0.2 to 1.0.2.2.
- [Release notes](https://github.com/xamarin/AndroidX/releases)
- [Commits](https://github.com/xamarin/AndroidX/commits)

---
updated-dependencies:
- dependency-name: Xamarin.AndroidX.Camera.Camera2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-01 23:20:59 +00:00
dependabot[bot] f299b03a34 Bump SharpZipLib from 1.3.1 to 1.3.3 in /source/SteamTool.Core
Bumps [SharpZipLib](https://github.com/icsharpcode/SharpZipLib) from 1.3.1 to 1.3.3.
- [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.3.1...v1.3.3)

---
updated-dependencies:
- dependency-name: SharpZipLib
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-01 16:24:27 +00:00
dependabot[bot] 942d6d5fd5 Bump DnsClient from 1.5.0 to 1.6.0
Bumps [DnsClient](https://github.com/MichaCo/DnsClient.NET) from 1.5.0 to 1.6.0.
- [Release notes](https://github.com/MichaCo/DnsClient.NET/releases)
- [Commits](https://github.com/MichaCo/DnsClient.NET/compare/1.5.0...1.6.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-30 23:21:58 +00:00
dependabot[bot] 5bd1076083 Bump OperatingSystem2 from 1.4.2.1 to 1.4.3
Bumps [OperatingSystem2](https://github.com/BeyondDimension/OperatingSystem2) from 1.4.2.1 to 1.4.3.
- [Release notes](https://github.com/BeyondDimension/OperatingSystem2/releases)
- [Commits](https://github.com/BeyondDimension/OperatingSystem2/compare/1.4.2.1...1.4.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-30 23:21:38 +00:00
Aigio Liu 4b358993be Support ImportGlobalFiles & Android ArchiSteamFarmForegroundService & ExplorerPageViewModel EditMode & fix Tar DirectorySeparatorChar 2022-01-28 17:01:10 +08:00
Aigio L 586c14b961 Merge pull request #946 from BeyondDimension/dependabot/nuget/Avalonia.Xaml.Behaviors-0.10.12
Bump Avalonia.Xaml.Behaviors from 0.10.11.5 to 0.10.12
2022-01-28 10:58:42 +08:00
dependabot[bot] 1453ae4368 Bump Avalonia.Xaml.Behaviors from 0.10.11.5 to 0.10.12
Bumps [Avalonia.Xaml.Behaviors](https://github.com/wieslawsoltes/AvaloniaBehaviors) from 0.10.11.5 to 0.10.12.
- [Release notes](https://github.com/wieslawsoltes/AvaloniaBehaviors/releases)
- [Commits](https://github.com/wieslawsoltes/AvaloniaBehaviors/compare/0.10.11.5...0.10.12)

---
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>
2022-01-27 23:35:43 +00:00
Aigio Liu 177abb2dda Update Packages Avalonia v0.10.12 2022-01-27 12:14:33 +08:00
Aigio L 536b1d9ade Merge pull request #938 from BeyondDimension/dependabot/nuget/TextCopy-6.1.0
Bump TextCopy from 6.0.0 to 6.1.0
2022-01-27 12:05:14 +08:00
Aigio L 5db27f73bf Merge pull request #945 from CMBill/patch-1
Update download-guide.md
2022-01-27 12:03:43 +08:00
CallMeBill 011e1bcab5 Update download-guide.md 2022-01-27 10:17:22 +08:00
dependabot[bot] 03adbc3094 Bump TextCopy from 6.0.0 to 6.1.0
Bumps [TextCopy](https://github.com/CopyText/TextCopy) from 6.0.0 to 6.1.0.
- [Release notes](https://github.com/CopyText/TextCopy/releases)
- [Commits](https://github.com/CopyText/TextCopy/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-26 23:20:01 +00:00
Aigio Liu adf1bf0d97 Android 本地加速改为 前台服务 & 修复 PendingIntent 在 Android 12+ 上的异常 & 主活动增加参数打开对应的子页 2022-01-26 19:24:10 +08:00
Aigio L 25851f7070 Merge pull request #928 from BeyondDimension/dependabot/nuget/AspNet.Security.OAuth.Apple-6.0.3
Bump AspNet.Security.OAuth.Apple from 6.0.2 to 6.0.3
2022-01-26 11:12:05 +08:00
Aigio L 0da4c530ea Merge branch 'develop' into dependabot/nuget/AspNet.Security.OAuth.Apple-6.0.3 2022-01-26 11:12:00 +08:00
Aigio L abb476e508 Merge pull request #927 from BeyondDimension/dependabot/nuget/AspNet.Security.OAuth.QQ-6.0.3
Bump AspNet.Security.OAuth.QQ from 6.0.2 to 6.0.3
2022-01-26 11:11:32 +08:00
Aigio L b55d7bcbb5 Merge pull request #904 from BeyondDimension/dependabot/nuget/Z.EntityFramework.Plus.EFCore-6.13.7
Bump Z.EntityFramework.Plus.EFCore from 6.13.6 to 6.13.7
2022-01-26 11:11:22 +08:00
Aigio L cb556f4f38 Merge pull request #901 from BeyondDimension/dependabot/nuget/HtmlAgilityPack-1.11.40
Bump HtmlAgilityPack from 1.11.39 to 1.11.40
2022-01-26 11:11:11 +08:00
Aigio L 1d7181e79d Merge pull request #900 from BeyondDimension/dependabot/nuget/Polly-7.2.3
Bump Polly from 7.2.2 to 7.2.3
2022-01-26 11:11:03 +08:00
Aigio L 91de79c6ec Merge pull request #932 from BeyondDimension/dependabot/nuget/NUnit3TestAdapter-4.2.1
Bump NUnit3TestAdapter from 4.2.0 to 4.2.1
2022-01-26 11:10:49 +08:00
Aigio L fb173ae725 Merge pull request #936 from BeyondDimension/dependabot/nuget/TextCopy-6.0.0
Bump TextCopy from 5.0.0 to 6.0.0
2022-01-26 11:10:39 +08:00
Aigio L 5fad2ffead Merge pull request #933 from BeyondDimension/dependabot/nuget/TaskScheduler-2.10.0
Bump TaskScheduler from 2.9.3 to 2.10.0
2022-01-26 11:10:29 +08:00
Aigio L 8adf02e181 Merge pull request #934 from BeyondDimension/dependabot/nuget/JustArchiNET.Madness-3.2.1
Bump JustArchiNET.Madness from 3.1.1 to 3.2.1
2022-01-26 11:10:11 +08:00
Aigio L decaae56d4 Merge pull request #935 from BeyondDimension/dependabot/nuget/Xamarin.Essentials-1.7.1
Bump Xamarin.Essentials from 1.7.0 to 1.7.1
2022-01-26 11:09:59 +08:00
dependabot[bot] 49b22d2aaf Bump TextCopy from 5.0.0 to 6.0.0
Bumps [TextCopy](https://github.com/CopyText/TextCopy) from 5.0.0 to 6.0.0.
- [Release notes](https://github.com/CopyText/TextCopy/releases)
- [Commits](https://github.com/CopyText/TextCopy/commits)

---
updated-dependencies:
- dependency-name: TextCopy
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-25 23:26:12 +00:00
dependabot[bot] 450e63158c Bump Xamarin.Essentials from 1.7.0 to 1.7.1
Bumps [Xamarin.Essentials](https://github.com/xamarin/Essentials) from 1.7.0 to 1.7.1.
- [Release notes](https://github.com/xamarin/Essentials/releases)
- [Commits](https://github.com/xamarin/Essentials/compare/1.7.0...1.7.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-25 23:25:27 +00:00
dependabot[bot] 6e073df974 Bump JustArchiNET.Madness from 3.1.1 to 3.2.1
Bumps [JustArchiNET.Madness](https://github.com/JustArchiNET/Madness) from 3.1.1 to 3.2.1.
- [Release notes](https://github.com/JustArchiNET/Madness/releases)
- [Commits](https://github.com/JustArchiNET/Madness/compare/3.1.1...3.2.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-24 23:36:31 +00:00
dependabot[bot] 24026c62d7 Bump TaskScheduler from 2.9.3 to 2.10.0
Bumps [TaskScheduler](https://github.com/dahall/taskscheduler) from 2.9.3 to 2.10.0.
- [Release notes](https://github.com/dahall/taskscheduler/releases)
- [Commits](https://github.com/dahall/taskscheduler/compare/v2.9.3...v2.10.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-24 23:25:54 +00:00
dependabot[bot] 02d88955c8 Bump NUnit3TestAdapter from 4.2.0 to 4.2.1
Bumps [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter) from 4.2.0 to 4.2.1.
- [Release notes](https://github.com/nunit/nunit3-vs-adapter/releases)
- [Commits](https://github.com/nunit/nunit3-vs-adapter/compare/V4.2.0...V4.2.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-24 23:23:37 +00:00
dependabot[bot] 6df9610463 Bump AspNet.Security.OAuth.Apple from 6.0.2 to 6.0.3
Bumps [AspNet.Security.OAuth.Apple](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers) from 6.0.2 to 6.0.3.
- [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.2...6.0.3)

---
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>
2022-01-23 23:21:20 +00:00
dependabot[bot] a8e6896c3d Bump AspNet.Security.OAuth.QQ from 6.0.2 to 6.0.3
Bumps [AspNet.Security.OAuth.QQ](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers) from 6.0.2 to 6.0.3.
- [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.2...6.0.3)

---
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>
2022-01-23 23:18:36 +00:00
Aigio Liu 435ab6e034 Fixed DebSection #909 & Android ASF Console ScrollToEnd 2022-01-20 21:04:32 +08:00
dependabot[bot] b17c094e76 Bump Z.EntityFramework.Plus.EFCore from 6.13.6 to 6.13.7
Bumps [Z.EntityFramework.Plus.EFCore](https://github.com/zzzprojects/EntityFramework-Plus) from 6.13.6 to 6.13.7.
- [Release notes](https://github.com/zzzprojects/EntityFramework-Plus/releases)
- [Commits](https://github.com/zzzprojects/EntityFramework-Plus/compare/6.13.6...6.13.7)

---
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>
2022-01-18 23:22:39 +00:00
Aigio Liu 316a522721 Android UserProfileActivity 2022-01-18 19:32:25 +08:00
dependabot[bot] 18bf3e5809 Bump HtmlAgilityPack from 1.11.39 to 1.11.40
Bumps [HtmlAgilityPack](https://github.com/zzzprojects/html-agility-pack) from 1.11.39 to 1.11.40.
- [Release notes](https://github.com/zzzprojects/html-agility-pack/releases)
- [Commits](https://github.com/zzzprojects/html-agility-pack/compare/v1.11.39...v1.11.40)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-17 23:22:52 +00:00
dependabot[bot] 7e8e366f66 Bump Polly from 7.2.2 to 7.2.3
Bumps [Polly](https://github.com/App-vNext/Polly) from 7.2.2 to 7.2.3.
- [Release notes](https://github.com/App-vNext/Polly/releases)
- [Changelog](https://github.com/App-vNext/Polly/blob/master/CHANGELOG.md)
- [Commits](https://github.com/App-vNext/Polly/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-17 23:22:21 +00:00
Aigio Liu 97693cf9d9 Update Microsoft.AppCenter v4.5.0 2022-01-14 22:43:13 +08:00
Aigio Liu 58cf7dc69d Misc 2022-01-14 20:17:06 +08:00
Aigio Liu a9fb87bb79 fix Android IsChangeSupportProxyServicesStatus 2022-01-14 20:16:21 +08:00
Aigio Liu 3994049c24 Android 本地加速 二级菜单展开与折叠与勾选 2022-01-14 20:02:06 +08:00
Aigio Liu f0cca6ee6d 新增 重置 Hosts 文件 & 打开 Hosts 所在文件夹
Toast LogAndShowT 替代同时写日志与 Toast 提示的场景
减少 GetAllMessage 文本量
fix MessageBox Wrap
2022-01-14 16:55:25 +08:00
RMBGAME e008fe542c Window Style Fix 2022-01-14 04:51:45 +08:00
Aigio Liu ef1971a907 fix 889
Android 网络加速,二级列表 UI XML
2022-01-13 22:01:27 +08:00
Aigio L bb17cdeec3 fix #890 2022-01-13 17:43:57 +08:00
Aigio Liu 760e05aa10 fix Microsoft.Data.SqlClient.SqlException (0x80131904): 不能将值 NULL 插入列 'NickName',列不允许有 Null 值。INSERT 失败。 2022-01-12 20:01:49 +08:00
Aigio Liu 2a94e4a110 Update Publish Tool 2022-01-12 11:01:13 +08:00
Aigio L 16ef05173d Merge pull request #879 from BeyondDimension/dependabot/nuget/Z.EntityFramework.Plus.EFCore-6.13.6
Bump Z.EntityFramework.Plus.EFCore from 6.13.5 to 6.13.6
2022-01-12 10:27:28 +08:00
dependabot[bot] 645636c4ca Bump Z.EntityFramework.Plus.EFCore from 6.13.5 to 6.13.6
Bumps [Z.EntityFramework.Plus.EFCore](https://github.com/zzzprojects/EntityFramework-Plus) from 6.13.5 to 6.13.6.
- [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>
2022-01-11 23:19:17 +00:00
Aigio Liu 0d9d86c04a Misc 2022-01-11 20:40:08 +08:00
Aigio Liu c0818da7db Misc 2022-01-11 20:02:51 +08:00
Aigio Liu 89862e94af fix AutoMapper 11 compatible 2022-01-11 19:41:46 +08:00
Aigio Liu ca1f997e7d Update Microsoft.AspNetCore.Mvc.Core 2.2.5 & fix AndroidDeviceInfoPlatformServiceImpl & Android TFM 12 & targetSdkVersion 31 & Process2.OpenCoreByProcess 2022-01-11 17:57:09 +08:00
Aigio Liu 185e8b0fe9 Update ASF v5.2.1.5-library
Microsoft.Extensions.* & AspNetCore & EntityFrameworkCore v3.1.22
Add ShortGuid & OSNames & AndroidDeviceInfoPlatformServiceImpl
2022-01-11 15:57:23 +08:00
Aigio Liu ab1ca7dd03 Remove Obsolete 2022-01-07 20:06:36 +08:00
Aigio Liu 3516fbd463 Misc 2022-01-07 20:04:07 +08:00
Aigio Liu c5dbac3c8e 改进 JumpListServiceImpl 在 >= Windows10.0.10586 上使用 UWP API 2022-01-07 20:00:50 +08:00
Aigio Liu bc665d1313 改进 JumpListServiceImpl 2022-01-07 19:31:01 +08:00
Aigio Liu e5b4c73d15 VersionController.CheckUpdate3,取消参数 isRunningAsUwp 2022-01-07 18:28:38 +08:00
Aigio L 0c77f07b05 Update milestone.md 2022-01-07 17:28:32 +08:00
Aigio L eef2b826d1 Merge pull request #870 from BeyondDimension/dependabot/nuget/TextCopy-5.0.0
Bump TextCopy from 4.3.1 to 5.0.0
2022-01-07 17:25:20 +08:00
Aigio Liu 05a4b2bfbf TEMPLATE Milestone 2022-01-07 17:23:42 +08:00
dependabot[bot] 2f1ab0dfc9 Bump TextCopy from 4.3.1 to 5.0.0
Bumps [TextCopy](https://github.com/CopyText/TextCopy) from 4.3.1 to 5.0.0.
- [Release notes](https://github.com/CopyText/TextCopy/releases)
- [Commits](https://github.com/CopyText/TextCopy/compare/4.3.1...5.0.0)

---
updated-dependencies:
- dependency-name: TextCopy
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-07 09:23:37 +00:00
Aigio Liu 9746e11163 Misc 2022-01-07 17:20:54 +08:00
Aigio L 0b5e2cbd0c Update issue templates 2022-01-07 17:11:12 +08:00
Aigio L c4b104be38 Merge pull request #863 from BeyondDimension/dependabot/nuget/AutoMapper.Extensions.Microsoft.DependencyInjection-11.0.0
Bump AutoMapper.Extensions.Microsoft.DependencyInjection from 8.1.1 to 11.0.0
2022-01-07 10:55:29 +08:00
Aigio L 28a46972ed Merge branch 'develop' into dependabot/nuget/AutoMapper.Extensions.Microsoft.DependencyInjection-11.0.0 2022-01-07 10:55:24 +08:00
Aigio L d0f5e77f28 Merge pull request #865 from BeyondDimension/dependabot/nuget/AutoMapper.Extensions.ExpressionMapping-5.0.0
Bump AutoMapper.Extensions.ExpressionMapping from 4.1.3 to 5.0.0
2022-01-07 10:54:59 +08:00
Aigio L dad478ad5f Merge pull request #864 from BeyondDimension/dependabot/nuget/AutoMapper-11.0.0
Bump AutoMapper from 10.1.1 to 11.0.0
2022-01-07 10:54:50 +08:00
Aigio L cee29aeabe Merge pull request #868 from BeyondDimension/dependabot/nuget/AspNet.Security.OAuth.Apple-6.0.2
Bump AspNet.Security.OAuth.Apple from 6.0.1 to 6.0.2
2022-01-07 10:54:39 +08:00
Aigio L eb4f9924a8 Merge branch 'develop' into dependabot/nuget/AspNet.Security.OAuth.Apple-6.0.2 2022-01-07 10:54:29 +08:00
Aigio L 1911141d2a Merge pull request #869 from BeyondDimension/dependabot/nuget/AspNet.Security.OAuth.QQ-6.0.2
Bump AspNet.Security.OAuth.QQ from 6.0.1 to 6.0.2
2022-01-07 10:53:53 +08:00
dependabot[bot] 82dd22467a Bump AspNet.Security.OAuth.QQ from 6.0.1 to 6.0.2
Bumps [AspNet.Security.OAuth.QQ](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers) from 6.0.1 to 6.0.2.
- [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.1...6.0.2)

---
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>
2022-01-06 23:33:27 +00:00
dependabot[bot] 54feb7ba60 Bump AspNet.Security.OAuth.Apple from 6.0.1 to 6.0.2
Bumps [AspNet.Security.OAuth.Apple](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers) from 6.0.1 to 6.0.2.
- [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.1...6.0.2)

---
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>
2022-01-06 23:21:57 +00:00
Aigio Liu e424352f93 改进 Android 取消针对每个选择的 ABI 生成一个包,使用包含全部 ABI 的单个包 2022-01-06 15:23:58 +08:00
dependabot[bot] 81dfd5dce3 Bump AutoMapper.Extensions.ExpressionMapping from 4.1.3 to 5.0.0
Bumps [AutoMapper.Extensions.ExpressionMapping](https://github.com/AutoMapper/AutoMapper.Extensions.ExpressionMapping) from 4.1.3 to 5.0.0.
- [Release notes](https://github.com/AutoMapper/AutoMapper.Extensions.ExpressionMapping/releases)
- [Commits](https://github.com/AutoMapper/AutoMapper.Extensions.ExpressionMapping/compare/v4.1.3...v5.0.0)

---
updated-dependencies:
- dependency-name: AutoMapper.Extensions.ExpressionMapping
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-05 23:20:07 +00:00
dependabot[bot] 8cc303ac16 Bump AutoMapper from 10.1.1 to 11.0.0
Bumps [AutoMapper](https://github.com/AutoMapper/AutoMapper) from 10.1.1 to 11.0.0.
- [Release notes](https://github.com/AutoMapper/AutoMapper/releases)
- [Changelog](https://github.com/AutoMapper/AutoMapper/blob/master/docs/API-Changes.md)
- [Commits](https://github.com/AutoMapper/AutoMapper/compare/v10.1.1...v11.0.0)

---
updated-dependencies:
- dependency-name: AutoMapper
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-05 23:19:47 +00:00
dependabot[bot] e7da3e509f Bump AutoMapper.Extensions.Microsoft.DependencyInjection
Bumps [AutoMapper.Extensions.Microsoft.DependencyInjection](https://github.com/AutoMapper/AutoMapper.Extensions.Microsoft.DependencyInjection) from 8.1.1 to 11.0.0.
- [Release notes](https://github.com/AutoMapper/AutoMapper.Extensions.Microsoft.DependencyInjection/releases)
- [Commits](https://github.com/AutoMapper/AutoMapper.Extensions.Microsoft.DependencyInjection/compare/v8.1.1...v11.0.0)

---
updated-dependencies:
- dependency-name: AutoMapper.Extensions.Microsoft.DependencyInjection
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-05 23:19:23 +00:00
Aigio Liu dfafc52011 Misc 2022-01-05 23:55:06 +08:00
Aigio Liu 03bf521b51 feature #271 #861
Windows 安装版将
AppData 目录移至 %LocalAppData%\Steam++
Cache 目录移至 %Tmp%\Steam++
读取 32 位注册表 LocalMachine\SOFTWARE\Steam++\InstPath 比对路径判断是否为安装版
日志文件夹全部移动到 Cache 目录中
2022-01-05 23:28:51 +08:00
Aigio Liu 510d45709d fix PlatformNotSupportedException 2022-01-05 21:22:55 +08:00
Aigio L f58fcd40dd Create download-guide.md 2022-01-05 18:22:24 +08:00
Aigio L e638a26cb8 Update download-guide.md 2022-01-05 18:22:19 +08:00
Aigio L 9d6bc2ebc8 Update download-guide.md 2022-01-05 18:21:48 +08:00
Aigio L bf762ab952 Update download-guide.md 2022-01-05 18:19:57 +08:00
Aigio Liu 84bbb0d5c8 fix UriFormatException 2022-01-05 17:36:01 +08:00
Aigio Liu 32b241299a fix Android Proxy 2022-01-05 17:05:12 +08:00
Aigio L 6562d28336 Merge pull request #858 from BeyondDimension/develop
Add macOS ARM64 pubxml
2022-01-05 14:59:20 +08:00
Aigio Liu 7c26e1fbc6 Add macOS ARM64 pubxml 2022-01-05 14:57:13 +08:00
Aigio L f15dc904ff Merge pull request #857 from BeyondDimension/develop
v2.6.4
2022-01-05 14:15:16 +08:00
Aigio Liu a6102b92d2 Update macOS ARM64 for Publish Tool 2022-01-05 14:12:03 +08:00
Aigio Liu fdf0e43ce6 v2.6.4 2022-01-05 14:08:59 +08:00
Aigio L 8f64b542a6 Update dotnet.yml 2022-01-05 11:40:39 +08:00
Aigio Liu 5fcab98d4d Update ReactiveUI Packages 2022-01-05 00:19:50 +08:00
Aigio Liu c8bf9b39f4 fix macOS Publish & SetAsSystemProxy 2022-01-05 00:07:30 +08:00
Aigio Liu fcaad74bb9 fix publish.yml 2022-01-04 22:46:37 +08:00
Aigio Liu 8361481d5c Add macOS ARM64 2022-01-04 22:42:08 +08:00
Aigio Liu db6bf1d673 Misc 2022-01-04 22:29:19 +08:00
Aigio Liu cbb7330bda change HttpClient AppVersion hedaer, now use referrer 2022-01-04 20:51:26 +08:00
RMBGAME 079469b89e 改进令牌登录导入步骤提示 2022-01-04 18:24:37 +08:00
RMBGAME 7f45ca966e Misc 2022-01-04 17:49:19 +08:00
RMBGAME a26b9689ee 改进steam用户信息和头像的获取方式 2022-01-04 17:19:35 +08:00
Aigio Liu 53bca3f027 Disable api/forward & Android VPN Settings 2022-01-04 16:52:01 +08:00
Aigio Liu 0cc5c28c85 feature #844 for Android 2022-01-01 11:26:30 +08:00
RMBGAME 32bdab41a7 修复令牌更改时托盘菜单没有实时变化
令牌交易确认标题添加令牌名称展示
2021-12-31 15:45:06 +08:00
Aigio L 6bdfb0b9e0 Merge pull request #845 from BeyondDimension/dependabot/nuget/Z.EntityFramework.Plus.EFCore-6.13.5
Bump Z.EntityFramework.Plus.EFCore from 6.13.4 to 6.13.5
2021-12-31 10:55:11 +08:00
dependabot[bot] 8558ec864f Bump Z.EntityFramework.Plus.EFCore from 6.13.4 to 6.13.5
Bumps [Z.EntityFramework.Plus.EFCore](https://github.com/zzzprojects/EntityFramework-Plus) from 6.13.4 to 6.13.5.
- [Release notes](https://github.com/zzzprojects/EntityFramework-Plus/releases)
- [Commits](https://github.com/zzzprojects/EntityFramework-Plus/compare/6.13.4...6.13.5)

---
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>
2021-12-30 23:23:43 +00:00
Aigio Liu 99745d8c77 改进 字体管理 2021-12-30 20:56:23 +08:00
Aigio Liu e20f96753b 7-Zip Update 21.07 (2021-12-26) for Windows 2021-12-30 13:00:55 +08:00
Aigio Liu 4cc738ca38 fix JNI 2021-12-29 23:08:31 +08:00
RMBGAME 83433aea70 fix dns resolve error 2021-12-29 16:17:36 +08:00
Aigio Liu d97ab12427 Android Tun2HttpVpnService 2021-12-28 22:06:11 +08:00
Aigio L 8bb3526e27 Merge pull request #841 from BeyondDimension/dependabot/nuget/NUnit3TestAdapter-4.2.0
Bump NUnit3TestAdapter from 4.1.0 to 4.2.0
2021-12-28 10:55:46 +08:00
dependabot[bot] 6894ad27e2 Bump NUnit3TestAdapter from 4.1.0 to 4.2.0
Bumps [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/nunit/nunit3-vs-adapter/releases)
- [Commits](https://github.com/nunit/nunit3-vs-adapter/compare/V4.1.0...V4.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-27 23:21:21 +00:00
Aigio Liu 053259bdaf fix Android Proxy 2021-12-27 19:59:36 +08:00
Aigio L 62d6f66344 Merge pull request #835 from BeyondDimension/dependabot/nuget/Splat-14.1.17
Bump Splat from 14.1.1 to 14.1.17
2021-12-27 11:15:57 +08:00
Aigio Liu 1d4b18da88 Android CommunityFix 2021-12-27 11:14:23 +08:00
Aigio Liu 90dc90329d Android ProxySettingsActivity 2021-12-25 16:51:11 +08:00
RMBGAME 76bf2eb80d Fix Window Style Error 2021-12-24 13:20:11 +08:00
RMBGAME 73b60d428d Update Avalonia 0.10.11 & FluentAvalonia 1.1.8 2021-12-24 13:20:03 +08:00
Aigio Liu 695657cbbc Android FilePicker2.SaveAsync Impl & CommunityFixFragment OptionsMenu 2021-12-24 01:28:52 +08:00
Mossimo aa20d3d19c 修复 编辑并刷新脚本导致含GM排序问题 2021-12-23 18:27:54 +08:00
dependabot[bot] c9b0fdbe88 Bump Splat from 14.1.1 to 14.1.17
Bumps [Splat](https://github.com/reactiveui/splat) from 14.1.1 to 14.1.17.
- [Release notes](https://github.com/reactiveui/splat/releases)
- [Commits](https://github.com/reactiveui/splat/compare/14.1.1...14.1.17)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-22 23:32:10 +00:00
Aigio L 35498b2751 Update sync-gitee.yml 2021-12-22 19:05:14 +08:00
Aigio L f894f0f58b Update sync-gitee.yml 2021-12-22 19:04:53 +08:00
Aigio Liu 6c08f51e9f Android CommunityFixVpnService Impl 2021-12-22 14:24:15 +08:00
Aigio Liu 12e46bd5a0 improvement AvaloniaFontManagerImpl & NameToFontFamilyConverter 2021-12-20 17:13:48 +08:00
Aigio Liu 8e98313634 fix AvaloniaFontManager & add archlinux package 2021-12-20 14:36:43 +08:00
Aigio Liu b947d6cdd5 fix HttpProxy for Android
fix https://github.com/BeyondDimension/SteamTools/issues/821
2021-12-20 13:36:42 +08:00
Aigio L e8e64c1c74 Merge pull request #823 from BeyondDimension/dependabot/nuget/DynamicData-7.4.9
Bump DynamicData from 7.4.3 to 7.4.9
2021-12-20 10:46:20 +08:00
dependabot[bot] 44b24406cf Bump DynamicData from 7.4.3 to 7.4.9
Bumps [DynamicData](https://github.com/reactiveui/DynamicData) from 7.4.3 to 7.4.9.
- [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.4.3...7.4.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-19 23:35:05 +00:00
Aigio Liu a4f06a2aa5 Android DnsAnalysisServiceImpl use System.Net.Dns 2021-12-19 00:51:20 +08:00
Aigio Liu 13db927cd3 fix Android SteamAuthTrade & DnsAnalysis -> IDnsAnalysisService & fix CommunityFixFragment 2021-12-19 00:16:21 +08:00
Aigio Liu 90088e8d2c Android CommunityFix 2021-12-18 17:59:36 +08:00
Aigio L 4d8f577e0b Merge pull request #820 from BeyondDimension/dependabot/nuget/MSBuild.Sdk.Extras-3.0.44
Bump MSBuild.Sdk.Extras from 3.0.38 to 3.0.44
2021-12-18 14:06:09 +08:00
dependabot[bot] 6ed175a01c Bump MSBuild.Sdk.Extras from 3.0.38 to 3.0.44
Bumps [MSBuild.Sdk.Extras](https://github.com/novotnyllc/MSBuildSdkExtras) from 3.0.38 to 3.0.44.
- [Release notes](https://github.com/novotnyllc/MSBuildSdkExtras/releases)
- [Commits](https://github.com/novotnyllc/MSBuildSdkExtras/compare/v3.0.38...v3.0.44)

---
updated-dependencies:
- dependency-name: MSBuild.Sdk.Extras
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-18 06:05:05 +00:00
Aigio L 7794eb7495 Merge pull request #798 from BeyondDimension/feature/android
Android Support
2021-12-18 14:02:27 +08:00
Aigio Liu f6c869081b Remove IsConnectedAsync MainThread2.InvokeOnMainThreadAsync 2021-12-18 14:01:17 +08:00
Aigio Liu 8a88dd0615 Remove Win10 IsConnected PlatformNetworkAccess 2021-12-18 13:25:39 +08:00
Aigio Liu b247e0f6bc CommunityFixVpnService 2021-12-18 13:22:21 +08:00
Aigio Liu 6e6fd8a881 Handle Java.Security.Cert.CertificateNotYetValidException 2021-12-17 13:49:00 +08:00
Aigio L 1e118ae5e0 Merge pull request #809 from BeyondDimension/dependabot/nuget/Z.EntityFramework.Plus.EFCore-6.13.4
Bump Z.EntityFramework.Plus.EFCore from 6.13.2 to 6.13.4
2021-12-17 11:28:33 +08:00
Aigio L 6c126f1c1f Merge pull request #818 from BeyondDimension/dependabot/nuget/Square.OkHttp3-4.9.2.1
Bump Square.OkHttp3 from 4.9.2 to 4.9.2.1
2021-12-17 11:28:17 +08:00
Aigio L 3df3d2857f Merge pull request #817 from BeyondDimension/dependabot/submodules/references/dotnet-packaging-3f7bd3c
Bump references/dotnet-packaging from `fb0ad36` to `3f7bd3c`
2021-12-17 11:27:50 +08:00
dependabot[bot] d3e6293a89 Bump Square.OkHttp3 from 4.9.2 to 4.9.2.1
Bumps Square.OkHttp3 from 4.9.2 to 4.9.2.1.

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-16 23:22:13 +00:00
dependabot[bot] 161297a478 Bump references/dotnet-packaging from fb0ad36 to 3f7bd3c
Bumps [references/dotnet-packaging](https://github.com/qmfrederik/dotnet-packaging) from `fb0ad36` to `3f7bd3c`.
- [Release notes](https://github.com/qmfrederik/dotnet-packaging/releases)
- [Commits](https://github.com/qmfrederik/dotnet-packaging/compare/fb0ad366401ab9f0d7467fac3e952febaae514a3...3f7bd3c61a00ce2c51f4f53f34d149b0ce5f8fdd)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-16 23:20:11 +00:00
Aigio Liu e244056d7d Misc 2021-12-16 18:39:47 +08:00
Aigio Liu 2e44dfc8ef Android CommunityFix & AccelerateProjectGroup 2021-12-16 15:36:15 +08:00
Aigio Liu 930eb2261f Update .NET 6.0.1 Packages 2021-12-15 11:19:09 +08:00
Aigio Liu c57b49e8de Update .NET 6.0.1 2021-12-15 11:18:54 +08:00
Aigio Liu 37be6b16eb Update .NET 6.0.1 Packages 2021-12-15 11:18:28 +08:00
Aigio Liu c64fe98f73 Update .NET 6.0.1 2021-12-15 11:10:57 +08:00
dependabot[bot] b8ebbc73b3 Bump Z.EntityFramework.Plus.EFCore from 6.13.2 to 6.13.4
Bumps [Z.EntityFramework.Plus.EFCore](https://github.com/zzzprojects/EntityFramework-Plus) from 6.13.2 to 6.13.4.
- [Release notes](https://github.com/zzzprojects/EntityFramework-Plus/releases)
- [Commits](https://github.com/zzzprojects/EntityFramework-Plus/commits/6.13.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>
2021-12-14 23:58:12 +00:00
Aigio Liu 12512231ba Misc 2021-12-14 23:03:21 +08:00
Aigio Liu a8f6f663a1 Android AboutController & SettingsController 2021-12-14 19:05:10 +08:00
Aigio Liu 35e9910ece Remove Xamarin.Forms 2021-12-14 14:51:04 +08:00
Aigio L 0d9394aea9 Merge pull request #795 from BeyondDimension/dependabot/nuget/TaskScheduler-2.9.3
Bump TaskScheduler from 2.9.2 to 2.9.3
2021-12-14 11:36:22 +08:00
dependabot[bot] 208435cd57 Bump TaskScheduler from 2.9.2 to 2.9.3
Bumps [TaskScheduler](https://github.com/dahall/taskscheduler) from 2.9.2 to 2.9.3.
- [Release notes](https://github.com/dahall/taskscheduler/releases)
- [Commits](https://github.com/dahall/taskscheduler/compare/v2.9.2...v2.9.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-13 23:28:09 +00:00
Aigio Liu e169bb4e88 改进 LOCAL_ACCELERATE 文件格式 2021-12-14 00:57:41 +08:00
Aigio Liu 88755791b1 fix ASF Config Dir FileSystemWatcher throw 2021-12-13 22:45:27 +08:00
Aigio Liu 73ba4d01bc 指定使用 Tls1.1~1.3 代替系统默认 2021-12-13 20:49:00 +08:00
Aigio Liu b230eb9839 更新依赖包 & 改进 hosts 文件被占用时错误提示 & 屏蔽发行版本的 DebugPage 2021-12-13 18:37:14 +08:00
Aigio Liu 70df1891bf UseSystemResourceKeys false 2021-12-13 13:51:56 +08:00
Aigio L 7bf0bc2be7 Merge pull request #784 from BeyondDimension/dependabot/nuget/ReactiveUI.XamForms-17.1.9
Bump ReactiveUI.XamForms from 17.1.6 to 17.1.9
2021-12-13 10:27:14 +08:00
Aigio L c694bd0586 Merge pull request #785 from BeyondDimension/dependabot/nuget/Xamarin.Google.MLKit.BarcodeScanning-116.1.2.3
Bump Xamarin.Google.MLKit.BarcodeScanning from 116.1.2.2 to 116.1.2.3
2021-12-13 10:26:49 +08:00
Aigio L ef79ceeb84 Merge pull request #786 from BeyondDimension/dependabot/nuget/JustArchiNET.Madness-3.1.1
Bump JustArchiNET.Madness from 3.0.0 to 3.1.1
2021-12-13 10:26:24 +08:00
Aigio L 3ee1d99330 Merge pull request #787 from BeyondDimension/dependabot/nuget/AspNet.Security.OAuth.Apple-6.0.1
Bump AspNet.Security.OAuth.Apple from 6.0.0 to 6.0.1
2021-12-13 10:26:14 +08:00
Aigio L 37735e0add Merge branch 'develop' into dependabot/nuget/AspNet.Security.OAuth.Apple-6.0.1 2021-12-13 10:26:09 +08:00
Aigio L 61e31aab82 Merge pull request #788 from BeyondDimension/dependabot/nuget/Net.Codecrete.QrCodeGenerator-2.0.1
Bump Net.Codecrete.QrCodeGenerator from 2.0.0 to 2.0.1
2021-12-13 10:25:36 +08:00
Aigio L 2ef08a87ea Merge pull request #789 from BeyondDimension/dependabot/nuget/ReactiveUI-17.1.9
Bump ReactiveUI from 17.1.6 to 17.1.9
2021-12-13 10:25:30 +08:00
Aigio L 147ff6ce9d Merge pull request #790 from BeyondDimension/dependabot/nuget/AspNet.Security.OAuth.QQ-6.0.1
Bump AspNet.Security.OAuth.QQ from 6.0.0 to 6.0.1
2021-12-13 10:25:20 +08:00
dependabot[bot] ec43d282e6 Bump AspNet.Security.OAuth.QQ from 6.0.0 to 6.0.1
Bumps [AspNet.Security.OAuth.QQ](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers) from 6.0.0 to 6.0.1.
- [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.0...6.0.1)

---
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>
2021-12-12 23:38:57 +00:00
dependabot[bot] 4211ab64a2 Bump ReactiveUI from 17.1.6 to 17.1.9
Bumps [ReactiveUI](https://github.com/reactiveui/reactiveui) from 17.1.6 to 17.1.9.
- [Release notes](https://github.com/reactiveui/reactiveui/releases)
- [Commits](https://github.com/reactiveui/reactiveui/compare/17.1.6...17.1.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-12 23:32:40 +00:00
dependabot[bot] 7f8411edc5 Bump Net.Codecrete.QrCodeGenerator from 2.0.0 to 2.0.1
Bumps [Net.Codecrete.QrCodeGenerator](https://github.com/manuelbl/QrCodeGenerator) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/manuelbl/QrCodeGenerator/releases)
- [Commits](https://github.com/manuelbl/QrCodeGenerator/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: Net.Codecrete.QrCodeGenerator
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-12 23:31:40 +00:00
dependabot[bot] 075ff38198 Bump AspNet.Security.OAuth.Apple from 6.0.0 to 6.0.1
Bumps [AspNet.Security.OAuth.Apple](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers) from 6.0.0 to 6.0.1.
- [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.0...6.0.1)

---
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>
2021-12-12 23:31:18 +00:00
dependabot[bot] 3627e26c5e Bump JustArchiNET.Madness from 3.0.0 to 3.1.1
Bumps [JustArchiNET.Madness](https://github.com/JustArchiNET/Madness) from 3.0.0 to 3.1.1.
- [Release notes](https://github.com/JustArchiNET/Madness/releases)
- [Commits](https://github.com/JustArchiNET/Madness/compare/3.0.0...3.1.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-12 23:24:05 +00:00
dependabot[bot] 2e296cb3ec Bump Xamarin.Google.MLKit.BarcodeScanning from 116.1.2.2 to 116.1.2.3
Bumps [Xamarin.Google.MLKit.BarcodeScanning](https://github.com/xamarin/GooglePlayServicesComponents) from 116.1.2.2 to 116.1.2.3.
- [Release notes](https://github.com/xamarin/GooglePlayServicesComponents/releases)
- [Commits](https://github.com/xamarin/GooglePlayServicesComponents/commits)

---
updated-dependencies:
- dependency-name: Xamarin.Google.MLKit.BarcodeScanning
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-12 23:23:47 +00:00
dependabot[bot] 132dd15f97 Bump ReactiveUI.XamForms from 17.1.6 to 17.1.9
Bumps [ReactiveUI.XamForms](https://github.com/reactiveui/reactiveui) from 17.1.6 to 17.1.9.
- [Release notes](https://github.com/reactiveui/reactiveui/releases)
- [Commits](https://github.com/reactiveui/reactiveui/compare/17.1.6...17.1.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-12 23:21:29 +00:00
Aigio Liu 7965d4cab4 Add HTTP3 Test 2021-12-12 22:30:26 +08:00
RMBGAME 869567fde5 fix macos host error 2021-12-12 19:00:11 +08:00
614 changed files with 11198 additions and 3781 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
---
name: Bug Report 🐛
name: "Bug Report \U0001F41B"
about: 创建 Bug 报告以帮助我们改进 / Create a report to help us improve
title: "🐛[BUG] "
title: "\U0001F41B[BUG] "
labels: bug
assignees: ''
+4 -4
View File
@@ -1,8 +1,8 @@
---
name: Feature request 👑
name: "Feature request \U0001F451"
about: 对程序的需求或建议 / Suggest an idea for program
title: "👑[Enhancement] "
labels: enhancement
title: "\U0001F451[Enhancement] "
labels: enhancement
assignees: ''
---
@@ -26,4 +26,4 @@ If you have a solution, explain it clearly here
<!--
如截图等其他信息可以贴在这里
Other information such as screenshots can be posted here
-->
-->
+17
View File
@@ -0,0 +1,17 @@
---
name: Milestone
about: Issue a summary of the fixes recorded for the next release
title: "vTBD Milestone"
labels: documentation
assignees: rmbadmin, AigioL, Mossimos
---
## New release previous preparations | 发行新版本前准备工作
- [ ] Translate resx | 翻译 resx
- [ ] Compile msixupload package | 编译 msixupload 包
- [ ] Github release / Gitee release | 在 Github 与 Gitee 上发布
- [ ] Upload network disk | 上传网盘
- [ ] Update the official website | 更新官网
- [ ] Server publishing tool enable new version | 服务器发布工具启用新版本
- [ ] ~~Enable MS store channel new version notification after waiting for MS store approval | 等待微软商店审核完成后启用该渠道新版本通知~~
+4 -4
View File
@@ -1,8 +1,8 @@
---
name: question 🧐
name: "Question \U0001F9D0"
about: 对程序使用的疑问或需要帮助 / Questions about the use of the program or need help
title: "🧐[Question] "
labels: question
title: "\U0001F9D0[Question] "
labels: question
assignees: ''
---
@@ -23,4 +23,4 @@ Other information such as screenshots can be posted here
- 程序版本(Program Version):
- 系统版本号(OS Version): <!-- example Windows 10.19042.844(see winver) / macOS Monterey 12 / Ubuntu 20.04.2 LTS -->
- 是否为应用商店版本(Whether it is a Store version): <!--是(Yes)/否(No)-->
- 是否为应用商店版本(Whether it is a Store version): <!--是(Yes)/否(No)-->
+8
View File
@@ -137,6 +137,14 @@ jobs:
with:
name: '[${{ matrix.configuration }}]${{ env.ProjectName }}_macos_x64_${{ env.GITHUB_SHA_SHORT }}'
path: src\ST.Client.Desktop.Avalonia.App\bin\${{ matrix.configuration }}\Publish\${{ env.ProjectName }}_macos_x64_${{ env.GITHUB_SHA_SHORT }}.7z
- name: Upload macos-arm64 App ${{ matrix.configuration }}
continue-on-error: true
if: ${{ matrix.os == 'windows-latest' && !startsWith(github.ref, 'refs/tags/') && github.event_name == 'push' }}
uses: actions/upload-artifact@v2
with:
name: '[${{ matrix.configuration }}]${{ env.ProjectName }}_macos_arm64_${{ env.GITHUB_SHA_SHORT }}'
path: src\ST.Client.Desktop.Avalonia.App\bin\${{ matrix.configuration }}\Publish\${{ env.ProjectName }}_macos_arm64_${{ env.GITHUB_SHA_SHORT }}.7z
- name: Upload linux-x64 App ${{ matrix.configuration }}
continue-on-error: true
+12 -3
View File
@@ -112,7 +112,7 @@ jobs:
env:
Token: ${{ secrets.PUBLISH_TOKEN }}
- name: Package fd-win-x64
- name: Package fd-win-x64 7z
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }}
shell: pwsh
run: |
@@ -128,7 +128,7 @@ jobs:
Copy-Item ".\src\ST.Client.Desktop.Avalonia.App\bin\${env:Configuration}\Publish\${env:ProjectName}_win_x64_fde_v${{ steps.tag.outputs.tag }}.exe" "${env:PublishFilePath}"
Write-Output "exe_fd_win_x64_SHA256=$(.\packaging\SHA256.ps1 ${env:PublishFilePath}\${env:ProjectName}_win_x64_fde_v${{ steps.tag.outputs.tag }}.exe)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Package win-x64
- name: Package win-x64 7z
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }}
shell: pwsh
run: |
@@ -144,7 +144,7 @@ jobs:
Copy-Item ".\src\ST.Client.Desktop.Avalonia.App\bin\${env:Configuration}\Publish\${env:ProjectName}_win_x64_v${{ steps.tag.outputs.tag }}.exe" "${env:PublishFilePath}"
Write-Output "exe_win_x64_SHA256=$(.\packaging\SHA256.ps1 ${env:PublishFilePath}\${env:ProjectName}_win_x64_v${{ steps.tag.outputs.tag }}.exe)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Package osx-64
- name: Package osx-x64 7z
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }}
shell: pwsh
run: |
@@ -152,6 +152,14 @@ jobs:
Copy-Item ".\src\ST.Client.Desktop.Avalonia.App\bin\${env:Configuration}\Publish\${env:ProjectName}_macos_x64_v${{ steps.tag.outputs.tag }}.7z" "${env:PublishFilePath}"
Write-Output "macos_x64_SHA256=$(.\packaging\SHA256.ps1 ${env:PublishFilePath}\${env:ProjectName}_macos_x64_v${{ steps.tag.outputs.tag }}.7z)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Package osx-arm64 7z
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }}
shell: pwsh
run: |
New-Item -ItemType Directory -Path ${env:PublishFilePath} -Force > $null
Copy-Item ".\src\ST.Client.Desktop.Avalonia.App\bin\${env:Configuration}\Publish\${env:ProjectName}_macos_arm64_v${{ steps.tag.outputs.tag }}.7z" "${env:PublishFilePath}"
Write-Output "macos_arm64_SHA256=$(.\packaging\SHA256.ps1 ${env:PublishFilePath}\${env:ProjectName}_macos_arm64_v${{ steps.tag.outputs.tag }}.7z)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Package linux-x64 7z
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }}
shell: pwsh
@@ -237,6 +245,7 @@ jobs:
| <sub>${{ env.ProjectName }}_linux_arm64_v${{ steps.tag.outputs.tag }}.rpm</sub> | <sub>${{ env.rpm_linux_arm64_SHA256 }}</sub> |
|||
| <sub>${{ env.ProjectName }}_macos_x64_v${{ steps.tag.outputs.tag }}.7z</sub> | <sub>${{ env.macos_x64_SHA256 }}</sub> |
| <sub>${{ env.ProjectName }}_macos_arm64_v${{ steps.tag.outputs.tag }}.7z</sub> | <sub>${{ env.macos_arm64_SHA256 }}</sub> |
[![WebSite steampp.net](https://img.shields.io/badge/WebSite-steampp.net-brightgreen.svg?style=flat-square&color=61dafb)](https://steampp.net)
+4 -4
View File
@@ -2,11 +2,11 @@ name: Sync To Gitee
on:
push:
branches: [ main, develop ]
branches: [ main, develop, www ]
delete:
branches: [ main, develop ]
branches: [ main, develop, www ]
create:
branches: [ main, develop ]
branches: [ main, develop, www ]
jobs:
build:
@@ -18,4 +18,4 @@ jobs:
SSH_PRIVATE_KEY: ${{ secrets.GITEE_PRIVATE_KEY }}
with:
source-repo: "git@github.com:BeyondDimension/SteamTools.git"
destination-repo: "git@gitee.com:rmbgame/SteamTools"
destination-repo: "git@gitee.com:rmbgame/SteamTools"
+89 -91
View File
@@ -1,22 +1,21 @@
<Project>
<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard')) Or $(TargetFramework.StartsWith('netcoreapp3.1'))">
<!-- Microsoft.Extensions.* & AspNetCore & EntityFrameworkCore(NETCOREAPP31) -->
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="3.1.21" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="3.1.21" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="3.1.21" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.21" />
<PackageVersion Include="Microsoft.Extensions.Logging.AzureAppServices" Version="3.1.21" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.21" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="3.1.21" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.21" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.21" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.21" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.21" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.21" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="3.1.21" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.21" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.1.21" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.21" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="3.1.22" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="3.1.22" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="3.1.22" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.22" />
<PackageVersion Include="Microsoft.Extensions.Logging.AzureAppServices" Version="3.1.22" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.22" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="3.1.22" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.22" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.22" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.22" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.22" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.22" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="3.1.22" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.22" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.1.22" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('net5.0')) ">
<!-- Microsoft.Extensions.* & AspNetCore & EntityFrameworkCore(NET50) -->
@@ -35,7 +34,6 @@
<PackageVersion Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="5.0.12" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="5.0.12" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="5.0.12" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="5.0.12" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('net6.0')) ">
<!-- Microsoft.Extensions.* & AspNetCore & EntityFrameworkCore(NET60) -->
@@ -43,28 +41,27 @@
<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.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="6.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="6.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="6.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.AzureAppServices" Version="6.0.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="6.0.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="6.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="6.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.1" />
</ItemGroup>
<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.2" />
<PackageVersion Include="Z.EntityFramework.Plus.EFCore" Version="6.13.7" />
<!-- AspNetCore 6 OpenId/OAuth -->
<PackageVersion Include="AspNet.Security.OpenId.Steam" Version="6.0.0" />
<PackageVersion Include="AspNet.Security.OAuth.QQ" Version="6.0.0" />
<PackageVersion Include="AspNet.Security.OAuth.Apple" Version="6.0.0" />
<PackageVersion Include="AspNet.Security.OAuth.QQ" Version="6.0.3" />
<PackageVersion Include="AspNet.Security.OAuth.Apple" Version="6.0.3" />
</ItemGroup>
<ItemGroup>
</ItemGroup>
@@ -82,7 +79,7 @@
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard')) ">
<!-- BCL(NETSTANDARD) -->
<PackageVersion Include="System.Text.Json" Version="6.0.0" />
<PackageVersion Include="System.Text.Json" Version="6.0.1" />
<PackageVersion Include="System.Text.Encodings.Web" Version="6.0.0" />
<PackageVersion Include="System.Drawing.Common" Version="6.0.0" />
<PackageVersion Include="System.Security.Principal.Windows" Version="5.0.0" />
@@ -97,24 +94,24 @@
<!--<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.22000.196" />
<PackageVersion Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22000.197" />
<!-- AppCenter.* -->
<PackageVersion Include="Microsoft.AppCenter" Version="4.4.0" />
<PackageVersion Include="Microsoft.AppCenter.Analytics" Version="4.4.0" />
<PackageVersion Include="Microsoft.AppCenter.Crashes" Version="4.4.0" />
<PackageVersion Include="Aigio.Avalonia.AppCenter" Version="4.4.0.1" />
<PackageVersion Include="Aigio.Avalonia.AppCenter.Analytics" Version="4.4.0" />
<PackageVersion Include="Aigio.Avalonia.AppCenter.Crashes" Version="4.4.0" />
<PackageVersion Include="nor0x.AppCenter" Version="4.4.0-XMAC" />
<PackageVersion Include="Microsoft.AppCenter" Version="4.5.0" />
<PackageVersion Include="Microsoft.AppCenter.Analytics" Version="4.5.0" />
<PackageVersion Include="Microsoft.AppCenter.Crashes" Version="4.5.0" />
<PackageVersion Include="Aigio.Avalonia.AppCenter" Version="4.5.0" />
<PackageVersion Include="Aigio.Avalonia.AppCenter.Analytics" Version="4.5.0" />
<PackageVersion Include="Aigio.Avalonia.AppCenter.Crashes" Version="4.5.0" />
<!--<PackageVersion Include="nor0x.AppCenter" Version="4.4.0-XMAC" />
<PackageVersion Include="nor0x.AppCenter.Analytics" Version="4.4.0-XMAC" />
<PackageVersion Include="nor0x.AppCenter.Crashes" Version="4.4.0-XMAC" />
<PackageVersion Include="nor0x.AppCenter.Crashes" Version="4.4.0-XMAC" />-->
<!-- .NET Platform Extensions 6 -->
<PackageVersion Include="System.Security.Cryptography.ProtectedData" Version="6.0.0" />
<!-- Xamarin -->
<PackageVersion Include="Xamarin.Essentials" Version="1.7.0" />
<PackageVersion Include="Xamarin.Essentials" Version="1.7.1" />
<!-- Xamarin.Forms -->
<PackageVersion Include="Xamarin.Forms" Version="5.0.0.2244" />
<PackageVersion Include="Xamarin.Forms.Visual.Material" Version="5.0.0.2244" />
@@ -122,7 +119,7 @@
<!-- NUnit & NUnit.Xamarin & Moq -->
<PackageVersion Include="NUnit" Version="3.13.2" />
<PackageVersion Include="NUnit3TestAdapter" Version="4.1.0" />
<PackageVersion Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageVersion Include="nunit.xamarin" Version="3.6.1" />
<PackageVersion Include="PCLStorage" Version="1.0.2" />
<PackageVersion Include="Moq" Version="4.16.1" />
@@ -134,18 +131,18 @@
<!-- ReactiveUI -->
<PackageVersion Include="System.Reactive" Version="5.0.0" />
<PackageVersion Include="Splat" Version="14.1.1" />
<PackageVersion Include="DynamicData" Version="7.4.3" />
<PackageVersion Include="ReactiveUI" Version="17.1.6" />
<!--<PackageVersion Include="ReactiveUI.Fody" Version="17.1.6" /> -->
<PackageVersion Include="ReactiveUI.XamForms" Version="17.1.6" />
<PackageVersion Include="ReactiveUI.AndroidX" Version="17.0.1" />
<PackageVersion Include="Splat" Version="14.1.17" />
<PackageVersion Include="DynamicData" Version="7.4.11" />
<PackageVersion Include="ReactiveUI" Version="17.1.17" />
<!--<PackageVersion Include="ReactiveUI.Fody" Version="17.1.17" /> -->
<PackageVersion Include="ReactiveUI.XamForms" Version="17.1.17" />
<PackageVersion Include="ReactiveUI.AndroidX" Version="17.1.17" />
<!-- SkiaSharp & HarfBuzzSharp -->
<PackageVersion Include="HarfBuzzSharp" Version="2.6.1.8" />
<PackageVersion Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.6.1.8" />
<PackageVersion Include="SkiaSharp" Version="2.80.3" />
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.80.3" />
<PackageVersion Include="HarfBuzzSharp" Version="2.8.2-preview.179" />
<PackageVersion Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.8.2-preview.179" />
<PackageVersion Include="SkiaSharp" Version="2.88.0-preview.179" />
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.0-preview.179" />
<!-- AutoMapper -->
<PackageVersion Include="AutoMapper" Version="10.1.1" />
@@ -156,13 +153,13 @@
<!-- QRCode -->
<!--<PackageVersion Include="QRCoder" Version="1.4.2" />-->
<PackageVersion Include="Net.Codecrete.QrCodeGenerator" Version="2.0.0" />
<PackageVersion Include="Net.Codecrete.QrCodeGenerator" Version="2.0.1" />
<!-- NotifyIcon -->
<PackageVersion Include="NotifyIcon.Base" Version="1.0.5" />
<!--<PackageVersion Include="NotifyIcon.Linux" Version="1.0.5" />-->
<!--<PackageVersion Include="NotifyIcon.Mac" Version="1.0.5" />-->
<PackageVersion Include="NotifyIcon.Windows" Version="1.0.5" />
<PackageVersion Include="NotifyIcon.Base" Version="1.0.5.1" />
<!--<PackageVersion Include="NotifyIcon.Linux" Version="1.0.5.1" />-->
<!--<PackageVersion Include="NotifyIcon.Mac" Version="1.0.5.1" />-->
<PackageVersion Include="NotifyIcon.Windows" Version="1.0.5.1" />
<!--<PackageVersion Include="GtkSharp" Version="3.24.24.34" />-->
<!-- Compression -->
@@ -181,7 +178,7 @@
<PackageVersion Include="TinyPinyin.Net" Version="1.0.2" />
<!-- Win32/Windows -->
<PackageVersion Include="TaskScheduler" Version="2.9.2" />
<PackageVersion Include="TaskScheduler" Version="2.10.0" />
<!-- Swagger -->
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.2.3" />
@@ -203,18 +200,18 @@
<PackageVersion Include="MonoMac.NetStandard" Version="0.0.4" />
<!-- .NET Compat -->
<PackageVersion Include="OperatingSystem2" Version="1.4.2" />
<PackageVersion Include="JustArchiNET.Madness" Version="3.0.0" />
<PackageVersion Include="OperatingSystem2" Version="1.4.3" />
<PackageVersion Include="JustArchiNET.Madness" Version="3.2.1" />
<!-- Serialize -->
<PackageVersion Include="MessagePack" Version="2.3.85" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.1" />
<!-- Html Parser -->
<PackageVersion Include="HtmlAgilityPack" Version="1.11.39" />
<PackageVersion Include="HtmlAgilityPack" Version="1.11.41" />
<!-- Clipboard -->
<PackageVersion Include="TextCopy" Version="4.3.1" />
<PackageVersion Include="TextCopy" Version="6.1.0" />
<!-- Nito.* -->
<PackageVersion Include="Nito.Comparers" Version="6.2.2" />
@@ -227,60 +224,61 @@
<PackageVersion Include="Fleck" Version="1.2.0" />
<!-- DNS -->
<PackageVersion Include="DnsClient" Version="1.5.0" />
<PackageVersion Include="DnsClient" Version="1.6.0" />
<!-- Cryptographic Algorithms & Protocols -->
<PackageVersion Include="Portable.BouncyCastle" Version="1.9.0" />
<!-- Resilience & Transient Fault Handling -->
<PackageVersion Include="Polly" Version="7.2.2" />
<PackageVersion Include="Polly" Version="7.2.3" />
<!--Avalonia Start-->
<PackageVersion Include="Avalonia" Version="0.10.10" />
<PackageVersion Include="Avalonia.Desktop" Version="0.10.10" />
<PackageVersion Include="Avalonia.Diagnostics" Version="0.10.10" />
<PackageVersion Include="Avalonia.ReactiveUI" Version="0.10.10" />
<!--<PackageVersion Include="Avalonia.Direct2D1" Version="0.10.9" />-->
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="0.10.10" />
<PackageVersion Include="Avalonia.Xaml.Behaviors" Version="0.10.10.4" />
<PackageVersion Include="Avalonia" Version="0.10.12" />
<PackageVersion Include="Avalonia.Desktop" Version="0.10.12" />
<PackageVersion Include="Avalonia.Skia" Version="0.10.12" />
<PackageVersion Include="Avalonia.Diagnostics" Version="0.10.12" />
<PackageVersion Include="Avalonia.ReactiveUI" Version="0.10.12" />
<!--<PackageVersion Include="Avalonia.Direct2D1" Version="0.10.12" />-->
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="0.10.12" />
<PackageVersion Include="Avalonia.Xaml.Behaviors" Version="0.10.12" />
<!--<PackageVersion Include="Avalonia.AvaloniaEdit" Version="0.10.4" />-->
<!--<PackageVersion Include="CefNet.Avalonia" Version="93.1.21240.857" />-->
<!--<PackageVersion Include="LibVLCSharp.Avalonia" Version="3.5.1" />-->
<!--<PackageVersion Include="FluentAvaloniaUI" Version="1.1.6" />-->
<PackageVersion Include="JumpLists.Win32.Avalonia" Version="0.0.1" />
<!--<PackageVersion Include="FluentAvaloniaUI" Version="1.1.8" />-->
<PackageVersion Include="JumpLists.Win32.Avalonia" Version="1.0.0" />
<!--Avalonia End-->
<!-- Xamarin.Android -->
<PackageVersion Include="Xamarin.Google.Dagger" Version="2.39.1" />
<PackageVersion Include="Xamarin.Google.MLKit.BarcodeScanning" Version="116.1.2.2" />
<PackageVersion Include="Xamarin.Google.MLKit.BarcodeScanning" Version="116.1.2.3" />
<PackageVersion Include="Plugin.CurrentActivity" Version="2.1.0.4" />
<PackageVersion Include="de.hdodenhof.circleimageview" Version="3.1.0" />
<PackageVersion Include="Square.OkHttp3" Version="4.9.2" />
<PackageVersion Include="Square.Picasso" Version="2.71828.0" />
<PackageVersion Include="LeakCanaryBinding" Version="1.5.1.1" />
<!--<PackageVersion Include="LeakCanaryBinding" Version="1.5.1.1" />-->
<!--<PackageVersion Include="TencentOpenApiSDK.Android" Version="3.5.4.11" />-->
<!-- Xamarin.AndroidX -->
<PackageVersion Include="Xamarin.AndroidX.Migration" Version="1.0.8" />
<PackageVersion Include="Xamarin.AndroidX.AppCompat" Version="1.3.1.3" />
<PackageVersion Include="Xamarin.AndroidX.AppCompat" Version="1.3.1.4" />
<PackageVersion Include="Xamarin.AndroidX.Emoji.AppCompat" Version="1.1.0.5" />
<PackageVersion Include="Xamarin.AndroidX.Fragment" Version="1.3.6.3" />
<PackageVersion Include="Xamarin.AndroidX.Fragment" Version="1.3.6.4" />
<PackageVersion Include="Xamarin.AndroidX.Navigation.Fragment" Version="2.3.5.3" />
<PackageVersion Include="Xamarin.AndroidX.RecyclerView" Version="1.2.1.3" />
<PackageVersion Include="Xamarin.AndroidX.ViewPager2" Version="1.0.0.12" />
<PackageVersion Include="Xamarin.Google.Android.Material" Version="1.4.0.4" />
<PackageVersion Include="Xamarin.AndroidX.SwipeRefreshLayout" Version="1.1.0.5" />
<PackageVersion Include="Xamarin.AndroidX.ConstraintLayout" Version="2.1.1.2" />
<PackageVersion Include="Xamarin.AndroidX.RecyclerView" Version="1.2.1.4" />
<PackageVersion Include="Xamarin.Google.Android.Material" Version="1.4.0.5" />
<PackageVersion Include="Xamarin.AndroidX.SwipeRefreshLayout" Version="1.1.0.6" />
<PackageVersion Include="Xamarin.AndroidX.ConstraintLayout" Version="2.1.2.1" />
<PackageVersion Include="Xamarin.AndroidX.Navigation.UI" Version="2.3.5.3" />
<PackageVersion Include="Xamarin.AndroidX.ViewPager2" Version="1.0.0.12" />
<PackageVersion Include="Xamarin.AndroidX.Activity" Version="1.3.1.2" />
<PackageVersion Include="Xamarin.AndroidX.ViewPager2" Version="1.0.0.13" />
<PackageVersion Include="Xamarin.AndroidX.Activity" Version="1.4.0.1" />
<PackageVersion Include="Xamarin.AndroidX.Biometric" Version="1.1.0.6" />
<PackageVersion Include="Xamarin.AndroidX.ExifInterface" Version="1.3.3.2" />
<PackageVersion Include="Xamarin.AndroidX.Legacy.Support.Core.UI" Version="1.0.0.11" />
<PackageVersion Include="Xamarin.AndroidX.Lifecycle.LiveData" Version="2.3.1.3" />
<PackageVersion Include="Xamarin.AndroidX.Camera.Camera2" Version="1.0.2" />
<PackageVersion Include="Xamarin.AndroidX.Camera.Lifecycle" Version="1.0.2" />
<PackageVersion Include="Xamarin.AndroidX.ExifInterface" Version="1.3.3.3" />
<PackageVersion Include="Xamarin.AndroidX.Legacy.Support.Core.UI" Version="1.0.0.12" />
<PackageVersion Include="Xamarin.AndroidX.Lifecycle.LiveData" Version="2.4.0.1" />
<PackageVersion Include="Xamarin.AndroidX.Camera.Camera2" Version="1.0.2.2" />
<PackageVersion Include="Xamarin.AndroidX.Camera.Lifecycle" Version="1.0.2.2" />
<PackageVersion Include="Xamarin.AndroidX.Camera.View" Version="1.0.0.5-alpha20" />
<!--<PackageVersion Include="Xamarin.AndroidX.Window" Version="1.0.0.3-beta02" />-->
<!-- Xamarin.iOS -->
<PackageVersion Include="Toast.iOS" Version="1.2.0" />
+22 -14
View File
@@ -13,7 +13,7 @@ English | [简体中文](./README.md)
[![GitHub Fork](https://img.shields.io/github/forks/rmbadmin/SteamTools?style=flat-square)](https://github.com/rmbadmin/SteamTools/network/members)
![GitHub Repo size](https://img.shields.io/github/repo-size/rmbadmin/SteamTools?style=flat-square&color=3cb371)
[![GitHub Repo Languages](https://img.shields.io/github/languages/top/BeyondDimension/SteamTools?style=flat-square)](https://github.com/BeyondDimension/SteamTools/search?l=c%23)
[![NET 6.0](https://img.shields.io/badge/dotnet-6.0-purple.svg?style=flat-square&color=512bd4)](https://github.com/dotnet/core/blob/main/release-notes/6.0/6.0.0/6.0.0.md?WT.mc_id=dotnet-35129-website)
[![NET 6.0](https://img.shields.io/badge/dotnet-6.0-purple.svg?style=flat-square&color=512bd4)](https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-6)
[![C# 10.0](https://img.shields.io/badge/c%23-10.0-green.svg?style=flat-square&color=6da86a)](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10)
[![Desktop UI](https://img.shields.io/badge/ui@desktop-AvaloniaUI-purple.svg?style=flat-square&color=8c45ab)](https://github.com/AvaloniaUI/Avalonia)
@@ -33,6 +33,7 @@ English | [简体中文](./README.md)
- [Gitee Releases](https://gitee.com/rmbgame/SteamTools/releases)
- [Official WebSite](https://steampp.net)
- [![Microsoft Store](./resources/MSStore_English.png)](https://www.microsoft.com/store/apps/9MTCFHS560NG)
- [Arch Linux Package](https://aur.archlinux.org/packages/steam%2B%2B-bin)(By [zhanghua000](https://github.com/zhanghua000))
## ✨ Functions
1. Local reverse proxy for Steam's community webpage to enable normal access in **the Chinese Mainland, Mainland of China**
@@ -52,8 +53,8 @@ English | [简体中文](./README.md)
OS | Version | Architectures | Lifecycle
--------------------------------------|-------------------------|-----------------|----------
[Windows Client][Windows-client] | 7 SP1(**\***), 8.1 | x64 | [Windows][Windows-lifecycle]
[Windows 10 Client][Windows-client] | Version 1607+(**\***) | x64 | [Windows][Windows-lifecycle]
[Windows Server][Windows-Server] | 2012+ | x64 | [Windows Server][Windows-Server-lifecycle]
[Windows 10 Client][Windows-client] | Version 1607+(**\***) | x64 | [Windows][Windows-lifecycle]
[Windows Server][Windows-Server] | 2012+ | x64 | [Windows Server][Windows-Server-lifecycle]
**\*** Windows 7 SP1 is supported with [Extended Security Updates](https://docs.microsoft.com/troubleshoot/windows-client/windows-7-eos-faq/windows-7-extended-security-updates-faq) installed.
**\*** Microsoft Store/Desktop Bridge Version 1809+
@@ -69,15 +70,16 @@ OS | Version | Architectures
OS | Version | Architectures | Lifecycle
--------------------------------------|-----------------------|-------------------|----------
[Alpine Linux][Alpine] | 3.13+ | x64, Arm64, Arm32 | [Alpine][Alpine-lifecycle]
[Alpine Linux][Alpine] | 3.13+ | x64, Arm64 | [Alpine][Alpine-lifecycle]
[CentOS][CentOS] | 7+ | x64 | [CentOS][CentOS-lifecycle]
[Debian][Debian] | 10+ | x64, Arm64, Arm32 | [Debian][Debian-lifecycle]
[Debian][Debian] | 10+ | x64, Arm64 | [Debian][Debian-lifecycle]
[Fedora][Fedora] | 33+ | x64 | [Fedora][Fedora-lifecycle]
[openSUSE][OpenSUSE] | 15+ | x64 | [OpenSUSE][OpenSUSE-lifecycle]
[Red Hat Enterprise Linux][RHEL] | 7+ | x64, Arm64 | [Red Hat][RHEL-lifecycle]
[SUSE Enterprise Linux (SLES)][SLES] | 12 SP2+ | x64 | [SUSE][SLES-lifecycle]
[Ubuntu][Ubuntu] | 16.04, 18.04, 20.04+ | x64, Arm64, Arm32 | [Ubuntu][Ubuntu-lifecycle]
[Deepin / UOS][Deepin] | 20+ | x64 | [Deepin][Deepin-lifecycle]
[Ubuntu][Ubuntu] | 16.04, 18.04, 20.04+ | x64, Arm64 | [Ubuntu][Ubuntu-lifecycle]
[Deepin / UOS][Deepin] | 20+ | x64 | [Deepin][Deepin-lifecycle]
[Arch Linux][Arch] | | x64 |
[Alpine]: https://alpinelinux.org/
[Alpine-lifecycle]: https://wiki.alpinelinux.org/wiki/Alpine_Linux:Releases
@@ -109,28 +111,32 @@ OS | Version | Architectures
[Ubuntu-pm]: https://docs.microsoft.com/dotnet/core/install/linux-package-manager-ubuntu-2004
[Deepin]: https://www.deepin.org/
[Deepin-lifecycle]: https://www.deepin.org/release-notes
[Arch]: https://archlinux.org/
### macOS
OS | Version | Architectures |
------------------------------|---------------------------|-------------------|
[macOS][macOS] | 10.14+ | x64 |
[macOS][macOS] | 10.14+ | x64 |
[macOS]: https://support.apple.com/macos
### Android
OS | Version | Architectures |
------------------------------|-------------------------|-------------------|
[Android][Android] | 5.0(API 21)+ | [x86](https://developer.android.google.cn/ndk/guides/abis?hl=zh_cn#x86), [Arm32](https://developer.android.google.cn/ndk/guides/abis?hl=zh_cn#v7a), [Arm64](https://developer.android.google.cn/ndk/guides/abis?hl=zh_cn#arm64-v8a) |
OS | Version | Architectures |
------------------------------|-------------------------|--------------------------------------------------------------------|
[Android][Android] | 5.0(API 21)+ | [x64][Android-x64], [Arm64][Android-Arm64], [Arm32][Android-Arm32] |
[Android]: https://support.google.com/android
[Android-x64]: https://developer.android.google.cn/ndk/guides/abis?hl=zh_cn#86-64
[Android-Arm32]: https://developer.android.google.cn/ndk/guides/abis?hl=zh_cn#v7a
[Android-Arm64]: https://developer.android.google.cn/ndk/guides/abis?hl=zh_cn#arm64-v8a
### ~~iOS / iPadOS~~
OS | Version | Architectures |
------------------------------|-------------------------|-------------------|
[iOS][iOS] | 10.0+ | x64, Arm32, Arm64 |
[iOS][iOS] | 10.0+ | x64, Arm64, Arm32 |
[iOS]: https://support.apple.com/ios
@@ -170,7 +176,7 @@ Read what we [milestones](https://github.com/BeyondDimension/SteamTools/mileston
- [NUnit VS Templates](https://marketplace.visualstudio.com/items?itemName=NUnitDevelopers.NUnitTemplatesforVisualStudio)
[OpenJDK 11](https://docs.microsoft.com/java/openjdk/download#openjdk-11)
[Android Studio 2020.3.1 Or Higher](https://developer.android.com/studio/)
[Android Studio 2021.1.1 Or Higher](https://developer.android.com/studio/)
[Xcode 13 Or Higher](https://developer.apple.com/xcode/)
## 📄 Thanks to the following Open Source Projects
@@ -194,11 +200,13 @@ Read what we [milestones](https://github.com/BeyondDimension/SteamTools/mileston
* [DnsClient.NET](https://github.com/MichaCo/DnsClient.NET)
* [Costura.Fody](https://github.com/Fody/Costura)
* [MessagePack-CSharp](https://github.com/neuecc/MessagePack-CSharp)
* [CSharpVitamins.ShortGuid](https://github.com/AigioL/CSharpVitamins.ShortGuid)
* [Nito.Comparers](https://github.com/StephenCleary/Comparers)
* [Nito.Disposables](https://github.com/StephenCleary/Disposables)
* [Crc32.NET](https://github.com/force-net/Crc32.NET)
* [gfoidl.Base64](https://github.com/gfoidl/Base64)
* [sqlite-net-pcl](https://github.com/praeclarum/sqlite-net)
* [AutoMapper](https://github.com/AutoMapper/AutoMapper)
* [Polly](https://github.com/App-vNext/Polly)
* [TaskScheduler](https://github.com/dahall/taskscheduler)
* [SharpZipLib](https://github.com/icsharpcode/SharpZipLib)
@@ -252,4 +260,4 @@ Read what we [milestones](https://github.com/BeyondDimension/SteamTools/mileston
* [command-line-api](https://github.com/dotnet/command-line-api)
* [.NET Runtime](https://github.com/dotnet/runtime)
* [Fluent UI System Icons](https://github.com/microsoft/fluentui-system-icons)
* [Material design icons](https://github.com/google/material-design-icons)
* [Material design icons](https://github.com/google/material-design-icons)
+20 -14
View File
@@ -13,7 +13,7 @@
[![GitHub Fork](https://img.shields.io/github/forks/BeyondDimension/SteamTools?style=flat-square)](https://github.com/BeyondDimension/SteamTools/network/members)
![GitHub Repo size](https://img.shields.io/github/repo-size/BeyondDimension/SteamTools?style=flat-square&color=3cb371)
[![GitHub Repo Languages](https://img.shields.io/github/languages/top/BeyondDimension/SteamTools?style=flat-square)](https://github.com/BeyondDimension/SteamTools/search?l=c%23)
[![NET 6.0](https://img.shields.io/badge/dotnet-6.0-purple.svg?style=flat-square&color=512bd4)](https://github.com/dotnet/core/blob/main/release-notes/6.0/6.0.0/6.0.0.md?WT.mc_id=dotnet-35129-website)
[![NET 6.0](https://img.shields.io/badge/dotnet-6.0-purple.svg?style=flat-square&color=512bd4)](https://docs.microsoft.com/zh-cn/dotnet/core/whats-new/dotnet-6)
[![C# 10.0](https://img.shields.io/badge/c%23-10.0-brightgreen.svg?style=flat-square&color=6da86a)](https://docs.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-10)
[![Desktop UI](https://img.shields.io/badge/ui@desktop-AvaloniaUI-purple.svg?style=flat-square&color=8c45ab)](https://github.com/AvaloniaUI/Avalonia)
@@ -34,6 +34,7 @@
- [Gitee Releases](https://gitee.com/rmbgame/SteamTools/releases)
- [Official WebSite](https://steampp.net)
- [![Microsoft Store](./resources/MSStore_English.png)](https://www.microsoft.com/store/apps/9MTCFHS560NG)
- [Arch Linux Package](https://aur.archlinux.org/packages/steam%2B%2B-bin)(By [zhanghua000](https://github.com/zhanghua000))
## ✨ 功能
1. 反代 Steam 的社区网页使其能正常访问
@@ -61,8 +62,8 @@
OS | Version | Architectures | Lifecycle
--------------------------------------|-------------------------|-----------------|----------
[Windows Client][Windows-client] | 7 SP1(**\***), 8.1 | x64 | [Windows][Windows-lifecycle]
[Windows 10 Client][Windows-client] | Version 1607+(**\***) | x64 | [Windows][Windows-lifecycle]
[Windows Server][Windows-Server] | 2012+ | x64 | [Windows Server][Windows-Server-lifecycle]
[Windows 10 Client][Windows-client] | Version 1607+(**\***) | x64 | [Windows][Windows-lifecycle]
[Windows Server][Windows-Server] | 2012+ | x64 | [Windows Server][Windows-Server-lifecycle]
**\*** Windows 7 SP1 is supported with [Extended Security Updates](https://docs.microsoft.com/troubleshoot/windows-client/windows-7-eos-faq/windows-7-extended-security-updates-faq) installed.
**\*** Microsoft Store/Desktop Bridge Version 1809+
@@ -78,15 +79,16 @@ OS | Version | Architectures
OS | Version | Architectures | Lifecycle
--------------------------------------|-----------------------|-------------------|----------
[Alpine Linux][Alpine] | 3.13+ | x64, Arm64, Arm32 | [Alpine][Alpine-lifecycle]
[Alpine Linux][Alpine] | 3.13+ | x64, Arm64 | [Alpine][Alpine-lifecycle]
[CentOS][CentOS] | 7+ | x64 | [CentOS][CentOS-lifecycle]
[Debian][Debian] | 10+ | x64, Arm64, Arm32 | [Debian][Debian-lifecycle]
[Debian][Debian] | 10+ | x64, Arm64 | [Debian][Debian-lifecycle]
[Fedora][Fedora] | 33+ | x64 | [Fedora][Fedora-lifecycle]
[openSUSE][OpenSUSE] | 15+ | x64 | [OpenSUSE][OpenSUSE-lifecycle]
[Red Hat Enterprise Linux][RHEL] | 7+ | x64, Arm64 | [Red Hat][RHEL-lifecycle]
[SUSE Enterprise Linux (SLES)][SLES] | 12 SP2+ | x64 | [SUSE][SLES-lifecycle]
[Ubuntu][Ubuntu] | 16.04, 18.04, 20.04+ | x64, Arm64, Arm32 | [Ubuntu][Ubuntu-lifecycle]
[Deepin / UOS][Deepin] | 20+ | x64 | [Deepin][Deepin-lifecycle]
[Ubuntu][Ubuntu] | 16.04, 18.04, 20.04+ | x64, Arm64 | [Ubuntu][Ubuntu-lifecycle]
[Deepin / UOS][Deepin] | 20+ | x64 | [Deepin][Deepin-lifecycle]
[Arch Linux][Arch] | | x64 |
[Alpine]: https://alpinelinux.org/
[Alpine-lifecycle]: https://wiki.alpinelinux.org/wiki/Alpine_Linux:Releases
@@ -118,22 +120,24 @@ OS | Version | Architectures
[Ubuntu-pm]: https://docs.microsoft.com/dotnet/core/install/linux-package-manager-ubuntu-2004
[Deepin]: https://www.deepin.org/
[Deepin-lifecycle]: https://www.deepin.org/release-notes
[Arch]: https://archlinux.org/
### macOS
OS | Version | Architectures |
------------------------------|---------------------------|-------------------|
[macOS][macOS] | 10.14+ | x64 |
[macOS][macOS] | 10.14+ | x64 |
[macOS]: https://support.apple.com/macos
### Android
OS | Version | Architectures |
------------------------------|-------------------------|-------------------|
[Android][Android] | 5.0(API 21)+ | [x86](https://developer.android.google.cn/ndk/guides/abis?hl=zh_cn#x86), [Arm32](https://developer.android.google.cn/ndk/guides/abis?hl=zh_cn#v7a), [Arm64](https://developer.android.google.cn/ndk/guides/abis?hl=zh_cn#arm64-v8a) |
OS | Version | Architectures |
------------------------------|-------------------------|--------------------------------------------------------------------|
[Android][Android] | 5.0(API 21)+ | [x64][Android-x64], [Arm64][Android-Arm64], [Arm32][Android-Arm32] |
[Android]: https://support.google.com/android
[Android-x64]: https://developer.android.google.cn/ndk/guides/abis?hl=zh_cn#86-64
[Android-Arm32]: https://developer.android.google.cn/ndk/guides/abis?hl=zh_cn#v7a
[Android-Arm64]: https://developer.android.google.cn/ndk/guides/abis?hl=zh_cn#arm64-v8a
### ~~iOS / iPadOS~~
@@ -179,7 +183,7 @@ OS | Version | Architectures |
- [NUnit VS Templates](https://marketplace.visualstudio.com/items?itemName=NUnitDevelopers.NUnitTemplatesforVisualStudio)
[OpenJDK 11](https://docs.microsoft.com/zh-cn/java/openjdk/download#openjdk-11)
[Android Studio 2020.3.1 或更高版本](https://developer.android.google.cn/studio/)
[Android Studio 2021.1.1 或更高版本](https://developer.android.google.cn/studio/)
[Xcode 13 或更高版本](https://developer.apple.com/xcode/)
## 🏗️ [项目结构](./src/README.md)
@@ -214,11 +218,13 @@ OS | Version | Architectures |
* [DnsClient.NET](https://github.com/MichaCo/DnsClient.NET)
* [Costura.Fody](https://github.com/Fody/Costura)
* [MessagePack-CSharp](https://github.com/neuecc/MessagePack-CSharp)
* [CSharpVitamins.ShortGuid](https://github.com/AigioL/CSharpVitamins.ShortGuid)
* [Nito.Comparers](https://github.com/StephenCleary/Comparers)
* [Nito.Disposables](https://github.com/StephenCleary/Disposables)
* [Crc32.NET](https://github.com/force-net/Crc32.NET)
* [gfoidl.Base64](https://github.com/gfoidl/Base64)
* [sqlite-net-pcl](https://github.com/praeclarum/sqlite-net)
* [AutoMapper](https://github.com/AutoMapper/AutoMapper)
* [Polly](https://github.com/App-vNext/Polly)
* [TaskScheduler](https://github.com/dahall/taskscheduler)
* [SharpZipLib](https://github.com/icsharpcode/SharpZipLib)
+33 -2
View File
@@ -164,7 +164,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Desktop.UnitTest"
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}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Diagnostics", "src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj", "{E84FF7BC-FC2A-424E-8780-7DA9B487E23F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Diagnostics", "src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj", "{E84FF7BC-FC2A-424E-8780-7DA9B487E23F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Skia.Internals", "src\Avalonia.Skia.Internals\Avalonia.Skia.Internals.csproj", "{47C151DA-D2B1-43F4-A04E-B454E2134852}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -1794,6 +1796,34 @@ Global
{E84FF7BC-FC2A-424E-8780-7DA9B487E23F}.Release|x64.Build.0 = Release|Any CPU
{E84FF7BC-FC2A-424E-8780-7DA9B487E23F}.Release|x86.ActiveCfg = Release|Any CPU
{E84FF7BC-FC2A-424E-8780-7DA9B487E23F}.Release|x86.Build.0 = Release|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Debug|Any CPU.Build.0 = Debug|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Debug|ARM.ActiveCfg = Debug|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Debug|ARM.Build.0 = Debug|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Debug|ARM64.Build.0 = Debug|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Debug|iPhone.Build.0 = Debug|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Debug|x64.ActiveCfg = Debug|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Debug|x64.Build.0 = Debug|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Debug|x86.ActiveCfg = Debug|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Debug|x86.Build.0 = Debug|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Release|Any CPU.ActiveCfg = Release|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Release|Any CPU.Build.0 = Release|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Release|ARM.ActiveCfg = Release|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Release|ARM.Build.0 = Release|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Release|ARM64.ActiveCfg = Release|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Release|ARM64.Build.0 = Release|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Release|iPhone.ActiveCfg = Release|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Release|iPhone.Build.0 = Release|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{47C151DA-D2B1-43F4-A04E-B454E2134852}.Release|x64.ActiveCfg = Release|Any CPU
{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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1857,9 +1887,10 @@ Global
{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}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9313F2B4-10DA-43AA-A481-CAA7571C740C}
RESX_NeutralResourcesLanguage = zh-Hans
SolutionGuid = {9313F2B4-10DA-43AA-A481-CAA7571C740C}
EndGlobalSection
EndGlobal
BIN
View File
Binary file not shown.
+12 -13
View File
@@ -1,30 +1,29 @@
# 下载指南
- Desktop(桌面端)
- Windows
- 如果你使用 Intel、AMD 的 x64 芯片的 Mac(较为**普遍**),则下载文件名中带有 **win_x64** 的文件
- 如果你使用 ARM64 芯片的 PC(极为**稀有**),例如 **Surface Pro X**,则下载文件名中带有 **win_x64** 的文件可通过 Win11 x86 模拟运行
- 如果你使用 Intel、AMD 的 x64 芯片的 PC(较为**普遍**),则下载文件名中带有 **win_x64** 的文件
- 如果你已安装了 [ASP.NET Core Runtime 6.0.1](https://dotnet.microsoft.com/download/dotnet/6.0) 则下载文件名中带有 **fde** 的文件,可减少磁盘占用空间
- [在 Windows 上安装 .NET](https://docs.microsoft.com/en-us/dotnet/core/install/windows)
- 在 Windows 上不需要 Hosting Bundle 和 IIS support
- [下载安装程序并手动安装(aspnetcore-runtime-6.0.1-win-x64.exe)](https://dotnet.microsoft.com/download/dotnet/thank-you/runtime-aspnetcore-6.0.1-windows-x64-installer)
- [使用 PowerShell 自动化安装](https://docs.microsoft.com/en-us/dotnet/core/install/windows?tabs=net60#install-with-powershell-automation)
- macOS
- 如果你使用 Intel、AMD 的 x64 芯片的 Mac(较为**普遍**),则下载文件名中带有 **macos_x64** 的文件
- 如果你使用 ARM64 芯片的 Mac(较为**稀有**),例如 **M1**,则下载文件名中带有 **macos_x64** 的文件可通过 [Rosetta 2](https://support.apple.com/zh-cn/HT211861) 运行
- 如果你使用 ARM64 芯片的 Mac(较为**稀有**),例如 **M1**,则下载文件名中带有 **macos_arm64** 的文件
- Linux
- 如果你使用 Intel、AMD 的 x64 芯片的 PC(较为**普遍**)则下载文件名中带有 **linux_x64** 的文件
- 如果你使用 ARM64 芯片的 PC(较为**稀有**)例如 **Raspberry Pi Model 3+**,则下载文件名中带有 **linux_arm64** 的文件
- Shared
- 如果你已安装了 [ASP.NET Core Runtime 6.0.0](https://dotnet.microsoft.com/download/dotnet/6.0) 则下载文件名中带有 **fde** 的文件,可减少磁盘占用空间
- [在 Windows 上安装 .NET](https://docs.microsoft.com/en-us/dotnet/core/install/windows)
- 在 Windows 上不需要 Hosting Bundle 和 IIS support
- [下载安装程序并手动安装(aspnetcore-runtime-6.0.0-win-x64.exe)](https://dotnet.microsoft.com/download/dotnet/thank-you/runtime-aspnetcore-6.0.0-windows-x64-installer)
- [使用 PowerShell 自动化安装](https://docs.microsoft.com/en-us/dotnet/core/install/windows?tabs=net60#install-with-powershell-automation)
- [在 Linux 上安装 .NET](https://docs.microsoft.com/en-us/dotnet/core/install/linux)
- 推荐 [通过 Snap 安装 .NET Runtime](https://docs.microsoft.com/zh-cn/dotnet/core/install/linux-snap)
- ```sudo snap install dotnet-runtime-60 --classic```
- Mobile(移动端)
- Android
- 如果你使用 ARM64 芯片的设备(较为**普遍**)则下载文件名中带有 **android_arm64_v8a** 的文件
- 如果你使用 ARM32 芯片的设备(较为**稀有**)通常为 **14** 年下半年之前生产的设备,则下载文件名中带有 **android_armeabi_v7a** 的文件
- 如果你使用 Intel、AMD 的 x86 芯片的设备(较为**稀有**)则下载文件名中带有 **android_x86** 的文件
- 如果你使用 Intel、AMD 的 x64 芯片的设备(较为**稀有**)则下载文件名中带有 **android_x64** 的文件
<!--
- 如果你使用 ARM64 芯片的 PC(极为**稀有**),例如 **Surface Pro X**,则下载文件名中带有 **win_x64** 的文件可通过 Win11 x86 模拟运行
- **[暂未支持]** ~~如果你使用 ARM64 芯片的 PC(极为**稀有**),例如 **Surface Pro X**,则下载文件名中带有 **win_arm64** 的文件~~
- **[暂未支持]** ~~如果你使用 ARM64 芯片的 Mac(较为**稀有**),例如 **M1**,则下载文件名中带有 **macos_arm64** 的文件~~
- [在 Linux 上安装 .NET](https://docs.microsoft.com/en-us/dotnet/core/install/linux)
- 推荐 [通过 Snap 安装 .NET Runtime](https://docs.microsoft.com/zh-cn/dotnet/core/install/linux-snap)
- ```sudo snap install dotnet-runtime-60 --classic```
-->
+2 -2
View File
@@ -1,8 +1,8 @@
{
"msbuild-sdks": {
"MSBuild.Sdk.Extras": "3.0.38"
"MSBuild.Sdk.Extras": "3.0.44"
},
"sdk": {
"version": "6.0.100"
"version": "6.0.101"
}
}
+2 -2
View File
@@ -33,9 +33,9 @@ emit_plist() {
<key>CFBundleIdentifier</key>
<string>net.steampp.app</string>
<key>CFBundleShortVersionString</key>
<string>2.6.3</string>
<string>2.6.5</string>
<key>CFBundleVersion</key>
<string>2.6.3.0</string>
<string>2.6.5.0</string>
<key>LSMinimumSystemVersion</key>
<string>10.14</string>
<key>CFBundleDevelopmentRegion</key>
+1 -1
View File
@@ -11,7 +11,7 @@ $proj_path = "$RootPath\src\ST.Client.Desktop.Avalonia.App\ST.Client.Avalonia.Ap
$publishtool_dir = "$RootPath\src\ST.Tools.Publish"
$publishtool_exe = "$publishtool_dir\bin\Release\net6.0\p.exe"
$build_pubxmls = "fd-win-x64","win-x64","osx-x64","linux-x64","linux-arm64"
$build_pubxmls = "fd-win-x64","win-x64","osx-x64","linux-x64","linux-arm64","osx-arm64"
function Build-PublishTool
{
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -51,13 +51,13 @@
- [尚未公证](https://support.apple.com/zh-cn/guide/mac-help/mh40616/10.15/mac/10.15),这会影响 macOS Catalina(版本 10.15)以上版本
- Linux
- **Hosts 代理模式**可能无法配置成功,推荐使用**系统代理模式**
- 系统代理模式下discord更新下载加速有问题暂不可用
- 系统代理模式下 Discord 更新下载加速不可用
- 窗口弹出位置不正确
- 鼠标指针浮动样式不正确
- Windows
- Windows 11
- 在 CPU 不受支持的 Win11 上无法启动,Windows 日志中显示 ```Failed to create CoreCLR, HRESULT: 0x80004005```
- 仅 .NET 6.0 受此影响,在几周后的 Insider 中会修复,见 [issue](https://github.com/dotnet/core/issues/6733)
- 仅 .NET 6.0 受此影响,在内部版本 22509 中修复,见 [issue](https://github.com/dotnet/core/issues/6733)
- **解决方案:** 可尝试使用旧版本 例如 v2.3.0
- Windows 7
- 先决条件
+1 -1
View File
@@ -13,7 +13,7 @@
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Ninject" Version="3.3.4" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.10" />
<PackageReference Include="SharpZipLib" Version="1.3.1" />
<PackageReference Include="SharpZipLib" Version="1.3.3" />
<PackageReference Include="System.Management" Version="5.0.0" />
<PackageReference Include="TaskScheduler" Version="2.9.1" />
</ItemGroup>
+22 -12
View File
@@ -106,6 +106,10 @@ namespace System.Application.UI
#endif
b.AppendLine();
b.Append("[os.name] ");
b.Append(DeviceInfo2.OSNameValue);
b.AppendLine();
b.Append("[app.ver] ");
#if __ANDROID__
GetAppDisplayVersion(activity, b);
@@ -142,6 +146,10 @@ namespace System.Application.UI
b.Append(ApplicationUpdateServiceBaseImpl.UpdateChannelType);
b.AppendLine();
b.Append("[app.install] ");
b.Append(platformService.IsInstall);
b.AppendLine();
b.Append("[deploy.mode] ");
b.Append(IApplication.Instance.DeploymentMode);
b.AppendLine();
@@ -237,7 +245,9 @@ namespace System.Application.UI
#if __ANDROID__
b.Append("[screen] ");
var metrics = new DisplayMetrics();
#pragma warning disable CS0618 // 类型或成员已过时
activity.WindowManager?.DefaultDisplay?.GetRealMetrics(metrics);
#pragma warning restore CS0618 // 类型或成员已过时
GetScreen(activity, metrics, b);
static void GetScreen(Context context, DisplayMetrics metrics, StringBuilder b)
{
@@ -404,18 +414,18 @@ namespace System.Application.UI
// b.Append(DeviceSecurityCheckUtil.IsEmulator.ToLowerString());
// b.AppendLine();
//}
b.Append("[device.gl.renderer] ");
b.Append(GLES20.GlGetString(GLES20.GlRenderer) ?? "");
b.AppendLine();
b.Append("[device.gl.vendor] ");
b.Append(GLES20.GlGetString(GLES20.GlVendor) ?? "");
b.AppendLine();
b.Append("[device.gl.version] ");
b.Append(GLES20.GlGetString(GLES20.GlVersion) ?? "");
b.AppendLine();
b.Append("[device.gl.extensions] ");
b.Append(GLES20.GlGetString(GLES20.GlExtensions) ?? "");
b.AppendLine();
//b.Append("[device.gl.renderer] ");
//b.Append(GLES20.GlGetString(GLES20.GlRenderer) ?? "");
//b.AppendLine();
//b.Append("[device.gl.vendor] ");
//b.Append(GLES20.GlGetString(GLES20.GlVendor) ?? "");
//b.AppendLine();
//b.Append("[device.gl.version] ");
//b.Append(GLES20.GlGetString(GLES20.GlVersion) ?? "");
//b.AppendLine();
//b.Append("[device.gl.extensions] ");
//b.Append(GLES20.GlGetString(GLES20.GlExtensions) ?? "");
//b.AppendLine();
b.Append("[device.biometric] ");
b.Append(IBiometricService.Instance.IsSupportedAsync().Result.ToLowerString());
b.AppendLine();
@@ -2,6 +2,10 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<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>
@@ -2,6 +2,10 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<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>
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<RootNamespace>Avalonia.Skia</RootNamespace>
<AssemblyName>Avalonia.Skia.UnitTests</AssemblyName>
<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>
<PackageReference Include="Avalonia.Skia" Aliases="AvaloniaSkia" />
</ItemGroup>
</Project>
@@ -0,0 +1,40 @@
// Replace font management to implement custom default font
extern alias AvaloniaSkia;
using Avalonia.Media;
using System.Collections.Generic;
using System.Globalization;
using FontManagerImpl = AvaloniaSkia::Avalonia.Skia.FontManagerImpl;
// ReSharper disable once CheckNamespace
namespace Avalonia.Platform
{
public interface IFontManagerImpl2 : IFontManagerImpl
{
protected IFontManagerImpl Impl { get; }
string DefaultFontFamilyName { get; }
Typeface OnCreateGlyphTypeface(Typeface typeface);
string IFontManagerImpl.GetDefaultFontFamilyName() => DefaultFontFamilyName;
IEnumerable<string> IFontManagerImpl.GetInstalledFontFamilyNames(bool checkForUpdates)
{
return Impl.GetInstalledFontFamilyNames(checkForUpdates);
}
bool IFontManagerImpl.TryMatchCharacter(int codepoint, FontStyle fontStyle, FontWeight fontWeight, FontFamily fontFamily, CultureInfo culture, out Typeface typeface)
{
return Impl.TryMatchCharacter(codepoint, fontStyle, fontWeight, fontFamily, culture, out typeface);
}
IGlyphTypefaceImpl IFontManagerImpl.CreateGlyphTypeface(Typeface typeface)
{
typeface = OnCreateGlyphTypeface(typeface);
return Impl.CreateGlyphTypeface(typeface);
}
protected static IFontManagerImpl CreateFontManager() => new FontManagerImpl();
}
}
@@ -0,0 +1,27 @@
extern alias AvaloniaSkia;
using Avalonia.Media;
using SkiaSharp;
using @this = AvaloniaSkia::Avalonia.Skia.SKTypefaceCollection;
namespace Avalonia.Skia
{
public sealed class SKTypefaceCollection
{
readonly @this @this;
internal SKTypefaceCollection(@this @this)
{
this.@this = @this;
}
public void AddTypeface(Typeface key, SKTypeface typeface)
{
@this.AddTypeface(key, typeface);
}
public SKTypeface Get(Typeface typeface)
{
return @this.Get(typeface);
}
}
}
@@ -0,0 +1,20 @@
extern alias AvaloniaSkia;
using Avalonia.Media;
using @this = AvaloniaSkia::Avalonia.Skia.SKTypefaceCollectionCache;
namespace Avalonia.Skia
{
public class SKTypefaceCollectionCache
{
/// <summary>
/// Gets the or add typeface collection.
/// </summary>
/// <param name="fontFamily">The font family.</param>
/// <returns></returns>
public static SKTypefaceCollection GetOrAddTypefaceCollection(FontFamily fontFamily)
{
return new(@this.GetOrAddTypefaceCollection(fontFamily));
}
}
}
@@ -2,6 +2,10 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<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>
@@ -2,6 +2,10 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<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>
+4
View File
@@ -2,6 +2,10 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<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>
+4
View File
@@ -2,6 +2,10 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<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>
@@ -267,23 +267,28 @@
// newRating++;
// }
// try
// {
// var opengl = Android.Opengl.GLES20.GlGetString(Android.Opengl.GLES20.GlRenderer);
// if (!string.IsNullOrWhiteSpace(opengl))
// {
//#pragma warning disable CS8604 // 可能的 null 引用参数。
// if (contains(opengl, "Bluestacks") ||
// contains(opengl, "Translator") ||
// contains(opengl, "youwave")
// )
//#pragma warning restore CS8604 // 可能的 null 引用参数。
// newRating += 10;
// }
// }
// catch
// {
// }
/* signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdd0
* Cause: null pointer dereference
* backtrace:
* #00 pc 0000000000005ff4 /system/lib64/libGLESv1_CM.so (glGetString+52)
*/
//// try
//// {
//// var opengl = Android.Opengl.GLES20.GlGetString(Android.Opengl.GLES20.GlRenderer);
//// if (!string.IsNullOrWhiteSpace(opengl))
//// {
////#pragma warning disable CS8604 // 可能的 null 引用参数。
//// if (contains(opengl, "Bluestacks") ||
//// contains(opengl, "Translator") ||
//// contains(opengl, "youwave")
//// )
////#pragma warning restore CS8604 // 可能的 null 引用参数。
//// newRating += 10;
//// }
//// }
//// catch
//// {
//// }
// try
// {
@@ -46,7 +46,7 @@ namespace System.Application.UI.Adapters
protected virtual ItemClickEventArgs<TViewModel>? GetItemClickEventArgs(View view, TViewHolder holder, View.LongClickEventArgs? longClickEventArgs = null)
{
var position = holder.AdapterPosition;
var position = holder.BindingAdapterPosition;
if (position < 0 || position >= ViewModels.Count) return null;
var current = ViewModels[position];
return new PlatformItemClickEventArgs<TViewModel>(view, position, current, longClickEventArgs);
@@ -1,4 +1,4 @@
using Android.Views;
using Android.Views;
namespace System.Application.UI.Adapters
{
@@ -1,5 +1,7 @@
using Android.Content;
using Android.App;
using Android.Content;
using Android.Graphics.Drawables;
using Android.OS;
using Android.Runtime;
using AndroidX.Annotations;
using AndroidX.Core.Content;
@@ -8,7 +10,7 @@ using AndroidApplication = Android.App.Application;
// ReSharper disable once CheckNamespace
namespace System
{
public static class ContextExtensions
public static partial class ContextExtensions
{
/// <inheritdoc cref="ContextCompat.GetSystemService(Context, Java.Lang.Class)"/>
public static TService GetSystemService<TService>(this Context context) where TService : class, IJavaObject
@@ -60,5 +62,12 @@ namespace System
/// <returns></returns>
public static Drawable GetDrawableCompat(this Context context, [DrawableRes] int id)
=> ContextCompat.GetDrawable(context, id);
/// <inheritdoc cref="Android.Content.Res.Resources.GetDimensionPixelSize(int)"/>
public static int GetDimensionPixelSize(this Context context, [DimenRes] int resId)
{
var value = context.Resources!.GetDimensionPixelSize(resId);
return value;
}
}
}
@@ -1,4 +1,4 @@
using Android.Runtime;
using Android.Runtime;
using Java.Security.Cert;
using System.IO;
using Xamarin.Android.Net;
@@ -14,7 +14,7 @@ namespace System
/// <param name="handler"></param>
/// <param name="certificateFileData">证书文件数据(文件流,内嵌资源流)</param>
/// <param name="certificateFileType">证书文件类型,默认使用X.509</param>
public static void AddTrustedCerts(
public static void AddTrustedCert(
this AndroidClientHandler handler,
Stream certificateFileData,
string certificateFileType = "X.509")
@@ -95,7 +95,7 @@ namespace System.Application
{
if (format == ResValueFormat.String)
{
using var reader = new StreamReader(stream, Encoding.UTF8);
using var reader = new StreamReader(stream, EncodingCache.UTF8NoBOM);
return reader.ReadToEnd();
}
if (format == ResValueFormat.StringGuidD || format == ResValueFormat.StringGuidN)
@@ -30,13 +30,15 @@ namespace System.Application
Unknown = -2,
}
const string TAG = nameof(Browser2);
static void HandlerException(Exception e)
{
if (OnError == null)
{
try
{
Toast.Show(e, nameof(Browser2));
e.LogAndShowT(TAG);
}
catch
{
@@ -69,18 +71,8 @@ namespace System.Application
static OpenResultCode OpenCoreByProcess(string url)
{
try
{
Process2.Start(url, useShellExecute: true);
return OpenResultCode.StartedByProcess2;
}
catch (Win32Exception e)
{
// [Win32Exception: 找不到应用程序] 39次报告
// 疑似缺失没有默认浏览器设置会导致此异常,可能与杀毒软件有关
HandlerException(e);
return OpenResultCode.Exception;
}
var r = Process2.OpenCoreByProcess(url, s => Toast.Show(s));
return r ? OpenResultCode.StartedByProcess2 : OpenResultCode.Exception;
}
}
@@ -135,65 +135,73 @@ namespace System.Application
}
}
public static string? OSName
public static string OSName => OSNameValue.ToDisplayName();
static readonly Lazy<OSNames.Value> _OSNameValue = new(() =>
{
get
if (OperatingSystem2.IsWindows)
{
if (OperatingSystem2.IsWindows)
if (DeviceInfo.Platform == DevicePlatform.UWP)
{
if (DeviceInfo.Platform == DevicePlatform.UWP)
{
return "UWP";
}
else if (DesktopBridge.IsRunningAsUwp)
{
return "Windows Desktop Bridge";
}
//else if (OperatingSystem2.IsRunningAsUwp)
//{
// return "Windows Sparse Package";
//}
else
{
return "Windows";
}
return OSNames.Value.UWP;
}
else if (OperatingSystem2.IsAndroid)
else if (DesktopBridge.IsRunningAsUwp)
{
if (OperatingSystem2.IsRunningOnWSA)
{
return "WSA";
}
else
{
return "Android";
}
return OSNames.Value.WindowsDesktopBridge;
}
else if (OperatingSystem2.IsIOS)
else
{
if (DeviceInfo.Idiom == XEDeviceIdiom.Tablet)
return "iPadOS";
return "iOS";
return OSNames.Value.Windows;
}
else if (OperatingSystem2.IsMacOS)
{
return "macOS";
}
else if (OperatingSystem2.IsTvOS)
{
return "tvOS";
}
else if (OperatingSystem2.IsWatchOS)
{
return "watchOS";
}
else if (OperatingSystem2.IsLinux)
{
return "Linux";
}
return default;
}
}
else if (OperatingSystem2.IsAndroid)
{
if (OperatingSystem2.IsRunningOnWSA)
{
return OSNames.Value.WSA;
}
else
{
if (DeviceType == DeviceType.Virtual)
{
return OSNames.Value.AndroidVirtual;
}
return DeviceInfo.Idiom.Convert() switch
{
DeviceIdiom.Phone => OSNames.Value.AndroidPhone,
DeviceIdiom.Tablet => OSNames.Value.AndroidTablet,
DeviceIdiom.Desktop => OSNames.Value.AndroidDesktop,
DeviceIdiom.TV => OSNames.Value.AndroidTV,
DeviceIdiom.Watch => OSNames.Value.AndroidWatch,
_ => OSNames.Value.AndroidUnknown,
};
}
}
else if (OperatingSystem2.IsIOS)
{
if (DeviceInfo.Idiom == XEDeviceIdiom.Tablet)
return OSNames.Value.iPadOS;
return OSNames.Value.iOS;
}
else if (OperatingSystem2.IsMacOS)
{
return OSNames.Value.macOS;
}
else if (OperatingSystem2.IsTvOS)
{
return OSNames.Value.tvOS;
}
else if (OperatingSystem2.IsWatchOS)
{
return OSNames.Value.watchOS;
}
else if (OperatingSystem2.IsLinux)
{
return OSNames.Value.Linux;
}
return default;
});
public static OSNames.Value OSNameValue => _OSNameValue.Value;
/// <inheritdoc cref="DeviceInfo.DeviceType"/>
public static DeviceType DeviceType
@@ -0,0 +1,124 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Xamarin.Essentials;
using BaseFilePickerFileType = Xamarin.Essentials.FilePickerFileType;
// ReSharper disable once CheckNamespace
namespace System.Application
{
partial class FilePicker2
{
public class SaveOptions : PickOptions
{
public string? InitialFileName { get; set; }
}
public class FilePickerFileType : BaseFilePickerFileType
{
sealed class FixedFilePickerFileType : FilePickerFileType
{
readonly IEnumerable<string> fileTypes;
public FixedFilePickerFileType(IEnumerable<string> fileTypes)
{
this.fileTypes = fileTypes;
}
protected override IEnumerable<string> GetPlatformFileType(DevicePlatform _) => fileTypes;
}
[return: NotNullIfNotNull("values")]
public static FilePickerFileType? Parse(IEnumerable<string>? values) => values == null ? null : new FixedFilePickerFileType(values);
[return: NotNullIfNotNull("values")]
public static implicit operator FilePickerFileType?(HashSet<string>? values) => Parse(values);
[return: NotNullIfNotNull("values")]
public static implicit operator FilePickerFileType?(string[]? values) => Parse(values);
[return: NotNullIfNotNull("values")]
public static implicit operator FilePickerFileType?(Collection<string>? values) => Parse(values);
[return: NotNullIfNotNull("values")]
public static implicit operator FilePickerFileType?(List<string>? values) => Parse(values);
sealed class PlatformFilePickerFileType<TValue> : FilePickerFileType where TValue : IEnumerable<string>
{
readonly IEnumerable<KeyValuePair<Platform, TValue?>> fileTypes;
public PlatformFilePickerFileType(IEnumerable<KeyValuePair<Platform, TValue?>> fileTypes)
{
this.fileTypes = fileTypes;
}
protected override IEnumerable<string>? GetPlatformFileType(DevicePlatform _)
{
var platform = DeviceInfo2.Platform;
foreach (var fileType in fileTypes)
{
if (fileType.Key.HasFlag(platform))
return fileType.Value;
}
return null;
}
}
[return: NotNullIfNotNull("values")]
public static FilePickerFileType? Parse<TValue>(IEnumerable<KeyValuePair<Platform, TValue?>> values) where TValue : IEnumerable<string> => values == null ? null : new PlatformFilePickerFileType<TValue>(values);
[return: NotNullIfNotNull("values")]
public static implicit operator FilePickerFileType?(Dictionary<Platform, IEnumerable<string>?> values) => Parse(values);
[return: NotNullIfNotNull("values")]
public static implicit operator FilePickerFileType?(Dictionary<Platform, string[]?> values) => Parse(values);
[return: NotNullIfNotNull("values")]
public static implicit operator FilePickerFileType?(Dictionary<Platform, List<string>?> values) => Parse(values);
[return: NotNullIfNotNull("values")]
public static implicit operator FilePickerFileType?(Dictionary<Platform, HashSet<string>?> values) => Parse(values);
[return: NotNullIfNotNull("values")]
public static implicit operator FilePickerFileType?(Dictionary<Platform, Collection<string>?> values) => Parse(values);
public interface IFilePickerFileTypeWithName
{
IEnumerable<(string, IEnumerable<string>)> GetFileTypes();
}
sealed class FixedFilePickerFileType<TValue> : FilePickerFileType, IFilePickerFileTypeWithName where TValue : IEnumerable<string>
{
readonly IEnumerable<(string name, TValue extensions)> fileTypes;
public FixedFilePickerFileType(IEnumerable<(string name, TValue extensions)> fileTypes)
{
this.fileTypes = fileTypes;
}
protected override IEnumerable<string> GetPlatformFileType(DevicePlatform _) => fileTypes.SelectMany(x => x.extensions);
IEnumerable<(string, IEnumerable<string>)> IFilePickerFileTypeWithName.GetFileTypes()
{
foreach (var item in fileTypes)
{
yield return item;
}
}
}
[return: NotNullIfNotNull("values")]
public static FilePickerFileType? Parse<TValue>(IEnumerable<(string name, TValue extensions)> values) where TValue : IEnumerable<string> => values == null ? null : new FixedFilePickerFileType<TValue>(values);
[return: NotNullIfNotNull("values")]
public static implicit operator FilePickerFileType?((string name, IEnumerable<string> extensions)[] values) => Parse(values);
[return: NotNullIfNotNull("values")]
public static implicit operator FilePickerFileType?((string name, List<string> extensions)[] values) => Parse(values);
[return: NotNullIfNotNull("values")]
public static implicit operator FilePickerFileType?((string name, string[] extensions)[] values) => Parse(values);
}
}
}
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Xamarin.Essentials;
@@ -13,29 +14,8 @@ namespace System.Application
/// <para><see cref="https://docs.microsoft.com/zh-cn/xamarin/essentials/file-picker"/></para>
/// <para><see cref="https://github.com/xamarin/Essentials/blob/main/Xamarin.Essentials/FilePicker/FilePicker.shared.cs"/></para>
/// </summary>
public static class FilePicker2
public static partial class FilePicker2
{
static readonly Lazy<bool> mIsSupportedFileExtensionFilter = new(() =>
{
if (Essentials.IsSupported)
{
return OperatingSystem2.IsWindows;
}
else
{
var s = IOpenFileDialogService.Instance;
if (s != null)
{
return s.IsSupportedFileExtensionFilter;
}
return false;
}
});
/// <summary>
/// 是否支持文件扩展名过滤。
/// </summary>
public static bool IsSupportedFileExtensionFilter => mIsSupportedFileExtensionFilter.Value;
static readonly Lazy<bool> mIsSupportedSaveFileDialog = new(() =>
{
var s = ISaveFileDialogService.Instance;
@@ -77,6 +57,8 @@ namespace System.Application
}
}
const string TAG = nameof(FilePicker2);
/// <summary>
/// 启动文件选择器以选择单个文件。
/// </summary>
@@ -106,7 +88,7 @@ namespace System.Application
}
catch (Exception e)
{
Toast.Show(e, nameof(FilePicker2));
e.LogAndShowT(TAG);
}
}
}
@@ -149,7 +131,7 @@ namespace System.Application
}
catch (Exception e)
{
Toast.Show(e, nameof(FilePicker2));
e.LogAndShowT(TAG);
}
}
}
@@ -222,7 +204,7 @@ namespace System.Application
}
catch (Exception e)
{
Toast.Show(e, nameof(FilePicker2));
e.LogAndShowT(TAG);
}
}
}
@@ -265,7 +247,7 @@ namespace System.Application
}
catch (Exception e)
{
Toast.Show(e, nameof(FilePicker2));
e.LogAndShowT(TAG);
}
}
}
@@ -285,7 +267,7 @@ namespace System.Application
/// <param name="options">要使用的文件保存弹窗选项,可能为空。</param>
/// <returns>文件拾取结果对象,或当用户取消拾取时为空。</returns>
/// <exception cref="PlatformNotSupportedException"></exception>
public static async Task<FileResult?> SaveAsync(SaveOptions? options = null)
public static async Task<SaveFileResult?> SaveAsync(SaveOptions? options = null)
{
try
{
@@ -302,82 +284,69 @@ namespace System.Application
}
}
public class SaveOptions : PickOptions
public sealed class SaveFileResult : IDisposable
{
public string? InitialFileName { get; set; }
}
readonly string? fullPath;
readonly Stream? stream;
readonly string? @string;
bool disposedValue;
public class GeneralFilePickerFileType : FilePickerFileType
{
readonly IEnumerable<string> values;
public GeneralFilePickerFileType(IEnumerable<string> values) : base()
public SaveFileResult(string fullPath)
{
this.values = values;
this.fullPath = fullPath;
}
public static implicit operator GeneralFilePickerFileType(string[] values) => new(values);
public static implicit operator GeneralFilePickerFileType(List<string> values) => new(values);
protected override IEnumerable<string> GetPlatformFileType(DevicePlatform _) => values;
}
public class FilePickerFileType2 : FilePickerFileType
{
readonly IReadOnlyDictionary<Platform, IEnumerable<string>> fileTypes;
public FilePickerFileType2(IReadOnlyDictionary<Platform, IEnumerable<string>> fileTypes) : base() => this.fileTypes = fileTypes;
public static implicit operator FilePickerFileType2(Dictionary<Platform, IEnumerable<string>> fileTypes) => new(fileTypes);
protected override IEnumerable<string> GetPlatformFileType(DevicePlatform _)
public SaveFileResult(Stream stream, string? @string = null)
{
if (fileTypes.TryGetValue(DeviceInfo2.Platform, out var type))
return type;
throw new PlatformNotSupportedException("This platform does not support this file type.");
this.stream = stream;
this.@string = @string;
}
}
public class FilePickerFilter : GeneralFilePickerFileType
{
public IEnumerable<(string name, IEnumerable<string> extensions)> Filters { get; }
public FilePickerFilter(IEnumerable<(string name, IEnumerable<string> extensions)> filters) : base(filters.SelectMany(x => x.extensions))
/// <summary>
/// 打开写入流,在桌面平台上为 <see cref="FileStream"/>,在 Android 上为 Java.IO.OutputStream
/// </summary>
/// <returns></returns>
/// <exception cref="NotSupportedException"></exception>
public Stream OpenWrite()
{
Filters = filters;
if (fullPath != null)
return new FileStream(fullPath, FileMode.OpenOrCreate, FileAccess.Write);
if (stream != null)
return stream;
throw new NotSupportedException();
}
}
public static class Images
{
static readonly Lazy<FilePickerFileType> _FileTypes = new(() =>
public override string ToString()
{
if (Essentials.IsSupported)
{
return FilePickerFileType.Images;
}
else if (OperatingSystem2.IsWindows)
{
GeneralFilePickerFileType fileTypes = new[] { FileEx.PNG, FileEx.JPG, FileEx.JPEG, FileEx.GIF, FileEx.BMP };
return fileTypes;
}
else
{
GeneralFilePickerFileType fileTypes = new[] { FileEx.PNG, FileEx.JPG, FileEx.JPEG, FileEx.GIF };
return fileTypes;
}
});
if (fullPath != null)
return fullPath;
if (@string != null)
return @string;
return base.ToString();
}
/// <inheritdoc cref="FilePickerFileType.Images"/>
public static FilePickerFileType FileTypes => _FileTypes.Value;
/// <inheritdoc cref="PickOptions.Images"/>
public static PickOptions PickOptions => new()
private void Dispose(bool disposing)
{
FileTypes = FileTypes,
};
if (!disposedValue)
{
if (disposing)
{
// TODO: 释放托管状态(托管对象)
stream?.Dispose();
}
// TODO: 释放未托管的资源(未托管的对象)并重写终结器
// TODO: 将大型字段设置为 null
disposedValue = true;
}
}
public void Dispose()
{
// 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}
}
@@ -1,20 +1,34 @@
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Essentials;
namespace System.Application.Services
{
public interface IDeviceInfoPlatformService
{
string Model => string.Empty;
string Model { get; }
string Manufacturer => string.Empty;
string Manufacturer { get; }
string Name => string.Empty;
string Name { get; }
string VersionString => string.Empty;
string VersionString { get; }
DeviceType DeviceType => DeviceType.Unknown;
DeviceType DeviceType { get; }
}
}
namespace System.Application.Services.Implementation
{
public abstract class DeviceInfoPlatformServiceImpl : IDeviceInfoPlatformService
{
public /*virtual*/ string Model => DeviceInfo.Model;
public /*virtual*/ string Manufacturer => DeviceInfo.Manufacturer;
public /*virtual*/ string Name => DeviceInfo.Name;
public /*virtual*/ string VersionString => DeviceInfo.VersionString;
public virtual DeviceType DeviceType => DeviceInfo.DeviceType;
}
}
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Xamarin.Essentials;
using static System.Application.FilePicker2;
@@ -13,7 +14,7 @@ namespace System.Application.Services
public interface IServiceBase
{
protected static void FormatExtensions(IEnumerable<string>? extensions, Action<string> add, bool trimLeadingPeriod = false)
protected static IEnumerable<string> FormatExtensions(IEnumerable<string>? extensions, bool trimLeadingPeriod = false)
{
var hasAtLeastOneType = false;
@@ -21,24 +22,33 @@ namespace System.Application.Services
{
foreach (var extension in extensions)
{
var ext = FileEx.Clean(extension, trimLeadingPeriod);
var ext = Clean(extension, trimLeadingPeriod);
static string Clean(string extension, bool trimLeadingPeriod = false)
{
if (string.IsNullOrWhiteSpace(extension))
return string.Empty;
if (extension.StartsWith('.'))
{
if (!trimLeadingPeriod) return extension;
return extension.TrimStart('.');
}
else
{
if (!trimLeadingPeriod) return "." + extension;
return extension;
}
}
if (!string.IsNullOrWhiteSpace(ext))
{
add(ext);
yield return ext;
hasAtLeastOneType = true;
}
}
}
if (!hasAtLeastOneType)
add("*");
}
protected static List<string> FormatExtensions(IEnumerable<string>? extensions, bool trimLeadingPeriod = false)
{
var list = new List<string>();
FormatExtensions(extensions, list.Add, trimLeadingPeriod);
return list;
yield return "*";
}
}
@@ -55,7 +65,7 @@ namespace System.Application.Services
{
static ISaveFileDialogService? Instance => DI.Get_Nullable<ISaveFileDialogService>();
Task<FileResult?> PlatformSaveAsync(SaveOptions? options);
Task<SaveFileResult?> PlatformSaveAsync(SaveOptions? options);
}
}
}
@@ -2,9 +2,7 @@ using SQLite;
using System.Application.Entities;
using System.Application.Repositories;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using NotNull = System.Diagnostics.CodeAnalysis.NotNullAttribute;
using SQLiteNotNull = SQLite.NotNullAttribute;
using SQLiteTable = SQLite.TableAttribute;
@@ -26,93 +24,33 @@ namespace System.Application.Services.Implementation
if (sharedName == null) return GetId(key);
return $"{key}_{sharedName}_S";
}
public void PlatformClear(string? sharedName)
{
if (sharedName == null)
{
conn.Execute(Sql_Delete_All);
}
else
{
conn.Execute(Sql_Delete_Where_SharedName_Equals, sharedName);
}
conn.Execute(Sql_Delete_Where_SharedName_Equals, sharedName ?? string.Empty);
}
//public void PlatformClear(string? sharedName)
//{
// if (sharedName == null)
// {
// conn.DeleteAll<Entity>();
// }
// else
// {
// var items = conn.Table<Entity>().Where(x => x.SharedName == sharedName).ToArray();
// foreach (var item in items)
// {
// conn.Delete(item);
// }
// }
//}
//public bool PlatformContainsKey(string key, string? sharedName)
//{
// int r;
// if (sharedName == null)
// {
// r = conn.Execute(Sql_Select_SharedName_Where_Key_Equals_And_SharedName_IsNull, GetId(key));
// }
// else
// {
// r = conn.Execute(Sql_Select_SharedName_Where_Key_Equals_And_SharedName_Equals, GetId(key, sharedName), sharedName);
// }
// return r > 0;
//}
public bool PlatformContainsKey(string key, string? sharedName)
{
var id = GetId(key, sharedName);
var item = conn.Table<Entity>().Where(x => x.Id == id && x.SharedName == sharedName).FirstOrDefault();
sharedName ??= string.Empty;
var item = conn.Table<Entity>()
.Where(x => x.Id == id && x.SharedName == sharedName)
.FirstOrDefault();
return item != null;
}
//public T? PlatformGet<T>(string key, T? defaultValue, string? sharedName) where T : notnull, IConvertible
//{
// string? r;
// if (sharedName == null)
// {
// r = conn.ExecuteScalar<string?>(Sql_Select_Value_Where_Key_Equals_And_SharedName_IsNull, GetId(key));
// }
// else
// {
// r = conn.ExecuteScalar<string?>(Sql_Select_Value_Where_Key_Equals_And_SharedName_Equals, GetId(key, sharedName), sharedName);
// }
// if (r == null) return defaultValue;
// var r2 = ConvertibleHelper.Convert<T>(r);
// return r2;
//}
public T? PlatformGet<T>(string key, T? defaultValue, string? sharedName) where T : notnull, IConvertible
{
var id = GetId(key, sharedName);
var item = conn.Table<Entity>().Where(x => x.Id == id && x.SharedName == sharedName).FirstOrDefault();
sharedName ??= string.Empty;
var item = conn.Table<Entity>()
.Where(x => x.Id == id && x.SharedName == sharedName)
.FirstOrDefault();
if (item == null) return defaultValue;
var value = ConvertibleHelper.Convert<T>(item.Value);
return value;
}
//public void PlatformRemove(string key, string? sharedName)
//{
// if (sharedName == null)
// {
// conn.Execute(Sql_Delete_Where_Id_Equals_And_SharedName_IsNull, GetId(key));
// }
// else
// {
// conn.Execute(Sql_Delete_Where_Id_Equals_And_SharedName_Equals, GetId(key, sharedName), sharedName);
// }
//}
public void PlatformRemove(string key, string? sharedName)
{
var id = GetId(key, sharedName);
@@ -132,19 +70,16 @@ namespace System.Application.Services.Implementation
{
Id = id,
Value = value.ToString(CultureInfo.InvariantCulture),
SharedName = sharedName,
SharedName = sharedName ?? string.Empty,
});
}
}
const string TableName = "0984415E";
const string TableName = "1984415E";
const string ColumnName_Id = "0F5E4BAA";
const string ColumnName_Value = "4FC331D7";
const string ColumnName_SharedName = "F6A739AA";
const string Sql_Delete_All =
$"DELETE FROM \"{TableName}\"";
const string Sql_Delete_Where_SharedName_Equals =
$"DELETE FROM \"{TableName}\" WHERE \"{ColumnName_SharedName}\" = ?";
@@ -174,19 +109,18 @@ namespace System.Application.Services.Implementation
[Column(ColumnName_Id)]
[PrimaryKey]
[SQLiteNotNull]
[NotNull, DisallowNull] // C# 8 not null
public string? Id { get; set; }
public string Id { get; set; } = string.Empty;
[Column(ColumnName_Value)]
[SQLiteNotNull]
[NotNull, DisallowNull] // C# 8 not null
public string? Value { get; set; }
public string Value { get; set; } = string.Empty;
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
[Column(ColumnName_SharedName)]
public string? SharedName { get; set; }
[SQLiteNotNull]
public string SharedName { get; set; } = string.Empty;
string DebuggerDisplay() => SharedName == null ? $"{Id}, {Value}" : $"{Id}, {Value}, {SharedName}";
string DebuggerDisplay() => SharedName == string.Empty ? $"{Id}, {Value}" : $"{Id}, {Value}, {SharedName}";
}
}
}
@@ -1,4 +1,4 @@
namespace System.Application.Services
namespace System.Application.Services
{
/// <summary>
/// 通知重要性级别
@@ -1,12 +1,8 @@
namespace System.Application.UI.Adapters
namespace System.Application.UI.Adapters
{
/// <summary>
/// 列表项点击事件参数
/// </summary>
/// <typeparam name="TViewModel"></typeparam>
#pragma warning disable IDE1006 // 命名样式
public interface ItemClickEventArgs<TViewModel>
#pragma warning restore IDE1006 // 命名样式
/// <inheritdoc cref="ItemClickEventArgs{TViewModel}"/>
public interface ItemClickEventArgs
{
/// <summary>
/// 位置
@@ -16,8 +12,21 @@
/// <summary>
/// 当前项
/// </summary>
TViewModel Current { get; }
object Current { get; }
bool Handled { get; set; }
}
/// <summary>
/// 列表项点击事件参数
/// </summary>
/// <typeparam name="TViewModel"></typeparam>
public interface ItemClickEventArgs<TViewModel> : ItemClickEventArgs
{
/// <inheritdoc cref="ItemClickEventArgs.Current"/>
new TViewModel Current { get; }
object ItemClickEventArgs.Current => Current;
}
#pragma warning restore IDE1006 // 命名样式
}
@@ -20,6 +20,6 @@ namespace System.Net.Http
}
}
public override Task<bool> IsConnectedAsync() => MainThread2.InvokeOnMainThreadAsync(() => IsConnected);
//public override Task<bool> IsConnectedAsync() => MainThread2.InvokeOnMainThreadAsync(() => IsConnected);
}
}
+30 -28
View File
@@ -1,5 +1,6 @@
using Microsoft.Extensions.Logging;
using System.Application.Services;
using System.Runtime.CompilerServices;
using System.Text;
namespace System
@@ -21,41 +22,42 @@ namespace System
toast.Show(text, duration);
}
static void ShowLong(string text) => Show(text, ToastLength.Long);
#if DEBUG
[Obsolete("use e.LogAndShowT(..", true)]
public static void Show(Exception e,
string? tag = null, LogLevel level = LogLevel.Error,
string? msg = null, params object?[] args) => e.LogAndShowT(tag, level, "", msg, args);
#endif
/// <summary>
/// 通过 <see cref="Exception"/> 显示 Toast 并纪录日志,传入 <see cref="LogLevel.None"/> 可不写日志
/// 通过 <see cref="Exception"/> 纪录日志并在 Toast 上显示,传入 <see cref="LogLevel.None"/> 可不写日志
/// </summary>
/// <param name="e"></param>
/// <param name="logger"></param>
/// <param name="tag"></param>
/// <param name="level"></param>
/// <param name="msg"></param>
/// <param name="args"></param>
public static void Show(Exception e, string? tag = null, LogLevel level = LogLevel.Error, string? msg = null, params string[] args)
{
if (string.IsNullOrWhiteSpace(tag)) tag = nameof(Toast);
var has_msg = !string.IsNullOrWhiteSpace(msg);
var has_args = args.Any_Nullable();
if (level < LogLevel.None)
{
var logger = Log.CreateLogger(tag);
if (has_msg)
{
if (has_args)
{
logger.Log(level, e, msg!, args);
}
else
{
logger.Log(level, e, msg!);
}
}
else
{
logger.Log(level, e, null);
}
}
/// <param name="memberName"></param>
public static void LogAndShowT(this Exception? e,
string? tag = null, LogLevel level = LogLevel.Error,
[CallerMemberName] string memberName = "",
string? msg = null, params object?[] args)
=> ExceptionExtensions.LogAndShow(e,
ShowLong,
string.IsNullOrWhiteSpace(tag) ? nameof(Toast) : tag, level,
memberName,
msg, args);
var text = ExceptionExtensions.GetAllMessageCore(e, has_msg, has_args, msg, args);
Show(text, ToastLength.Long);
}
/// <inheritdoc cref="LogAndShowT(Exception, string?, LogLevel, string, string?, string[])"/>
public static void LogAndShowT(this Exception? e,
ILogger logger, LogLevel level = LogLevel.Error,
[CallerMemberName] string memberName = "",
string? msg = null, params object?[] args) => ExceptionExtensions.LogAndShow(e,
ShowLong,
logger, level,
memberName, msg, args);
}
}
@@ -1,4 +1,5 @@
using System.Application.Models;
using System.Application.Models;
using System.Diagnostics.CodeAnalysis;
namespace System.Application.Models
{
@@ -15,7 +16,7 @@ namespace System
{
public static class ExplicitHasValueExtensions
{
public static bool HasValue(this IExplicitHasValue? obj)
public static bool HasValue([NotNullWhen(true)] this IExplicitHasValue? obj)
{
return obj != null && obj.ExplicitHasValue();
}
+126
View File
@@ -0,0 +1,126 @@
namespace System.Application
{
public static class OSNames
{
const string WindowsDesktopBridge = "Windows Desktop Bridge";
const string Android = "Android";
public enum Value : byte
{
/// <summary>
/// Universal Windows Platform / 通用 Windows 平台
/// </summary>
UWP = 1,
/// <summary>
/// Windows 桌面桥应用
/// <para>桌面桥应用是使用桌面桥转换为通用 Windows 平台 (UWP) 应用的 Windows 桌面应用程序。 转换后,将以面向 Windows 10 桌面版的 UWP 应用包(.appx 或 .appxbundle)的形式打包、维护和部署 Windows 桌面应用程序。</para>
/// </summary>
WindowsDesktopBridge,
/// <summary>
/// 桌面 Win32 应用
/// </summary>
Windows,
/// <summary>
/// 适用于 Android™ 的 Windows 子系统
/// </summary>
WSA,
/// <summary>
/// 未知设备类型的 Android
/// </summary>
AndroidUnknown,
/// <summary>
/// https://www.apple.com.cn/ipados
/// </summary>
iPadOS,
/// <summary>
/// https://developer.apple.com/cn/ios
/// </summary>
iOS,
/// <summary>
/// https://www.apple.com.cn/macos
/// </summary>
macOS,
/// <summary>
/// https://developer.apple.com/cn/tvos
/// </summary>
tvOS,
/// <summary>
/// https://www.apple.com.cn/watchos
/// </summary>
watchOS,
/// <summary>
/// GNU/Linux
/// </summary>
Linux,
/// <summary>
/// Android 手机
/// </summary>
AndroidPhone,
/// <summary>
/// Android 平板
/// </summary>
AndroidTablet,
/// <summary>
/// Android 桌面端
/// </summary>
AndroidDesktop,
/// <summary>
/// https://developer.android.google.cn/training/tv
/// </summary>
AndroidTV,
/// <summary>
/// https://developer.android.google.cn/training/wearables
/// </summary>
AndroidWatch,
/// <summary>
/// Android 模拟器
/// </summary>
AndroidVirtual,
}
public static string ToDisplayName(this Value value) => value == default ? string.Empty :
(value.IsAndroid() ? Android :
(value switch
{
Value.WindowsDesktopBridge => WindowsDesktopBridge,
_ => value.ToString(),
}));
public static Value Parse(string value)
{
if (Enum.TryParse<Value>(value, true, out var valueEnum)) return valueEnum;
if (string.Equals(value, WindowsDesktopBridge, StringComparison.OrdinalIgnoreCase))
return Value.WindowsDesktopBridge;
return default;
}
public static bool IsAndroid(this Value value) => value switch
{
Value.WSA or
Value.AndroidUnknown or
Value.AndroidPhone or
Value.AndroidTablet or
Value.AndroidDesktop or
Value.AndroidTV or
Value.AndroidWatch or
Value.AndroidVirtual => true,
_ => false,
};
}
}
@@ -1,4 +1,4 @@
using System.Application.Entities;
using System.Application.Entities;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
@@ -119,7 +119,7 @@ namespace System.Application.Repositories
/// <exception cref="ArgumentNullException">
/// 集合 或 <paramref name="predicate" /> 为 <see langword="null" />
/// </exception>
Task<TEntity?> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate);
Task<TEntity?> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellation = default);
#endregion
}
@@ -22,7 +22,7 @@ namespace System.Application.Services
string? requestUri,
Func<HttpRequestMessage> requestFactory,
string? accept,
bool enableForward,
//bool enableForward,
CancellationToken cancellationToken,
Action<HttpResponseMessage>? handlerResponse = null,
Action<HttpResponseMessage>? handlerResponseByIsNotSuccessStatusCode = null,
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
@@ -9,7 +9,7 @@ namespace System.Application.Services.Implementation
/// <inheritdoc cref="IModelValidator"/>
public class ModelValidator : IModelValidator
{
static readonly MethodInfo matchValidateMethod = typeof(ModelValidator).GetMethod(nameof(MatchValidate), BindingFlags.NonPublic | BindingFlags.Static);
static readonly MethodInfo matchValidateMethod = typeof(ModelValidator).GetMethod(nameof(MatchValidate), BindingFlags.NonPublic | BindingFlags.Static)!;
static readonly IDictionary<Type, object> validators = new Dictionary<Type, object>();
public static void AddColumnValidate<T>(Func<T, string?> validate)
+2
View File
@@ -29,5 +29,7 @@ namespace System
public const string DateCN2 = "yyyy年M月d日";
public const string RFC1123 = "r";
public const string File = "yyyy-MM-dd HHmmssfffffff";
}
}
@@ -2,56 +2,195 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using System.Text;
using Microsoft.Extensions.Logging;
// ReSharper disable once CheckNamespace
namespace System
{
public static class ExceptionExtensions
{
static bool JavaInterop => OperatingSystem2.IsAndroid;
/// <summary>
/// 获取异常是否为已知类型,通常不为 <see cref="ExceptionKnownType.Unknown"/> 的异常不需要纪录日志
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
public static ExceptionKnownType GetKnownType(this Exception e)
{
if (e is TaskCanceledException)
{
return ExceptionKnownType.TaskCanceled;
}
else if (e is OperationCanceledException)
{
return ExceptionKnownType.OperationCanceled;
}
if (JavaInterop)
{
var typeName = e.GetType().FullName;
switch (typeName)
{
case "Java.Security.Cert.CertificateNotYetValidException":
return ExceptionKnownType.CertificateNotYetValid;
case "Java.IO.IOException":
if (e.Message == "Canceled")
{
return ExceptionKnownType.Canceled;
}
break;
}
}
e = e.InnerException;
if (e != null)
{
return GetKnownType(e);
}
return ExceptionKnownType.Unknown;
}
/// <summary>
/// 是否为取消操作异常
/// </summary>
/// <param name="exception"></param>
/// <param name="value"></param>
/// <returns></returns>
public static bool IsCanceledException(this Exception e)
public static bool IsCanceledException(this ExceptionKnownType value)
=> value == ExceptionKnownType.Canceled ||
value == ExceptionKnownType.OperationCanceled ||
value == ExceptionKnownType.TaskCanceled;
///// <summary>
///// 是否为取消操作异常
///// </summary>
///// <param name="exception"></param>
///// <returns></returns>
//[Obsolete("use GetKnownType", true)]
//public static bool IsCanceledException(this Exception e) => GetKnownType(e).IsCanceledException();
/// <summary>
/// 通过 <see cref="Exception"/> 纪录日志并在 UI 上显示,传入 <see cref="LogLevel.None"/> 可不写日志
/// </summary>
/// <param name="e"></param>
/// <param name="show"></param>
/// <param name="logger"></param>
/// <param name="tag"></param>
/// <param name="level"></param>
/// <param name="memberName"></param>
/// <param name="msg"></param>
/// <param name="args"></param>
public static void LogAndShow(Exception? e,
Action<string>? show,
string tag, LogLevel level = LogLevel.Error,
string memberName = "",
string? msg = null, params object?[] args) => LogAndShowCore(e, show, tag, logger: null, level, memberName, msg, args);
/// <inheritdoc cref="LogAndShow(Exception, Action{string}?, string, LogLevel, string?,string, string[])"/>
public static void LogAndShow(Exception? e,
Action<string>? show,
ILogger? logger, LogLevel level = LogLevel.Error,
string memberName = "",
string? msg = null, params object?[] args) => LogAndShowCore(e, show, tag: null, logger, level, memberName, msg, args);
static void LogAndShowCore(Exception? e,
Action<string>? show,
string? tag = null, ILogger? logger = null, LogLevel level = LogLevel.Error,
string memberName = "",
string? msg = null, params object?[] args)
{
if (e is TaskCanceledException || e is OperationCanceledException)
bool has_msg = !string.IsNullOrWhiteSpace(msg);
if (!has_msg)
{
return true;
}
if (OperatingSystem2.IsAndroid)
{
if (e.Message == "Canceled" && e.GetType().FullName == "Java.IO.IOException")
if (!string.IsNullOrWhiteSpace(memberName))
{
return true;
msg = $"{memberName} Error";
has_msg = true;
}
}
return false;
var has_args = args.Any_Nullable();
var has_e = e != null;
if (has_e)
{
var knownType = e!.GetKnownType();
if (knownType != ExceptionKnownType.Unknown) level = LogLevel.None;
}
var has_log_level = level < LogLevel.None;
if (has_log_level)
{
if (logger == null && tag != null)
{
logger = Log.CreateLogger(tag);
}
if (logger != null)
{
if (has_args)
{
logger.Log(level, e, msg!, args);
}
else
{
logger.Log(level, e, msg!);
}
}
}
show?.Invoke(GetShowMsg());
string GetShowMsg()
{
if (has_e) return GetAllMessageCore(e!, has_msg, has_args, msg, args);
if (has_msg)
{
if (has_args)
{
return msg!.Format(args);
}
else
{
return msg!;
}
}
return "";
}
}
/// <summary>
/// 获取异常中所有错误信息
/// </summary>
/// <param name="e">当前捕获的异常</param>
/// <param name="has_msg"></param>
/// <param name="has_args"></param>
/// <param name="msg">可选的消息,将写在第一行</param>
/// <param name="args">可选的消息参数</param>
/// <returns></returns>
public static string GetAllMessage(this Exception e, string? msg = null, params string[] args)
public static string GetAllMessage(this Exception e, string? msg = null, params object?[] args)
{
var has_msg = !string.IsNullOrWhiteSpace(msg);
var has_args = args.Any_Nullable();
return GetAllMessageCore(e, has_msg, has_args, msg, args);
}
/// <inheritdoc cref="GetAllMessage(Exception, string?, string[])" />
public static string GetAllMessageCore(Exception e, bool has_msg, bool has_args, string? msg = null, params string[] args)
/// <inheritdoc cref="GetAllMessage(Exception, string?, string[])"/>
static string GetAllMessageCore(Exception e,
bool has_msg, bool has_args,
string? msg = null, params object?[] args)
{
StringBuilder sb = new();
if (has_msg)
{
if (has_args)
{
sb.AppendFormat(msg, args);
try
{
sb.AppendFormat(msg, args);
}
catch
{
sb.Append(msg);
foreach (var item in args)
{
sb.Append(' ');
sb.Append(item);
}
}
sb.AppendLine();
}
else
@@ -59,31 +198,45 @@ namespace System
sb.AppendLine(msg!);
}
}
var e_str = e.ToString();
sb.AppendLine(e_str);
var stackTrace = e.StackTrace;
if (!string.IsNullOrWhiteSpace(stackTrace) &&
!e_str.Contains(stackTrace))
{
sb.AppendLine(stackTrace);
}
var exception = e;
ushort i = 0;
while (exception != null && i++ < byte.MaxValue)
{
var exception_message = exception.Message;
if (!string.IsNullOrWhiteSpace(exception_message) &&
!e_str.Contains(exception_message))
if (!string.IsNullOrWhiteSpace(exception_message))
{
sb.AppendLine(exception_message);
}
exception = exception.InnerException;
}
var text = sb.ToString().Trim();
return text;
}
}
/// <summary>
/// 异常已知类型,通常不为 <see cref="Unknown"/> 的异常不需要纪录日志
/// </summary>
public enum ExceptionKnownType : byte
{
Unknown,
/// <summary>
/// 取消操作异常
/// </summary>
Canceled,
/// <summary>
/// 证书时间验证错误异常,通常为本地时间不正确导致 SSL 握手失败或服务端证书失效
/// </summary>
CertificateNotYetValid,
/// <inheritdoc cref="OperationCanceledException"/>
OperationCanceled,
/// <inheritdoc cref="TaskCanceledException"/>
TaskCanceled,
}
}
@@ -1,24 +1,51 @@
using System.Common;
using System.Common;
// ReSharper disable once CheckNamespace
namespace System
{
public static class GuidExtensions
{
// N 32 digits:
// 00000000000000000000000000000000
// D 32 digits separated by hyphens:
// 00000000-0000-0000-0000-000000000000
// B 32 digits separated by hyphens, enclosed in braces:
// {00000000-0000-0000-0000-000000000000}
// P 32 digits separated by hyphens, enclosed in parentheses:
// (00000000-0000-0000-0000-000000000000)
// X Four hexadecimal values enclosed in braces, where the fourth value is a subset of eight hexadecimal values that is also enclosed in braces:
// {0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
// S Base64Url ShortGuid
/// <summary>
/// 返回 <see cref="Guid"/> 结构的此实例值的字符串表示形式(格式N)
/// 返回 <see cref="Guid"/> 结构的此实例值的字符串表示形式,格式:N
/// </summary>
/// <param name="guid"></param>
/// <returns></returns>
public static string ToStringN(this Guid guid) => guid.ToString(Constants.N);
/// <summary>
/// 返回 <see cref="Guid"/> 结构的此实例值的字符串表示形式(格式N)
/// 返回 <see cref="Guid"/> 结构的此实例值的字符串表示形式,格式:N
/// </summary>
/// <param name="guid"></param>
/// <returns></returns>
public static string? ToStringN(this Guid? guid) => guid.HasValue ? guid.Value.ToStringN() : null;
/// <summary>
/// 返回 <see cref="Guid"/> 结构的此实例值的字符串表示形式,格式:<see cref="ShortGuid"/>
/// </summary>
/// <param name="guid"></param>
/// <returns></returns>
public static string ToStringS(this Guid guid) => ShortGuid.Encode(guid);
/// <summary>
/// 返回 <see cref="Guid"/> 结构的此实例值的字符串表示形式,格式:<see cref="ShortGuid"/>
/// </summary>
/// <param name="guid"></param>
/// <returns></returns>
public static string? ToStringS(this Guid? guid) => guid.HasValue ? guid.Value.ToStringS() : null;
static bool TryParseGuid_Format_D(string? input, out Guid result) => Guid.TryParse(input, out result);
static bool TryParseGuid_Format_N(string? input, out Guid result) => Guid.TryParseExact(input, Constants.N, out result);
@@ -90,10 +90,6 @@ namespace System
return stream.ReadStringInternalDynamic(Encoding.UTF8, '\0');
}
static readonly Lazy<Encoding> _UTF8NoBOM = new(() => new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true));
internal static Encoding UTF8NoBOM => _UTF8NoBOM.Value;
const int DefaultBufferSize = 1024;
public static StreamWriter GetWriter(this Stream stream, Encoding? encoding = null, int bufferSize = -1, bool leaveOpen = false)
@@ -108,7 +104,7 @@ namespace System
{
if (encoding == null)
{
encoding = UTF8NoBOM;
encoding = EncodingCache.UTF8NoBOM;
}
if (bufferSize == -1)
{
+4 -10
View File
@@ -109,19 +109,13 @@ namespace System
public const string XML = ".xml";
public static string Clean(string extension, bool trimLeadingPeriod = false)
{
if (string.IsNullOrWhiteSpace(extension))
return string.Empty;
public const string PFX = ".pfx";
extension = extension.TrimStart('*');
extension = extension.TrimStart('.');
public const string CER = ".cer";
if (!trimLeadingPeriod)
extension = "." + extension;
public const string DAT = ".dat";
return extension;
}
public const string maFile = ".maFile";
public static bool IsSupportedTextReader(string extension) =>
string.Equals(extension, JSON, StringComparison.OrdinalIgnoreCase) ||
+14
View File
@@ -0,0 +1,14 @@
// 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/corefx/blob/master/src/Common/src/CoreLib/System/IO/EncodingCache.cs
using System.Text;
namespace System.IO
{
public static class EncodingCache
{
public static readonly Encoding UTF8NoBOM = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
}
}
+38
View File
@@ -167,6 +167,41 @@ namespace System
IOPath.getAppDataDirectory = getAppDataDirectory;
IOPath.getCacheDirectory = getCacheDirectory;
}
protected static void InitFileSystemWithMigrations(
string destAppDataPath, string destCachePath,
string sourceAppDataPath, string sourceCachePath)
{
var paths = new[] { destAppDataPath, destCachePath, };
var dict_paths = paths.ToDictionary(x => x, Directory.Exists);
if (dict_paths.Values.All(x => !x))
{
var old_paths = new[] { sourceAppDataPath, sourceCachePath, };
if (old_paths.All(Directory.Exists)) // 迁移之前根目录上的文件夹
{
for (int i = 0; i < old_paths.Length; i++)
{
var path = paths[i];
var old_path = old_paths[i];
Directory.Move(old_path, path);
dict_paths[path] = true;
}
}
}
foreach (var item in dict_paths)
{
if (!item.Value)
{
Directory.CreateDirectory(item.Key);
}
}
InitFileSystem(GetAppDataDirectory, GetCacheDirectory);
string GetAppDataDirectory() => destAppDataPath;
string GetCacheDirectory() => destCachePath;
}
}
/// <summary>
@@ -413,5 +448,8 @@ namespace System
var t1 = Math.Round(t, 2);
return Convert.ToInt32(t1 * 100);
}
public const char UnixDirectorySeparatorChar = '/';
public const char WinDirectorySeparatorChar = '\\';
}
}
+2
View File
@@ -82,5 +82,7 @@ namespace System
public const string All = "*/*";
public const string _7Z = "application/x-7z-compressed";
public const string CER = "application/x-x509-ca-cert";
}
}
@@ -20,7 +20,7 @@ namespace System.Net.Http
{
request.AllowAutoRedirect = true;
request.MaximumAutomaticRedirections = 1000;
request.Timeout = DefaultTimeoutTotalMilliseconds;
request.Timeout = DefaultTimeoutMilliseconds;
#if NETSTANDARD
// .NET Core 3+ 上已由 HttpClient.DefaultProxy 生效
// https://docs.microsoft.com/zh-cn/dotnet/api/system.net.http.httpclient.defaultproxy?view=net-6.0
@@ -5,11 +5,9 @@ namespace System.Net.Http
/// <summary>
/// 默认超时时间,45 秒
/// </summary>
public static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(45);
static readonly Lazy<int> mDefaultTimeoutTotalMilliseconds = new(() => DefaultTimeout.TotalMilliseconds.ToInt32());
public static readonly TimeSpan DefaultTimeout = TimeSpan.FromMilliseconds(DefaultTimeoutMilliseconds);
/// <inheritdoc cref="DefaultTimeout"/>
public static int DefaultTimeoutTotalMilliseconds => mDefaultTimeoutTotalMilliseconds.Value;
public const int DefaultTimeoutMilliseconds = 45000;
}
}
+20 -13
View File
@@ -30,8 +30,25 @@ namespace System.Net.Sockets
/// <summary>
/// 检查指定的端口是否被占用
/// </summary>
/// <param name="address"></param>
/// <param name="port"></param>
/// <returns></returns>
public static bool IsUsePort(IPAddress address, int port)
{
try
{
var listener = new TcpListener(address, port);
listener.Start();
listener.Stop();
return false;
}
catch
{
return true;
}
}
/// <inheritdoc cref="IsUsePort(IPAddress, int)"/>
public static bool IsUsePort(int port)
{
try
@@ -42,17 +59,7 @@ namespace System.Net.Sockets
}
catch
{
try
{
var listener = new TcpListener(IPAddress.Loopback, port);
listener.Start();
listener.Stop();
return false;
}
catch
{
return true;
}
return IsUsePort(IPAddress.Loopback, port);
}
}
@@ -62,7 +69,7 @@ namespace System.Net.Sockets
/// <param name="port"></param>
/// <returns></returns>
#if NET5_0_OR_GREATER
[SupportedOSPlatform("Windows")]
[SupportedOSPlatform("Windows7.0")]
#endif
public static Process? GetProcessByTcpPort(ushort port)
=> GetAllTcpConnections().FirstOrDefault(x => x.LocalPort == port)?.Process;
@@ -81,7 +88,7 @@ namespace System.Net.Sockets
/// is insufficient memory to satisfy the request.
/// </exception>
#if NET5_0_OR_GREATER
[SupportedOSPlatform("Windows")]
[SupportedOSPlatform("Windows7.0")]
#endif
public static List<TcpProcessRecord> GetAllTcpConnections()
{
+17
View File
@@ -1,6 +1,7 @@
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Properties;
namespace System
{
@@ -80,5 +81,21 @@ namespace System
p.UseShellExecute = useShellExecute;
return Process.Start(p);
}
public static bool OpenCoreByProcess(string url, Action<string>? onError = null)
{
try
{
Start(url, useShellExecute: true);
return true;
}
catch (Win32Exception e)
{
// [Win32Exception: 找不到应用程序] 39次报告
// 疑似缺失没有默认浏览器设置会导致此异常,可能与杀毒软件有关
onError?.Invoke(SR.OpenCoreByProcess_Win32Exception_.Format(Convert.ToString(e.NativeErrorCode, 16)));
return false;
}
}
}
}
+10 -1
View File
@@ -19,7 +19,7 @@ namespace System.Properties {
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class SR {
@@ -231,6 +231,15 @@ namespace System.Properties {
}
}
/// <summary>
/// 查找类似 打开 Web 链接失败 0x{0},请设置系统默认浏览器后再尝试 的本地化字符串。
/// </summary>
internal static string OpenCoreByProcess_Win32Exception_ {
get {
return ResourceManager.GetString("OpenCoreByProcess_Win32Exception_", resourceCulture);
}
}
/// <summary>
/// 查找类似 她 的本地化字符串。
/// </summary>
+4
View File
@@ -205,4 +205,8 @@
<value>Unsupported mobile phone number segment ({0})</value>
<comment>Comment=;Author=MicrosoftTranslator</comment>
</data>
<data name="OpenCoreByProcess_Win32Exception_" xml:space="preserve">
<value>Open web link fails 0x{0}, please set the system default browser before trying</value>
<comment>Comment=;Author=MicrosoftTranslator</comment>
</data>
</root>
+4
View File
@@ -205,4 +205,8 @@
<value>Segmento de número de teléfono móvil no compatible ({0})</value>
<comment>Comment=;Author=MicrosoftTranslator</comment>
</data>
<data name="OpenCoreByProcess_Win32Exception_" xml:space="preserve">
<value>Abrir enlace web falla 0x{0}, configure el navegador predeterminado del sistema antes de intentarlo</value>
<comment>Comment=;Author=MicrosoftTranslator</comment>
</data>
</root>
+4
View File
@@ -205,4 +205,8 @@
<value>Segmento di numero di cellulare non supportato ({0})</value>
<comment>Comment=;Author=MicrosoftTranslator</comment>
</data>
<data name="OpenCoreByProcess_Win32Exception_" xml:space="preserve">
<value>Il collegamento Web aperto non riesce 0x{0}, impostare il browser predefinito del sistema prima di provare</value>
<comment>Comment=;Author=MicrosoftTranslator</comment>
</data>
</root>
+4
View File
@@ -205,4 +205,8 @@
<value>サポートされていない携帯電話番号セグメント ({0})</value>
<comment>Comment=;Author=MicrosoftTranslator</comment>
</data>
<data name="OpenCoreByProcess_Win32Exception_" xml:space="preserve">
<value>Web リンクを開くと 0x {0}に失敗しました</value>
<comment>Comment=;Author=MicrosoftTranslator</comment>
</data>
</root>
+4
View File
@@ -205,4 +205,8 @@
<value>지원되지 않는 휴대폰 번호 세그먼트({0})</value>
<comment>Comment=;Author=MicrosoftTranslator</comment>
</data>
<data name="OpenCoreByProcess_Win32Exception_" xml:space="preserve">
<value>웹 링크를 열지 못한 경우 0x{0} 시스템 기본 브라우저를 설정한 다음 다시 시도하십시오</value>
<comment>Comment=;Author=MicrosoftTranslator</comment>
</data>
</root>
+3
View File
@@ -175,6 +175,9 @@
<value>Collection was of a fixed size.</value>
<comment>https://github.com/dotnet/runtime/blob/v5.0.0-rc.1.20451.14/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx#L2893</comment>
</data>
<data name="OpenCoreByProcess_Win32Exception_" xml:space="preserve">
<value>打开 Web 链接失败 0x{0},请设置系统默认浏览器后再尝试</value>
</data>
<data name="She" xml:space="preserve">
<value>她</value>
</data>
+4
View File
@@ -205,4 +205,8 @@
<value>Неподдерживаемый сегмент номера мобильного телефона ({0})</value>
<comment>Comment=;Author=MicrosoftTranslator</comment>
</data>
<data name="OpenCoreByProcess_Win32Exception_" xml:space="preserve">
<value>Открытие веб-ссылки завершается неудачей {0} 0x, установите системный браузер по умолчанию и повторите попытку</value>
<comment>Comment=;Author=MicrosoftTranslator</comment>
</data>
</root>
@@ -205,4 +205,8 @@
<value>不受支援的手機號碼號段({0})</value>
<comment>Comment=;Author=MicrosoftTranslator</comment>
</data>
<data name="OpenCoreByProcess_Win32Exception_" xml:space="preserve">
<value>打開 Web 連結失敗 0x{0},請設置系統預設瀏覽器後再嘗試</value>
<comment>Comment=;Author=MicrosoftTranslator</comment>
</data>
</root>
@@ -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.6.3";
public const string Version = "2.6.5";
//public const string InfoVersion = Version + "-beta";
}
+28
View File
@@ -21,6 +21,7 @@ using static System.Serializable;
using SJsonSerializer = System.Text.Json.JsonSerializer;
using SJsonSerializerOptions = System.Text.Json.JsonSerializerOptions;
using SJsonIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition;
using System.Threading.Tasks;
namespace System
{
@@ -159,6 +160,22 @@ namespace System
public static byte[] SMP(Type type, object value, CancellationToken cancellationToken = default)
=> MessagePackSerializer.Serialize(type, value, options: lz4Options, cancellationToken: cancellationToken);
/// <inheritdoc cref="SMP{T}(T, CancellationToken)"/>
public static void SMP<T>(Stream stream, T value, CancellationToken cancellationToken = default)
=> MessagePackSerializer.Serialize(stream, value, options: lz4Options, cancellationToken: cancellationToken);
/// <inheritdoc cref="SMP{T}(T, CancellationToken)"/>
public static void SMP(Type type, Stream stream, object value, CancellationToken cancellationToken = default)
=> MessagePackSerializer.Serialize(type, stream, value, options: lz4Options, cancellationToken: cancellationToken);
/// <inheritdoc cref="SMP{T}(T, CancellationToken)"/>
public static Task SMPAsync<T>(Stream stream, T value, CancellationToken cancellationToken = default)
=> MessagePackSerializer.SerializeAsync(stream, value, options: lz4Options, cancellationToken: cancellationToken);
/// <inheritdoc cref="SMP{T}(T, CancellationToken)"/>
public static Task SMPAsync(Type type, Stream stream, object value, CancellationToken cancellationToken = default)
=> MessagePackSerializer.SerializeAsync(type, stream, value, options: lz4Options, cancellationToken: cancellationToken);
/// <summary>
/// (Serialize)MessagePack 序列化 + Base64Url Encode
/// </summary>
@@ -240,6 +257,17 @@ namespace System
public static object? DMP(Type type, Stream buffer, CancellationToken cancellationToken = default)
=> MessagePackSerializer.Deserialize(type, buffer, options: lz4Options, cancellationToken: cancellationToken);
/// <inheritdoc cref="DMP{T}(Stream, CancellationToken)"/>
public static async ValueTask<T?> DMPAsync<T>(Stream buffer, CancellationToken cancellationToken = default)
{
var r = await MessagePackSerializer.DeserializeAsync<T>(buffer, options: lz4Options, cancellationToken: cancellationToken);
return r;
}
/// <inheritdoc cref="DMP{T}(Stream, CancellationToken)"/>
public static ValueTask<object?> DMPAsync(Type type, Stream buffer, CancellationToken cancellationToken = default)
=> MessagePackSerializer.DeserializeAsync(type, buffer, options: lz4Options, cancellationToken: cancellationToken);
/// <summary>
/// (Deserialize)MessagePack 反序列化 + Base64Url Decode
/// </summary>
+428
View File
@@ -0,0 +1,428 @@
// MIT License
// Copyright(c) 2007 Dave Transom
// https://github.com/AigioL/CSharpVitamins.ShortGuid/blob/master/CSharpVitamins.ShortGuid/ShortGuid.cs
// https://github.com/csharpvitamins/CSharpVitamins.ShortGuid/blob/master/CSharpVitamins.ShortGuid/ShortGuid.cs
using System.Diagnostics;
#if !NET40
using gfoidl.Base64;
#endif
namespace System
{
/// <summary>
/// A convenience wrapper struct for dealing with URL-safe Base64 encoded globally unique identifiers (GUID),
/// making a shorter string value (22 vs 36 characters long).
/// </summary>
/// <remarks>
/// What is URL-safe Base64? That's just a Base64 string with well known special characters replaced (/, +)
/// or removed (==).
///
/// <para>NB: As of version 2.0.0, <see cref="Decode(string)"/> performs a sanity check when decoding
/// strings to ensure they haven't been tampered with, i.e. allowing the end of a Base64 string to be tweaked
/// where it still produces that same byte array to create the underlying Guid. Effectively there is "unused
/// space" in the Base64 string which is ignored, but will now result in an <see cref="FormatException"/> being
/// thrown.</para>
///
/// <para>ShortGuid will never produce an invalid string, however if one is supplied it, could result in an
/// unintended collision where multiple URL-safe Base64 strings can point to the same Guid. To avoid this
/// uncertainty, a round-trip check is performed to ensure a 1-1 match with the input string.</para>
///
/// <para>Stick with version 1.1.0 if you require the old behaviour with opt-in strict parsing.</para>
/// </remarks>
[DebuggerDisplay("{Value}")]
public struct ShortGuid
{
/// <summary>
/// A read-only instance of the ShortGuid struct whose value is guaranteed to be all zeroes i.e. equivalent
/// to <see cref="Guid.Empty"/>.
/// </summary>
public static readonly ShortGuid Empty = new(Guid.Empty);
public const int StringLength = 22;
readonly Guid underlyingGuid;
readonly string encodedString;
/// <summary>
/// Creates a new instance with the given URL-safe Base64 encoded string.
/// <para>See also <seealso cref="TryParse(string, out ShortGuid)"/> which will try to coerce the
/// the value from URL-safe Base64 or normal Guid string.</para>
/// </summary>
/// <param name="value">A 22 character URL-safe Base64 encoded string to decode.</param>
public ShortGuid(string value)
{
encodedString = value;
underlyingGuid = Decode(value);
}
/// <summary>
/// Creates a new instance with the given <see cref="System.Guid"/>.
/// </summary>
/// <param name="guid">The <see cref="System.Guid"/> to encode.</param>
public ShortGuid(Guid guid)
{
encodedString = Encode(guid);
underlyingGuid = guid;
}
/// <summary>
/// Gets the underlying <see cref="System.Guid"/> for the encoded ShortGuid.
/// </summary>
public Guid Guid => underlyingGuid;
/// <summary>
/// Gets the encoded string value of the <see cref="Guid"/> as a URL-safe Base64 string.
/// </summary>
public string Value => encodedString;
/// <summary>
/// Returns the encoded URL-safe Base64 string.
/// </summary>
/// <returns></returns>
public override string ToString() => encodedString;
/// <summary>
/// Returns a value indicating whether this instance and a specified object represent the same type and value.
/// <para>Compares for equality against other string, Guid and ShortGuid types.</para>
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object obj)
{
if (obj is ShortGuid shortGuid)
{
return underlyingGuid.Equals(shortGuid.underlyingGuid);
}
if (obj is Guid guid)
{
return underlyingGuid.Equals(guid);
}
if (obj is string str)
{
// Try a ShortGuid string.
if (TryDecode(str, out guid))
return underlyingGuid.Equals(guid);
// Try a guid string.
if (Guid.TryParse(str, out guid))
return underlyingGuid.Equals(guid);
}
return false;
}
/// <summary>
/// Returns the hash code for the underlying <see cref="System.Guid"/>.
/// </summary>
/// <returns></returns>
public override int GetHashCode() => underlyingGuid.GetHashCode();
/// <summary>
/// Initialises a new instance of a ShortGuid using <see cref="Guid.NewGuid()"/>.
/// <para>Equivalent of calling: <code>`new ShortGuid(Guid.NewGuid())`</code></para>
/// </summary>
/// <returns></returns>
public static ShortGuid NewGuid() => new(Guid.NewGuid());
/// <summary>
/// Encodes the given value as an encoded ShortGuid string. The encoding is similar to Base64, with
/// some non-URL safe characters replaced, and padding removed, resulting in a 22 character string.
/// </summary>
/// <param name="value">Any valid <see cref="System.Guid"/> string.</param>
/// <returns>A 22 character ShortGuid URL-safe Base64 string.</returns>
public static string Encode(string value)
{
var guid = new Guid(value);
return Encode(guid);
}
/// <summary>
/// Encodes the given <see cref="System.Guid"/> as an encoded ShortGuid string. The encoding is
/// similar to Base64, with some non-URL safe characters replaced, and padding removed, resulting
/// in a 22 character string.
/// </summary>
/// <param name="guid">The <see cref="System.Guid"/> to encode.</param>
/// <returns>A 22 character ShortGuid URL-safe Base64 string.</returns>
public static string Encode(Guid guid)
{
#if NET40
string encoded = Convert.ToBase64String(guid.ToByteArray());
encoded = encoded
.Replace("/", "_")
.Replace("+", "-");
return encoded.Substring(0, StringLength);
#else
return Base64.Url.Encode(guid.ToByteArray());
#endif
}
/// <summary>
/// Decodes the given value from a 22 character URL-safe Base64 string to a <see cref="System.Guid"/>.
/// <para>Supports: ShortGuid format only.</para>
/// <para>See also <seealso cref="TryDecode(string, out Guid)"/> or <seealso cref="TryParse(string, out Guid)"/>.</para>
/// </summary>
/// <param name="value">A 22 character URL-safe Base64 encoded string to decode.</param>
/// <returns>A new <see cref="System.Guid"/> instance from the parsed string.</returns>
/// <exception cref="FormatException">
/// If <paramref name="value"/> is not a valid Base64 string (<seealso cref="Convert.FromBase64String(string)"/>)
/// or if the decoded guid doesn't strictly match the input <paramref name="value"/>.
/// </exception>
public static Guid Decode(string value) => DecodeCore(value);
static Guid DecodeCore(string? value)
{
// avoid parsing larger strings/blobs
if (value?.Length != StringLength)
{
throw new ArgumentException(
$"A ShortGuid must be exactly 22 characters long. Received a {value?.Length ?? 0} character string.",
paramName: nameof(value)
);
}
#if NET40
string base64 = value
.Replace("_", "/")
.Replace("-", "+") + "==";
byte[] blob = Convert.FromBase64String(base64);
#else
byte[] blob = Base64.Url.Decode(value.AsSpan());
#endif
var guid = new Guid(blob);
var sanityCheck = Encode(guid);
if (sanityCheck != value)
{
throw new FormatException(
$"Invalid strict ShortGuid encoded string. The string '{value}' is valid URL-safe Base64, " +
$"but failed a round-trip test expecting '{sanityCheck}'."
);
}
return guid;
}
/// <summary>
/// <para>Supports ShortGuid format only.</para>
/// <para>Attempts to decode the given value from a 22 character URL-safe Base64 string to
/// a <see cref="System.Guid"/>.</para>
/// <para>The difference between TryParse and TryDecode:</para>
/// <list type="number">
/// <item>
/// <term><see cref="TryParse(string, out ShortGuid)"/></term>
/// <description>Supports: Guid &amp; ShortGuid;</description>
/// <description>Tries to parse first as a <see cref="ShortGuid"/>, then as a
/// <see cref="System.Guid"/>, outputs the <see cref="ShortGuid"/> instance.</description>
/// </item>
/// <item>
/// <term><see cref="TryParse(string, out Guid)"/></term>
/// <description>Supports: Guid &amp; ShortGuid;</description>
/// <description>Tries to parse first as a <see cref="ShortGuid"/>, then as a
/// <see cref="System.Guid"/>, outputs the underlying <see cref="System.Guid"/>.</description>
/// </item>
/// <item>
/// <term><see cref="TryDecode(string, out Guid)"/></term>
/// <description>Supports: ShortGuid;</description>
/// <description>Tries to decode a 22 character URL-safe Base64 string as a
/// <see cref="ShortGuid"/> only, but outputs the result as a <see cref="System.Guid"/> - this method.</description>
/// </item>
/// </list>
/// </summary>
/// <param name="value">The ShortGuid encoded string to decode.</param>
/// <param name="guid">A new <see cref="System.Guid"/> instance from the parsed string.</param>
/// <returns>A boolean indicating if the decode was successful.</returns>
public static bool TryDecode(string? value, out Guid guid)
{
try
{
guid = DecodeCore(value);
return true;
}
catch
{
guid = Guid.Empty;
return false;
}
}
/// <summary>
/// <para>Supports ShortGuid &amp; Guid formats.</para>
/// <para>Tries to parse the value from either a 22 character URL-safe Base64 string or
/// a <see cref="System.Guid"/> string, and outputs a <see cref="ShortGuid"/> instance.</para>
/// <para>The difference between TryParse and TryDecode:</para>
/// <list type="number">
/// <item>
/// <term><see cref="TryParse(string, out ShortGuid)"/></term>
/// <description>Supports: Guid &amp; ShortGuid; </description>
/// <description>Tries to parse first as a <see cref="ShortGuid"/>, then as a
/// <see cref="System.Guid"/>, outputs the <see cref="ShortGuid"/> instance - this method.</description>
/// </item>
/// <item>
/// <term><see cref="TryParse(string, out Guid)"/></term>
/// <description>Supports: Guid &amp; ShortGuid;</description>
/// <description>Tries to parse first as a <see cref="ShortGuid"/>, then as a
/// <see cref="System.Guid"/>, outputs the <see cref="System.Guid"/>.</description>
/// </item>
/// <item>
/// <term><see cref="TryDecode(string, out Guid)"/></term>
/// <description>Supports: ShortGuid;</description>
/// <description>Tries to decode a 22 character URL-safe Base64 string as a
/// <see cref="ShortGuid"/> only, but outputs the result as a <see cref="System.Guid"/>.</description>
/// </item>
/// </list>
/// </summary>
/// <param name="value">The ShortGuid encoded string or string representation of a Guid.</param>
/// <param name="shortGuid">A new <see cref="ShortGuid"/> instance from the parsed string.</param>
public static bool TryParse(string? value, out ShortGuid shortGuid)
{
// Try a ShortGuid string.
if (TryDecode(value, out var guid))
{
shortGuid = guid;
return true;
}
// Try a Guid string.
if (value.TryParseGuid(out var guid2))
{
shortGuid = guid2;
return true;
}
shortGuid = Empty;
return false;
}
/// <summary>
/// <para>Supports ShortGuid &amp; Guid formats.</para>
/// <para>Tries to parse the value either a 22 character URL-safe Base64 string or
/// <see cref="System.Guid"/> string, and outputs the <see cref="Guid"/> value.</para>
/// <para>The difference between TryParse and TryDecode:</para>
/// <list type="number">
/// <item>
/// <term><see cref="TryParse(string, out ShortGuid)"/></term>
/// <description>Supports: Guid &amp; ShortGuid;</description>
/// <description>Tries to parse first as a <see cref="ShortGuid"/>, then as a
/// <see cref="System.Guid"/>, outputs the <see cref="ShortGuid"/> instance.</description>
/// </item>
/// <item>
/// <term><see cref="TryParse(string, out Guid)"/></term>
/// <description>Supports: Guid &amp; ShortGuid;</description>
/// <description>Tries to parse first as a <see cref="ShortGuid"/>, then as a
/// <see cref="System.Guid"/>, outputs the <see cref="System.Guid"/> - this method.</description>
/// </item>
/// <item>
/// <term><see cref="TryDecode(string, out Guid)"/></term>
/// <description>Supports: ShortGuid;</description>
/// <description>Tries to decode a 22 character URL-safe Base64 string as a
/// <see cref="ShortGuid"/> only, outputting the result as a <see cref="System.Guid"/>.</description>
/// </item>
/// </list>
/// </summary>
/// <param name="value">The ShortGuid encoded string or string representation of a Guid.</param>
/// <param name="guid">A new <see cref="System.Guid"/> instance from the parsed string.</param>
/// <returns>A boolean indicating if the parse was successful.</returns>
public static bool TryParse(string? value, out Guid guid)
{
// Try a ShortGuid string.
if (TryDecode(value, out guid))
return true;
// Try a Guid string.
if (value.TryParseGuid(out guid))
{
return true;
}
guid = Guid.Empty;
return false;
}
#region Operators
/// <summary>
/// Determines if both ShortGuid instances have the same underlying <see cref="System.Guid"/> value.
/// </summary>
public static bool operator ==(ShortGuid x, ShortGuid y)
{
if (ReferenceEquals(x, null))
return ReferenceEquals(y, null);
return x.underlyingGuid == y.underlyingGuid;
}
/// <summary>
/// Determines if both instances have the same underlying <see cref="System.Guid"/> value.
/// </summary>
public static bool operator ==(ShortGuid x, Guid y)
{
if (ReferenceEquals(x, null))
return ReferenceEquals(y, null);
return x.underlyingGuid == y;
}
/// <summary>
/// Determines if both instances have the same underlying <see cref="System.Guid"/> value.
/// </summary>
public static bool operator ==(Guid x, ShortGuid y) => y == x; // NB: order of arguments
/// <summary>
/// Determines if both ShortGuid instances do not have the same underlying <see cref="System.Guid"/> value.
/// </summary>
public static bool operator !=(ShortGuid x, ShortGuid y) => !(x == y);
/// <summary>
/// Determines if both instances do not have the same underlying <see cref="System.Guid"/> value.
/// </summary>
public static bool operator !=(ShortGuid x, Guid y) => !(x == y);
/// <summary>
/// Determines if both instances do not have the same underlying <see cref="System.Guid"/> value.
/// </summary>
public static bool operator !=(Guid x, ShortGuid y) => !(x == y);
/// <summary>
/// Implicitly converts the ShortGuid to its string equivalent.
/// </summary>
public static implicit operator string(ShortGuid shortGuid) => shortGuid.encodedString;
/// <summary>
/// Implicitly converts the ShortGuid to its <see cref="System.Guid"/> equivalent.
/// </summary>
public static implicit operator Guid(ShortGuid shortGuid) => shortGuid.underlyingGuid;
/// <summary>
/// Implicitly converts the string to a ShortGuid.
/// </summary>
public static implicit operator ShortGuid(string value)
{
if (string.IsNullOrEmpty(value))
return Empty;
if (TryParse(value, out ShortGuid shortGuid))
return shortGuid;
throw new FormatException("ShortGuid should contain 22 Base64 characters or "
+ "Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).");
}
/// <summary>
/// Implicitly converts the <see cref="System.Guid"/> to a ShortGuid.
/// </summary>
public static implicit operator ShortGuid(Guid guid)
{
if (guid == Guid.Empty)
return Empty;
return new ShortGuid(guid);
}
#endregion
}
}
@@ -1,7 +1,7 @@
using System.IO.FileFormats;
using System.IO.FileFormats;
using System.Application.Columns;
namespace System.Application.Entities
namespace System.Application.Entities.Abstractions
{
public interface IImage : IEntity<Guid>, ISoftDeleted
{
@@ -0,0 +1,20 @@
namespace System.Application.Entities.Abstractions
{
public interface IUser : IEntity<Guid>
{
/// <summary>
/// 昵称
/// </summary>
string? NickName { get; set; }
/// <summary>
/// 用户名
/// </summary>
string? UserName { get; set; }
/// <summary>
/// 封禁到解封日期
/// </summary>
DateTimeOffset? BanEnd { get; set; }
}
}
@@ -1,12 +1,16 @@
using System.Application.Columns;
using System.Application.Columns;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
namespace System.Application.Entities
{
/// <summary>
/// 验证码纪录表(短信或邮箱)
/// </summary>
/// <typeparam name="TSendSmsRequestType"></typeparam>
/// <typeparam name="TAuthMessageType"></typeparam>
public class AuthMessageRecord<TSendSmsRequestType, TAuthMessageType> : IEntity<Guid>, ICreationTime
where TSendSmsRequestType : notnull, Enum
where TAuthMessageType : notnull, Enum
where TSendSmsRequestType : struct, Enum
where TAuthMessageType : struct, Enum
{
[Key] // EF 主键
public Guid Id { get; set; }
@@ -30,8 +34,7 @@ namespace System.Application.Entities
/// 调用方IP地址
/// </summary>
[Required] // EF not null
[NotNull, DisallowNull] // C# 8 not null
public string? IPAddress { get; set; }
public string IPAddress { get; set; } = string.Empty;
#region 提供商内容
@@ -40,8 +43,7 @@ namespace System.Application.Entities
/// 比如网易/阿里云
/// </summary>
[Required] // EF not null
[NotNull, DisallowNull] // C# 8 not null
public string? Channel { get; set; }
public string Channel { get; set; } = string.Empty;
/// <summary>
/// 第三方提供商返回的内容
@@ -66,8 +68,7 @@ namespace System.Application.Entities
/// 短信内容通常仅含有验证码数字,不包括其他的提示语文字
/// </summary>
[Required] // EF not null
[NotNull, DisallowNull] // C# 8 not null
public string? Content { get; set; }
public string Content { get; set; } = string.Empty;
/// <summary>
/// 是否校验过
@@ -1,10 +0,0 @@
namespace System.Application.Entities
{
public interface IUser<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// 昵称
/// </summary>
string? NickName { get; set; }
}
}
@@ -1,4 +1,5 @@
using System.Application.Columns;
using System.Application.Entities.Abstractions;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
@@ -13,10 +14,9 @@ namespace System.Application.Entities
/// </summary>
[Table("Images")]
[DebuggerDisplay("{DebuggerDisplay(),nq}")]
public class Image<TUserKey, TUser, TUploadImageType> : IImage, INEWSEQUENTIALID
where TUser : IUser<TUserKey>
where TUserKey : IEquatable<TUserKey>
where TUploadImageType : Enum
public class Image<TUser, TUploadImageType> : IImage, INEWSEQUENTIALID
where TUser : IUser
where TUploadImageType : struct, Enum
{
string DebuggerDisplay() => $"{Id}, {Type}, {SHA384}";
@@ -41,7 +41,7 @@ namespace System.Application.Entities
/// <summary>
/// 上传纪录
/// </summary>
public virtual List<ImageUploadRecord<TUserKey, TUser, TUploadImageType>>? Records { get; set; }
public virtual List<ImageUploadRecord<TUser, TUploadImageType>>? Records { get; set; }
public string GetFileName() => SHA384 + Type.GetExtension();
@@ -1,8 +1,8 @@
using System.Application.Columns;
using System.Application.Columns;
using System.Application.Entities.Abstractions;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
namespace System.Application.Entities
{
@@ -11,12 +11,11 @@ namespace System.Application.Entities
/// </summary>
[Table("ImageUploadRecords")]
[DebuggerDisplay("{DebuggerDisplay(),nq}")]
public class ImageUploadRecord<TUserKey, TUser, TUploadImageType> : INEWSEQUENTIALID, ICreationTime
where TUser : IUser<TUserKey>
where TUserKey : IEquatable<TUserKey>
where TUploadImageType : Enum
public class ImageUploadRecord<TUser, TUploadImageType> : INEWSEQUENTIALID, ICreationTime
where TUser : IUser
where TUploadImageType : struct, Enum
{
string DebuggerDisplay() => $"{ImagesId}, {Type}, {User?.NickName ?? (UserId?.ToString())}";
string DebuggerDisplay() => $"{ImagesId}, {Type}, {User?.NickName ?? (UserId.ToString())}";
[Key] // EF 主键
public Guid Id { get; set; }
@@ -25,8 +24,7 @@ namespace System.Application.Entities
/// 上传的用户ID
/// </summary>
[Required] // EF not null
[NotNull, DisallowNull] // C# 8 not null
public TUserKey? UserId { get; set; }
public Guid UserId { get; set; }
/// <summary>
/// 上传的用户
@@ -44,7 +42,6 @@ namespace System.Application.Entities
/// 上传图片类型(用途)
/// </summary>
[Required] // EF not null
[NotNull, DisallowNull] // C# 8 not null
public TUploadImageType? Type { get; set; }
public TUploadImageType Type { get; set; }
}
}
@@ -1,8 +1,7 @@
using System.Application.Columns;
using System.Application.Columns;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
namespace System.Application.Entities
{
@@ -15,12 +14,10 @@ namespace System.Application.Entities
public sealed class KeyValuePair : IEntity<string>, ISoftDeleted
{
[Key] // EF 主键
[NotNull, DisallowNull] // C# 8 not null
public string? Id { get; set; }
public string Id { get; set; } = string.Empty;
[Required] // EF not null
[NotNull, DisallowNull] // C# 8 not null
public string? Value { get; set; }
public string Value { get; set; } = string.Empty;
public bool SoftDeleted { get; set; }
@@ -19,6 +19,36 @@ namespace System.Application
public static void Main<TStartup>(string projectName,
string[] args, Action<string>? writeLine = null) where TStartup : class
{
var logger = NLogBuilder.ConfigureNLog(InitNLogConfig()).GetCurrentClassLogger();
try
{
logger.Info("init main");
var host = CreateHostBuilder<TStartup>(args).Build();
DI.Init(host.Services);
writeLine ??= Console.WriteLine;
Console.OutputEncoding = Encoding.Unicode; // 使用UTF16编码输出控制台文字
Version = typeof(TStartup).Assembly.GetName().Version?.ToString() ?? string.Empty;
UnityConsoleOutputHead.Write(writeLine,
projectName,
Version,
RuntimeVersion,
CentralProcessorName);
host.Run();
}
catch (Exception exception)
{
//NLog: catch setup errors
logger.Error(exception, "Stopped program because of exception");
throw;
}
finally
{
// Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
NLog.LogManager.Shutdown();
}
static LoggingConfiguration InitNLogConfig()
{
// https://github.com/NLog/NLog/wiki/Getting-started-with-ASP.NET-Core-5
@@ -62,36 +92,6 @@ namespace System.Application
return xmlConfig;
}
var logger = NLogBuilder.ConfigureNLog(InitNLogConfig()).GetCurrentClassLogger();
try
{
logger.Info("init main");
var host = CreateHostBuilder<TStartup>(args).Build();
DI.Init(host.Services);
writeLine ??= Console.WriteLine;
Console.OutputEncoding = Encoding.Unicode; // 使用UTF16编码输出控制台文字
Version = typeof(TStartup).Assembly.GetName().Version?.ToString() ?? string.Empty;
UnityConsoleOutputHead.Write(writeLine,
projectName,
Version,
RuntimeVersion,
CentralProcessorName);
host.Run();
}
catch (Exception exception)
{
//NLog: catch setup errors
logger.Error(exception, "Stopped program because of exception");
throw;
}
finally
{
// Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
NLog.LogManager.Shutdown();
}
}
public static IHostBuilder CreateHostBuilder<TStartup>(string[] args) where TStartup : class =>
+2 -2
View File
@@ -98,13 +98,13 @@ namespace Microsoft.Extensions.DependencyInjection
## 📁 存储空间
- AppData
- Microsoft Store ```%USERPROFILE%\AppData\Local\Packages\4651ED44255E.47979655102CE_k6txddmbb6c52\LocalState```
- Windows ```\AppData```
- Windows ```\AppData``` or ```%LocalAppData%\Steam++```
- macOS ```~/Library/Steam++```
- Linux ```$XDG_DATA_HOME/Steam++``` or ```$HOME/.local/share/Steam++```
- Android ```/data/data/net.steampp.app/files```
- Cache
- Microsoft Store ```%USERPROFILE%\AppData\Local\Packages\4651ED44255E.47979655102CE_k6txddmbb6c52\LocalCache```
- Windows ```\Cache```
- Windows ```\Cache``` or ```%Tmp%\Steam++```
- macOS ```~/Library/Caches/Steam++```
- Linux ```$XDG_CACHE_HOME/Steam++``` or ```$HOME/.cache/Steam++```
- Android ```/data/data/net.steampp.app/cache```
@@ -1,4 +1,4 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using System.Application.Columns;
using System.Application.Entities;
@@ -53,7 +53,7 @@ namespace System.Application.Repositories
public Repository(TDbContext dbContext) : base(dbContext)
{
Entity = dbContext.Set<TEntity>();
mEntityType = new Lazy<IEntityType>(() => dbContext.Model.FindEntityType(entityType));
mEntityType = new Lazy<IEntityType>(() => dbContext.Model.FindEntityType(entityType).ThrowIsNull(nameof(entityType)));
mTableName = new Lazy<string>(() => EFCoreUtils.GetTableNameByClrType(dbContext.Database, EntityType));
}
@@ -144,7 +144,7 @@ namespace System.Application.Repositories
#region 查(通用查询)
public virtual Task<TEntity?> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate) => FirstOrDefaultAsync(predicate, default);
//public virtual Task<TEntity?> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate) => FirstOrDefaultAsync(predicate, default);
/// <inheritdoc cref="FirstOrDefaultAsync(Expression{Func{TEntity, bool}})"/>
public virtual async Task<TEntity?> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken)
@@ -0,0 +1,7 @@
namespace System
{
public static class ColumnTypeNames
{
public const string Decimal_18_4 = "decimal(18,4)";
}
}
+2 -2
View File
@@ -1,4 +1,4 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using System.Application.Repositories;
@@ -41,7 +41,7 @@ namespace System
public static string GetTableNameByClrType(DbContext context, Type entityType)
{
var entityType_ = context.Model.FindEntityType(entityType);
return GetTableNameByClrType(context.Database, entityType_);
return GetTableNameByClrType(context.Database, entityType_.ThrowIsNull(nameof(entityType)));
}
/// <summary>
@@ -144,7 +144,7 @@ namespace System.Application.Repositories
#region 查(通用查询)
public virtual async Task<TEntity?> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate)
public virtual async Task<TEntity?> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default)
{
var dbConnection = await GetDbConnection().ConfigureAwait(false);
return await AttemptAndRetry(() => dbConnection.FindAsync(predicate)).ConfigureAwait(false);
@@ -0,0 +1,40 @@
using Android.Graphics.Drawables;
using Android.Widget;
using R = System.Application.Resource;
// ReSharper disable once CheckNamespace
namespace System
{
/// <summary>
/// <see cref="CheckBox"/> 扩展
/// </summary>
public static partial class CheckBoxExtensions
{
public static void SetChecked(this CheckBox checkBox, bool? value)
{
if (checkBox.GetChecked() == value) return;
Drawable? drawable = null;
if (value.HasValue)
{
checkBox.Checked = value.Value;
if (checkBox.GetTag(R.Id.checkbox_indeterminate_state) is Drawable d && checkBox.ButtonDrawable != d) drawable = d;
checkBox.SetTag(R.Id.checkbox_indeterminate_state, null);
}
else
{
if (checkBox.GetTag(R.Id.checkbox_indeterminate_state) == null)
checkBox.SetTag(R.Id.checkbox_indeterminate_state, checkBox.ButtonDrawable);
drawable = checkBox.Context!.GetDrawableCompat(R.Drawable.bg_checkbox_indeterminate);
}
if (drawable != null) checkBox.SetButtonDrawable(drawable);
}
public static bool? GetChecked(this CheckBox checkBox)
{
var state = checkBox.GetTag(R.Id.checkbox_indeterminate_state);
if (state != null) return null;
return checkBox.Checked;
}
}
}
@@ -0,0 +1,31 @@
using Android.App;
using Android.Content;
using Android.OS;
using NativeService = System.Application.Services.Native.IServiceBase;
// ReSharper disable once CheckNamespace
namespace System
{
partial class ContextExtensions
{
/// <summary>
/// 启动或关闭前台服务
/// </summary>
/// <typeparam name="TService"></typeparam>
/// <param name="context"></param>
/// <param name="startOrStop"></param>
public static void StartOrStopForegroundService<TService>(this Context context, bool startOrStop) where TService : Service, NativeService
{
Intent intent = new(context, typeof(TService));
intent.SetAction(startOrStop ? NativeService.START : NativeService.STOP);
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
context.StartForegroundService(intent);
}
else
{
context.StartService(intent);
}
}
}
}
@@ -1,8 +1,9 @@
using System;
using System.Application.UI.Activities;
using System.Collections.Generic;
using System.Text;
#if __XAMARIN_FORMS__
using Xamarin.Forms.Platform.Android;
#endif
using Fragment = AndroidX.Fragment.App.Fragment;
// ReSharper disable once CheckNamespace
@@ -13,9 +14,11 @@ namespace System
/// </summary>
public static partial class FragmentExtensions
{
#if __XAMARIN_FORMS__
public static bool IsEmbeddedForms(this Fragment? fragment)
{
return fragment?.Activity is FormsAppCompatActivity;
}
#endif
}
}
@@ -0,0 +1,169 @@
using Android.Content;
using Android.Graphics;
using Android.Graphics.Drawables;
using AndroidX.Annotations;
using AndroidX.RecyclerView.Widget;
using System.Application;
// ReSharper disable once CheckNamespace
namespace System
{
/// <summary>
/// 对 <see cref="RecyclerView"/> 类的扩展函数集
/// </summary>
public static class RecycleViewExtensions
{
/// <summary>
/// 设置使用线性布局管理列表,默认纵向,使用 <see cref="LinearLayoutManager2"/>
/// </summary>
/// <param name="recycleView"></param>
/// <param name="orientation"></param>
/// <param name="reverseLayout"></param>
public static void SetLinearLayoutManager(this RecyclerView recycleView, int orientation = LinearLayoutManager.Vertical, bool reverseLayout = false)
{
var layout = new LinearLayoutManager2(recycleView.Context!, orientation, reverseLayout);
recycleView.SetLayoutManager(layout);
}
/// <summary>
/// 添加纵向列表组项间距,使用 <see cref="VerticalGroupItemDecoration(int)"/>
/// </summary>
/// <param name="recycleView"></param>
/// <param name="height"></param>
public static void AddVerticalGroupItemDecoration(this RecyclerView recycleView, int height)
{
VerticalGroupItemDecoration itemDecoration = new(height);
recycleView.AddItemDecoration(itemDecoration);
}
/// <summary>
/// 添加纵向列表组项间距,使用 <see cref="VerticalGroupItemDecoration(int)"/>
/// </summary>
/// <param name="recycleView"></param>
/// <param name="heightResId"></param>
public static void AddVerticalGroupItemDecorationRes(this RecyclerView recycleView, [DimenRes] int heightResId)
{
var height = recycleView.Context!.GetDimensionPixelSize(heightResId);
recycleView.AddVerticalGroupItemDecoration(height);
}
/// <summary>
/// 添加纵向列表项间距,使用 <see cref="VerticalItemDecoration(int)"/>
/// </summary>
/// <param name="recycleView"></param>
/// <param name="height"></param>
public static void AddVerticalItemDecoration(this RecyclerView recycleView, int height)
{
VerticalItemDecoration itemDecoration = new(height);
recycleView.AddItemDecoration(itemDecoration);
}
/// <summary>
/// 添加纵向列表项间距,使用 <see cref="VerticalItemDecoration(int)"/>
/// </summary>
/// <param name="recycleView"></param>
/// <param name="heightResId"></param>
public static void AddVerticalItemDecorationRes(this RecyclerView recycleView, [DimenRes] int heightResId)
{
var height = recycleView.Context!.GetDimensionPixelSize(heightResId);
recycleView.AddVerticalItemDecoration(height);
}
/// <summary>
/// 添加纵向列表项间距,使用 <see cref="VerticalItemDecoration2(int, int, bool)"/>
/// </summary>
/// <param name="recycleView"></param>
/// <param name="height"></param>
/// <param name="paddingBottom"></param>
/// <param name="noTop"></param>
public static void AddVerticalItemDecoration(this RecyclerView recycleView, int height, int paddingBottom, bool noTop = false)
{
VerticalItemDecoration2 itemDecoration = new(height, paddingBottom, noTop);
recycleView.AddItemDecoration(itemDecoration);
}
/// <summary>
/// 添加纵向列表项间距,使用 <see cref="VerticalItemDecoration2.Get(Context, int, int, bool)"/>
/// </summary>
/// <param name="recycleView"></param>
/// <param name="heightResId"></param>
/// <param name="paddingBottomResId"></param>
/// <param name="noTop"></param>
public static void AddVerticalItemDecorationRes(this RecyclerView recycleView, [DimenRes] int heightResId, [DimenRes] int paddingBottomResId = default, bool noTop = false)
{
var itemDecoration = VerticalItemDecoration2.Get(recycleView.Context!, heightResId, paddingBottomResId, noTop);
recycleView.AddItemDecoration(itemDecoration);
}
/// <summary>
/// 添加分割线,由 <see cref="Drawable"/> 绘制
/// </summary>
/// <param name="recycleView"></param>
/// <param name="drawable"></param>
/// <param name="orientation"></param>
public static void AddDividerItemDecoration(this RecyclerView recycleView, Drawable drawable, int orientation = DividerItemDecoration.Vertical)
{
DividerItemDecoration itemDecoration = new(recycleView.Context!, orientation);
itemDecoration.Drawable = drawable;
recycleView.AddItemDecoration(itemDecoration);
}
/// <summary>
/// 添加分割线,由 <see cref="DrawableResAttribute"/> 绘制
/// </summary>
/// <param name="recycleView"></param>
/// <param name="drawableResId"></param>
/// <param name="orientation"></param>
public static void AddDividerItemDecorationRes(this RecyclerView recycleView, [DrawableRes] int drawableResId, int orientation = DividerItemDecoration.Vertical)
{
var drawable = recycleView.Context!.GetDrawableCompat(drawableResId);
recycleView.AddDividerItemDecoration(drawable, orientation);
}
/// <summary>
/// 添加分割线,由 <see cref="Color"/> 绘制
/// </summary>
/// <param name="recycleView"></param>
/// <param name="color"></param>
/// <param name="size"></param>
/// <param name="orientation"></param>
public static void AddDividerItemDecoration(this RecyclerView recycleView, int colorArgb, int size = 1, int orientation = DividerItemDecoration.Vertical)
{
GradientDrawable shape = new();
shape.SetColor(colorArgb);
if (orientation == DividerItemDecoration.Vertical)
{
shape.SetSize(0, size);
}
else if (orientation == DividerItemDecoration.Horizontal)
{
shape.SetSize(size, 0);
}
recycleView.AddDividerItemDecoration(shape, orientation);
}
/// <summary>
/// 添加分割线,由 <see cref="ColorResAttribute"/> 绘制
/// </summary>
/// <param name="recycleView"></param>
/// <param name="colorResId"></param>
/// <param name="size"></param>
/// <param name="orientation"></param>
public static void AddDividerItemDecorationRes(this RecyclerView recycleView, [ColorRes] int colorResId, int size = 1, int orientation = DividerItemDecoration.Vertical)
{
var colorArgb = recycleView.Context!.GetColorCompat(colorResId);
recycleView.AddDividerItemDecoration(colorArgb, size, orientation);
}
/// <summary>
/// 添加分割线
/// </summary>
/// <param name="recycleView"></param>
/// <param name="orientation"></param>
public static void AddDividerItemDecorationRes(this RecyclerView recycleView, int orientation = DividerItemDecoration.Vertical)
{
var colorResId = Resource.Color.bg_divider;
recycleView.AddDividerItemDecorationRes(colorResId, orientation: orientation);
}
}
}

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