Compare commits

...
21 Commits
Author SHA1 Message Date
rmbgame cf17ca8dd6 ready 1.0.2 2020-12-21 21:18:14 +08:00
rmbgame 0b88de7195 添加了自动更新检测功能 2020-12-21 21:17:49 +08:00
rmbgame 3342e35440 bug fix 2020-12-21 21:17:43 +08:00
rmbgame 56baba4a53 修复了443端口占用只会提示一次的问题 2020-12-21 21:17:38 +08:00
rmbgame 8b1a946fe2 添加discord代理选项 2020-12-20 14:57:34 +08:00
rmbgame 9e08c0b7c4 优化反代启用时内存占用
添加github图片资源文件代理服务支持
2020-12-20 14:57:18 +08:00
rmbgame 3a38333dfc 移除无用代码,修正一个命名错误 2020-12-20 14:57:04 +08:00
rmbgame 16d1bba515 update readme 2020-12-20 00:21:35 +08:00
rmbgame 00cf9da911 修复了程序启动时自动启动代理脚本不生效的问题
因为有问题暂时去掉了GOG Galaxy代理选项
增加捐助列表的展示
增加启动时程序最小化到托盘菜单设置
2020-12-20 00:14:22 +08:00
rmbgame 088256faf9 修复一个会导致steam未连接文字闪烁的BUG 2020-12-20 00:14:17 +08:00
rmbgame ca244edc51 sync gitee 2020-12-19 00:24:56 +08:00
rmbgame c91608da09 update readme 2020-12-19 00:23:49 +08:00
rmbgame 2945e9fa3e 更新了新的图标
增加steam启动参数设置
修复了一些文本bug
2020-12-19 00:22:54 +08:00
rmbgame 1f0a40cd3b 新增帐户切换删除功能(凑合用)
修复一个会导致程序启动没有反应的bug
修复托盘菜单steam昵称过长ui错位bug
修正了配置文件夹命名错误(1.0.0版本更新后设置会被重置)
2020-12-19 00:07:02 +08:00
rmbgame b1fbe64ab2 update readme 2020-12-17 17:19:28 +08:00
rmbgame 9a13665e68 ready 1.0.0 2020-12-17 12:09:47 +08:00
rmbgame 5c0f71f4a7 sync gitee 2020-12-16 10:45:03 +08:00
rmbgame 3e045e5db0 delete ref lib 2020-12-16 10:33:43 +08:00
rmbgame c4f99906ab update 2020-12-16 10:29:55 +08:00
rmbgame 94e50f663b 删除无用代码 2020-12-15 23:35:17 +08:00
rmbgame 49e08101c6 delete error ref 2020-12-15 23:29:36 +08:00
92 changed files with 1220 additions and 1258 deletions
+1
View File
@@ -26,6 +26,7 @@ bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ib/
# Visual Studio 2015/2017 cache/options directory
.vs/
+74
View File
@@ -0,0 +1,74 @@
[
{
"Index": 1,
"Name": "*瑞",
"Amount": 5,
"OrderNumber": "",
"PayType": 1,
"Remark": "请大佬喝瓶饮料",
"PayTime": "2020-12-17 19:41:57"
},
{
"Index": 2,
"Name": "**耀",
"Amount": 5,
"OrderNumber": "",
"PayType": 1,
"Remark": "小小支持一波!",
"PayTime": "2020-12-17 20:46:01"
},
{
"Index": 3,
"Name": "**皓",
"Amount": 1,
"OrderNumber": "",
"PayType": 1,
"Remark": "2077掏空了我,等挂卡出来。在。。em",
"PayTime": "2020-12-17 22:41:27"
},
{
"Index": 4,
"Name": "**宇",
"Amount": 1,
"OrderNumber": "",
"PayType": 1,
"Remark": "",
"PayTime": "2020-12-18 08:39:42"
},
{
"Index": 5,
"Name": "*钊",
"Amount": 20,
"OrderNumber": "",
"PayType": 1,
"Remark": "其乐坛友bzll6538一点心意",
"PayTime": "2020-12-19 17:10:44"
},
{
"Index": 6,
"Name": "R*n",
"Amount": 20,
"OrderNumber": "",
"PayType": 2,
"Remark": "绿豆",
"PayTime": "2020-12-17 14:32:00"
},
{
"Index": 7,
"Name": "*炜",
"Amount": 100,
"OrderNumber": "",
"PayType": 1,
"Remark": "其乐坛友Davyheaven",
"PayTime": "2020-12-20 12:02:17"
},
{
"Index": 8,
"Name": "**智",
"Amount": 20,
"OrderNumber": "",
"PayType": 1,
"Remark": "派大星",
"PayTime": "2020-12-20 12:21:04"
}
]
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+54 -9
View File
@@ -1,6 +1,5 @@
# Steam++工具箱 v1.0
# Steam++ SteamTools
------
「Steam++」是一个包含多种Steam工具功能的工具箱。
@@ -8,14 +7,11 @@
------
## 主要功能
## 核心功能
### 1. 反代Steam的社区网页使其能正常访问
功能类似羽翼城大佬的Steam302,相比之下有:
- [X] 更快的启动速度
- [X] 支持脚本注入
功能类似羽翼城大佬的Steam302,使用[Titanium-Web-Proxy](https://github.com/justcoding121/Titanium-Web-Proxy)开源项目进行本地反代,相比302工具具有更快的启动速度,以及支持简单的脚本注入。
---
### 2. 快速切换当前PC已经记住登陆的Steam账号
@@ -24,12 +20,12 @@
---
### 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)。
---
@@ -38,3 +34,52 @@
这一块是随缘做一些我经常用或者闲着没事捣鼓的功能。
---
## 预计后续添加的功能
### 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)。
---
## License
> [GPL-3.0 License](LICENSE.txt)
> 根据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/Grabacr07/MetroTrilithonhttps://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)
+59 -10
View File
@@ -1,6 +1,4 @@
# Steam++工具箱 v1.0
------
# Steam++工具箱
「Steam++」是一个包含多种Steam工具功能的工具箱。
@@ -8,14 +6,11 @@
------
## 主要功能
## 核心功能
### 1. 反代Steam的社区网页使其能正常访问
功能类似羽翼城大佬的Steam302,相比之下有:
- [X] 更快的启动速度
- [X] 支持脚本注入
功能类似羽翼城大佬的Steam302,使用[Titanium-Web-Proxy](https://github.com/justcoding121/Titanium-Web-Proxy)开源项目进行本地反代,相比302工具具有更快的启动速度,以及支持简单的脚本注入。
---
### 2. 快速切换当前PC已经记住登陆的Steam账号
@@ -24,12 +19,12 @@
---
### 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)。
---
@@ -38,3 +33,57 @@
这一块是随缘做一些我经常用或者闲着没事捣鼓的功能。
---
## 预计后续添加的功能
### 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)。
> 缺失的程序集为我自己修改后的项目
* [Titanium-Web-Proxy](https://github.com/rmbadmin/Titanium-Web-Proxy)
* [MetroRadiance](https://github.com/rmbadmin/MetroRadiance)
---
## License
> [GPL-3.0 License](LICENSE.txt)
> 根据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/Grabacr07/MetroTrilithonhttps://github.com/ugaya40/StatefulModel)
* [Hardcodet.NotifyIcon](https://github.com/HavenDV/Hardcodet.NotifyIcon.Wpf.NetCore)
* [System.Reactive](https://github.com/dotnet/reactive)
* [Titanium-Web-Proxy](https://github.com/justcoding121/Titanium-Web-Proxy)
* [Ninject](https://github.com/ninject/Ninject)
* [log4net](https://github.com/apache/logging-log4net)
* [SteamDB-API](https://github.com/SteamDB-API/api)
* [SteamAchievementManager](https://github.com/gibbed/SteamAchievementManager)
* [ArchiSteamFarm](https://github.com/JustArchiNET/ArchiSteamFarm)
* [WinAuth](https://github.com/winauth/winauth)
* [SteamDesktopAuthenticator](https://github.com/Jessecar96/SteamDesktopAuthenticator)
* [Gameloop.Vdf](https://github.com/shravan2x/Gameloop.Vdf)
* [Costura.Fody](https://github.com/Fody/Costura)
-249
View File
@@ -1,249 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using WinAuth;
namespace SteamTool.Auth
{
public static class AuthService
{
/// <summary>
/// Import a file containing authenticators in the KeyUriFormat. The file might be plain text, encrypted zip or encrypted pgp.
/// </summary>
/// <param name="parent">parent Form</param>
/// <param name="file">file name to import</param>
/// <returns>list of imported authenticators</returns>
public static List<WinAuthAuthenticator> ImportAuthenticators(string file)
{
List<WinAuthAuthenticator> authenticators = new List<WinAuthAuthenticator>();
StringBuilder lines = new StringBuilder();
bool retry;
do
{
retry = false;
lines.Length = 0;
// read a plain text file
lines.Append(File.ReadAllText(file));
} while (retry);
int linenumber = 0;
try
{
using (var sr = new StringReader(lines.ToString()))
{
string line;
while ((line = sr.ReadLine()) != null)
{
linenumber++;
// ignore blank lines or comments
line = line.Trim();
if (line.Length == 0 || line.IndexOf("#") == 0)
{
continue;
}
// bug if there is a hash before ?
var hash = line.IndexOf("#");
var qm = line.IndexOf("?");
if (hash != -1 && hash < qm)
{
line = line.Substring(0, hash) + "%23" + line.Substring(hash + 1);
}
// parse and validate URI
var uri = new Uri(line);
// we only support "otpauth"
if (uri.Scheme != "otpauth")
{
throw new ApplicationException("Import only supports otpauth://");
}
// we only support totp (not hotp)
if (uri.Host != "totp" && uri.Host != "hotp")
{
throw new ApplicationException("Import only supports otpauth://totp/ or otpauth://hotp/");
}
// get the label and optional issuer
string issuer = string.Empty;
string label = (string.IsNullOrEmpty(uri.LocalPath) == false ? uri.LocalPath.Substring(1) : string.Empty); // skip past initial /
int p = label.IndexOf(":");
if (p != -1)
{
issuer = label.Substring(0, p);
label = label.Substring(p + 1);
}
// + aren't decoded
label = label.Replace("+", " ");
var query = HttpUtility.ParseQueryString(uri.Query);
string secret = query["secret"];
if (string.IsNullOrEmpty(secret) == true)
{
throw new ApplicationException("Authenticator does not contain secret");
}
string counter = query["counter"];
if (uri.Host == "hotp" && string.IsNullOrEmpty(counter) == true)
{
throw new ApplicationException("HOTP authenticator should have a counter");
}
WinAuthAuthenticator importedAuthenticator = new WinAuthAuthenticator
{
AutoRefresh = false
};
//
Authenticator auth;
if (string.Compare(issuer, "BattleNet", true) == 0)
{
string serial = query["serial"];
if (string.IsNullOrEmpty(serial) == true)
{
throw new ApplicationException("Battle.net Authenticator does not have a serial");
}
serial = serial.ToUpper();
if (Regex.IsMatch(serial, @"^[A-Z]{2}-?[\d]{4}-?[\d]{4}-?[\d]{4}$") == false)
{
throw new ApplicationException("Invalid serial for Battle.net Authenticator");
}
auth = new BattleNetAuthenticator();
//char[] decoded = Base32.getInstance().Decode(secret).Select(c => Convert.ToChar(c)).ToArray(); // this is hex string values
//string hex = new string(decoded);
//((BattleNetAuthenticator)auth).SecretKey = Authenticator.StringToByteArray(hex);
((BattleNetAuthenticator)auth).SecretKey = Base32.getInstance().Decode(secret);
((BattleNetAuthenticator)auth).Serial = serial;
issuer = string.Empty;
}
else if (string.Compare(issuer, "Steam", true) == 0)
{
auth = new SteamAuthenticator();
((SteamAuthenticator)auth).SecretKey = Base32.getInstance().Decode(secret);
((SteamAuthenticator)auth).Serial = string.Empty;
((SteamAuthenticator)auth).DeviceId = query["deviceid"] ?? string.Empty;
((SteamAuthenticator)auth).SteamData = query["data"] ?? string.Empty;
issuer = string.Empty;
}
else if (uri.Host == "hotp")
{
auth = new HOTPAuthenticator();
((HOTPAuthenticator)auth).SecretKey = Base32.getInstance().Decode(secret);
((HOTPAuthenticator)auth).Counter = int.Parse(counter);
if (string.IsNullOrEmpty(issuer) == false)
{
auth.Issuer = issuer;
}
}
else // if (string.Compare(issuer, "Google", true) == 0)
{
auth = new GoogleAuthenticator();
((GoogleAuthenticator)auth).Enroll(secret);
if (string.Compare(issuer, "Google", true) == 0)
{
issuer = string.Empty;
}
else if (string.IsNullOrEmpty(issuer) == false)
{
auth.Issuer = issuer;
}
}
int period = 0;
int.TryParse(query["period"], out period);
if (period != 0)
{
auth.Period = period;
}
int digits = 0;
int.TryParse(query["digits"], out digits);
if (digits != 0)
{
auth.CodeDigits = digits;
}
Authenticator.HMACTypes hmactype;
if (Enum.TryParse<Authenticator.HMACTypes>(query["algorithm"], true, out hmactype) == true)
{
auth.HMACType = hmactype;
}
//
if (label.Length != 0)
{
importedAuthenticator.Name = (issuer.Length != 0 ? issuer + " (" + label + ")" : label);
}
else if (issuer.Length != 0)
{
importedAuthenticator.Name = issuer;
}
else
{
importedAuthenticator.Name = "Imported";
}
//
importedAuthenticator.AuthenticatorData = auth;
// sync
importedAuthenticator.Sync();
authenticators.Add(importedAuthenticator);
}
}
return authenticators;
}
catch (UriFormatException ex)
{
throw new ImportException(string.Format("Invalid authenticator at line {0}", linenumber), ex);
}
catch (Exception ex)
{
throw new ImportException(string.Format("Error importing at line {0}:{1}", ex.Message), ex);
}
}
public static string ExportAuthenticators(IList<WinAuthAuthenticator> authenticators, string password)
{
// create file in memory
using (var ms = new MemoryStream())
{
using (var sw = new StreamWriter(ms))
{
List<WinAuthAuthenticator> unprotected = new List<WinAuthAuthenticator>();
foreach (var auth in authenticators)
{
unprotected.Add(auth);
string line = auth.ToUrl();
sw.WriteLine(line);
}
// reprotect
foreach (var auth in unprotected)
{
auth.AuthenticatorData.Protect();
}
// reset and write stream out to disk or as zip
sw.Flush();
ms.Seek(0, SeekOrigin.Begin);
var result = Encoding.UTF8.GetString(ms.ToArray());
return result;
}
}
}
}
}
-19
View File
@@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SteamTool.Auth
{
/// <summary>
/// Exception class wrapper for importing error
/// </summary>
public class ImportException : ApplicationException
{
public ImportException() : base() { }
public ImportException(string message) : base(message) { }
public ImportException(string message, Exception ex) : base(message, ex) { }
}
}
-18
View File
@@ -1,18 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Platforms>AnyCPU;x86</Platforms>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SteamTool.Authenticator\SteamTool.Authenticator.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="PresentationCore">
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\PresentationCore.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
-22
View File
@@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace SteamTool.Auth.Win32
{
public class WinAPI
{
public const string LibraryName = "user32.dll";
[DllImport(LibraryName, CharSet = CharSet.Auto)]
internal static extern IntPtr GetOpenClipboardWindow();
[DllImport(LibraryName, SetLastError = true, CharSet = CharSet.Auto)]
internal static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport(LibraryName, CharSet = CharSet.Auto, SetLastError = true)]
internal static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
}
}
-597
View File
@@ -1,597 +0,0 @@
using SteamTool.Auth.Win32;
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Windows;
using System.Xml;
using WinAuth;
namespace SteamTool.Auth
{
public interface IWinAuthAuthenticatorChangedListener
{
void OnWinAuthAuthenticatorChanged(WinAuthAuthenticator sender, WinAuthAuthenticatorChangedEventArgs e);
}
/// <summary>
/// Wrapper for real authenticator data used to save to file with other application information
/// </summary>
public class WinAuthAuthenticator : ICloneable
{
/// <summary>
/// Event handler fired when property is changed
/// </summary>
public event WinAuthAuthenticatorChangedHandler OnWinAuthAuthenticatorChanged;
/// <summary>
/// Unique Id of authenticator saved in config
/// </summary>
public Guid Id { get; set; }
/// <summary>
/// Index for authenticator when in sorted list
/// </summary>
public int Index { get; set; }
/// <summary>
/// Actual authenticator data
/// </summary>
public Authenticator AuthenticatorData { get; set; }
/// <summary>
/// When this authenticator was created
/// </summary>
public DateTime Created { get; set; }
private string _name;
private bool _autoRefresh;
private bool _allowCopy;
private bool _copyOnCode;
private bool _hideSerial;
/// <summary>
/// Create the authenticator wrapper
/// </summary>
public WinAuthAuthenticator()
{
Id = Guid.NewGuid();
Created = DateTime.Now;
_autoRefresh = true;
}
/// <summary>
/// Clone this authenticator
/// </summary>
/// <returns></returns>
public object Clone()
{
WinAuthAuthenticator clone = this.MemberwiseClone() as WinAuthAuthenticator;
clone.Id = Guid.NewGuid();
clone.OnWinAuthAuthenticatorChanged = null;
clone.AuthenticatorData = (this.AuthenticatorData != null ? this.AuthenticatorData.Clone() as Authenticator : null);
return clone;
}
/// <summary>
/// Mark this authenticator as having changed
/// </summary>
public void MarkChanged()
{
if (OnWinAuthAuthenticatorChanged != null)
{
OnWinAuthAuthenticatorChanged(this, new WinAuthAuthenticatorChangedEventArgs());
}
}
/// <summary>
/// Get/set the name of this authenticator
/// </summary>
public string Name
{
get
{
return _name;
}
set
{
_name = value;
if (OnWinAuthAuthenticatorChanged != null)
{
OnWinAuthAuthenticatorChanged(this, new WinAuthAuthenticatorChangedEventArgs("Name"));
}
}
}
/// <summary>
/// Get/set auto refresh flag
/// </summary>
public bool AutoRefresh
{
get
{
if (this.AuthenticatorData != null && this.AuthenticatorData is HOTPAuthenticator)
{
return false;
}
else
{
return _autoRefresh;
}
}
set
{
// HTOP must always be false
if (this.AuthenticatorData != null && this.AuthenticatorData is HOTPAuthenticator)
{
_autoRefresh = false;
}
else
{
_autoRefresh = value;
}
if (OnWinAuthAuthenticatorChanged != null)
{
OnWinAuthAuthenticatorChanged(this, new WinAuthAuthenticatorChangedEventArgs("AutoRefresh"));
}
}
}
/// <summary>
/// Get/set allow copy flag
/// </summary>
public bool AllowCopy
{
get
{
return _allowCopy;
}
set
{
_allowCopy = value;
if (OnWinAuthAuthenticatorChanged != null)
{
OnWinAuthAuthenticatorChanged(this, new WinAuthAuthenticatorChangedEventArgs("AllowCopy"));
}
}
}
/// <summary>
/// Get/set auto copy flag
/// </summary>
public bool CopyOnCode
{
get
{
return _copyOnCode;
}
set
{
_copyOnCode = value;
if (OnWinAuthAuthenticatorChanged != null)
{
OnWinAuthAuthenticatorChanged(this, new WinAuthAuthenticatorChangedEventArgs("CopyOnCode"));
}
}
}
/// <summary>
/// Get/set hide serial flag
/// </summary>
public bool HideSerial
{
get
{
return _hideSerial;
}
set
{
_hideSerial = value;
if (OnWinAuthAuthenticatorChanged != null)
{
OnWinAuthAuthenticatorChanged(this, new WinAuthAuthenticatorChangedEventArgs("HideSerial"));
}
}
}
public string CurrentCode
{
get
{
if (this.AuthenticatorData == null)
{
return null;
}
string code = this.AuthenticatorData.CurrentCode;
if (this.AuthenticatorData is HOTPAuthenticator)
{
if (OnWinAuthAuthenticatorChanged != null)
{
OnWinAuthAuthenticatorChanged(this, new WinAuthAuthenticatorChangedEventArgs("HOTP", this.AuthenticatorData));
}
}
return code;
}
}
/// <summary>
/// Sync the current authenticator's time with its server
/// </summary>
public void Sync()
{
if (AuthenticatorData != null)
{
try
{
AuthenticatorData.Sync();
}
catch (EncryptedSecretDataException)
{
// reset lastsync to force sync on next decryption
}
}
}
/// <summary>
/// Copy the current code to the clipboard
/// </summary>
public void CopyCodeToClipboard(string code = null, bool showError = false)
{
if (code == null)
{
code = this.CurrentCode;
}
bool clipRetry = false;
do
{
bool failed = false;
// check if the clipboard is locked
IntPtr hWnd = WinAPI.GetOpenClipboardWindow();
if (hWnd != IntPtr.Zero)
{
int len = WinAPI.GetWindowTextLength(hWnd);
if (len == 0)
{
//WinAuthMain.LogException(new ApplicationException("Clipboard in use by another process"));
}
else
{
StringBuilder sb = new StringBuilder(len + 1);
WinAPI.GetWindowText(hWnd, sb, sb.Capacity);
//WinAuthMain.LogException(new ApplicationException("Clipboard in use by '" + sb.ToString() + "'"));
}
failed = true;
}
else
{
// Issue#170: can still get error copying even though it works, so just increase retries and ignore error
try
{
Clipboard.Clear();
// add delay for clip error
System.Threading.Thread.Sleep(100);
Clipboard.SetDataObject(code, true);
}
catch (ExternalException)
{
}
}
if (failed == true && showError == true)
{
// only show an error the first time
//clipRetry = (MessageBox.Show(form, strings.ClipboardInUse,
// WinAuthMain.APPLICATION_NAME,
// MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes);
}
}
while (clipRetry == true);
}
public bool ReadXml(XmlReader reader, string password)
{
bool changed = false;
Guid id;
if (Guid.TryParse(reader.GetAttribute("id"), out id) == true)
{
Id = id;
}
string authenticatorType = reader.GetAttribute("type");
if (string.IsNullOrEmpty(authenticatorType) == false)
{
Type type = typeof(Authenticator).Assembly.GetType(authenticatorType, false, true);
this.AuthenticatorData = Activator.CreateInstance(type) as Authenticator;
}
//string encrypted = reader.GetAttribute("encrypted");
//if (string.IsNullOrEmpty(encrypted) == false)
//{
// // read the encrypted text from the node
// string data = reader.ReadElementContentAsString();
// // decrypt
// Authenticator.PasswordTypes passwordType;
// data = Authenticator.DecryptSequence(data, encrypted, password, out passwordType);
// using (MemoryStream ms = new MemoryStream(Authenticator.StringToByteArray(data)))
// {
// reader = XmlReader.Create(ms);
// ReadXml(reader, password);
// }
// this.PasswordType = passwordType;
// this.Password = password;
// return;
//}
reader.MoveToContent();
if (reader.IsEmptyElement)
{
reader.Read();
return changed;
}
reader.Read();
while (reader.EOF == false)
{
if (reader.IsStartElement())
{
switch (reader.Name)
{
case "name":
Name = reader.ReadElementContentAsString();
break;
case "created":
long t = reader.ReadElementContentAsLong();
t += Convert.ToInt64(new TimeSpan(new DateTime(1970, 1, 1).Ticks).TotalMilliseconds);
t *= TimeSpan.TicksPerMillisecond;
Created = new DateTime(t).ToLocalTime();
break;
case "autorefresh":
_autoRefresh = reader.ReadElementContentAsBoolean();
break;
case "allowcopy":
_allowCopy = reader.ReadElementContentAsBoolean();
break;
case "copyoncode":
_copyOnCode = reader.ReadElementContentAsBoolean();
break;
case "hideserial":
_hideSerial = reader.ReadElementContentAsBoolean();
break;
case "authenticatordata":
try
{
// we don't pass the password as they are locked till clicked
changed = this.AuthenticatorData.ReadXml(reader) || changed;
}
catch (EncryptedSecretDataException)
{
// no action needed
}
catch (BadPasswordException)
{
// no action needed
}
break;
// v2
case "authenticator":
this.AuthenticatorData = Authenticator.ReadXmlv2(reader, password);
break;
// v2
case "servertimediff":
this.AuthenticatorData.ServerTimeDiff = reader.ReadElementContentAsLong();
break;
default:
reader.Skip();
break;
}
}
else
{
reader.Read();
break;
}
}
return changed;
}
/// <summary>
/// Write the data as xml into an XmlWriter
/// </summary>
/// <param name="writer">XmlWriter to write config</param>
public void WriteXmlString(XmlWriter writer)
{
writer.WriteStartElement(typeof(WinAuthAuthenticator).Name);
writer.WriteAttributeString("id", this.Id.ToString());
if (this.AuthenticatorData != null)
{
writer.WriteAttributeString("type", this.AuthenticatorData.GetType().FullName);
}
//if (this.PasswordType != Authenticator.PasswordTypes.None)
//{
// string data;
// using (MemoryStream ms = new MemoryStream())
// {
// XmlWriterSettings settings = new XmlWriterSettings();
// settings.Indent = true;
// settings.Encoding = Encoding.UTF8;
// using (XmlWriter encryptedwriter = XmlWriter.Create(ms, settings))
// {
// Authenticator.PasswordTypes savedpasswordType = PasswordType;
// PasswordType = Authenticator.PasswordTypes.None;
// WriteXmlString(encryptedwriter);
// PasswordType = savedpasswordType;
// }
// //data = Encoding.UTF8.GetString(ms.ToArray());
// data = Authenticator.ByteArrayToString(ms.ToArray());
// }
// string encryptedTypes;
// data = Authenticator.EncryptSequence(data, PasswordType, Password, out encryptedTypes);
// writer.WriteAttributeString("encrypted", encryptedTypes);
// writer.WriteString(data);
// writer.WriteEndElement();
// return;
//}
writer.WriteStartElement("name");
writer.WriteValue(this.Name ?? string.Empty);
writer.WriteEndElement();
writer.WriteStartElement("created");
writer.WriteValue(Convert.ToInt64((this.Created.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalMilliseconds));
writer.WriteEndElement();
writer.WriteStartElement("autorefresh");
writer.WriteValue(this.AutoRefresh);
writer.WriteEndElement();
//
writer.WriteStartElement("allowcopy");
writer.WriteValue(this.AllowCopy);
writer.WriteEndElement();
//
writer.WriteStartElement("copyoncode");
writer.WriteValue(this.CopyOnCode);
writer.WriteEndElement();
//
writer.WriteStartElement("hideserial");
writer.WriteValue(this.HideSerial);
writer.WriteEndElement();
//
// save the authenticator to the config file
if (this.AuthenticatorData != null)
{
this.AuthenticatorData.WriteToWriter(writer);
// save script with password and generated salt
//if (this.AutoLogin != null)
//{
// this.AutoLogin.WriteXmlString(writer, this.AuthenticatorData.PasswordType, this.AuthenticatorData.Password);
//}
}
writer.WriteEndElement();
}
/// <summary>
/// Create a KeyUriFormat compatible URL
/// See https://code.google.com/p/google-authenticator/wiki/KeyUriFormat
/// </summary>
/// <returns>string</returns>
public virtual string ToUrl(bool compat = false)
{
string type = "totp";
string extraparams = string.Empty;
Match match;
string issuer = this.AuthenticatorData.Issuer;
string label = this.Name;
if (string.IsNullOrEmpty(issuer) == true && (match = Regex.Match(label, @"^([^\(]+)\s+\((.*?)\)(.*)")).Success == true)
{
issuer = match.Groups[1].Value;
label = match.Groups[2].Value + match.Groups[3].Value;
}
if (string.IsNullOrEmpty(issuer) == false && (match = Regex.Match(label, @"^" + issuer + @"\s+\((.*?)\)(.*)")).Success == true)
{
label = match.Groups[1].Value + match.Groups[2].Value;
}
if (string.IsNullOrEmpty(issuer) == false)
{
extraparams += "&issuer=" + HttpUtility.UrlEncode(issuer);
}
if (this.AuthenticatorData.HMACType != Authenticator.DEFAULT_HMAC_TYPE)
{
extraparams += "&algorithm=" + this.AuthenticatorData.HMACType.ToString();
}
if (this.AuthenticatorData is BattleNetAuthenticator)
{
extraparams += "&serial=" + HttpUtility.UrlEncode(((BattleNetAuthenticator)this.AuthenticatorData).Serial.Replace("-", ""));
}
else if (this.AuthenticatorData is SteamAuthenticator)
{
if (compat == false)
{
extraparams += "&deviceid=" + HttpUtility.UrlEncode(((SteamAuthenticator)this.AuthenticatorData).DeviceId);
extraparams += "&data=" + HttpUtility.UrlEncode(((SteamAuthenticator)this.AuthenticatorData).SteamData);
}
}
else if (this.AuthenticatorData is HOTPAuthenticator)
{
type = "hotp";
extraparams += "&counter=" + ((HOTPAuthenticator)this.AuthenticatorData).Counter;
}
string secret = HttpUtility.UrlEncode(Base32.getInstance().Encode(this.AuthenticatorData.SecretKey));
if (this.AuthenticatorData.Period != Authenticator.DEFAULT_PERIOD)
{
extraparams += "&period=" + this.AuthenticatorData.Period;
}
var url = string.Format("otpauth://" + type + "/{0}?secret={1}&digits={2}{3}",
(string.IsNullOrEmpty(issuer) == false ? HttpUtility.UrlPathEncode(issuer) + ":" + HttpUtility.UrlPathEncode(label) : HttpUtility.UrlPathEncode(label)),
secret,
this.AuthenticatorData.CodeDigits,
extraparams);
return url;
}
}
/// <summary>
/// Delegate for ConfigChange event
/// </summary>
/// <param name="source"></param>
/// <param name="args"></param>
public delegate void WinAuthAuthenticatorChangedHandler(WinAuthAuthenticator source, WinAuthAuthenticatorChangedEventArgs args);
/// <summary>
/// Change event arguments
/// </summary>
public class WinAuthAuthenticatorChangedEventArgs : EventArgs
{
public string Property { get; private set; }
public Authenticator Authenticator { get; private set; }
/// <summary>
/// Default constructor
/// </summary>
public WinAuthAuthenticatorChangedEventArgs(string property = null, Authenticator authenticator = null)
{
Property = property;
Authenticator = authenticator;
}
}
}
+2 -2
View File
@@ -13,12 +13,12 @@ namespace SteamTool.Proxy
public static string GetPublicPemCertificateString(this X509Certificate2 @this)
{
StringBuilder builder = new StringBuilder();
builder.AppendLine(Const.HostTag);
builder.AppendLine(Const.HOST_TAG);
builder.AppendLine("-----BEGIN CERTIFICATE-----");
builder.AppendLine(
Convert.ToBase64String(@this.RawData, Base64FormattingOptions.InsertLineBreaks));
builder.AppendLine("-----END CERTIFICATE-----");
builder.AppendLine(Const.HostTag);
builder.AppendLine(Const.HOST_TAG);
return builder.ToString();
}
+6 -6
View File
@@ -13,7 +13,7 @@ namespace SteamTool.Core
{
public class HostsService
{
public readonly static string HostsPath = $@"{Environment.GetFolderPath(Environment.SpecialFolder.System)}\drivers\etc\hosts";
public readonly static string HostsPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.System)}\\drivers\\etc\\hosts";
public OperationResult<List<string>> ReadHostsAllLines()
@@ -74,7 +74,7 @@ namespace SteamTool.Core
try
{
dataLines.Add($"{ip} {domain} {Const.HostTag}");
dataLines.Add($"{ip} {domain} {Const.HOST_TAG}");
File.WriteAllLines(HostsPath, dataLines);
//File.SetAttributes(HostsPath, FileAttributes.ReadOnly);
@@ -95,7 +95,7 @@ namespace SteamTool.Core
{
var result = new OperationResult(OperationResultType.Error, Resources.Hosts_WirteError);
if (hosts.Count == 0)
if (hosts.Count == 0)
{
return result;
}
@@ -128,7 +128,7 @@ namespace SteamTool.Core
foreach (var (ip, domain) in hosts)
{
dataLines.Add($"{ip} {domain} {Const.HostTag}");
dataLines.Add($"{ip} {domain} {Const.HOST_TAG}");
}
try
{
@@ -205,7 +205,7 @@ namespace SteamTool.Core
{
if (!temp[0].StartsWith("#"))
{
return !temp.Contains(Const.HostTag);
return !temp.Contains(Const.HOST_TAG);
}
}
return true;
@@ -228,7 +228,7 @@ namespace SteamTool.Core
return result;
}
public void StartNotepadEditHosts()
public void StartNotepadEditHosts()
{
System.Diagnostics.Process.Start("notepad.exe", HostsPath);
}
+13 -14
View File
@@ -35,6 +35,8 @@ namespace SteamTool.Core
public string SteamExePath { get; set; }
public const string UserDataDirectory = @"\userdata";
public const string UserVdfPath = @"\config\loginusers.vdf";
private const string SteamRegistryPath = @"SOFTWARE\Valve\Steam";
@@ -60,7 +62,7 @@ namespace SteamTool.Core
Process[] processes = Process.GetProcesses();
foreach (Process process in processes)
{
if (process.ProcessName.ToLower() == "steam" || process.ProcessName.ToLower() == "steamService" || process.ProcessName.ToLower() == "steamwebhelper")
if (process.ProcessName.Equals("steam", StringComparison.OrdinalIgnoreCase) || process.ProcessName.Equals("steamService", StringComparison.OrdinalIgnoreCase) || process.ProcessName.Equals("steamwebhelper", StringComparison.OrdinalIgnoreCase))
{
process.Kill();
}
@@ -134,7 +136,6 @@ namespace SteamTool.Core
registryKeyService.AddOrUpdateRegistryKey(Registry.CurrentUser, SteamRegistryPath, "AutoLoginUser", username, RegistryValueKind.String);
}
public List<SteamApp> GetAppListJson(string filepath)
{
if (!File.Exists(filepath))
@@ -154,7 +155,6 @@ namespace SteamTool.Core
return apps.AppList.Apps;
}
public bool UpdateAppListJson(List<SteamApp> apps, string filepath)
{
var json = JsonConvert.SerializeObject(apps);
@@ -184,28 +184,17 @@ namespace SteamTool.Core
return true;
}
public void SetWindowsStartupAutoRun(bool IsAutoRun, string Name = "Steam++")
{
// Get the service on the local machine
if (IsAutoRun)
{
using TaskDefinition td = TaskService.Instance.NewTask();
// Create a new task definition and assign properties
td.RegistrationInfo.Description = Name + "System Boot Run";
td.Settings.Priority = System.Diagnostics.ProcessPriorityClass.Normal;
// Create a trigger that will fire after the system boot
td.Triggers.Add(new LogonTrigger());
// Create an action that will launch Notepad whenever the trigger fires
td.Actions.Add(new ExecAction(Assembly.GetCallingAssembly().Location, "-minimized", Path.GetDirectoryName(Assembly.GetCallingAssembly().Location)));
if (IsAdministrator)
td.Principal.RunLevel = TaskRunLevel.Highest;
// Register the task in the root folder
TaskService.Instance.RootFolder.RegisterTaskDefinition(Name, td);
//TaskService.Instance.RootFolder.AddTask(Name, QuickTriggerType.Boot, Assembly.GetCallingAssembly().Location, "-a");
}
@@ -214,5 +203,15 @@ namespace SteamTool.Core
TaskService.Instance.RootFolder.DeleteTask(Name);
}
}
public void DeleteSteamLocalUserData(SteamUser user)
{
vdfService.DeleteVdfValueByKey(SteamPath + UserVdfPath, user.SteamId64.ToString());
var temp = SteamPath + Path.Combine(UserDataDirectory, user.SteamId3_Int.ToString());
if (Directory.Exists(temp))
{
Directory.Delete(temp, true);
}
}
}
}
+17 -5
View File
@@ -1,23 +1,23 @@
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;
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)
public VProperty GetVdfModel(string text)
{
return VdfConvert.Deserialize(text);
}
@@ -29,8 +29,20 @@ namespace SteamTool.Core
/// <returns></returns>
public dynamic GetVdfModelByPath(string path)
{
string text = File.ReadAllText(path,Encoding.UTF8);
return GetVdfModel(text); ;
string text = File.ReadAllText(path, Encoding.UTF8);
return GetVdfModel(text);
}
public void DeleteVdfValueByKey(string path, string key)
{
string text = File.ReadAllText(path, Encoding.UTF8);
//如此实现的功能非常简单,但是应付嵌套的格式时会有问题
var index = text.IndexOf($"\"{key}\"");
var lastIndex = text.IndexOf('}', index);
text = text.Remove(index, lastIndex - index + 1);
//Debug.WriteLine(text);
File.WriteAllText(path, text, Encoding.UTF8);
}
}
}
+8 -2
View File
@@ -7,8 +7,14 @@ namespace SteamTool.Model
public const string APP_LIST_FILE = "apps.json";
public const string SETTINGS_FILE = "settings.json";
public const string SCRIPT_DIR = "scripts";
public const string HostTag = "#S302";
public const string HOST_TAG = "#S302";
public const string REWARDMELIST_URL = "https://gitee.com/rmbgame/steam-tools_-data/raw/master/RewardRecord.json";
//public const string REWARDMELIST_URL = "https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/Data/RewardRecord.json";
public const string GITHUB_RELEASEAPI_URL = "https://api.github.com/repos/rmbadmin/SteamTools/releases/latest";
public const string GITHUB_URL = "https://github.com/rmbadmin/SteamTools";
public const string GITHUB_RELEASES_URL = "https://github.com/rmbadmin/SteamTools/releases";
public const string MY_PROFILE_URL = "https://steamcommunity.com/profiles/76561198289531723/";
public const string MY_WISHLIST_URL = "https://store.steampowered.com/wishlist/profiles/76561198289531723/";
public const string MY_MINIPROFILE_URL = "https://steamcommunity.com/miniprofile/329265995";
@@ -27,7 +33,7 @@ namespace SteamTool.Model
public const string STEAM_INSTALL_URL = "steam://install/{0}";
public const string STEAM_RUNGAME_URL = "steam://rungameid/{0}";
public const string STEAM_OPENURL = "steam://openurl/{0}";
public const string STEAM_RUN_KeyURL = "steam://openurl/https://store.steampowered.com/account/registerkey?key={0}";
public const string STEAM_RUN_KEYURL = "steam://openurl/https://store.steampowered.com/account/registerkey?key={0}";
public const string STEAMDB_USERINFO_URL = "https://api.steamdb.ml/v1/users/{0}";
public const string STEAMDB_APPINFO_URL = "https://api.steamdb.ml/v1/apps/{0}";
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SteamTool.Model.ToolModel
{
public class GithubReleaseModel
{
public string id { get; set; }
public string html_url { get; set; }
public string tag_name { get; set; }
public Version version => new Version(tag_name);
public string target_commitish { get; set; }
public string created_at { get; set; }
public string published_at { get; set; }
public List<Assets> assets { get; set; }
public string body { get; set; }
}
public class Assets
{
public string id { get; set; }
public string url { get; set; }
public string name { get; set; }
public string content_type { get; set; }
public string size { get; set; }
public string download_count { get; set; }
public string updated_at { get; set; }
public string browser_download_url { get; set; }
}
}
+55 -38
View File
@@ -13,6 +13,7 @@ using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Models;
using SteamTool.Model;
using System.Security.Cryptography;
namespace SteamTool.Proxy
{
@@ -38,6 +39,7 @@ namespace SteamTool.Proxy
public async Task OnRequest(object sender, SessionEventArgs e)
{
#if DEBUG
#region 测试用
/*
if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains("steampowered.com"))
@@ -61,7 +63,6 @@ namespace SteamTool.Proxy
}
*/
#endregion
#if DEBUG
Debug.WriteLine("OnRequest" + e.HttpClient.Request.RequestUri.AbsoluteUri);
#endif
foreach (var item in ProxyDomains)
@@ -107,6 +108,7 @@ namespace SteamTool.Proxy
}
}
}
//GC.Collect();
}
public async Task OnResponse(object sender, SessionEventArgs e)
{
@@ -164,7 +166,7 @@ namespace SteamTool.Proxy
//e.HttpClient.Response.Headers.AddHeader("Content-Security-Policy", result);
}
#if DEBUG
Debug.WriteLine(t);
Debug.WriteLine(e.HttpClient.Request.RequestUri.AbsoluteUri);
#endif
foreach (var req in script.Require)
{
@@ -237,25 +239,58 @@ namespace SteamTool.Proxy
{
if (ProxyRunning)
return false;
using (var store = new X509Store(StoreName.Root, StoreLocation.CurrentUser))
try
{
store.Open(OpenFlags.MaxAllowed);
//var test = store.Certificates.Find(X509FindType.FindByIssuerName, "titan", true);
var test = store.Certificates.Find(X509FindType.FindByIssuerName, CertificateName, true);
foreach (var item in test)
using (var store = new X509Store(StoreName.Root, StoreLocation.CurrentUser))
{
store.Remove(item);
store.Open(OpenFlags.MaxAllowed);
//var test = store.Certificates.Find(X509FindType.FindByIssuerName, "titan", true);
var test = store.Certificates.Find(X509FindType.FindByIssuerName, CertificateName, true);
foreach (var item in test)
{
store.Remove(item);
}
//if (store.Certificates.Contains(proxyServer.CertificateManager.RootCertificate))
// store.Remove(proxyServer.CertificateManager.RootCertificate);
}
proxyServer.CertificateManager.ClearRootCertificate();
proxyServer.CertificateManager.RemoveTrustedRootCertificate(true);
proxyServer.CertificateManager.RemoveTrustedRootCertificateAsAdmin(true);
proxyServer.CertificateManager.CertificateStorage.Clear();
}
catch (Exception ex)
{
if (ex is CryptographicException)
{
//取消删除证书
}
else
{
throw;
}
//if (store.Certificates.Contains(proxyServer.CertificateManager.RootCertificate))
// store.Remove(proxyServer.CertificateManager.RootCertificate);
}
proxyServer.CertificateManager.ClearRootCertificate();
proxyServer.CertificateManager.RemoveTrustedRootCertificate(true);
proxyServer.CertificateManager.RemoveTrustedRootCertificateAsAdmin(true);
proxyServer.CertificateManager.CertificateStorage.Clear();
return true;
}
public static bool PortInUse(int port)
{
bool inUse = false;
var ipProperties = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties();
IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();
foreach (IPEndPoint endPoint in ipEndPoints)
{
if (endPoint.Port == port)
{
inUse = true;
break;
}
}
return inUse;
}
public bool StartProxy(bool IsProxyGOG = false)
{
if (!IsCertificateInstalled(proxyServer.CertificateManager.RootCertificate))
@@ -265,10 +300,10 @@ namespace SteamTool.Proxy
{
return false;
}
if (PortInUse(443))
{
return false;
}
}
if (PortInUse(443))
{
return false;
}
if (IsProxyGOG) { WirtePemCertificateToGoGSteamPlugins(); }
@@ -335,24 +370,6 @@ namespace SteamTool.Proxy
return true;
}
public static bool PortInUse(int port)
{
bool inUse = false;
var ipProperties = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties();
IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();
foreach (IPEndPoint endPoint in ipEndPoints)
{
if (endPoint.Port == port)
{
inUse = true;
break;
}
}
return inUse;
}
public void StopProxy()
{
@@ -382,14 +399,14 @@ namespace SteamTool.Proxy
if (File.Exists(certifi))
{
var file = File.ReadAllText(certifi);
var s = file.Substring(Const.HostTag, Const.HostTag, true);
var s = file.Substring(Const.HOST_TAG, Const.HOST_TAG, true);
if (string.IsNullOrEmpty(s))
{
File.AppendAllText(certifi, "\r\n" + pem);
}
else if (s.Trim() != pem.Trim())
{
var index = file.IndexOf(Const.HostTag);
var index = file.IndexOf(Const.HOST_TAG);
File.WriteAllText(certifi, file.Remove(index, s.Length) + pem);
}
return true;
@@ -80,5 +80,7 @@ namespace SteamTool.Proxy
GoogleCode = 8,
[Description("GOG.COM")]
GOG = 8,
[Description("Github图片修复")]
GithubContent = 9,
}
}
+9
View File
@@ -69,6 +69,15 @@ namespace SteamTool.Proxy.Properties {
}
}
/// <summary>
/// 查找类似 Github图片资源修复 的本地化字符串。
/// </summary>
public static string GithubContent {
get {
return ResourceManager.GetString("GithubContent", resourceCulture);
}
}
/// <summary>
/// 查找类似 GOG Galaxy 的本地化字符串。
/// </summary>
@@ -120,6 +120,9 @@
<data name="Discord" xml:space="preserve">
<value>Discord语音</value>
</data>
<data name="GithubContent" xml:space="preserve">
<value>Github图片资源修复</value>
</data>
<data name="GOG" xml:space="preserve">
<value>GOG Galaxy</value>
</data>
-14
View File
@@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SteamTool.Composition.Interface
{
[PluginFeature]
public interface ITool
{
string Name { get; }
object View { get; }
}
}
@@ -1,9 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SteamTool.Composition
{
[AttributeUsage(AttributeTargets.Interface)]
public sealed class PluginFeatureAttribute : Attribute { }
}
@@ -1,10 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Configurations>Debug;Release;发布</Configurations>
<LangVersion>8.0</LangVersion>
<Platforms>AnyCPU;x86</Platforms>
</PropertyGroup>
</Project>
+1 -1
View File
@@ -11,7 +11,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamTool.Proxy", "SteamToo
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Composition", "Composition", "{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", "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}"
EndProject
+8 -8
View File
@@ -32,7 +32,7 @@ namespace SteamTools
public static App Instance => Current as App;
public DirectoryInfo LocalAppData = new DirectoryInfo(
Path.Combine(
Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
ProductInfo.Company,
ProductInfo.Product));
@@ -83,16 +83,16 @@ namespace SteamTools
this.compositeDisposable.Add(ProxyService.Current.Shutdown);
this.compositeDisposable.Add(SteamConnectService.Current.Shutdown);
//托盘加载
GeneralSettings.Culture.Subscribe(x => ResourceService.Current.ChangeCulture(x)).AddTo(this);
WindowService.Current.AddTo(this).Initialize();
ProxyService.Current.Initialize();
SteamConnectService.Current.Initialize();
//托盘加载
TaskbarService.Current.Taskbar = (TaskbarIcon)FindResource("Taskbar");
ThemeService.Current.Register(this, Theme.Windows, Accent.Windows);
this.MainWindow = WindowService.Current.GetMainWindow();
if (e.Args.ContainsArg("-minimized"))
if (e.Args.ContainsArg("-minimized") || GeneralSettings.IsStartupAppMinimized.Value)
(WindowService.Current.MainWindow as MainWindowViewModel).Initialize();
else
this.MainWindow.Show();
@@ -102,7 +102,7 @@ namespace SteamTools
{
// 检测到多次启动时将主窗口置于最前面
this.Dispatcher.Invoke(() => WindowService.Current.MainWindow.Activate());
//this.ProcessCommandLineParameter(args.CommandLineArgs);
this.ProcessCommandLineParameter(args.CommandLineArgs);
};
#endif
@@ -155,10 +155,10 @@ namespace SteamTools
{
Debug.WriteLine("多重启动通知: " + args.ToString(" "));
// 当使用命令行参数多次启动时,您可以执行某些操作
//if (args.Length == 0)
//{
// this.Shutdown();
//}
if (args.Length == 0)
{
this.Shutdown();
}
if (args.ContainsArg("-log"))
{
Logger.EnableTextLog = true;
+7 -2
View File
@@ -18,6 +18,7 @@ namespace SteamTools.Models
private static readonly Lazy<string> versionLazy = new Lazy<string>(() => $"{Version.ToString(3)}{(IsBetaRelease ? " β" : "")}{(Version.Revision == 0 ? "" : " rev." + Version.Revision)}");
private static readonly Lazy<IReadOnlyCollection<Library>> librariesLazy = new Lazy<IReadOnlyCollection<Library>>(() => new List<Library>
{
new Library("Newtonsoft.Json", new Uri("https://github.com/JamesNK/Newtonsoft.Json")),
new Library("MetroRadiance", new Uri("https://github.com/Grabacr07/MetroRadiance")),
new Library("MetroTrilithon", new Uri("https://github.com/Grabacr07/MetroTrilithon")),
new Library("Livet", new Uri("https://github.com/runceel/Livet")),
@@ -25,11 +26,15 @@ namespace SteamTools.Models
new Library("Hardcodet.NotifyIcon", new Uri("https://github.com/HavenDV/Hardcodet.NotifyIcon.Wpf.NetCore")),
new Library("System.Reactive", new Uri("https://github.com/dotnet/reactive")),
new Library("Titanium-Web-Proxy", new Uri("https://github.com/justcoding121/Titanium-Web-Proxy")),
new Library("Ninject", new Uri("http://www.ninject.org/")),
new Library("log4net", new Uri("https://logging.apache.org/log4net/")),
new Library("Ninject", new Uri("https://github.com/ninject/Ninject")),
new Library("log4net", new Uri("https://github.com/apache/logging-log4net")),
new Library("SteamDB-API", new Uri("https://github.com/SteamDB-API/api")),
new Library("SteamAchievementManager", new Uri("https://github.com/gibbed/SteamAchievementManager")),
new Library("ArchiSteamFarm", new Uri("https://github.com/JustArchiNET/ArchiSteamFarm")),
new Library("WinAuth", new Uri("https://github.com/winauth/winauth")),
new Library("SteamDesktopAuthenticator", new Uri("https://github.com/Jessecar96/SteamDesktopAuthenticator")),
new Library("Gameloop.Vdf", new Uri("https://github.com/shravan2x/Gameloop.Vdf")),
new Library("Costura.Fody", new Uri("https://github.com/Fody/Costura")),
//new Library("idle_master_extended", new Uri("https://github.com/JonasNilson/idle_master_extended")),
});
+18 -1
View File
@@ -33,6 +33,12 @@ namespace SteamTools.Models.Settings
public static SerializableProperty<bool> WindowsStartupAutoRun { get; }
= new SerializableProperty<bool>(GetKey(), Providers.Roaming, false) { AutoSave = true };
/// <summary>
/// 程序启动时最小化
/// </summary>
public static SerializableProperty<bool> IsStartupAppMinimized { get; }
= new SerializableProperty<bool>(GetKey(), Providers.Roaming, false) { AutoSave = true };
/// <summary>
/// 是否显示起始页
/// </summary>
@@ -40,11 +46,22 @@ namespace SteamTools.Models.Settings
= new SerializableProperty<bool>(GetKey(), Providers.Roaming, true) { AutoSave = true };
/// <summary>
/// 游戏列表本地缓存
/// 启用游戏列表本地缓存
/// </summary>
public static SerializableProperty<bool> IsSteamAppListLocalCache { get; }
= new SerializableProperty<bool>(GetKey(), Providers.Roaming, true) { AutoSave = true };
/// <summary>
/// Steam启动参数
/// </summary>
public static SerializableProperty<string> SteamStratParameter { get; }
= new SerializableProperty<string>(GetKey(), Providers.Local, string.Empty) { AutoSave = true };
/// <summary>
/// 自动检查更新
/// </summary>
public static SerializableProperty<bool> IsAutoCheckUpdate { get; }
= new SerializableProperty<bool>(GetKey(), Providers.Roaming, true) { AutoSave = true };
private static string GetKey([CallerMemberName] string propertyName = "")
{
+35
View File
@@ -0,0 +1,35 @@
using SteamTool.Core.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SteamTools
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
try
{
if (args.ContainsArg("-log"))
{
Logger.EnableTextLog = true;
}
App app = new App();
app.InitializeComponent();
app.Run();
}
catch (Exception ex)
{
Logger.Error(ex);
}
}
}
}
+28 -1
View File
@@ -78,6 +78,15 @@ namespace SteamTools.Properties {
}
}
/// <summary>
/// 查找类似 捐助纪录 的本地化字符串。
/// </summary>
public static string About_DonateList {
get {
return ResourceManager.GetString("About_DonateList", resourceCulture);
}
}
/// <summary>
/// 查找类似 帮助 的本地化字符串。
/// </summary>
@@ -456,6 +465,15 @@ namespace SteamTools.Properties {
}
}
/// <summary>
/// 查找类似 Github图片资源修复 的本地化字符串。
/// </summary>
public static string GithubContent {
get {
return ResourceManager.GetString("GithubContent", resourceCulture);
}
}
/// <summary>
/// 查找类似 GOG Galaxy 的本地化字符串。
/// </summary>
@@ -655,7 +673,7 @@ namespace SteamTools.Properties {
}
/// <summary>
/// 查找类似 复位成就和/统计 的本地化字符串。
/// 查找类似 复位成就和统计 的本地化字符串。
/// </summary>
public static string OnRest {
get {
@@ -825,6 +843,15 @@ namespace SteamTools.Properties {
}
}
/// <summary>
/// 查找类似 帐户切换设置 的本地化字符串。
/// </summary>
public static string Settings_AccountChange {
get {
return ResourceManager.GetString("Settings_AccountChange", resourceCulture);
}
}
/// <summary>
/// 查找类似 令牌设置 的本地化字符串。
/// </summary>
+10 -1
View File
@@ -126,6 +126,9 @@
<data name="About_Donate" xml:space="preserve">
<value>捐助</value>
</data>
<data name="About_DonateList" xml:space="preserve">
<value>捐助纪录</value>
</data>
<data name="About_Help" xml:space="preserve">
<value>帮助</value>
</data>
@@ -249,6 +252,9 @@
<data name="Game_UnInstall" xml:space="preserve">
<value>未安装</value>
</data>
<data name="GithubContent" xml:space="preserve">
<value>Github图片资源修复</value>
</data>
<data name="GOG" xml:space="preserve">
<value>GOG Galaxy</value>
</data>
@@ -316,7 +322,7 @@
<value>刷新成绩和统计</value>
</data>
<data name="OnRest" xml:space="preserve">
<value>复位成就和/统计</value>
<value>复位成就和统计</value>
</data>
<data name="OnStore" xml:space="preserve">
<value>保存并应用成就和统计</value>
@@ -372,6 +378,9 @@
<data name="Settings_Accent" xml:space="preserve">
<value>颜色</value>
</data>
<data name="Settings_AccountChange" xml:space="preserve">
<value>帐户切换设置</value>
</data>
<data name="Settings_Auth" xml:space="preserve">
<value>令牌设置</value>
</data>
+2 -1
View File
@@ -1,7 +1,8 @@
{
"profiles": {
"SteamTools": {
"commandName": "Project"
"commandName": "Project",
"commandLineArgs": "-log"
}
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 KiB

After

Width:  |  Height:  |  Size: 364 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

+10 -6
View File
@@ -60,15 +60,19 @@ namespace SteamTools.Services
}
}
public AuthService()
public void Initialize()
{
if (!string.IsNullOrEmpty(AuthSettings.Authenticators.Value))
{
Authenticators = new BindingList<WinAuthAuthenticator>(AuthService.LoadJsonAuthenticator(AuthSettings.Authenticators.Value.DecompressString()));
}
else
{
Authenticators = new BindingList<WinAuthAuthenticator>();
try
{
var auths = AuthService.LoadJsonAuthenticator(AuthSettings.Authenticators.Value.DecompressString());
Authenticators = new BindingList<WinAuthAuthenticator>(auths);
}
catch (Exception ex)
{
WindowService.Current.MainWindow.Dialog($"令牌同步服务器失败,错误信息:{ex.Message}");
}
}
}
+96
View File
@@ -0,0 +1,96 @@
using SteamTool.Core;
using SteamTool.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using SteamTool.Model.ToolModel;
using SteamTools.Models;
using SteamTool.Core.Common;
using System.Net;
using System.IO;
using Livet;
using SteamTools.Properties;
namespace SteamTools.Services
{
public class AutoUpdateService : NotificationObject
{
#region static members
public static AutoUpdateService Current { get; } = new AutoUpdateService();
#endregion
private readonly HttpServices httpServices = SteamToolCore.Instance.Get<HttpServices>();
#region 更新进度变更通知
private double _ProgressValue;
public double ProgressValue
{
get => this._ProgressValue;
set
{
if (this._ProgressValue != value)
{
this._ProgressValue = value;
this.RaisePropertyChanged();
}
}
}
#endregion
public async void CheckUpdate()
{
try
{
StatusService.Current.Notify("正在从Github检查更新...");
var result = await httpServices.Get(Const.GITHUB_RELEASEAPI_URL);
var model = JsonConvert.DeserializeObject<GithubReleaseModel>(result);
if (!(ProductInfo.Version < model.version))
{
StatusService.Current.Notify("当前已是最新版本");
return;
}
if (WindowService.Current.MainWindow.Dialog($"检测到新版本更新内容:{model.body}\r\n是否立即更新?", $"{ProductInfo.Title} | 更新提示") == true)
{
//var name = model.assets.FirstOrDefault()?.name;
var name = Path.Combine(AppContext.BaseDirectory, @$"{ProductInfo.Title} {model.version}.zip");
if (File.Exists(name))
{
StatusService.Current.Notify("更新文件已经存在,不需要下载");
return;
}
var fileReq = WebRequest.Create(model.assets.FirstOrDefault()?.browser_download_url);
await fileReq?.GetResponseAsync().ContinueWith(s =>
{
long totalBytes = s.Result.ContentLength;
using Stream responseStream = s.Result.GetResponseStream();
using FileStream fileStream = new FileStream(name, FileMode.Create, FileAccess.Write);
long totalDownloadBytes = 0;
byte[] bs = new byte[4096];
int size = responseStream.Read(bs, 0, bs.Length);
while (size > 0)
{
totalDownloadBytes += size;
fileStream.Write(bs, 0, size);
ProgressValue = ((double)totalDownloadBytes / (double)totalBytes);
StatusService.Current.Set($"下载更新{ProgressValue.ToString("P")}");
size = responseStream.Read(bs, 0, bs.Length);
}
fileStream.Flush();
fileStream.Close();
StatusService.Current.Set(Resources.Ready);
StatusService.Current.Notify($"{ProductInfo.Title} {model.version}版本已经下载到程序根目录下,暂时请手动替换更新");
});
}
}
catch (Exception ex)
{
Logger.Error("更新出错:", ex);
WindowService.Current.MainWindow.Dialog($"更新出错:{ex.Message}");
}
}
}
}
+97 -69
View File
@@ -10,17 +10,20 @@ using System.IO;
using SteamTool.Model;
using SteamTools.Models;
using SteamTools.Models.Settings;
using SteamTool.Core;
namespace SteamTools.Services
{
public class ProxyService : NotificationObject
{
public static ProxyService Current { get; } = new ProxyService();
private readonly HostsService hostsService = new HostsService();
public HttpProxy Proxy { get; set; }
public void Initialize()
{
//启动时恢复host
hostsService.RemoveHostsByTag();
if (ProxySettings.SupportProxyServicesStatus.Value.Count > 0)
{
foreach (var item in ProxyDomains.Value)
@@ -33,6 +36,11 @@ namespace SteamTools.Services
}
Proxy = new HttpProxy(ProxyDomains.Value, ProductInfo.Product);
InitJsScript();
Proxy.IsEnableScript = IsEnableScript;
if (ProxySettings.ProgramStartupRunProxy.Value)
{
ProxyStatus = true;
}
}
private Lazy<IReadOnlyCollection<ProxyDomainModel>> _ProxyDomains = new Lazy<IReadOnlyCollection<ProxyDomainModel>>(() => new List<ProxyDomainModel>
@@ -73,43 +81,43 @@ namespace SteamTools.Services
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=4,
Name=Resources.Discord,
Domains = new List<string>{ "discordapp.com","discordapp.net" },
//ToDomain = "discord.com",
ProxyIPAddres="162.159.130.232",
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" },
Domains = new List<string>{ "twitch.tv" ,"usher.ttvnw.net"},
ToDomain="twitch.map.fastly.net",
Hosts = new List<string>{
"twitch.tv",
@@ -150,7 +158,7 @@ namespace SteamTools.Services
"irc-ws.chat.twitch.tv",
"irc-ws-r.chat.twitch.tv",
//"platform.twitter.com",
//"usher.ttvnw.net",
"usher.ttvnw.net",
},
DomainTag = DomainTag.Twitch,
IsEnable= false,
@@ -172,39 +180,39 @@ namespace SteamTools.Services
// 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=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,
@@ -214,6 +222,26 @@ namespace SteamTools.Services
DomainTag = DomainTag.GoogleCode,
IsEnable= false,
},
new ProxyDomainModel{
Index=9,
Name=Resources.GithubContent,
Domains = new List<string>{"githubusercontent.com","raw.github.com" },
//ToDomain = "github.map.fastly.net",
ProxyIPAddres = "151.101.88.133",
Hosts = new List<string>{
"raw.github.com",
"raw.githubusercontent.com",
"camo.githubusercontent.com",
"cloud.githubusercontent.com",
"avatars0.githubusercontent.com",
"avatars1.githubusercontent.com",
"avatars2.githubusercontent.com",
"avatars3.githubusercontent.com",
"user-images.githubusercontent.com",
},
DomainTag = DomainTag.GithubContent,
IsEnable= false,
},
});
public Lazy<IReadOnlyCollection<ProxyDomainModel>> ProxyDomains
{
+8 -6
View File
@@ -96,22 +96,24 @@ namespace SteamTools.Services
{
Task.Run(async () =>
{
Thread.CurrentThread.IsBackground = true;
while (true)
{
if (Process.GetProcessesByName("steam").Length > 0)
{
if (!IsConnectToSteam)
{
IsConnectToSteam = ApiService.Initialize();
if (IsConnectToSteam)
if (ApiService.Initialize())
{
var id = ApiService.GetSteamId64();
if (id == 76561197960265728)
{
//该64位id的steamID3等于0,是steam未获取到当前登录用户的默认返回值,所以直接重新获取
IsConnectToSteam = false;
//该64位id的steamID3等于0,是steam未获取到当前登录用户的默认返回值,所以直接重新获取,
//希望这位用户不会用steam++,嗯...
ApiService.SteamClient.Dispose();
continue;
}
IsConnectToSteam = true;
CurrentSteamUser = await steamDbApiService.GetUserInfo(id);
var mainViewModel = (WindowService.Current.MainWindow as MainWindowViewModel);
mainViewModel.SteamAppPage.Initialize();
@@ -126,9 +128,9 @@ namespace SteamTools.Services
IsConnectToSteam = false;
//StatusService.Current.Notify(Resources.Steam_Not_Runing);
}
await Task.Delay(1000);
await Task.Delay(1500);
}
});
}).ContinueWith(s => { Logger.Error(s.Exception); WindowService.Current.ShowDialogWindow(s.Exception.Message); }, TaskContinuationOptions.OnlyOnFaulted);
}
public void Initialize(int appid)
+3 -3
View File
@@ -55,12 +55,12 @@ namespace SteamTools.Services
throw new InvalidOperationException();
}
public DialogWindowViewModel ShowDialogWindow(string content)
public bool ShowDialogWindow(string content)
{
return ShowDialogWindow(content, ProductInfo.Title);
}
public DialogWindowViewModel ShowDialogWindow(string content, string title)
public bool ShowDialogWindow(string content, string title)
{
var dialog = new DialogWindowViewModel
{
@@ -70,7 +70,7 @@ namespace SteamTools.Services
var window = new MessageDialog { DataContext = dialog };
window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
window.ShowDialog();
return dialog;
return dialog.DialogResult;
}
#region disposable members
+18 -5
View File
@@ -32,13 +32,15 @@
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<Description>Steam++</Description>
<Description>「Steam++」是一个包含多种Steam工具功能的工具箱。</Description>
<Platforms>AnyCPU;x86</Platforms>
<Product>SteamTools</Product>
<PackageId />
<Version>1.0.2</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net472|AnyCPU'">
@@ -109,7 +111,7 @@
<None Remove="Resources\Asstes\save.png" />
<None Remove="Resources\Asstes\seek.png" />
<None Remove="Resources\Asstes\unlock.png" />
<None Remove="Resources\Asstes\wechatpay.png" />
<None Remove="Resources\Asstes\wechatdonate.png" />
</ItemGroup>
<ItemGroup>
@@ -137,7 +139,7 @@
<Resource Include="Resources\Asstes\save.png" />
<Resource Include="Resources\Asstes\seek.png" />
<Resource Include="Resources\Asstes\unlock.png" />
<Resource Include="Resources\Asstes\wechatpay.png" />
<Resource Include="Resources\Asstes\wechatdonate.png" />
</ItemGroup>
<ItemGroup>
@@ -237,6 +239,10 @@
<Page Update="Resources\Styles\Controls.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Views\Content\About\AboutDonateList.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
</Page>
<Page Update="Views\Content\About\AboutUpdateHistory.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
@@ -310,8 +316,7 @@
<ProjectReference Include="..\SteamTool.Authenticator\SteamTool.Authenticator.csproj" />
<ProjectReference Include="..\SteamTool.Core\SteamTool.Core.csproj" />
<ProjectReference Include="..\SteamTool.Proxy\SteamTool.Proxy.csproj" />
<ProjectReference Include="..\SteamTools.Composition\SteamTool.Composition.csproj" />
<ProjectReference Include="..\SteamTools.Steam.Service\SteamTool.Steam.Service.csproj" />
<ProjectReference Include="..\SteamTool.Steam.Service\SteamTool.Steam.Service.csproj" />
</ItemGroup>
<ItemGroup>
@@ -330,6 +335,9 @@
<Reference Include="MetroTrilithon.Desktop">
<HintPath>..\Lib\MetroTrilithon.Desktop.dll</HintPath>
</Reference>
<Reference Include="SimpleSyndicate.UriTemplate">
<HintPath>..\Lib\SimpleSyndicate.UriTemplate.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@@ -346,8 +354,13 @@
<None Update="scripts\Steam自动探索队列.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="scripts\Steam解锁不可描述游戏商店页.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="scripts\Steam解锁区域限制.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ProjectExtensions><VisualStudio><UserProperties /></VisualStudio></ProjectExtensions>
</Project>
@@ -0,0 +1,66 @@
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.Core;
using System.IO;
using SteamTools.Properties;
using SteamTool.Model;
using Newtonsoft.Json;
using System.Threading;
namespace SteamTools.ViewModels
{
public class AboutDonateListViewModel : Livet.ViewModel
{
private readonly HttpServices httpServices = SteamToolCore.Instance.Get<HttpServices>();
public class DonateRecord
{
public long Index { get; set; }
public string Name { get; set; }
public decimal Amount { get; set; }
public string OrderNumber { get; set; }
public string Remark { get; set; }
public short PayType { get; set; }
public DateTime PayTime { get; set; }
}
private List<DonateRecord> _DonateRecordList;
public List<DonateRecord> DonateRecordList
{
get => this._DonateRecordList;
set
{
if (this._DonateRecordList != value)
{
this._DonateRecordList = value;
this.RaisePropertyChanged();
}
}
}
public AboutDonateListViewModel()
{
Task.Run(() =>
{
httpServices.Get(Const.REWARDMELIST_URL).ContinueWith(s =>
{
if (!string.IsNullOrEmpty(s.Result))
{
DonateRecordList = JsonConvert.DeserializeObject<List<DonateRecord>>(s.Result);
}
});
});
}
}
}
@@ -69,7 +69,7 @@ namespace SteamTools.ViewModels
}
p.Close();
standardOutput.Close();
});
}).ContinueWith(s => { Logger.Error(s.Exception); WindowService.Current.ShowDialogWindow(s.Exception.Message); }, TaskContinuationOptions.OnlyOnFaulted);
}
}
}
@@ -33,7 +33,7 @@ namespace SteamTools.ViewModels
{
if (IsRefreshGameListCache)
{
StatusService.Current.Notify("正在下在Steam游戏数据中...");
StatusService.Current.Notify("正在下载Steam游戏数据中...");
return;
}
StatusService.Current.Notify("刷新Steam游戏数据");
@@ -47,7 +47,7 @@ namespace SteamTools.ViewModels
apps = apps.DistinctBy(d => d.AppId).ToList();
//SteamConnectService.Current.SteamApps = apps;
SteamConnectService.Current.SteamApps = SteamConnectService.Current.ApiService.OwnsApps(apps);
}).ContinueWith(s =>
}).ContinueWith(s => { Logger.Error(s.Exception); WindowService.Current.ShowDialogWindow(s.Exception.Message); }, TaskContinuationOptions.OnlyOnFaulted).ContinueWith(s =>
{
StatusService.Current.Notify("刷新Steam游戏数据完成");
IsRefreshGameListCache = false;
@@ -60,5 +60,10 @@ namespace SteamTools.ViewModels
StatusService.Current.Notify("未检测到Steam运行");
}
}
public void CheckUpdate_Click()
{
AutoUpdateService.Current.CheckUpdate();
}
}
}
+13 -10
View File
@@ -14,6 +14,8 @@ using System.Windows.Interop;
using SteamTools.Services;
using SteamTools.Properties;
using MetroRadiance.Interop.Win32;
using SteamTool.Core.Common;
using SteamTools.Models.Settings;
namespace SteamTools.ViewModels
{
@@ -70,8 +72,8 @@ namespace SteamTools.ViewModels
ChangeWindowVisible();
if (value)
{
App.Current.MainWindow.Topmost = true;
App.Current.MainWindow.WindowState = WindowState.Normal;
App.Current.MainWindow.Topmost = true;
User32Window.FlashWindow(new WindowInteropHelper(App.Current.MainWindow).Handle);
App.Current.MainWindow.Topmost = false;
}
@@ -131,13 +133,13 @@ namespace SteamTools.ViewModels
continue;
item.Initialize();
}
}).ContinueWith(s => s.Dispose());
//foreach (var item in this.TabItems)
//{
// if (item == SteamAppPage)
// continue;
// item.Initialize();
//}
}).ContinueWith(s => { Logger.Error(s.Exception); WindowService.Current.ShowDialogWindow(s.Exception.Message); }, TaskContinuationOptions.OnlyOnFaulted)
.ContinueWith(s => s.Dispose());
AuthService.Current.Initialize();
if (GeneralSettings.IsAutoCheckUpdate)
{
AutoUpdateService.Current.CheckUpdate();
}
StatusService.Current.Set(Resources.Ready);
this.IsInitialized = true;
}
@@ -152,14 +154,15 @@ namespace SteamTools.ViewModels
if (IsVisible)
{
App.Current.MainWindow.Show();
//App.Current.MainWindow.Focus();
App.Current.MainWindow.WindowState = WindowState.Normal;
App.Current.MainWindow.Activate();
User32Window.FlashWindow(new WindowInteropHelper(App.Current.MainWindow).Handle);
}
else
{
App.Current.MainWindow.WindowState = WindowState.Minimized;
//App.Current.MainWindow.WindowState = WindowState.Minimized;
App.Current.MainWindow.Hide();
App.Current.MainWindow.Visibility = Visibility.Collapsed;
}
}
}
@@ -26,14 +26,6 @@ namespace SteamTools.ViewModels
protected set { throw new NotImplementedException(); }
}
internal override void Initialize()
{
if (ProxySettings.ProgramStartupRunProxy.Value)
{
ProxyService.Current.ProxyStatus = true;
}
}
public void SetupCertificate_OnClick()
{
ProxyService.Current.Proxy.SetupCertificate();
@@ -1,4 +1,5 @@
using MetroRadiance.Platform;
using SteamTool.Core.Common;
using SteamTool.Steam.Service.Local;
using SteamTools.Services;
using System;
@@ -44,6 +45,8 @@ namespace SteamTools.ViewModels
DebugText += Environment.NewLine;
DebugText += SteamConnectService.Current.ApiService.GetSteamId64();
DebugText += Environment.NewLine;
DebugText += SteamConnectService.Current.CurrentSteamUser.SteamId3_Int;
DebugText += Environment.NewLine;
DebugText += SteamConnectService.Current.ApiService.SteamClient.SteamUtils.GetAppId();
DebugText += Environment.NewLine;
DebugText += SteamConnectService.Current.ApiService.SteamClient.SteamApps008.IsAppInstalled(730);
@@ -52,7 +55,7 @@ namespace SteamTools.ViewModels
DebugText += Environment.NewLine;
DebugText += SteamConnectService.Current.ApiService.SteamClient.SteamApps008.GetAppInstallDir(730);
DebugText += Environment.NewLine;
}).ContinueWith(s => s.Dispose());
}).ContinueWith(s => { Logger.Error(s.Exception); WindowService.Current.ShowDialogWindow(s.Exception.Message); }, TaskContinuationOptions.OnlyOnFaulted).ContinueWith(s => s.Dispose());
}
public void Test_OnClick()
@@ -96,15 +96,8 @@ namespace SteamTools.ViewModels
internal override void Initialize()
{
AuthService.Current.Subscribe(nameof(AuthService.Current.Authenticators), this.Update).AddTo(this);
//Task.Run(() =>
//{
//});
}
private void Update()
{
Authenticators = AuthService.Current.Authenticators;
AuthService.Current.Subscribe(nameof(AuthService.Current.Authenticators),
()=> { Authenticators = AuthService.Current.Authenticators; }).AddTo(this);
}
public void AddAuth_Click()
@@ -114,9 +107,10 @@ namespace SteamTools.ViewModels
public void EditAuth_Click()
{
if (Authenticators.Count < 1)
if (Authenticators?.Count < 1)
{
StatusService.Current.Notify("没有可编辑的令牌");
return;
}
this.IsEdit = !IsEdit;
if (!IsEdit)
@@ -13,6 +13,8 @@ using System.Diagnostics;
using SteamTool.Steam.Service.Web;
using SteamTool.Steam.Service;
using SteamTools.Services;
using SteamTool.Core.Common;
using SteamTools.Models.Settings;
namespace SteamTools.ViewModels
{
@@ -30,9 +32,9 @@ namespace SteamTools.ViewModels
/// <summary>
/// steam记住的用户列表
/// </summary>
private List<SteamUser> _steamUsers;
private BindingList<SteamUser> _steamUsers;
public List<SteamUser> SteamUsers
public BindingList<SteamUser> SteamUsers
{
get => this._steamUsers;
set
@@ -50,7 +52,11 @@ namespace SteamTools.ViewModels
StatusService.Current.Notify("加载本地Steam用户数据");
Task.Run(async () =>
{
SteamUsers = steamService.GetAllUser();
SteamUsers = new BindingList<SteamUser>(steamService.GetAllUser());
if (SteamUsers?.Count < 1)
{
StatusService.Current.Notify("没有检测到Steam用户数据");
}
var users = SteamUsers.ToArray();
for (var i = 0; i < SteamUsers.Count; i++)
{
@@ -62,16 +68,9 @@ namespace SteamTools.ViewModels
users[i].Timestamp = temp.Timestamp;
users[i].LastLoginTime = temp.LastLoginTime;
}
if (SteamUsers.Count > 0)
{
SteamUsers = users.OrderByDescending(o => o.MostRecent).ThenByDescending(o => o.RememberPassword).ThenByDescending(o => o.LastLoginTime).ToList();
StatusService.Current.Notify("加载本地Steam用户数据完成");
}
else
{
StatusService.Current.Notify("没有检测到Steam用户数据");
}
}).ContinueWith(s => s.Dispose());
SteamUsers = new BindingList<SteamUser>(users.OrderByDescending(o => o.MostRecent).ThenByDescending(o => o.RememberPassword).ThenByDescending(o => o.LastLoginTime).ToList());
StatusService.Current.Notify("加载本地Steam用户数据完成");
}).ContinueWith(s => { Logger.Error(s.Exception); WindowService.Current.ShowDialogWindow(s.Exception.Message); }, TaskContinuationOptions.OnlyOnFaulted).ContinueWith(s => s.Dispose());
}
@@ -79,7 +78,7 @@ namespace SteamTools.ViewModels
{
steamService.SetCurrentUser(parameter);
steamService.KillSteamProcess();
steamService.StartSteam();
steamService.StartSteam(GeneralSettings.SteamStratParameter.Value);
SteamConnectService.Current.IsConnectToSteam = false;
}
@@ -87,5 +86,15 @@ namespace SteamTools.ViewModels
{
Process.Start(parameter);
}
public void DeleteAccount_OnClick(SteamUser user)
{
var result = WindowService.Current.MainWindow.Dialog("确定要删除这条本地记录帐户数据吗?\r\n这将会删除此账户在本地的Steam缓存数据。");
if (result)
{
steamService.DeleteSteamLocalUserData(user);
SteamUsers.Remove(user);
}
}
}
}
@@ -131,7 +131,7 @@ namespace SteamTools.ViewModels
SteamConnectService.Current.Subscribe(nameof(SteamConnectService.Current.SteamApps), this.Update).AddTo(this);
}).ContinueWith(s =>
}).ContinueWith(s => { Logger.Error(s.Exception); WindowService.Current.ShowDialogWindow(s.Exception.Message); }, TaskContinuationOptions.OnlyOnFaulted).ContinueWith(s =>
{
StatusService.Current.Notify("加载Steam游戏数据完成");
s.Dispose();
@@ -1,6 +1,7 @@
using MetroTrilithon.Mvvm;
using SAM.API.Types;
using SteamTool.Core;
using SteamTool.Core.Common;
using SteamTool.Model;
using SteamTool.Steam.Service;
using SteamTools.Properties;
@@ -138,7 +139,7 @@ namespace SteamTools.ViewModels
SteamConnectService.Current.ApiService.RunCallbacks(false);
await Task.Delay(1500);
}
});
}).ContinueWith(s => { Logger.Error(s.Exception); WindowService.Current.ShowDialogWindow(s.Exception.Message); }, TaskContinuationOptions.OnlyOnFaulted);
this.RefreshStats_Click();
//this.Initialize();
@@ -149,10 +149,6 @@ namespace SteamTools.ViewModels
if (File.Exists(WinAuthFileName))
{
StatusService.Current.Set("导入WinAuth令牌中...");
//Task.Run(() =>
//{
//});
AuthService.Current.ImportAuthenticators(WinAuthFileName);
AuthSettings.Authenticators.Value = AuthService.ConvertJsonAuthenticator(AuthService.Current.Authenticators).CompressString();
//(WindowService.Current.MainWindow as MainWindowViewModel).LocalAuthPage
@@ -48,7 +48,7 @@
<LineBreak />
<Run Text="微信" FontSize="16"/>
<LineBreak/>
<Image Source="pack://application:,,,/Resources/Asstes/wechatpay.png" Height="300"></Image>
<Image Source="pack://application:,,,/Resources/Asstes/wechatdonate.png" Height="300"></Image>
<LineBreak/>
<LineBreak/>
<LineBreak/>
@@ -0,0 +1,53 @@
<UserControl x:Class="SteamTools.Views.Content.AboutDonateList"
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}"
d:DataContext="{d:DesignInstance viewModel:AboutDonateListViewModel}">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="..\Common.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<DockPanel>
<TextBlock DockPanel.Dock="Top" Text="{Binding Resources.About_DonateList, Source={x:Static services:ResourceService.Current}, Mode=OneWay}"
Style="{DynamicResource SettingsHeaderTextStyleKey}" />
<DockPanel Grid.Column="1">
<TextBlock DockPanel.Dock="Top">
<Run Text="十分感谢此列表的大佬们对我的支持与捐助,此工具的完善离不开以下大佬的支持:" Style="{StaticResource DetailTextElementStyleKey}" />
</TextBlock>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding DonateRecordList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DockPanel Margin="8">
<WrapPanel VerticalAlignment="Center">
<TextBlock Text="{Binding Name}" Foreground="{StaticResource ActiveForegroundBrushKey}" Margin="10,0,0,0" Width="50"></TextBlock>
<TextBlock Text="{Binding Amount,StringFormat={}{0:F2}元}" Foreground="{StaticResource ActiveForegroundBrushKey}" Margin="30,0,0,0" Width="100"></TextBlock>
<TextBlock Text="{Binding Remark}" Foreground="{StaticResource ActiveForegroundBrushKey}" Margin="30,0,0,0"></TextBlock>
</WrapPanel>
<TextBlock Text="{Binding PayTime,StringFormat='{}{0:yyyy年MM月dd日}',ConverterCulture=zh-CN}" Foreground="{StaticResource ActiveForegroundBrushKey}" Margin="10" HorizontalAlignment="Right"></TextBlock>
</DockPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<!--<WebBrowser x:Name="web" Opacity="0.2"></WebBrowser>-->
</DockPanel>
</DockPanel>
</UserControl>
@@ -0,0 +1,44 @@
using SteamTool.Core;
using SteamTool.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace SteamTools.Views.Content
{
/// <summary>
/// AboutDonate.xaml 的交互逻辑
/// </summary>
public partial class AboutDonateList : UserControl
{
//private readonly HttpServices httpServices = SteamToolCore.Instance.Get<HttpServices>();
public AboutDonateList()
{
InitializeComponent();
}
//private void UserControl_Loaded(object sender, RoutedEventArgs e)
//{
// httpServices.Get(Const.REWARDMELIST_URL).ContinueWith(s =>
// {
// web.Dispatcher.Invoke(() =>
// {
// web.NavigateToString(s.Result);
// });
// });
//}
}
}
@@ -14,7 +14,6 @@
mc:Ignorable="d"
d:DesignHeight="400"
d:DesignWidth="600"
Padding="8"
Background="{DynamicResource ThemeBrushKey}">
<UserControl.Resources>
<ResourceDictionary>
@@ -23,33 +22,83 @@
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<DockPanel>
<TextBlock DockPanel.Dock="Top" Text="{Binding Resources.AboutUpdateHistory, Source={x:Static services:ResourceService.Current}, Mode=OneWay}"
<ScrollViewer Padding="8" VerticalScrollBarVisibility="Auto">
<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"
<Border Grid.Column="1">
<FlowDocumentScrollViewer Padding="0,-18,0,0"
HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto">
<FlowDocument FontSize="12"
<FlowDocument FontSize="12"
Foreground="{DynamicResource ForegroundBrushKey}"
FontFamily="Meiryo UI"
TextAlignment="Left"
MaxPageWidth="900">
<Paragraph Language="zh-cn">
<Run Text="Steam++ v1.0.0" FontSize="16"/>
<Run Text="&#160;"/>
<Run Text="2020-12-14" FontSize="10" />
<LineBreak />
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="发布第一个版本" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="主要功能:社区反代,帐户切换,成就解锁,本地令牌。"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="次要功能:强制无边框窗口化以及CSGO VAC屏蔽修复。"></Run>
</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
</Border>
</DockPanel>
<Paragraph Language="zh-cn">
<Run Text="Steam++ v1.0.2" FontSize="16"/>
<Run Text="&#160;"/>
<Run Text="2020-12-21" FontSize="10" />
<LineBreak />
<Run Text="更新内容"></Run>
<LineBreak />
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="更新了由Benares制作的图标" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增帐户切换删除功能" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="添加github图片资源文件代理服务与discord代理服务支持" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="因为有问题暂时去掉了GOG Galaxy代理选项"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复一个会导致程序启动没有反应的bug"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复托盘菜单steam昵称过长ui错位bug"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增steam启动参数设置"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增启动时程序最小化到托盘菜单设置"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增捐助列表的展示"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增工具自动更新功能"></Run>
<LineBreak />
<LineBreak />
<Run Text="已知的未修复问题"></Run>
<LineBreak />
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="(严重)经反馈,程序运行时可能会影响部分steam游戏掉帧,GPU占用率变低,这个BUG目前在作者的机器上无法复现所以暂时没有修复,如果你遇到这个问题可以手动关闭steam++解决。" />
<LineBreak />
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="程序在高DPI缩放分辨率下可能会UI布局错位,目前暂时拖动程序可恢复。" />
<LineBreak />
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="部分用户无法加载游戏列表,无法复现,原因暂时不明。" />
</Paragraph>
<Paragraph Language="zh-cn">
<Run Text="Steam++ v1.0.0" FontSize="16"/>
<Run Text="&#160;"/>
<Run Text="2020-12-14" FontSize="10" />
<LineBreak />
<Run Text="发布第一个版本" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="主要功能:社区反代,帐户切换,成就解锁,本地令牌。"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="次要功能:强制无边框窗口化以及CSGO VAC屏蔽修复。"></Run>
</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
</Border>
</DockPanel>
</ScrollViewer>
</UserControl>
@@ -47,12 +47,14 @@
</StackPanel>
<TextBlock Style="{StaticResource DetailTextStyleKey}" Margin="20,6,0,0">
<Run Text="CSGO的Vac屏蔽问题是个老玄学问题了,就算是V社官方也不能确定原因。"></Run>
<Run Text="CSGO的Vac屏蔽问题是个老玄学问题了,就算是V社官方也只能给个排查范围。"></Run>
<metro2:HyperlinkEx Uri="https://support.steampowered.com/kb_article.php?ref=2117-ILZV-2837">
<Run Text="V社官方说明"></Run>
</metro2:HyperlinkEx>
<LineBreak/>
<Run Text="这里只是一个可能修复的方法,如果尝试后无效只能依次在尝试验证游戏完整性,重启电脑,实在不行(大概)就只有重装CSGO了。"/>
<Run Text="如果尝试后无效只能依次在尝试验证游戏完整性,重启电脑,实在不行(大概)就只有重装CSGO了。"/>
<LineBreak/>
<Run Text="功能实现使用了狙击手Ricky的批处理指令。"></Run>
</TextBlock>
<metro:PromptTextBox
@@ -15,7 +15,6 @@
mc:Ignorable="d"
d:DesignHeight="400"
d:DesignWidth="600"
Padding="8"
Background="{DynamicResource ThemeBrushKey}"
d:DataContext="{d:DesignInstance viewModel:SettingsGeneralViewModel}">
@@ -51,6 +50,37 @@
<TextBlock Text="开机自启动"></TextBlock>
</CheckBox>
<Separator Opacity="0" Height="10"/>
<WrapPanel>
<CheckBox
HorizontalAlignment="Left"
IsChecked="{Binding Source={x:Static ms:GeneralSettings.IsStartupAppMinimized}, Path=Value, Mode=TwoWay}">
<TextBlock Text="启动时最小化到托盘菜单"></TextBlock>
</CheckBox>
<TextBlock Style="{StaticResource DetailTextStyleKey}" Margin="10,0,0,0">
<Run Text="*此设置不影响开机自启动时最小化"></Run>
</TextBlock>
</WrapPanel>
<Separator Opacity="0" Height="10"/>
<CheckBox
HorizontalAlignment="Left"
IsChecked="{Binding Source={x:Static ms:GeneralSettings.IsAutoCheckUpdate}, Path=Value, Mode=TwoWay}">
<TextBlock Text="启动时自动检查更新"></TextBlock>
</CheckBox>
<Separator Opacity="0" Height="10"/>
<WrapPanel>
<metro2:CallMethodButton Content="检查更新"
Width="80"
Height="30"
HorizontalAlignment="Left"
MethodName="CheckUpdate_Click"
MethodTarget="{Binding}"/>
<TextBlock Style="{StaticResource DetailTextStyleKey}" Margin="10,0,0,0">
<Run Text="手动检查更新"></Run>
</TextBlock>
</WrapPanel>
<!--<Separator Opacity="0" Height="10"/>-->
<Border Height="1"
@@ -58,6 +88,23 @@
Margin="-20,8" />
</StackPanel>
<StackPanel Margin="20,0,0,0">
<TextBlock Margin="-20,0,0,10" Text="Steam启动参数" Style="{DynamicResource SettingsHeaderTextStyleKey}" />
<metro:PromptTextBox Prompt="自定义Steam启动参数"
Text="{Binding Source={x:Static ms:GeneralSettings.SteamStratParameter}, Path=Value, Mode=TwoWay}"
Width="400"
HorizontalAlignment="Left"
TextWrapping="Wrap"
AcceptsReturn="True"
VerticalScrollBarVisibility="Visible"
MaxLines="3"></metro:PromptTextBox>
<TextBlock Style="{StaticResource DetailTextStyleKey}" Margin="0,6,0,0">
<Run Text="在帐户切换启动Steam时会带上这些参数启动Steam。"></Run>
</TextBlock>
<Border Height="1"
Background="{DynamicResource BorderBrushKey}"
Margin="-20,8" />
</StackPanel>
<StackPanel Margin="20,0,0,0">
<TextBlock Margin="-20,0,0,10" Text="{Binding Resources.Settings_GameList, Source={x:Static services:ResourceService.Current}, Mode=OneWay}" Style="{DynamicResource SettingsHeaderTextStyleKey}" />
@@ -68,7 +115,7 @@
<TextBlock Text="启用游戏列表本地缓存"></TextBlock>
</CheckBox>
<TextBlock Style="{StaticResource DetailTextStyleKey}" Margin="0,6,0,0">
<Run Text="取消本地缓存后每次启动都将从Steam服务器加载最新游戏列表数据,加载速度会变慢。"></Run>
<Run Text="取消本地缓存后每次启动都将从Steam服务器加载最新游戏列表数据,但每次启动时加载速度会变慢。"></Run>
</TextBlock>
<Separator Opacity="0" Height="10"/>
@@ -81,9 +128,9 @@
MethodTarget="{Binding}"/>
<TextBlock Style="{StaticResource DetailTextStyleKey}" Margin="0,6,0,0">
<Run Text="因为从Steam获取游戏列表数据时会很慢,为了避免加载缓慢所以在本地会缓存一份游戏列表的数据。"></Run>
<Run Text="因为从Steam获取游戏列表数据时很慢,为了避免加载缓慢所以在本地会缓存一份游戏列表的数据。"></Run>
<LineBreak/>
<Run Text="但是数据因为数据是默认10天更新一次,因此如果您发现在游戏列表搜索不到新发布的游戏时,可以考虑手动刷新游戏列表缓存。"/>
<Run Text="游戏列表缓存默认10天更新一次,因此如果您发现在游戏列表搜索不到新发布的游戏时,可以考虑手动刷新游戏列表缓存。"/>
</TextBlock>
<Border Height="1"
+11 -7
View File
@@ -11,8 +11,12 @@
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:livet="http://schemas.livet-mvvm.net/2011/wpf"
mc:Ignorable="d"
Height="345" Width="180"
Height="350" Width="180"
FontSize="14"
UseLayoutRounding="True"
TextOptions.TextFormattingMode="Display"
TextOptions.TextRenderingMode="Auto"
SnapsToDevicePixels="True"
Foreground="{DynamicResource ForegroundBrushKey}"
d:DataContext="{d:DesignInstance vm:TaskBarViewModel}">
<Border>
@@ -28,11 +32,11 @@
BorderThickness=".99">
<Grid Margin="8,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="70"></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}}">
<DockPanel 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">
@@ -41,15 +45,15 @@
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
<StackPanel VerticalAlignment="Center" >
<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}}">
</DockPanel>
<DockPanel 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>
<!--设置图像如何显示-->
@@ -74,7 +78,7 @@
<Run Text="{Binding Source={x:Static models:ProductInfo.VersionString}, StringFormat=版本 {0}, Mode=OneWay}"></Run>
</TextBlock>
</StackPanel>
</WrapPanel>
</DockPanel>
<StackPanel Grid.Row="1">
<Rectangle Height=".99"
Fill="{DynamicResource InactiveForegroundBrushKey}"
+1 -1
View File
@@ -20,9 +20,9 @@
Foreground="{DynamicResource ActiveForegroundBrushKey}"
FontFamily="{StaticResource DefaultFontFamilyKey}"
UseLayoutRounding="True"
SnapsToDevicePixels="True"
TextOptions.TextFormattingMode="Display"
TextOptions.TextRenderingMode="Auto"
SnapsToDevicePixels="True"
WindowStartupLocation="CenterScreen"
IsRestoringWindowPlacement="True"
d:DataContext="{d:DesignInstance vm:MainWindowViewModel}"
+19 -4
View File
@@ -43,7 +43,19 @@
</TabItem.Header>
<contents:AboutDonate></contents:AboutDonate>
</TabItem>
<TabItem>
<TabItem.Header>
<TextBlock Text="{Binding Resources.About_DonateList,Source={x:Static services:ResourceService.Current}, Mode=OneWay}"
Style="{StaticResource TabHeaderTextStyleKey}" />
</TabItem.Header>
<contents:AboutDonateList>
<contents:AboutDonateList.DataContext>
<viewModel:AboutDonateListViewModel></viewModel:AboutDonateListViewModel>
</contents:AboutDonateList.DataContext>
</contents:AboutDonateList>
</TabItem>
<TabItem>
<TabItem.Header>
<TextBlock Text="{Binding Resources.AboutUpdateHistory,Source={x:Static services:ResourceService.Current}, Mode=OneWay}"
@@ -59,15 +71,18 @@
</TabItem.Header>
</TabItem>
<TabItem Visibility="Collapsed">
<TabItem>
<TabItem.Header>
<TextBlock Text="{Binding Resources.About_OpenSourceLicensing,Source={x:Static services:ResourceService.Current}, Mode=OneWay}"
Style="{StaticResource TabHeaderTextStyleKey}" />
</TabItem.Header>
<ScrollViewer VerticalScrollBarVisibility="Auto" Margin="8">
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="8">
<StackPanel>
<TextBlock Style="{StaticResource HeaderTextStyleKey}" FontSize="20">
<Run Text="此软件的诞生离不开以下开源软件"/>
<Run Text="{Binding Resources.About_OpenSourceLicensing,Source={x:Static services:ResourceService.Current}, Mode=OneWay}"/>
</TextBlock>
<TextBlock Style="{StaticResource DetailTextStyleKey}">
<Run Text="此软件的诞生离不开以下开源项目:"/>
<LineBreak/>
</TextBlock>
<ItemsControl ItemsSource="{Binding Source={x:Static models:ProductInfo.Libraries}}">
+1 -1
View File
@@ -24,7 +24,7 @@
</ResourceDictionary>
</UserControl.Resources>
<Grid Margin="10">
<Grid Margin="8,0,8,8">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
-1
View File
@@ -135,7 +135,6 @@
</Border>
<!--</Expander>-->
<!--Content-->
<Border Grid.Row="1" Margin="8"
BorderBrush="{DynamicResource BorderBrushKey}"
@@ -92,17 +92,27 @@
<!--<TextBlock Text="最近登录的账户" Foreground="Green" Visibility="{Binding MostRecent,Converter={StaticResource BooleanToVisibilityConverter}}"></TextBlock>-->
<!--</StackPanel>-->
</StackPanel>
<Separator Opacity="0" Width="30"/>
<!--<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center">-->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center">
<!--<Image Source="pack://application:,,,/Resources/Asstes/time.png" Width="20" HorizontalAlignment="Right" Margin="0,0,5,0" Visibility="{Binding MostRecent,Converter={StaticResource BooleanToVisibilityConverter}}"></Image>-->
<TextBlock HorizontalAlignment="Right"
<TextBlock HorizontalAlignment="Right"
VerticalAlignment="Center"
FontSize="12"
TextAlignment="Center" Width="Auto"
Text="{Binding LastLoginTime,StringFormat={x:Static prop:Resources.LastloginTime},Mode=OneWay}"/>
<!--</StackPanel>-->
<Image HorizontalAlignment="Right" Source="/Resources/Asstes/delete.png" Width="16" Height="16" Cursor="Hand" ToolTip="{Binding Resources.Delete,Source={x:Static services:ResourceService.Current}}" Margin="10,0,0,0">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<livet:LivetCallMethodAction
MethodName="DeleteAccount_OnClick"
MethodParameter="{Binding}"
MethodTarget="{Binding DataContext,ElementName=u}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
</StackPanel>
</DockPanel>
<Rectangle Height=".99"
Fill="{DynamicResource InactiveForegroundBrushKey}"
+25 -18
View File
@@ -34,7 +34,7 @@
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Margin="0,0,30,-4"
Opacity="0.25">
Opacity="0.30">
</Image>
<Border Grid.Column="0"
BorderBrush="{DynamicResource BorderBrushKey}"
@@ -75,8 +75,8 @@
<LineBreak />
<Run Text="程序图标:" />
<metro2:HyperlinkEx Uri="https://keylol.com/">
<Run Text="@Keylol" />
<metro2:HyperlinkEx Uri="https://steamcommunity.com/profiles/76561198110756239/">
<Run Text="@Benares" />
</metro2:HyperlinkEx>
</TextBlock>
@@ -91,7 +91,7 @@
<Run Text="请不要使用修改版魔改版程序。"></Run>
<LineBreak />
<LineBreak />
<Run Text="程序完全免费,"></Run>
<Run Text="程序完全免费并开源于Github,"></Run>
<LineBreak />
<Run Text="若在任意渠道购买请差评退款。"></Run>
<LineBreak />
@@ -139,7 +139,7 @@
<Run Text="此工具的大部分功能都是需要您下载安装Steam才能使用。" />
</Paragraph>
<Paragraph Language="zh-cn">
<Run Text="主要功能" FontSize="18"/>
<Run Text="核心功能" FontSize="18"/>
<LineBreak/>
<LineBreak />
<Run Text=" "></Run>
@@ -151,17 +151,16 @@
<LineBreak/>
<LineBreak />
<Run Text=" "></Run>
<Run Text="3.Steam游戏的成就统计管理功能,该功能的实现是调用了Steam客户端的接口。" />
<Run Text="3.Steam成就统计信息修改,该功能的实现与SAM是一样的。" />
<LineBreak/>
<LineBreak />
<Run Text=" "></Run>
<Run Text="4.Steam本地两步身份验证器的实现,可以使您不用启动移动版Steam App也能查看您的令牌。" />
<LineBreak/>
<Run Text="4.Steam本地两步身份验证器,可以使您不用启动移动版Steam App也能查看您的令牌。" />
<Run Text="(暂时还不支持进行市场交易确认,计划后续添加支持)"/>
<LineBreak/>
<LineBreak />
<Run Text=" "></Run>
<Run Text="5.一些游戏工具,目前已有强制游戏无边框窗口化,CSGO修复VAC屏蔽。" />
<Run Text="5.一些游戏工具类功能(不会开发作弊相关功能),目前已有强制游戏无边框窗口化,CSGO修复VAC屏蔽。" />
<Run Text="(正在开发...)"></Run>
</Paragraph>
<Paragraph>
@@ -169,13 +168,13 @@
<LineBreak/>
<LineBreak/>
<Run Text=" "></Run>
<Run Text="尝试用社区反代和成就管理的API实现一个全自动的挂卡功能。" />
<Run Text="Steam自动挂卡,尝试用社区反代功能结合成就解锁功能来重新实现,目的是实现在软件内登录Steam即可直接获取徽章卡片信息并开始挂卡。" />
<Run Text="(接下来要做的...)"></Run>
<LineBreak/>
<LineBreak />
<Run Text=" "></Run>
<Run Text="Steam皮肤的可视化设计编辑功能。" />
<Run Text="(短期内应该做不完...)"></Run>
<Run Text="(挖坑画大饼,可视化编辑Steam皮肤,而且如果软件能上架Steam的话打算支持创意工坊分享设计的Steam皮肤,短期内肯定做不完...)"></Run>
<LineBreak/>
<LineBreak />
<Run Text=" "></Run>
@@ -219,19 +218,27 @@
<metro2:HyperlinkEx Uri="https://spp.rmbgame.net">
<Run Text="https://spp.rmbgame.net" />
</metro2:HyperlinkEx>-->
<Run Text="Release:" />
<metro2:HyperlinkEx Uri="https://github.com/rmbadmin/Steam-PlusPlus/releases">
<Run Text="https://github.com/rmbadmin/Steam-PlusPlus/releases" />
<Run Text="开源地址:" />
<metro2:HyperlinkEx Uri="https://github.com/rmbadmin/SteamTools">
<Run Text="https://github.com/rmbadmin/SteamTools" />
</metro2:HyperlinkEx>
<LineBreak />
<Run Text="发布地址:" />
<metro2:HyperlinkEx Uri="https://github.com/rmbadmin/SteamTools/releases">
<Run Text="https://github.com/rmbadmin/SteamTools/releases" />
</metro2:HyperlinkEx>
<LineBreak />
<LineBreak />
<Run Text="BUG&amp;建议反馈:" />
<metro2:HyperlinkEx Uri="https://github.com/rmbadmin/SteamTools/issues">
<Run Text="https://github.com/rmbadmin/SteamTools/issues" />
</metro2:HyperlinkEx>
<LineBreak />
<Run Text="或者发送到我的邮箱:"></Run>
<metro2:HyperlinkEx Uri="rmb@rmbgame.net">
<Run Text="rmb@rmbgame.net" />
</metro2:HyperlinkEx>
<Run Text="开源地址:" />
<metro2:HyperlinkEx Uri="https://github.com/rmbadmin/Steam-PlusPlus.git">
<Run Text="https://github.com/rmbadmin/Steam-PlusPlus.git" />
</metro2:HyperlinkEx>
</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
@@ -232,7 +232,7 @@
</Grid.ColumnDefinitions>
<TextBlock Margin="0,2"
VerticalAlignment="Center"
HorizontalAlignment="Right" Foreground="{DynamicResource AccentForegroundBrushKey}">
HorizontalAlignment="Right" Foreground="{DynamicResource ActiveForegroundBrushKey}">
<Run Text="{Binding Resources.Search,Source={x:Static services:ResourceService.Current},Mode=OneWay}" />
<Run Text=":" />
</TextBlock>
+3 -3
View File
@@ -260,9 +260,9 @@
<metro:PromptTextBox Grid.Row="1"
Grid.Column="1"
TextWrapping="Wrap"
AcceptsReturn="True"
VerticalScrollBarVisibility="Visible"
MaxLines="3"
AcceptsReturn="True"
VerticalScrollBarVisibility="Visible"
MaxLines="3"
Text="{Binding SteamGuard, Mode=TwoWay}"
Prompt="" />
<!--<metro2:CallMethodButton Width="80"
+6 -6
View File
@@ -29,16 +29,16 @@
<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
<!--Windows 7
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
<!--Windows 7-->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
<!--Windows 8
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
<!--Windows 8-->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
Windows 8.1
<!--Windows 8.1-->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
Windows 10
<!--Windows 10-->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
@@ -0,0 +1,17 @@
// ==UserScript==
// @name Steam解锁不可描述游戏商店页
// @namespace http://tampermonkey.net/
// @version 1.1
// @description Steam Store (Turn on mature content in some region)
// @author Dogfight360
// @match http*://store.steampowered.com/
// @icon http://store.steampowered.com/favicon.ico
// @namespace https://greasyfork.org/
// @enable true
// @grant none
// ==/UserScript==
(function() {
document.cookie="wants_mature_content=1"
document.cookie="birthtime=22503171"
})();
+99
View File
@@ -0,0 +1,99 @@
# 前言
Steam++项目创建于2018年5月8日,不过并不是耗时两年才做出来,之前一直由于工作原因,并没有多少空闲时间,直到今年中旬辞职了,才开始猛肝。
本来是想一直做到完全体了,才考虑发布,不过现在感慨一下,果然是没法这么快就整完的,所以还是一版一版更新做到完全体吧。
Steam++只在keylol论坛与github发布,为了账号安全,请不要到其它不明地方下载。
已经收到了B叔制作的图标,下个版本可以换上更好看的图标了。
# Steam++工具箱
## 已知的未修复问题
> 目前已知坛友反馈的严重BUG问题
* steam++启动后运行steam在运行steam的部分游戏会使游戏掉帧,gpu利用率很低,这个问题在作者的电脑上确实无法复现,所以暂时只能请各位在遇到此问题时手动关闭steam++,带来不便请谅解,抱歉。
## 工具介绍
`Steam++`是一个包含多种Steam工具功能的工具箱,开源发布于[Github](https://github.com/rmbadmin/SteamTools),如果您对发布的二进制文件不放心,可以自行下载源码编译运行。
此工具的大部分功能都是需要您下载安装Steam才能使用。
工具预计将整合进大部分常用的Steam相关工具,并且尽力做到比原工具更好用,在各种整合添加功能的同时,也会注意体积尽量的控制到最小。
查毒链接[https://www.virustotal.com/gui/file/3889babb8b0dcf79b16045679a5cb57a70cc6d60447078fb65b8a8979da2f14d/detection](https://www.virustotal.com/gui/file/3889babb8b0dcf79b16045679a5cb57a70cc6d60447078fb65b8a8979da2f14d/detection)
虽然没有什么杀毒软件报毒,但是使用过程中可能遇到windows defender误报,您可以选择添加信任。
软件截图
[hide]
[attachimg]1224039[/attachimg]
[attachimg]1224038[/attachimg]
[attachimg]1224040[/attachimg]
[/hide]
## 核心功能
### 1. 反代Steam的社区网页使其能正常访问
功能类似羽翼城大佬的steamcommunity_302,使用[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]1224032[/attachimg]
### 2. 快速切换当前PC已经记住登陆的Steam账号
该功能是读取Steam路径下存储的本地用户登录记录直接展示操作,可以多账号切换无需重新输入密码和令牌。
[attachimg]1224033[/attachimg]
### 3. Steam游戏的成就统计管理功能
功能参考[SteamAchievementManager](https://github.com/gibbed/SteamAchievementManager)进行二次开发,修复了成就语言有中文却依然是英文成就信息的BUG,修改了游戏列表的加载和操作易用性。
[attachimg]1224034[/attachimg]
### 4. Steam本地两步身份验证器
功能参考[WinAuth](https://github.com/winauth/winauth)开发,可以使您不用启动移动版Steam App也能查看您的令牌,功能类似的软件有[WinAuth](https://github.com/winauth/winauth)、[SteamDesktopAuthenticator](https://github.com/Jessecar96/SteamDesktopAuthenticator)。
[attachimg]1224035[/attachimg]
### 5. 一些游戏工具
目前已有强制游戏无边框窗口化,CSGO修复VAC屏蔽。
这一块是随缘做一些我经常用或者闲着没事捣鼓的功能。
将任何游戏强制无边框窗口化
[attachimg]1224036[/attachimg]
使任何窗口化游戏变成动态桌面壁纸(终于可以用《山》当壁纸了)
[attachimg]1224037[/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)
> [蓝奏云](https://wws.lanzous.com/ijIlwjg2bjc)
> [百度云](https://pan.baidu.com/s/19XCB3-X7isygG6UFpXcCtg)
> 查看百度云提取码
> [hide]
> 提取码:zbs6
> [/hide]
> exe体积:4.81MB
> md5:AEECBD9B268C0BB8D619555CE125C9A5