Compare commits

...
Author SHA1 Message Date
Aigio Liu 0367fc027e 🚧 net35 2023-09-07 21:14:53 +08:00
RMBGAME c80f4de55b 🐛 Misc 2023-09-07 21:13:27 +08:00
Aigio Liu 9c01b74a4b 🐛 OrderBy(KeyValuePair<int, MenuTabItemViewModel> m) 2023-09-07 20:31:16 +08:00
RMBGAME 894f8d4239 🐛 Fix Bugs 2023-09-07 20:26:15 +08:00
ff m 6dcda63be6 🐛迁移 Script 文件夹错误
🐛更换 API 地址
2023-09-07 19:44:55 +08:00
Aigio Liu 7f9840c3ee ✨ TryDeleteRootPathObsoleteFiles 2023-09-07 19:21:06 +08:00
Aigio Liu 8a1b60dcbb 🐛 2023-09-07 18:19:28 +08:00
Aigio Liu 23e62c2fac 🐛 WindowsFileSystem 2023-09-07 16:29:53 +08:00
Aigio Liu ce56e4e1dd 🐛 WindowsFileSystem.InitFileSystemByInstallVersion 2023-09-07 15:58:56 +08:00
Aigio Liu 798efb5873 🐛 WindowsFileSystem 2023-09-07 15:00:40 +08:00
RMBGAME 0261fa4460 📃 2023-09-07 00:56:54 +08:00
RMBGAME fb9faf53af 📃 ReadMe 2023-09-07 00:34:14 +08:00
Aigio Liu ef3006861e 💚 fix Restore Workload 2023-09-06 19:02:55 +08:00
Aigio Liu c3a92d31d2 🐛 OnExit 2023-09-06 18:15:54 +08:00
Aigio Liu f37afe1aa0 🐛 IsConnected 2023-09-06 17:56:11 +08:00
Aigio Liu 7df6b0d007 🚧 IDotNetPublishCommand 2023-09-06 17:33:50 +08:00
RMBGAME 632ddd44e3 sign 2023-09-06 16:52:12 +08:00
RMBGAME 17f03a523c Readme 2023-09-06 16:50:48 +08:00
Aigio Liu f2c1df5b35 🚧 NSIS 2023-09-06 16:49:38 +08:00
Aigio Liu 166e258b38 🎨 NSIS 2023-09-06 15:45:54 +08:00
Aigio Liu f95d1c3515 🚧 windows dekstop bridge 2023-09-05 21:44:12 +08:00
Aigio Liu bf5dbf9435 🚧 windows dekstop bridge 2023-09-05 20:39:20 +08:00
Aigio Liu 66a92f8363 🐛 EntryPointExe 2023-09-05 19:40:39 +08:00
Aigio Liu 5dec270ff5 🐛 NativeLibrary.SetDllImportResolver 2023-09-05 19:11:16 +08:00
Mossimo ae5b881b30 🐛 Mac 原生库环境变量路径 Git Crlf lf 换行符问题手动复制 build 中 Linux 到发布 ShellScript/Linux 2023-09-05 18:48:51 +08:00
RMBGAME ac84585630 🚧 Misc 2023-09-05 18:09:55 +08:00
Aigio Liu 16e766f54a ✨ BD.WTTS.Client.AppHost.Bridge.Package 2023-09-05 17:44:27 +08:00
Aigio Liu eec99d64c6 🚑 restore RequestCacheRepository 2023-09-05 17:26:19 +08:00
Aigio Liu 2b5892348c 🐛 AppCenter 2023-09-05 17:12:42 +08:00
Aigio Liu 751875b05a 🚑 2023-09-05 16:27:42 +08:00
Aigio Liu a35f612d3d 🐛 AppCenter 2023-09-05 16:21:11 +08:00
john.jiang b45c989062 🎨 fixs 2023-09-05 11:39:57 +08:00
ff m 1c386dd87c 🐛优化环境检测脚本启动加速 检测依赖环境 2023-09-04 19:29:56 +08:00
RMBGAME 8669667118 🐛 脚本为空时提示优化 2023-09-04 18:12:32 +08:00
Aigio 9887b9e125 🐛 AvaloniaApplicationUpdateServiceImpl.OnExistNewVersion 2023-09-04 18:09:36 +08:00
Aigio afb0dc7319 🐛 IApplication.DeploymentMode 2023-09-04 17:35:05 +08:00
RMBGAME e61ebea90e 🐛 Misc 2023-09-04 14:18:06 +08:00
RMBGAME 3578311463 🐛 Fix Delete Account Toast Error 2023-09-04 14:05:03 +08:00
RMBGAME c383c900f8 ✨ Steam Rich Presence 2023-09-04 13:45:13 +08:00
RMBGAME 4b05d368d6 🐛 Fix PublishTool Pri Bug 2023-09-04 07:42:08 +08:00
RMBGAME 989ed16b00 ⬆️ LiveCharts 2023-09-04 03:10:20 +08:00
RMBGAME 0d2d6d6438 ✨ 托盘 退出 Steam 2023-09-04 02:27:03 +08:00
Aigio Liu 62909aa651 🚧 PublishTool 2023-09-03 17:18:31 +08:00
Aigio Liu c0d735d9cf ➕ Facepunch.Steamworks 2023-09-03 17:18:31 +08:00
RMBGAME 93531ea3d9 🐛 Misc 2023-09-03 12:58:47 +08:00
RMBGAME e937ab1b35 🐛 Misc 2023-09-03 10:59:02 +08:00
RMBGAME a730339153 🐛 一个奇怪的 CancellationToken 问题修复 2023-09-02 18:40:17 +08:00
Aigio Liu c4a7dd7994 🚧 3.0.0-rc.1 2023-09-02 17:34:56 +08:00
Aigio Liu 7366e2c904 🚧 Misc 2023-09-02 17:28:32 +08:00
ff m 5215e3d613 🐛打包卸载 启动 脚本 2023-09-02 14:27:58 +08:00
ff m 1c454123b8 ✨检查环境脚本 卸载安装脚本 2023-09-02 14:04:40 +08:00
RMBGAME 18080285bf 💄 Misc 2023-09-02 12:23:22 +08:00
Aigio Liu 1049355476 ✨ Application Crash(WPFMessageBox) 2023-09-02 02:22:09 +08:00
Aigio Liu dc74c2ae10 🚧 Misc 2023-09-02 02:02:14 +08:00
ff m b32cb40949 🐛 修复 系统版本获取字段 2023-09-01 20:49:47 +08:00
Aigio Liu 98324d95a8 🐛 WriteDefaultHostsContent & DisablePluginsAssemblyLoadContext 2023-09-01 19:56:20 +08:00
Aigio Liu bed2fbb98d 🐛 System.InvalidOperationException: No service for type 'BD.WTTS.Settings.Abstractions.IPartialGameLibrarySettings' has been registered. 2023-09-01 17:32:45 +08:00
Aigio Liu dd09e37048 🐛 HostsFileServiceImpl Ipc 2023-09-01 17:09:33 +08:00
Aigio Liu d359392fc0 ✨ stmupload 2023-09-01 15:24:44 +08:00
ff m 4601987cb4 🐛脚本安装默认启用 2023-09-01 15:17:25 +08:00
RMBGAME 7c21e8454e 🐛 Fixed Bugs 2023-09-01 13:40:46 +08:00
RMBGAME 6f60f10fc8 🐛 Fixed Bugs 2023-09-01 13:24:43 +08:00
RMBGAME 41b51f4e0a 🐛 Steam 令牌 闪退问题 2023-09-01 11:22:47 +08:00
Aigio 83952d6d76 🚧 3.0.0-preview.7 2023-09-01 06:43:18 +08:00
Aigio 44b4a3b05e 🐛 RunSingleInstancePipeServer 2023-09-01 06:29:54 +08:00
Aigio ac91872815 ✨ HostsTest 2023-09-01 05:09:48 +08:00
RMBGAME 2795dbac5f 🐛 Misc 2023-08-31 18:43:36 +08:00
ff m 4e2fe256ed 🐛 检测且初始化 nssdb 2023-08-31 18:33:54 +08:00
Aigio 83c515542c 🔥 StartAsAdministratorByBypassUAC 2023-08-31 18:06:35 +08:00
Aigio 0c9f25a304 🐛 CSR 2023-08-31 17:29:11 +08:00
Aigio 63be2ba037 ✨ CSR 2023-08-31 17:21:46 +08:00
Aigio 4c464623b8 🚧 3.0.0-preview.6 2023-08-31 04:30:17 +08:00
Aigio 7c16daafba 🐛 RequestCacheRepository 2023-08-31 03:48:21 +08:00
Aigio 2acc0a95e0 Merge branch 'develop' of https://github.com/BeyondDimension/SteamTools into develop 2023-08-31 03:26:30 +08:00
Aigio 8072b16d42 🐛 RequestCache 2023-08-31 03:26:11 +08:00
ff m 9766e9e71b 🐛修复 Mac Debug 无法启动加速进程 修复 Mac 启动加速退出卡死
🎨 Misc PlatformSetTextAsync
2023-08-31 02:34:52 +08:00
Aigio d39f63db65 🐛 UniqueKeyForRequest 2023-08-31 02:22:41 +08:00
Aigio fd6235f110 Merge branch 'develop' of https://github.com/BeyondDimension/SteamTools into develop 2023-08-31 02:01:07 +08:00
Aigio 4a9a53dda8 🐛 HttpCache 2023-08-31 02:00:52 +08:00
RMBGAME 4668e26b65 🐛 Misc 2023-08-31 01:05:55 +08:00
RMBGAME c5f24ae32c ⬆️ Update BD.Common 2023-08-31 00:10:14 +08:00
ff m 1acf872e80 🐛 PlatformSetTextAsync 不能用 await 等待 Linux 上不知原因不执行后续 2023-08-30 23:26:24 +08:00
ff m 82ea1a62e9 🐛 LinuxDeviceInfoPlatformServiceImpl 2023-08-30 21:35:02 +08:00
Aigio Liu 04b0c0e433 🐛 LinuxDeviceInfoPlatformServiceImpl 2023-08-30 21:29:52 +08:00
Aigio Liu 8dfb37bf8b ✨ LinuxDeviceInfoPlatformServiceImpl 2023-08-30 21:08:36 +08:00
ff m a19b3128db 🐛 127.* 与 localhost 不能添加不然会导致 不走代理 2023-08-30 21:03:23 +08:00
Aigio Liu f70b349229 🚧 3.0.0-preview.5 2023-08-30 20:58:25 +08:00
ff m ed104071c2 🐛 取消平台限制 打开换成文件夹 2023-08-30 20:44:31 +08:00
Aigio Liu 21ae674895 ⬆️ Update Common 2023-08-30 19:47:52 +08:00
Aigio Liu 500a87d62f ✨ AvaloniaFilePickerFileTypeFilter 2023-08-30 15:35:53 +08:00
john.jiang d1ae1787b7 🎨 fixs 2023-08-30 13:43:42 +08:00
RMBGAME 5742158c83 🚧 Misc 2023-08-30 09:31:13 +08:00
RMBGAME 235525a9f3 🐛 库存游戏加载图片逻辑优化 2023-08-30 05:52:05 +08:00
RMBGAME 329340ae2d 🐛 Fixed Bugs 2023-08-30 04:29:52 +08:00
RMBGAME e8e6808930 💄 文本过长宽度过小 显示优化 2023-08-30 02:54:56 +08:00
RMBGAME a77fb08a04 🐛 Fixed Bugs 2023-08-30 02:27:05 +08:00
RMBGAME c05fe78d2d 🐛 修复交易确认首次登录失败 2023-08-30 02:27:04 +08:00
ff m 7b6b8a9b2d 🐛脚本匹配域名等优先读取本地文件的内容 2023-08-30 02:11:06 +08:00
Aigio Liu 3886a96f61 🚧 3.0.0-preview.4 2023-08-29 18:13:38 +08:00
200 changed files with 6827 additions and 1198 deletions
+1 -1
View File
@@ -62,7 +62,7 @@ jobs:
# run: dotnet workload install wasm-tools
- name: Restore Workload
run: dotnet workload restore
run: dotnet workload restore src\BD.WTTS.Client.Avalonia.App\BD.WTTS.Client.Avalonia.App.csproj
- name: Verify dotnet info
run: dotnet --info
+3
View File
@@ -34,3 +34,6 @@
[submodule "ref/WinAuth"]
path = ref/WinAuth
url = https://github.com/BeyondDimension/WinAuth.git
[submodule "ref/Facepunch.Steamworks"]
path = ref/Facepunch.Steamworks
url = https://github.com/BeyondDimension/Facepunch.Steamworks.git
+18 -12
View File
@@ -5,7 +5,7 @@
[English](./README.en.md) | 简体中文
「Watt Toolkit」是一个开源跨平台的多功能游戏工具箱,此工具的大部分功能都是需要您下载安装 Steam 才能使用。
![Release Download](https://img.shields.io/github/downloads/BeyondDimension/SteamTools/total?style=flat-square)
[![Release Version](https://img.shields.io/github/v/release/BeyondDimension/SteamTools?style=flat-square)](https://github.com/BeyondDimension/SteamTools/releases/latest)
[![GitHub license](https://img.shields.io/github/license/BeyondDimension/SteamTools?style=flat-square)](LICENSE)
@@ -30,6 +30,7 @@
</div>
## 🚀 下载渠道
- [![Steam 商店](./res/brands/steam.jpg)](https://store.steampowered.com/app/2425030)
- [![Microsoft 应用商店](./res/brands/msstore.en.png)](https://apps.microsoft.com/store/detail/watt-toolkit/9MTCFHS560NG?hl=zh-cn&gl=cn)
- [软件官网](https://steampp.net)
- [GitHub 发行版](https://github.com/BeyondDimension/SteamTools/releases)
@@ -41,22 +42,23 @@
详见 [./doc/download-guide.md](./doc/download-guide.md)
## ✨ 功能
全新的 3.0 版本,支持自定义插件功能,以下功能为下载时自带的默认插件,可以自行删除或禁用。
1. 网络加速 <img src="./res/brands/windows.svg" width="16" height="16" /> <img src="./res/brands/linux.svg" width="16" height="16" /> <img src="./res/brands/apple.svg" width="16" height="16" /> <img src="./res/brands/android.svg" width="16" height="16" />
- ~~使用 [Titanium-Web-Proxy](https://github.com/justcoding121/Titanium-Web-Proxy) 开源项目进行本地反代来支持更快的访问游戏网站。~~
- 使用 [YARP.ReverseProxy](https://github.com/microsoft/reverse-proxy) 开源项目进行本地反代来支持更快的访问游戏网站。
2. 脚本配置 <img src="./res/brands/windows.svg" width="16" height="16" /> <img src="./res/brands/linux.svg" width="16" height="16" /> <img src="./res/brands/apple.svg" width="16" height="16" />
- 通过加速服务拦截网络请求将一些 JS 脚本注入在网页中,提供类似网页插件的功能。
3. 账号切换 <img src="./res/brands/windows.svg" width="16" height="16" /> <img src="./res/brands/linux.svg" width="16" height="16" /> <img src="./res/brands/apple.svg" width="16" height="16" />
- 一键切换已在当前 PC 上登录过的 Steam 账号,与管理家庭共享库排序及禁用等功能。
4. 库存管理 <img src="./res/brands/windows.svg" width="16" height="16" /> <img src="./res/brands/linux.svg" width="16" height="16" /> <img src="./res/brands/apple.svg" width="16" height="16" />
- 让您直接管理 Steam 游戏库存,可以编辑游戏名称和[自定义封面](https://www.steamgriddb.com),也能解锁以及反解锁 Steam 游戏成就。
- 快速切换已在当前 PC 上登录过的 Steam、Epic、Uplay 等等多平台账号,与管理 Steam 家庭共享库排序及禁用等功能。
4. 库存游戏 <img src="./res/brands/windows.svg" width="16" height="16" /> <img src="./res/brands/linux.svg" width="16" height="16" /> <img src="./res/brands/apple.svg" width="16" height="16" />
- 直接管理你的 Steam 游戏库存,可以编辑游戏名称和[自定义封面](https://www.steamgriddb.com)。
- 监控 Steam 游戏下载进度实现 Steam 游戏下载完成定时关机功能。
- 模拟运行 Steam 游戏,让您不用安装和下载对应的游戏也能挂游玩时间和 Steam 卡片
- 自助管理 Steam 游戏云存档,随时删除和上传自定义的存档文件至 Steam 云
- 模拟运行 Steam 游戏,让您不用安装和下载对应的游戏也能挂游玩时间和掉落 Steam 卡片
- 自助管理 Steam 游戏云存档,随时删除和上传自定义的存档文件至 Steam 云。
- 解锁以及反解锁 Steam 游戏成就。
5. 本地令牌 <img src="./res/brands/windows.svg" width="16" height="16" /> <img src="./res/brands/linux.svg" width="16" height="16" /> <img src="./res/brands/apple.svg" width="16" height="16" /> <img src="./res/brands/android.svg" width="16" height="16" />
- 让您的手机令牌统一保存在电脑中,目前仅支持 Steam 令牌,后续会开发支持更多的令牌种类与云同步令牌。
6. 自动挂卡 <img src="./res/brands/windows.svg" width="16" height="16" /> <img src="./res/brands/linux.svg" width="16" height="16" /> <img src="./res/brands/apple.svg" width="16" height="16" /> <img src="./res/brands/android.svg" width="16" height="16" />
- 集成 [ArchiSteamFarm](https://github.com/JustArchiNET/ArchiSteamFarm) 在应用内提供 挂机掉落 Steam 集换式卡牌 等功能。
- 让您的手机令牌统一保存在电脑中、支持通用HOTP、TOTP、Steam、Google 等令牌导入。
- 支持 Steam 登录账号自定绑定生成令牌、支持 Steam 批量确认交易功能。
6. ~~自动挂卡(新版本开发中)~~ <img src="./res/brands/windows.svg" width="16" height="16" /> <img src="./res/brands/linux.svg" width="16" height="16" /> <img src="./res/brands/apple.svg" width="16" height="16" /> <img src="./res/brands/android.svg" width="16" height="16" />
- ~~集成 [ArchiSteamFarm](https://github.com/JustArchiNET/ArchiSteamFarm) 在应用内提供 挂机掉落 Steam 集换式卡牌 等功能。~~
7. 游戏工具 <img src="./res/brands/windows.svg" width="16" height="16" />
- 强制游戏窗口使用无边框窗口化、更多功能待开发。
@@ -74,8 +76,12 @@
## 🧩 截图
<img src="./res/screenshots/screenshot-windows-accelerator.webp" width="800" />
<br/>
<img src="./res/screenshots/screenshot-windows-gameaccount.webp" width="800" />
<br/>
<img src="./res/screenshots/screenshot-android-authenticator.png" width="800" />
<img src="./res/screenshots/screenshot-windows-gamelist.webp" width="800" />
<br/>
<br/>
<!--<img src="./res/screenshots/screenshot-android-authenticator.png" width="800" />-->
## 从移动端 Steam App 导入令牌指南
- [Android 添加本地令牌(Xposed)](https://github.com/BeyondDimension/SteamTools/issues/2276)
+902 -1
View File
File diff suppressed because it is too large Load Diff
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
run_path=$(dirname "$0")
dotnet_path="$run_path/dotnet"
dotnet_exec="$dotnet_path/dotnet"
export DOTNET_ROOT="$dotnet_path"
link_exec="$run_path/Steam++"
# 判断符号链接是否存在
if [ -L "$link_exec" ]; then
echo "符号链接 $link_exec 已存在"
else
rm -rf "$link_exec" 2>/dev/null
echo "创建符号链接 $dotnet_exec 到 $link_exec"
ln -s "$dotnet_exec" "$link_exec"
chmod +x "$link_exec"
fi
"$link_exec" "$run_path/assemblies/Steam++.dll" "$@"
exit
+58
View File
@@ -0,0 +1,58 @@
#!/bin/bash
base_path="$HOME/WattToolkit"
export LC_ALL=en_US.UTF-8
if [ "$1" = "-c" ]; then
# 只验证 certutil 是否可用
if command -v certutil &>/dev/null; then
exit 200
else
echo "请手动安装 certutil 工具。"
exit 1
fi
else
Install_certutil() {
# 判断发行版类型
if command -v certutil &>/dev/null; then
echo "certutil 工具已安装。"
else
echo "证书导入以及验证需要使用 certutil 工具。"
# 判断包管理器
if command -v apt &>/dev/null; then
# 使用 apt (Debian/Ubuntu)
sudo apt update
sudo apt install -y libnss3-tools
elif command -v dnf &>/dev/null; then
# 使用 dnf (Fedora)
sudo dnf install -y nss-tools
elif command -v yum &>/dev/null; then
# 使用 yum (CentOS/Red Hat)
sudo yum install -y nss-tools
elif command -v pacman &>/dev/null; then
# 使用 pacman (Arch Linux)
# sudo pacman -S nss
echo "请手动安装 certutil 工具。"
exit 1
else
echo "请手动安装 certutil 工具。"
exit 1
fi
echo "certutil 工具已安装。"
fi
}
certutil_Init() {
certutil -d sql:$HOME/.pki/nssdb -L
ret=$?
if [ $ret -ne 0 ]; then
echo "即将初始化 certutil sql:\$HOME/.pki/nssdb"
mkdir -p sql:$HOME/.pki
mkdir -p sql:$HOME/.pki/nssdb
chmod 700 sql:$HOME/.pki/nssdb
certutil -d sql:$HOME/.pki/nssdb -N --empty-password
else
echo "certutil nssdb 正常"
fi
}
Install_certutil
certutil_Init
exit 0
fi
+16 -19
View File
@@ -6,7 +6,7 @@ appVer_path="$base_path/WattToolkit.AppVer"
exec_name="Steam++"
tar_name="WattToolkit.tgz"
tar_path="$base_path/$tar_name"
base_url="https://steampp.mossimo.net:8800"
base_url="https://api.steampp.net"
architecture=1
app_name="Watt Toolkit"
PROCESS_NAMES=("$exec_name" "$app_name")
@@ -40,6 +40,19 @@ Install_certutil() {
echo "certutil 工具已安装。"
fi
}
certutil_Init() {
certutil -d sql:$HOME/.pki/nssdb -L
ret=$?
if [ $ret -ne 0 ]; then
echo "即将初始化 certutil sql:\$HOME/.pki/nssdb"
mkdir -p sql:$HOME/.pki
mkdir -p sql:$HOME/.pki/nssdb
chmod 700 sql:$HOME/.pki/nssdb
certutil -d sql:$HOME/.pki/nssdb -N --empty-password
else
echo "certutil nssdb 正常"
fi
}
Install_jq() {
# Check if jq is already installed
if command -v jq &>/dev/null; then
@@ -139,7 +152,7 @@ Get_NewVer() {
esac
# 获取发行版信息
read -r os_version <<<"$(cat /etc/os-release | grep -E 'VERSION=' | awk -F'=' '{ print $2 }' | tr -d '"')"
read -r os_version <<<"$(cat /etc/os-release | grep -E 'VERSION_ID=' | awk -F'=' '{ print $2 }' | tr -d '"')"
# 如果 VERSION 为空,则使用 BUILD_ID 填充
if [ -z "$os_version" ]; then
@@ -270,23 +283,6 @@ Decompression() {
else
chmod +x "$dotnet_exec"
fi
rm "$base_path/start.sh"
rm "$base_path/Steam++"
echo "#!/bin/bash
run_path=\$(dirname \"\$0\")
dotnet_path=\"\$run_path/dotnet\"
dotnet_exec=\"\$dotnet_path/dotnet\"
export DOTNET_ROOT=\"\$dotnet_path\"
link_exec=\"\$run_path/Steam++\"
# 判断符号链接是否存在
if [ ! -L \"\$link_exec\" ]; then
echo \"创建符号链接 \$dotnet_exec 到 \$link_exec\"
ln -s \"\$dotnet_exec\" \"\$link_exec\"
else
echo \"符号链接 \$link_exec 已存在\"
fi
\"\$link_exec\" \"\$run_path/assemblies/Steam++.dll\" \"\$@\"
exit" >"$base_path/$exec_name.sh"
chmod +x "$base_path/$exec_name.sh"
}
@@ -294,6 +290,7 @@ exit" >"$base_path/$exec_name.sh"
Install_certutil
Install_zenity
Install_jq
certutil_Init
#版本检查更新;
Get_NewVer
+60
View File
@@ -0,0 +1,60 @@
#!/bin/bash
base_path="$HOME/WattToolkit"
export LC_ALL=en_US.UTF-8
exec_name="Steam++"
app_name="Watt Toolkit"
AppData="$XDG_DATA_HOME/Steam++"
AppData_t="$HOME/.local/share/Steam++"
Cache="$XDG_CACHE_HOME/Steam++"
Cache_t="$HOME/.cache/Steam+"
PROCESS_NAMES=("$exec_name" "$app_name")
Kill_Process() {
# 尝试的次数
Kill_MAX_RETRIES=3
# 循环尝试终止进程
for process_name in "${PROCESS_NAMES[@]}"; do
kill_retry=1
while [ $kill_retry -le $Kill_MAX_RETRIES ]; do
pid=$(pgrep "$process_name")
if [ -n "$pid" ]; then
echo "尝试 $kill_retry: 进程 $process_name 正在运行中。正在终止..."
kill $pid
sleep 2
else
break
fi
kill_retry=$((kill_retry + 1))
done
done
for process_name in "${PROCESS_NAMES[@]}"; do
# 检查是否成功终止进程
if pgrep -x "$process_name" >/dev/null; then
echo "无法终止程序 $process_name。尝试次数已达上限。"
exit 1
else
echo "程序 $process_name 已成功终止。"
fi
done
}
Kill_Process
zenity --question --text="是否删除用户数据" --width=400
# 获取上一个命令的退出码
response=$?
if [ $response -eq 0 ]; then
rm -rfq "$AppData" 2>/dev/null
rm -rfq "$AppData_t" 2>/dev/null
else
echo "保留用户数据方便下次安装。"
echo "如需删除可手动删除该目录:$AppData 或者 $AppData_t"
fi
rm -rfq "$Cache" 2>/dev/null
rm -rfq "$Cache_t" 2>/dev/null
rm -rfq "$base_path" 2>/dev/null
rm -rfq "$HOME/Desktop/Watt Toolkit.desktop" 2>/dev/null
zenity --info --text="卸载完成!" --width=300
+12 -12
View File
@@ -1,3 +1,4 @@
#!/bin/bash
# 判断是否提供了 Build_Mode 参数
if [ -z "$1" ]; then
Build_Mode="any" # 如果没有提供参数,则设置默认值为 "any"
@@ -9,10 +10,11 @@ Base_Path="/Users/moxiansheng/Documents/GitHub/SteamTools"
App_Path="$Base_Path/src/BD.WTTS.Client.Avalonia.App"
Publish_Path="bin/Release/Publish/assemblies"
Plugins_Release_Path="bin/Release"
CodesignKey_Name="mossimo CodesignKey"
App_Modules_Path="$App_Path/$Publish_Path/modules"
echo "编译主程序"
cd "$App_Path"
dotnet publish -c Release -p:PublishDir="$Publish_Path" -f net7.0-macos -p:CreatePackage=false
dotnet publish -c Release -p:PublishDir="$Publish_Path" -f net7.0-macos -p:CreatePackage=false -p:EnableCodeSigning=true -p:CodesignKey="$CodesignKey_Name"
rm -r "$App_Modules_Path"
mkdir -p "$App_Modules_Path"
echo "编译插件"
@@ -34,34 +36,34 @@ Plugins_Accelerator_ReverseProxy_Path="$Base_Path/src/BD.WTTS.Client.Plugins.Acc
cd "$Plugins_Accelerator_ReverseProxy_Path"
# 根据 Build_Mode 执行不同逻辑
if [ "$Build_Mode" = "any" ]; then
dotnet publish -c Release -p:PublishDir="$Publish_Path/arm64" -f net7.0 -r osx-arm64 -p:PublishSingleFile=true --self-contained
dotnet publish -c Release -p:PublishDir="$Publish_Path/x64" -f net7.0 -r osx-x64 -p:PublishSingleFile=true --self-contained
dotnet publish -c Release -p:PublishDir="$Publish_Path/arm64" -f net7.0 -r osx-arm64 -p:PublishSingleFile=true --self-contained -p:EnableCodeSigning=true -p:CodesignKey="$CodesignKey_Name"
dotnet publish -c Release -p:PublishDir="$Publish_Path/x64" -f net7.0 -r osx-x64 -p:PublishSingleFile=true --self-contained -p:EnableCodeSigning=true -p:CodesignKey="$CodesignKey_Name"
lipo -create "$Publish_Path/arm64/Steam++.Accelerator" "$Publish_Path/x64/Steam++.Accelerator" -output "$Publish_Path/Steam++.Accelerator"
Copy_Plugins "$Publish_Path" "Accelerator" "Steam++.Accelerator"
elif [ "$Build_Mode" = "arm64" ]; then
dotnet publish -c Release -p:PublishDir="$Publish_Path/arm64" -f net7.0 -r osx-arm64 -p:PublishSingleFile=true --self-contained
dotnet publish -c Release -p:PublishDir="$Publish_Path/arm64" -f net7.0 -r osx-arm64 -p:PublishSingleFile=true --self-contained -p:EnableCodeSigning=true -p:CodesignKey="$CodesignKey_Name"
Copy_Plugins "$Publish_Path/arm64" "Accelerator" "Steam++.Accelerator"
elif [ "$Build_Mode" = "x64" ]; then
dotnet publish -c Release -p:PublishDir="$Publish_Path/x64" -f net7.0 -r osx-x64 -p:PublishSingleFile=true --self-contained
dotnet publish -c Release -p:PublishDir="$Publish_Path/x64" -f net7.0 -r osx-x64 -p:PublishSingleFile=true --self-contained -p:EnableCodeSigning=true -p:CodesignKey="$CodesignKey_Name"
Copy_Plugins "$Publish_Path/x64" "Accelerator" "Steam++.Accelerator"
fi
echo "编译令牌插件"
Plugins_Authenticator_Path="$Base_Path/src/BD.WTTS.Client.Plugins.Authenticator"
cd "$Plugins_Authenticator_Path"
dotnet publish -c Release -p:PublishDir="$Publish_Path" -f net7.0-macos
dotnet publish -c Release -p:PublishDir="$Publish_Path" -f net7.0-macos -p:EnableCodeSigning=true -p:CodesignKey="$CodesignKey_Name"
Copy_Plugins "$Plugins_Release_Path/net7.0-macos" "Authenticator" "BD.WTTS.Client.Plugins.Authenticator.dll"
echo "编译账户插件"
Plugins_GameAccount_Path="$Base_Path/src/BD.WTTS.Client.Plugins.GameAccount"
cd "$Plugins_GameAccount_Path"
dotnet publish -c Release -p:PublishDir="$Publish_Path" -f net7.0-macos
dotnet publish -c Release -p:PublishDir="$Publish_Path" -f net7.0-macos -p:EnableCodeSigning=true -p:CodesignKey="$CodesignKey_Name"
Copy_Plugins "$Plugins_Release_Path/net7.0-macos" "GameAccount" "BD.WTTS.Client.Plugins.GameAccount.dll"
echo "编译游戏库插件"
Plugins_GameList_Path="$Base_Path/src/BD.WTTS.Client.Plugins.GameList"
cd "$Plugins_GameList_Path"
dotnet publish -c Release -p:PublishDir="$Publish_Path" -f net7.0-macos
dotnet publish -c Release -p:PublishDir="$Publish_Path" -f net7.0-macos -p:EnableCodeSigning=true -p:CodesignKey="$CodesignKey_Name"
Copy_Plugins "$Plugins_Release_Path/net7.0-macos" "GameList" "BD.WTTS.Client.Plugins.GameList.dll"
echo "复制插件到程序目录"
@@ -72,10 +74,8 @@ if [ "$Build_Mode" = "any" ]; then
cp -r "$App_Modules_Path" "$Plugins_Release_Path/net7.0-macos/Steam++.app/Contents/MonoBundle"
elif [ "$Build_Mode" = "arm64" ]; then
cp -r "$App_Modules_Path" "$Plugins_Release_Path/net7.0-macos/osx-arm64/Steam++.app/Contents/MonoBundle"
cp -r "$Plugins_Release_Path/net7.0-macos/Steam++.app/Contents/Resources" "$Plugins_Release_Path/net7.0-macos/osx-arm64/Steam++.app/Contents"
cp -r "$Plugins_Release_Path/net7.0-macos/Steam++.app/Contents/Info.plist" "$Plugins_Release_Path/net7.0-macos/osx-arm64/Steam++.app/Contents"
cp -r "$Plugins_Release_Path/net7.0-macos/Steam++.app/Contents/Resources" "$Plugins_Release_Path/net7.0-macos/Steam++.app/Contents"
elif [ "$Build_Mode" = "x64" ]; then
cp -r "$App_Modules_Path" "$Plugins_Release_Path/net7.0-macos/osx-x64/Steam++.app/Contents/MonoBundle"
cp -r "$Plugins_Release_Path/net7.0-macos/Steam++.app/Contents/Resources" "$Plugins_Release_Path/net7.0-macos/osx-x64/Steam++.app/Contents"
cp -r "$Plugins_Release_Path/net7.0-macos/Steam++.app/Contents/Info.plist" "$Plugins_Release_Path/net7.0-macos/osx-arm64/Steam++.app/Contents"
cp -r "$Plugins_Release_Path/net7.0-macos/Steam++.app/Contents/Resources" "$Plugins_Release_Path/net7.0-macos/Steam++.app/Contents"
fi
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.
+6 -6
View File
@@ -12,20 +12,20 @@ public static partial class AssemblyInfo
public const string Version = "3.0.0";
/// <summary>
/// 预览版本号,范围 1~9
/// 预览版本号,范围 1~9,只增不减
/// </summary>
const string ver_for_preview = "3";
const string ver_for_preview = "7";
/// <summary>
/// RC 版本号,范围 0~9
/// RC 版本号,范围 0~9,只增不减
/// </summary>
const string ver_for_rc = "0";
const string ver_for_rc = "1";
public const string FileVersion = $"{Version}.{ver_for_rc}0{ver_for_preview}";
//public const string InformationalVersion = Version;
public const string InformationalVersion = $"{Version}-preview.{ver_for_preview}";
//public const string InformationalVersion = $"{Version}-rc.{ver_for_rc}";
//public const string InformationalVersion = $"{Version}-preview.{ver_for_preview}";
public const string InformationalVersion = $"{Version}-rc.{ver_for_rc}";
#if !APP_HOST
/// <summary>
Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 787 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
xmlns:desktop2="http://schemas.microsoft.com/appx/manifest/desktop/windows10/2"
IgnorableNamespaces="uap rescap desktop desktop2">
<Identity
Name="4651ED44255E.47979655102CE"
Publisher="CN=A90E406B-B2D3-4A23-B061-0FA1D65C4F66"
Version="3.0.0.0" />
<Properties>
<DisplayName>Watt Toolkit</DisplayName>
<PublisherDisplayName>软妹币玩家</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="Watt Toolkit"
Description="「Watt Toolkit」是一个开源跨平台的多功能游戏工具箱,此工具的大部分功能都是需要您下载安装 Steam 才能使用。"
BackgroundColor="transparent"
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png" Square71x71Logo="Images\SmallTile.png" Square310x310Logo="Images\LargeTile.png" ShortName="Steam++">
<uap:ShowNameOnTiles>
<uap:ShowOn Tile="square150x150Logo"/>
<uap:ShowOn Tile="wide310x150Logo"/>
<uap:ShowOn Tile="square310x310Logo"/>
</uap:ShowNameOnTiles>
</uap:DefaultTile >
<uap:SplashScreen Image="Images\SplashScreen.png" />
<uap:InitialRotationPreference>
<uap:Rotation Preference="landscape"/>
</uap:InitialRotationPreference>
<uap:LockScreen BadgeLogo="Images\BadgeLogo.png" Notification="badgeAndTileText"/>
</uap:VisualElements>
<Extensions>
<desktop:Extension Category="windows.fullTrustProcess" Executable="Steam++\Steam++.exe" />
<desktop:Extension Category="windows.startupTask" Executable="Steam++\Steam++.exe" EntryPoint="Windows.FullTrustApplication">
<desktop:StartupTask TaskId="BootAutoStartTask" Enabled="true" DisplayName="Steam++ System Boot Run" />
</desktop:Extension>
</Extensions>
</Application>
</Applications>
<Extensions>
<desktop2:Extension Category="windows.firewallRules">
<desktop2:FirewallRules Executable="Steam++\Steam++.exe">
<desktop2:Rule Direction="in" IPProtocol="TCP" Profile="all" />
<desktop2:Rule Direction="in" IPProtocol="UDP" Profile="all" />
</desktop2:FirewallRules>
</desktop2:Extension>
</Extensions>
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="runFullTrust" />
<rescap:Capability Name="allowElevation" />
</Capabilities>
</Package>
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<runtime>
<gcServer enabled="false"/>
<GCConserveMemory enabled="9"/>
<legacyCorruptedStateExceptionsPolicy enabled="true"/>
</runtime>
<appSettings>
<add key="d" value="7.0.10"/>
</appSettings>
</configuration>
@@ -0,0 +1,60 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>Steam++</AssemblyName>
<TargetFramework>net472</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings>
<IsTrimmable>false</IsTrimmable>
<OutputType Condition="'$(Configuration)'=='Debug'">Exe</OutputType>
<OutputType Condition="'$(Configuration)'=='Release'">WinExe</OutputType>
<Prefer32Bit>false</Prefer32Bit>
<ApplicationManifest>..\BD.WTTS.Client.AppHost\Properties\app.manifest</ApplicationManifest>
<DefineConstants>APP_HOST;WINDOWS_DEKSTOP_BRIDGE;$(DefineConstants)</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RootNamespace>BD.WTTS</RootNamespace>
<EnableMsixTooling>true</EnableMsixTooling>
<ServerGarbageCollection>false</ServerGarbageCollection>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon Condition="'$(Configuration)'=='Release'">..\..\res\icons\app\v3\Icon.ico</ApplicationIcon>
<ApplicationIcon Condition="'$(Configuration)'=='Debug'">..\..\res\icons\app\v3\Icon.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition=" $(TargetFramework.StartsWith('net4')) OR $(TargetFramework.StartsWith('net3')) ">
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\WattToolkit.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('net4')) OR $(TargetFramework.StartsWith('net3')) ">
<Reference Include="System.Configuration" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<AllowedReferenceRelatedFileExtensions>
<!-- Prevent default XML and PDB files copied to output in RELEASE.
Only *.allowedextension files will be included, which doesn't exist in my case.
-->
.allowedextension
</AllowedReferenceRelatedFileExtensions>
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Compile Remove="..\ImplicitUsings.Common.cs" />
<Compile Include="..\AssemblyInfo.Constants.cs">
<LinkBase>Properties</LinkBase>
</Compile>
<Compile Include="..\BD.WTTS.Client\Startup\Startup.CompatibilityCheck.cs" />
<Compile Condition="'$(Configuration)'=='Debug'" Include="..\Utils.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\BD.WTTS.Client.AppHost\**\*.cs" />
<Compile Remove="..\BD.WTTS.Client.AppHost\bin\**" />
<Compile Remove="..\BD.WTTS.Client.AppHost\obj\**" />
</ItemGroup>
</Project>
+2
View File
@@ -143,7 +143,9 @@ static unsafe partial class Program
Architecture.X64 => "x64",
Architecture.Arm => "Arm32",
Architecture.Arm64 => "Arm64",
#if !NETFRAMEWORK
Architecture.Armv6 => "Armv6",
#endif
_ => throw new ArgumentOutOfRangeException(nameof(architecture), architecture, null),
};
+1 -1
View File
@@ -153,7 +153,7 @@ static class Strings
public static string Error_IncompatibleOS => GetString(l => l switch
{
Language.ChineseSimplified => "此应用程序仅兼容 Windows 11 与 Windows 10 版本 1809(OS 内部版本 17763)或更高版本",
Language.ChineseTraditional => "此應用程序僅相容 Windows 11 與 Windows 10 版本 1809(OS 內部版本17763)或更高版本",
Language.ChineseTraditional => "此應用程序僅相容 Windows 11 與 Windows 10 版本 1809(OS 內部版本 17763)或更高版本",
Language.Spanish => "Esta aplicación solo es compatible con Windows 11 y Windows 10 versión 1809 (versión interna del sistema operativo 17763) o superior",
Language.Italian => "Questa applicazione è compatibile solo con Windows 11 e Windows 10 versione 1809 (versione interna del sistema operativo 17763) o superiore",
Language.Japanese => "このアプリケーションは、Windows 11およびWindows 10 バージョン1809(OS内部バージョン17763)以降にのみ対応しています",
@@ -2,7 +2,7 @@
"profiles": {
"BD.WTTS.Client.Avalonia.App": {
"commandName": "Project",
"commandLineArgs": "-clt devtools"
"commandLineArgs": "-clt devtools -steamrun"
}
}
}
+26 -1
View File
@@ -58,6 +58,7 @@ sealed partial class Program : Startup
// Essentials
#if LINUX
services.TryAddSingleton<IApplicationVersionService, Essentials_AppVerS>();
services.AddSingleton<IDeviceInfoPlatformService, LinuxDeviceInfoPlatformServiceImpl>();
#else
#if WINDOWS
#if AVALONIA
@@ -199,7 +200,7 @@ sealed partial class Program : Startup
WatchTrace.Record("ConfigureDemandServices.Notification");
#endif
if (HasHosts)
if (HasHosts || HasIPCRoot)
{
// hosts 文件助手服务
services.AddHostsFileService();
@@ -252,6 +253,30 @@ sealed partial class Program : Startup
string IApplicationVersionService.AssemblyTrademark => AssemblyInfo.Trademark;
}
#if LINUX
sealed class LinuxDeviceInfoPlatformServiceImpl : IDeviceInfoPlatformService
{
public string Model => "";
public string Manufacturer => "";
public string Name => "";
public string VersionString => Environment.OSVersion.VersionString;
public DeviceType DeviceType => DeviceType.Physical;
public bool IsChromeOS => false;
public bool IsWinUI => false;
public bool IsUWP => false;
public DeviceIdiom Idiom => DeviceIdiom.Desktop;
}
#endif
#if AVALONIA && WINDOWS
sealed class AvaWinDeviceInfoPlatformServiceImpl :
Common.Services.Implementation.Essentials.DeviceInfoPlatformServiceImpl
@@ -0,0 +1,21 @@
namespace BD.WTTS.Converters;
public sealed class VisbleStringConverter : IMultiValueConverter
{
public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
{
if (values.Count >= 3 && values.FirstOrDefault() is bool isVisble)
{
if (isVisble)
{
return values[1];
}
else
{
return values[2];
}
}
return values;
}
}
@@ -34,6 +34,8 @@ sealed class AvaloniaApplicationUpdateServiceImpl : AppUpdateServiceBaseImpl
protected override async void OnExistNewVersion()
{
base.OnExistNewVersion();
var hasActiveWindow = App.Instance.HasActiveWindow();
if (hasActiveWindow)
{
@@ -1,4 +1,6 @@
#if LINUX
using static System.Net.Mime.MediaTypeNames;
namespace BD.WTTS.Services.Implementation;
public sealed class AvaloniaClipboardPlatformService : IClipboardPlatformService
@@ -28,7 +30,9 @@ public sealed class AvaloniaClipboardPlatformService : IClipboardPlatformService
var clipboard = topLevel.Clipboard;
if (clipboard != null)
{
await clipboard.SetTextAsync(text);
//不能用 await 等待 Linux 上不知啥原因导致卡死
clipboard.SetTextAsync(text).GetAwaiter();
await Task.CompletedTask;
}
}
}
@@ -197,11 +197,27 @@ sealed class AvaloniaFilePickerPlatformService : BaseService, IServiceBase, IOpe
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static IReadOnlyList<APS_FilePickerFileType>? Convert(IFilePickerFileType? fileTypes)
{
if (fileTypes is FilePickerFileTypeWrapper impl)
if (fileTypes is AvaloniaFilePickerFileTypeFilter ava)
{
var items = ava.Values;
if (items != null)
{
var query = from m in items
select new APS_FilePickerFileType(m.Name)
{
Patterns = m.Patterns,
AppleUniformTypeIdentifiers = m.AppleUniformTypeIdentifiers,
MimeTypes = m.MimeTypes,
};
return query.ToArray();
}
return null;
}
else if (fileTypes is FilePickerFileTypeWrapper impl)
{
return impl.Values;
}
if (fileTypes is FilePickerFileType.IFilePickerFileTypeWithName @interface)
else if (fileTypes is FilePickerFileType.IFilePickerFileTypeWithName @interface)
{
var values = @interface.GetFileTypes();
if (values.Any())
@@ -1,6 +1,8 @@
using Avalonia.Controls;
using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Media.Animation;
using FluentAvalonia.UI.Navigation;
using System.Xml.Linq;
namespace BD.WTTS.Services.Implementation;
@@ -50,11 +52,20 @@ public sealed class NavigationService : INavigationService
_overlayHost = p;
}
public void Navigate(Type? t, NavigationTransitionEffect effect = NavigationTransitionEffect.None)
public void Navigate(Type? t, NavigationTransitionEffect effect = NavigationTransitionEffect.None, bool useCache = true)
{
_frame.ThrowIsNull();
var navOptions = new FrameNavigationOptions
{
IsNavigationStackEnabled = useCache,
TransitionInfoOverride = GetNavigationTransitionInfo(effect)
};
if (t == null)
{
_frame?.Navigate(typeof(ErrorPage), null, GetNavigationTransitionInfo(effect));
navOptions.IsNavigationStackEnabled = false;
_frame.NavigateToType(typeof(ErrorPage), null, navOptions);
return;
}
@@ -66,19 +77,45 @@ public sealed class NavigationService : INavigationService
if (t == null)
{
_frame?.Navigate(typeof(ErrorPage), null, GetNavigationTransitionInfo(effect));
navOptions.IsNavigationStackEnabled = false;
_frame.NavigateToType(typeof(ErrorPage), null, navOptions);
return;
}
if (_frame?.Content?.GetType() != t)
if (_frame.Content?.GetType() != t)
{
_frame?.Navigate(t, null, GetNavigationTransitionInfo(effect));
_frame.NavigateToType(t, null, navOptions);
//if (!useCache && navOptions.IsNavigationStackEnabled)
//{
// _frame.BackStack.Remove(_frame.BackStack.Last());
//}
}
}
public void GoBack()
public void GoBack(Type? t = null)
{
_frame?.GoBack();
if (t == null)
{
_frame?.GoBack();
return;
}
if (t.IsSubclassOf(typeof(ViewModelBase)))
{
var pageType = GetViewModelToPageContent(t, false);
t = pageType as Type;
}
if (t == null)
{
_frame?.GoBack();
return;
}
if (_frame?.CurrentSourcePageType == t)
{
_frame?.GoBack();
}
}
public void NavigateFromContext(object dataContext, NavigationTransitionEffect effect = NavigationTransitionEffect.None)
@@ -105,7 +142,6 @@ public sealed class NavigationService : INavigationService
public void ClearOverlay()
{
_overlayHost?.Children.Clear();
}
private static NavigationTransitionInfo GetNavigationTransitionInfo(NavigationTransitionEffect effect)
@@ -142,11 +142,56 @@ partial class App : IApplication
object IApplication.CurrentPlatformUIHost => MainWindow!;
DeploymentMode IApplication.DeploymentMode => DeploymentMode.
#if FRAMEWORK_DEPENDENT || !PUBLISH
FDE
#else
SCD
#endif
;
public System.Drawing.Size? GetScreenSize()
{
try
{
var window = GetFirstOrDefaultWindow();
var screen = window?.Screens?.Primary;
if (screen != default)
{
return new(screen.Bounds.Width, screen.Bounds.Height);
}
}
catch
{
}
return null;
}
public bool? IsAnyWindowNotMinimized()
{
try
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime l)
{
foreach (var window in l.Windows)
{
static bool WindowIntersectsWithAnyScreen(Window window)
{
static bool IntersectsWith(Rect rect, PixelRect @this)
{
if (rect.X < @this.X + @this.Width && @this.X < rect.X + rect.Width && rect.Y < @this.Y + @this.Height)
{
return @this.Y < rect.Y + rect.Height;
}
return false;
}
return window.Screens.All.Any(screen => IntersectsWith(window.Bounds, screen.Bounds));
}
if (window.WindowState != WindowState.Minimized && WindowIntersectsWithAnyScreen(window))
{
return true;
}
}
}
}
catch
{
}
return default;
}
}
+27 -1
View File
@@ -1,4 +1,6 @@
using BD.SteamClient.Services;
using BD.WTTS.Client.Resources;
using BD.WTTS.Converters;
using static BD.WTTS.Services.INotificationService;
namespace BD.WTTS.UI;
@@ -39,7 +41,31 @@ partial class App
//new NativeMenuItemSeparator(),
new NativeMenuItem
{
Header = "打开主面板",
[!NativeMenuItem.HeaderProperty] = new MultiBinding {
Bindings = new List<Avalonia.Data.IBinding>()
{
new Binding { Path = "IsRunningSteamProcess", Source = SteamConnectService.Current, Mode = BindingMode.OneWay },
new Binding { Path = "Res.CloseSteam", Source = ResourceService.Current, Mode = BindingMode.OneWay },
new Binding { Path = "Res.StartSteam", Source = ResourceService.Current, Mode = BindingMode.OneWay },
},
Converter = (VisbleStringConverter)App.Instance.FindResource("VisbleStringConverter")!,
},
Command = ReactiveCommand.Create(() =>
{
if(ISteamService.Instance.IsRunningSteamProcess)
{
ISteamService.Instance.TryKillSteamProcess();
}
else
{
ISteamService.Instance.StartSteamWithParameter();
}
})
},
new NativeMenuItemSeparator(),
new NativeMenuItem
{
[!NativeMenuItem.HeaderProperty] = new Binding { Path = "Res.OpenMainWindow", Source = ResourceService.Current, Mode = BindingMode.OneWay },
Command = ReactiveCommand.Create(RestoreMainWindow)
},
new NativeMenuItemSeparator(),
+1
View File
@@ -17,6 +17,7 @@
<spp:EnumEqualValueConverter x:Key="EnumEqualValueConverter" />
<spp:StringEqualsConverter x:Key="StringEqualsConverter" />
<spp:EnumLocalizationNameConverter x:Key="EnumLocalizationNameConverter" />
<spp:VisbleStringConverter x:Key="VisbleStringConverter" />
</Application.Resources>
<Application.Styles>
<sty:FluentAvaloniaTheme PreferSystemTheme="False" PreferUserAccentColor="True" />
@@ -42,6 +42,32 @@ public sealed partial class App : Application
try
{
AvaloniaXamlLoader.Load(this);
#if WINDOWS || LINUX || MACOS
if (Startup.Instance.IsSteamRun)
{
try
{
Steamworks.Dispatch.OnException = (e) =>
{
Log.Error(nameof(Steamworks), e, "Steamworks.SteamClient OnException.");
};
// Init Client
Steamworks.SteamClient.Init(2425030);
//if (Steamworks.SteamClient.IsValid)
//{
// Steamworks.SteamFriends.SetRichPresence("steam_display", "#Status_AtMainMenu");
// //var r = Steamworks.SteamFriends.GetRichPresence("steam_display");
//}
}
catch (Exception ex)
{
Log.Error(nameof(Steamworks), ex, "Steamworks.SteamClient Init");
}
}
#endif
}
catch (Exception ex)
{
@@ -20,8 +20,8 @@
IsVisible="{TemplateBinding IsLoading}"
Spacing="8">
<spp:Image2
Width="150"
Height="150"
Width="100"
Height="100"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
RenderOptions.BitmapInterpolationMode="HighQuality"
@@ -31,6 +31,14 @@
HorizontalAlignment="Center"
Text="{Binding Path=Res.GameList_IsLoading, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
Theme="{StaticResource SubtitleTextBlockStyle}" />
<TextBlock
HorizontalAlignment="Center"
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
IsVisible="{TemplateBinding CustomLoadingText,
Converter={StaticResource IsNullConverter},
ConverterParameter=invert}"
Text="{TemplateBinding CustomLoadingText}"
Theme="{StaticResource BodyStrongTextBlockStyle}" />
<Border
Width="35"
Height="35"
@@ -157,6 +157,7 @@
<TextBlock
Name="ControlNameTextBlock"
FontSize="36"
MaxLines="2"
Text="{TemplateBinding Title}"
Theme="{StaticResource TitleTextBlockStyle}">
<TextBlock.Transitions>
@@ -174,6 +175,7 @@
<TextBlock
FontStyle="Italic"
Foreground="{DynamicResource AccentTextFillColorPrimaryBrush}"
MaxLines="2"
Text="{TemplateBinding Subtitle}"
Theme="{StaticResource CaptionTextBlockStyle}" />
</Button>
@@ -182,6 +184,7 @@
FontStyle="Italic"
Foreground="{DynamicResource TextFillColorTertiaryBrush}"
IsVisible="False"
MaxLines="4"
Text="{Binding Path=Description, RelativeSource={RelativeSource TemplatedParent}}"
Theme="{StaticResource CaptionTextBlockStyle}" />
</StackPanel>
@@ -270,6 +273,11 @@
</Setter>
</Style>
<Style Selector="spp|PageBase:namespace /template/ Panel#OptionsRegion Button">
<Setter Property="MaxWidth" Value="200" />
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
</Style>
<Style Selector="spp|PageBase:namespace /template/ Button#NamespaceText">
<Setter Property="IsVisible" Value="True" />
</Style>
@@ -163,9 +163,9 @@ public class PageBase : UserControl
{
var sz = e.NewSize.Width;
bool isSmallWidth2 = sz < 580;
bool isSmallWidth2 = sz < 640;
PseudoClasses.Set(":smallWidth", sz < 710);
PseudoClasses.Set(":smallWidth", sz < 800);
PseudoClasses.Set(":smallWidth2", isSmallWidth2);
if (isSmallWidth2 && !_isSmallWidth2)
@@ -48,6 +48,12 @@ public class ContentLoader : ContentControl
public static readonly StyledProperty<bool> IsShowNoResultTextProperty =
AvaloniaProperty.Register<ContentLoader, bool>(nameof(IsShowNoResultText), false);
/// <summary>
/// Defines the <see cref="CustomLoadingText"/> property
/// </summary>
public static readonly StyledProperty<string?> CustomLoadingTextProperty =
AvaloniaProperty.Register<ContentLoader, string?>(nameof(CustomLoadingText), null);
/// <summary>
/// 是否正在加载中
/// </summary>
@@ -69,6 +75,15 @@ public class ContentLoader : ContentControl
set => SetValue(IsShowNoResultTextProperty, value);
}
/// <summary>
/// 自定义加载提示
/// </summary>
public string? CustomLoadingText
{
get => GetValue(CustomLoadingTextProperty);
set => SetValue(CustomLoadingTextProperty, value);
}
/// <summary>
/// 无结果时提示
/// </summary>
@@ -76,26 +76,14 @@ public sealed class CustomFilePicker : ContentControl
private async void CustomFilePicker_Tapped(object? sender, RoutedEventArgs e)
{
//if (string.IsNullOrEmpty(FileExtensions) || FileExtensions == "*")
//{
// fileTypes = new ValueTuple<string, string[]>[] { ("All Files", new[] { "*" }) };
//}
//else
//{
// fileTypes = new ValueTuple<string, string[]>[] {
// ("Required Files", FileExtensions.Split(",")),
// ("All Files", new[] { "*" }),
// };
//}
var result = await FilePicker2.PickAsync(PickOptions.Images);
if (result != null)
{
FileName = result.FullPath;
}
else
{
Toast.Show(ToastIcon.Warning, Strings.PleaseSelect);
}
//else
//{
// Toast.Show(ToastIcon.Warning, Strings.PleaseSelect);
//}
}
}
@@ -3,6 +3,9 @@
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:generic="using:System.Collections.Generic"
xmlns:i="using:Avalonia.Xaml.Interactivity"
xmlns:ia="using:Avalonia.Xaml.Interactions.Core"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:spp="https://steampp.net/ui"
xmlns:ui="using:FluentAvalonia.UI.Controls"
@@ -32,7 +35,7 @@
ClipToBounds="True"
CornerRadius="8">
<Panel>
<Carousel Name="Carousel" Grid.Column="1">
<Carousel Name="CarouselControl" Grid.Column="1">
<Carousel.PageTransition>
<PageSlide Orientation="Horizontal" Duration="0.25" />
</Carousel.PageTransition>
@@ -68,15 +71,43 @@
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<DataTemplate>
<Button Padding="0" Classes="Plain">
<DataTemplate.DataType>
<x:Type x:TypeArguments="x:Int32, x:String" TypeName="generic:KeyValuePair" />
</DataTemplate.DataType>
<Button
Padding="0"
Classes="Plain"
Click="CarouselBannerIndexButton_Click"
Tag="{Binding Key}">
<Ellipse
Name="IndexEllipse"
Width="10"
Height="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="{ReflectionBinding}"
Fill="{Binding Value}"
Opacity="0.6"
StrokeThickness="0" />
<!--<i:Interaction.Behaviors>
<ia:DataTriggerBehavior
Binding="{Binding}"
ComparisonCondition="Equal"
Value="{Binding #Carousel.SelectedIndex}">
<ia:ChangePropertyAction
PropertyName="Fill"
TargetObject="IndexEllipse"
Value="White" />
</ia:DataTriggerBehavior>
<ia:DataTriggerBehavior
Binding="{Binding}"
ComparisonCondition="NotEqual"
Value="{Binding #Carousel.SelectedIndex}">
<ia:ChangePropertyAction
PropertyName="Fill"
TargetObject="IndexEllipse"
Value="Gray" />
</ia:DataTriggerBehavior>
</i:Interaction.Behaviors>-->
</Button>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
@@ -73,14 +73,14 @@ namespace BD.WTTS.UI.Views.Controls
Left.Click += (s, e) => SwiperPrevious();
Right.Click += (s, e) => SwiperNext();
//Carousel[!Carousel.Items] = this[!Items];
Carousel[!Carousel.ItemsSourceProperty] = this[!ItemsSourceProperty];
Carousel[!Carousel.ItemTemplateProperty] = this[!ItemTemplateProperty];
//CarouselControl[!Carousel.Items] = this[!Items];
CarouselControl[!Carousel.ItemsSourceProperty] = this[!ItemsSourceProperty];
CarouselControl[!Carousel.ItemTemplateProperty] = this[!ItemTemplateProperty];
this.GetObservable(ItemsSourceProperty)
.Subscribe(_ => SwipersLoad());
Carousel.GetObservable(Carousel.SelectedIndexProperty)
CarouselControl.GetObservable(Carousel.SelectedIndexProperty)
.Subscribe(x => SwipersLoad());
this.GetObservable(AutoScrollProperty)
@@ -107,14 +107,22 @@ namespace BD.WTTS.UI.Views.Controls
});
}
private void CarouselBannerIndexButton_Click(object? sender, RoutedEventArgs e)
{
if (sender is Button button && button.Tag is int index)
{
CarouselControl.SelectedIndex = index;
}
}
private void SwipersLoad()
{
if (Carousel.ItemCount <= 0)
if (CarouselControl.ItemCount <= 0)
{
Swiper.ItemsSource = null;
return;
}
if (Carousel.ItemCount == 1)
if (CarouselControl.ItemCount == 1)
{
Left.IsVisible = Right.IsVisible = Swiper.IsVisible = false;
return;
@@ -122,12 +130,12 @@ namespace BD.WTTS.UI.Views.Controls
else
{
Left.IsVisible = Right.IsVisible = Swiper.IsVisible = true;
var arr = new string[Carousel.ItemCount];
for (var i = 0; i < arr.Length; i++)
var arr = new Dictionary<int, string>();
for (var i = 0; i < CarouselControl.ItemCount; i++)
{
arr[i] = "#ADADAD";
arr.Add(i, "#ADADAD");
}
var index = Carousel.SelectedIndex < 0 ? 0 : Carousel.SelectedIndex;
var index = CarouselControl.SelectedIndex < 0 ? 0 : CarouselControl.SelectedIndex;
arr[index] = "#FFFFFF";
Swiper.ItemsSource = arr;
@@ -136,29 +144,29 @@ namespace BD.WTTS.UI.Views.Controls
private void SwiperNext()
{
if (Carousel.ItemCount < 1)
if (CarouselControl.ItemCount < 1)
return;
if (Carousel.SelectedIndex < Carousel.ItemCount - 1)
if (CarouselControl.SelectedIndex < CarouselControl.ItemCount - 1)
{
Carousel.Next();
CarouselControl.Next();
}
else
{
Carousel.SelectedIndex = 0;
CarouselControl.SelectedIndex = 0;
}
}
private void SwiperPrevious()
{
if (Carousel.ItemCount < 1)
if (CarouselControl.ItemCount < 1)
return;
if (Carousel.SelectedIndex > 0)
if (CarouselControl.SelectedIndex > 0)
{
Carousel.Previous();
CarouselControl.Previous();
}
else
{
Carousel.SelectedIndex = Carousel.ItemCount - 1;
CarouselControl.SelectedIndex = CarouselControl.ItemCount - 1;
}
}
}

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