Compare commits

..
9 Commits
Author SHA1 Message Date
rmbgame 8da01ac3dd ready 1.0.4 2020-12-28 20:35:45 +08:00
rmbgame 2ab26f7848 ready 1.0.3 2020-12-26 22:20:50 +08:00
rmbgame d646eacda1 ready 1.0.2 2020-12-21 21:54:23 +08:00
rmbgame fb029f729b ready 1.0.0 2020-12-21 21:47:08 +08:00
rmbgame 5ef6663269 delete ref lib 2020-12-21 21:36:17 +08:00
rmbgame 5c86b53000 ready 1.0.0 2020-12-17 12:10:47 +08:00
rmbgame efb6adbd9b delete ref lib 2020-12-16 10:38:03 +08:00
rmbgame 209202b5cf sync develop 2020-12-16 10:36:52 +08:00
rmbgame c0a081e226 delete ref lib 2020-12-16 10:34:52 +08:00
587 changed files with 2204 additions and 3677 deletions
+13
View File
@@ -0,0 +1,13 @@
### 该问题是怎么引起的?
### 重现步骤
### 报错信息
+15
View File
@@ -0,0 +1,15 @@
### 相关的Issue
### 原因(目的、解决的问题等)
### 描述(做了什么,变更了什么)
### 测试用例(新增、改动、可能影响的功能)
-6
View File
@@ -1,6 +0,0 @@
[submodule "references/Titanium-Web-Proxy"]
path = references/Titanium-Web-Proxy
url = https://github.com/rmbadmin/Titanium-Web-Proxy.git
[submodule "references/MetroRadiance"]
path = references/MetroRadiance
url = https://github.com/rmbadmin/MetroRadiance.git
View File

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 145 KiB

View File

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 148 KiB

View File

Before

Width:  |  Height:  |  Size: 322 KiB

After

Width:  |  Height:  |  Size: 322 KiB

View File

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 130 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 MiB

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

Before

Width:  |  Height:  |  Size: 427 KiB

After

Width:  |  Height:  |  Size: 427 KiB

@@ -1,5 +1,6 @@
[
{
"Index": 1,
"Name": "*瑞",
"Amount": 5,
"OrderNumber": "",
@@ -8,6 +9,7 @@
"PayTime": "2020-12-17 19:41:57"
},
{
"Index": 2,
"Name": "**耀",
"Amount": 5,
"OrderNumber": "",
@@ -16,6 +18,7 @@
"PayTime": "2020-12-17 20:46:01"
},
{
"Index": 3,
"Name": "**皓",
"Amount": 1,
"OrderNumber": "",
@@ -24,6 +27,7 @@
"PayTime": "2020-12-17 22:41:27"
},
{
"Index": 4,
"Name": "**宇",
"Amount": 1,
"OrderNumber": "",
@@ -32,6 +36,7 @@
"PayTime": "2020-12-18 08:39:42"
},
{
"Index": 5,
"Name": "*钊",
"Amount": 20,
"OrderNumber": "",
@@ -40,6 +45,7 @@
"PayTime": "2020-12-19 17:10:44"
},
{
"Index": 6,
"Name": "R*n",
"Amount": 20,
"OrderNumber": "",
@@ -48,6 +54,7 @@
"PayTime": "2020-12-17 14:32:00"
},
{
"Index": 7,
"Name": "*炜",
"Amount": 100,
"OrderNumber": "",
@@ -56,6 +63,7 @@
"PayTime": "2020-12-20 12:02:17"
},
{
"Index": 8,
"Name": "**智",
"Amount": 20,
"OrderNumber": "",
@@ -64,6 +72,7 @@
"PayTime": "2020-12-20 12:21:04"
},
{
"Index": 9,
"Name": "*森",
"Amount": 66,
"OrderNumber": "",
@@ -72,6 +81,7 @@
"PayTime": "2020-12-21 23:03:26"
},
{
"Index": 10,
"Name": "*珂",
"Amount": 50,
"OrderNumber": "",
@@ -80,6 +90,7 @@
"PayTime": "2020-12-21 23:18:09"
},
{
"Index": 11,
"Name": "**丰",
"Amount": 1,
"OrderNumber": "",
@@ -88,6 +99,7 @@
"PayTime": "2020-12-22 12:33:46"
},
{
"Index": 12,
"Name": "Ruby",
"Amount": 77,
"OrderNumber": "",
@@ -96,6 +108,7 @@
"PayTime": "2020-12-24 19:40:25"
},
{
"Index": 13,
"Name": "**桐",
"Amount": 1,
"OrderNumber": "",
@@ -104,6 +117,7 @@
"PayTime": "2020-12-26 09:32:57"
},
{
"Index": 14,
"Name": "**珂",
"Amount": 5,
"OrderNumber": "",
@@ -112,6 +126,7 @@
"PayTime": "2020-12-26 13:28:07"
},
{
"Index": 15,
"Name": "z.w",
"Amount": 10,
"OrderNumber": "",
@@ -120,6 +135,7 @@
"PayTime": "2020-12-26 15:34:50"
},
{
"Index": 16,
"Name": "**林",
"Amount": 6,
"OrderNumber": "",
@@ -128,6 +144,7 @@
"PayTime": "2020-12-26 18:25:06"
},
{
"Index": 17,
"Name": "**立",
"Amount": 1,
"OrderNumber": "",
@@ -136,6 +153,7 @@
"PayTime": "2020-12-26 18:56:57"
},
{
"Index": 18,
"Name": "*易",
"Amount": 6.66,
"OrderNumber": "",
@@ -144,6 +162,7 @@
"PayTime": "2020-12-27 13:55:11"
},
{
"Index": 19,
"Name": "*明",
"Amount": 10,
"OrderNumber": "",
@@ -152,6 +171,7 @@
"PayTime": "2020-12-27 21:28:40"
},
{
"Index": 20,
"Name": "山山为川",
"Amount": 1,
"OrderNumber": "",
@@ -160,6 +180,7 @@
"PayTime": "2020-12-27 22:17:22"
},
{
"Index": 21,
"Name": "*梁",
"Amount": 3,
"OrderNumber": "",
@@ -168,6 +189,7 @@
"PayTime": "2020-12-28 11:59:20"
},
{
"Index": 22,
"Name": "**男",
"Amount": 1,
"OrderNumber": "",
@@ -176,131 +198,12 @@
"PayTime": "2020-12-28 14:54:48"
},
{
"Index": 23,
"Name": "匿名",
"Amount": 14.61,
"OrderNumber": "",
"PayType": 2,
"Remark": "",
"PayTime": "2020-12-28 14:07:44"
},
{
"Name": "jiwuwang",
"Amount": 10,
"OrderNumber": "",
"PayType": 2,
"Remark": "希望挂卡早点安排上",
"PayTime": "2020-12-29 03:14:35"
},
{
"Name": "缄默",
"Amount": 10,
"OrderNumber": "",
"PayType": 2,
"Remark": "给软软打call!steam++是目前接触的最好用的插件!",
"PayTime": "2020-12-29 12:35:07"
},
{
"Name": "**宇",
"Amount": 6,
"OrderNumber": "",
"PayType": 1,
"Remark": "",
"PayTime": "2020-12-31 20:14:05"
},
{
"Name": "**东",
"Amount": 1,
"OrderNumber": "",
"PayType": 1,
"Remark": "一点绵薄之力,希望继续完善!",
"PayTime": "2021-01-03 21:28:08"
},
{
"Name": "**羽",
"Amount": 5,
"OrderNumber": "",
"PayType": 2,
"Remark": "感谢大佬",
"PayTime": "2021-01-05 16:22:11"
},
{
"Name": "**彬",
"Amount": 5,
"OrderNumber": "",
"PayType": 1,
"Remark": "平其心论天下之事,定其心应天下之变",
"PayTime": "2021-01-06 17:08:36"
},
{
"Name": "K",
"Amount": 10,
"OrderNumber": "",
"PayType": 2,
"Remark": "支持一下",
"PayTime": "2021-01-07 14:46:04"
},
{
"Name": "*鹏",
"Amount": 10,
"OrderNumber": "",
"PayType": 1,
"Remark": "加油💪",
"PayTime": "2021-01-07 11:42:38"
},
{
"Name": "*成",
"Amount": 6.66,
"OrderNumber": "",
"PayType": 1,
"Remark": "",
"PayTime": "2021-01-07 12:25:59"
},
{
"Name": "素年",
"Amount": 5,
"OrderNumber": "",
"PayType": 2,
"Remark": "不闪退了。支持一下",
"PayTime": "2021-01-08 22:37:11"
},
{
"Name": "kingburial",
"Amount": 1,
"OrderNumber": "",
"PayType": 2,
"Remark": "不是很常用,但是切换账号就很方便。谢谢啦",
"PayTime": "2021-01-09 10:16:04"
},
{
"Name": "**宇",
"Amount": 5,
"OrderNumber": "",
"PayType": 1,
"Remark": "",
"PayTime": "2021-01-12 20:39:26"
},
{
"Name": "Mixer",
"Amount": 20,
"OrderNumber": "",
"PayType": 2,
"Remark": "非常感谢!很好用",
"PayTime": "2021-01-14 06:15:26"
},
{
"Name": "**政",
"Amount": 5,
"OrderNumber": "",
"PayType": 2,
"Remark": "给个建议 令牌页面保持前端显示",
"PayTime": "2021-01-14 11:07:54"
},
{
"Name": "**浩",
"Amount": 6.66,
"OrderNumber": "",
"PayType": 1,
"Remark": "",
"PayTime": "2021-01-16 09:48:57"
}
]
View File

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

View File

Before

Width:  |  Height:  |  Size: 199 KiB

After

Width:  |  Height:  |  Size: 199 KiB

View File

Before

Width:  |  Height:  |  Size: 236 KiB

After

Width:  |  Height:  |  Size: 236 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before

Width:  |  Height:  |  Size: 364 KiB

After

Width:  |  Height:  |  Size: 364 KiB

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 364 KiB

After

Width:  |  Height:  |  Size: 364 KiB

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

+48 -70
View File
@@ -1,98 +1,78 @@
<img src="https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/icon/LOGO1.png" alt="logo" width="130" height="130" align="left" />
# Steam++ SteamTools
<h1>Steam++ Tools</h1>
> 「Steam++」is a toolkit that contains a variety of Steam tools, most of which require you to download and install Steam in order to use them.
<br/>
「Steam++」是一个包含多种Steam工具功能的工具箱。
![Release Download](https://img.shields.io/github/downloads/rmbadmin/SteamTools/latest/total?style=flat-square)
[![Release Version](https://img.shields.io/github/v/release/rmbadmin/SteamTools?style=flat-square)](https://github.com/rmbadmin/SteamTools/releases/latest)
[![GitHub license](https://img.shields.io/github/license/rmbadmin/SteamTools?style=flat-square)](LICENSE)
[![GitHub Star](https://img.shields.io/github/stars/rmbadmin/SteamTools?style=flat-square)](https://github.com/rmbadmin/SteamTools/stargazers)
[![GitHub Fork](https://img.shields.io/github/forks/rmbadmin/SteamTools?style=flat-square)](https://github.com/rmbadmin/SteamTools/network/members)
![GitHub repo size](https://img.shields.io/github/repo-size/rmbadmin/SteamTools?style=flat-square&color=3cb371)
此工具的大部分功能都是需要您下载安装Steam才能使用。
# Steam++
[English](https://github.com/rmbadmin/SteamTools/blob/develop/README.en.md)
[简体中文](https://github.com/rmbadmin/SteamTools/blob/develop/README.md)
## Samples
-------
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/s.png)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/e.png)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/e2.png)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/t.png)
------
## Core Functions
## 核心功能
### 1. 反代Steam的社区网页使其能正常访问
功能类似羽翼城大佬的Steam302,使用[Titanium-Web-Proxy](https://github.com/justcoding121/Titanium-Web-Proxy)开源项目进行本地反代,相比302工具具有更快的启动速度,以及支持简单的脚本注入。
### 1. Local reverse proxy for Steam's community webpage to enable normal access in mainland China
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/1.png)
---
### 2. Quickly switch the Steam account that the current PC has remembered to log into
### 2. 快速切换当前PC已经记住登陆的Steam账号
This feature is to read the local user login records stored under the Steam path to directly display the operation, you can switch between multiple accounts without re-entering passwords and tokens.
该功能是读取Steam路径下存储的本地用户登录记录直接展示操作,可以多账号切换无需重新输入密码和令牌。
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/2.png)
---
### 3. Achievement stat modifications for Steam games
Function reference [SteamAchievementManager](https://github.com/gibbed/SteamAchievementManager) for secondary development, modified the game list loading and operation ease of use.
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/3.png)
---
### 4. Steam Local Two-Step Authenticator
The function reference [WinAuth](https://github.com/winauth/winauth) is developed to enable you to view your token without launching the mobile version of Steam App, similar function software are [WinAuth](https://github.com/winauth/winauth), [SteamDesktopAuthenticator](https://github.com/Jessecar96/SteamDesktopAuthenticator).
! [](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/4.png)
### 3. Steam游戏的成就统计管理功能
功能参考[SteamAchievementManager](https://github.com/gibbed/SteamAchievementManager)进行二次开发,修改了游戏列表的加载和操作易用性。
---
### 5. Some game tools
Currently there is a forced game borderless windowing, CSGO fix VAC shield.
This piece is randomly do some of my often used or idle tinkering with the function.
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/5.png)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/6.png)
---
## Features expected to be added subsequently
### Steam Idle Card
The goal is to enable direct access to badge card information and start hanging cards without logging into your Steam account within the software.
### Plug-in form to load and run ASF
Support ASF as a plug-in to run within the tool and enhance the use of ASF in Windows Desktop environment.
### Steam Custom Cover Management
Enhanced management of Steam custom covers and quick matching of downloaded app covers from [SteamGridDB](https://www.steamgriddb.com/).
### More other game platform features
### More non-cheat game features
### 4. Steam本地两步身份验证器
功能参考[WinAuth](https://github.com/winauth/winauth)开发,可以使您不用启动移动版Steam App也能查看您的令牌,功能类似的软件有[WinAuth](https://github.com/winauth/winauth)、[SteamDesktopAuthenticator](https://github.com/Jessecar96/SteamDesktopAuthenticator)。
---
## Operating Environment
> The program was developed using C# WPF in .,If it does not work please download and install[.NET Framework 4.7.2](https://dotnet.microsoft.com/download/dotnet-framework/net472)。
> The missing assembly is my own modified project
* [Titanium-Web-Proxy](https://github.com/rmbadmin/Titanium-Web-Proxy)
* [MetroRadiance](https://github.com/rmbadmin/MetroRadiance)
### 5. 一些游戏工具
目前已有强制游戏无边框窗口化,CSGO修复VAC屏蔽。
这一块是随缘做一些我经常用或者闲着没事捣鼓的功能。
---
## 预计后续添加的功能
### 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](https://github.com/rmbadmin/SteamTools/blob/develop/LICENSE)
> Open source/free software released under the GPLv3 license.
> [GPL-3.0 License](LICENSE.txt)
> 根据GPLv3许可发布的开源/免费软件。
---
## Thanks to the following open source projects
## 感谢以下开源项目
* [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json)
* [MetroRadiance](https://github.com/Grabacr07/MetroRadiance)
* [MetroTrilithon](https://github.com/Grabacr07/MetroTrilithon)
* [Livet](https://github.com/runceel/Livet)
* [StatefulModel](https://github.com/ugaya40/StatefulModel)
* [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)
@@ -102,6 +82,4 @@ Enhanced management of Steam custom covers and quick matching of downloaded app
* [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)
* [SteamDesktopAuthenticator](https://github.com/Jessecar96/SteamDesktopAuthenticator)
+17 -41
View File
@@ -1,62 +1,37 @@
<img src="https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/icon/LOGO1.png" alt="logo" width="130" height="130" align="left" />
# Steam++工具箱
<h1>Steam++ 工具箱</h1>
「Steam++」是一个包含多种Steam工具功能的工具箱。
> 「Steam++」是一个包含多种Steam工具功能的工具箱,
> 此工具的大部分功能都是需要您下载安装Steam才能使用。
<br/>
此工具的大部分功能都是需要您下载安装Steam才能使用。
![Release Download](https://img.shields.io/github/downloads/rmbadmin/SteamTools/latest/total?style=flat-square)
[![Release Version](https://img.shields.io/github/v/release/rmbadmin/SteamTools?style=flat-square)](https://github.com/rmbadmin/SteamTools/releases/latest)
[![GitHub license](https://img.shields.io/github/license/rmbadmin/SteamTools?style=flat-square)](LICENSE)
[![GitHub Star](https://img.shields.io/github/stars/rmbadmin/SteamTools?style=flat-square)](https://github.com/rmbadmin/SteamTools/stargazers)
[![GitHub Fork](https://img.shields.io/github/forks/rmbadmin/SteamTools?style=flat-square)](https://github.com/rmbadmin/SteamTools/network/members)
![GitHub repo size](https://img.shields.io/github/repo-size/rmbadmin/SteamTools?style=flat-square&color=3cb371)
# Steam++
[English](https://github.com/rmbadmin/SteamTools/blob/develop/README.en.md)
[简体中文](https://github.com/rmbadmin/SteamTools/blob/develop/README.md)
## 效果展示
-------
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/s.png)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/e.png)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/e-1.png)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/t.png)
------
## 核心功能
### 1. 反代Steam的社区网页使其能正常访问
功能类似羽翼城大佬的[steamcommunity_302](https://www.dogfight360.com/blog/686/),使用[Titanium-Web-Proxy](https://github.com/justcoding121/Titanium-Web-Proxy)开源项目进行本地反代,使国内用户可以正常访问steam社区页,相比302工具具有更快的启动速度,以及支持简单的脚本注入。(还顺便支持了Pixiv、Discord、Twitch等网站的反代支持)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/1.png)
功能类似羽翼城大佬的Steam302,使用[Titanium-Web-Proxy](https://github.com/justcoding121/Titanium-Web-Proxy)开源项目进行本地反代,相比302工具具有更快的启动速度,以及支持简单的脚本注入。
---
### 2. 快速切换当前PC已经记住登陆的Steam账号
该功能是读取Steam路径下存储的本地用户登录记录直接展示操作,可以多账号切换无需重新输入密码和令牌。
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/2.png)
---
### 3. Steam游戏的成就统计管理功能
功能参考[SteamAchievementManager](https://github.com/gibbed/SteamAchievementManager)进行二次开发,修改了游戏列表的加载和操作易用性。
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/3.png)
---
### 4. Steam本地两步身份验证器
功能参考[WinAuth](https://github.com/winauth/winauth)开发,可以使您不用启动移动版Steam App也能查看您的令牌,功能类似的软件有[WinAuth](https://github.com/winauth/winauth)、[SteamDesktopAuthenticator](https://github.com/Jessecar96/SteamDesktopAuthenticator)。
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/4.png)
本地令牌交易市场报价确认
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/4-1.png)
---
### 5. 一些游戏工具
目前已有强制游戏无边框窗口化,CSGO修复VAC屏蔽。
这一块是随缘做一些我经常用或者闲着没事捣鼓的功能。
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/5.png)
![](https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/resources/5-1.png)
---
## 预计后续添加的功能
@@ -80,15 +55,16 @@
---
## 开发环境
> 开发工具 [Visual Studio 2019](https://visualstudio.microsoft.com/)
> 开发语言 C# WPF
> .NET版本 .NET Framework4.7.2 和 .NET5
> 如果无法运行请下载安装[.NET Framework 4.7.2](https://dotnet.microsoft.com/download/dotnet-framework/net472)或[.NET 5](https://dotnet.microsoft.com/download/dotnet/5.0)。
## 运行环境
> 程序使用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](https://github.com/rmbadmin/SteamTools/blob/develop/LICENSE)
> [GPL-3.0 License](LICENSE.txt)
> 根据GPLv3许可发布的开源/免费软件。
---
@@ -98,7 +74,7 @@
* [MetroRadiance](https://github.com/Grabacr07/MetroRadiance)
* [MetroTrilithon](https://github.com/Grabacr07/MetroTrilithon)
* [Livet](https://github.com/runceel/Livet)
* [StatefulModel](https://github.com/ugaya40/StatefulModel)
* [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)
@@ -82,7 +82,7 @@ namespace WinAuth
/// <summary>
/// Time for http request when calling Sync in ms
/// </summary>
private const int SYNC_TIMEOUT = 30000;
private const int SYNC_TIMEOUT = 5000;
/// <summary>
/// Steam issuer for KeyUri
@@ -32,7 +32,6 @@ using System.Web;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Threading.Tasks;
#if NETFX_4
using System.Runtime.Serialization;
using System.Threading.Tasks;
@@ -50,11 +49,11 @@ namespace WinAuth
/// </summary>
private const string COMMUNITY_DOMAIN = "steamcommunity.com";
private const string COMMUNITY_BASE = "https://" + COMMUNITY_DOMAIN;
private const string WEBAPI_BASE = "https://api.steampowered.com";
private const string API_GETWGTOKEN = WEBAPI_BASE + "/IMobileAuthService/GetWGToken/v0001";
private const string API_LOGOFF = WEBAPI_BASE + "/ISteamWebUserPresenceOAuth/Logoff/v0001";
private const string API_LOGON = WEBAPI_BASE + "/ISteamWebUserPresenceOAuth/Logon/v0001";
private const string API_POLLSTATUS = WEBAPI_BASE + "/ISteamWebUserPresenceOAuth/PollStatus/v0001";
private static string WEBAPI_BASE = "https://api.steampowered.com";
private static string API_GETWGTOKEN = WEBAPI_BASE + "/IMobileAuthService/GetWGToken/v0001";
private static string API_LOGOFF = WEBAPI_BASE + "/ISteamWebUserPresenceOAuth/Logoff/v0001";
private static string API_LOGON = WEBAPI_BASE + "/ISteamWebUserPresenceOAuth/Logon/v0001";
private static string API_POLLSTATUS = WEBAPI_BASE + "/ISteamWebUserPresenceOAuth/PollStatus/v0001";
/// <summary>
/// Default mobile user agent
@@ -64,11 +63,11 @@ namespace WinAuth
/// <summary>
/// Regular expressions for trade confirmations
/// </summary>
private static readonly Regex _tradesRegex = new Regex("\"mobileconf_list_entry\"(.*?)>(.*?)\"mobileconf_list_entry_sep\"", RegexOptions.Singleline | RegexOptions.IgnoreCase);
private static readonly Regex _tradeConfidRegex = new Regex(@"data-confid\s*=\s*""([^""]+)""", RegexOptions.Singleline | RegexOptions.IgnoreCase);
private static readonly Regex _tradeKeyRegex = new Regex(@"data-key\s*=\s*""([^""]+)""", RegexOptions.Singleline | RegexOptions.IgnoreCase);
private static readonly Regex _tradePlayerRegex = new Regex("\"mobileconf_list_entry_icon\"(.*?)src=\"([^\"]+)\"", RegexOptions.Singleline | RegexOptions.IgnoreCase);
private static readonly Regex _tradeDetailsRegex = new Regex("\"mobileconf_list_entry_description\".*?<div>([^<]*)</div>[^<]*<div>([^<]*)</div>[^<]*<div>([^<]*)</div>[^<]*</div>", RegexOptions.Singleline | RegexOptions.IgnoreCase);
private static Regex _tradesRegex = new Regex("\"mobileconf_list_entry\"(.*?)>(.*?)\"mobileconf_list_entry_sep\"", RegexOptions.Singleline | RegexOptions.IgnoreCase);
private static Regex _tradeConfidRegex = new Regex(@"data-confid\s*=\s*""([^""]+)""", RegexOptions.Singleline | RegexOptions.IgnoreCase);
private static Regex _tradeKeyRegex = new Regex(@"data-key\s*=\s*""([^""]+)""", RegexOptions.Singleline | RegexOptions.IgnoreCase);
private static Regex _tradePlayerRegex = new Regex("\"mobileconf_list_entry_icon\"(.*?)src=\"([^\"]+)\"", RegexOptions.Singleline | RegexOptions.IgnoreCase);
private static Regex _tradeDetailsRegex = new Regex("\"mobileconf_list_entry_description\".*?<div>([^<]*)</div>[^<]*<div>([^<]*)</div>[^<]*<div>([^<]*)</div>[^<]*</div>", RegexOptions.Singleline | RegexOptions.IgnoreCase);
/// <summary>
/// Number of Confirmation retries
@@ -130,11 +129,10 @@ namespace WinAuth
}
else
{
List<string> props = new List<string>
{
"\"duration\":" + this.Duration,
"\"action\":" + (int)this.Action
};
List<string> props = new List<string>();
props.Add("\"duration\":" + this.Duration);
props.Add("\"action\":" + (int)this.Action);
if (this.Ids != null)
{
props.Add("\"ids\":[" + (this.Ids.Count != 0 ? "\"" + string.Join("\",\"", this.Ids.ToArray()) + "\"" : string.Empty) + "]");
@@ -198,14 +196,14 @@ namespace WinAuth
/// </summary>
public class Confirmation
{
public string Id { get; set; }
public string Key { get; set; }
public bool Offline { get; set; }
public bool IsNew { get; set; }
public string Image { get; set; }
public string Details { get; set; }
public string Traded { get; set; }
public string When { get; set; }
public string Id;
public string Key;
public bool Offline;
public bool IsNew;
public string Image;
public string Details;
public string Traded;
public string When;
}
/// <summary>
@@ -534,22 +532,20 @@ namespace WinAuth
}
// login request
data = new NameValueCollection
{
{ "password", encryptedPassword64 },
{ "username", username },
{ "twofactorcode", this.Authenticator.CurrentCode },
//data.Add("emailauth", string.Empty);
{ "loginfriendlyname", "#login_emailauth_friendlyname_mobile" },
{ "captchagid", (string.IsNullOrEmpty(captchaId) == false ? captchaId : "-1") },
{ "captcha_text", (string.IsNullOrEmpty(captchaText) == false ? captchaText : "enter above characters") },
//data.Add("emailsteamid", (string.IsNullOrEmpty(emailcode) == false ? this.SteamId ?? string.Empty : string.Empty));
{ "rsatimestamp", rsaresponse.SelectToken("timestamp").Value<string>() },
{ "remember_login", "false" },
{ "oauth_client_id", "DE45CD61" },
{ "oauth_scope", "read_profile write_profile read_client write_client" },
{ "donotache", new DateTime().ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds.ToString() }
};
data = new NameValueCollection();
data.Add("password", encryptedPassword64);
data.Add("username", username);
data.Add("twofactorcode", this.Authenticator.CurrentCode);
//data.Add("emailauth", string.Empty);
data.Add("loginfriendlyname", "#login_emailauth_friendlyname_mobile");
data.Add("captchagid", (string.IsNullOrEmpty(captchaId) == false ? captchaId : "-1"));
data.Add("captcha_text", (string.IsNullOrEmpty(captchaText) == false ? captchaText : "enter above characters"));
//data.Add("emailsteamid", (string.IsNullOrEmpty(emailcode) == false ? this.SteamId ?? string.Empty : string.Empty));
data.Add("rsatimestamp", rsaresponse.SelectToken("timestamp").Value<string>());
data.Add("remember_login", "false");
data.Add("oauth_client_id", "DE45CD61");
data.Add("oauth_scope", "read_profile write_profile read_client write_client");
data.Add("donotache", new DateTime().ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds.ToString());
response = GetString(COMMUNITY_BASE + "/mobilelogin/dologin/", "POST", data);
Dictionary<string, object> loginresponse = JsonConvert.DeserializeObject<Dictionary<string, object>>(response);
@@ -644,11 +640,9 @@ namespace WinAuth
if (string.IsNullOrEmpty(this.Session.UmqId) == false)
{
var data = new NameValueCollection
{
{ "access_token", this.Session.OAuthToken },
{ "umqid", this.Session.UmqId }
};
var data = new NameValueCollection();
data.Add("access_token", this.Session.OAuthToken);
data.Add("umqid", this.Session.UmqId);
GetString(API_LOGOFF, "POST", data);
}
}
+33
View File
@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using SteamTools.Model;
using Newtonsoft.Json;
namespace SteamTools.Helper
{
public static class ConfigHelper
{
private const string ConfigFileName = "SteamToolData.dat";
private static readonly string ConfigPath =
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), ConfigFileName);
public static SteamToolConfig SteamToolConfig { get; set; }
public static void SaveConfig()
{
var jsonData = JsonConvert.SerializeObject(SteamToolConfig);
File.WriteAllText(ConfigPath, jsonData, Encoding.UTF8);
}
public static SteamToolConfig ReadConfig()
{
SteamToolConfig = JsonConvert.DeserializeObject<SteamToolConfig>(File.ReadAllText(ConfigPath, Encoding.UTF8));
return SteamToolConfig;
}
}
}
@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Win32;
namespace SteamTools.Helper
{
public static class RegistryKeyHelper
{
/// <summary>
/// 创建注册表项
/// </summary>
/// <param name="registryKey"></param>
/// <param name="path"></param>
/// <returns></returns>
public static RegistryKey CreateRegistryKey(RegistryKey registryKey, string path)
{
return registryKey.CreateSubKey(path);
}
/// <summary>
/// 删除注册表项
/// </summary>
/// <param name="registryKey"></param>
/// <param name="path"></param>
/// <returns></returns>
public static void DeleteRegistryKey(RegistryKey registryKey, string path)
{
registryKey.DeleteSubKey(path, true); //该方法无返回值,直接调用即可
registryKey.Close();
}
/// <summary>
/// 读取注册表值
/// </summary>
/// <param name="registryKey"></param>
/// <param name="path"></param>
/// <param name="key"></param>
/// <returns></returns>
public static string ReadRegistryKey(RegistryKey registryKey, string path, string key)
{
var myreg = registryKey.OpenSubKey(path);
if (myreg != null)
{
var info = myreg.GetValue(key).ToString();
myreg.Close();
return info;
}
return string.Empty;
}
/// <summary>
/// 新增或修改注册表值
/// </summary>
/// <param name="registryKey"></param>
/// <param name="path"></param>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="registryValueKind"></param>
/// <returns></returns>
public static void AddOrUpdateRegistryKey(RegistryKey registryKey, string path, string key, string value, RegistryValueKind registryValueKind)
{
RegistryKey myreg = registryKey.OpenSubKey(path, true); //该项必须已存在
if (myreg != null)
{
myreg.SetValue(key, value, registryValueKind);
myreg.Close();
}
}
}
}
+107
View File
@@ -0,0 +1,107 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Gameloop.Vdf.Linq;
using Microsoft.Win32;
using SteamTool.Common.Helper;
using SteamTools.Model;
namespace SteamTools.Helper
{
public class SteamHelper
{
public static readonly SteamHelper Instance = new SteamHelper();
public string SteamPath { get; set; }
public string SteamExePath { get; set; }
private const string SteamRegistryPath = @"SOFTWARE\Valve\Steam";
public SteamHelper()
{
var steamExePath = RegistryKeyHelper.ReadRegistryKey(Registry.CurrentUser, SteamRegistryPath, "SteamExe");
var steamPath = RegistryKeyHelper.ReadRegistryKey(Registry.CurrentUser, SteamRegistryPath, "SteamPath");
if (File.Exists(steamExePath))
{
SteamExePath = steamExePath;
}
if (Directory.Exists(steamPath))
{
SteamPath = steamPath;
}
}
public void KillSteamProcess()
{
Process[] processes = Process.GetProcesses();
foreach (Process process in processes)
{
if (process.ProcessName == "Steam" || process.ProcessName == "SteamService" || process.ProcessName == "steamwebhelper")
{
process.Kill();
}
}
}
public void StartSteam(string param = "")
{
if (!string.IsNullOrEmpty(SteamExePath))
{
Process.Start(SteamExePath, param);
}
}
/// <summary>
/// 获取最后一次自动登陆steam用户名称
/// </summary>
/// <returns></returns>
public string GetLastLoginUserName()
{
return RegistryKeyHelper.ReadRegistryKey(Registry.CurrentUser, SteamRegistryPath, "AutoLoginUser");
}
/// <summary>
/// 获取所有记住登陆steam用户信息
/// </summary>
/// <returns></returns>
public List<SteamUser> GetAllUser()
{
var users = new List<SteamUser>();
if (SteamPath != null)
{
var v = VdfHelper.GetVdfModelByPath(SteamPath + "/config/loginusers.vdf");
foreach (var item in v.Value)
{
var i = item.Value;
var user = new SteamUser
{
AccountName = i.AccountName.ToString(),
PersonaName = i.PersonaName.ToString(),
RememberPassword = Convert.ToBoolean(Convert.ToInt64(i.RememberPassword.ToString())),
MostRecent = Convert.ToBoolean(Convert.ToInt64(i.MostRecent.ToString())),
Timestamp = Convert.ToInt64(i.Timestamp.ToString())
};
user.LastLoginTime= new DateTime(1970, 1, 1, 8, 0, 0).AddSeconds(user.Timestamp);
users.Add(user);
}
}
return users;
}
/// <summary>
/// 设置下次登陆steam用户
/// </summary>
public void SetCurrentUser(string username)
{
RegistryKeyHelper.AddOrUpdateRegistryKey(Registry.CurrentUser, SteamRegistryPath, "AutoLoginUser", username, RegistryValueKind.String);
}
}
}
+35
View File
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Gameloop.Vdf;
using Gameloop.Vdf.Linq;
namespace SteamTool.Common.Helper
{
public static class VdfHelper
{
/// <summary>
/// 获取VDF类型内容
/// </summary>
/// <param name="path">vdf文件内容</param>
/// <returns></returns>
public static dynamic GetVdfModel(string text)
{
return VdfConvert.Deserialize(text);
}
/// <summary>
/// 根据路径获取VDF类型内容
/// </summary>
/// <param name="path">vdf文件路径</param>
/// <returns></returns>
public static dynamic GetVdfModelByPath(string path)
{
string text = File.ReadAllText(path,Encoding.UTF8);
return GetVdfModel(text); ;
}
}
}
+21
View File
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SteamTools.Model
{
public class SteamToolConfig
{
/// <summary>
/// 启动参数
/// </summary>
public string SteamRunParam { get; set; }
/// <summary>
/// 保存用户
/// </summary>
public List<SteamUser> SteamUsers { get; set; }
}
}
+65
View File
@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SteamTools.Model
{
public class SteamUser
{
public string SteamId3 { get; set; }
public int SteamId3_Int { get; }
public string SteamId32 { get; set; }
public int SteamId32_Int { get; }
public long SteamId64 { get; set; }
/// <summary>
/// 个人资料链接
/// </summary>
public string ProfileUrl { get; set; }
/// <summary>
/// 昵称
/// </summary>
public string PersonaName { get; set; }
/// <summary>
/// 用户名
/// </summary>
public string AccountName { get; set; }
/// <summary>
/// 是否记住密码
/// </summary>
public bool RememberPassword { get; set; }
/// <summary>
/// 密码
/// </summary>
public string PassWord { get; set; }
/// <summary>
/// 最后登录时间戳
/// </summary>
public long Timestamp { get; set; }
/// <summary>
/// 最后登录时间
/// </summary>
public DateTime LastLoginTime { get; set; }
/// <summary>
/// 最近登录
/// </summary>
public bool MostRecent { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
}
}
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("SteamTool.Common")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SteamTool.Common")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("75e148c7-5f32-4f01-9444-cedefa28748a")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SteamTool.Common.Service
{
public class SteamToolsService
{
}
}
+74
View File
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{75E148C7-5F32-4F01-9444-CEDEFA28748A}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SteamTool.Common</RootNamespace>
<AssemblyName>SteamTool.Common</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == '发布|AnyCPU'">
<OutputPath>bin\发布\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Gameloop.Vdf, Version=0.6.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Gameloop.Vdf.0.6.1\lib\net45\Gameloop.Vdf.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Helper\ConfigHelper.cs" />
<Compile Include="Helper\RegistryKeyHelper.cs" />
<Compile Include="Helper\SteamHelper.cs" />
<Compile Include="Helper\VdfHelper.cs" />
<Compile Include="Model\SteamToolConfig.cs" />
<Compile Include="Model\SteamUser.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Service\SteamToolsService.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
+5
View File
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Gameloop.Vdf" version="0.6.1" targetFramework="net46" />
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net46" />
</packages>
+26
View File
@@ -0,0 +1,26 @@
using SteamTool.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace SteamTool.Proxy
{
public static class CertificateEx
{
public static string GetPublicPemCertificateString(this X509Certificate2 @this)
{
StringBuilder builder = new StringBuilder();
builder.AppendLine(Const.HOST_TAG);
builder.AppendLine("-----BEGIN CERTIFICATE-----");
builder.AppendLine(
Convert.ToBase64String(@this.RawData, Base64FormattingOptions.InsertLineBreaks));
builder.AppendLine("-----END CERTIFICATE-----");
builder.AppendLine(Const.HOST_TAG);
return builder.ToString();
}
}
}
@@ -9,15 +9,6 @@ namespace SteamTool.Core.Common
{
public static class Common
{
/// <summary>
/// 时间戳转DateTime(系统时区)
/// </summary>
/// <returns></returns>
public static DateTime ToDateTime(this long timestamp)
{
return TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(timestamp), TimeZoneInfo.Local);
}
/// <summary>
/// 返回当前时间戳
/// </summary>
@@ -46,16 +37,6 @@ namespace SteamTool.Core.Common
}
}
/// <summary>
/// 移除字符串内所有\r \n \t
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string RemovePattern(this string inputString)
{
return inputString.Replace("\t", "").Replace("\r", "").Replace("\n", "");
}
/// <summary>
/// 获取两个字符串中间的字符串
/// </summary>
@@ -92,7 +92,7 @@ namespace SteamTool.Core
try
{
dataLines.Add($"{ip} {domain} {Const.HOST_TAG}");
File.WriteAllLines(HostsPath, dataLines, Encoding.UTF8);
File.WriteAllLines(HostsPath, dataLines);
//File.SetAttributes(HostsPath, FileAttributes.ReadOnly);
result.ResultType = OperationResultType.Success;
@@ -153,7 +153,7 @@ namespace SteamTool.Core
}
try
{
File.WriteAllLines(HostsPath, dataLines, Encoding.UTF8);
File.WriteAllLines(HostsPath, dataLines);
//File.SetAttributes(HostsPath, FileAttributes.ReadOnly);
result.ResultType = OperationResultType.Success;
result.Message = Resources.Hosts_UpdateSuccess;
@@ -197,7 +197,7 @@ namespace SteamTool.Core
try
{
File.WriteAllLines(HostsPath, dataLines, Encoding.UTF8);
File.WriteAllLines(HostsPath, dataLines);
//File.SetAttributes(HostsPath, FileAttributes.ReadOnly);
result.ResultType = OperationResultType.Success;
@@ -240,7 +240,7 @@ namespace SteamTool.Core
try
{
File.WriteAllLines(HostsPath, dataLines, Encoding.UTF8);
File.WriteAllLines(HostsPath, dataLines);
//File.SetAttributes(HostsPath, FileAttributes.ReadOnly);
result.ResultType = OperationResultType.Success;
result.Message = Resources.Hosts_UpdateSuccess;
@@ -255,6 +255,7 @@ namespace SteamTool.Core
return result;
}
public void StartNotepadEditHosts()
{
System.Diagnostics.Process.Start("notepad.exe", HostsPath);
@@ -1,6 +1,5 @@
using Newtonsoft.Json;
using Ninject.Modules;
using SteamTool.Core.Common;
using System;
using System.Collections.Generic;
using System.Dynamic;
@@ -20,47 +19,23 @@ namespace SteamTool.Core
public string Accept { get; set; } = "application/json";
private async Task<string> SendAsync(HttpRequestMessage request)
{
try
{
var response = await _client.SendAsync(request).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
}
catch (Exception ex)
{
Logger.Error(ex);
}
return null;
}
private async Task<Stream> SendAsyncAsStream(HttpRequestMessage request)
{
try
{
var response = await _client.SendAsync(request).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
}
}
catch (Exception ex)
{
Logger.Error(ex);
}
return null;
}
public async Task<string> Get(string url)
{
var request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Add("User-Agent", UserAgent);
request.Headers.Add("Accept", Accept);
return await SendAsync(request);
var response = await _client.SendAsync(request).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
else
{
return null;
}
}
public async Task<string> Get(string url, Dictionary<string, string> keyValuePairs)
{
@@ -78,7 +53,20 @@ namespace SteamTool.Core
{
request.Headers.Add("Accept", Accept);
}
return await SendAsync(request);
var response = await _client.SendAsync(request).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
else
{
return null;
}
}
public async Task<Stream> GetStream(string url, Dictionary<string, string> keyValuePairs)
{
@@ -97,7 +85,18 @@ namespace SteamTool.Core
request.Headers.Add("Accept", Accept);
}
return await SendAsyncAsStream(request);
var response = await _client.SendAsync(request).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
}
else
{
return null;
}
}
public async Task<string> Post(string url, string content)
@@ -108,7 +107,18 @@ namespace SteamTool.Core
};
request.Headers.Add("User-Agent", UserAgent);
request.Headers.Add("Accept", Accept);
return await SendAsync(request);
var response = await _client.SendAsync(request).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
else
{
return null;
}
}
public async Task<string> Post(string url, Dictionary<string, string> keyValuePairs, string content)
{
@@ -129,7 +139,18 @@ namespace SteamTool.Core
request.Headers.Add("Accept", Accept);
}
return await SendAsync(request);
var response = await _client.SendAsync(request).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
else
{
return null;
}
}
public async Task<Stream> PostStream(string url, Dictionary<string, string> keyValuePairs, Stream content)
{
@@ -150,7 +171,18 @@ namespace SteamTool.Core
request.Headers.Add("Accept", Accept);
}
return await SendAsyncAsStream(request);
var response = await _client.SendAsync(request).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
}
else
{
return null;
}
}
}
}
@@ -12,7 +12,6 @@
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Ninject" Version="3.3.4" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.9" />
<PackageReference Include="SharpZipLib" Version="1.3.1" />
<PackageReference Include="System.Management" Version="5.0.0" />
<PackageReference Include="TaskScheduler" Version="2.9.0" />
@@ -37,11 +37,6 @@ namespace SteamTool.Core
public const string UserDataDirectory = @"\userdata";
/*
Windows: ~\Steam\config\loginusers.vdf
Linux: ~/.steam/steam/config/loginusers.vdf
Mac: ~/Library/Application Support/Steam/config/loginusers.vdf
*/
public const string UserVdfPath = @"\config\loginusers.vdf";
private const string SteamRegistryPath = @"SOFTWARE\Valve\Steam";
@@ -50,13 +45,15 @@ namespace SteamTool.Core
{
var steamExePath = registryKeyService.ReadRegistryKey(Registry.CurrentUser, SteamRegistryPath, "SteamExe");
var steamPath = registryKeyService.ReadRegistryKey(Registry.CurrentUser, SteamRegistryPath, "SteamPath");
//steamExePath = Path.GetFullPath(steamExePath);
//steamPath = Path.GetFullPath(steamPath);
if (File.Exists(steamExePath))
{
SteamExePath = Path.GetFullPath(steamExePath);
SteamExePath = steamExePath;
}
if (Directory.Exists(steamPath))
{
SteamPath = Path.GetFullPath(steamPath);
SteamPath = steamPath;
}
}
@@ -65,7 +62,7 @@ namespace SteamTool.Core
Process[] processes = Process.GetProcesses();
foreach (Process process in processes)
{
if (process.ProcessName.Equals("steam", StringComparison.OrdinalIgnoreCase) || process.ProcessName.Equals("steamservice", StringComparison.OrdinalIgnoreCase) || process.ProcessName.Equals("steamwebhelper", StringComparison.OrdinalIgnoreCase))
if (process.ProcessName.Equals("steam", StringComparison.OrdinalIgnoreCase) || process.ProcessName.Equals("steamService", StringComparison.OrdinalIgnoreCase) || process.ProcessName.Equals("steamwebhelper", StringComparison.OrdinalIgnoreCase))
{
process.Kill();
}
@@ -93,40 +90,38 @@ namespace SteamTool.Core
/// 获取所有记住登陆steam用户信息
/// </summary>
/// <returns></returns>
public List<SteamUser> GetRememberUserList()
public List<SteamUser> GetAllUser()
{
var users = new List<SteamUser>();
if (File.Exists(SteamPath + UserVdfPath))
{
var v = vdfService.GetVdfModelByPath(SteamPath + UserVdfPath);
foreach (var item in v.Value)
{
var i = item.Value;
var user = new SteamUser(item.ToString())
var user = new SteamUser
{
SteamId64 = Convert.ToInt64(item.Key.ToString()),
AccountName = i.AccountName?.ToString(),
SteamID = i.PersonaName?.ToString(),
PersonaName = i.PersonaName?.ToString(),
RememberPassword = Convert.ToBoolean(Convert.ToInt64(i.RememberPassword?.ToString())),
Timestamp = Convert.ToInt64(i.Timestamp?.ToString())
};
user.LastLoginTime = user.Timestamp.ToDateTime();
//老版本Steam数据 小写mostrecent 支持
user.MostRecent = i.mostrecent != null ?
Convert.ToBoolean(Convert.ToByte(i.mostrecent.ToString())) :
Convert.ToBoolean(Convert.ToByte(i.MostRecent.ToString()));
user.WantsOfflineMode = i.WantsOfflineMode != null ?
Convert.ToBoolean(Convert.ToByte(i.WantsOfflineMode.ToString())) : false;
// 因为警告这个东西应该都不需要所以直接默认跳过好了
user.SkipOfflineModeWarning = true;
//user.SkipOfflineModeWarning = i.SkipOfflineModeWarning != null ?
// Convert.ToBoolean(Convert.ToByte(i.SkipOfflineModeWarning.ToString())) : false;
user.LastLoginTime = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(user.Timestamp), TimeZoneInfo.Local);
if (i.mostrecent != null)//老版本Steam数据 小写mostrecent 支持
{
user.MostRecent = Convert.ToBoolean(Convert.ToInt64(i.mostrecent.ToString()));
}
else if (i.MostRecent != null)
{
user.MostRecent = Convert.ToBoolean(Convert.ToInt64(i.MostRecent.ToString()));
}
else
{
user.MostRecent = false;
}
users.Add(user);
}
}
@@ -219,10 +214,5 @@ namespace SteamTool.Core
Directory.Delete(temp, true);
}
}
public void UpdateSteamLocalUserData(SteamUser user)
{
vdfService.UpdateVdfValueByReplace(SteamPath + UserVdfPath, user.OriginVdfString, user.CurrentVdfString);
}
}
}
@@ -7,7 +7,6 @@ using System.Text;
using System.Threading.Tasks;
using Gameloop.Vdf;
using Gameloop.Vdf.Linq;
using SteamTool.Core.Common;
namespace SteamTool.Core
{
@@ -34,14 +33,6 @@ namespace SteamTool.Core
return GetVdfModel(text);
}
public void UpdateVdfValueByReplace(string path, string oldVaule, string newValue)
{
string text = File.ReadAllText(path, Encoding.UTF8);
text = text.RemovePattern().Replace(
oldVaule.RemovePattern().Replace(" ",string.Empty), newValue);
//Debug.WriteLine(text);
File.WriteAllText(path, text, Encoding.UTF8);
}
public void DeleteVdfValueByKey(string path, string key)
{
@@ -53,13 +44,5 @@ namespace SteamTool.Core
//Debug.WriteLine(text);
File.WriteAllText(path, text, Encoding.UTF8);
}
public void DeleteVdfValueByReplace(string path, string oldVaule)
{
string text = File.ReadAllText(path, Encoding.UTF8);
text = text.Replace(oldVaule, string.Empty);
//Debug.WriteLine(text);
File.WriteAllText(path, text, Encoding.UTF8);
}
}
}
@@ -8,7 +8,6 @@ namespace SteamTool.Model
public const string AUTHDATA_FILE = "authenticators.dat";
public const string SETTINGS_FILE = "settings.json";
public const string SCRIPT_DIR = "scripts";
public const string LOG_DIR = "log";
public const string HOST_TAG = "#S302";
public const string REWARDMELIST_URL = "https://gitee.com/rmbgame/steam-tools_-data/raw/master/RewardRecord.json";
@@ -42,11 +41,5 @@ namespace SteamTool.Model
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}";
//https://steamcommunity.com/profiles/76561198289531723?xml=1
public const string STEAM_USERINFO_XML_URL = "https://steamcommunity.com/profiles/{0}?xml=1";
public const string STEAMCN_USERINFO_XML_URL = "https://my.steamchina.com/profiles/76561198289531723?xml=1";
}
}
@@ -16,7 +16,7 @@ namespace SteamTool.Model
public bool IsHidden { get; set; }
public bool IsAchieved { get; set; }
public bool IsChecked { get; set; }
public long UnlockTimeUnix { get; set; }
public int UnlockTimeUnix { get; set; }
public DateTime UnlockTime { get; set; }
public string IconUrl => IsAchieved ? string.Format(Const.STEAMAPP_ICON_URL, AppId, IconNormal) : string.Format(Const.STEAMAPP_ICON_URL, AppId, IconLocked);
public int Permission { get; set; }
@@ -1,25 +1,15 @@
using System;
using System.Xml.Serialization;
namespace SteamTool.Model
{
[XmlRoot("profile")]
public class SteamUser
{
public SteamUser() { }
public SteamUser(string vdfstring)
{
OriginVdfString = vdfstring;
}
public string SteamId3 { get; set; }
public long SteamId3_Int => ((SteamId64 >> (ushort)0) & 0xFFFFFFFF);
public string SteamId32 { get; set; }
public long SteamId32_Int { get; set; }
[XmlElement("steamID64")]
public long SteamId64 { get; set; }
/// <summary>
@@ -30,7 +20,6 @@ namespace SteamTool.Model
/// <summary>
/// 在线状态
/// </summary>
[XmlElement("onlineState")]
public string OnlineState { get; set; }
public string IPCountry { get; set; }
@@ -40,42 +29,32 @@ namespace SteamTool.Model
/// friendsonly
/// public
/// </summary>
[XmlElement("privacyState")]
public string PrivacyState { get; set; }
/// <summary>
/// 头像小图标
/// 头像链接
/// </summary>
[XmlElement("avatarIcon")]
public string AvatarIcon { get; set; }
/// <summary>
/// 头像中等图片链接
/// 头像链接
/// </summary>
[XmlElement("avatarMedium")]
public string AvatarMedium { get; set; } = "/Resources/Asstes/avater.jpg";
public string AvatarMedium { get; set; }
/// <summary>
/// 头像大图链接
/// 头像链接
/// </summary>
[XmlElement("avatarFull")]
public string AvatarFull { get; set; }
/// <summary>
/// 昵称
/// </summary>
[XmlElement("steamID")]
public string SteamID { get; set; }
/// <summary>
/// 昵称
/// </summary>
public string SteamNickName => string.IsNullOrEmpty(SteamID) ? PersonaName : SteamID;
/// <summary>
/// 从VDF读取到的用户名
/// </summary>
public string PersonaName { get; set; }
public string SteamNickName => string.IsNullOrEmpty(SteamID) ? "无法获取此账户昵称" : SteamID;
/// <summary>
/// 用户名
@@ -107,37 +86,9 @@ namespace SteamTool.Model
/// </summary>
public bool MostRecent { get; set; }
/// <summary>
/// 离线模式
/// </summary>
public bool WantsOfflineMode { get; set; }
/// <summary>
/// 忽略离线模式警告弹窗
/// </summary>
public bool SkipOfflineModeWarning { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
/// <summary>
/// 来源VDF字符串
/// </summary>
public string OriginVdfString { get; set; }
/// <summary>
/// 导出VDF配置字符串
/// </summary>
public string CurrentVdfString =>
"\"" + SteamId64 + "\"\n{\n" +
"\t\t\"AccountName\"\t\t\"" + AccountName + "\"\n" +
"\t\t\"PersonaName\"\t\t\"" + PersonaName + "\"\n" +
"\t\t\"RememberPassword\"\t\t\"" + Convert.ToByte(RememberPassword) + "\"\n" +
"\t\t\"MostRecent\"\t\t\"" + Convert.ToByte(MostRecent) + "\"\n" +
"\t\t\"WantsOfflineMode\"\t\t\"" + Convert.ToByte(WantsOfflineMode) + "\"\n" +
"\t\t\"SkipOfflineModeWarning\"\t\t\"" + Convert.ToByte(SkipOfflineModeWarning) + "\"\n" +
"\t\t\"Timestamp\"\t\t\"" + Timestamp + "\"\n}";
}
}
@@ -23,7 +23,7 @@ namespace SteamTool.Model.ToolModel
public string url { get; set; }
public string name { get; set; }
public string content_type { get; set; }
public long size { 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; }
@@ -14,9 +14,6 @@ using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Models;
using SteamTool.Model;
using System.Security.Cryptography;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.X509;
namespace SteamTool.Proxy
{
@@ -30,19 +27,13 @@ namespace SteamTool.Proxy
public IReadOnlyCollection<ProxyDomainModel> ProxyDomains { get; set; }
public List<ProxyScript> Scripts { get; set; }
public bool IsEnableScript { get; set; }
public bool IsOnlyWorkSteamBrowser { get; set; }
public string CertificateName { get; }
public HttpProxy(IReadOnlyCollection<ProxyDomainModel> proxyDomains, string certificateName)
{
proxyServer.ThreadPoolWorkerThread = Environment.ProcessorCount * 8;
ProxyDomains = proxyDomains;
CertificateName = certificateName;
//proxyServer.CertificateManager.PfxPassword = $"{CertificateName}";
proxyServer.ThreadPoolWorkerThread = Environment.ProcessorCount * 8;
proxyServer.CertificateManager.PfxFilePath = Path.Combine(AppContext.BaseDirectory, $@"{CertificateName}.Certificate.pfx");
proxyServer.CertificateManager.RootCertificateIssuerName = $"{CertificateName} Certificate Authority";
proxyServer.CertificateManager.RootCertificateName = $"{CertificateName} Certificate";
proxyServer.CertificateManager.CertificateEngine = Titanium.Web.Proxy.Network.CertificateEngine.DefaultWindows;
}
public bool ProxyRunning => proxyServer.ProxyRunning;
@@ -75,19 +66,18 @@ namespace SteamTool.Proxy
#endregion
Debug.WriteLine("OnRequest " + e.HttpClient.Request.RequestUri.AbsoluteUri);
Debug.WriteLine("OnRequest HTTP " + e.HttpClient.Request.HttpVersion);
//Logger.Info("OnRequest" + e.HttpClient.Request.RequestUri.AbsoluteUri);
#endif
// Dns.GetHostAddressesAsync(e.HttpClient.Request.Host).ContinueWith(s =>
//{
// //部分运营商将奇怪的域名解析到127.0.0.1 再此排除这些不支持的代理域名
// if (IPAddress.IsLoopback(s.Result.FirstOrDefault())
// && ProxyDomains.Count(w => w.IsEnable && w.Hosts.Contains(e.HttpClient.Request.Host)) == 0)
// {
// e.Ok($"URL : {e.HttpClient.Request.RequestUri.AbsoluteUri} \r\n not support proxy");
// return;
// }
//});
//Logger.Info("Steam++ OnRequest: " + e.HttpClient.Request.RequestUri.AbsoluteUri);
Logger.Info("OnRequest" + e.HttpClient.Request.RequestUri.AbsoluteUri);
#endif
await Dns.GetHostAddressesAsync(e.HttpClient.Request.Host).ContinueWith(s =>
{
//部分运营商将奇怪的域名解析到127.0.0.1 再此排除这些不支持的代理域名
if (IPAddress.IsLoopback(s.Result.FirstOrDefault())
&& ProxyDomains.Count(w => w.IsEnable && w.Hosts.Contains(e.HttpClient.Request.Host)) == 0)
{
e.Ok($"URL : {e.HttpClient.Request.RequestUri.AbsoluteUri} \r\n not support proxy");
return;
}
});
foreach (var item in ProxyDomains)
{
if (!item.IsEnable)
@@ -98,10 +88,6 @@ namespace SteamTool.Proxy
{
if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains(host))
{
if (e.HttpClient.Request.RequestUri.Scheme.Equals("http", StringComparison.OrdinalIgnoreCase))
{
e.Redirect(e.HttpClient.Request.RequestUri.AbsoluteUri.Remove(0, 4).Insert(0, "https"));
}
IPAddress iP = null;
if (!string.IsNullOrEmpty(item.ProxyIPAddres))
{
@@ -111,7 +97,6 @@ namespace SteamTool.Proxy
{
var iPs = await Dns.GetHostAddressesAsync(item.ToDomain);
iP = iPs.FirstOrDefault();
//Logger.Info("Proxy IP: " + iP);
}
if (iP != null)
{
@@ -119,7 +104,6 @@ namespace SteamTool.Proxy
}
if (e.HttpClient.ConnectRequest?.ClientHelloInfo != null)
{
//Logger.Info("ClientHelloInfo Info: " + e.HttpClient.ConnectRequest.ClientHelloInfo);
if (!string.IsNullOrEmpty(item.ServerName))
{
var sni = e.HttpClient.ConnectRequest.ClientHelloInfo.Extensions["server_name"];
@@ -131,36 +115,21 @@ namespace SteamTool.Proxy
e.HttpClient.ConnectRequest.ClientHelloInfo.Extensions.Remove("server_name");
}
}
return;
}
}
}
//没有匹配到的结果直接返回不支持,避免出现Loopback死循环内存溢出
e.Ok($"URL : {e.HttpClient.Request.RequestUri.AbsoluteUri} {Environment.NewLine}not support proxy");
return;
}
public async Task OnResponse(object sender, SessionEventArgs e)
{
// read response headers
//var responseHeaders = e.HttpClient.Response.Headers;
//if (!e.ProxySession.Request.Host.Equals("medeczane.sgk.gov.tr")) return;
#if DEBUG
Debug.WriteLine("OnResponse" + e.HttpClient.Request.RequestUri.AbsoluteUri);
Logger.Info("OnResponse" + e.HttpClient.Request.RequestUri.AbsoluteUri);
#endif
if (IsEnableScript)
{
if (IsOnlyWorkSteamBrowser)
{
var ua = e.HttpClient.Request.Headers.GetHeaders("User-Agent");
if (ua.Any())
{
if (!ua.First().Value.Contains("Valve Steam"))
{
return;
}
}
else
return;
}
foreach (var script in Scripts)
{
if (script.Enable)
@@ -181,12 +150,12 @@ namespace SteamTool.Proxy
if (e.HttpClient.Request.RequestUri.AbsoluteUri.IsWildcard(host))
{
var doc = await e.GetResponseBodyAsString();
if (script.Require.Length > 0 || script.Grant.Length > 0)
if (script.Require.Length > 0)
{
//var headIndex = doc.LastIndexOf("</head>", StringComparison.OrdinalIgnoreCase);
//doc = doc.Insert(headIndex, "<meta http-equiv=\"Content-Security-Policy\" content=\"default - src 'self' data: gap: https://ssl.gstatic.com 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *\">");
var t = e.HttpClient.Response.Headers.GetFirstHeader("Content-Security-Policy");
if (!string.IsNullOrEmpty(t?.Value))
if (!string.IsNullOrEmpty(t.Value))
{
//var tt = t.Value.Split(';');
//for (var i = 0; i < tt.Length; i++)
@@ -231,23 +200,26 @@ namespace SteamTool.Proxy
close:;
}
}
}
//// 允许重写默认的证书验证逻辑
//public Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)
//{
// // 根据证书错误,设置IsValid为真/假
// //if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
// e.IsValid = true;
// return Task.CompletedTask;
//}
// 允许重写默认的证书验证逻辑
public Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)
{
// 根据证书错误,设置IsValid为真/假
if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
e.IsValid = true;
return Task.CompletedTask;
}
//// 允许在相互身份验证期间重写默认客户端证书选择逻辑
//public Task OnCertificateSelection(object sender, CertificateSelectionEventArgs e)
//{
// // set e.clientCertificate to override
// return Task.CompletedTask;
//}
// 允许在相互身份验证期间重写默认客户端证书选择逻辑
public Task OnCertificateSelection(object sender, CertificateSelectionEventArgs e)
{
// set e.clientCertificate to override
return Task.CompletedTask;
}
public bool SetupCertificate()
{
@@ -256,22 +228,20 @@ namespace SteamTool.Proxy
//proxyServer.CertificateManager
// .CreateServerCertificate($"{Assembly.GetCallingAssembly().GetName().Name} Certificate")
// .ContinueWith(c => proxyServer.CertificateManager.RootCertificate = c.Result);
proxyServer.CertificateManager.PfxFilePath = Path.Combine(AppContext.BaseDirectory, $@"{CertificateName}.Certificate.pfx");
//proxyServer.CertificateManager.PfxPassword = $"{CertificateName}";
proxyServer.CertificateManager.RootCertificateIssuerName = CertificateName;
proxyServer.CertificateManager.RootCertificateName = $"{CertificateName} Certificate";
proxyServer.CertificateManager.CertificateEngine = Titanium.Web.Proxy.Network.CertificateEngine.DefaultWindows;
// 可选地设置证书引擎
// 在Mono之下,只有BouncyCastle将得到支持
//proxyServer.CertificateManager.CertificateEngine = Network.CertificateEngine.BouncyCastle;
//proxyServer.CertificateManager.SaveFakeCertificates = true;
var result = proxyServer.CertificateManager.CreateRootCertificate(true);
//if (result)
//{
if (!result)
{
Logger.Error("创建证书失败");
}
proxyServer.CertificateManager.RootCertificate.SaveCerCertificateFile(Path.Combine(AppContext.BaseDirectory, $@"{CertificateName}.Certificate.cer"));
proxyServer.CertificateManager.SaveFakeCertificates = false;
proxyServer.CertificateManager.CreateRootCertificate(true);
proxyServer.CertificateManager.EnsureRootCertificate();
//}
//proxyServer.CertificateManager.TrustRootCertificate(true);
return IsCertificateInstalled(proxyServer.CertificateManager.RootCertificate);
}
@@ -281,19 +251,22 @@ namespace SteamTool.Proxy
return false;
try
{
//using (var store = new X509Store(StoreName.Root, StoreLocation.CurrentUser))
//{
// store.Open(OpenFlags.MaxAllowed);
// var test = store.Certificates.Find(X509FindType.FindByIssuerName, CertificateName, true);
// foreach (var item in test)
// {
// store.Remove(item);
// }
//}
//proxyServer.CertificateManager.ClearRootCertificate();
proxyServer.CertificateManager.RemoveTrustedRootCertificate();
//proxyServer.CertificateManager.RemoveTrustedRootCertificateAsAdmin();
//proxyServer.CertificateManager.CertificateStorage.Clear();
using (var store = new X509Store(StoreName.Root, StoreLocation.CurrentUser))
{
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)
{
@@ -338,10 +311,10 @@ namespace SteamTool.Proxy
return false;
}
}
//if (PortInUse(443))
//{
// return false;
//}
if (PortInUse(443))
{
return false;
}
if (IsProxyGOG) { WirtePemCertificateToGoGSteamPlugins(); }
#region 写入Hosts
@@ -352,13 +325,7 @@ namespace SteamTool.Proxy
{
foreach (var host in proxyDomain.Hosts)
{
if (host.Contains(" "))
{
var h = host.Split(' ');
hosts.Add((h[0], h[1]));
}
else
hosts.Add((IPAddress.Loopback.ToString(), host));
hosts.Add((IPAddress.Loopback.ToString(), host));
}
}
}
@@ -371,27 +338,27 @@ namespace SteamTool.Proxy
//proxyServer.ServerCertificateValidationCallback += OnCertificateValidation;
//proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection;
//var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8888, true)
//var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 443, true)
//{
// // 在所有https请求上使用自颁发的通用证书
// // 通过不为每个启用http的域创建证书来优化性能
// // 当代理客户端不需要证书信任时非常有用
// //GenericCertificate = new X509Certificate2(Path.Combine(AppContext.BaseDirectory, "genericcert.pfx"), "password")
//};
//当接收到连接请求时触发
//explicitEndPoint.BeforeTunnelConnectRequest += OnBeforeTunnelRequest;
//explicit endpoint 是客户端知道代理存在的地方
//因此,客户端以代理友好的方式发送请求
//proxyServer.AddEndPoint(explicitEndPoint);
proxyServer.AddEndPoint(new TransparentProxyEndPoint(IPAddress.Any, 443, true)
// 透明endpoint 对于反向代理很有用(客户端不知道代理的存在)
// 透明endpoint 通常需要一个网络路由器端口来转发HTTP(S)包或DNS
// 发送数据到此endpoint
var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 443, true)
{
// 通过不启用为每个http的域创建证书来优化性能
//GenericCertificate = proxyServer.CertificateManager.RootCertificate
});
proxyServer.AddEndPoint(new TransparentProxyEndPoint(IPAddress.Any, 80, true));
proxyServer.ExceptionFunc = ((Exception exception) =>
{
Logger.Error(exception);
});
//GenericCertificateName= "steamcommunity-a.akamaihd.net"
};
proxyServer.AddEndPoint(transparentEndPoint);
try
{
proxyServer.Start();
@@ -401,10 +368,10 @@ namespace SteamTool.Proxy
Logger.Error(ex);
return false;
}
//proxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
//proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
#endregion
#if DEBUG
foreach (var endPoint in proxyServer.ProxyEndPoints)
Debug.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ",
@@ -420,8 +387,8 @@ namespace SteamTool.Proxy
{
proxyServer.BeforeRequest -= OnRequest;
proxyServer.BeforeResponse -= OnResponse;
//proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation;
//proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection;
proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation;
proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection;
proxyServer.Stop();
hostsService.RemoveHostsByTag();
}
@@ -445,7 +412,7 @@ namespace SteamTool.Proxy
var s = file.Substring(Const.HOST_TAG, Const.HOST_TAG, true);
if (string.IsNullOrEmpty(s))
{
File.AppendAllText(certifi, Environment.NewLine + pem);
File.AppendAllText(certifi, "\r\n" + pem);
}
else if (s.Trim() != pem.Trim())
{
@@ -9,6 +9,8 @@ namespace SteamTool.Proxy
{
public class ProxyDomainModel
{
public int Index { get; set; }
/// <summary>
/// 显示在UI上的名称
/// </summary>
@@ -17,7 +19,7 @@ namespace SteamTool.Proxy
/// <summary>
/// 代理域名合集
/// </summary>
public IReadOnlyCollection<string> Domains { get; set; }
public List<string> Domains { get; set; }
/// <summary>
/// 端口
@@ -44,7 +46,7 @@ namespace SteamTool.Proxy
/// </summary>
public bool IsEnable { get; set; }
public IReadOnlyCollection<string> Hosts { get; set; }
public IEnumerable<string> Hosts { get; set; }
public DomainTag DomainTag { get; set; }
}
@@ -52,8 +54,14 @@ namespace SteamTool.Proxy
[TypeConverter(typeof(EnumDescriptionTypeConverter))]
public enum DomainTag : byte
{
/// <summary>
/// steam社区
/// </summary>
[Description("steam社区")]
SteamCommunity = 0,
/// <summary>
/// steam商店
/// </summary>
[Description("steam商店")]
SteamStore = 1,
[Description("steam部分图片修复")]
@@ -62,27 +70,21 @@ namespace SteamTool.Proxy
SteamChat = 3,
[Description("Discord语音")]
Discord = 4,
[Description("Twitch直播")]
Twitch = 5,
[Description("Origin下载(Akamai)")]
OriginGameDownload = 6,
[Description("GOG.COM")]
GOG = 7,
[Description("Google(Recaptcha)")]
GoogleCode = 8,
[Description("Github图片及资源修复")]
GithubContent = 9,
[Description("Pixiv")]
Pixiv = 10,
[Description("Discord更新下载")]
DiscordNet = 11,
[Description("Twitch直播")]
Twitch = 5,
[Description("Origin下载加速(Akamai)")]
OriginGameDownload = 6,
[Description("Uplay更新防劫持")]
UplayUpdate = 12,
[Description("Twitch聊天")]
TwitchChat = 13,
[Description("Github Gist")]
GithubGist = 14,
[Description("Pixiv图片")]
PixivImage = 15,
UplayUpdate = 7,
[Description("Google(Recaptcha)")]
GoogleCode = 8,
[Description("GOG.COM")]
GOG = 8,
[Description("Github图片修复")]
GithubContent = 9,
[Description("Pixiv")]
Pixiv = 10,
}
}
@@ -70,7 +70,7 @@ namespace SteamTool.Proxy.Properties {
}
/// <summary>
/// 查找类似 Discord图片及更新下载 的本地化字符串。
/// 查找类似 Discord更新下载 的本地化字符串。
/// </summary>
public static string DiscordNet {
get {
@@ -87,15 +87,6 @@ namespace SteamTool.Proxy.Properties {
}
}
/// <summary>
/// 查找类似 Github Gist 的本地化字符串。
/// </summary>
public static string GithubGist {
get {
return ResourceManager.GetString("GithubGist", resourceCulture);
}
}
/// <summary>
/// 查找类似 GOG Galaxy 的本地化字符串。
/// </summary>
@@ -141,15 +132,6 @@ namespace SteamTool.Proxy.Properties {
}
}
/// <summary>
/// 查找类似 Pixiv图片 的本地化字符串。
/// </summary>
public static string PixivImgae {
get {
return ResourceManager.GetString("PixivImgae", resourceCulture);
}
}
/// <summary>
/// 查找类似 Steam好友聊天 的本地化字符串。
/// </summary>
@@ -195,15 +177,6 @@ namespace SteamTool.Proxy.Properties {
}
}
/// <summary>
/// 查找类似 Twitch聊天 的本地化字符串。
/// </summary>
public static string TwitchChat {
get {
return ResourceManager.GetString("TwitchChat", resourceCulture);
}
}
/// <summary>
/// 查找类似 Uplay更新 的本地化字符串。
/// </summary>
@@ -121,14 +121,11 @@
<value>Discord语音</value>
</data>
<data name="DiscordNet" xml:space="preserve">
<value>Discord图片及更新下载</value>
<value>Discord更新下载</value>
</data>
<data name="GithubContent" xml:space="preserve">
<value>Github图片资源修复</value>
</data>
<data name="GithubGist" xml:space="preserve">
<value>Github Gist</value>
</data>
<data name="GOG" xml:space="preserve">
<value>GOG Galaxy</value>
</data>
@@ -144,9 +141,6 @@
<data name="Pixiv" xml:space="preserve">
<value>Pixiv</value>
</data>
<data name="PixivImgae" xml:space="preserve">
<value>Pixiv图片</value>
</data>
<data name="SteamChat" xml:space="preserve">
<value>Steam好友聊天</value>
</data>
@@ -162,9 +156,6 @@
<data name="Twitch" xml:space="preserve">
<value>Twitch直播</value>
</data>
<data name="TwitchChat" xml:space="preserve">
<value>Twitch聊天</value>
</data>
<data name="UplayUpdate" xml:space="preserve">
<value>Uplay更新</value>
</data>
@@ -11,7 +11,7 @@
<PackageReference Include="BrotliSharpLib" Version="0.3.3" />
<PackageReference Include="DnsClient" Version="1.3.2" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.9" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.8" />
<PackageReference Include="System.Buffers" Version="4.5.1" />
<PackageReference Include="System.Memory" Version="4.5.4" />
<PackageReference Include="System.Runtime.InteropServices.RuntimeInformation" Version="4.3.0" />
@@ -21,7 +21,12 @@
<ItemGroup>
<ProjectReference Include="..\SteamTool.Core\SteamTool.Core.csproj" />
<ProjectReference Include="..\..\references\Titanium-Web-Proxy\src\Titanium.Web.Proxy\Titanium.Web.Proxy.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="Titanium.Web.Proxy">
<HintPath>..\Lib\Titanium.Web.Proxy.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@@ -115,7 +115,7 @@ namespace SteamTool.Steam.Service.Local
return SteamClient.SteamUserStats.GetAchievementState(name, out isAchieved);
}
public bool GetAchievementAndUnlockTime(string name, out bool isAchieved, out long unlockTime)
public bool GetAchievementAndUnlockTime(string name, out bool isAchieved, out int unlockTime)
{
return SteamClient.SteamUserStats.GetAchievementAndUnlockTime(name, out isAchieved, out unlockTime);
}
@@ -17,18 +17,14 @@ namespace SteamTool.Steam.Service.Web
public async Task<SteamUser> GetUserInfo(long steamId64)
{
var r = await httpServices.Get(string.Format(Const.STEAMDB_USERINFO_URL, steamId64));
if (!string.IsNullOrEmpty(r))
{
var userInfo = JsonConvert.DeserializeObject<SteamUser>(r);
return userInfo;
}
return new SteamUser() { SteamId64 = steamId64 };
var userInfo = JsonConvert.DeserializeObject<SteamUser>(r);
return userInfo;
}
public async Task<List<SteamUser>> GetUserInfo(long[] steamId64s)
{
var users = new List<SteamUser>();
foreach (var i in steamId64s)
foreach (var i in steamId64s)
{
users.Add(await GetUserInfo(i));
}
@@ -36,15 +32,11 @@ namespace SteamTool.Steam.Service.Web
}
public async Task<SteamApp> GetAppInfo(int appId)
public async Task<SteamApp> GetAppInfo(long appId)
{
var r = await httpServices.Get(string.Format(Const.STEAMDB_APPINFO_URL, appId));
if (!string.IsNullOrEmpty(r))
{
var steamApp = JsonConvert.DeserializeObject<SteamApp>(r);
return steamApp;
}
return new SteamApp() { AppId = (uint)appId };
var steamApp = JsonConvert.DeserializeObject<SteamApp>(r);
return steamApp;
}
}
@@ -3,10 +3,8 @@ using SteamTool.Core;
using SteamTool.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace SteamTool.Steam.Service.Web
{
@@ -28,17 +26,5 @@ namespace SteamTool.Steam.Service.Web
return apps.AppList.Apps;
}
public async Task<SteamUser> GetUserInfo(long steamId64)
{
var r = await httpServices.Get(string.Format(Const.STEAM_USERINFO_XML_URL, steamId64));
if (!string.IsNullOrEmpty(r))
{
using StringReader sr = new StringReader(r);
var xmldes = new XmlSerializer(typeof(SteamUser));
return xmldes.Deserialize(sr) as SteamUser;
}
return new SteamUser() { SteamId64 = steamId64 };
}
}
}

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