Add Proxy page

This commit is contained in:
2023-10-08 00:01:20 +08:00
parent 2c2f05c5b2
commit 2a51fcb47d
18 changed files with 579 additions and 126 deletions

View File

@ -79,6 +79,9 @@
<setting name="IsHotkeyEenabled" serializeAs="String"> <setting name="IsHotkeyEenabled" serializeAs="String">
<value>True</value> <value>True</value>
</setting> </setting>
<setting name="AutoStartProxy" serializeAs="String">
<value>False</value>
</setting>
</GrasscutterTools.Properties.Settings> </GrasscutterTools.Properties.Settings>
</userSettings> </userSettings>
</configuration> </configuration>

View File

@ -30,15 +30,20 @@ using GrasscutterTools.Utils;
namespace GrasscutterTools.Forms namespace GrasscutterTools.Forms
{ {
public partial class FormMain : Form internal partial class FormMain : Form
{ {
#region - Init - private const string TAG = nameof(FormMain);
private const string TAG = "FormMain"; public static FormMain Instance { get; private set; }
#region - Init -
public FormMain() public FormMain()
{ {
Logger.I(TAG, "FormMain ctor enter"); Logger.I(TAG, "FormMain ctor enter");
Instance = this;
InitializeComponent(); InitializeComponent();
Icon = Resources.IconGrasscutter; Icon = Resources.IconGrasscutter;
@ -110,21 +115,9 @@ namespace GrasscutterTools.Forms
ph.OnLanguageChanged = () => FormMain_Load(this, EventArgs.Empty); ph.OnLanguageChanged = () => FormMain_Load(this, EventArgs.Empty);
var poc = CreatePage<PageOpenCommand>(); var poc = CreatePage<PageOpenCommand>();
poc.ShowTipInRunButton = msg => ShowTip(msg, BtnInvokeOpenCommand); poc.ShowTipInRunButton = msg => ShowTip(msg, BtnInvokeOpenCommand);
var pcc = CreatePage<PageCustomCommands>(); CreatePage<PageProxy>();
var phk = CreatePage<PageHotKey>(); CreatePage<PageCustomCommands>();
pcc.OnAddHotKey = tag => CreatePage<PageHotKey>();
{
phk.AddNewHotKey(tag);
// 跳转到快捷键界面
for (var i = 0; i < TCMain.Controls.Count; i++)
{
if (TCMain.Controls[i].Controls[0] == phk)
{
ListPages.SelectedIndex = i;
break;
}
}
};
CreatePage<PageGiveArtifact>(); CreatePage<PageGiveArtifact>();
CreatePage<PageSetProp>(); CreatePage<PageSetProp>();
CreatePage<PageSpawn>(); CreatePage<PageSpawn>();
@ -156,6 +149,7 @@ namespace GrasscutterTools.Forms
{ {
Resources.PageHomeTitle, Resources.PageHomeTitle,
Resources.PageOpenCommandTitle, Resources.PageOpenCommandTitle,
Resources.PageProxyTitle,
Resources.PageCustomCommandsTitle, Resources.PageCustomCommandsTitle,
Resources.PageHotKey, Resources.PageHotKey,
Resources.PageGetArtifactTitle, Resources.PageGetArtifactTitle,
@ -472,16 +466,7 @@ namespace GrasscutterTools.Forms
if (Common.OC == null || !Common.OC.CanInvoke) if (Common.OC == null || !Common.OC.CanInvoke)
{ {
ShowTip(Resources.RequireOpenCommandTip, BtnInvokeOpenCommand); ShowTip(Resources.RequireOpenCommandTip, BtnInvokeOpenCommand);
//TCMain.SelectedTab = TPRemoteCall; NavigateTo<PageOpenCommand>();
for (var i = 0; i < TCMain.Controls.Count; i++)
{
if (TCMain.Controls[i].Controls[0] is PageOpenCommand)
{
ListPages.SelectedIndex = i;
break;
}
}
return false; return false;
} }
@ -637,6 +622,25 @@ namespace GrasscutterTools.Forms
TTip.Show(message, control, 0, control.Size.Height, 3000); TTip.Show(message, control, 0, control.Size.Height, 3000);
} }
/// <summary>
/// 导航到目标页面并返回该页面实例
/// </summary>
/// <typeparam name="TPage">页面类型</typeparam>
/// <returns>如果导航到了则返回页面实例,否则返回空</returns>
public TPage NavigateTo<TPage>() where TPage : BasePage
{
for (var i = 0; i < TCMain.Controls.Count; i++)
{
if (TCMain.Controls[i].Controls[0] is TPage page)
{
ListPages.SelectedIndex = i;
return page;
}
}
return null;
}
#endregion - General - #endregion - General -
} }
} }

View File

@ -280,6 +280,12 @@
<Compile Include="Pages\PageOpenCommand.Designer.cs"> <Compile Include="Pages\PageOpenCommand.Designer.cs">
<DependentUpon>PageOpenCommand.cs</DependentUpon> <DependentUpon>PageOpenCommand.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Pages\PageProxy.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Pages\PageProxy.Designer.cs">
<DependentUpon>PageProxy.cs</DependentUpon>
</Compile>
<Compile Include="Pages\PageQuest.cs"> <Compile Include="Pages\PageQuest.cs">
<SubType>UserControl</SubType> <SubType>UserControl</SubType>
</Compile> </Compile>
@ -590,6 +596,9 @@
<EmbeddedResource Include="Pages\PageOpenCommand.zh-TW.resx"> <EmbeddedResource Include="Pages\PageOpenCommand.zh-TW.resx">
<DependentUpon>PageOpenCommand.cs</DependentUpon> <DependentUpon>PageOpenCommand.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="Pages\PageProxy.resx">
<DependentUpon>PageProxy.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Pages\PageQuest.en-US.resx"> <EmbeddedResource Include="Pages\PageQuest.en-US.resx">
<DependentUpon>PageQuest.cs</DependentUpon> <DependentUpon>PageQuest.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>

View File

@ -21,7 +21,7 @@ using System;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using GrasscutterTools.Forms;
using GrasscutterTools.Properties; using GrasscutterTools.Properties;
using GrasscutterTools.Utils; using GrasscutterTools.Utils;
@ -249,8 +249,9 @@ namespace GrasscutterTools.Pages
} }
} }
public Action<string> OnAddHotKey; /// <summary>
/// 点击添加快捷键时触发
/// </summary>
private void BtnAddHotKey_Click(object sender, EventArgs e) private void BtnAddHotKey_Click(object sender, EventArgs e)
{ {
var name = TxtCustomName.Text.Trim(); var name = TxtCustomName.Text.Trim();
@ -259,7 +260,10 @@ namespace GrasscutterTools.Pages
MessageBox.Show(Resources.CommandTagCannotBeEmpty, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(Resources.CommandTagCannotBeEmpty, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
return; return;
} }
OnAddHotKey?.Invoke(name);
// 跳转到快捷键界面
FormMain.Instance.NavigateTo<PageHotKey>()?
.AddNewHotKey(name); // 设置标签
} }
} }
} }

View File

@ -60,7 +60,6 @@
this.TxtHost = new System.Windows.Forms.ComboBox(); this.TxtHost = new System.Windows.Forms.ComboBox();
this.BtnQueryServerStatus = new System.Windows.Forms.Button(); this.BtnQueryServerStatus = new System.Windows.Forms.Button();
this.LblHost = new System.Windows.Forms.Label(); this.LblHost = new System.Windows.Forms.Label();
this.BtnProxy = new System.Windows.Forms.Button();
this.GrpServerStatus.SuspendLayout(); this.GrpServerStatus.SuspendLayout();
this.GrpRemoteCommand.SuspendLayout(); this.GrpRemoteCommand.SuspendLayout();
this.TPOpenCommandCheck.SuspendLayout(); this.TPOpenCommandCheck.SuspendLayout();
@ -302,18 +301,10 @@
resources.ApplyResources(this.LblHost, "LblHost"); resources.ApplyResources(this.LblHost, "LblHost");
this.LblHost.Name = "LblHost"; this.LblHost.Name = "LblHost";
// //
// BtnProxy
//
resources.ApplyResources(this.BtnProxy, "BtnProxy");
this.BtnProxy.Name = "BtnProxy";
this.BtnProxy.UseVisualStyleBackColor = true;
this.BtnProxy.Click += new System.EventHandler(this.BtnProxy_Click);
//
// PageOpenCommand // PageOpenCommand
// //
resources.ApplyResources(this, "$this"); resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.BtnProxy);
this.Controls.Add(this.LnkLinks); this.Controls.Add(this.LnkLinks);
this.Controls.Add(this.LnkGOODHelp); this.Controls.Add(this.LnkGOODHelp);
this.Controls.Add(this.LnkInventoryKamera); this.Controls.Add(this.LnkInventoryKamera);
@ -374,6 +365,5 @@
private System.Windows.Forms.ComboBox TxtHost; private System.Windows.Forms.ComboBox TxtHost;
private System.Windows.Forms.Button BtnQueryServerStatus; private System.Windows.Forms.Button BtnQueryServerStatus;
private System.Windows.Forms.Label LblHost; private System.Windows.Forms.Label LblHost;
private System.Windows.Forms.Button BtnProxy;
} }
} }

View File

@ -64,8 +64,6 @@ namespace GrasscutterTools.Pages
TxtHost.Items.Add("http://127.0.0.1:443"); TxtHost.Items.Add("http://127.0.0.1:443");
TxtHost.SelectedIndex = 0; TxtHost.SelectedIndex = 0;
} }
BtnProxy.Text = Resources.StartProxy;
} }
#region - - #region - -
@ -248,6 +246,8 @@ namespace GrasscutterTools.Pages
return; return;
} }
Settings.Default.Host = host;
var isOcEnabled = false; var isOcEnabled = false;
try try
{ {
@ -275,8 +275,6 @@ namespace GrasscutterTools.Pages
LblOpenCommandSupport.ForeColor = Color.Red; LblOpenCommandSupport.ForeColor = Color.Red;
GrpRemoteCommand.Enabled = false; GrpRemoteCommand.Enabled = false;
} }
BtnProxy.Enabled = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -608,44 +606,5 @@ namespace GrasscutterTools.Pages
} }
#endregion - GOOD - #endregion - GOOD -
#region - Porxy -
/// <summary>
/// 点击代理按钮时触发
/// </summary>
private void BtnProxy_Click(object sender, EventArgs e)
{
try
{
// 正在运行则关闭
if (ProxyHelper.IsRunning)
{
ProxyHelper.StopProxy();
BtnProxy.Text = Resources.StartProxy;
}
else
{
// 创建根证书并检查信任
if (!ProxyHelper.CheckAndCreateCertifier())
{
MessageBox.Show("必须先信任根证书才能继续", Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// 启动代理
ProxyHelper.StartProxy(Common.OC.Host);
BtnProxy.Text = Resources.StopProxy;
}
}
catch (Exception ex)
{
Logger.E(TAG, "Start Proxy failed.", ex);
MessageBox.Show(ex.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
#endregion
} }
} }

View File

@ -151,7 +151,7 @@
<value>$this</value> <value>$this</value>
</data> </data>
<data name="&gt;&gt;LnkLinks.ZOrder" xml:space="preserve"> <data name="&gt;&gt;LnkLinks.ZOrder" xml:space="preserve">
<value>1</value> <value>0</value>
</data> </data>
<data name="LnkGOODHelp.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms"> <data name="LnkGOODHelp.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>None</value> <value>None</value>
@ -184,7 +184,7 @@
<value>$this</value> <value>$this</value>
</data> </data>
<data name="&gt;&gt;LnkGOODHelp.ZOrder" xml:space="preserve"> <data name="&gt;&gt;LnkGOODHelp.ZOrder" xml:space="preserve">
<value>2</value> <value>1</value>
</data> </data>
<data name="LnkInventoryKamera.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms"> <data name="LnkInventoryKamera.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>None</value> <value>None</value>
@ -214,7 +214,7 @@
<value>$this</value> <value>$this</value>
</data> </data>
<data name="&gt;&gt;LnkInventoryKamera.ZOrder" xml:space="preserve"> <data name="&gt;&gt;LnkInventoryKamera.ZOrder" xml:space="preserve">
<value>3</value> <value>2</value>
</data> </data>
<data name="LblGOODHelp.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms"> <data name="LblGOODHelp.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>None</value> <value>None</value>
@ -244,7 +244,7 @@
<value>$this</value> <value>$this</value>
</data> </data>
<data name="&gt;&gt;LblGOODHelp.ZOrder" xml:space="preserve"> <data name="&gt;&gt;LblGOODHelp.ZOrder" xml:space="preserve">
<value>4</value> <value>3</value>
</data> </data>
<data name="ButtonOpenGOODImport.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms"> <data name="ButtonOpenGOODImport.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>None</value> <value>None</value>
@ -274,7 +274,7 @@
<value>$this</value> <value>$this</value>
</data> </data>
<data name="&gt;&gt;ButtonOpenGOODImport.ZOrder" xml:space="preserve"> <data name="&gt;&gt;ButtonOpenGOODImport.ZOrder" xml:space="preserve">
<value>5</value> <value>4</value>
</data> </data>
<data name="LblHostTip.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms"> <data name="LblHostTip.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>None</value> <value>None</value>
@ -307,7 +307,7 @@
<value>$this</value> <value>$this</value>
</data> </data>
<data name="&gt;&gt;LblHostTip.ZOrder" xml:space="preserve"> <data name="&gt;&gt;LblHostTip.ZOrder" xml:space="preserve">
<value>6</value> <value>5</value>
</data> </data>
<data name="GrpServerStatus.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms"> <data name="GrpServerStatus.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>None</value> <value>None</value>
@ -514,7 +514,7 @@
<value>$this</value> <value>$this</value>
</data> </data>
<data name="&gt;&gt;GrpServerStatus.ZOrder" xml:space="preserve"> <data name="&gt;&gt;GrpServerStatus.ZOrder" xml:space="preserve">
<value>7</value> <value>6</value>
</data> </data>
<data name="GrpRemoteCommand.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms"> <data name="GrpRemoteCommand.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>None</value> <value>None</value>
@ -923,7 +923,7 @@
<value>$this</value> <value>$this</value>
</data> </data>
<data name="&gt;&gt;GrpRemoteCommand.ZOrder" xml:space="preserve"> <data name="&gt;&gt;GrpRemoteCommand.ZOrder" xml:space="preserve">
<value>8</value> <value>7</value>
</data> </data>
<data name="TxtHost.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms"> <data name="TxtHost.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>None</value> <value>None</value>
@ -947,7 +947,7 @@
<value>$this</value> <value>$this</value>
</data> </data>
<data name="&gt;&gt;TxtHost.ZOrder" xml:space="preserve"> <data name="&gt;&gt;TxtHost.ZOrder" xml:space="preserve">
<value>9</value> <value>8</value>
</data> </data>
<data name="BtnQueryServerStatus.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms"> <data name="BtnQueryServerStatus.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>None</value> <value>None</value>
@ -959,7 +959,7 @@
<value>324, 34</value> <value>324, 34</value>
</data> </data>
<data name="BtnQueryServerStatus.Size" type="System.Drawing.Size, System.Drawing"> <data name="BtnQueryServerStatus.Size" type="System.Drawing.Size, System.Drawing">
<value>50, 23</value> <value>50, 25</value>
</data> </data>
<data name="BtnQueryServerStatus.TabIndex" type="System.Int32, mscorlib"> <data name="BtnQueryServerStatus.TabIndex" type="System.Int32, mscorlib">
<value>3</value> <value>3</value>
@ -977,7 +977,7 @@
<value>$this</value> <value>$this</value>
</data> </data>
<data name="&gt;&gt;BtnQueryServerStatus.ZOrder" xml:space="preserve"> <data name="&gt;&gt;BtnQueryServerStatus.ZOrder" xml:space="preserve">
<value>10</value> <value>9</value>
</data> </data>
<data name="LblHost.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms"> <data name="LblHost.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>None</value> <value>None</value>
@ -1010,34 +1010,7 @@
<value>$this</value> <value>$this</value>
</data> </data>
<data name="&gt;&gt;LblHost.ZOrder" xml:space="preserve"> <data name="&gt;&gt;LblHost.ZOrder" xml:space="preserve">
<value>11</value> <value>10</value>
</data>
<data name="BtnProxy.Enabled" type="System.Boolean, mscorlib">
<value>False</value>
</data>
<data name="BtnProxy.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 3</value>
</data>
<data name="BtnProxy.Size" type="System.Drawing.Size, System.Drawing">
<value>120, 25</value>
</data>
<data name="BtnProxy.TabIndex" type="System.Int32, mscorlib">
<value>11</value>
</data>
<data name="BtnProxy.Text" xml:space="preserve">
<value>启动代理</value>
</data>
<data name="&gt;&gt;BtnProxy.Name" xml:space="preserve">
<value>BtnProxy</value>
</data>
<data name="&gt;&gt;BtnProxy.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;BtnProxy.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;BtnProxy.ZOrder" xml:space="preserve">
<value>0</value>
</data> </data>
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>

View File

@ -0,0 +1,196 @@
namespace GrasscutterTools.Pages
{
partial class PageProxy
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.TxtHost = new System.Windows.Forms.TextBox();
this.LblServerAddress = new System.Windows.Forms.Label();
this.BtnStartProxy = new System.Windows.Forms.Button();
this.ChkAutoStart = new System.Windows.Forms.CheckBox();
this.LblProxyIntroduction = new System.Windows.Forms.Label();
this.BtnDestroyCert = new System.Windows.Forms.Button();
this.LnkEavesdrop = new System.Windows.Forms.LinkLabel();
this.LnkAbout = new System.Windows.Forms.LinkLabel();
this.LblGcJarPath = new System.Windows.Forms.Label();
this.TxtGcJarPath = new System.Windows.Forms.TextBox();
this.BtnStartGc = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// TxtHost
//
this.TxtHost.Anchor = System.Windows.Forms.AnchorStyles.None;
this.TxtHost.Location = new System.Drawing.Point(227, 40);
this.TxtHost.Name = "TxtHost";
this.TxtHost.Size = new System.Drawing.Size(160, 23);
this.TxtHost.TabIndex = 4;
this.TxtHost.Text = "http://127.0.0.1:443";
//
// LblServerAddress
//
this.LblServerAddress.Anchor = System.Windows.Forms.AnchorStyles.None;
this.LblServerAddress.AutoSize = true;
this.LblServerAddress.Location = new System.Drawing.Point(84, 43);
this.LblServerAddress.Name = "LblServerAddress";
this.LblServerAddress.Size = new System.Drawing.Size(137, 17);
this.LblServerAddress.TabIndex = 3;
this.LblServerAddress.Text = "目标 http(s) 服务器地址";
//
// BtnStartProxy
//
this.BtnStartProxy.Anchor = System.Windows.Forms.AnchorStyles.None;
this.BtnStartProxy.Location = new System.Drawing.Point(393, 40);
this.BtnStartProxy.Name = "BtnStartProxy";
this.BtnStartProxy.Size = new System.Drawing.Size(120, 25);
this.BtnStartProxy.TabIndex = 5;
this.BtnStartProxy.Text = "启动代理";
this.BtnStartProxy.UseVisualStyleBackColor = true;
this.BtnStartProxy.Click += new System.EventHandler(this.BtnStartProxy_Click);
//
// ChkAutoStart
//
this.ChkAutoStart.Anchor = System.Windows.Forms.AnchorStyles.None;
this.ChkAutoStart.AutoSize = true;
this.ChkAutoStart.Location = new System.Drawing.Point(519, 42);
this.ChkAutoStart.Name = "ChkAutoStart";
this.ChkAutoStart.Size = new System.Drawing.Size(75, 21);
this.ChkAutoStart.TabIndex = 6;
this.ChkAutoStart.Text = "自动开启";
this.ChkAutoStart.UseVisualStyleBackColor = true;
this.ChkAutoStart.CheckedChanged += new System.EventHandler(this.ChkAutoStart_CheckedChanged);
//
// LblProxyIntroduction
//
this.LblProxyIntroduction.Anchor = System.Windows.Forms.AnchorStyles.None;
this.LblProxyIntroduction.Location = new System.Drawing.Point(48, 72);
this.LblProxyIntroduction.Name = "LblProxyIntroduction";
this.LblProxyIntroduction.Size = new System.Drawing.Size(550, 120);
this.LblProxyIntroduction.TabIndex = 7;
this.LblProxyIntroduction.Text = " 启动代理需要信任本应用的临时根证书该证书仅用于代理动漫游戏相关请求有效期1月你可以随时点击右下角卸载证书。\r\n 代理功能代码来自开源项目 Ea" +
"vesdrop遵循MIT开源协议经过魔改以匹配应用需求。\r\n 本代理通过大量过滤规则来规避非动漫游戏的请求经过应用,减小影响,欢迎体验!\r\n 程" +
"序退出时会自动关闭代理,放心使用 :)";
//
// BtnDestroyCert
//
this.BtnDestroyCert.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.BtnDestroyCert.Location = new System.Drawing.Point(529, 207);
this.BtnDestroyCert.Name = "BtnDestroyCert";
this.BtnDestroyCert.Size = new System.Drawing.Size(100, 25);
this.BtnDestroyCert.TabIndex = 10;
this.BtnDestroyCert.Text = "卸载证书";
this.BtnDestroyCert.UseVisualStyleBackColor = true;
this.BtnDestroyCert.Click += new System.EventHandler(this.BtnDestroyCert_Click);
//
// LnkEavesdrop
//
this.LnkEavesdrop.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.LnkEavesdrop.AutoSize = true;
this.LnkEavesdrop.Location = new System.Drawing.Point(15, 211);
this.LnkEavesdrop.Name = "LnkEavesdrop";
this.LnkEavesdrop.Size = new System.Drawing.Size(70, 17);
this.LnkEavesdrop.TabIndex = 8;
this.LnkEavesdrop.TabStop = true;
this.LnkEavesdrop.Text = "Eavesdrop";
this.LnkEavesdrop.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LnkEavesdrop_LinkClicked);
//
// LnkAbout
//
this.LnkAbout.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.LnkAbout.AutoSize = true;
this.LnkAbout.Location = new System.Drawing.Point(482, 211);
this.LnkAbout.Name = "LnkAbout";
this.LnkAbout.Size = new System.Drawing.Size(32, 17);
this.LnkAbout.TabIndex = 9;
this.LnkAbout.TabStop = true;
this.LnkAbout.Text = "关于";
this.LnkAbout.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LnkAbout_LinkClicked);
//
// LblGcJarPath
//
this.LblGcJarPath.AutoSize = true;
this.LblGcJarPath.Location = new System.Drawing.Point(102, 14);
this.LblGcJarPath.Name = "LblGcJarPath";
this.LblGcJarPath.Size = new System.Drawing.Size(119, 17);
this.LblGcJarPath.TabIndex = 0;
this.LblGcJarPath.Text = "GrasscutterJar 路径";
this.LblGcJarPath.Visible = false;
//
// TxtGcJarPath
//
this.TxtGcJarPath.Location = new System.Drawing.Point(227, 11);
this.TxtGcJarPath.Name = "TxtGcJarPath";
this.TxtGcJarPath.Size = new System.Drawing.Size(160, 23);
this.TxtGcJarPath.TabIndex = 1;
this.TxtGcJarPath.Visible = false;
//
// BtnStartGc
//
this.BtnStartGc.Location = new System.Drawing.Point(393, 11);
this.BtnStartGc.Name = "BtnStartGc";
this.BtnStartGc.Size = new System.Drawing.Size(120, 25);
this.BtnStartGc.TabIndex = 2;
this.BtnStartGc.Text = "启动服务器";
this.BtnStartGc.UseVisualStyleBackColor = true;
this.BtnStartGc.Visible = false;
this.BtnStartGc.Click += new System.EventHandler(this.BtnStartGc_Click);
//
// PageProxy
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.BtnStartGc);
this.Controls.Add(this.TxtGcJarPath);
this.Controls.Add(this.LblGcJarPath);
this.Controls.Add(this.LnkAbout);
this.Controls.Add(this.LnkEavesdrop);
this.Controls.Add(this.BtnDestroyCert);
this.Controls.Add(this.LblProxyIntroduction);
this.Controls.Add(this.ChkAutoStart);
this.Controls.Add(this.BtnStartProxy);
this.Controls.Add(this.LblServerAddress);
this.Controls.Add(this.TxtHost);
this.Name = "PageProxy";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox TxtHost;
private System.Windows.Forms.Label LblServerAddress;
private System.Windows.Forms.Button BtnStartProxy;
private System.Windows.Forms.CheckBox ChkAutoStart;
private System.Windows.Forms.Label LblProxyIntroduction;
private System.Windows.Forms.Button BtnDestroyCert;
private System.Windows.Forms.LinkLabel LnkEavesdrop;
private System.Windows.Forms.LinkLabel LnkAbout;
private System.Windows.Forms.Label LblGcJarPath;
private System.Windows.Forms.TextBox TxtGcJarPath;
private System.Windows.Forms.Button BtnStartGc;
}
}

View File

@ -0,0 +1,127 @@
/**
* Grasscutter Tools
* Copyright (C) 2023 jie65535
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
**/
using System;
using System.Windows.Forms;
using GrasscutterTools.Forms;
using GrasscutterTools.Properties;
using GrasscutterTools.Utils;
namespace GrasscutterTools.Pages
{
internal partial class PageProxy : BasePage
{
private const string TAG = nameof(PageProxy);
public PageProxy()
{
InitializeComponent();
}
public override void OnLoad()
{
if (!string.IsNullOrEmpty(Settings.Default.Host))
TxtHost.Text = Settings.Default.Host;
ChkAutoStart.Checked = Settings.Default.AutoStartProxy;
if (Settings.Default.AutoStartProxy && !ProxyHelper.IsRunning)
{
Logger.I(TAG, "Auto start proxy!");
BtnStartProxy_Click(BtnStartProxy, EventArgs.Empty);
}
}
/// <summary>
/// 点击启动GC服务器时触发
/// </summary>
private void BtnStartGc_Click(object sender, EventArgs e)
{
// TODO Run java -jar grasscutter.jar
}
/// <summary>
/// 点击代理按钮时触发
/// </summary>
private void BtnStartProxy_Click(object sender, EventArgs e)
{
try
{
// 正在运行则关闭
if (ProxyHelper.IsRunning)
{
ProxyHelper.StopProxy();
BtnStartProxy.Text = Resources.StartProxy;
TxtHost.Enabled = true;
}
else
{
// 创建根证书并检查信任
if (!ProxyHelper.CheckAndCreateCertificate())
{
MessageBox.Show(Resources.TrustedBeforeContinuing, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// 启动代理
ProxyHelper.StartProxy(TxtHost.Text);
BtnStartProxy.Text = Resources.StopProxy;
TxtHost.Enabled = false;
}
}
catch (Exception ex)
{
Logger.E(TAG, "Start Proxy failed.", ex);
MessageBox.Show(ex.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 点击 Eavesdrop 标签时触发
/// </summary>
private void LnkEavesdrop_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
UIUtil.OpenURL("https://github.com/ArachisH/Eavesdrop");
}
/// <summary>
/// 点击关于标签时触发
/// </summary>
private void LnkAbout_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
FormMain.Instance.NavigateTo<PageAbout>();
}
/// <summary>
/// 点击卸载证书时触发
/// </summary>
private void BtnDestroyCert_Click(object sender, EventArgs e)
{
Logger.I(TAG, "DestroyCertificate");
ProxyHelper.DestroyCertificate();
MessageBox.Show("OK", Resources.Tips);
}
/// <summary>
/// 自动启动代理选项更改时触发
/// </summary>
private void ChkAutoStart_CheckedChanged(object sender, EventArgs e)
{
Settings.Default.AutoStartProxy = ChkAutoStart.Checked;
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1194,6 +1194,15 @@ namespace GrasscutterTools.Properties {
} }
} }
/// <summary>
/// 查找类似 代理 的本地化字符串。
/// </summary>
internal static string PageProxyTitle {
get {
return ResourceManager.GetString("PageProxyTitle", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 任务 的本地化字符串。 /// 查找类似 任务 的本地化字符串。
/// </summary> /// </summary>
@ -1588,6 +1597,15 @@ namespace GrasscutterTools.Properties {
} }
} }
/// <summary>
/// 查找类似 必须先信任根证书才能继续! 的本地化字符串。
/// </summary>
internal static string TrustedBeforeContinuing {
get {
return ResourceManager.GetString("TrustedBeforeContinuing", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 用户名不能为空! 的本地化字符串。 /// 查找类似 用户名不能为空! 的本地化字符串。
/// </summary> /// </summary>

View File

@ -375,4 +375,10 @@ Improvement suggestions have been submitted, please use caution to send emails t
<data name="PageSceneTagTitle" xml:space="preserve"> <data name="PageSceneTagTitle" xml:space="preserve">
<value>SceneTag</value> <value>SceneTag</value>
</data> </data>
<data name="TrustedBeforeContinuing" xml:space="preserve">
<value>The root certificate must be trusted before continuing!</value>
</data>
<data name="PageProxyTitle" xml:space="preserve">
<value>Proxy</value>
</data>
</root> </root>

View File

@ -387,4 +387,10 @@
<data name="PageSceneTagTitle" xml:space="preserve"> <data name="PageSceneTagTitle" xml:space="preserve">
<value>场景项</value> <value>场景项</value>
</data> </data>
<data name="TrustedBeforeContinuing" xml:space="preserve">
<value>必须先信任根证书才能继续!</value>
</data>
<data name="PageProxyTitle" xml:space="preserve">
<value>代理</value>
</data>
</root> </root>

View File

@ -363,4 +363,10 @@
<data name="PageSceneTagTitle" xml:space="preserve"> <data name="PageSceneTagTitle" xml:space="preserve">
<value>Тег сцены</value> <value>Тег сцены</value>
</data> </data>
<data name="TrustedBeforeContinuing" xml:space="preserve">
<value>Прежде чем продолжить, необходимо доверять корневому сертификату!</value>
</data>
<data name="PageProxyTitle" xml:space="preserve">
<value>Прокси</value>
</data>
</root> </root>

View File

@ -369,4 +369,10 @@
<data name="PageSceneTagTitle" xml:space="preserve"> <data name="PageSceneTagTitle" xml:space="preserve">
<value>場景項</value> <value>場景項</value>
</data> </data>
<data name="TrustedBeforeContinuing" xml:space="preserve">
<value>必須先信任根憑證才能繼續!</value>
</data>
<data name="PageProxyTitle" xml:space="preserve">
<value>代理</value>
</data>
</root> </root>

View File

@ -298,5 +298,17 @@ namespace GrasscutterTools.Properties {
this["IsHotkeyEenabled"] = value; this["IsHotkeyEenabled"] = value;
} }
} }
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool AutoStartProxy {
get {
return ((bool)(this["AutoStartProxy"]));
}
set {
this["AutoStartProxy"] = value;
}
}
} }
} }

View File

@ -71,5 +71,8 @@
<Setting Name="IsHotkeyEenabled" Type="System.Boolean" Scope="User"> <Setting Name="IsHotkeyEenabled" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value> <Value Profile="(Default)">True</Value>
</Setting> </Setting>
<Setting Name="AutoStartProxy" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
</Settings> </Settings>
</SettingsFile> </SettingsFile>

View File

@ -30,6 +30,11 @@ namespace GrasscutterTools.Utils
{ {
private const string TAG = "Proxy"; private const string TAG = "Proxy";
static ProxyHelper()
{
Eavesdropper.Certifier = new Certifier("jie65535", "GrasscutterTools Root Certificate Authority");
}
#region - Windows API - #region - Windows API -
[DllImport("wininet.dll")] [DllImport("wininet.dll")]
@ -171,6 +176,8 @@ namespace GrasscutterTools.Utils
private static string _gcDispatch; private static string _gcDispatch;
public static void StartProxy(string gcDispatch) public static void StartProxy(string gcDispatch)
{ {
// Check Url format
var _ = new Uri(gcDispatch);
_gcDispatch = gcDispatch.TrimEnd('/'); _gcDispatch = gcDispatch.TrimEnd('/');
Logger.I(TAG, "Start Proxy, redirect to " + _gcDispatch); Logger.I(TAG, "Start Proxy, redirect to " + _gcDispatch);
StartGsProxyServer(ProxyServerPort); StartGsProxyServer(ProxyServerPort);
@ -184,12 +191,16 @@ namespace GrasscutterTools.Utils
StopGsProxyServer(); StopGsProxyServer();
} }
public static bool CheckAndCreateCertifier() public static bool CheckAndCreateCertificate()
{ {
Eavesdropper.Certifier = new Certifier("jie65535", "GrasscutterTools Root Certificate Authority");
return Eavesdropper.Certifier.CreateTrustedRootCertificate(); return Eavesdropper.Certifier.CreateTrustedRootCertificate();
} }
public static bool DestroyCertificate()
{
return Eavesdropper.Certifier.DestroyTrustedRootCertificate();
}
public static bool IsRunning => Eavesdropper.IsRunning; public static bool IsRunning => Eavesdropper.IsRunning;
} }
} }