Compare commits
74 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 451de6ca55 | |||
| 691fb360bb | |||
| 686e3987f8 | |||
| 79871c3bcb | |||
| c1b19b4929 | |||
| c564ea10eb | |||
| d5006da378 | |||
| 878e9dbd32 | |||
| bd7f9e76b8 | |||
| fc285cf583 | |||
| 3ab0ae46c0 | |||
| 4550ff1621 | |||
| 1663bd4277 | |||
| 679afdef1b | |||
| d38588d45c | |||
| 42b11ce241 | |||
| c01512bcf6 | |||
| dd89595629 | |||
| 94b5539823 | |||
| 317baff79c | |||
| f702c3ae62 | |||
| 177216a51e | |||
| 46b1c01107 | |||
| 798355e342 | |||
| ee741d3138 | |||
| e31b668beb | |||
| c00955205c | |||
| 5345926c8b | |||
| 0987f58fee | |||
| 715737bce2 | |||
| 44245aa2b7 | |||
| 97e6b92ef6 | |||
| 445f130272 | |||
| 39fcc4d9a8 | |||
| b4a755a647 | |||
| 083189c264 | |||
| 676c628b6f | |||
| 43ca455e70 | |||
| 95e834a188 | |||
| e9d822bb0c | |||
| f395383db8 | |||
| f805911f4e | |||
| b3d203fbda | |||
| bb022f45fd | |||
| e4a97463f4 | |||
| 11adabb749 | |||
| 8a7ad67363 | |||
| 7af0888b0a | |||
| 42fc93a524 | |||
| 5c832f489b | |||
| 5e7ed26bc6 | |||
| 085ad3d944 | |||
| 334503445c | |||
| cf17ca8dd6 | |||
| 0b88de7195 | |||
| 3342e35440 | |||
| 56baba4a53 | |||
| 8b1a946fe2 | |||
| 9e08c0b7c4 | |||
| 3a38333dfc | |||
| 16d1bba515 | |||
| 00cf9da911 | |||
| 088256faf9 | |||
| ca244edc51 | |||
| c91608da09 | |||
| 2945e9fa3e | |||
| 1f0a40cd3b | |||
| b1fbe64ab2 | |||
| 9a13665e68 | |||
| 5c0f71f4a7 | |||
| 3e045e5db0 | |||
| c4f99906ab | |||
| 94e50f663b | |||
| 49e08101c6 |
@@ -1,13 +0,0 @@
|
||||
### 该问题是怎么引起的?
|
||||
|
||||
|
||||
|
||||
### 重现步骤
|
||||
|
||||
|
||||
|
||||
### 报错信息
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
### 相关的Issue
|
||||
|
||||
|
||||
### 原因(目的、解决的问题等)
|
||||
|
||||
|
||||
### 描述(做了什么,变更了什么)
|
||||
|
||||
|
||||
### 测试用例(新增、改动、可能影响的功能)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ib/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
|
||||
@@ -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
|
||||
@@ -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/>
|
||||
|
||||

|
||||
[](https://github.com/rmbadmin/SteamTools/releases/latest)
|
||||
[](LICENSE)
|
||||
[](https://github.com/rmbadmin/SteamTools/stargazers)
|
||||
[](https://github.com/rmbadmin/SteamTools/network/members)
|
||||

|
||||
|
||||
## Samples
|
||||
-------
|
||||

|
||||

|
||||

|
||||

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

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

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

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

|
||||

|
||||
---
|
||||
|
||||
## 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)
|
||||
@@ -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/>
|
||||
|
||||

|
||||
[](https://github.com/rmbadmin/SteamTools/releases/latest)
|
||||
[](LICENSE)
|
||||
[](https://github.com/rmbadmin/SteamTools/stargazers)
|
||||
[](https://github.com/rmbadmin/SteamTools/network/members)
|
||||

|
||||
|
||||
# Steam++
|
||||
|
||||
## 效果展示
|
||||
-------
|
||||

|
||||

|
||||

|
||||

|
||||
------
|
||||
|
||||
「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等网站的反代支持)
|
||||

|
||||
---
|
||||
### 2. 快速切换当前PC已经记住登陆的Steam账号
|
||||
|
||||
该功能是读取Steam路径下存储的本地用户登录记录直接展示操作,可以多账号切换无需重新输入密码和令牌。
|
||||
|
||||

|
||||
---
|
||||
### 3. Steam游戏的成就统计管理功能
|
||||
功能类似[SteamAchievementManager](https://github.com/gibbed/SteamAchievementManager),实现也参考了SAM,并且略作修改了,游戏列表的读取,解锁成就的逻辑。
|
||||
|
||||
功能参考[SteamAchievementManager](https://github.com/gibbed/SteamAchievementManager)进行二次开发,修改了游戏列表的加载和操作易用性。
|
||||

|
||||
---
|
||||
|
||||
### 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)。
|
||||

|
||||
---
|
||||
|
||||
### 5. 一些游戏工具
|
||||
目前已有强制游戏无边框窗口化,CSGO修复VAC屏蔽。
|
||||
这一块是随缘做一些我经常用或者闲着没事捣鼓的功能。
|
||||

|
||||

|
||||
---
|
||||
|
||||
## 预计后续添加的功能
|
||||
|
||||
### 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)
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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) { }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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); ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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); ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 243 KiB |
|
Before Width: | Height: | Size: 510 B |
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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=" "/>
|
||||
<Run Text="2020-12-14" FontSize="10" />
|
||||
<LineBreak />
|
||||
<Run Text="    "/>
|
||||
<Run Text="发布第一个版本" />
|
||||
<LineBreak/>
|
||||
<Run Text="    "/>
|
||||
<Run Text="主要功能:社区反代,帐户切换,成就解锁,本地令牌。"></Run>
|
||||
<LineBreak/>
|
||||
<Run Text="    "/>
|
||||
<Run Text="次要功能:强制无边框窗口化以及CSGO VAC屏蔽修复。"></Run>
|
||||
</Paragraph>
|
||||
</FlowDocument>
|
||||
</FlowDocumentScrollViewer>
|
||||
</Border>
|
||||
</DockPanel>
|
||||
</UserControl>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 +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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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误报,您可以选择添加信任。
|
||||
|
After Width: | Height: | Size: 145 KiB |
|
After Width: | Height: | Size: 148 KiB |
|
After Width: | Height: | Size: 322 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 427 KiB |
@@ -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"
|
||||
}
|
||||
]
|
||||
|
After Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 199 KiB |
|
After Width: | Height: | Size: 364 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 364 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 236 KiB |
|
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
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||