Compare commits

...

74 Commits

Author SHA1 Message Date
rmbgame 451de6ca55 令牌交易确认功能上线
新增消息通知设置项
新增检测是否蒸汽平台启动
2021-01-22 22:25:08 +08:00
rmbgame 691fb360bb 修改了所有代理服务的域名解析方式
修复twitch聊天频道连接失效
修复gihub头像资源加载失败
新增pixiv图片的代理选项来修复pixiv图片失效
2021-01-22 16:24:37 +08:00
rmbgame 686e3987f8 修复discord更新下载和图片失效
新增github gist代理服务支持
2021-01-20 17:06:13 +08:00
rmbgame 79871c3bcb 自动更新增加一个简单的文件效验
保存备份机制修改
2021-01-19 15:21:52 +08:00
rmbgame c1b19b4929 ui库代码更新 2021-01-18 20:47:25 +08:00
rmbgame c564ea10eb 令牌交易确认的进度推进
许多细节改进
2021-01-18 20:33:16 +08:00
rmbgame d5006da378 新增steam史低查询脚本
修复仅在steam内置浏览器生效功能有时候没有用的问题
2021-01-14 05:00:03 +08:00
rmbgame 878e9dbd32 修改用户信息api为steam官方api 2021-01-12 16:22:10 +08:00
rmbgame bd7f9e76b8 增加80端口反代,以便自动跳转http访问到https请求上 2021-01-12 16:10:39 +08:00
rmbgame fc285cf583 修改生成的cer证书编码格式为utf8 2021-01-12 11:16:23 +08:00
rmbgame 3ab0ae46c0 新增启用日志设置项
修复twitch反代聊天连接错误和直播视频无法观看
使httpclient更稳定
2021-01-11 11:18:42 +08:00
rmbgame 4550ff1621 放宽令牌同步时网络请求超时时间 2021-01-08 21:50:18 +08:00
rmbgame 1663bd4277 fix text error 2021-01-08 10:56:53 +08:00
rmbgame 679afdef1b ready 1.0.5 2021-01-08 09:55:03 +08:00
rmbgame d38588d45c 修复了因为steamdb.ml api挂掉导致的程序启动崩溃 2021-01-08 09:44:07 +08:00
rmbgame 42b11ce241 帐户切换功能增加离线模式选项
更改了许多文本问题
2021-01-07 09:37:56 +08:00
rmbgame c01512bcf6 帐户切换功能增加离线模式选项
更改了许多文本问题
2021-01-07 09:37:48 +08:00
rmbgame dd89595629 update readme 2021-01-06 06:55:40 +08:00
rmbgame 94b5539823 last 2021-01-06 06:36:21 +08:00
rmbgame 317baff79c fix submodules path 2021-01-06 06:28:51 +08:00
rmbgame f702c3ae62 子模块路径修复
修复一些.NET 5的BUG
2021-01-06 06:25:34 +08:00
rmbgame 177216a51e fix 2021-01-06 06:25:21 +08:00
rmbgame 46b1c01107 submodule sync 2021-01-06 04:59:08 +08:00
rmbgame 798355e342 更新目录结构
新增反代脚本只对Steam内置浏览器生效的选项
2021-01-06 04:30:56 +08:00
rmbgame ee741d3138 新增令牌数据刷新功能 2021-01-05 02:07:11 +08:00
rmbgame e31b668beb 更新引用 2021-01-04 14:26:50 +08:00
rmbgame c00955205c .NET 5 2021-01-04 14:26:05 +08:00
rmbgame 5345926c8b 引用项目改为子模块方式
更新引用项目升级到.NET5
2021-01-04 14:26:01 +08:00
rmbgame 0987f58fee 增加了启动时自动运行Steam的设置项
社区加速功能的证书会同时生成一份cer证书文件在程序根目录(方便导入火狐等浏览器)
2021-01-04 06:55:53 +08:00
rmbgame 715737bce2 优化反代过程逻辑
修复一些文本错误
2020-12-30 20:43:55 +08:00
rmbgame 44245aa2b7 md 2020-12-29 03:02:42 +08:00
rmbgame 97e6b92ef6 update readme 2020-12-29 03:02:18 +08:00
rmbgame 445f130272 移除无用代码,更新readme 2020-12-29 02:43:15 +08:00
rmbgame 39fcc4d9a8 update text 2020-12-28 20:34:57 +08:00
rmbgame b4a755a647 edit text 2020-12-28 20:34:55 +08:00
rmbgame 083189c264 更友好的自动更新 2020-12-28 20:00:57 +08:00
rmbgame 676c628b6f 更友好的更新提示 2020-12-28 20:00:50 +08:00
rmbgame 43ca455e70 尝试不需要帐号密码实现确认交易的可能性 2020-12-28 20:00:38 +08:00
rmbgame 95e834a188 新增令牌导出备份功能
新增令牌数据保存在程序目录设置项
2020-12-28 20:00:24 +08:00
rmbgame e9d822bb0c *修改了配置文件的加载保存路径和格式(如果更新到此版本会丢失之前的配置)
新增令牌导出功能
2020-12-28 01:15:46 +08:00
rmbgame f395383db8 修改steam社区商店页的代理上游
修复成就窗口关闭游戏依然运行
2020-12-27 14:29:15 +08:00
rmbgame f805911f4e 准备更新挂卡功能,修复托盘启动多个窗口问题 2020-12-27 12:53:50 +08:00
rmbgame b3d203fbda 1.0.3.2 2020-12-27 01:33:55 +08:00
rmbgame bb022f45fd 优化令牌的加载 2020-12-27 01:33:49 +08:00
rmbgame e4a97463f4 修复程序最小化启动时弹窗报错 2020-12-27 00:59:53 +08:00
rmbgame 11adabb749 添加steam图片修复和pixiv代理选项 2020-12-26 22:19:42 +08:00
rmbgame 8a7ad67363 修改初始化和steamapi连接方式 2020-12-26 20:02:15 +08:00
rmbgame 7af0888b0a 修复一个因为DNS解析错误会导致程序内存溢出闪退的BUG 2020-12-26 19:21:01 +08:00
rmbgame 42fc93a524 修复最小化UI错位BUG 2020-12-26 19:20:48 +08:00
rmbgame 5c832f489b 修复在令牌初始化时犯下的一个愚蠢问题导致令牌各种非空报错
修改帐户切换的最近登录时间为当前电脑时区显示
2020-12-26 19:19:50 +08:00
rmbgame 5e7ed26bc6 add static resources 2020-12-23 01:25:40 +08:00
rmbgame 085ad3d944 修改多语言文本
修改部分相对路径为绝对路径
2020-12-22 13:00:10 +08:00
rmbgame 334503445c edit text 2020-12-22 13:00:03 +08:00
rmbgame cf17ca8dd6 ready 1.0.2 2020-12-21 21:18:14 +08:00
rmbgame 0b88de7195 添加了自动更新检测功能 2020-12-21 21:17:49 +08:00
rmbgame 3342e35440 bug fix 2020-12-21 21:17:43 +08:00
rmbgame 56baba4a53 修复了443端口占用只会提示一次的问题 2020-12-21 21:17:38 +08:00
rmbgame 8b1a946fe2 添加discord代理选项 2020-12-20 14:57:34 +08:00
rmbgame 9e08c0b7c4 优化反代启用时内存占用
添加github图片资源文件代理服务支持
2020-12-20 14:57:18 +08:00
rmbgame 3a38333dfc 移除无用代码,修正一个命名错误 2020-12-20 14:57:04 +08:00
rmbgame 16d1bba515 update readme 2020-12-20 00:21:35 +08:00
rmbgame 00cf9da911 修复了程序启动时自动启动代理脚本不生效的问题
因为有问题暂时去掉了GOG Galaxy代理选项
增加捐助列表的展示
增加启动时程序最小化到托盘菜单设置
2020-12-20 00:14:22 +08:00
rmbgame 088256faf9 修复一个会导致steam未连接文字闪烁的BUG 2020-12-20 00:14:17 +08:00
rmbgame ca244edc51 sync gitee 2020-12-19 00:24:56 +08:00
rmbgame c91608da09 update readme 2020-12-19 00:23:49 +08:00
rmbgame 2945e9fa3e 更新了新的图标
增加steam启动参数设置
修复了一些文本bug
2020-12-19 00:22:54 +08:00
rmbgame 1f0a40cd3b 新增帐户切换删除功能(凑合用)
修复一个会导致程序启动没有反应的bug
修复托盘菜单steam昵称过长ui错位bug
修正了配置文件夹命名错误(1.0.0版本更新后设置会被重置)
2020-12-19 00:07:02 +08:00
rmbgame b1fbe64ab2 update readme 2020-12-17 17:19:28 +08:00
rmbgame 9a13665e68 ready 1.0.0 2020-12-17 12:09:47 +08:00
rmbgame 5c0f71f4a7 sync gitee 2020-12-16 10:45:03 +08:00
rmbgame 3e045e5db0 delete ref lib 2020-12-16 10:33:43 +08:00
rmbgame c4f99906ab update 2020-12-16 10:29:55 +08:00
rmbgame 94e50f663b 删除无用代码 2020-12-15 23:35:17 +08:00
rmbgame 49e08101c6 delete error ref 2020-12-15 23:29:36 +08:00
613 changed files with 8461 additions and 5257 deletions
-13
View File
@@ -1,13 +0,0 @@
### 该问题是怎么引起的?
### 重现步骤
### 报错信息
-15
View File
@@ -1,15 +0,0 @@
### 相关的Issue
### 原因(目的、解决的问题等)
### 描述(做了什么,变更了什么)
### 测试用例(新增、改动、可能影响的功能)
+1
View File
@@ -26,6 +26,7 @@ bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ib/
# Visual Studio 2015/2017 cache/options directory
.vs/
+6
View File
@@ -0,0 +1,6 @@
[submodule "references/Titanium-Web-Proxy"]
path = references/Titanium-Web-Proxy
url = https://github.com/rmbadmin/Titanium-Web-Proxy.git
[submodule "references/MetroRadiance"]
path = references/MetroRadiance
url = https://github.com/rmbadmin/MetroRadiance.git
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+85 -24
View File
@@ -1,40 +1,101 @@
# Steam++工具箱 v1.0
<img src="https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/icon/LOGO1.png" alt="logo" width="130" height="130" align="left" />
<h1>Steam++ Tools</h1>
> 「Steam++」is a toolkit that contains a variety of Steam tools, most of which require you to download and install Steam in order to use them.
<br/>
![Release Download](https://img.shields.io/github/downloads/rmbadmin/SteamTools/latest/total?style=flat-square)
[![Release Version](https://img.shields.io/github/v/release/rmbadmin/SteamTools?style=flat-square)](https://github.com/rmbadmin/SteamTools/releases/latest)
[![GitHub license](https://img.shields.io/github/license/rmbadmin/SteamTools?style=flat-square)](LICENSE)
[![GitHub Star](https://img.shields.io/github/stars/rmbadmin/SteamTools?style=flat-square)](https://github.com/rmbadmin/SteamTools/stargazers)
[![GitHub Fork](https://img.shields.io/github/forks/rmbadmin/SteamTools?style=flat-square)](https://github.com/rmbadmin/SteamTools/network/members)
![GitHub repo size](https://img.shields.io/github/repo-size/rmbadmin/SteamTools?style=flat-square&color=3cb371)
## Samples
-------
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/s.png)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/e.png)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/e2.png)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/t.png)
------
「Steam++」是一个包含多种Steam工具功能的工具箱。
此工具的大部分功能都是需要您下载安装Steam才能使用。
------
## 主要功能
### 1. 反代Steam的社区网页使其能正常访问
功能类似羽翼城大佬的Steam302,相比之下有:
- [X] 更快的启动速度
- [X] 支持脚本注入
## Core Functions
### 1. Local reverse proxy for Steam's community webpage to enable normal access in mainland China
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/1.png)
---
### 2. 快速切换当前PC已经记住登陆的Steam账号
### 2. Quickly switch the Steam account that the current PC has remembered to log into
该功能是读取Steam路径下存储的本地用户登录记录直接展示操作,可以多账号切换无需重新输入密码和令牌。
This feature is to read the local user login records stored under the Steam path to directly display the operation, you can switch between multiple accounts without re-entering passwords and tokens.
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/2.png)
---
### 3. Steam游戏的成就统计管理功能
功能类似[SteamAchievementManager](https://github.com/gibbed/SteamAchievementManager),实现也参考了SAM,并且略作修改了,游戏列表的读取,解锁成就的逻辑。
### 3. Achievement stat modifications for Steam games
Function reference [SteamAchievementManager](https://github.com/gibbed/SteamAchievementManager) for secondary development, modified the game list loading and operation ease of use.
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/3.png)
---
### 4. Steam Local Two-Step Authenticator
The function reference [WinAuth](https://github.com/winauth/winauth) is developed to enable you to view your token without launching the mobile version of Steam App, similar function software are [WinAuth](https://github.com/winauth/winauth), [SteamDesktopAuthenticator](https://github.com/Jessecar96/SteamDesktopAuthenticator).
! [](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/4.png)
---
### 4. Steam本地两步身份验证器
可以使您不用启动移动版Steam App也能查看您的令牌,功能类似的软件有[WinAuth](https://github.com/winauth/winauth)、[SteamDesktopAuthenticator](https://github.com/Jessecar96/SteamDesktopAuthenticator)。
### 5. Some game tools
Currently there is a forced game borderless windowing, CSGO fix VAC shield.
This piece is randomly do some of my often used or idle tinkering with the function.
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/5.png)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/6.png)
---
## Features expected to be added subsequently
### Steam Idle Card
The goal is to enable direct access to badge card information and start hanging cards without logging into your Steam account within the software.
### Plug-in form to load and run ASF
Support ASF as a plug-in to run within the tool and enhance the use of ASF in Windows Desktop environment.
### Steam Custom Cover Management
Enhanced management of Steam custom covers and quick matching of downloaded app covers from [SteamGridDB](https://www.steamgriddb.com/).
### More other game platform features
### More non-cheat game features
---
### 5. 一些游戏工具
目前已有强制游戏无边框窗口化,CSGO修复VAC屏蔽。
这一块是随缘做一些我经常用或者闲着没事捣鼓的功能。
## Operating Environment
> The program was developed using C# WPF in .,If it does not work please download and install[.NET Framework 4.7.2](https://dotnet.microsoft.com/download/dotnet-framework/net472)。
> The missing assembly is my own modified project
* [Titanium-Web-Proxy](https://github.com/rmbadmin/Titanium-Web-Proxy)
* [MetroRadiance](https://github.com/rmbadmin/MetroRadiance)
---
## License
> [GPL-3.0 License](https://github.com/rmbadmin/SteamTools/blob/develop/LICENSE)
> Open source/free software released under the GPLv3 license.
---
## Thanks to the following open source projects
* [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json)
* [MetroRadiance](https://github.com/Grabacr07/MetroRadiance)
* [MetroTrilithon](https://github.com/Grabacr07/MetroTrilithon)
* [Livet](https://github.com/runceel/Livet)
* [StatefulModel](https://github.com/ugaya40/StatefulModel)
* [Hardcodet.NotifyIcon](https://github.com/HavenDV/Hardcodet.NotifyIcon.Wpf.NetCore)
* [System.Reactive](https://github.com/dotnet/reactive)
* [Titanium-Web-Proxy](https://github.com/justcoding121/Titanium-Web-Proxy)
* [Ninject](https://github.com/ninject/Ninject)
* [log4net](https://github.com/apache/logging-log4net)
* [SteamDB-API](https://github.com/SteamDB-API/api)
* [SteamAchievementManager](https://github.com/gibbed/SteamAchievementManager)
* [ArchiSteamFarm](https://github.com/JustArchiNET/ArchiSteamFarm)
* [WinAuth](https://github.com/winauth/winauth)
* [SteamDesktopAuthenticator](https://github.com/Jessecar96/SteamDesktopAuthenticator)
* [Gameloop.Vdf](https://github.com/shravan2x/Gameloop.Vdf)
* [Costura.Fody](https://github.com/Fody/Costura)
+84 -19
View File
@@ -1,40 +1,105 @@
# Steam++工具箱 v1.0
<img src="https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/icon/LOGO1.png" alt="logo" width="130" height="130" align="left" />
<h1>Steam++ 工具箱</h1>
> 「Steam++」是一个包含多种Steam工具功能的工具箱,
> 此工具的大部分功能都是需要您下载安装Steam才能使用。
<br/>
![Release Download](https://img.shields.io/github/downloads/rmbadmin/SteamTools/latest/total?style=flat-square)
[![Release Version](https://img.shields.io/github/v/release/rmbadmin/SteamTools?style=flat-square)](https://github.com/rmbadmin/SteamTools/releases/latest)
[![GitHub license](https://img.shields.io/github/license/rmbadmin/SteamTools?style=flat-square)](LICENSE)
[![GitHub Star](https://img.shields.io/github/stars/rmbadmin/SteamTools?style=flat-square)](https://github.com/rmbadmin/SteamTools/stargazers)
[![GitHub Fork](https://img.shields.io/github/forks/rmbadmin/SteamTools?style=flat-square)](https://github.com/rmbadmin/SteamTools/network/members)
![GitHub repo size](https://img.shields.io/github/repo-size/rmbadmin/SteamTools?style=flat-square&color=3cb371)
# Steam++
## 效果展示
-------
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/s.png)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/e.png)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/e2.png)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/t.png)
------
「Steam++」是一个包含多种Steam工具功能的工具箱。
此工具的大部分功能都是需要您下载安装Steam才能使用。
------
## 主要功能
## 核心功能
### 1. 反代Steam的社区网页使其能正常访问
功能类似羽翼城大佬的Steam302,相比之下有:
- [X] 更快的启动速度
- [X] 支持脚本注入
功能类似羽翼城大佬的[steamcommunity_302](https://www.dogfight360.com/blog/686/),使用[Titanium-Web-Proxy](https://github.com/justcoding121/Titanium-Web-Proxy)开源项目进行本地反代,使国内用户可以正常访问steam社区页,相比302工具具有更快的启动速度,以及支持简单的脚本注入。(还顺便支持了Pixiv、Discord、Twitch等网站的反代支持)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/1.png)
---
### 2. 快速切换当前PC已经记住登陆的Steam账号
该功能是读取Steam路径下存储的本地用户登录记录直接展示操作,可以多账号切换无需重新输入密码和令牌。
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/2.png)
---
### 3. Steam游戏的成就统计管理功能
功能类似[SteamAchievementManager](https://github.com/gibbed/SteamAchievementManager),实现也参考了SAM,并且略作修改了,游戏列表的读取,解锁成就的逻辑。
功能参考[SteamAchievementManager](https://github.com/gibbed/SteamAchievementManager)进行二次开发,修改了游戏列表的加载和操作易用性。
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/3.png)
---
### 4. Steam本地两步身份验证器
可以使您不用启动移动版Steam App也能查看您的令牌,功能类似的软件有[WinAuth](https://github.com/winauth/winauth)、[SteamDesktopAuthenticator](https://github.com/Jessecar96/SteamDesktopAuthenticator)。
功能参考[WinAuth](https://github.com/winauth/winauth)开发,可以使您不用启动移动版Steam App也能查看您的令牌,功能类似的软件有[WinAuth](https://github.com/winauth/winauth)、[SteamDesktopAuthenticator](https://github.com/Jessecar96/SteamDesktopAuthenticator)。
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/4.png)
---
### 5. 一些游戏工具
目前已有强制游戏无边框窗口化,CSGO修复VAC屏蔽。
这一块是随缘做一些我经常用或者闲着没事捣鼓的功能。
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/5.png)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/6.png)
---
## 预计后续添加的功能
### Steam自动挂卡
尝试用社区反代功能结合成就解锁功能来重新实现,目的是实现在软件内无需登录Steam帐户即可直接获取徽章卡片信息并开始挂卡。
### Steam皮肤设计器
挖坑画大饼,可视化编辑Steam皮肤,而且如果软件能上架Steam的话打算支持创意工坊分享设计的Steam皮肤,短期内肯定做不完。
### 插件形式加载运行ASF
以插件形式支持ASF在工具内运行并增强ASF在Windows Desktop环境下的使用。
### Steam自定义封面管理
增强Steam自定义封面的管理以及从[SteamGridDB](https://www.steamgriddb.com/)快速匹配下载应用封面。
### 更多其它游戏平台功能
### 更多非作弊游戏功能
---
## 开发环境
> 开发工具 [Visual Studio 2019](https://visualstudio.microsoft.com/)
> 开发语言 C# WPF
> .NET版本 .NET Framework4.7.2 和 .NET5
> 如果无法运行请下载安装[.NET Framework 4.7.2](https://dotnet.microsoft.com/download/dotnet-framework/net472)或[.NET 5](https://dotnet.microsoft.com/download/dotnet/5.0)。
---
## License
> [GPL-3.0 License](https://github.com/rmbadmin/SteamTools/blob/develop/LICENSE)
> 根据GPLv3许可发布的开源/免费软件。
---
## 感谢以下开源项目
* [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json)
* [MetroRadiance](https://github.com/Grabacr07/MetroRadiance)
* [MetroTrilithon](https://github.com/Grabacr07/MetroTrilithon)
* [Livet](https://github.com/runceel/Livet)
* [StatefulModel](https://github.com/ugaya40/StatefulModel)
* [Hardcodet.NotifyIcon](https://github.com/HavenDV/Hardcodet.NotifyIcon.Wpf.NetCore)
* [System.Reactive](https://github.com/dotnet/reactive)
* [Titanium-Web-Proxy](https://github.com/justcoding121/Titanium-Web-Proxy)
* [Ninject](https://github.com/ninject/Ninject)
* [log4net](https://github.com/apache/logging-log4net)
* [SteamDB-API](https://github.com/SteamDB-API/api)
* [SteamAchievementManager](https://github.com/gibbed/SteamAchievementManager)
* [ArchiSteamFarm](https://github.com/JustArchiNET/ArchiSteamFarm)
* [WinAuth](https://github.com/winauth/winauth)
* [SteamDesktopAuthenticator](https://github.com/Jessecar96/SteamDesktopAuthenticator)
* [Gameloop.Vdf](https://github.com/shravan2x/Gameloop.Vdf)
* [Costura.Fody](https://github.com/Fody/Costura)
-249
View File
@@ -1,249 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using WinAuth;
namespace SteamTool.Auth
{
public static class AuthService
{
/// <summary>
/// Import a file containing authenticators in the KeyUriFormat. The file might be plain text, encrypted zip or encrypted pgp.
/// </summary>
/// <param name="parent">parent Form</param>
/// <param name="file">file name to import</param>
/// <returns>list of imported authenticators</returns>
public static List<WinAuthAuthenticator> ImportAuthenticators(string file)
{
List<WinAuthAuthenticator> authenticators = new List<WinAuthAuthenticator>();
StringBuilder lines = new StringBuilder();
bool retry;
do
{
retry = false;
lines.Length = 0;
// read a plain text file
lines.Append(File.ReadAllText(file));
} while (retry);
int linenumber = 0;
try
{
using (var sr = new StringReader(lines.ToString()))
{
string line;
while ((line = sr.ReadLine()) != null)
{
linenumber++;
// ignore blank lines or comments
line = line.Trim();
if (line.Length == 0 || line.IndexOf("#") == 0)
{
continue;
}
// bug if there is a hash before ?
var hash = line.IndexOf("#");
var qm = line.IndexOf("?");
if (hash != -1 && hash < qm)
{
line = line.Substring(0, hash) + "%23" + line.Substring(hash + 1);
}
// parse and validate URI
var uri = new Uri(line);
// we only support "otpauth"
if (uri.Scheme != "otpauth")
{
throw new ApplicationException("Import only supports otpauth://");
}
// we only support totp (not hotp)
if (uri.Host != "totp" && uri.Host != "hotp")
{
throw new ApplicationException("Import only supports otpauth://totp/ or otpauth://hotp/");
}
// get the label and optional issuer
string issuer = string.Empty;
string label = (string.IsNullOrEmpty(uri.LocalPath) == false ? uri.LocalPath.Substring(1) : string.Empty); // skip past initial /
int p = label.IndexOf(":");
if (p != -1)
{
issuer = label.Substring(0, p);
label = label.Substring(p + 1);
}
// + aren't decoded
label = label.Replace("+", " ");
var query = HttpUtility.ParseQueryString(uri.Query);
string secret = query["secret"];
if (string.IsNullOrEmpty(secret) == true)
{
throw new ApplicationException("Authenticator does not contain secret");
}
string counter = query["counter"];
if (uri.Host == "hotp" && string.IsNullOrEmpty(counter) == true)
{
throw new ApplicationException("HOTP authenticator should have a counter");
}
WinAuthAuthenticator importedAuthenticator = new WinAuthAuthenticator
{
AutoRefresh = false
};
//
Authenticator auth;
if (string.Compare(issuer, "BattleNet", true) == 0)
{
string serial = query["serial"];
if (string.IsNullOrEmpty(serial) == true)
{
throw new ApplicationException("Battle.net Authenticator does not have a serial");
}
serial = serial.ToUpper();
if (Regex.IsMatch(serial, @"^[A-Z]{2}-?[\d]{4}-?[\d]{4}-?[\d]{4}$") == false)
{
throw new ApplicationException("Invalid serial for Battle.net Authenticator");
}
auth = new BattleNetAuthenticator();
//char[] decoded = Base32.getInstance().Decode(secret).Select(c => Convert.ToChar(c)).ToArray(); // this is hex string values
//string hex = new string(decoded);
//((BattleNetAuthenticator)auth).SecretKey = Authenticator.StringToByteArray(hex);
((BattleNetAuthenticator)auth).SecretKey = Base32.getInstance().Decode(secret);
((BattleNetAuthenticator)auth).Serial = serial;
issuer = string.Empty;
}
else if (string.Compare(issuer, "Steam", true) == 0)
{
auth = new SteamAuthenticator();
((SteamAuthenticator)auth).SecretKey = Base32.getInstance().Decode(secret);
((SteamAuthenticator)auth).Serial = string.Empty;
((SteamAuthenticator)auth).DeviceId = query["deviceid"] ?? string.Empty;
((SteamAuthenticator)auth).SteamData = query["data"] ?? string.Empty;
issuer = string.Empty;
}
else if (uri.Host == "hotp")
{
auth = new HOTPAuthenticator();
((HOTPAuthenticator)auth).SecretKey = Base32.getInstance().Decode(secret);
((HOTPAuthenticator)auth).Counter = int.Parse(counter);
if (string.IsNullOrEmpty(issuer) == false)
{
auth.Issuer = issuer;
}
}
else // if (string.Compare(issuer, "Google", true) == 0)
{
auth = new GoogleAuthenticator();
((GoogleAuthenticator)auth).Enroll(secret);
if (string.Compare(issuer, "Google", true) == 0)
{
issuer = string.Empty;
}
else if (string.IsNullOrEmpty(issuer) == false)
{
auth.Issuer = issuer;
}
}
int period = 0;
int.TryParse(query["period"], out period);
if (period != 0)
{
auth.Period = period;
}
int digits = 0;
int.TryParse(query["digits"], out digits);
if (digits != 0)
{
auth.CodeDigits = digits;
}
Authenticator.HMACTypes hmactype;
if (Enum.TryParse<Authenticator.HMACTypes>(query["algorithm"], true, out hmactype) == true)
{
auth.HMACType = hmactype;
}
//
if (label.Length != 0)
{
importedAuthenticator.Name = (issuer.Length != 0 ? issuer + " (" + label + ")" : label);
}
else if (issuer.Length != 0)
{
importedAuthenticator.Name = issuer;
}
else
{
importedAuthenticator.Name = "Imported";
}
//
importedAuthenticator.AuthenticatorData = auth;
// sync
importedAuthenticator.Sync();
authenticators.Add(importedAuthenticator);
}
}
return authenticators;
}
catch (UriFormatException ex)
{
throw new ImportException(string.Format("Invalid authenticator at line {0}", linenumber), ex);
}
catch (Exception ex)
{
throw new ImportException(string.Format("Error importing at line {0}:{1}", ex.Message), ex);
}
}
public static string ExportAuthenticators(IList<WinAuthAuthenticator> authenticators, string password)
{
// create file in memory
using (var ms = new MemoryStream())
{
using (var sw = new StreamWriter(ms))
{
List<WinAuthAuthenticator> unprotected = new List<WinAuthAuthenticator>();
foreach (var auth in authenticators)
{
unprotected.Add(auth);
string line = auth.ToUrl();
sw.WriteLine(line);
}
// reprotect
foreach (var auth in unprotected)
{
auth.AuthenticatorData.Protect();
}
// reset and write stream out to disk or as zip
sw.Flush();
ms.Seek(0, SeekOrigin.Begin);
var result = Encoding.UTF8.GetString(ms.ToArray());
return result;
}
}
}
}
}
-19
View File
@@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SteamTool.Auth
{
/// <summary>
/// Exception class wrapper for importing error
/// </summary>
public class ImportException : ApplicationException
{
public ImportException() : base() { }
public ImportException(string message) : base(message) { }
public ImportException(string message, Exception ex) : base(message, ex) { }
}
}
-18
View File
@@ -1,18 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Platforms>AnyCPU;x86</Platforms>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SteamTool.Authenticator\SteamTool.Authenticator.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="PresentationCore">
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\PresentationCore.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
-22
View File
@@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace SteamTool.Auth.Win32
{
public class WinAPI
{
public const string LibraryName = "user32.dll";
[DllImport(LibraryName, CharSet = CharSet.Auto)]
internal static extern IntPtr GetOpenClipboardWindow();
[DllImport(LibraryName, SetLastError = true, CharSet = CharSet.Auto)]
internal static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport(LibraryName, CharSet = CharSet.Auto, SetLastError = true)]
internal static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
}
}
-597
View File
@@ -1,597 +0,0 @@
using SteamTool.Auth.Win32;
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Windows;
using System.Xml;
using WinAuth;
namespace SteamTool.Auth
{
public interface IWinAuthAuthenticatorChangedListener
{
void OnWinAuthAuthenticatorChanged(WinAuthAuthenticator sender, WinAuthAuthenticatorChangedEventArgs e);
}
/// <summary>
/// Wrapper for real authenticator data used to save to file with other application information
/// </summary>
public class WinAuthAuthenticator : ICloneable
{
/// <summary>
/// Event handler fired when property is changed
/// </summary>
public event WinAuthAuthenticatorChangedHandler OnWinAuthAuthenticatorChanged;
/// <summary>
/// Unique Id of authenticator saved in config
/// </summary>
public Guid Id { get; set; }
/// <summary>
/// Index for authenticator when in sorted list
/// </summary>
public int Index { get; set; }
/// <summary>
/// Actual authenticator data
/// </summary>
public Authenticator AuthenticatorData { get; set; }
/// <summary>
/// When this authenticator was created
/// </summary>
public DateTime Created { get; set; }
private string _name;
private bool _autoRefresh;
private bool _allowCopy;
private bool _copyOnCode;
private bool _hideSerial;
/// <summary>
/// Create the authenticator wrapper
/// </summary>
public WinAuthAuthenticator()
{
Id = Guid.NewGuid();
Created = DateTime.Now;
_autoRefresh = true;
}
/// <summary>
/// Clone this authenticator
/// </summary>
/// <returns></returns>
public object Clone()
{
WinAuthAuthenticator clone = this.MemberwiseClone() as WinAuthAuthenticator;
clone.Id = Guid.NewGuid();
clone.OnWinAuthAuthenticatorChanged = null;
clone.AuthenticatorData = (this.AuthenticatorData != null ? this.AuthenticatorData.Clone() as Authenticator : null);
return clone;
}
/// <summary>
/// Mark this authenticator as having changed
/// </summary>
public void MarkChanged()
{
if (OnWinAuthAuthenticatorChanged != null)
{
OnWinAuthAuthenticatorChanged(this, new WinAuthAuthenticatorChangedEventArgs());
}
}
/// <summary>
/// Get/set the name of this authenticator
/// </summary>
public string Name
{
get
{
return _name;
}
set
{
_name = value;
if (OnWinAuthAuthenticatorChanged != null)
{
OnWinAuthAuthenticatorChanged(this, new WinAuthAuthenticatorChangedEventArgs("Name"));
}
}
}
/// <summary>
/// Get/set auto refresh flag
/// </summary>
public bool AutoRefresh
{
get
{
if (this.AuthenticatorData != null && this.AuthenticatorData is HOTPAuthenticator)
{
return false;
}
else
{
return _autoRefresh;
}
}
set
{
// HTOP must always be false
if (this.AuthenticatorData != null && this.AuthenticatorData is HOTPAuthenticator)
{
_autoRefresh = false;
}
else
{
_autoRefresh = value;
}
if (OnWinAuthAuthenticatorChanged != null)
{
OnWinAuthAuthenticatorChanged(this, new WinAuthAuthenticatorChangedEventArgs("AutoRefresh"));
}
}
}
/// <summary>
/// Get/set allow copy flag
/// </summary>
public bool AllowCopy
{
get
{
return _allowCopy;
}
set
{
_allowCopy = value;
if (OnWinAuthAuthenticatorChanged != null)
{
OnWinAuthAuthenticatorChanged(this, new WinAuthAuthenticatorChangedEventArgs("AllowCopy"));
}
}
}
/// <summary>
/// Get/set auto copy flag
/// </summary>
public bool CopyOnCode
{
get
{
return _copyOnCode;
}
set
{
_copyOnCode = value;
if (OnWinAuthAuthenticatorChanged != null)
{
OnWinAuthAuthenticatorChanged(this, new WinAuthAuthenticatorChangedEventArgs("CopyOnCode"));
}
}
}
/// <summary>
/// Get/set hide serial flag
/// </summary>
public bool HideSerial
{
get
{
return _hideSerial;
}
set
{
_hideSerial = value;
if (OnWinAuthAuthenticatorChanged != null)
{
OnWinAuthAuthenticatorChanged(this, new WinAuthAuthenticatorChangedEventArgs("HideSerial"));
}
}
}
public string CurrentCode
{
get
{
if (this.AuthenticatorData == null)
{
return null;
}
string code = this.AuthenticatorData.CurrentCode;
if (this.AuthenticatorData is HOTPAuthenticator)
{
if (OnWinAuthAuthenticatorChanged != null)
{
OnWinAuthAuthenticatorChanged(this, new WinAuthAuthenticatorChangedEventArgs("HOTP", this.AuthenticatorData));
}
}
return code;
}
}
/// <summary>
/// Sync the current authenticator's time with its server
/// </summary>
public void Sync()
{
if (AuthenticatorData != null)
{
try
{
AuthenticatorData.Sync();
}
catch (EncryptedSecretDataException)
{
// reset lastsync to force sync on next decryption
}
}
}
/// <summary>
/// Copy the current code to the clipboard
/// </summary>
public void CopyCodeToClipboard(string code = null, bool showError = false)
{
if (code == null)
{
code = this.CurrentCode;
}
bool clipRetry = false;
do
{
bool failed = false;
// check if the clipboard is locked
IntPtr hWnd = WinAPI.GetOpenClipboardWindow();
if (hWnd != IntPtr.Zero)
{
int len = WinAPI.GetWindowTextLength(hWnd);
if (len == 0)
{
//WinAuthMain.LogException(new ApplicationException("Clipboard in use by another process"));
}
else
{
StringBuilder sb = new StringBuilder(len + 1);
WinAPI.GetWindowText(hWnd, sb, sb.Capacity);
//WinAuthMain.LogException(new ApplicationException("Clipboard in use by '" + sb.ToString() + "'"));
}
failed = true;
}
else
{
// Issue#170: can still get error copying even though it works, so just increase retries and ignore error
try
{
Clipboard.Clear();
// add delay for clip error
System.Threading.Thread.Sleep(100);
Clipboard.SetDataObject(code, true);
}
catch (ExternalException)
{
}
}
if (failed == true && showError == true)
{
// only show an error the first time
//clipRetry = (MessageBox.Show(form, strings.ClipboardInUse,
// WinAuthMain.APPLICATION_NAME,
// MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes);
}
}
while (clipRetry == true);
}
public bool ReadXml(XmlReader reader, string password)
{
bool changed = false;
Guid id;
if (Guid.TryParse(reader.GetAttribute("id"), out id) == true)
{
Id = id;
}
string authenticatorType = reader.GetAttribute("type");
if (string.IsNullOrEmpty(authenticatorType) == false)
{
Type type = typeof(Authenticator).Assembly.GetType(authenticatorType, false, true);
this.AuthenticatorData = Activator.CreateInstance(type) as Authenticator;
}
//string encrypted = reader.GetAttribute("encrypted");
//if (string.IsNullOrEmpty(encrypted) == false)
//{
// // read the encrypted text from the node
// string data = reader.ReadElementContentAsString();
// // decrypt
// Authenticator.PasswordTypes passwordType;
// data = Authenticator.DecryptSequence(data, encrypted, password, out passwordType);
// using (MemoryStream ms = new MemoryStream(Authenticator.StringToByteArray(data)))
// {
// reader = XmlReader.Create(ms);
// ReadXml(reader, password);
// }
// this.PasswordType = passwordType;
// this.Password = password;
// return;
//}
reader.MoveToContent();
if (reader.IsEmptyElement)
{
reader.Read();
return changed;
}
reader.Read();
while (reader.EOF == false)
{
if (reader.IsStartElement())
{
switch (reader.Name)
{
case "name":
Name = reader.ReadElementContentAsString();
break;
case "created":
long t = reader.ReadElementContentAsLong();
t += Convert.ToInt64(new TimeSpan(new DateTime(1970, 1, 1).Ticks).TotalMilliseconds);
t *= TimeSpan.TicksPerMillisecond;
Created = new DateTime(t).ToLocalTime();
break;
case "autorefresh":
_autoRefresh = reader.ReadElementContentAsBoolean();
break;
case "allowcopy":
_allowCopy = reader.ReadElementContentAsBoolean();
break;
case "copyoncode":
_copyOnCode = reader.ReadElementContentAsBoolean();
break;
case "hideserial":
_hideSerial = reader.ReadElementContentAsBoolean();
break;
case "authenticatordata":
try
{
// we don't pass the password as they are locked till clicked
changed = this.AuthenticatorData.ReadXml(reader) || changed;
}
catch (EncryptedSecretDataException)
{
// no action needed
}
catch (BadPasswordException)
{
// no action needed
}
break;
// v2
case "authenticator":
this.AuthenticatorData = Authenticator.ReadXmlv2(reader, password);
break;
// v2
case "servertimediff":
this.AuthenticatorData.ServerTimeDiff = reader.ReadElementContentAsLong();
break;
default:
reader.Skip();
break;
}
}
else
{
reader.Read();
break;
}
}
return changed;
}
/// <summary>
/// Write the data as xml into an XmlWriter
/// </summary>
/// <param name="writer">XmlWriter to write config</param>
public void WriteXmlString(XmlWriter writer)
{
writer.WriteStartElement(typeof(WinAuthAuthenticator).Name);
writer.WriteAttributeString("id", this.Id.ToString());
if (this.AuthenticatorData != null)
{
writer.WriteAttributeString("type", this.AuthenticatorData.GetType().FullName);
}
//if (this.PasswordType != Authenticator.PasswordTypes.None)
//{
// string data;
// using (MemoryStream ms = new MemoryStream())
// {
// XmlWriterSettings settings = new XmlWriterSettings();
// settings.Indent = true;
// settings.Encoding = Encoding.UTF8;
// using (XmlWriter encryptedwriter = XmlWriter.Create(ms, settings))
// {
// Authenticator.PasswordTypes savedpasswordType = PasswordType;
// PasswordType = Authenticator.PasswordTypes.None;
// WriteXmlString(encryptedwriter);
// PasswordType = savedpasswordType;
// }
// //data = Encoding.UTF8.GetString(ms.ToArray());
// data = Authenticator.ByteArrayToString(ms.ToArray());
// }
// string encryptedTypes;
// data = Authenticator.EncryptSequence(data, PasswordType, Password, out encryptedTypes);
// writer.WriteAttributeString("encrypted", encryptedTypes);
// writer.WriteString(data);
// writer.WriteEndElement();
// return;
//}
writer.WriteStartElement("name");
writer.WriteValue(this.Name ?? string.Empty);
writer.WriteEndElement();
writer.WriteStartElement("created");
writer.WriteValue(Convert.ToInt64((this.Created.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalMilliseconds));
writer.WriteEndElement();
writer.WriteStartElement("autorefresh");
writer.WriteValue(this.AutoRefresh);
writer.WriteEndElement();
//
writer.WriteStartElement("allowcopy");
writer.WriteValue(this.AllowCopy);
writer.WriteEndElement();
//
writer.WriteStartElement("copyoncode");
writer.WriteValue(this.CopyOnCode);
writer.WriteEndElement();
//
writer.WriteStartElement("hideserial");
writer.WriteValue(this.HideSerial);
writer.WriteEndElement();
//
// save the authenticator to the config file
if (this.AuthenticatorData != null)
{
this.AuthenticatorData.WriteToWriter(writer);
// save script with password and generated salt
//if (this.AutoLogin != null)
//{
// this.AutoLogin.WriteXmlString(writer, this.AuthenticatorData.PasswordType, this.AuthenticatorData.Password);
//}
}
writer.WriteEndElement();
}
/// <summary>
/// Create a KeyUriFormat compatible URL
/// See https://code.google.com/p/google-authenticator/wiki/KeyUriFormat
/// </summary>
/// <returns>string</returns>
public virtual string ToUrl(bool compat = false)
{
string type = "totp";
string extraparams = string.Empty;
Match match;
string issuer = this.AuthenticatorData.Issuer;
string label = this.Name;
if (string.IsNullOrEmpty(issuer) == true && (match = Regex.Match(label, @"^([^\(]+)\s+\((.*?)\)(.*)")).Success == true)
{
issuer = match.Groups[1].Value;
label = match.Groups[2].Value + match.Groups[3].Value;
}
if (string.IsNullOrEmpty(issuer) == false && (match = Regex.Match(label, @"^" + issuer + @"\s+\((.*?)\)(.*)")).Success == true)
{
label = match.Groups[1].Value + match.Groups[2].Value;
}
if (string.IsNullOrEmpty(issuer) == false)
{
extraparams += "&issuer=" + HttpUtility.UrlEncode(issuer);
}
if (this.AuthenticatorData.HMACType != Authenticator.DEFAULT_HMAC_TYPE)
{
extraparams += "&algorithm=" + this.AuthenticatorData.HMACType.ToString();
}
if (this.AuthenticatorData is BattleNetAuthenticator)
{
extraparams += "&serial=" + HttpUtility.UrlEncode(((BattleNetAuthenticator)this.AuthenticatorData).Serial.Replace("-", ""));
}
else if (this.AuthenticatorData is SteamAuthenticator)
{
if (compat == false)
{
extraparams += "&deviceid=" + HttpUtility.UrlEncode(((SteamAuthenticator)this.AuthenticatorData).DeviceId);
extraparams += "&data=" + HttpUtility.UrlEncode(((SteamAuthenticator)this.AuthenticatorData).SteamData);
}
}
else if (this.AuthenticatorData is HOTPAuthenticator)
{
type = "hotp";
extraparams += "&counter=" + ((HOTPAuthenticator)this.AuthenticatorData).Counter;
}
string secret = HttpUtility.UrlEncode(Base32.getInstance().Encode(this.AuthenticatorData.SecretKey));
if (this.AuthenticatorData.Period != Authenticator.DEFAULT_PERIOD)
{
extraparams += "&period=" + this.AuthenticatorData.Period;
}
var url = string.Format("otpauth://" + type + "/{0}?secret={1}&digits={2}{3}",
(string.IsNullOrEmpty(issuer) == false ? HttpUtility.UrlPathEncode(issuer) + ":" + HttpUtility.UrlPathEncode(label) : HttpUtility.UrlPathEncode(label)),
secret,
this.AuthenticatorData.CodeDigits,
extraparams);
return url;
}
}
/// <summary>
/// Delegate for ConfigChange event
/// </summary>
/// <param name="source"></param>
/// <param name="args"></param>
public delegate void WinAuthAuthenticatorChangedHandler(WinAuthAuthenticator source, WinAuthAuthenticatorChangedEventArgs args);
/// <summary>
/// Change event arguments
/// </summary>
public class WinAuthAuthenticatorChangedEventArgs : EventArgs
{
public string Property { get; private set; }
public Authenticator Authenticator { get; private set; }
/// <summary>
/// Default constructor
/// </summary>
public WinAuthAuthenticatorChangedEventArgs(string property = null, Authenticator authenticator = null)
{
Property = property;
Authenticator = authenticator;
}
}
}
File diff suppressed because it is too large Load Diff
-33
View File
@@ -1,33 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using SteamTools.Model;
using Newtonsoft.Json;
namespace SteamTools.Helper
{
public static class ConfigHelper
{
private const string ConfigFileName = "SteamToolData.dat";
private static readonly string ConfigPath =
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), ConfigFileName);
public static SteamToolConfig SteamToolConfig { get; set; }
public static void SaveConfig()
{
var jsonData = JsonConvert.SerializeObject(SteamToolConfig);
File.WriteAllText(ConfigPath, jsonData, Encoding.UTF8);
}
public static SteamToolConfig ReadConfig()
{
SteamToolConfig = JsonConvert.DeserializeObject<SteamToolConfig>(File.ReadAllText(ConfigPath, Encoding.UTF8));
return SteamToolConfig;
}
}
}
@@ -1,75 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Win32;
namespace SteamTools.Helper
{
public static class RegistryKeyHelper
{
/// <summary>
/// 创建注册表项
/// </summary>
/// <param name="registryKey"></param>
/// <param name="path"></param>
/// <returns></returns>
public static RegistryKey CreateRegistryKey(RegistryKey registryKey, string path)
{
return registryKey.CreateSubKey(path);
}
/// <summary>
/// 删除注册表项
/// </summary>
/// <param name="registryKey"></param>
/// <param name="path"></param>
/// <returns></returns>
public static void DeleteRegistryKey(RegistryKey registryKey, string path)
{
registryKey.DeleteSubKey(path, true); //该方法无返回值,直接调用即可
registryKey.Close();
}
/// <summary>
/// 读取注册表值
/// </summary>
/// <param name="registryKey"></param>
/// <param name="path"></param>
/// <param name="key"></param>
/// <returns></returns>
public static string ReadRegistryKey(RegistryKey registryKey, string path, string key)
{
var myreg = registryKey.OpenSubKey(path);
if (myreg != null)
{
var info = myreg.GetValue(key).ToString();
myreg.Close();
return info;
}
return string.Empty;
}
/// <summary>
/// 新增或修改注册表值
/// </summary>
/// <param name="registryKey"></param>
/// <param name="path"></param>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="registryValueKind"></param>
/// <returns></returns>
public static void AddOrUpdateRegistryKey(RegistryKey registryKey, string path, string key, string value, RegistryValueKind registryValueKind)
{
RegistryKey myreg = registryKey.OpenSubKey(path, true); //该项必须已存在
if (myreg != null)
{
myreg.SetValue(key, value, registryValueKind);
myreg.Close();
}
}
}
}
-107
View File
@@ -1,107 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Gameloop.Vdf.Linq;
using Microsoft.Win32;
using SteamTool.Common.Helper;
using SteamTools.Model;
namespace SteamTools.Helper
{
public class SteamHelper
{
public static readonly SteamHelper Instance = new SteamHelper();
public string SteamPath { get; set; }
public string SteamExePath { get; set; }
private const string SteamRegistryPath = @"SOFTWARE\Valve\Steam";
public SteamHelper()
{
var steamExePath = RegistryKeyHelper.ReadRegistryKey(Registry.CurrentUser, SteamRegistryPath, "SteamExe");
var steamPath = RegistryKeyHelper.ReadRegistryKey(Registry.CurrentUser, SteamRegistryPath, "SteamPath");
if (File.Exists(steamExePath))
{
SteamExePath = steamExePath;
}
if (Directory.Exists(steamPath))
{
SteamPath = steamPath;
}
}
public void KillSteamProcess()
{
Process[] processes = Process.GetProcesses();
foreach (Process process in processes)
{
if (process.ProcessName == "Steam" || process.ProcessName == "SteamService" || process.ProcessName == "steamwebhelper")
{
process.Kill();
}
}
}
public void StartSteam(string param = "")
{
if (!string.IsNullOrEmpty(SteamExePath))
{
Process.Start(SteamExePath, param);
}
}
/// <summary>
/// 获取最后一次自动登陆steam用户名称
/// </summary>
/// <returns></returns>
public string GetLastLoginUserName()
{
return RegistryKeyHelper.ReadRegistryKey(Registry.CurrentUser, SteamRegistryPath, "AutoLoginUser");
}
/// <summary>
/// 获取所有记住登陆steam用户信息
/// </summary>
/// <returns></returns>
public List<SteamUser> GetAllUser()
{
var users = new List<SteamUser>();
if (SteamPath != null)
{
var v = VdfHelper.GetVdfModelByPath(SteamPath + "/config/loginusers.vdf");
foreach (var item in v.Value)
{
var i = item.Value;
var user = new SteamUser
{
AccountName = i.AccountName.ToString(),
PersonaName = i.PersonaName.ToString(),
RememberPassword = Convert.ToBoolean(Convert.ToInt64(i.RememberPassword.ToString())),
MostRecent = Convert.ToBoolean(Convert.ToInt64(i.MostRecent.ToString())),
Timestamp = Convert.ToInt64(i.Timestamp.ToString())
};
user.LastLoginTime= new DateTime(1970, 1, 1, 8, 0, 0).AddSeconds(user.Timestamp);
users.Add(user);
}
}
return users;
}
/// <summary>
/// 设置下次登陆steam用户
/// </summary>
public void SetCurrentUser(string username)
{
RegistryKeyHelper.AddOrUpdateRegistryKey(Registry.CurrentUser, SteamRegistryPath, "AutoLoginUser", username, RegistryValueKind.String);
}
}
}
-35
View File
@@ -1,35 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Gameloop.Vdf;
using Gameloop.Vdf.Linq;
namespace SteamTool.Common.Helper
{
public static class VdfHelper
{
/// <summary>
/// 获取VDF类型内容
/// </summary>
/// <param name="path">vdf文件内容</param>
/// <returns></returns>
public static dynamic GetVdfModel(string text)
{
return VdfConvert.Deserialize(text);
}
/// <summary>
/// 根据路径获取VDF类型内容
/// </summary>
/// <param name="path">vdf文件路径</param>
/// <returns></returns>
public static dynamic GetVdfModelByPath(string path)
{
string text = File.ReadAllText(path,Encoding.UTF8);
return GetVdfModel(text); ;
}
}
}
-21
View File
@@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SteamTools.Model
{
public class SteamToolConfig
{
/// <summary>
/// 启动参数
/// </summary>
public string SteamRunParam { get; set; }
/// <summary>
/// 保存用户
/// </summary>
public List<SteamUser> SteamUsers { get; set; }
}
}
-65
View File
@@ -1,65 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SteamTools.Model
{
public class SteamUser
{
public string SteamId3 { get; set; }
public int SteamId3_Int { get; }
public string SteamId32 { get; set; }
public int SteamId32_Int { get; }
public long SteamId64 { get; set; }
/// <summary>
/// 个人资料链接
/// </summary>
public string ProfileUrl { get; set; }
/// <summary>
/// 昵称
/// </summary>
public string PersonaName { get; set; }
/// <summary>
/// 用户名
/// </summary>
public string AccountName { get; set; }
/// <summary>
/// 是否记住密码
/// </summary>
public bool RememberPassword { get; set; }
/// <summary>
/// 密码
/// </summary>
public string PassWord { get; set; }
/// <summary>
/// 最后登录时间戳
/// </summary>
public long Timestamp { get; set; }
/// <summary>
/// 最后登录时间
/// </summary>
public DateTime LastLoginTime { get; set; }
/// <summary>
/// 最近登录
/// </summary>
public bool MostRecent { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
}
}
@@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("SteamTool.Common")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SteamTool.Common")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("75e148c7-5f32-4f01-9444-cedefa28748a")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
@@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SteamTool.Common.Service
{
public class SteamToolsService
{
}
}
-74
View File
@@ -1,74 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{75E148C7-5F32-4F01-9444-CEDEFA28748A}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SteamTool.Common</RootNamespace>
<AssemblyName>SteamTool.Common</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == '发布|AnyCPU'">
<OutputPath>bin\发布\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Gameloop.Vdf, Version=0.6.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Gameloop.Vdf.0.6.1\lib\net45\Gameloop.Vdf.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Helper\ConfigHelper.cs" />
<Compile Include="Helper\RegistryKeyHelper.cs" />
<Compile Include="Helper\SteamHelper.cs" />
<Compile Include="Helper\VdfHelper.cs" />
<Compile Include="Model\SteamToolConfig.cs" />
<Compile Include="Model\SteamUser.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Service\SteamToolsService.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
-5
View File
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Gameloop.Vdf" version="0.6.1" targetFramework="net46" />
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net46" />
</packages>
-26
View File
@@ -1,26 +0,0 @@
using SteamTool.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace SteamTool.Proxy
{
public static class CertificateEx
{
public static string GetPublicPemCertificateString(this X509Certificate2 @this)
{
StringBuilder builder = new StringBuilder();
builder.AppendLine(Const.HostTag);
builder.AppendLine("-----BEGIN CERTIFICATE-----");
builder.AppendLine(
Convert.ToBase64String(@this.RawData, Base64FormattingOptions.InsertLineBreaks));
builder.AppendLine("-----END CERTIFICATE-----");
builder.AppendLine(Const.HostTag);
return builder.ToString();
}
}
}
-36
View File
@@ -1,36 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Gameloop.Vdf;
using Gameloop.Vdf.Linq;
namespace SteamTool.Core
{
public class VdfService
{
/// <summary>
/// 获取VDF类型内容
/// </summary>
/// <param name="path">vdf文件内容</param>
/// <returns></returns>
public dynamic GetVdfModel(string text)
{
return VdfConvert.Deserialize(text);
}
/// <summary>
/// 根据路径获取VDF类型内容
/// </summary>
/// <param name="path">vdf文件路径</param>
/// <returns></returns>
public dynamic GetVdfModelByPath(string path)
{
string text = File.ReadAllText(path,Encoding.UTF8);
return GetVdfModel(text); ;
}
}
}
-87
View File
@@ -1,87 +0,0 @@
using System;
namespace SteamTool.Model
{
public class SteamUser
{
public string SteamId3 { get; set; }
public long SteamId3_Int => ((SteamId64 >> (ushort)0) & 0xFFFFFFFF);
public string SteamId32 { get; set; }
public long SteamId32_Int { get; set; }
public long SteamId64 { get; set; }
/// <summary>
/// 个人资料链接
/// </summary>
public string ProfileUrl => string.Format("https://steamcommunity.com/profiles/{0}", SteamId64);
/// <summary>
/// 在线状态
/// </summary>
public string OnlineState { get; set; }
/// <summary>
/// 公开状态
/// friendsonly
/// public
/// </summary>
public string PrivacyState { get; set; }
/// <summary>
/// 头像链接
/// </summary>
public string AvatarIcon { get; set; }
/// <summary>
/// 头像链接
/// </summary>
public string AvatarMedium { get; set; }
/// <summary>
/// 头像链接
/// </summary>
public string AvatarFull { get; set; }
/// <summary>
/// 昵称
/// </summary>
public string SteamID { get; set; }
/// <summary>
/// 用户名
/// </summary>
public string AccountName { get; set; }
/// <summary>
/// 是否记住密码
/// </summary>
public bool RememberPassword { get; set; }
/// <summary>
/// 密码
/// </summary>
public string PassWord { get; set; }
/// <summary>
/// 最后登录时间戳
/// </summary>
public long Timestamp { get; set; }
/// <summary>
/// 最后登录时间
/// </summary>
public DateTime LastLoginTime { get; set; }
/// <summary>
/// 最近登录
/// </summary>
public bool MostRecent { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
}
}
Binary file not shown.
Binary file not shown.
-14
View File
@@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SteamTool.Composition.Interface
{
[PluginFeature]
public interface ITool
{
string Name { get; }
object View { get; }
}
}
@@ -1,9 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SteamTool.Composition
{
[AttributeUsage(AttributeTargets.Interface)]
public sealed class PluginFeatureAttribute : Attribute { }
}
@@ -1,10 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Configurations>Debug;Release;发布</Configurations>
<LangVersion>8.0</LangVersion>
<Platforms>AnyCPU;x86</Platforms>
</PropertyGroup>
</Project>
+105 -240
View File
@@ -7,382 +7,189 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UI", "UI", "{45E5B6B2-0A6D-
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{350F425C-AF5A-4ED2-BDDC-B905A4E63A14}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Proxy", "SteamTool.Proxy\SteamTool.Proxy.csproj", "{A70C148D-042C-48DA-9963-0B777FC60215}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Proxy", "source\SteamTool.Proxy\SteamTool.Proxy.csproj", "{A70C148D-042C-48DA-9963-0B777FC60215}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Composition", "Composition", "{F62E508E-B374-4149-B9AC-0A8090AA6CD1}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Reference", "Reference", "{F62E508E-B374-4149-B9AC-0A8090AA6CD1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Steam.Service", "SteamTools.Steam.Service\SteamTool.Steam.Service.csproj", "{2A155A7B-3DFD-4F16-929D-9693D2411B83}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Steam.Service", "source\SteamTool.Steam.Service\SteamTool.Steam.Service.csproj", "{2A155A7B-3DFD-4F16-929D-9693D2411B83}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Core", "SteamTool.Core\SteamTool.Core.csproj", "{23E26040-19A5-4623-8863-B9ED539403B0}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Core", "source\SteamTool.Core\SteamTool.Core.csproj", "{23E26040-19A5-4623-8863-B9ED539403B0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTools", "SteamTools\SteamTools.csproj", "{0663899A-2EC5-4929-868C-9D9620FEA4FE}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTools", "source\SteamTools\SteamTools.csproj", "{0663899A-2EC5-4929-868C-9D9620FEA4FE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Steam4NET.Test", "SteamTool.Steam4NET.Test\SteamTool.Steam4NET.Test.csproj", "{790D22D4-94B0-4575-8E2D-C451EC520407}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Steam4NET.Test", "source\SteamTool.Steam4NET.Test\SteamTool.Steam4NET.Test.csproj", "{790D22D4-94B0-4575-8E2D-C451EC520407}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Steam4NET", "SteamTool.Steam4NET\SteamTool.Steam4NET.csproj", "{D4157059-D31A-4A21-AF4C-2D458F768041}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Steam4NET", "source\SteamTool.Steam4NET\SteamTool.Steam4NET.csproj", "{D4157059-D31A-4A21-AF4C-2D458F768041}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{D245A82C-66B2-4CD5-881C-3ED4332FC91D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Steamworks.Test", "SteamTool.Steamworks.Test\SteamTool.Steamworks.Test.csproj", "{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Steamworks.Test", "source\SteamTool.Steamworks.Test\SteamTool.Steamworks.Test.csproj", "{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lib", "lib", "{868B3B33-14B3-49AF-AE01-28D85FD98C1F}"
ProjectSection(SolutionItems) = preProject
Lib\MetroRadiance.Chrome.dll = Lib\MetroRadiance.Chrome.dll
Lib\MetroRadiance.Core.dll = Lib\MetroRadiance.Core.dll
Lib\MetroRadiance.dll = Lib\MetroRadiance.dll
C:\Users\Dark\Desktop\Titanium-Web-Proxy-master\Titanium-Web-Proxy-master\src\Titanium.Web.Proxy\obj\Debug\netstandard2.0\Titanium.Web.Proxy.dll = C:\Users\Dark\Desktop\Titanium-Web-Proxy-master\Titanium-Web-Proxy-master\src\Titanium.Web.Proxy\obj\Debug\netstandard2.0\Titanium.Web.Proxy.dll
EndProjectSection
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Proxy.Test", "source\SteamTool.Proxy.Test\SteamTool.Proxy.Test.csproj", "{4C441E34-FA65-4425-8242-4EB767BA9B95}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Proxy.Test", "SteamTool.Proxy.Test\SteamTool.Proxy.Test.csproj", "{4C441E34-FA65-4425-8242-4EB767BA9B95}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Model", "source\SteamTool.Model\SteamTool.Model.csproj", "{BDBACE3A-0138-4930-95F6-82562EA03F7A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Model", "SteamTool.Model\SteamTool.Model.csproj", "{BDBACE3A-0138-4930-95F6-82562EA03F7A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.SteamAPI", "source\SteamTool.SteamAPI\SteamTool.SteamAPI.csproj", "{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.SteamAPI", "SteamTool.SteamAPI\SteamTool.SteamAPI.csproj", "{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Authenticator", "source\SteamTool.Authenticator\SteamTool.Authenticator.csproj", "{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Authenticator", "SteamTool.Authenticator\SteamTool.Authenticator.csproj", "{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}"
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "SteamTools.UWP", "source\SteamTools.UWP\SteamTools.UWP.wapproj", "{2E755C75-E472-44E0-8AC4-F40209A60172}"
EndProject
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "SteamTools.UWP", "SteamTools.UWP\SteamTools.UWP.wapproj", "{2E755C75-E472-44E0-8AC4-F40209A60172}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Titanium.Web.Proxy", "references\Titanium-Web-Proxy\src\Titanium.Web.Proxy\Titanium.Web.Proxy.csproj", "{BBB75CAC-2BA3-473D-935D-0E59406F5E61}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MetroRadiance", "MetroRadiance", "{2B74A2B2-148D-4518-BF74-3408095E920B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MetroTrilithon.Desktop", "references\MetroRadiance\source\MetroTrilithon.Desktop\MetroTrilithon.Desktop.csproj", "{4E2EB2E0-E5FE-4FEB-A3E5-5F2F05CD1A67}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MetroRadiance.Core", "references\MetroRadiance\source\MetroRadiance.Core\MetroRadiance.Core.csproj", "{AF006EF5-D4BC-49C6-8E0E-DC2B882BE767}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MetroRadiance.Chrome", "references\MetroRadiance\source\MetroRadiance.Chrome\MetroRadiance.Chrome.csproj", "{DE0B3A58-C301-4671-8B32-4F195C9457A7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MetroRadiance", "references\MetroRadiance\source\MetroRadiance\MetroRadiance.csproj", "{2E226B1E-80F6-448D-B02B-0A029C5BC09E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MetroTrilithon", "references\MetroRadiance\source\MetroTrilithon\MetroTrilithon.csproj", "{2EE1744F-2D3C-4032-9A9E-C57FA3B512B3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
发布|Any CPU = 发布|Any CPU
发布|ARM = 发布|ARM
发布|ARM64 = 发布|ARM64
发布|x64 = 发布|x64
发布|x86 = 发布|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A70C148D-042C-48DA-9963-0B777FC60215}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.Debug|ARM.ActiveCfg = Debug|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.Debug|ARM.Build.0 = Debug|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.Debug|ARM64.Build.0 = Debug|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.Debug|x64.ActiveCfg = Debug|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.Debug|x64.Build.0 = Debug|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.Debug|x86.ActiveCfg = Debug|x86
{A70C148D-042C-48DA-9963-0B777FC60215}.Debug|x86.Build.0 = Debug|x86
{A70C148D-042C-48DA-9963-0B777FC60215}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.Release|Any CPU.Build.0 = Release|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.Release|ARM.ActiveCfg = Release|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.Release|ARM.Build.0 = Release|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.Release|ARM64.ActiveCfg = Release|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.Release|ARM64.Build.0 = Release|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.Release|x64.ActiveCfg = Release|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.Release|x64.Build.0 = Release|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.Release|x86.ActiveCfg = Release|x86
{A70C148D-042C-48DA-9963-0B777FC60215}.Release|x86.Build.0 = Release|x86
{A70C148D-042C-48DA-9963-0B777FC60215}.发布|Any CPU.ActiveCfg = 发布|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.发布|Any CPU.Build.0 = 发布|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.发布|ARM.ActiveCfg = 发布|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.发布|ARM.Build.0 = 发布|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.发布|ARM64.ActiveCfg = 发布|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.发布|ARM64.Build.0 = 发布|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.发布|x64.ActiveCfg = 发布|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.发布|x64.Build.0 = 发布|Any CPU
{A70C148D-042C-48DA-9963-0B777FC60215}.发布|x86.ActiveCfg = 发布|x86
{A70C148D-042C-48DA-9963-0B777FC60215}.发布|x86.Build.0 = 发布|x86
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Debug|ARM.ActiveCfg = Debug|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Debug|ARM.Build.0 = Debug|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Debug|ARM64.Build.0 = Debug|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Debug|x64.ActiveCfg = Debug|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Debug|x64.Build.0 = Debug|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Debug|x86.ActiveCfg = Debug|x86
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Debug|x86.Build.0 = Debug|x86
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Release|Any CPU.Build.0 = Release|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Release|ARM.ActiveCfg = Release|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Release|ARM.Build.0 = Release|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Release|ARM64.ActiveCfg = Release|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Release|ARM64.Build.0 = Release|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Release|x64.ActiveCfg = Release|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Release|x64.Build.0 = Release|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Release|x86.ActiveCfg = Release|x86
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.Release|x86.Build.0 = Release|x86
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.发布|Any CPU.ActiveCfg = 发布|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.发布|Any CPU.Build.0 = 发布|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.发布|ARM.ActiveCfg = 发布|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.发布|ARM.Build.0 = 发布|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.发布|ARM64.ActiveCfg = 发布|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.发布|ARM64.Build.0 = 发布|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.发布|x64.ActiveCfg = 发布|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.发布|x64.Build.0 = 发布|Any CPU
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.发布|x86.ActiveCfg = 发布|x86
{2A155A7B-3DFD-4F16-929D-9693D2411B83}.发布|x86.Build.0 = 发布|x86
{23E26040-19A5-4623-8863-B9ED539403B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.Debug|ARM.ActiveCfg = Debug|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.Debug|ARM.Build.0 = Debug|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.Debug|ARM64.Build.0 = Debug|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.Debug|x64.ActiveCfg = Debug|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.Debug|x64.Build.0 = Debug|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.Debug|x86.ActiveCfg = Debug|x86
{23E26040-19A5-4623-8863-B9ED539403B0}.Debug|x86.Build.0 = Debug|x86
{23E26040-19A5-4623-8863-B9ED539403B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.Release|Any CPU.Build.0 = Release|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.Release|ARM.ActiveCfg = Release|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.Release|ARM.Build.0 = Release|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.Release|ARM64.ActiveCfg = Release|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.Release|ARM64.Build.0 = Release|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.Release|x64.ActiveCfg = Release|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.Release|x64.Build.0 = Release|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.Release|x86.ActiveCfg = Release|x86
{23E26040-19A5-4623-8863-B9ED539403B0}.Release|x86.Build.0 = Release|x86
{23E26040-19A5-4623-8863-B9ED539403B0}.发布|Any CPU.ActiveCfg = Release|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.发布|Any CPU.Build.0 = Release|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.发布|ARM.ActiveCfg = Release|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.发布|ARM.Build.0 = Release|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.发布|ARM64.ActiveCfg = Release|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.发布|ARM64.Build.0 = Release|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.发布|x64.ActiveCfg = Release|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.发布|x64.Build.0 = Release|Any CPU
{23E26040-19A5-4623-8863-B9ED539403B0}.发布|x86.ActiveCfg = Debug|x86
{23E26040-19A5-4623-8863-B9ED539403B0}.发布|x86.Build.0 = Debug|x86
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Debug|ARM.ActiveCfg = Debug|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Debug|ARM.Build.0 = Debug|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Debug|ARM64.Build.0 = Debug|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Debug|x64.ActiveCfg = Debug|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Debug|x64.Build.0 = Debug|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Debug|x86.ActiveCfg = Debug|x86
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Debug|x86.Build.0 = Debug|x86
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Release|Any CPU.Build.0 = Release|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Release|ARM.ActiveCfg = Release|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Release|ARM.Build.0 = Release|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Release|ARM64.ActiveCfg = Release|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Release|ARM64.Build.0 = Release|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Release|x64.ActiveCfg = Release|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Release|x64.Build.0 = Release|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Release|x86.ActiveCfg = Release|x86
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.Release|x86.Build.0 = Release|x86
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.发布|Any CPU.ActiveCfg = Release|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.发布|Any CPU.Build.0 = Release|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.发布|ARM.ActiveCfg = Release|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.发布|ARM.Build.0 = Release|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.发布|ARM64.ActiveCfg = Release|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.发布|ARM64.Build.0 = Release|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.发布|x64.ActiveCfg = Release|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.发布|x64.Build.0 = Release|Any CPU
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.发布|x86.ActiveCfg = Debug|x86
{0663899A-2EC5-4929-868C-9D9620FEA4FE}.发布|x86.Build.0 = Debug|x86
{790D22D4-94B0-4575-8E2D-C451EC520407}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{790D22D4-94B0-4575-8E2D-C451EC520407}.Debug|Any CPU.Build.0 = Debug|Any CPU
{790D22D4-94B0-4575-8E2D-C451EC520407}.Debug|ARM.ActiveCfg = Debug|Any CPU
{790D22D4-94B0-4575-8E2D-C451EC520407}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{790D22D4-94B0-4575-8E2D-C451EC520407}.Debug|x64.ActiveCfg = Debug|Any CPU
{790D22D4-94B0-4575-8E2D-C451EC520407}.Debug|x86.ActiveCfg = Debug|x86
{790D22D4-94B0-4575-8E2D-C451EC520407}.Debug|x86.Build.0 = Debug|x86
{790D22D4-94B0-4575-8E2D-C451EC520407}.Release|Any CPU.ActiveCfg = Release|Any CPU
{790D22D4-94B0-4575-8E2D-C451EC520407}.Release|Any CPU.Build.0 = Release|Any CPU
{790D22D4-94B0-4575-8E2D-C451EC520407}.Release|ARM.ActiveCfg = Release|Any CPU
{790D22D4-94B0-4575-8E2D-C451EC520407}.Release|ARM64.ActiveCfg = Release|Any CPU
{790D22D4-94B0-4575-8E2D-C451EC520407}.Release|x64.ActiveCfg = Release|Any CPU
{790D22D4-94B0-4575-8E2D-C451EC520407}.Release|x86.ActiveCfg = Release|x86
{790D22D4-94B0-4575-8E2D-C451EC520407}.Release|x86.Build.0 = Release|x86
{790D22D4-94B0-4575-8E2D-C451EC520407}.发布|Any CPU.ActiveCfg = Release|Any CPU
{790D22D4-94B0-4575-8E2D-C451EC520407}.发布|Any CPU.Build.0 = Release|Any CPU
{790D22D4-94B0-4575-8E2D-C451EC520407}.发布|ARM.ActiveCfg = Release|Any CPU
{790D22D4-94B0-4575-8E2D-C451EC520407}.发布|ARM64.ActiveCfg = Release|Any CPU
{790D22D4-94B0-4575-8E2D-C451EC520407}.发布|x64.ActiveCfg = Release|Any CPU
{790D22D4-94B0-4575-8E2D-C451EC520407}.发布|x86.ActiveCfg = Debug|x86
{790D22D4-94B0-4575-8E2D-C451EC520407}.发布|x86.Build.0 = Debug|x86
{D4157059-D31A-4A21-AF4C-2D458F768041}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.Debug|ARM.ActiveCfg = Debug|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.Debug|ARM.Build.0 = Debug|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.Debug|ARM64.Build.0 = Debug|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.Debug|x64.ActiveCfg = Debug|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.Debug|x64.Build.0 = Debug|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.Debug|x86.ActiveCfg = Debug|x86
{D4157059-D31A-4A21-AF4C-2D458F768041}.Debug|x86.Build.0 = Debug|x86
{D4157059-D31A-4A21-AF4C-2D458F768041}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.Release|Any CPU.Build.0 = Release|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.Release|ARM.ActiveCfg = Release|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.Release|ARM.Build.0 = Release|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.Release|ARM64.ActiveCfg = Release|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.Release|ARM64.Build.0 = Release|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.Release|x64.ActiveCfg = Release|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.Release|x64.Build.0 = Release|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.Release|x86.ActiveCfg = Release|x86
{D4157059-D31A-4A21-AF4C-2D458F768041}.Release|x86.Build.0 = Release|x86
{D4157059-D31A-4A21-AF4C-2D458F768041}.发布|Any CPU.ActiveCfg = Release|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.发布|Any CPU.Build.0 = Release|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.发布|ARM.ActiveCfg = Release|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.发布|ARM.Build.0 = Release|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.发布|ARM64.ActiveCfg = Release|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.发布|ARM64.Build.0 = Release|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.发布|x64.ActiveCfg = Release|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.发布|x64.Build.0 = Release|Any CPU
{D4157059-D31A-4A21-AF4C-2D458F768041}.发布|x86.ActiveCfg = Debug|x86
{D4157059-D31A-4A21-AF4C-2D458F768041}.发布|x86.Build.0 = Debug|x86
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.Debug|x64.ActiveCfg = Debug|Any CPU
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.Debug|x86.ActiveCfg = Debug|x86
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.Debug|x86.Build.0 = Debug|x86
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.Release|Any CPU.Build.0 = Release|Any CPU
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.Release|ARM.ActiveCfg = Release|Any CPU
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.Release|ARM64.ActiveCfg = Release|Any CPU
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.Release|x64.ActiveCfg = Release|Any CPU
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.Release|x86.ActiveCfg = Release|x86
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.Release|x86.Build.0 = Release|x86
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.发布|Any CPU.ActiveCfg = Release|Any CPU
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.发布|Any CPU.Build.0 = Release|Any CPU
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.发布|ARM.ActiveCfg = Release|Any CPU
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.发布|ARM64.ActiveCfg = Release|Any CPU
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.发布|x64.ActiveCfg = Release|Any CPU
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.发布|x86.ActiveCfg = Debug|x86
{C03E4CF5-D68F-4CAC-B002-3A6799ED9E15}.发布|x86.Build.0 = Debug|x86
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Debug|ARM.ActiveCfg = Debug|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Debug|ARM.Build.0 = Debug|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Debug|ARM64.Build.0 = Debug|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Debug|x64.ActiveCfg = Debug|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Debug|x64.Build.0 = Debug|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Debug|x86.ActiveCfg = Debug|x86
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Debug|x86.Build.0 = Debug|x86
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Release|Any CPU.Build.0 = Release|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Release|ARM.ActiveCfg = Release|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Release|ARM.Build.0 = Release|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Release|ARM64.ActiveCfg = Release|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Release|ARM64.Build.0 = Release|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Release|x64.ActiveCfg = Release|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Release|x64.Build.0 = Release|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Release|x86.ActiveCfg = Release|x86
{4C441E34-FA65-4425-8242-4EB767BA9B95}.Release|x86.Build.0 = Release|x86
{4C441E34-FA65-4425-8242-4EB767BA9B95}.发布|Any CPU.ActiveCfg = Release|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.发布|Any CPU.Build.0 = Release|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.发布|ARM.ActiveCfg = Release|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.发布|ARM.Build.0 = Release|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.发布|ARM64.ActiveCfg = Release|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.发布|ARM64.Build.0 = Release|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.发布|x64.ActiveCfg = Release|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.发布|x64.Build.0 = Release|Any CPU
{4C441E34-FA65-4425-8242-4EB767BA9B95}.发布|x86.ActiveCfg = Debug|x86
{4C441E34-FA65-4425-8242-4EB767BA9B95}.发布|x86.Build.0 = Debug|x86
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Debug|ARM.ActiveCfg = Debug|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Debug|ARM.Build.0 = Debug|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Debug|ARM64.Build.0 = Debug|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Debug|x64.ActiveCfg = Debug|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Debug|x64.Build.0 = Debug|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Debug|x86.ActiveCfg = Debug|x86
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Debug|x86.Build.0 = Debug|x86
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Release|Any CPU.Build.0 = Release|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Release|ARM.ActiveCfg = Release|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Release|ARM.Build.0 = Release|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Release|ARM64.ActiveCfg = Release|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Release|ARM64.Build.0 = Release|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Release|x64.ActiveCfg = Release|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Release|x64.Build.0 = Release|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Release|x86.ActiveCfg = Release|x86
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.Release|x86.Build.0 = Release|x86
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.发布|Any CPU.ActiveCfg = Release|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.发布|Any CPU.Build.0 = Release|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.发布|ARM.ActiveCfg = Release|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.发布|ARM.Build.0 = Release|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.发布|ARM64.ActiveCfg = Release|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.发布|ARM64.Build.0 = Release|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.发布|x64.ActiveCfg = Release|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.发布|x64.Build.0 = Release|Any CPU
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.发布|x86.ActiveCfg = Debug|x86
{BDBACE3A-0138-4930-95F6-82562EA03F7A}.发布|x86.Build.0 = Debug|x86
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Debug|ARM.ActiveCfg = Debug|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Debug|ARM.Build.0 = Debug|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Debug|ARM64.Build.0 = Debug|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Debug|x64.ActiveCfg = Debug|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Debug|x64.Build.0 = Debug|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Debug|x86.ActiveCfg = Debug|x86
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Debug|x86.Build.0 = Debug|x86
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Release|Any CPU.Build.0 = Release|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Release|ARM.ActiveCfg = Release|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Release|ARM.Build.0 = Release|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Release|ARM64.ActiveCfg = Release|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Release|ARM64.Build.0 = Release|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Release|x64.ActiveCfg = Release|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Release|x64.Build.0 = Release|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Release|x86.ActiveCfg = Release|x86
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.Release|x86.Build.0 = Release|x86
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.发布|Any CPU.ActiveCfg = Debug|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.发布|Any CPU.Build.0 = Debug|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.发布|ARM.ActiveCfg = Release|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.发布|ARM.Build.0 = Release|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.发布|ARM64.ActiveCfg = Release|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.发布|ARM64.Build.0 = Release|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.发布|x64.ActiveCfg = Release|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.发布|x64.Build.0 = Release|Any CPU
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.发布|x86.ActiveCfg = Debug|x86
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F}.发布|x86.Build.0 = Debug|x86
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Debug|Any CPU.Build.0 = Debug|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Debug|ARM.ActiveCfg = Debug|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Debug|ARM.Build.0 = Debug|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Debug|ARM64.Build.0 = Debug|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Debug|x64.ActiveCfg = Debug|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Debug|x64.Build.0 = Debug|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Debug|x86.ActiveCfg = Debug|x86
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Debug|x86.Build.0 = Debug|x86
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Release|Any CPU.ActiveCfg = Release|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Release|Any CPU.Build.0 = Release|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Release|ARM.ActiveCfg = Release|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Release|ARM.Build.0 = Release|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Release|ARM64.ActiveCfg = Release|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Release|ARM64.Build.0 = Release|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Release|x64.ActiveCfg = Release|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Release|x64.Build.0 = Release|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Release|x86.ActiveCfg = Release|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.Release|x86.Build.0 = Release|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.发布|Any CPU.ActiveCfg = Debug|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.发布|Any CPU.Build.0 = Debug|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.发布|ARM.ActiveCfg = Release|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.发布|ARM.Build.0 = Release|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.发布|ARM64.ActiveCfg = Release|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.发布|ARM64.Build.0 = Release|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.发布|x64.ActiveCfg = Release|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.发布|x64.Build.0 = Release|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.发布|x86.ActiveCfg = Debug|Any CPU
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666}.发布|x86.Build.0 = Debug|Any CPU
{2E755C75-E472-44E0-8AC4-F40209A60172}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E755C75-E472-44E0-8AC4-F40209A60172}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E755C75-E472-44E0-8AC4-F40209A60172}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{2E755C75-E472-44E0-8AC4-F40209A60172}.Debug|ARM.ActiveCfg = Debug|ARM
{2E755C75-E472-44E0-8AC4-F40209A60172}.Debug|ARM.Build.0 = Debug|ARM
{2E755C75-E472-44E0-8AC4-F40209A60172}.Debug|ARM.Deploy.0 = Debug|ARM
{2E755C75-E472-44E0-8AC4-F40209A60172}.Debug|ARM64.ActiveCfg = Debug|ARM64
{2E755C75-E472-44E0-8AC4-F40209A60172}.Debug|ARM64.Build.0 = Debug|ARM64
{2E755C75-E472-44E0-8AC4-F40209A60172}.Debug|ARM64.Deploy.0 = Debug|ARM64
{2E755C75-E472-44E0-8AC4-F40209A60172}.Debug|x64.ActiveCfg = Debug|x64
{2E755C75-E472-44E0-8AC4-F40209A60172}.Debug|x64.Build.0 = Debug|x64
{2E755C75-E472-44E0-8AC4-F40209A60172}.Debug|x64.Deploy.0 = Debug|x64
@@ -392,33 +199,84 @@ Global
{2E755C75-E472-44E0-8AC4-F40209A60172}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2E755C75-E472-44E0-8AC4-F40209A60172}.Release|Any CPU.Build.0 = Release|Any CPU
{2E755C75-E472-44E0-8AC4-F40209A60172}.Release|Any CPU.Deploy.0 = Release|Any CPU
{2E755C75-E472-44E0-8AC4-F40209A60172}.Release|ARM.ActiveCfg = Release|ARM
{2E755C75-E472-44E0-8AC4-F40209A60172}.Release|ARM.Build.0 = Release|ARM
{2E755C75-E472-44E0-8AC4-F40209A60172}.Release|ARM.Deploy.0 = Release|ARM
{2E755C75-E472-44E0-8AC4-F40209A60172}.Release|ARM64.ActiveCfg = Release|ARM64
{2E755C75-E472-44E0-8AC4-F40209A60172}.Release|ARM64.Build.0 = Release|ARM64
{2E755C75-E472-44E0-8AC4-F40209A60172}.Release|ARM64.Deploy.0 = Release|ARM64
{2E755C75-E472-44E0-8AC4-F40209A60172}.Release|x64.ActiveCfg = Release|x64
{2E755C75-E472-44E0-8AC4-F40209A60172}.Release|x64.Build.0 = Release|x64
{2E755C75-E472-44E0-8AC4-F40209A60172}.Release|x64.Deploy.0 = Release|x64
{2E755C75-E472-44E0-8AC4-F40209A60172}.Release|x86.ActiveCfg = Release|x86
{2E755C75-E472-44E0-8AC4-F40209A60172}.Release|x86.Build.0 = Release|x86
{2E755C75-E472-44E0-8AC4-F40209A60172}.Release|x86.Deploy.0 = Release|x86
{2E755C75-E472-44E0-8AC4-F40209A60172}.发布|Any CPU.ActiveCfg = Release|Any CPU
{2E755C75-E472-44E0-8AC4-F40209A60172}.发布|Any CPU.Build.0 = Release|Any CPU
{2E755C75-E472-44E0-8AC4-F40209A60172}.发布|Any CPU.Deploy.0 = Release|Any CPU
{2E755C75-E472-44E0-8AC4-F40209A60172}.发布|ARM.ActiveCfg = Debug|ARM
{2E755C75-E472-44E0-8AC4-F40209A60172}.发布|ARM.Build.0 = Debug|ARM
{2E755C75-E472-44E0-8AC4-F40209A60172}.发布|ARM.Deploy.0 = Debug|ARM
{2E755C75-E472-44E0-8AC4-F40209A60172}.发布|ARM64.ActiveCfg = Debug|ARM64
{2E755C75-E472-44E0-8AC4-F40209A60172}.发布|ARM64.Build.0 = Debug|ARM64
{2E755C75-E472-44E0-8AC4-F40209A60172}.发布|ARM64.Deploy.0 = Debug|ARM64
{2E755C75-E472-44E0-8AC4-F40209A60172}.发布|x64.ActiveCfg = Debug|x64
{2E755C75-E472-44E0-8AC4-F40209A60172}.发布|x64.Build.0 = Debug|x64
{2E755C75-E472-44E0-8AC4-F40209A60172}.发布|x64.Deploy.0 = Debug|x64
{2E755C75-E472-44E0-8AC4-F40209A60172}.发布|x86.ActiveCfg = Debug|x86
{2E755C75-E472-44E0-8AC4-F40209A60172}.发布|x86.Build.0 = Debug|x86
{2E755C75-E472-44E0-8AC4-F40209A60172}.发布|x86.Deploy.0 = Debug|x86
{BBB75CAC-2BA3-473D-935D-0E59406F5E61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BBB75CAC-2BA3-473D-935D-0E59406F5E61}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BBB75CAC-2BA3-473D-935D-0E59406F5E61}.Debug|x64.ActiveCfg = Debug|Any CPU
{BBB75CAC-2BA3-473D-935D-0E59406F5E61}.Debug|x64.Build.0 = Debug|Any CPU
{BBB75CAC-2BA3-473D-935D-0E59406F5E61}.Debug|x86.ActiveCfg = Debug|Any CPU
{BBB75CAC-2BA3-473D-935D-0E59406F5E61}.Debug|x86.Build.0 = Debug|Any CPU
{BBB75CAC-2BA3-473D-935D-0E59406F5E61}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BBB75CAC-2BA3-473D-935D-0E59406F5E61}.Release|Any CPU.Build.0 = Release|Any CPU
{BBB75CAC-2BA3-473D-935D-0E59406F5E61}.Release|x64.ActiveCfg = Release|Any CPU
{BBB75CAC-2BA3-473D-935D-0E59406F5E61}.Release|x64.Build.0 = Release|Any CPU
{BBB75CAC-2BA3-473D-935D-0E59406F5E61}.Release|x86.ActiveCfg = Release|Any CPU
{BBB75CAC-2BA3-473D-935D-0E59406F5E61}.Release|x86.Build.0 = Release|Any CPU
{4E2EB2E0-E5FE-4FEB-A3E5-5F2F05CD1A67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E2EB2E0-E5FE-4FEB-A3E5-5F2F05CD1A67}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E2EB2E0-E5FE-4FEB-A3E5-5F2F05CD1A67}.Debug|x64.ActiveCfg = Debug|Any CPU
{4E2EB2E0-E5FE-4FEB-A3E5-5F2F05CD1A67}.Debug|x64.Build.0 = Debug|Any CPU
{4E2EB2E0-E5FE-4FEB-A3E5-5F2F05CD1A67}.Debug|x86.ActiveCfg = Debug|Any CPU
{4E2EB2E0-E5FE-4FEB-A3E5-5F2F05CD1A67}.Debug|x86.Build.0 = Debug|Any CPU
{4E2EB2E0-E5FE-4FEB-A3E5-5F2F05CD1A67}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E2EB2E0-E5FE-4FEB-A3E5-5F2F05CD1A67}.Release|Any CPU.Build.0 = Release|Any CPU
{4E2EB2E0-E5FE-4FEB-A3E5-5F2F05CD1A67}.Release|x64.ActiveCfg = Release|Any CPU
{4E2EB2E0-E5FE-4FEB-A3E5-5F2F05CD1A67}.Release|x64.Build.0 = Release|Any CPU
{4E2EB2E0-E5FE-4FEB-A3E5-5F2F05CD1A67}.Release|x86.ActiveCfg = Release|Any CPU
{4E2EB2E0-E5FE-4FEB-A3E5-5F2F05CD1A67}.Release|x86.Build.0 = Release|Any CPU
{AF006EF5-D4BC-49C6-8E0E-DC2B882BE767}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF006EF5-D4BC-49C6-8E0E-DC2B882BE767}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF006EF5-D4BC-49C6-8E0E-DC2B882BE767}.Debug|x64.ActiveCfg = Debug|Any CPU
{AF006EF5-D4BC-49C6-8E0E-DC2B882BE767}.Debug|x64.Build.0 = Debug|Any CPU
{AF006EF5-D4BC-49C6-8E0E-DC2B882BE767}.Debug|x86.ActiveCfg = Debug|Any CPU
{AF006EF5-D4BC-49C6-8E0E-DC2B882BE767}.Debug|x86.Build.0 = Debug|Any CPU
{AF006EF5-D4BC-49C6-8E0E-DC2B882BE767}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF006EF5-D4BC-49C6-8E0E-DC2B882BE767}.Release|Any CPU.Build.0 = Release|Any CPU
{AF006EF5-D4BC-49C6-8E0E-DC2B882BE767}.Release|x64.ActiveCfg = Release|Any CPU
{AF006EF5-D4BC-49C6-8E0E-DC2B882BE767}.Release|x64.Build.0 = Release|Any CPU
{AF006EF5-D4BC-49C6-8E0E-DC2B882BE767}.Release|x86.ActiveCfg = Release|Any CPU
{AF006EF5-D4BC-49C6-8E0E-DC2B882BE767}.Release|x86.Build.0 = Release|Any CPU
{DE0B3A58-C301-4671-8B32-4F195C9457A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DE0B3A58-C301-4671-8B32-4F195C9457A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE0B3A58-C301-4671-8B32-4F195C9457A7}.Debug|x64.ActiveCfg = Debug|Any CPU
{DE0B3A58-C301-4671-8B32-4F195C9457A7}.Debug|x64.Build.0 = Debug|Any CPU
{DE0B3A58-C301-4671-8B32-4F195C9457A7}.Debug|x86.ActiveCfg = Debug|Any CPU
{DE0B3A58-C301-4671-8B32-4F195C9457A7}.Debug|x86.Build.0 = Debug|Any CPU
{DE0B3A58-C301-4671-8B32-4F195C9457A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE0B3A58-C301-4671-8B32-4F195C9457A7}.Release|Any CPU.Build.0 = Release|Any CPU
{DE0B3A58-C301-4671-8B32-4F195C9457A7}.Release|x64.ActiveCfg = Release|Any CPU
{DE0B3A58-C301-4671-8B32-4F195C9457A7}.Release|x64.Build.0 = Release|Any CPU
{DE0B3A58-C301-4671-8B32-4F195C9457A7}.Release|x86.ActiveCfg = Release|Any CPU
{DE0B3A58-C301-4671-8B32-4F195C9457A7}.Release|x86.Build.0 = Release|Any CPU
{2E226B1E-80F6-448D-B02B-0A029C5BC09E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E226B1E-80F6-448D-B02B-0A029C5BC09E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E226B1E-80F6-448D-B02B-0A029C5BC09E}.Debug|x64.ActiveCfg = Debug|Any CPU
{2E226B1E-80F6-448D-B02B-0A029C5BC09E}.Debug|x64.Build.0 = Debug|Any CPU
{2E226B1E-80F6-448D-B02B-0A029C5BC09E}.Debug|x86.ActiveCfg = Debug|Any CPU
{2E226B1E-80F6-448D-B02B-0A029C5BC09E}.Debug|x86.Build.0 = Debug|Any CPU
{2E226B1E-80F6-448D-B02B-0A029C5BC09E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2E226B1E-80F6-448D-B02B-0A029C5BC09E}.Release|Any CPU.Build.0 = Release|Any CPU
{2E226B1E-80F6-448D-B02B-0A029C5BC09E}.Release|x64.ActiveCfg = Release|Any CPU
{2E226B1E-80F6-448D-B02B-0A029C5BC09E}.Release|x64.Build.0 = Release|Any CPU
{2E226B1E-80F6-448D-B02B-0A029C5BC09E}.Release|x86.ActiveCfg = Release|Any CPU
{2E226B1E-80F6-448D-B02B-0A029C5BC09E}.Release|x86.Build.0 = Release|Any CPU
{2EE1744F-2D3C-4032-9A9E-C57FA3B512B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2EE1744F-2D3C-4032-9A9E-C57FA3B512B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2EE1744F-2D3C-4032-9A9E-C57FA3B512B3}.Debug|x64.ActiveCfg = Debug|Any CPU
{2EE1744F-2D3C-4032-9A9E-C57FA3B512B3}.Debug|x64.Build.0 = Debug|Any CPU
{2EE1744F-2D3C-4032-9A9E-C57FA3B512B3}.Debug|x86.ActiveCfg = Debug|Any CPU
{2EE1744F-2D3C-4032-9A9E-C57FA3B512B3}.Debug|x86.Build.0 = Debug|Any CPU
{2EE1744F-2D3C-4032-9A9E-C57FA3B512B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2EE1744F-2D3C-4032-9A9E-C57FA3B512B3}.Release|Any CPU.Build.0 = Release|Any CPU
{2EE1744F-2D3C-4032-9A9E-C57FA3B512B3}.Release|x64.ActiveCfg = Release|Any CPU
{2EE1744F-2D3C-4032-9A9E-C57FA3B512B3}.Release|x64.Build.0 = Release|Any CPU
{2EE1744F-2D3C-4032-9A9E-C57FA3B512B3}.Release|x86.ActiveCfg = Release|Any CPU
{2EE1744F-2D3C-4032-9A9E-C57FA3B512B3}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -436,6 +294,13 @@ Global
{4E66F4F4-7771-4FFA-A907-3F99A95C6A7F} = {F62E508E-B374-4149-B9AC-0A8090AA6CD1}
{86F6CF23-35C4-45AD-BC0D-6BD50C03F666} = {F62E508E-B374-4149-B9AC-0A8090AA6CD1}
{2E755C75-E472-44E0-8AC4-F40209A60172} = {45E5B6B2-0A6D-4D57-804B-7B8313145B62}
{BBB75CAC-2BA3-473D-935D-0E59406F5E61} = {F62E508E-B374-4149-B9AC-0A8090AA6CD1}
{2B74A2B2-148D-4518-BF74-3408095E920B} = {F62E508E-B374-4149-B9AC-0A8090AA6CD1}
{4E2EB2E0-E5FE-4FEB-A3E5-5F2F05CD1A67} = {2B74A2B2-148D-4518-BF74-3408095E920B}
{AF006EF5-D4BC-49C6-8E0E-DC2B882BE767} = {2B74A2B2-148D-4518-BF74-3408095E920B}
{DE0B3A58-C301-4671-8B32-4F195C9457A7} = {2B74A2B2-148D-4518-BF74-3408095E920B}
{2E226B1E-80F6-448D-B02B-0A029C5BC09E} = {2B74A2B2-148D-4518-BF74-3408095E920B}
{2EE1744F-2D3C-4032-9A9E-C57FA3B512B3} = {2B74A2B2-148D-4518-BF74-3408095E920B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5214732D-5A99-44C5-9F02-56348CC457EF}
@@ -1,24 +0,0 @@
using MetroTrilithon.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace SteamTools.Models.Settings
{
public static class AuthSettings
{
/// <summary>
/// ÁîÅÆÊý¾Ý(ѹËõ´æ´¢£©
/// </summary>
public static SerializableProperty<string> Authenticators { get; }
= new SerializableProperty<string>(GetKey(), Providers.Local) { AutoSave = true };
private static string GetKey([CallerMemberName] string propertyName = "")
{
return nameof(GeneralSettings) + "." + propertyName;
}
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 510 B

-322
View File
@@ -1,322 +0,0 @@
using Livet;
using SteamTool.Proxy;
using SteamTool.Proxy.Properties;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using SteamTool.Model;
using SteamTools.Models;
using SteamTools.Models.Settings;
namespace SteamTools.Services
{
public class ProxyService : NotificationObject
{
public static ProxyService Current { get; } = new ProxyService();
public HttpProxy Proxy { get; set; }
public void Initialize()
{
if (ProxySettings.SupportProxyServicesStatus.Value.Count > 0)
{
foreach (var item in ProxyDomains.Value)
{
if (ProxySettings.SupportProxyServicesStatus.Value.TryGetValue(item.Index, out bool value))
{
item.IsEnable = value;
}
}
}
Proxy = new HttpProxy(ProxyDomains.Value, ProductInfo.Product);
InitJsScript();
}
private Lazy<IReadOnlyCollection<ProxyDomainModel>> _ProxyDomains = new Lazy<IReadOnlyCollection<ProxyDomainModel>>(() => new List<ProxyDomainModel>
{
new ProxyDomainModel{
Index=0,
Name=Resources.SteamCommunity,
Domains = new List<string>{"steamcommunity.com" },
ToDomain = "steamcommunity-a.akamaihd.net",
Hosts = new List<string>{ "steamcommunity.com", "www.steamcommunity.com"},
DomainTag = DomainTag.SteamCommunity,
IsEnable= true,
},
new ProxyDomainModel{
Index=1,
Name=Resources.SteamStore,
Domains = new List<string>{"steampowered.com" },
ToDomain = "steamstore-a.akamaihd.net",
Hosts = new List<string>{ "store.steampowered.com", "api.steampowered.com"},
DomainTag = DomainTag.SteamStore,
IsEnable= false,
},
//new ProxyDomainModel{
// Index=2,
// Name=Resources.SteamImage,
// Domains = new List<string>{"steamcdn-a.akamaihd.net" },
// ToDomain = "steamuserimages-a.akamaihd.net",
// Hosts = new List<string>{ "steamcdn-a.akamaihd.net"},
// DomainTag = DomainTag.SteamImage,
// IsEnable= false,
//},
new ProxyDomainModel{
Index=3,
Name=Resources.SteamChat,
Domains = new List<string>{"steam-chat.com" },
ToDomain = "s.team",
Hosts = new List<string>{ "steam-chat.com"},
DomainTag = DomainTag.SteamChat,
IsEnable= false,
},
//new ProxyDomainModel{
//Index=4,
// Name=Resources.Discord,
// Domains = new List<string>{ "discordapp.com" },
// ToDomain = "discord.com",
// //ProxyIPAddres="104.16.10.231",
// Hosts = new List<string>{
// "discordapp.com",
// "dl.discordapp.net",
// "media.discordapp.net",
// "images-ext-2.discordapp.net",
// "images-ext-1.discordapp.net",
// "support.discordapp.com",
// "url9177.discordapp.com",
// "canary-api.discordapp.com",
// "cdn-ptb.discordapp.com",
// "ptb.discordapp.com",
// "status.discordapp.com",
// "cdn-canary.discordapp.com",
// "cdn.discordapp.com",
// "streamkit.discordapp.com",
// "i18n.discordapp.com" ,
// "url9624.discordapp.com",
// "url7195.discordapp.com",
// "merch.discordapp.com",
// "printer.discordapp.com",
// "canary.discordapp.com",
// "apps.discordapp.com",
// "pax.discordapp.com",
// },
// DomainTag = DomainTag.Discord,
// IsEnable= false,
//},
new ProxyDomainModel{
Index=5,
Name=Resources.Twitch,
Domains = new List<string>{ "twitch.tv" },
ToDomain="twitch.map.fastly.net",
Hosts = new List<string>{
"twitch.tv",
"www.twitch.tv",
"m.twitch.tv",
"app.twitch.tv",
"music.twitch.tv",
"badges.twitch.tv",
"blog.twitch.tv",
"inspector.twitch.tv",
"stream.twitch.tv",
"dev.twitch.tv",
"clips.twitch.tv",
"spade.twitch.tv",
"gql.twitch.tv",
"vod-secure.twitch.tv",
"vod-storyboards.twitch.tv",
"trowel.twitch.tv",
"countess.twitch.tv",
"extension-files.twitch.tv",
"vod-metro.twitch.tv",
"pubster.twitch.tv",
"help.twitch.tv",
"passport.twitch.tv",
"id.twitch.tv",
"link.twitch.tv",
"id-cdn.twitch.tv",
"player.twitch.tv",
"api.twitch.tv",
"cvp.twitch.tv",
"clips-media-assets2.twitch.tv",
"client-event-reporter.twitch.tv",
"gds-vhs-drops-campaign-images.twitch.tv",
"us-west-2.uploads-regional.twitch.tv",
"assets.help.twitch.tv",
"discuss.dev.twitch.tv",
"pubsub-edge.twitch.tv",
"irc-ws.chat.twitch.tv",
"irc-ws-r.chat.twitch.tv",
//"platform.twitter.com",
//"usher.ttvnw.net",
},
DomainTag = DomainTag.Twitch,
IsEnable= false,
},
new ProxyDomainModel{
Index=6,
Name=Resources.OriginDownload,
Domains = new List<string>{"origin-a.akamaihd.net" },
ToDomain = "cctv4-lh.akamaihd.net",
Hosts = new List<string>{ "origin-a.akamaihd.net"},
DomainTag = DomainTag.OriginGameDownload,
IsEnable= false,
},
//new ProxyDomainModel{
// Name=Resources.UplayUpdate,
// Domains = new List<string>{"static3.cdn.ubi.com" },
// ToDomain = "static3.cdn.ubi.com",
// Hosts = new List<string>{ "static3.cdn.ubi.com"},
// DomainTag = DomainTag.UplayUpdate,
// IsEnable= false,
//},
new ProxyDomainModel{
Index=7,
Name=Resources.GOG,
Domains = new List<string>{ "gog.com" },
ToDomain = "api.gog.com",
Hosts = new List<string>{
"www.gog.com",
"images.gog.com",
"images-1.gog.com",
"images-2.gog.com",
"images-3.gog.com",
"images-4.gog.com",
"webinstallers.gog.com",
"menu.gog.com",
"auth.gog.com",
"login.gog.com",
//"api.gog.com",
"reviews.gog.com",
"insights-collector.gog.com",
"remote-config.gog.com",
"external-accounts.gog.com",
"chat.gog.com",
"presence.gog.com",
"external-users.gog.com",
"gamesdb.gog.com",
"gameplay.gog.com",
"cfg.gog.com",
"notifications.gog.com",
"users.gog.com",
},
DomainTag = DomainTag.GOG,
IsEnable= false,
},
new ProxyDomainModel{
Index=8,
Name=Resources.GoogleRecaptchaCode,
Domains = new List<string>{"www.google.com" },
ToDomain = "kh.google.com",
Hosts = new List<string>{ "www.google.com"},
DomainTag = DomainTag.GoogleCode,
IsEnable= false,
},
});
public Lazy<IReadOnlyCollection<ProxyDomainModel>> ProxyDomains
{
get => _ProxyDomains;
set
{
if (_ProxyDomains != value)
{
_ProxyDomains = value;
Proxy.ProxyDomains = value.Value;
this.RaisePropertyChanged();
}
}
}
public bool IsEnableScript
{
get => ProxySettings.IsEnableScript.Value;
set
{
if (ProxySettings.IsEnableScript.Value != value)
{
ProxySettings.IsEnableScript.Value = value;
Proxy.IsEnableScript = value;
this.RaisePropertyChanged();
}
}
}
#region 代理状态变更通知
public bool ProxyStatus
{
get { return Proxy.ProxyRunning; }
set
{
if (value != Proxy.ProxyRunning)
{
if (value)
{
var isRun = Proxy.StartProxy(ProxySettings.IsProxyGOG.Value);
if (isRun)
{
StatusService.Current.Notify(SteamTools.Properties.Resources.ProxyRun);
}
else
{
WindowService.Current.ShowDialogWindow("启动加速服务失败,请检查443端口是否被占用或者证书安装失败。");
}
}
else
{
Proxy.StopProxy();
StatusService.Current.Notify(SteamTools.Properties.Resources.ProxyStop);
}
this.RaisePropertyChanged();
}
}
}
#endregion
private List<ProxyScript> _ProxyScripts;
public List<ProxyScript> ProxyScripts
{
get => _ProxyScripts;
set
{
if (_ProxyScripts != value)
{
_ProxyScripts = value;
Proxy.Scripts = value;
this.RaisePropertyChanged();
}
}
}
/// <summary>
/// 加载js脚本列表
/// </summary>
public void InitJsScript()
{
var scripts = new List<ProxyScript>();
var dir = new DirectoryInfo(Const.SCRIPT_DIR);
if (!dir.Exists)
{
dir.Create();
return;
}
foreach (var file in dir.GetFiles())
{
if (file.Extension.Equals(".js", StringComparison.OrdinalIgnoreCase))
{
if (ProxyScript.TryParse(file.FullName, out var script))
scripts.Add(script);
else
scripts.Add(new ProxyScript { FilePath = file.FullName, Name = Resources.Not_Support_JS });
}
}
ProxyScripts = scripts;
}
public void Shutdown()
{
Current.Proxy?.Dispose();
}
}
}
-151
View File
@@ -1,151 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Livet;
using SteamTool.Core.Common;
using SteamTool.Model;
using SteamTool.Steam.Service;
using SteamTool.Steam.Service.Local;
using SteamTool.Steam.Service.Web;
using SteamTools.Properties;
using SteamTools.ViewModels;
namespace SteamTools.Services
{
public class SteamConnectService : NotificationObject
{
#region static members
public static SteamConnectService Current { get; } = new SteamConnectService();
#endregion
//public readonly SteamDLLService DLLService = SteamService.Instance.Get<SteamDLLService>();
public readonly SteamworksApiService ApiService = SteamService.Instance.Get<SteamworksApiService>();
public readonly SteamworksWebApiService SteamworksWebApiService = SteamService.Instance.Get<SteamworksWebApiService>();
public readonly SteamDbApiService steamDbApiService = SteamService.Instance.Get<SteamDbApiService>();
#region Steam游戏列表
private IReadOnlyCollection<SteamApp> _SteamApps;
public IReadOnlyCollection<SteamApp> SteamApps
{
get => _SteamApps;
set
{
if (_SteamApps != value)
{
_SteamApps = value;
this.RaisePropertyChanged();
}
}
}
#endregion
#region 运行中的游戏列表
private IList<SteamApp> _RuningSteamApps = new List<SteamApp>();
public IList<SteamApp> RuningSteamApps
{
get => _RuningSteamApps;
set
{
if (_RuningSteamApps != value)
{
_RuningSteamApps = value;
this.RaisePropertyChanged();
}
}
}
#endregion
#region 当前steam登录用户
private SteamUser _CurrentSteamUser;
public SteamUser CurrentSteamUser
{
get => _CurrentSteamUser;
set
{
if (_CurrentSteamUser != value)
{
_CurrentSteamUser = value;
this.RaisePropertyChanged();
}
}
}
#endregion
#region 连接steamclient是否成功
private bool _IsConnectToSteam;
public bool IsConnectToSteam
{
get => _IsConnectToSteam;
set
{
if (_IsConnectToSteam != value)
{
_IsConnectToSteam = value;
this.RaisePropertyChanged();
}
}
}
#endregion
public void Initialize()
{
Task.Run(async () =>
{
while (true)
{
if (Process.GetProcessesByName("steam").Length > 0)
{
if (!IsConnectToSteam)
{
IsConnectToSteam = ApiService.Initialize();
if (IsConnectToSteam)
{
var id = ApiService.GetSteamId64();
if (id == 76561197960265728)
{
//该64位id的steamID3等于0,是steam未获取到当前登录用户的默认返回值,所以直接重新获取
IsConnectToSteam = false;
continue;
}
CurrentSteamUser = await steamDbApiService.GetUserInfo(id);
var mainViewModel = (WindowService.Current.MainWindow as MainWindowViewModel);
mainViewModel.SteamAppPage.Initialize();
#if DEBUG
mainViewModel.SystemTabItems[mainViewModel.SystemTabItems.Count - 1].Initialize();
#endif
}
}
}
else
{
IsConnectToSteam = false;
//StatusService.Current.Notify(Resources.Steam_Not_Runing);
}
await Task.Delay(1000);
}
});
}
public void Initialize(int appid)
{
if (Process.GetProcessesByName("steam").Length > 0)
{
IsConnectToSteam = ApiService.Initialize(appid);
}
}
public void Shutdown()
{
foreach (var app in SteamConnectService.Current.RuningSteamApps)
{
if (!app.Process.HasExited)
app.Process.Kill();
}
}
}
}
@@ -1,78 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SteamTools.Models;
using Livet;
using MetroRadiance.UI.Controls;
using Livet.EventListeners;
using SteamTools.Services;
namespace SteamTools.ViewModels
{
public abstract class TabItemViewModel : ItemViewModel, ITabItem
{
#region Name 変更通知
public abstract string Name { get; protected set; }
#endregion
#region Badge 変更通知
private int? _Badge;
public virtual int? Badge
{
get { return this._Badge; }
protected set
{
if (this._Badge != value)
{
this._Badge = value;
this.RaisePropertyChanged();
}
}
}
#endregion
#region Status 変更通知
private ViewModel _Status;
/// <summary>
/// 获取状态栏中显示的状态
/// </summary>
public virtual ViewModel Status
{
get { return this._Status; }
protected set
{
if (this._Status != value)
{
this._Status = value;
this.RaisePropertyChanged();
}
}
}
#endregion
protected TabItemViewModel()
{
if (Models.Helper.IsInDesignMode) return;
this.CompositeDisposable.Add(new PropertyChangedEventListener(ResourceService.Current)
{
(sender, args) => this.RaisePropertyChanged(nameof(this.Name)),
});
}
internal virtual void Initialize()
{
}
}
}
@@ -1,64 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows;
using SteamTools.Win32;
using MetroRadiance.Interop.Win32;
using System.Diagnostics;
using SteamTool.Core.Common;
using System.Runtime.InteropServices;
using SteamTools.Services;
using SteamTool.Steam.Service.Web;
using SteamTool.Core;
using SteamTool.Steam.Service;
using SteamTool.Model;
using Newtonsoft.Json;
using SteamTools.Models.Settings;
namespace SteamTools.ViewModels
{
public class SettingsGeneralViewModel : Livet.ViewModel
{
private SteamworksWebApiService SteamworksWebApi => SteamService.Instance.Get<SteamworksWebApiService>();
private SteamToolService SteamTool => SteamToolCore.Instance.Get<SteamToolService>();
private bool IsRefreshGameListCache;
public void RefreshGameListCache()
{
if (SteamConnectService.Current.IsConnectToSteam)
{
if (IsRefreshGameListCache)
{
StatusService.Current.Notify("正在下在Steam游戏数据中...");
return;
}
StatusService.Current.Notify("刷新Steam游戏数据");
IsRefreshGameListCache = true;
Task.Run(async () =>
{
var result = await SteamworksWebApi.GetAllSteamAppsString();
if (GeneralSettings.IsSteamAppListLocalCache)
SteamTool.UpdateAppListJson(result, Const.APP_LIST_FILE);
var apps = JsonConvert.DeserializeObject<SteamApps>(result).AppList.Apps;
apps = apps.DistinctBy(d => d.AppId).ToList();
//SteamConnectService.Current.SteamApps = apps;
SteamConnectService.Current.SteamApps = SteamConnectService.Current.ApiService.OwnsApps(apps);
}).ContinueWith(s =>
{
StatusService.Current.Notify("刷新Steam游戏数据完成");
IsRefreshGameListCache = false;
s.Dispose();
});
}
else
{
StatusService.Current.Notify("未检测到Steam运行");
}
}
}
}
@@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SteamTools.ViewModels
{
public class SteamIdlePageViewModel : TabItemViewModel
{
public override string Name
{
get { return Properties.Resources.IdleCard; }
protected set { throw new NotImplementedException(); }
}
}
}
@@ -1,37 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SteamTool.Model;
using SteamTools.Models.Settings;
using SteamTools.Services;
namespace SteamTools.ViewModels
{
public class WelcomePageViewModel: TabItemViewModel
{
public override string Name
{
get { return Properties.Resources.Welcome; }
protected set { throw new NotImplementedException(); }
}
public override bool IsShowTab
{
get { return GeneralSettings.IsShowStartPage.Value; }
}
public MainWindowViewModel Content { get; }
public WelcomePageViewModel(MainWindowViewModel owner)
{
this.Content = owner;
}
internal override void Initialize()
{
}
}
}
@@ -1,55 +0,0 @@
<UserControl x:Class="SteamTools.Views.Content.AboutUpdateHistory"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SteamTools.Views.Content"
xmlns:viewModel="clr-namespace:SteamTools.ViewModels"
xmlns:services="clr-namespace:SteamTools.Services"
xmlns:metro="http://schemes.grabacr.net/winfx/2014/controls"
xmlns:metro2="http://schemes.grabacr.net/winfx/2015/personal/controls"
xmlns:model="clr-namespace:SteamTool.Model;assembly=SteamTool.Model"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:livet="http://schemas.livet-mvvm.net/2011/wpf"
mc:Ignorable="d"
d:DesignHeight="400"
d:DesignWidth="600"
Padding="8"
Background="{DynamicResource ThemeBrushKey}">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="..\Common.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<DockPanel>
<TextBlock DockPanel.Dock="Top" Text="{Binding Resources.AboutUpdateHistory, Source={x:Static services:ResourceService.Current}, Mode=OneWay}"
Style="{DynamicResource SettingsHeaderTextStyleKey}" />
<Border Grid.Column="1">
<FlowDocumentScrollViewer Padding="0,-18,0,0"
HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto">
<FlowDocument FontSize="12"
Foreground="{DynamicResource ForegroundBrushKey}"
FontFamily="Meiryo UI"
TextAlignment="Left"
MaxPageWidth="900">
<Paragraph Language="zh-cn">
<Run Text="Steam++ v1.0.0" FontSize="16"/>
<Run Text="&#160;"/>
<Run Text="2020-12-14" FontSize="10" />
<LineBreak />
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="发布第一个版本" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="主要功能:社区反代,帐户切换,成就解锁,本地令牌。"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="次要功能:强制无边框窗口化以及CSGO VAC屏蔽修复。"></Run>
</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
</Border>
</DockPanel>
</UserControl>
-76
View File
@@ -1,76 +0,0 @@
<UserControl x:Class="SteamTools.Views.Controls.StatusBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SteamTools.Views.Controls"
xmlns:metro="http://schemes.grabacr.net/winfx/2014/controls"
xmlns:services="clr-namespace:SteamTools.Services"
xmlns:vm="clr-namespace:SteamTools.ViewModels"
mc:Ignorable="d"
d:DesignHeight="25" d:DesignWidth="780"
d:DataContext="{d:DesignInstance vm:StatusBarViewModel}">
<Grid Grid.Row="2" Background="{DynamicResource AccentBrushKey}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="23" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="{Binding Source={x:Static services:StatusService.Current}, Path=Message}"
FontSize="13"
Style="{DynamicResource DefaultTextStyleKey}"
Foreground="{DynamicResource AccentForegroundBrushKey}"
TextWrapping="NoWrap"
Margin="8,0" />
<ContentControl Grid.Column="1"
Content="{Binding}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type vm:WelcomePageViewModel}" />
<DataTemplate DataType="{x:Type vm:CommunityProxyPageViewModel}" />
<DataTemplate DataType="{x:Type vm:SteamAccountPageViewModel}" />
<DataTemplate DataType="{x:Type vm:SteamAppPageViewModel}" >
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground"
Value="{DynamicResource AccentForegroundBrushKey}" />
<Setter Property="FontFamily"
Value="{DynamicResource DefaultFontFamilyKey}" />
<Setter Property="FontSize"
Value="{DynamicResource DefaultFontSizeKey}" />
<Setter Property="VerticalAlignment"
Value="Center" />
</Style>
</StackPanel.Resources>
<TextBlock VerticalAlignment="Center" Text="{Binding Source={x:Static services:ResourceService.Current}, Path=Resources.Steam_Not_Runing_Tips}"
Visibility="{Binding Source={x:Static services:SteamConnectService.Current}, Path=IsConnectToSteam,Mode=OneWay,Converter={StaticResource ReverseBooleanToVisibilityConverter}}">
</TextBlock>
<TextBlock Text="{Binding Source={x:Static services:ResourceService.Current}, Path=Resources.Game_Total, StringFormat='{}{0}: '}" />
<TextBlock Text="{Binding Games.Count,Mode=OneWay}"
MinWidth="45" />
<TextBlock Text="{Binding Source={x:Static services:ResourceService.Current}, Path=Resources.Game_Install, StringFormat='{}{0}: '}" />
<TextBlock Text="{Binding InstalledCount,Mode=OneWay}"
MinWidth="65" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SettingsPageViewModel}" />
<DataTemplate DataType="{x:Type vm:OtherPlatformPageViewModel}" />
<DataTemplate DataType="{x:Type vm:LocalAuthPageViewModel}" />
<DataTemplate DataType="{x:Type vm:GameRelatedPageViewModel}" />
<DataTemplate DataType="{x:Type vm:ArchiSteamFarmPlusPageViewModel}" />
<DataTemplate DataType="{x:Type vm:AboutPageViewModel}" />
<DataTemplate DataType="{x:Type vm:DebugPageViewModel}" />
<DataTemplate DataType="{x:Type vm:AchievementWindowViewModel}" />
<DataTemplate DataType="{x:Type vm:SteamIdlePageViewModel}" />
</ContentControl.Resources>
</ContentControl>
<!--<metro:CaptionButton Grid.Column="2" VerticalAlignment="Center"
ToolTip="{Binding Path=Badge,StringFormat=Resources.NotificationString,Source={x:Static services:ResourceService.Current}, Mode=OneWay}"
Style="{DynamicResource StatusButtonStyleKey}" >
<svgc:SvgViewbox IsHitTestVisible="False" Source="pack://application:,,,/Resources/Asstes/bell.svg" Width="11" />
</metro:CaptionButton>-->
<metro:ResizeGrip Grid.Column="3" />
</Grid>
</UserControl>
-204
View File
@@ -1,204 +0,0 @@
<UserControl x:Class="SteamTools.Views.Controls.TaskBarPopup"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:metro2="http://schemes.grabacr.net/winfx/2015/personal/controls"
xmlns:vm="clr-namespace:SteamTools.ViewModels"
xmlns:services="clr-namespace:SteamTools.Services"
xmlns:metro="http://schemes.grabacr.net/winfx/2014/controls"
xmlns:models="clr-namespace:SteamTools.Models"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:livet="http://schemas.livet-mvvm.net/2011/wpf"
mc:Ignorable="d"
Height="345" Width="180"
FontSize="14"
Foreground="{DynamicResource ForegroundBrushKey}"
d:DataContext="{d:DesignInstance vm:TaskBarViewModel}">
<Border>
<Grid>
<Rectangle Stroke="{DynamicResource AccentBrushKey}"
StrokeThickness="3">
<Rectangle.Effect>
<BlurEffect Radius="8" />
</Rectangle.Effect>
</Rectangle>
<Border Background="{DynamicResource ThemeBrushKey}"
BorderBrush="{DynamicResource AccentBrushKey}"
BorderThickness=".99">
<Grid Margin="8,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<WrapPanel Grid.Row="0" Margin="0,8,0,0" Visibility="{Binding ElementName=user,Path=IsVisible,Converter={StaticResource ReverseBooleanToVisibilityConverter}}">
<Image Source="pack://application:,,,/Resources/Asstes/app.ico" Width="64" Height="64" Cursor="Hand">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<livet:LivetCallMethodAction MethodName="ShowUrl"
MethodTarget="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
<StackPanel VerticalAlignment="Center" >
<TextBlock Text="{Binding Source={x:Static services:ResourceService.Current}, Path=Resources.WinTitle,Mode=OneWay}"
Foreground="{DynamicResource HighlightForegroundBrushKey}" Style="{StaticResource HeaderTextStyleKey}" FontSize="16"/>
<TextBlock Text="{Binding Source={x:Static models:ProductInfo.VersionString}, StringFormat=版本 {0}, Mode=OneWay}"
Foreground="{DynamicResource HighlightForegroundBrushKey}" Style="{StaticResource DetailTextStyleKey}"/>
</StackPanel>
</WrapPanel>
<WrapPanel x:Name="user" Grid.Row="0" Margin="0,8,0,0" Visibility="{Binding CurrentSteamUser,Source={x:Static services:SteamConnectService.Current},Mode=OneWay,Converter={StaticResource NullToVisibilityConverter}}">
<Image Source="{Binding CurrentSteamUser.AvatarMedium,Source={x:Static services:SteamConnectService.Current},Mode=OneWay}" Width="64" Height="64" Cursor="Hand">
<Image.Clip>
<!--设置图像如何显示-->
<EllipseGeometry RadiusX="32" RadiusY="32" Center="32,32"/>
</Image.Clip>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<livet:LivetCallMethodAction MethodName="ShowUrl"
MethodTarget="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
<StackPanel VerticalAlignment="Center" Margin="8,0,0,0">
<TextBlock Text="{Binding CurrentSteamUser.SteamID,Source={x:Static services:SteamConnectService.Current},Mode=OneWay}" VerticalAlignment="Center" TextTrimming="CharacterEllipsis"
Foreground="{DynamicResource HighlightForegroundBrushKey}"
Style="{StaticResource HeaderTextStyleKey}" FontSize="16"></TextBlock>
<TextBlock
Foreground="{DynamicResource HighlightForegroundBrushKey}"
Style="{StaticResource DetailTextStyleKey}">
<Run Text="{Binding Source={x:Static models:ProductInfo.Title}, Mode=OneWay}"></Run>
<LineBreak/>
<Run Text="{Binding Source={x:Static models:ProductInfo.VersionString}, StringFormat=版本 {0}, Mode=OneWay}"></Run>
</TextBlock>
</StackPanel>
</WrapPanel>
<StackPanel Grid.Row="1">
<Rectangle Height=".99"
Fill="{DynamicResource InactiveForegroundBrushKey}"
Margin="0,8" />
<DockPanel>
<TextBlock VerticalAlignment="Center" Foreground="{DynamicResource HighlightForegroundBrushKey}" FontFamily="{StaticResource DefaultFontFamilyKey}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding ProxyStatus,Source={x:Static services:ProxyService.Current},Mode=OneWay}" Value="False">
<Setter Property="Text" Value="{Binding Resources.StartService,Source={x:Static services:ResourceService.Current}, Mode=OneWay}"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ProxyStatus,Source={x:Static services:ProxyService.Current},Mode=OneWay}" Value="True">
<Setter Property="Text" Value="{Binding Resources.StopService,Source={x:Static services:ResourceService.Current}, Mode=OneWay}"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<CheckBox x:Name="service" Style="{DynamicResource SliderCheckBox}" Margin="5" HorizontalAlignment="Right"
IsChecked="{Binding ProxyStatus,Source={x:Static services:ProxyService.Current},Mode=TwoWay}">
</CheckBox>
</DockPanel>
<!--<metro:LinkButton Text="{Binding Source={x:Static services:ResourceService.Current}, Path=Resources.Exit}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<livet:LivetCallMethodAction MethodName="ExitApplication"
MethodTarget="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</metro:LinkButton>-->
<Rectangle Height=".99"
Fill="{DynamicResource InactiveForegroundBrushKey}"
Margin="0,8" />
</StackPanel>
<StackPanel Grid.Row="2" VerticalAlignment="Bottom">
<ListBox Style="{StaticResource MetroListBox}" FontSize="12" FontFamily="{StaticResource CaptionFontFamilyKey}" BorderThickness="0" Margin="-8,0">
<ListBoxItem>
<Border Padding="8">
<StackPanel>
<TextBlock Text="{Binding Source={x:Static services:ResourceService.Current}, Path=Resources.CommunityFix}" VerticalAlignment="Center"></TextBlock>
</StackPanel>
</Border>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<livet:LivetCallMethodAction MethodName="NavigateTabItem"
MethodTarget="{Binding}" MethodParameter="1"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBoxItem>
<ListBoxItem>
<Border Padding="8">
<StackPanel>
<TextBlock Text="{Binding Source={x:Static services:ResourceService.Current}, Path=Resources.UserFastChange}" VerticalAlignment="Center"></TextBlock>
</StackPanel>
</Border>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<livet:LivetCallMethodAction MethodName="NavigateTabItem"
MethodTarget="{Binding}" MethodParameter="2"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBoxItem>
<ListBoxItem>
<Border Padding="8">
<StackPanel>
<TextBlock Text="{Binding Source={x:Static services:ResourceService.Current}, Path=Resources.GameList}" VerticalAlignment="Center"></TextBlock>
</StackPanel>
</Border>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<livet:LivetCallMethodAction MethodName="NavigateTabItem"
MethodTarget="{Binding}" MethodParameter="3"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBoxItem>
<ListBoxItem>
<Border Padding="8">
<StackPanel>
<TextBlock Text="{Binding Source={x:Static services:ResourceService.Current}, Path=Resources.SteamAuth}" VerticalAlignment="Center"></TextBlock>
</StackPanel>
</Border>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<livet:LivetCallMethodAction MethodName="NavigateTabItem"
MethodTarget="{Binding}" MethodParameter="4"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBoxItem>
<ListBoxItem IsEnabled="False" Margin="0,5">
<Rectangle Height=".99"
Fill="{DynamicResource InactiveForegroundBrushKey}"
Margin="8,0" />
</ListBoxItem>
<ListBoxItem>
<Border Padding="8">
<StackPanel>
<TextBlock Text="{Binding Source={x:Static services:ResourceService.Current}, Path=Resources.Settings}" VerticalAlignment="Center"></TextBlock>
</StackPanel>
</Border>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<livet:LivetCallMethodAction MethodName="NavigateTabItem"
MethodTarget="{Binding}" MethodParameter="-1"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBoxItem>
<ListBoxItem>
<Border Padding="8">
<StackPanel>
<TextBlock Text="{Binding Source={x:Static services:ResourceService.Current}, Path=Resources.Exit}" VerticalAlignment="Center"></TextBlock>
</StackPanel>
</Border>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<livet:LivetCallMethodAction MethodName="ExitApplication"
MethodTarget="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBoxItem>
</ListBox>
</StackPanel>
</Grid>
</Border>
</Grid>
</Border>
</UserControl>
-79
View File
@@ -1,79 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
namespace SteamTools.Win32
{
internal class WinInet
{
// For PInvoke: Initiates the enumeration of the cache groups in the Internet cache
[DllImport(@"wininet",
SetLastError = true,
CharSet = CharSet.Auto,
EntryPoint = "FindFirstUrlCacheGroup",
CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr FindFirstUrlCacheGroup(
int dwFlags,
int dwFilter,
IntPtr lpSearchCondition,
int dwSearchCondition,
ref long lpGroupId,
IntPtr lpReserved);
// For PInvoke: Retrieves the next cache group in a cache group enumeration
[DllImport(@"wininet",
SetLastError = true,
CharSet = CharSet.Auto,
EntryPoint = "FindNextUrlCacheGroup",
CallingConvention = CallingConvention.StdCall)]
public static extern bool FindNextUrlCacheGroup(
IntPtr hFind,
ref long lpGroupId,
IntPtr lpReserved);
// For PInvoke: Releases the specified GROUPID and any associated state in the cache index file
[DllImport(@"wininet",
SetLastError = true,
CharSet = CharSet.Auto,
EntryPoint = "DeleteUrlCacheGroup",
CallingConvention = CallingConvention.StdCall)]
public static extern bool DeleteUrlCacheGroup(
long groupId,
int dwFlags,
IntPtr lpReserved);
// For PInvoke: Begins the enumeration of the Internet cache
[DllImport(@"wininet",
SetLastError = true,
CharSet = CharSet.Auto,
EntryPoint = "FindFirstUrlCacheEntryA",
CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr FindFirstUrlCacheEntry(
[MarshalAs(UnmanagedType.LPTStr)] string lpszUrlSearchPattern,
IntPtr lpFirstCacheEntryInfo,
ref int lpdwFirstCacheEntryInfoBufferSize);
// For PInvoke: Retrieves the next entry in the Internet cache
[DllImport(@"wininet",
SetLastError = true,
CharSet = CharSet.Auto,
EntryPoint = "FindNextUrlCacheEntryA",
CallingConvention = CallingConvention.StdCall)]
public static extern bool FindNextUrlCacheEntry(
IntPtr hFind,
IntPtr lpNextCacheEntryInfo,
ref int lpdwNextCacheEntryInfoBufferSize);
// For PInvoke: Removes the file that is associated with the source name from the cache, if the file exists
[DllImport(@"wininet",
SetLastError = true,
CharSet = CharSet.Auto,
EntryPoint = "DeleteUrlCacheEntryA",
CallingConvention = CallingConvention.StdCall)]
public static extern bool DeleteUrlCacheEntry(
IntPtr lpszUrlName);
}
}
-15
View File
@@ -1,15 +0,0 @@
// ==UserScript==
// @name GM
// @namespace
// @version 0.1
// @description 基础脚本框架
// @author 软妹币玩家
// @match *
// @enable true
// @grant GM_xmlhttpRequest
// ==/UserScript==
var unsafeWindow = this;
function GM_xmlhttpRequest(details)
{
}
-1
View File
@@ -1 +0,0 @@
dotnet publish SteamTools -c Release -f net5.0-windows -r win-x86 -p:PublishSingleFile=true -p:UseAppHost=true --self-contained false -o out/result
+1
View File
@@ -0,0 +1 @@
dotnet publish ..\source\SteamTools -c Release -f net5.0-windows -r win-x86 - /p:PublishSingleFile=true /p:PublishTrimmed=true -o out/result
+318
View File
@@ -0,0 +1,318 @@
function Main
{
begin
{
$ErrorActionPreference = 'stop'
$target = 'net472'
$result = 'Steam++'
$bin = '..\source\SteamTools\bin\x86\Release\'
# '*.exe.config'
$targetKeywords = '*.exe','*.dll','*.txt','*.VisualElementsManifest.xml','*.pak','*.bin','*.js','Log4net.config'
$ignoreKeywords = '*.vshost.*','Microsoft.*.resources.dll','ExPlugin.*.dll'
$exeSource = '\Steam++.exe'
if (-not(Test-Path $bin))
{
throw 'Script detected as locate in invalid path exception!! Make sure exist in <SteamTools repository root>\tools-release\'
}
}
end
{
try
{
# clean up current
Get-ChildItem -Directory | Remove-item -Recurse
Get-ChildItem | where { $_.Extension -eq ".zip" } | Remove-Item
Copy-StrictedFilterFileWithDirectoryStructure -Path $(Join-Path $bin $target) -Destination '.\' -Targets $targetKeywords -Exclude $ignoreKeywords
# valid path check
$versionSource = Join-Path $target $exeSource -Resolve
if ((Test-Path $versionSource) -and (Test-Path $target))
{
$version = (Get-ChildItem $versionSource).VersionInfo
$result = $result + ' v{0}.{1}.{2}' -f $version.ProductMajorPart, $version.ProductMinorPart,$version.ProductBuildPart
Rename-Item -NewName $result -Path $target
New-ZipCompression -source $(Join-Path $(Get-Location) $result) -destination $(Join-Path $(Get-Location).Path ('./' + $result + '.zip'))
}
}
catch
{
throw $_
}
}
}
# https://gist.github.com/guitarrapc/e78bbd4ddc07389e17d6
function Copy-StrictedFilterFileWithDirectoryStructure
{
[CmdletBinding()]
param
(
[parameter(
mandatory = 1,
position = 0,
ValueFromPipeline = 1,
ValueFromPipelineByPropertyName = 1)]
[string]
$Path,
[parameter(
mandatory = 1,
position = 1,
ValueFromPipelineByPropertyName = 1)]
[string]
$Destination,
[parameter(
mandatory = 1,
position = 2,
ValueFromPipelineByPropertyName = 1)]
[string[]]
$Targets,
[parameter(
mandatory = 0,
position = 3,
ValueFromPipelineByPropertyName = 1)]
[string[]]
$Excludes
)
begin
{
$list = New-Object 'System.Collections.Generic.List[String]'
}
process
{
Foreach ($target in $Targets)
{
# Copy "All Directory Structure" and "File" which Extension type is $ex
Copy-Item -Path $Path -Destination $Destination -Force -Recurse -Filter $target
}
}
end
{
# Remove -Exclude Item
Foreach ($exclude in $Excludes)
{
Get-ChildItem -Path $Destination -Recurse -File | where Name -like $exclude | Remove-Item
}
# search Folder which include file
$allFolder = Get-ChildItem $Destination -Recurse -Directory
$containsFile = $allFolder | where {$_.GetFiles()}
$containsFile.FullName `
| %{
$fileContains = $_
$result = $allFolder.FullName `
| where {$_ -notin $list} `
| where {
$shortPath = $_
$fileContains -like "$shortPath*"
}
$result | %{$list.Add($_)}
}
$folderToKeep = $list | sort -Unique
# Remove All Empty (none file exist) folders
Get-ChildItem -Path $Destination -Recurse -Directory | where fullName -notin $folderToKeep | Remove-Item -Recurse
}
}
# http://tech.guitarrapc.com/entry/2013/10/08/040325
function New-ZipCompression
{
[CmdletBinding()]
param
(
[parameter(
mandatory,
position = 0,
valuefrompipeline,
valuefrompipelinebypropertyname)]
[string]
$source,
[parameter(
mandatory = 0,
position = 1,
valuefrompipeline,
valuefrompipelinebypropertyname)]
[string]
$destination,
[parameter(
mandatory = 0,
position = 2)]
[switch]
$quiet,
[parameter(
mandatory = 0,
position = 3)]
[switch]
$force
)
try
{
Add-Type -AssemblyName 'System.IO.Compression.FileSystem'
}
catch
{
}
# check file is directory
$file = Get-Item -Path $source
# set zip extension
$zipExtension = '.zip'
# set desktop as destination path if it null
if ([string]::IsNullOrWhiteSpace($destination))
{
if ($file.Mode -like 'd*')
{
$destination = (Join-Path ([System.Environment]::GetFolderPath([Environment+SpecialFolder]::Desktop)) [System.IO.Path]::GetFileNameWithoutExtension($source + $zipExtension))
}
else
{
$destination = (Join-Path ([System.Environment]::GetFolderPath([Environment+SpecialFolder]::Desktop)) [System.IO.Path]::GetFileNameWithoutExtension(($file | select -First 1 -ExpandProperty fullname))) + $zipExtension
}
}
# check destination is input as .zip
if (-not($destination.EndsWith($zipExtension)))
{
throw ('destination parameter value [{0}] not end with extension {1}' -f $destination, $zipExtension)
}
# check destination is already exist or not
if (Test-Path $destination)
{
Remove-Item -Path $destination -Confirm
}
# compressionLevel
$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
# check file mode for source
Write-Verbose ('file.mode = {0}' -f $file.Mode)
if ($file.Mode -like 'd*') # Directory should be d---
{
try # create zip from directory
{
# force output zip file to new destination path, avoiding destination zip name conflict.
if ($force)
{
# check destination is already exist, CreateFromDirectory will fail with same name of destination file.
if (Test-Path $destination)
{
# show warning for same destination exist.
Write-Verbose ('Detected destination name {0} is already exist. Force trying output to new destination zip name.' -f $destination)
# get current destination information
$destinationRoot = [System.IO.Path]::GetDirectoryName($destination)
$destinationfile = [System.IO.Path]::GetFileNameWithoutExtension($destination)
$destinationExtension = [System.IO.Path]::GetExtension($destination)
# renew destination name with (2)...(x) until no more same name catch.
$count = 2
$destination = Join-Path $destinationRoot ($destinationfile + '(' + $count + ')' + $destinationExtension)
while (Test-Path $destination)
{
++$count
$destination = Join-Path $destinationRoot ($destinationfile + '(' + $count + ')' + $destinationExtension)
}
# show warning as destination name had been changed due to escape error.
Write-Verbose ('Deistination name change to new name {0}' -f $destination)
}
}
# include BaseDirectory
$includeBaseDirectory = $true
Write-Verbose ('destination = {0}' -f $destination)
Write-Verbose ('file.fullname = {0}' -f $file.FullName)
Write-Verbose ('compressionLevel = {0}' -f $compressionLevel)
Write-Verbose ('includeBaseDirectory = {0}' -f $includeBaseDirectory)
if ($quiet)
{
Write-Verbose ('zipping up folder {0} to {1}' -f $file.FullName,$destination)
[System.IO.Compression.ZipFile]::CreateFromDirectory($file.fullname,$destination,$compressionLevel,$includeBaseDirectory) > $null
$?
}
else
{
Write-Verbose ('zipping up folder {0} to {1}' -f $file.FullName,$destination)
[System.IO.Compression.ZipFile]::CreateFromDirectory($file.fullname,$destination,$compressionLevel,$includeBaseDirectory)
Get-Item $destination
}
}
catch
{
Write-Error $_
$?
}
}
else
{
try # create zip from files
{
# create zip to add
$destzip = [System.IO.Compression.Zipfile]::Open($destination,'Update')
# get items
$files = Get-ChildItem -Path $source
foreach ($file in $files)
{
$file2 = $file.name
Write-Verbose ('destzip = {0}' -f $destzip)
Write-Verbose ('file.fullname = {0}' -f $file.FullName)
Write-Verbose ('file2 = {0}' -f $file2)
Write-Verbose ('compressionLevel = {0}' -f $compressionLevel)
if ($quiet)
{
Write-Verbose ('zipping up files {0} to {1}' -f $file.FullName,$destzip)
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($destzip,$file.fullname,$file2,$compressionLevel) > $null
$?
}
else
{
Write-Verbose ('zipping up files {0} to {1}' -f $file.FullName,$destzip)
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($destzip,$file.fullname,$file2,$compressionLevel)
}
}
}
catch
{
Write-Error $_
$?
}
finally
{
# dispose opened zip
$destzip.Dispose()
}
}
}
Main
+169
View File
@@ -0,0 +1,169 @@
# 前言
Steam++项目创建于2018年5月8日,不过并不是耗时两年才做出来,之前一直由于工作原因,并没有多少空闲时间,直到今年中旬辞职了,才开始猛肝。
本来是想一直做到完全体了,才考虑发布,不过现在感慨一下,果然是没法这么快就整完的,所以还是一版一版更新做到完全体吧。
Steam++只在keylol论坛与github发布,为了账号安全,请不要到其它不明地方下载。
# Steam++工具箱
## 已知的未修复问题
* 部分用户无法加载游戏列表,原因可能是因为第一次加载游戏列表时未加载完成程序停止运行了,导致生成了错误的缓存文件apps.json,如果遇到此问题可尝试手动删除程序目录下的apps.json然后重启程序。
## 更新内容
### 1.0.6
```
修改了用户信息获取的api为steam官方社区api(但是没有启动软件的自动代理服务的话依然加载不出头像。)
新增启用日志记录设置项(反馈bug时一起提交方便排查问题)
修复twitch反代聊天连接错误和直播视频无法观看
放宽令牌同步时网络请求超时时间以降低令牌同步时提示超时概率
修改生成的cer证书编码格式为utf8,解决火狐无法导入cer证书
增加80端口反代,以便自动跳转http访问到https请求上
```
### 1.0.5
```
紧急修复因为第三方steamdb api挂掉导致程序崩溃(第三方api确实还是不太靠谱,考虑之后换回steam官方api)
优化反代过程的逻辑
增加启动时自动运行Steam的设置项
新增令牌刷新功能
帐户切换增加了离线模式启动的选项
修复刷新游戏缓存按钮程序闪退BUG
还修复了一些没有记下来的小错误...
```
### 1.0.4
```
此版本修改了配置文件的保存读取功能,会无法读取1.0.4版本以前的配置文件包括令牌数据。(可以通过设置-令牌设置-导入旧版本Steam++令牌数据按钮来恢复旧版本令牌数据)
还原steam社区反代上游地址修复部分请求会提示需要登录的问题
新增令牌导入导出备份功能
新增令牌可以选择保存在程序根目录下的设置选项(方便备份)
修改了自动更新的提示方式
自动更新可以自动覆盖升级,不再需要手动替换
修复令牌无法保存的问题
```
### 1.0.3.3
```
新增pixiv本地反代服务支持
新增在欢迎页steam昵称后显示steam的登陆区域
添加steam图片修复的本地反代支持
修复最小化恢复时UI边框错位的BUG
修复令牌编辑和导入时出现的非空报错
帐户切换功能的最近登陆时间从北京时间改为当前系统时区时间
修复一个因为DNS解析错误会导致程序内存溢出闪退的BUG
SDA令牌导入不再支持导入加密文件,如果要导入加密的maFile请先在SDA移除加密
修改初始化的方式和steam api的连接逻辑来避免steam游戏掉帧的BUG
解决程序最小化启动时弹窗报错
优化本地令牌的加载
修复托盘图标单击启动多个窗口
修复设置界面设置UI错位
修复成就窗口关闭游戏依然运行
修改steam社区商店图片代理上游地址为steampowered.com
```
### 1.0.2
```
更新了由Benares制作的图标
新增帐户切换删除功能
添加github图片资源文件代理服务与discord代理服务支持
因为有问题暂时去掉了GOG Galaxy代理选项
修复一个会导致程序启动没有反应的bug
修复托盘菜单steam昵称过长ui错位bug
新增steam启动参数设置
新增启动时程序最小化到托盘菜单设置
新增捐助列表的展示
新增工具自动更新功能
```
## 工具介绍
`Steam++`是一个包含多种Steam工具功能的工具箱,开源发布于[Github](https://github.com/rmbadmin/SteamTools),如果您对发布的二进制文件不放心,可以自行下载源码编译运行。
此工具的大部分功能都是需要您下载安装Steam才能使用。
工具预计将整合进大部分常用的Steam相关工具,并且尽力做到比原工具更好用,在各种整合添加功能的同时,也会注意体积尽量的控制到最小。
软件截图
[hide]
[attachimg]1228394[/attachimg]
[attachimg]1228395[/attachimg]
[attachimg]1228396[/attachimg]
[attachimg]1228397[/attachimg]
[/hide]
## 核心功能
### 1. 反代Steam的社区网页使其能正常访问
功能类似羽翼城大佬的[steamcommunity_302](https://www.dogfight360.com/blog/686/),使用[Titanium-Web-Proxy](https://github.com/justcoding121/Titanium-Web-Proxy)开源项目进行本地反代,相比302工具具有更快的启动速度,以及支持简单的脚本注入。该功能也可以配合羽翼城大佬的[UsbEAm Hosts Editor](https://www.dogfight360.com/blog/475/)里的网页相关-steamcommunity_302 社区/api/商店加载速度选项的hosts提升加载速度。
[attachimg]1228388[/attachimg]
### 2. 快速切换当前PC已经记住登陆的Steam账号
该功能是读取Steam路径下存储的本地用户登录记录直接展示操作,可以多账号切换无需重新输入密码和令牌。
[attachimg]1228389[/attachimg]
### 3. Steam游戏的成就统计管理功能
功能参考[SteamAchievementManager](https://github.com/gibbed/SteamAchievementManager)进行二次开发,修复了成就语言有中文却依然是英文成就信息的BUG,修改了游戏列表的加载和操作易用性。
[attachimg]1228390[/attachimg]
### 4. Steam本地两步身份验证器
功能参考[WinAuth](https://github.com/winauth/winauth)开发,可以使您不用启动移动版Steam App也能查看您的令牌,功能类似的软件有[WinAuth](https://github.com/winauth/winauth)、[SteamDesktopAuthenticator](https://github.com/Jessecar96/SteamDesktopAuthenticator)。
[attachimg]1228391[/attachimg]
### 5. 一些游戏工具
目前已有强制游戏无边框窗口化,CSGO修复VAC屏蔽。
这一块是随缘做一些我经常用或者闲着没事捣鼓的功能。
将任何游戏强制无边框窗口化
[attachimg]1228392[/attachimg]
使任何窗口化游戏变成动态桌面壁纸(终于可以用《山》当壁纸了)
[attachimg]1228393[/attachimg]
------
## 预计后续添加的功能
### Steam自动挂卡
尝试用社区反代功能结合成就解锁功能来重新实现,目的是实现在软件内不用登录Steam即可直接获取徽章卡片信息并开始挂卡。
### Steam皮肤设计器
挖坑画大饼,可视化编辑Steam皮肤,而且如果软件能上架Steam的话打算支持创意工坊分享设计的Steam皮肤,短期内肯定做不完。
### 插件形式加载运行ASF
以插件形式支持ASF在工具内运行并增强ASF在Windows Desktop环境下的使用。
### Steam自定义封面管理
增强Steam自定义封面的管理以及从[SteamGridDB](https://www.steamgriddb.com/)快速匹配下载应用封面。
------
## 运行环境
> 程序使用C# WPF在 .NET Framework4.7.2环境下开发,如果无法运行请下载安装[.NET Framework 4.7.2](https://dotnet.microsoft.com/download/dotnet-framework/net472)。
## 下载
> [Github](https://github.com/rmbadmin/SteamTools/releases)
> 分流下载:
> [hide]
> [蓝奏云](https://wws.lanzous.com/i45yAkbbz9g)
> [百度云](https://pan.baidu.com/s/1qRnTuIjjM2FOfTrYHZxshg)
> 提取码:97c7
> [/hide]
> EXE 大小:4.85MB
> MD5:7FC035E1F38E79569597A6A6DDDF279B
> [查毒链接](https://www.virustotal.com/gui/file/6d0a506044013d1cea7c2b4f7734f2405ad7ac6b1f5213abc68743f979acf51f/detection)
虽然没有什么杀毒软件报毒,但是使用过程中可能遇到windows defender误报,您可以选择添加信任。
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 427 KiB

+306
View File
@@ -0,0 +1,306 @@
[
{
"Name": "*瑞",
"Amount": 5,
"OrderNumber": "",
"PayType": 1,
"Remark": "请大佬喝瓶饮料",
"PayTime": "2020-12-17 19:41:57"
},
{
"Name": "**耀",
"Amount": 5,
"OrderNumber": "",
"PayType": 1,
"Remark": "小小支持一波!",
"PayTime": "2020-12-17 20:46:01"
},
{
"Name": "**皓",
"Amount": 1,
"OrderNumber": "",
"PayType": 1,
"Remark": "2077掏空了我,等挂卡出来。在。。em",
"PayTime": "2020-12-17 22:41:27"
},
{
"Name": "**宇",
"Amount": 1,
"OrderNumber": "",
"PayType": 1,
"Remark": "",
"PayTime": "2020-12-18 08:39:42"
},
{
"Name": "*钊",
"Amount": 20,
"OrderNumber": "",
"PayType": 1,
"Remark": "其乐坛友bzll6538一点心意",
"PayTime": "2020-12-19 17:10:44"
},
{
"Name": "R*n",
"Amount": 20,
"OrderNumber": "",
"PayType": 2,
"Remark": "绿豆",
"PayTime": "2020-12-17 14:32:00"
},
{
"Name": "*炜",
"Amount": 100,
"OrderNumber": "",
"PayType": 1,
"Remark": "其乐坛友Davyheaven",
"PayTime": "2020-12-20 12:02:17"
},
{
"Name": "**智",
"Amount": 20,
"OrderNumber": "",
"PayType": 1,
"Remark": "派大星",
"PayTime": "2020-12-20 12:21:04"
},
{
"Name": "*森",
"Amount": 66,
"OrderNumber": "",
"PayType": 1,
"Remark": "区区心意,不成敬意(三个六给不起)",
"PayTime": "2020-12-21 23:03:26"
},
{
"Name": "*珂",
"Amount": 50,
"OrderNumber": "",
"PayType": 1,
"Remark": "其乐YK93,支持大佬",
"PayTime": "2020-12-21 23:18:09"
},
{
"Name": "**丰",
"Amount": 1,
"OrderNumber": "",
"PayType": 1,
"Remark": "",
"PayTime": "2020-12-22 12:33:46"
},
{
"Name": "Ruby",
"Amount": 77,
"OrderNumber": "",
"PayType": 2,
"Remark": "资瓷一下",
"PayTime": "2020-12-24 19:40:25"
},
{
"Name": "**桐",
"Amount": 1,
"OrderNumber": "",
"PayType": 1,
"Remark": "",
"PayTime": "2020-12-26 09:32:57"
},
{
"Name": "**珂",
"Amount": 5,
"OrderNumber": "",
"PayType": 1,
"Remark": "其乐坛友wjkhj123,小小支持一波",
"PayTime": "2020-12-26 13:28:07"
},
{
"Name": "z.w",
"Amount": 10,
"OrderNumber": "",
"PayType": 2,
"Remark": "滋瓷一下",
"PayTime": "2020-12-26 15:34:50"
},
{
"Name": "**林",
"Amount": 6,
"OrderNumber": "",
"PayType": 2,
"Remark": "一丶心意,大佬加油!",
"PayTime": "2020-12-26 18:25:06"
},
{
"Name": "**立",
"Amount": 1,
"OrderNumber": "",
"PayType": 2,
"Remark": "",
"PayTime": "2020-12-26 18:56:57"
},
{
"Name": "*易",
"Amount": 6.66,
"OrderNumber": "",
"PayType": 1,
"Remark": "其乐Kenagi,给大佬递冰阔落",
"PayTime": "2020-12-27 13:55:11"
},
{
"Name": "*明",
"Amount": 10,
"OrderNumber": "",
"PayType": 1,
"Remark": "感谢大佬",
"PayTime": "2020-12-27 21:28:40"
},
{
"Name": "山山为川",
"Amount": 1,
"OrderNumber": "",
"PayType": 2,
"Remark": "",
"PayTime": "2020-12-27 22:17:22"
},
{
"Name": "*梁",
"Amount": 3,
"OrderNumber": "",
"PayType": 1,
"Remark": "其乐wuwang23333 给大佬递",
"PayTime": "2020-12-28 11:59:20"
},
{
"Name": "**男",
"Amount": 1,
"OrderNumber": "",
"PayType": 1,
"Remark": "越做越好",
"PayTime": "2020-12-28 14:54:48"
},
{
"Name": "匿名",
"Amount": 14.61,
"OrderNumber": "",
"PayType": 2,
"Remark": "",
"PayTime": "2020-12-28 14:07:44"
},
{
"Name": "jiwuwang",
"Amount": 10,
"OrderNumber": "",
"PayType": 2,
"Remark": "希望挂卡早点安排上",
"PayTime": "2020-12-29 03:14:35"
},
{
"Name": "缄默",
"Amount": 10,
"OrderNumber": "",
"PayType": 2,
"Remark": "给软软打call!steam++是目前接触的最好用的插件!",
"PayTime": "2020-12-29 12:35:07"
},
{
"Name": "**宇",
"Amount": 6,
"OrderNumber": "",
"PayType": 1,
"Remark": "",
"PayTime": "2020-12-31 20:14:05"
},
{
"Name": "**东",
"Amount": 1,
"OrderNumber": "",
"PayType": 1,
"Remark": "一点绵薄之力,希望继续完善!",
"PayTime": "2021-01-03 21:28:08"
},
{
"Name": "**羽",
"Amount": 5,
"OrderNumber": "",
"PayType": 2,
"Remark": "感谢大佬",
"PayTime": "2021-01-05 16:22:11"
},
{
"Name": "**彬",
"Amount": 5,
"OrderNumber": "",
"PayType": 1,
"Remark": "平其心论天下之事,定其心应天下之变",
"PayTime": "2021-01-06 17:08:36"
},
{
"Name": "K",
"Amount": 10,
"OrderNumber": "",
"PayType": 2,
"Remark": "支持一下",
"PayTime": "2021-01-07 14:46:04"
},
{
"Name": "*鹏",
"Amount": 10,
"OrderNumber": "",
"PayType": 1,
"Remark": "加油💪",
"PayTime": "2021-01-07 11:42:38"
},
{
"Name": "*成",
"Amount": 6.66,
"OrderNumber": "",
"PayType": 1,
"Remark": "",
"PayTime": "2021-01-07 12:25:59"
},
{
"Name": "素年",
"Amount": 5,
"OrderNumber": "",
"PayType": 2,
"Remark": "不闪退了。支持一下",
"PayTime": "2021-01-08 22:37:11"
},
{
"Name": "kingburial",
"Amount": 1,
"OrderNumber": "",
"PayType": 2,
"Remark": "不是很常用,但是切换账号就很方便。谢谢啦",
"PayTime": "2021-01-09 10:16:04"
},
{
"Name": "**宇",
"Amount": 5,
"OrderNumber": "",
"PayType": 1,
"Remark": "",
"PayTime": "2021-01-12 20:39:26"
},
{
"Name": "Mixer",
"Amount": 20,
"OrderNumber": "",
"PayType": 2,
"Remark": "非常感谢!很好用",
"PayTime": "2021-01-14 06:15:26"
},
{
"Name": "**政",
"Amount": 5,
"OrderNumber": "",
"PayType": 2,
"Remark": "给个建议 令牌页面保持前端显示",
"PayTime": "2021-01-14 11:07:54"
},
{
"Name": "**浩",
"Amount": 6.66,
"OrderNumber": "",
"PayType": 1,
"Remark": "",
"PayTime": "2021-01-16 09:48:57"
}
]
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

@@ -82,7 +82,7 @@ namespace WinAuth
/// <summary>
/// Time for http request when calling Sync in ms
/// </summary>
private const int SYNC_TIMEOUT = 5000;
private const int SYNC_TIMEOUT = 30000;
/// <summary>
/// Steam issuer for KeyUri
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,7 @@
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.8" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.9" />
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="5.0.0" />
</ItemGroup>
@@ -0,0 +1,76 @@
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using SteamTool.Model;
using System;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.RegularExpressions;
namespace SteamTool.Proxy
{
public static class CertificateEx
{
public static string GetPublicPemCertificateString(this X509Certificate2 @this)
{
StringBuilder builder = new StringBuilder();
builder.AppendLine(Const.HOST_TAG);
builder.AppendLine("-----BEGIN CERTIFICATE-----");
builder.AppendLine(
Convert.ToBase64String(@this.RawData, Base64FormattingOptions.InsertLineBreaks));
builder.AppendLine("-----END CERTIFICATE-----");
builder.AppendLine(Const.HOST_TAG);
return builder.ToString();
}
public static string GetPrivatePemCertificateString(this X509Certificate2 @this)
{
RSACryptoServiceProvider pkey = (RSACryptoServiceProvider)@this.PrivateKey;
AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetRsaKeyPair(pkey);
using TextWriter tw = new StreamWriter(Path.Combine(AppContext.BaseDirectory, @this.IssuerName.Name + ".key"), false, new UTF8Encoding(false));
PemWriter pw = new PemWriter(tw);
pw.WriteObject(keyPair.Private);
tw.Flush();
return tw.ToString();
}
public static List<string> GetSubjectAlternativeNames(this X509Certificate2 certificate)
{
foreach (X509Extension extension in certificate.Extensions)
{
// Create an AsnEncodedData object using the extensions information.
AsnEncodedData asndata = new AsnEncodedData(extension.Oid, extension.RawData);
if (string.Equals(extension.Oid.FriendlyName, "Subject Alternative Name"))
{
//Console.WriteLine("Extension type: {0}", extension.Oid.FriendlyName);
//Console.WriteLine("Oid value: {0}", asndata.Oid.Value);
//Console.WriteLine("Raw data length: {0} {1}", asndata.RawData.Length, Environment.NewLine);
//Console.WriteLine(asndata.Format(true));
return new List<string>(
asndata.Format(true).Split(new string[] { Environment.NewLine, "DNS Name=" },
StringSplitOptions.RemoveEmptyEntries));
}
}
return new List<string>();
}
public static void SaveCerCertificateFile(this X509Certificate2 @this, string pathOrName)
{
StringBuilder builder = new StringBuilder();
builder.AppendLine("-----BEGIN CERTIFICATE-----");
builder.AppendLine(
Convert.ToBase64String(@this.Export(X509ContentType.Cert), Base64FormattingOptions.InsertLineBreaks));
builder.AppendLine("-----END CERTIFICATE-----");
File.WriteAllText(pathOrName, builder.ToString(), new UTF8Encoding(false));
}
}
}
@@ -9,6 +9,15 @@ namespace SteamTool.Core.Common
{
public static class Common
{
/// <summary>
/// 时间戳转DateTime(系统时区)
/// </summary>
/// <returns></returns>
public static DateTime ToDateTime(this long timestamp)
{
return TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(timestamp), TimeZoneInfo.Local);
}
/// <summary>
/// 返回当前时间戳
/// </summary>
@@ -37,6 +46,16 @@ namespace SteamTool.Core.Common
}
}
/// <summary>
/// 移除字符串内所有\r \n \t
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string RemovePattern(this string inputString)
{
return inputString.Replace("\t", "").Replace("\r", "").Replace("\n", "");
}
/// <summary>
/// 获取两个字符串中间的字符串
/// </summary>
@@ -15,6 +15,10 @@ namespace SteamTool.Core.Common
/// <returns></returns>
public static string CompressString(this string text)
{
if (string.IsNullOrEmpty(text))
{
return null;
}
byte[] buffer = Encoding.UTF8.GetBytes(text);
var memoryStream = new MemoryStream();
using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
@@ -40,6 +44,10 @@ namespace SteamTool.Core.Common
/// <returns></returns>
public static string DecompressString(this string compressedText)
{
if (string.IsNullOrEmpty(compressedText))
{
return null;
}
byte[] gZipBuffer = Convert.FromBase64String(compressedText);
using var memoryStream = new MemoryStream();
int dataLength = BitConverter.ToInt32(gZipBuffer, 0);
@@ -1,12 +1,14 @@
using log4net;
using log4net.Config;
using log4net.Repository;
using SteamTool.Core.Properties;
using SteamTool.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml;
namespace SteamTool.Core.Common
{
@@ -21,7 +23,16 @@ namespace SteamTool.Core.Common
static Logger()
{
ILoggerRepository repository = LogManager.CreateRepository(Assembly.GetCallingAssembly().GetName().Name);
XmlConfigurator.Configure(repository, new FileInfo(@"log\Log4net.config"));
if (File.Exists(Path.Combine(AppContext.BaseDirectory, @"log\Log4net.config")))
{
XmlConfigurator.Configure(repository, new FileInfo(@"log\Log4net.config"));
}
else
{
var doc = new XmlDocument();
doc.LoadXml(Resources.Log4netXml);
XmlConfigurator.Configure(repository, doc.DocumentElement);
}
_textLog = LogManager.GetLogger(repository.Name, "TextLog");
}
+71
View File
@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace SteamTool.Core.Common
{
/// <summary>
/// 类名 :MD5加密<br/>
/// 说明 :<br/>
/// </summary>
public static class Md5Method
{
/// <summary>
/// 用MD5加密一段字符串
/// </summary>
/// <param name="str">字符串</param>
/// <param name="isLower">是否小写</param>
/// <returns>MD5串</returns>
public static string MD5Encrypt(string str, bool isLower = false)
{
using (var md5 = MD5.Create())
{
var result = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
var strResult = BitConverter.ToString(result).Replace("-", "");
return isLower ? strResult.ToLower() : strResult;
}
}
/// <summary>
/// 用MD5加密流
/// </summary>
/// <param name="myStream">流</param>
/// <returns>str</returns>
public static byte[] MD5Encrypt(Stream inputStream)
{
System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
return md5.ComputeHash(inputStream);
}
/// <summary>
/// 用MD5加密字节数组
/// </summary>
/// <param name="myBytes">字节数组</param>
/// <returns></returns>
public static byte[] MD5Encrypt(byte[] myBytes)
{
System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
return md5.ComputeHash(myBytes, 0, myBytes.Length);
}
/// <summary>
/// 文件路径
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static string FileMD5Encrypt(string path)
{
using FileStream fs = new FileStream(path, FileMode.Open);
MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
byte[] data = provider.ComputeHash(fs);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
builder.Append(data[i].ToString("X2"));
}
return builder.ToString();
}
}
}

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