mirror of
https://github.com/jie65535/GrasscutterCommandGenerator.git
synced 2025-06-07 22:59:14 +08:00
207 lines
8.6 KiB
C#
207 lines
8.6 KiB
C#
/**
|
|
* 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.Runtime.InteropServices;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Win32;
|
|
using Eavesdrop;
|
|
using System.Net;
|
|
|
|
namespace GrasscutterTools.Utils
|
|
{
|
|
internal static class ProxyHelper
|
|
{
|
|
private const string TAG = "Proxy";
|
|
|
|
static ProxyHelper()
|
|
{
|
|
Eavesdropper.Certifier = new Certifier("jie65535", "GrasscutterTools Root Certificate Authority");
|
|
}
|
|
|
|
#region - Windows API -
|
|
|
|
[DllImport("wininet.dll")]
|
|
private static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);
|
|
private const int INTERNET_OPTION_SETTINGS_CHANGED = 39;
|
|
private const int INTERNET_OPTION_REFRESH = 37;
|
|
|
|
#endregion
|
|
|
|
#region - System Proxy -
|
|
|
|
private const string RegKeyInternetSettings = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
|
|
private const string RegProxyEnable = "ProxyEnable";
|
|
private const string RegProxyServer = "ProxyServer";
|
|
private const string RegProxyOverride = "ProxyOverride";
|
|
|
|
private const string PassBy =
|
|
"localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*";
|
|
|
|
private static void FlushOs()
|
|
{
|
|
InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);
|
|
InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);
|
|
}
|
|
|
|
private static bool _isSetSystemProxy;
|
|
|
|
private static void SetSystemProxy(int proxyPort)
|
|
{
|
|
using (var reg = Registry.CurrentUser.OpenSubKey(RegKeyInternetSettings, true))
|
|
{
|
|
reg.SetValue(RegProxyServer, $"http=127.0.0.1:{proxyPort};https=127.0.0.1:{proxyPort}");
|
|
reg.SetValue(RegProxyOverride, PassBy);
|
|
reg.SetValue(RegProxyEnable, 1);
|
|
}
|
|
|
|
_isSetSystemProxy = true;
|
|
FlushOs();
|
|
}
|
|
|
|
private static void CloseSystemProxy()
|
|
{
|
|
if (!_isSetSystemProxy) return;
|
|
_isSetSystemProxy = false;
|
|
|
|
using (var reg = Registry.CurrentUser.OpenSubKey(RegKeyInternetSettings, true))
|
|
reg.SetValue(RegProxyEnable, 0);
|
|
FlushOs();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region - GS Proxy Server -
|
|
|
|
private const string ProxyOverrides =
|
|
"localhost;1*;" + //" 127.*;10.*;192.168.*;" +
|
|
"*0;*1;*2;*3;*4;*5;*6;*7;*8;*9;" +
|
|
"*a;*b;*c;*d;*e;*f;*g;*h;*i;*j;*k;*l;*n;*o;*p;*q;*r;*s;*t;*u;*v;*w;*x;*y;*z" +
|
|
"*a.com;*b.com;*c.com;*d.com;*f.com;*g.com;*h.com;*i.com;*j.com;*k.com;*l.com;*m.com;*p.com;*q.com;*r.com;*s.com;*t.com;*u.com;*v.com;*w.com;*x.com;*y.com;*z.com;" +
|
|
"*ae.com;*be.com;*ce.com;*de.com;*fe.com;*ge.com;*pe.com;*te.com;*me.com;*le.com;*ve.com;" +
|
|
"*ao.com;*bo.com;*eo.com;*go.com;*ke.com;*oo.com;*so.com;*io.com" +
|
|
"*an.com;*cn.com;*dn.com;*gn.com;*wn.com;*dn.com;*sn.com;*un.com;*in.com";
|
|
//"*bing*;*google*;*live.com;*office.com;*weibo*;*yahoo*;*taobao*;*go.com;*csdn.com;*msn.com;*aliyun.com;*cdn.com;";
|
|
//"*ttvnw*;*edge*;*microsoft*;*bing*;*google*;*discordapp*;*gstatic.com;*imgur.com;*hub.*;*gitlab.com;*googleapis.com;*facebook.com;*cloudfront.net;*gvt1.com;*jquery.com;*akamai.net;*ultra-rv.com;*youtube*;*ytimg*;*ggpht*;" +
|
|
//"*baidu*;*qq*;*sohu*;*weibo*;*163*;*360*;*iqiyi*;*youku*;*bilibili*;*sogou*;*taobao*;*jd*;*zhihu*;*steam*;*ea.com;*csdn*;*.msn.*;*aliyun*;*cdn*;" +
|
|
//"*twitter.com;*instagram.com;*wikipedia.org;*yahoo*;*xvideos.com;*whatsapp.com;*live.com;*netflix.com;*office.com;*tiktok.com;*reddit.com;*discord*;*twitch*;*duckduckgo.com";
|
|
|
|
private static string[] urls =
|
|
{
|
|
"hoyoverse.com",
|
|
"mihoyo.com",
|
|
"yuanshen.com",
|
|
};
|
|
|
|
private static void StartGsProxyServer(int port)
|
|
{
|
|
if (Eavesdropper.IsRunning) return;
|
|
Eavesdropper.Overrides.Clear();
|
|
Eavesdropper.Overrides.AddRange(ProxyOverrides.Split(';'));
|
|
Eavesdropper.RequestInterceptedAsync += EavesdropperOnRequestInterceptedAsync;
|
|
Eavesdropper.Initiate(port);
|
|
}
|
|
|
|
private static Task EavesdropperOnRequestInterceptedAsync(object sender, RequestInterceptedEventArgs e)
|
|
{
|
|
var url = e.Request.RequestUri.OriginalString;
|
|
foreach (var mhy in urls)
|
|
{
|
|
var i = url.IndexOf(mhy, StringComparison.CurrentCultureIgnoreCase);
|
|
if (i == -1) continue;
|
|
var p = url.IndexOf('/', i + mhy.Length);
|
|
var target = p >= 0 ? _gcDispatch + url.Substring(p) : _gcDispatch;
|
|
e.Request = RedirectRequest(e.Request as HttpWebRequest, new Uri(target));
|
|
Logger.I(TAG, $"Redirect to {e.Request.RequestUri}");
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
Logger.I(TAG, "Direct " + e.Request.RequestUri);
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private static HttpWebRequest RedirectRequest(HttpWebRequest request, Uri newUri)
|
|
{
|
|
var newRequest = WebRequest.CreateHttp(newUri);
|
|
newRequest.ProtocolVersion = request.ProtocolVersion;
|
|
newRequest.CookieContainer = request.CookieContainer;
|
|
newRequest.AllowAutoRedirect = request.AllowAutoRedirect;
|
|
newRequest.KeepAlive = request.KeepAlive;
|
|
newRequest.Method = request.Method;
|
|
newRequest.Proxy = request.Proxy;
|
|
foreach (var name in request.Headers.AllKeys)
|
|
{
|
|
switch (name.ToLower())
|
|
{
|
|
case "host" : newRequest.Host = request.Host; break;
|
|
case "accept" : newRequest.Accept = request.Accept; break;
|
|
case "referer" : newRequest.Referer = request.Referer; break;
|
|
case "user-agent" : newRequest.UserAgent = request.UserAgent; break;
|
|
case "content-type" : newRequest.ContentType = request.ContentType; break;
|
|
case "content-length" : newRequest.ContentLength = request.ContentLength; break;
|
|
case "if-modified-since": newRequest.IfModifiedSince = request.IfModifiedSince; break;
|
|
case "date" : newRequest.Date = request.Date; break;
|
|
default: newRequest.Headers[name] = request.Headers[name]; break;
|
|
}
|
|
}
|
|
//newRequest.Headers = request.Headers;
|
|
return newRequest;
|
|
}
|
|
|
|
private static void StopGsProxyServer()
|
|
{
|
|
Eavesdropper.Terminate();
|
|
}
|
|
|
|
#endregion
|
|
|
|
private const int ProxyServerPort = 8146;
|
|
private static string _gcDispatch;
|
|
public static void StartProxy(string gcDispatch)
|
|
{
|
|
// Check Url format
|
|
var _ = new Uri(gcDispatch);
|
|
_gcDispatch = gcDispatch.TrimEnd('/');
|
|
Logger.I(TAG, "Start Proxy, redirect to " + _gcDispatch);
|
|
StartGsProxyServer(ProxyServerPort);
|
|
//SetSystemProxy(ProxyServerPort);
|
|
}
|
|
|
|
public static void StopProxy()
|
|
{
|
|
Logger.I(TAG, "Stop Proxy");
|
|
//CloseSystemProxy();
|
|
StopGsProxyServer();
|
|
}
|
|
|
|
public static bool CheckAndCreateCertificate()
|
|
{
|
|
return Eavesdropper.Certifier.CreateTrustedRootCertificate();
|
|
}
|
|
|
|
public static bool DestroyCertificate()
|
|
{
|
|
return Eavesdropper.Certifier.DestroyTrustedRootCertificate();
|
|
}
|
|
|
|
public static bool IsRunning => Eavesdropper.IsRunning;
|
|
}
|
|
}
|