Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9eb5def6f0 | ||
|
|
2467ce9bb4 | ||
|
|
f968f3f66a | ||
|
|
511a2fa366 | ||
|
|
5ed54bd72e | ||
|
|
91ecfa342a | ||
|
|
be1481d063 | ||
|
|
fce80b18ee | ||
|
|
211daa428a | ||
|
|
781fd9489f | ||
|
|
680586b6e9 | ||
|
|
35ee526efc | ||
|
|
2f0090d571 | ||
|
|
2f6ad43382 | ||
|
|
20056583a3 | ||
|
|
77dc0abd2a | ||
|
|
ddf6486af6 | ||
|
|
0229003e19 | ||
|
|
8486edf6b8 | ||
|
|
fe941e1271 | ||
|
|
81129afc8f | ||
|
|
566cc4c017 | ||
|
|
0925ec9104 | ||
|
|
cac4a9370a | ||
|
|
e32fade0ea | ||
|
|
f6554a3b21 | ||
|
|
d00572d97d | ||
|
|
56e3563634 | ||
|
|
9355c317ac | ||
|
|
35b5edd09a | ||
|
|
ab22ea1113 | ||
|
|
62c015ad0b | ||
|
|
195f5269be | ||
|
|
b1fa5b4a4d | ||
|
|
7778854007 | ||
|
|
68bbd8b3e3 | ||
|
|
137a2dcde9 | ||
|
|
ef239c5dc2 | ||
|
|
1fd4d4e35a | ||
|
|
a71ff13d49 | ||
|
|
56f9be173a | ||
|
|
6e3e84c9c3 | ||
|
|
a55e28600f | ||
|
|
31dd805a6d | ||
|
|
aeac99fc1c | ||
|
|
5b9bc9e00b | ||
|
|
5c3ab25271 | ||
|
|
1e8d373df5 | ||
|
|
f226aeb8a9 | ||
|
|
3f0422cfbb | ||
|
|
af89dddc4c | ||
|
|
55f2c519b2 | ||
|
|
527f5fb8a4 | ||
|
|
8139a7414d | ||
|
|
0367fc027e | ||
|
|
c80f4de55b | ||
|
|
9c01b74a4b | ||
|
|
894f8d4239 | ||
|
|
6dcda63be6 | ||
|
|
7f9840c3ee | ||
|
|
8a1b60dcbb | ||
|
|
23e62c2fac | ||
|
|
ce56e4e1dd | ||
|
|
798efb5873 | ||
|
|
0261fa4460 | ||
|
|
fb9faf53af | ||
|
|
ef3006861e | ||
|
|
c3a92d31d2 | ||
|
|
f37afe1aa0 | ||
|
|
7df6b0d007 | ||
|
|
632ddd44e3 | ||
|
|
17f03a523c | ||
|
|
f2c1df5b35 | ||
|
|
166e258b38 | ||
|
|
f95d1c3515 | ||
|
|
bf5dbf9435 | ||
|
|
66a92f8363 | ||
|
|
5dec270ff5 | ||
|
|
ae5b881b30 | ||
|
|
ac84585630 | ||
|
|
16e766f54a | ||
|
|
eec99d64c6 | ||
|
|
2b5892348c | ||
|
|
751875b05a | ||
|
|
a35f612d3d | ||
|
|
b45c989062 | ||
|
|
1c386dd87c | ||
|
|
8669667118 | ||
|
|
9887b9e125 | ||
|
|
afb0dc7319 | ||
|
|
e61ebea90e | ||
|
|
3578311463 | ||
|
|
c383c900f8 | ||
|
|
4b05d368d6 | ||
|
|
989ed16b00 | ||
|
|
0d2d6d6438 | ||
|
|
62909aa651 | ||
|
|
c0d735d9cf | ||
|
|
93531ea3d9 | ||
|
|
e937ab1b35 | ||
|
|
a730339153 | ||
|
|
c4a7dd7994 |
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
[English](./README.en.md) | 简体中文
|
||||
|
||||
「Watt Toolkit」是一个开源跨平台的多功能游戏工具箱,此工具的大部分功能都是需要您下载安装 Steam 才能使用。
|
||||
|
||||
|
||||

|
||||
[](https://github.com/BeyondDimension/SteamTools/releases/latest)
|
||||
[](LICENSE)
|
||||
@@ -30,6 +30,7 @@
|
||||
</div>
|
||||
|
||||
## 🚀 下载渠道
|
||||
- [](https://store.steampowered.com/app/2425030)
|
||||
- [](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)
|
||||
|
||||
@@ -5,11 +5,13 @@ dotnet_exec="$dotnet_path/dotnet"
|
||||
export DOTNET_ROOT="$dotnet_path"
|
||||
link_exec="$run_path/Steam++"
|
||||
# 判断符号链接是否存在
|
||||
if [ ! -L "$link_exec" ]; then
|
||||
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"
|
||||
else
|
||||
echo "符号链接 $link_exec 已存在"
|
||||
chmod +x "$link_exec"
|
||||
fi
|
||||
"$link_exec" "$run_path/assemblies/Steam++.dll" "$@"
|
||||
exit
|
||||
"$link_exec" "$run_path/assemblies/Steam++.dll" "$@"
|
||||
exit
|
||||
|
||||
@@ -1,48 +1,58 @@
|
||||
#!/bin/bash
|
||||
base_path="$HOME/WattToolkit"
|
||||
export LC_ALL=en_US.UTF-8
|
||||
|
||||
Install_certutil() {
|
||||
# 判断发行版类型
|
||||
if [ "$1" = "-c" ]; then
|
||||
# 只验证 certutil 是否可用
|
||||
if command -v certutil &>/dev/null; then
|
||||
echo "certutil 工具已安装。"
|
||||
exit 200
|
||||
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
|
||||
echo "请手动安装 certutil 工具。"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
Install_certutil() {
|
||||
# 判断发行版类型
|
||||
if command -v certutil &>/dev/null; then
|
||||
echo "certutil 工具已安装。"
|
||||
else
|
||||
echo "请手动安装 certutil 工具。"
|
||||
exit 1
|
||||
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
|
||||
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
|
||||
}
|
||||
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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/bin/bash
|
||||
# 判断是否提供了 Build_Mode 参数
|
||||
if [ -z "$1" ]; then
|
||||
Build_Mode="any" # 如果没有提供参数,则设置默认值为 "any"
|
||||
@@ -9,10 +10,12 @@ 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 code"
|
||||
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 +37,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 +75,22 @@ 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
|
||||
|
||||
echo "代码签名重新手动签名"
|
||||
App_Publish_Path="$App_Path/bin/Release/net7.0-macos/Steam++.app"
|
||||
# #代码签名重新手动签名
|
||||
codesign --remove-signature "$App_Publish_Path"
|
||||
codesign --remove-signature "$App_Publish_Path/Contents/MacOS/Steam++"
|
||||
dylibs=$(find "$App_Publish_Path/Contents/MonoBundle" -type f -name "*.dylib")
|
||||
for dylib in $dylibs; do
|
||||
codesign --remove-signature "$dylib"
|
||||
codesign -f -s "$CodesignKey_Name" "$dylib"
|
||||
done
|
||||
codesign -f -s "$CodesignKey_Name" "$App_Publish_Path/Contents/MacOS/Steam++"
|
||||
codesign -f -s "$CodesignKey_Name" "$App_Publish_Path"
|
||||
sudo xattr -rd com.apple.quarantine "$App_Publish_Path"
|
||||
|
||||
@@ -498,7 +498,7 @@
|
||||
{
|
||||
"TypeName": "bool",
|
||||
"PropertyName": "GameInstalledFilter",
|
||||
"DefaultValue": "true",
|
||||
"DefaultValue": "false",
|
||||
"DefaultValueIsConst": true,
|
||||
"Summary": "已安装游戏筛选",
|
||||
"IsRegionOrEndregion": null,
|
||||
@@ -943,6 +943,24 @@
|
||||
},
|
||||
{
|
||||
"Sharp": "endif"
|
||||
},
|
||||
{
|
||||
"TypeName": "bool",
|
||||
"PropertyName": "UseDoh",
|
||||
"DefaultValue": "true",
|
||||
"DefaultValueIsConst": true,
|
||||
"Summary": "启用 DNS over HTTPS",
|
||||
"IsRegionOrEndregion": null,
|
||||
"IsValueType": null
|
||||
},
|
||||
{
|
||||
"TypeName": "string",
|
||||
"PropertyName": "CustomDohAddres",
|
||||
"DefaultValue": "null",
|
||||
"DefaultValueIsConst": true,
|
||||
"Summary": "自定义 DNS over HTTPS 地址",
|
||||
"IsRegionOrEndregion": null,
|
||||
"IsValueType": null
|
||||
}
|
||||
],
|
||||
"Usings": ""
|
||||
|
||||
|
After Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 2.5 KiB |
@@ -5,27 +5,29 @@ namespace BD.WTTS;
|
||||
/// </summary>
|
||||
public static partial class AssemblyInfo
|
||||
{
|
||||
const string Version2 = "3.0";
|
||||
|
||||
/// <summary>
|
||||
/// 语义化应用程序版本
|
||||
/// https://semver.org/lang/zh-CN/
|
||||
/// </summary>
|
||||
public const string Version = "3.0.0";
|
||||
public const string Version = $"{Version2}.0";
|
||||
|
||||
/// <summary>
|
||||
/// 预览版本号,范围 1~9
|
||||
/// 预览版本号,范围 1~9,只增不减
|
||||
/// </summary>
|
||||
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 = "2";
|
||||
|
||||
public const string FileVersion = $"{Version}.{ver_for_rc}0{ver_for_preview}";
|
||||
public const string FileVersion = $"{Version2}.{ver_for_rc}0{ver_for_preview}.0";
|
||||
|
||||
//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>
|
||||
|
||||
|
After Width: | Height: | Size: 190 B |
|
After Width: | Height: | Size: 218 B |
|
After Width: | Height: | Size: 231 B |
|
After Width: | Height: | Size: 279 B |
|
After Width: | Height: | Size: 444 B |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 666 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 666 B |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 484 B |
|
After Width: | Height: | Size: 787 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
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.207.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++\modules\Accelerator\Steam++.Accelerator.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.11"/>
|
||||
</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>
|
||||
@@ -10,6 +10,6 @@
|
||||
<legacyCorruptedStateExceptionsPolicy enabled="true"/>
|
||||
</runtime>
|
||||
<appSettings>
|
||||
<add key="d" value="7.0.10"/>
|
||||
<add key="d" value="7.0.11"/>
|
||||
</appSettings>
|
||||
</configuration>
|
||||
@@ -18,7 +18,7 @@ static unsafe partial class Program
|
||||
{
|
||||
dotnet_version_major = "7";
|
||||
dotnet_version_minor = "0";
|
||||
dotnet_version_build = "10";
|
||||
dotnet_version_build = "11";
|
||||
dotnet_version = $"{dotnet_version_major}.{dotnet_version_minor}.{dotnet_version_build}";
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ static unsafe partial class Program
|
||||
//#else
|
||||
// public const string dotnet_version_major = "7";
|
||||
// public const string dotnet_version_minor = "0";
|
||||
// public const string dotnet_version_build = "10";
|
||||
// public const string dotnet_version_build = "11";
|
||||
// public const string dotnet_version = $"{dotnet_version_major}.{dotnet_version_minor}.{dotnet_version_build}";
|
||||
//#endif
|
||||
|
||||
@@ -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,8 +1,7 @@
|
||||
{
|
||||
"profiles": {
|
||||
"BD.WTTS.Client.Avalonia.App": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "-clt devtools"
|
||||
"commandName": "Project"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -248,7 +248,7 @@ sealed partial class Program : Startup
|
||||
|
||||
sealed class Essentials_AppVerS : IApplicationVersionService
|
||||
{
|
||||
string IApplicationVersionService.ApplicationVersion => AssemblyInfo.Version;
|
||||
string IApplicationVersionService.ApplicationVersion => AssemblyInfo.FileVersion;
|
||||
|
||||
string IApplicationVersionService.AssemblyTrademark => AssemblyInfo.Trademark;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,44 +5,19 @@ namespace BD.WTTS.Services.Implementation;
|
||||
/// <inheritdoc cref="IAppUpdateService"/>
|
||||
sealed class AvaloniaApplicationUpdateServiceImpl : AppUpdateServiceBaseImpl
|
||||
{
|
||||
readonly IWindowManager windowManager;
|
||||
|
||||
public AvaloniaApplicationUpdateServiceImpl(
|
||||
IApplication application,
|
||||
INotificationService notificationService,
|
||||
IWindowManager windowManager,
|
||||
IToast toast,
|
||||
IMicroServiceClient client,
|
||||
IOptions<AppSettings> options) : base(application, notificationService, toast, client, options)
|
||||
{
|
||||
this.windowManager = windowManager;
|
||||
|
||||
}
|
||||
|
||||
protected override async Task ShowNewVersionWindowAsync()
|
||||
{
|
||||
await windowManager.ShowAsync(typeof(object), AppEndPoint.NewVersion, isParent: false);
|
||||
}
|
||||
|
||||
public override async void OnMainOpenTryShowNewVersionWindow()
|
||||
{
|
||||
if (ShowNewVersionWindowOnMainOpen)
|
||||
{
|
||||
ShowNewVersionWindowOnMainOpen = false;
|
||||
await ShowNewVersionWindowAsync();
|
||||
}
|
||||
}
|
||||
|
||||
protected override async void OnExistNewVersion()
|
||||
protected override bool HasActiveWindow()
|
||||
{
|
||||
var hasActiveWindow = App.Instance.HasActiveWindow();
|
||||
if (hasActiveWindow)
|
||||
{
|
||||
await ShowNewVersionWindowAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowNewVersionWindowOnMainOpen = true;
|
||||
notification.Notify(AppResources.NewVersionUpdateNotifyText_.Format(NewVersionInfo?.Version), NotificationType.NewVersion);
|
||||
}
|
||||
return hasActiveWindow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@ public sealed class NavigationService : INavigationService
|
||||
{
|
||||
public static NavigationService Instance { get; } = (NavigationService)Ioc.Get<INavigationService>();
|
||||
|
||||
public Control? PreviousPage { get; set; }
|
||||
//public Type? PreviousPage { get; set; }
|
||||
|
||||
public Type? CurrnetPage => _frame?.CurrentSourcePageType;
|
||||
|
||||
public object? GetViewModelToPageContent(object viewModel, bool isCreateInstance = true)
|
||||
{
|
||||
@@ -54,7 +56,8 @@ public sealed class NavigationService : INavigationService
|
||||
|
||||
public void Navigate(Type? t, NavigationTransitionEffect effect = NavigationTransitionEffect.None, bool useCache = true)
|
||||
{
|
||||
_frame.ThrowIsNull();
|
||||
if (_frame == null)
|
||||
return;
|
||||
|
||||
var navOptions = new FrameNavigationOptions
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,16 @@
|
||||
using Avalonia.Controls;
|
||||
using BD.SteamClient.Services;
|
||||
using BD.WTTS.Client.Resources;
|
||||
using BD.WTTS.Converters;
|
||||
using System.Collections.Specialized;
|
||||
using static BD.WTTS.Services.INotificationService;
|
||||
|
||||
namespace BD.WTTS.UI;
|
||||
|
||||
partial class App
|
||||
{
|
||||
public Dictionary<string, TrayMenuItem> TrayMenus { get; } = new Dictionary<string, TrayMenuItem>();
|
||||
|
||||
public TrayIcons TrayIcons { get; init; } = new TrayIcons();
|
||||
|
||||
readonly Dictionary<string, ICommand> trayIconMenus = new();
|
||||
@@ -30,27 +36,11 @@ partial class App
|
||||
ToolTipText = AssemblyInfo.Trademark,
|
||||
Command = ReactiveCommand.Create(RestoreMainWindow),
|
||||
//[!TrayIcon.IsVisibleProperty] = new Binding { Path = "Value", Source = GeneralSettings.IsEnableTrayIcon, Mode = BindingMode.OneWay },
|
||||
Menu = new NativeMenu
|
||||
{
|
||||
//new NativeMenuItem
|
||||
//{
|
||||
// Header = "Test",
|
||||
//},
|
||||
//new NativeMenuItemSeparator(),
|
||||
new NativeMenuItem
|
||||
{
|
||||
Header = "打开主面板",
|
||||
Command = ReactiveCommand.Create(RestoreMainWindow)
|
||||
},
|
||||
new NativeMenuItemSeparator(),
|
||||
new NativeMenuItem
|
||||
{
|
||||
[!NativeMenuItem.HeaderProperty] = new Binding { Path = "Res.Exit", Source = ResourceService.Current, Mode = BindingMode.OneWay },
|
||||
Command = ReactiveCommand.Create(() => { Shutdown(); })
|
||||
}
|
||||
}
|
||||
Menu = new NativeMenu(),
|
||||
});
|
||||
|
||||
UpdateMenuItems();
|
||||
|
||||
//IViewModelManager.Instance.InitTaskBarWindowViewModel();
|
||||
//NotifyIconHelper.Init(this,
|
||||
// notifyIconClick: (_, _) => RestoreMainWindow());
|
||||
@@ -76,4 +66,108 @@ partial class App
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateMenuItems()
|
||||
{
|
||||
MainThread2.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
var menus = TrayIcons.FirstOrDefault()?.Menu;
|
||||
|
||||
if (menus != null)
|
||||
{
|
||||
menus.Items.Clear();
|
||||
|
||||
var defaultTrayMenus = new List<NativeMenuItemBase>()
|
||||
{
|
||||
new NativeMenuItem
|
||||
{
|
||||
[!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(async () =>
|
||||
{
|
||||
if(ISteamService.Instance.IsRunningSteamProcess)
|
||||
{
|
||||
await 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(),
|
||||
new NativeMenuItem
|
||||
{
|
||||
[!NativeMenuItem.HeaderProperty] = new Binding { Path = "Res.Exit", Source = ResourceService.Current, Mode = BindingMode.OneWay },
|
||||
Command = ReactiveCommand.Create(() => { Shutdown(); })
|
||||
},
|
||||
};
|
||||
|
||||
if (TrayMenus.Any_Nullable())
|
||||
{
|
||||
foreach (var item in TrayMenus)
|
||||
{
|
||||
NativeMenu? subMenu = null;
|
||||
if (item.Value.Items.Any_Nullable())
|
||||
{
|
||||
subMenu = new NativeMenu();
|
||||
foreach (var sub in item.Value.Items)
|
||||
subMenu.Add(new NativeMenuItem
|
||||
{
|
||||
Header = sub.Name,
|
||||
Command = sub.Command,
|
||||
CommandParameter = sub.CommandParameter,
|
||||
});
|
||||
menus.Add(new NativeMenuItem
|
||||
{
|
||||
Header = item.Value.Name,
|
||||
Menu = subMenu,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
menus.Add(new NativeMenuItem
|
||||
{
|
||||
Header = item.Value.Name,
|
||||
Command = item.Value.Command,
|
||||
CommandParameter = item.Value.CommandParameter,
|
||||
});
|
||||
}
|
||||
}
|
||||
menus.Add(new NativeMenuItemSeparator());
|
||||
}
|
||||
|
||||
foreach (var item in defaultTrayMenus)
|
||||
{
|
||||
menus.Add(item);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void UpdateMenuItems(string menuKey, TrayMenuItem trayMenuItem)
|
||||
{
|
||||
if (TrayMenus != null)
|
||||
{
|
||||
if (TrayMenus.ContainsKey(menuKey))
|
||||
TrayMenus[menuKey] = trayMenuItem;
|
||||
else
|
||||
TrayMenus.Add(menuKey, trayMenuItem);
|
||||
|
||||
UpdateMenuItems();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,34 @@ public sealed partial class App : Application
|
||||
try
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
|
||||
#if WINDOWS || LINUX || MACOS
|
||||
if (GeneralSettings.MinimizeOnStartup.Value)
|
||||
Startup.Instance.IsMinimize = true;
|
||||
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)
|
||||
{
|
||||
@@ -64,8 +92,17 @@ public sealed partial class App : Application
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
MainWindow = InitializeMainWindow?.Invoke(this);
|
||||
desktop.MainWindow = MainWindow ??= new MainWindow();
|
||||
MainWindow = InitializeMainWindow?.Invoke(this) ?? new MainWindow();
|
||||
desktop.MainWindow =
|
||||
#if !UI_DEMO
|
||||
Startup.Instance.IsMinimize ? null :
|
||||
#endif
|
||||
MainWindow;
|
||||
|
||||
if (Startup.Instance.IsMinimize && MainWindow is AppWindow appWindow)
|
||||
{
|
||||
Task2.InBackground(() => appWindow.SplashScreen.RunTasks(CancellationToken.None));
|
||||
}
|
||||
}
|
||||
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleView)
|
||||
{
|
||||
|
||||
@@ -136,7 +136,8 @@
|
||||
Classes="Banner Scale"
|
||||
ClickCommand="{Binding OpenBrowserCommand, Source={x:Static spp:App.Instance}}"
|
||||
ClickCommandParameter="{Binding Url}"
|
||||
Description="{Binding Name}">
|
||||
Description="{Binding Name}"
|
||||
ToolTip.Tip="{Binding Describe}">
|
||||
<spp:AppItem.Status>
|
||||
<Border
|
||||
Padding="20,10"
|
||||
|
||||
@@ -73,15 +73,19 @@ public sealed partial class MainView : ReactiveUserControl<MainWindowViewModel>
|
||||
|
||||
NavView.SelectedItem = null;
|
||||
|
||||
foreach (var nvi in NavView.MenuItemsSource)
|
||||
{
|
||||
SetSelectedItem(nvi);
|
||||
}
|
||||
var menuItemsSource = NavView.MenuItemsSource;
|
||||
if (menuItemsSource != null)
|
||||
foreach (var nvi in menuItemsSource)
|
||||
{
|
||||
SetSelectedItem(nvi);
|
||||
}
|
||||
|
||||
foreach (var nvi in NavView.FooterMenuItemsSource)
|
||||
{
|
||||
SetSelectedItem(nvi);
|
||||
}
|
||||
var footerMenuItemsSource = NavView.FooterMenuItemsSource;
|
||||
if (footerMenuItemsSource != null)
|
||||
foreach (var nvi in footerMenuItemsSource)
|
||||
{
|
||||
SetSelectedItem(nvi);
|
||||
}
|
||||
|
||||
if (FrameView.BackStackDepth > 0 && !NavView.IsBackButtonVisible)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
mc:Ignorable="d">
|
||||
<Panel>
|
||||
<TextBlock
|
||||
Margin="20"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
IsVisible="{Binding Path=!!!Notices.Count, Mode=OneWay, Source={x:Static s:NoticeService.Current}}"
|
||||
|
||||
@@ -30,19 +30,39 @@ public sealed partial class MainWindow : ReactiveAppWindow<MainWindowViewModel>
|
||||
Hide();
|
||||
}
|
||||
base.OnClosing(e);
|
||||
|
||||
if (Steamworks.SteamClient.IsValid)
|
||||
{
|
||||
Steamworks.SteamFriends.ClearRichPresence();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnOpened(EventArgs e)
|
||||
{
|
||||
base.OnOpened(e);
|
||||
|
||||
if (Steamworks.SteamClient.IsValid)
|
||||
{
|
||||
Steamworks.SteamFriends.SetRichPresence("steam_display", "#Status_AtMainMenu");
|
||||
}
|
||||
if (AppSplashScreen.IsInitialized)
|
||||
{
|
||||
if (NavigationService.Instance.CurrnetPage == null)
|
||||
{
|
||||
INavigationService.Instance.Navigate(typeof(HomePage));
|
||||
}
|
||||
Task2.InBackground(async () =>
|
||||
{
|
||||
await AdvertiseService.Current.RefrshAdvertiseAsync();
|
||||
NoticeService.Current.GetNewsAsync();
|
||||
});
|
||||
try // 在主窗口显示时调用此函数检查是否需要显示新版本通知窗口
|
||||
{
|
||||
Ioc.Get_Nullable<IAppUpdateService>()?.OnMainOpenTryShowNewVersionWindow();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,134 +90,137 @@ public sealed class AppSplashScreen : IApplicationSplashScreen
|
||||
{
|
||||
return Task.Run(
|
||||
async () =>
|
||||
{
|
||||
{
|
||||
if (!AppSplashScreen.IsInitialized)
|
||||
{
|
||||
#if STARTUP_WATCH_TRACE || DEBUG
|
||||
WatchTrace.Start();
|
||||
WatchTrace.Start();
|
||||
#endif
|
||||
|
||||
var s = Instance;
|
||||
if (s.IsMainProcess)
|
||||
{
|
||||
VersionTracking2.Track();
|
||||
var s = Instance;
|
||||
if (s.IsMainProcess)
|
||||
{
|
||||
VersionTracking2.Track();
|
||||
#if STARTUP_WATCH_TRACE || DEBUG
|
||||
WatchTrace.Record("VersionTracking2.Track");
|
||||
WatchTrace.Record("VersionTracking2.Track");
|
||||
#endif
|
||||
|
||||
Migrations.Up();
|
||||
Migrations.Up();
|
||||
#if STARTUP_WATCH_TRACE || DEBUG
|
||||
WatchTrace.Record("Migrations.Up");
|
||||
WatchTrace.Record("Migrations.Up");
|
||||
#endif
|
||||
|
||||
// 仅在主进程中启动 IPC 服务端
|
||||
IPCMainProcessService.Instance.Run();
|
||||
// 仅在主进程中启动 IPC 服务端
|
||||
IPCMainProcessService.Instance.Run();
|
||||
#if STARTUP_WATCH_TRACE || DEBUG
|
||||
WatchTrace.Record("IPC.StartServer");
|
||||
WatchTrace.Record("IPC.StartServer");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
LiveCharts.Configure(config =>
|
||||
{
|
||||
config
|
||||
// registers SkiaSharp as the library backend
|
||||
// REQUIRED unless you build your own
|
||||
.AddSkiaSharp();
|
||||
// adds the default supported types
|
||||
// OPTIONAL but highly recommend
|
||||
//.AddDefaultMappers()
|
||||
LiveCharts.Configure(config =>
|
||||
{
|
||||
config
|
||||
// registers SkiaSharp as the library backend
|
||||
// REQUIRED unless you build your own
|
||||
.AddSkiaSharp();
|
||||
// adds the default supported types
|
||||
// OPTIONAL but highly recommend
|
||||
//.AddDefaultMappers()
|
||||
|
||||
// select a theme, default is Light
|
||||
// OPTIONAL
|
||||
//.AddDarkTheme()
|
||||
// select a theme, default is Light
|
||||
// OPTIONAL
|
||||
//.AddDarkTheme()
|
||||
|
||||
// In case you need a non-Latin based font, you must register a typeface for SkiaSharp
|
||||
config.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('汉')); // <- Chinese // mark
|
||||
//.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('أ')) // <- Arabic // mark
|
||||
//.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('あ')) // <- Japanese // mark
|
||||
//.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('헬')) // <- Korean // mark
|
||||
//.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('Ж')) // <- Russian // mark
|
||||
// In case you need a non-Latin based font, you must register a typeface for SkiaSharp
|
||||
config.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('汉')); // <- Chinese // mark
|
||||
//.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('أ')) // <- Arabic // mark
|
||||
//.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('あ')) // <- Japanese // mark
|
||||
//.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('헬')) // <- Korean // mark
|
||||
//.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('Ж')) // <- Russian // mark
|
||||
|
||||
if (App.Instance.Theme != AppTheme.FollowingSystem)
|
||||
{
|
||||
if (App.Instance.Theme == AppTheme.Light)
|
||||
config.AddLightTheme();
|
||||
else
|
||||
config.AddDarkTheme();
|
||||
}
|
||||
else
|
||||
{
|
||||
var dps = IPlatformService.Instance;
|
||||
var isLightOrDarkTheme = dps.IsLightOrDarkTheme;
|
||||
if (isLightOrDarkTheme.HasValue)
|
||||
{
|
||||
var mThemeFS = IApplication.GetAppThemeByIsLightOrDarkTheme(isLightOrDarkTheme.Value);
|
||||
if (mThemeFS == AppTheme.Light)
|
||||
config.AddLightTheme();
|
||||
else
|
||||
config.AddDarkTheme();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (App.Instance.Theme != AppTheme.FollowingSystem)
|
||||
{
|
||||
if (App.Instance.Theme == AppTheme.Light)
|
||||
config.AddLightTheme();
|
||||
else
|
||||
config.AddDarkTheme();
|
||||
}
|
||||
else
|
||||
{
|
||||
var dps = IPlatformService.Instance;
|
||||
var isLightOrDarkTheme = dps.IsLightOrDarkTheme;
|
||||
if (isLightOrDarkTheme.HasValue)
|
||||
{
|
||||
var mThemeFS = IApplication.GetAppThemeByIsLightOrDarkTheme(isLightOrDarkTheme.Value);
|
||||
if (mThemeFS == AppTheme.Light)
|
||||
config.AddLightTheme();
|
||||
else
|
||||
config.AddDarkTheme();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
AdvertiseService.Current.InitAdvertise();
|
||||
NoticeService.Current.GetNewsAsync();
|
||||
AdvertiseService.Current.InitAdvertise();
|
||||
NoticeService.Current.GetNewsAsync();
|
||||
|
||||
var mainWindow = App.Instance.MainWindow;
|
||||
mainWindow.ThrowIsNull();
|
||||
var mainWindow = App.Instance.MainWindow;
|
||||
mainWindow.ThrowIsNull();
|
||||
|
||||
#pragma warning disable SA1114 // Parameter list should follow declaration
|
||||
IViewModelManager.Instance.InitViewModels(new TabItemViewModel[]
|
||||
{
|
||||
IViewModelManager.Instance.InitViewModels(new TabItemViewModel[]
|
||||
{
|
||||
new MenuTabItemViewModel("Welcome")
|
||||
{
|
||||
PageType = typeof(HomePage),
|
||||
IsResourceGet = true,
|
||||
IconKey = "avares://BD.WTTS.Client.Avalonia/UI/Assets/Icons/home.ico",
|
||||
},
|
||||
}, ImmutableArray.Create<TabItemViewModel>(
|
||||
}, ImmutableArray.Create<TabItemViewModel>(
|
||||
#if DEBUG
|
||||
new MenuTabItemViewModel("Debug")
|
||||
{
|
||||
PageType = typeof(DebugPage),
|
||||
IsResourceGet = false,
|
||||
IconKey = "avares://BD.WTTS.Client.Avalonia/UI/Assets/Icons/bug.ico",
|
||||
},
|
||||
#endif
|
||||
new MenuTabItemViewModel("Plugin_Store")
|
||||
{
|
||||
PageType = null,
|
||||
IsResourceGet = true,
|
||||
IconKey = "avares://BD.WTTS.Client.Avalonia/UI/Assets/Icons/store.ico",
|
||||
},
|
||||
new MenuTabItemViewModel("Settings")
|
||||
{
|
||||
PageType = typeof(SettingsPage),
|
||||
IsResourceGet = true,
|
||||
IconKey = "avares://BD.WTTS.Client.Avalonia/UI/Assets/Icons/settings.ico",
|
||||
}));
|
||||
new MenuTabItemViewModel("Debug")
|
||||
{
|
||||
PageType = typeof(DebugPage),
|
||||
IsResourceGet = false,
|
||||
IconKey = "avares://BD.WTTS.Client.Avalonia/UI/Assets/Icons/bug.ico",
|
||||
},
|
||||
#endif
|
||||
new MenuTabItemViewModel("Plugin_Store")
|
||||
{
|
||||
PageType = null,
|
||||
IsResourceGet = true,
|
||||
IconKey = "avares://BD.WTTS.Client.Avalonia/UI/Assets/Icons/store.ico",
|
||||
},
|
||||
new MenuTabItemViewModel("Settings")
|
||||
{
|
||||
PageType = typeof(SettingsPage),
|
||||
IsResourceGet = true,
|
||||
IconKey = "avares://BD.WTTS.Client.Avalonia/UI/Assets/Icons/settings.ico",
|
||||
}));
|
||||
#pragma warning restore SA1114 // Parameter list should follow declaration
|
||||
IViewModelManager.Instance.MainWindow.ThrowIsNull();
|
||||
IViewModelManager.Instance.MainWindow.ThrowIsNull();
|
||||
|
||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
mainWindow.DataContext = IViewModelManager.Instance.MainWindow;
|
||||
s.InitSettingSubscribe();
|
||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
mainWindow.DataContext = IViewModelManager.Instance.MainWindow;
|
||||
s.InitSettingSubscribe();
|
||||
|
||||
INavigationService.Instance.Navigate(typeof(HomePage));
|
||||
});
|
||||
INavigationService.Instance.Navigate(typeof(HomePage));
|
||||
});
|
||||
#if STARTUP_WATCH_TRACE || DEBUG
|
||||
WatchTrace.Record("InitMainWindowViewModel");
|
||||
WatchTrace.Record("InitMainWindowViewModel");
|
||||
#endif
|
||||
|
||||
#if STARTUP_WATCH_TRACE || DEBUG
|
||||
WatchTrace.Stop();
|
||||
WatchTrace.Stop();
|
||||
#endif
|
||||
s.OnStartup();
|
||||
await IViewModelManager.Instance.MainWindow.Initialize();
|
||||
s.OnStartup();
|
||||
await IViewModelManager.Instance.MainWindow.Initialize();
|
||||
|
||||
App.Instance.CompositeDisposable.Add(IViewModelManager.Instance.MainWindow);
|
||||
App.Instance.CompositeDisposable.Add(SteamConnectService.Current.Dispose);
|
||||
App.Instance.CompositeDisposable.Add(IViewModelManager.Instance.MainWindow);
|
||||
App.Instance.CompositeDisposable.Add(SteamConnectService.Current.Dispose);
|
||||
|
||||
IsInitialized = true;
|
||||
}, cancellationToken: token);
|
||||
IsInitialized = true;
|
||||
}
|
||||
}, cancellationToken: token);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +125,16 @@ public interface IPCSubProcessService : IDisposable
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
else if (!OperatingSystem.IsWindows() && !libraryFileName.StartsWith("lib", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
libraryFileName = $"lib{libraryFileName}";
|
||||
libraryPath = Path.Combine(nativeLibraryPath, libraryFileName);
|
||||
if (File.Exists(libraryPath) &&
|
||||
NativeLibrary.TryLoad(libraryPath, out handle))
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
return NativeLibrary.Load(libraryName, assembly, searchPath);
|
||||
}
|
||||
NativeLibrary.SetDllImportResolver(loadedAssembly, Delegate);
|
||||
|
||||
@@ -59,10 +59,23 @@
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- AppCenter -->
|
||||
<Compile Include="..\VisualStudioAppCenterSDK.cs">
|
||||
<LinkBase>Helpers</LinkBase>
|
||||
</Compile>
|
||||
<Compile Include="..\VisualStudioAppCenterSDK.AppSecret.cs">
|
||||
<LinkBase>Helpers</LinkBase>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\BD.WTTS.Client\Constants\CertificateConstants.cs">
|
||||
<LinkBase>Constants</LinkBase>
|
||||
</Compile>
|
||||
<Compile Include="..\BD.WTTS.Client\Services\Platform\IPlatformService.OS.Linux.Etc.Os_Release.cs">
|
||||
<LinkBase>Services\Platform</LinkBase>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -77,6 +90,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BD.Common" />
|
||||
<PackageReference Include="BD.Common.Repositories.SQLitePCL" />
|
||||
<PackageReference Include="NLog" />
|
||||
<PackageReference Include="System.Linq.Async" />
|
||||
<PackageReference Include="Ae.DNS.Client" />
|
||||
@@ -84,6 +98,12 @@
|
||||
<PackageReference Include="DnsClient" />
|
||||
<PackageReference Include="Yarp.ReverseProxy" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" />
|
||||
<PackageReference Include="Aigio.Any.AppCenter" />
|
||||
<PackageReference Include="Aigio.Any.AppCenter.Analytics" />
|
||||
<PackageReference Include="Aigio.Any.AppCenter.Crashes" />
|
||||
<PackageReference Include="System.Drawing.Common" />
|
||||
<PackageReference Include="System.Runtime.Caching" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="$([MSBuild]::IsOSPlatform('windows')) AND ($(RuntimeIdentifier.StartsWith('win-')) OR $(RuntimeIdentifier) == '')">
|
||||
|
||||
@@ -6,8 +6,8 @@ public static partial class ServiceCollectionExtensions
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static IServiceCollection AddDnsAnalysisService(this IServiceCollection services)
|
||||
{
|
||||
//services.AddSingleton<IDnsAnalysisService, DnsDohAnalysisService>();
|
||||
services.AddSingleton<IDnsAnalysisService, DnsAnalysisServiceImpl>();
|
||||
services.AddSingleton<DnsDohAnalysisService>();
|
||||
services.AddSingleton<DnsAnalysisServiceImpl>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using BD.Common.Repositories.Abstractions;
|
||||
using dotnetCampus.Ipc.CompilerServices.GeneratedProxies;
|
||||
using KeyValuePair = BD.Common.Entities.KeyValuePair;
|
||||
|
||||
const string moduleName = AssemblyInfo.Accelerator;
|
||||
const string pluginName = AssemblyInfo.Accelerator;
|
||||
@@ -37,6 +39,8 @@ try
|
||||
{
|
||||
var exitCode = await IPCSubProcessService.MainAsync(moduleName, pluginName, ConfigureServices, static ipcProvider =>
|
||||
{
|
||||
VisualStudioAppCenterSDK.Init();
|
||||
|
||||
// 添加反向代理服务(供主进程的 IPC 远程访问)
|
||||
ipcProvider.CreateIpcJoint(LazyReverseProxyServiceImpl.Instance);
|
||||
ipcProvider.CreateIpcJoint(LazyCertificateManager.Instance);
|
||||
@@ -56,6 +60,17 @@ catch (Exception ex)
|
||||
Console.ReadLine();
|
||||
return 500;
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
VisualStudioAppCenterSDK.UtilsImpl.Instance.OnExit(null, EventArgs.Empty);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
@@ -68,11 +83,76 @@ static void ConfigureServices(IServiceCollection services)
|
||||
#endif
|
||||
});
|
||||
|
||||
// 设置仓储层数据库文件存放路径
|
||||
Repository.DataBaseDirectory = IOPath.AppDataDirectory;
|
||||
services.TryAddSingleton<ISecureStorage, RepositorySecureStorage>();
|
||||
|
||||
services.AddHttpClient();
|
||||
services.AddCommonHttpClientFactory();
|
||||
services.AddSingleton<IHttpPlatformHelperService, HttpPlatformHelperConsoleService>();
|
||||
|
||||
services.AddDnsAnalysisService();
|
||||
// 添加反向代理服务(子进程实现)
|
||||
services.AddReverseProxyService();
|
||||
services.AddSingleton<ICertificateManager, CertificateManagerImpl>();
|
||||
}
|
||||
|
||||
sealed class RepositorySecureStorage : Repository<KeyValuePair, string>, ISecureStorage
|
||||
{
|
||||
bool ISecureStorage.IsNativeSupportedBytes => true;
|
||||
|
||||
static string GetKey(string key) => Hashs.String.SHA256(key);
|
||||
|
||||
async Task<byte[]?> ISecureStorage.GetBytesAsync(string key)
|
||||
{
|
||||
key = GetKey(key);
|
||||
var item = await FirstOrDefaultAsync(x => x.Id == key);
|
||||
var value = item?.Value;
|
||||
var value2 = value;
|
||||
return value2;
|
||||
}
|
||||
|
||||
async Task InsertOrUpdateAsync(string key, byte[] value)
|
||||
{
|
||||
var value2 = value;
|
||||
await InsertOrUpdateAsync(new KeyValuePair
|
||||
{
|
||||
Id = key,
|
||||
Value = value2.ThrowIsNull(nameof(value2)),
|
||||
});
|
||||
}
|
||||
|
||||
Task ISecureStorage.SetAsync(string key, byte[]? value)
|
||||
{
|
||||
key = GetKey(key);
|
||||
if (value == null || value.Length <= 0)
|
||||
{
|
||||
return DeleteAsync(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
return InsertOrUpdateAsync(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
async Task<bool> ISecureStorage.RemoveAsync(string key)
|
||||
{
|
||||
key = GetKey(key);
|
||||
var result = await DeleteAsync(key);
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
async Task<bool> ISecureStorage.ContainsKeyAsync(string key)
|
||||
{
|
||||
key = GetKey(key);
|
||||
var item = await FirstOrDefaultAsync(x => x.Id == key);
|
||||
return item != null;
|
||||
}
|
||||
}
|
||||
|
||||
sealed class HttpPlatformHelperConsoleService : HttpPlatformHelperService
|
||||
{
|
||||
new const string DefaultUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 Edg/90.0.818.51";
|
||||
|
||||
public override string UserAgent => DefaultUserAgent;
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"><assemblyIdentity version="1.0.0.0" name="BeyondDimension.WattToolkit.Accelerator"/><trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"><security><requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"><requestedExecutionLevel level="requireAdministrator" uiAccess="false" /></requestedPrivileges></security></trustInfo><compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application><supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" /><supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" /><supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" /><supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" /><supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" /></application></compatibility></assembly>
|
||||
<?xml version="1.0" encoding="utf-8"?><assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"><assemblyIdentity version="1.0.0.0" name="BeyondDimension.WattToolkit.Accelerator"/><trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"><security><requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"><requestedExecutionLevel level="asInvoker" uiAccess="false" /></requestedPrivileges></security></trustInfo><compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application><supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" /><supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" /><supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" /><supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" /><supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" /></application></compatibility></assembly>
|
||||