-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a04179a
commit 045bca3
Showing
7 changed files
with
482 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<configuration> | ||
<startup> | ||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" /> | ||
</startup> | ||
</configuration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,263 @@ | ||
using System; | ||
using System.Runtime.InteropServices; | ||
using System.Windows.Forms; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
using System.Text.RegularExpressions; | ||
using System.Management; | ||
using System.ComponentModel; | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
using System.Text; | ||
|
||
namespace fix_lcu_window_bin | ||
{ | ||
internal class App | ||
{ | ||
[DllImport("User32.dll", EntryPoint = "FindWindow")] | ||
public extern static IntPtr FindWindow(string lpClassName, string lpWindowName); | ||
|
||
[DllImport("User32.dll", EntryPoint = "FindWindowEx")] | ||
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName); | ||
|
||
[DllImport("user32.dll", CharSet = CharSet.Auto)] | ||
private static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags); | ||
|
||
[DllImport("user32.dll")] | ||
private static extern uint GetDpiForWindow([In] IntPtr hmonitor); | ||
|
||
// 取commandline | ||
private static string GetCommandLineByProcessId(int processId) | ||
{ | ||
try | ||
{ | ||
return GetCommandLineArgsCore(); | ||
} | ||
catch (Win32Exception ex) when ((uint)ex.ErrorCode == 0x80004005) | ||
{ | ||
return string.Empty; | ||
} | ||
catch (InvalidOperationException) | ||
{ | ||
return string.Empty; | ||
} | ||
|
||
string GetCommandLineArgsCore() | ||
{ | ||
using (var searcher = new ManagementObjectSearcher( | ||
"SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + processId)) | ||
using (var objects = searcher.Get()) | ||
{ | ||
var @object = objects.Cast<ManagementBaseObject>().SingleOrDefault(); | ||
return @object?["CommandLine"]?.ToString() ?? ""; | ||
} | ||
} | ||
} | ||
|
||
private static int GetProcessId(String processName) | ||
{ | ||
Process[] processes = Process.GetProcesses(); | ||
int iProcessId = 0; | ||
|
||
foreach (Process p in processes) | ||
{ | ||
if (p.ProcessName == processName) | ||
{ | ||
iProcessId = p.Id; | ||
break; | ||
} | ||
} | ||
|
||
return iProcessId; | ||
} | ||
|
||
private static (bool Available, int Port, string Token, string Protocol) CommandLineParser(string command) | ||
{ | ||
Regex installAuthToken = new Regex(@"""--remoting-auth-token=(.*?)"""); | ||
Regex installAppPort = new Regex(@"""--app-port=(.*?)"""); | ||
|
||
var portMatch = installAppPort.Match(command); | ||
var tokenMatch = installAuthToken.Match(command); | ||
|
||
if (portMatch.Success && tokenMatch.Success) | ||
{ | ||
return (true, int.Parse(portMatch.Groups[1].Value), tokenMatch.Groups[1].Value, "https"); | ||
} | ||
|
||
return (false, 0, null, null); | ||
} | ||
|
||
private static async Task<double> GetLeagueClientZoom(int Port, String Token) | ||
{ | ||
|
||
String address = "https://127.0.0.1:" + Port + "/riotclient/zoom-scale"; | ||
|
||
WebRequestHandler handler = new WebRequestHandler(); | ||
HttpClient client = new HttpClient(handler); | ||
|
||
handler.ServerCertificateValidationCallback = delegate { return true; }; | ||
client.DefaultRequestHeaders.Add("Accept", "*/*"); | ||
client.DefaultRequestHeaders.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes("riot:" + Token))); | ||
try | ||
{ | ||
HttpResponseMessage response = await client.GetAsync(address); | ||
response.EnsureSuccessStatusCode(); | ||
|
||
return double.Parse(await response.Content.ReadAsStringAsync()); | ||
} | ||
catch | ||
{ | ||
return -1; | ||
} | ||
} | ||
|
||
private static async Task<bool> RestartClientUx(int Port, String Token) | ||
{ | ||
|
||
string address = "https://127.0.0.1:" + Port + "/riotclient/kill-and-restart-ux"; | ||
|
||
WebRequestHandler handler = new WebRequestHandler(); | ||
HttpClient client = new HttpClient(handler); | ||
|
||
handler.ServerCertificateValidationCallback = delegate { return true; }; | ||
client.DefaultRequestHeaders.Add("Accept", "*/*"); | ||
client.DefaultRequestHeaders.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes("riot:" + Token))); | ||
try | ||
{ | ||
HttpResponseMessage response = await client.PostAsync(address, new StringContent("")); | ||
response.EnsureSuccessStatusCode(); | ||
|
||
return true; | ||
} | ||
catch | ||
{ | ||
return false; | ||
} | ||
} | ||
|
||
private static void emitExit() | ||
{ | ||
Console.WriteLine("按任意键退出..."); | ||
Console.ReadKey(); | ||
} | ||
|
||
private static async Task MethodPlanA() | ||
{ | ||
var LeagueClientUxCommandLine = GetCommandLineByProcessId(GetProcessId("LeagueClientUx")); | ||
var LeagueClientUxArgs = CommandLineParser(LeagueClientUxCommandLine); | ||
|
||
if (!LeagueClientUxArgs.Available) | ||
{ | ||
Console.WriteLine("Can't find LeagueClientUx process."); | ||
emitExit(); | ||
return; | ||
} | ||
|
||
IntPtr pLeagueClientWindowHWnd = FindWindow("RCLIENT", "League of Legends"); | ||
IntPtr pLeagueClientWindowCefHWnd = FindWindowEx(pLeagueClientWindowHWnd, IntPtr.Zero, "CefBrowserWindow", null); | ||
|
||
if (pLeagueClientWindowHWnd == IntPtr.Zero || pLeagueClientWindowCefHWnd == IntPtr.Zero) | ||
{ | ||
Console.WriteLine("Can't find LeagueClient window."); | ||
emitExit(); | ||
return; | ||
} | ||
|
||
double fLeagueClientZoom = await GetLeagueClientZoom(LeagueClientUxArgs.Port, LeagueClientUxArgs.Token); | ||
double fScreenDpi = GetDpiForWindow(pLeagueClientWindowHWnd) / 96.0; | ||
int iScreenWidth = Screen.PrimaryScreen.Bounds.Width; | ||
int iScreenHeight = Screen.PrimaryScreen.Bounds.Height; | ||
|
||
if (fLeagueClientZoom == -1) | ||
{ | ||
Console.WriteLine("Can't get original zoom of LeagueClientUx"); | ||
emitExit(); | ||
return; | ||
} | ||
|
||
int iTargetWindowWidth = (int)(1280 * fLeagueClientZoom); | ||
int iTargetWindowHeight = (int)(720 * fLeagueClientZoom); | ||
|
||
Console.WriteLine("LeagueClientPort: " + LeagueClientUxArgs.Port); | ||
Console.WriteLine("LeagueClientAuthtoken: " + LeagueClientUxArgs.Token); | ||
Console.WriteLine("LeagueClientOriginZoom: " + fLeagueClientZoom); | ||
Console.WriteLine("LeagueClientWindowHWnd: " + pLeagueClientWindowHWnd); | ||
Console.WriteLine("LeagueClientWindowCefHWnd: " + pLeagueClientWindowCefHWnd); | ||
Console.WriteLine("ScreenWidth: " + iScreenWidth * fScreenDpi); | ||
Console.WriteLine("ScreenHeight: " + iScreenHeight * fScreenDpi); | ||
Console.WriteLine("ScreenDpi: " + fScreenDpi); | ||
Console.WriteLine("TargetWindowWidth: " + iTargetWindowWidth); | ||
Console.WriteLine("TargetWindowHeight: " + iTargetWindowHeight); | ||
|
||
Console.WriteLine("-----------------------------"); | ||
Console.WriteLine("客户端修复成功!"); | ||
Console.WriteLine("-----------------------------"); | ||
|
||
SetWindowPos(pLeagueClientWindowHWnd, 0, (iScreenWidth - iTargetWindowWidth) / 2, (iScreenHeight - iTargetWindowHeight) / 2, iTargetWindowWidth, iTargetWindowHeight, 0x0040); | ||
SetWindowPos(pLeagueClientWindowCefHWnd, 0, 0, 0, iTargetWindowWidth, iTargetWindowHeight, 0x0040); | ||
} | ||
|
||
private static async Task MethodPlanB() | ||
{ | ||
var LeagueClientUxCommandLine = GetCommandLineByProcessId(GetProcessId("LeagueClientUx")); | ||
var LeagueClientUxArgs = CommandLineParser(LeagueClientUxCommandLine); | ||
|
||
if (!LeagueClientUxArgs.Available) | ||
{ | ||
Console.WriteLine("Can't find LeagueClientUx process."); | ||
emitExit(); | ||
return; | ||
} | ||
|
||
if (!await RestartClientUx(LeagueClientUxArgs.Port, LeagueClientUxArgs.Token)) | ||
{ | ||
Console.WriteLine("Failed to reload LeagueClientUx."); | ||
emitExit(); | ||
return; | ||
} | ||
|
||
Console.WriteLine("LeagueClientPort: " + LeagueClientUxArgs.Port); | ||
Console.WriteLine("LeagueClientAuthtoken: " + LeagueClientUxArgs.Token); | ||
|
||
Console.WriteLine("-----------------------------"); | ||
Console.WriteLine("客户端修复成功!"); | ||
Console.WriteLine("-----------------------------"); | ||
} | ||
|
||
static void Main(string[] args) | ||
{ | ||
Console.WriteLine("-----------------------------"); | ||
Console.WriteLine("Bilibili: Butter_Cookies"); | ||
Console.WriteLine("Github: https://github.com/LeagueTavern/fix-lcu-window"); | ||
Console.WriteLine("Code by LeagueTavern"); | ||
Console.WriteLine("-----------------------------"); | ||
Console.WriteLine("选择修复模式:"); | ||
Console.WriteLine("[1]: 通过 窗口句柄 修复客户端"); | ||
Console.WriteLine("[2]: 通过 LCUAPI 热重载客户端"); | ||
Console.WriteLine("-----------------------------"); | ||
Console.WriteLine("输入您想选择的修复模式 [1]:"); | ||
|
||
String strUserInput = Console.ReadLine(); | ||
int iUserChoice; | ||
|
||
Console.WriteLine("-----------------------------"); | ||
|
||
|
||
if (String.IsNullOrWhiteSpace(strUserInput) || !int.TryParse(strUserInput, out iUserChoice)) | ||
{ | ||
iUserChoice = 1; | ||
} | ||
|
||
switch (iUserChoice) | ||
{ | ||
case 1: | ||
MethodPlanA().Wait(); | ||
break; | ||
case 2: | ||
MethodPlanB().Wait(); | ||
break; | ||
} | ||
emitExit(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using System.Reflection; | ||
using System.Runtime.CompilerServices; | ||
using System.Runtime.InteropServices; | ||
|
||
|
||
[assembly: AssemblyTitle("Fix-LCU-Window")] | ||
[assembly: AssemblyDescription("Fix League of Legends client window.")] | ||
[assembly: AssemblyConfiguration("")] | ||
[assembly: AssemblyCompany("LeagueTavern")] | ||
[assembly: AssemblyProduct("fix-lcu-window")] | ||
[assembly: AssemblyCopyright("Copyright © LeagueTavern 2023")] | ||
[assembly: AssemblyTrademark("")] | ||
[assembly: AssemblyCulture("")] | ||
|
||
[assembly: ComVisible(false)] | ||
[assembly: Guid("3787836b-68c8-4026-bc2d-833e1752e7f6")] | ||
|
||
[assembly: AssemblyVersion("1.0.0.0")] | ||
[assembly: AssemblyFileVersion("1.0.0.0")] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> | ||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> | ||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> | ||
<security> | ||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> | ||
<!-- UAC 清单选项 | ||
如果想要更改 Windows 用户帐户控制级别,请使用 | ||
以下节点之一替换 requestedExecutionLevel 节点。 | ||
<requestedExecutionLevel level="asInvoker" uiAccess="false" /> | ||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> | ||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" /> | ||
指定 requestedExecutionLevel 元素将禁用文件和注册表虚拟化。 | ||
如果你的应用程序需要此虚拟化来实现向后兼容性,则移除此 | ||
元素。 | ||
--> | ||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> | ||
</requestedPrivileges> | ||
</security> | ||
</trustInfo> | ||
|
||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> | ||
<application> | ||
<!-- 设计此应用程序与其一起工作且已针对此应用程序进行测试的 | ||
Windows 版本的列表。取消评论适当的元素, | ||
Windows 将自动选择最兼容的环境。 --> | ||
|
||
<!-- Windows Vista --> | ||
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />--> | ||
|
||
<!-- Windows 7 --> | ||
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />--> | ||
|
||
<!-- Windows 8 --> | ||
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />--> | ||
|
||
<!-- Windows 8.1 --> | ||
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />--> | ||
|
||
<!-- Windows 10 --> | ||
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />--> | ||
|
||
</application> | ||
</compatibility> | ||
|
||
<!-- 指示该应用程序可感知 DPI 且 Windows 在 DPI 较高时将不会对其进行 | ||
自动缩放。Windows Presentation Foundation (WPF)应用程序自动感知 DPI,无需 | ||
选择加入。选择加入此设置的 Windows 窗体应用程序(面向 .NET Framework 4.6)还应 | ||
在其 app.config 中将 "EnableWindowsFormsHighDpiAutoResizing" 设置设置为 "true"。 | ||
将应用程序设为感知长路径。请参阅 https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation --> | ||
<!-- | ||
<application xmlns="urn:schemas-microsoft-com:asm.v3"> | ||
<windowsSettings> | ||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware> | ||
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware> | ||
</windowsSettings> | ||
</application> | ||
--> | ||
|
||
<!-- 启用 Windows 公共控件和对话框的主题(Windows XP 和更高版本) --> | ||
<!-- | ||
<dependency> | ||
<dependentAssembly> | ||
<assemblyIdentity | ||
type="win32" | ||
name="Microsoft.Windows.Common-Controls" | ||
version="6.0.0.0" | ||
processorArchitecture="*" | ||
publicKeyToken="6595b64144ccf1df" | ||
language="*" | ||
/> | ||
</dependentAssembly> | ||
</dependency> | ||
--> | ||
|
||
</assembly> |
Oops, something went wrong.