Skip to content

Commit

Permalink
Compatibled for Chinese Bilibili Server
Browse files Browse the repository at this point in the history
  • Loading branch information
emako committed Dec 3, 2022
1 parent 9e1d752 commit bd6a80c
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 6 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,14 @@
## 常见问题

1. 若安装包无法安装,请确保你的系统已安装应用商店,安装包依赖商店架构 (MSIX)。
2. 运行环境是net6.0-windows10.0.19041.0。
2. 运行环境是net6.0-windows10.0.19041.0。
3. 如何按需选择程序包
- 带Setup字眼的是安装包
- 带full字眼的内置.NET运行环境

## 额外说明

- 针对B服的说明
- [x] 自动检测系统安装原神是否为B服。前提是注册表有对应的安装记录,如果使用其他切服程序也能正确识别;
- [x] 自动识别B服登录界面。B服登录框点击延时为登录延时的二分之一,因此每轮用时会延长这部分所需时长,但注意“不会”计入「用时预测」;

2 changes: 1 addition & 1 deletion build/nsis/setup.nsi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
!define PRODUCT_NAME "GenshinWoodmen"
!define PRODUCT_VERSION "1.6.8.0"
!define PRODUCT_VERSION "1.7.0.0"
!define PRODUCT_PUBLISHER "GenshinMatrix"
!define PRODUCT_WEB_SITE "https://github.com/genshin-matrix"
!define PRODUCT_LEGAL "Licensed under MIT"
Expand Down
100 changes: 100 additions & 0 deletions src/GenshinWoodmen/Core/Compatible/CompatibleBilibili.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management;
using System.Threading.Tasks;

namespace GenshinWoodmen.Core;

internal sealed class CompatibleBilibili
{
public static bool IsAvailabled { get; private set; } = false;

public static bool RefreshAvailabled()
{
try
{
string configIni = @$"{GenshinRegedit.InstallPath}\config.ini";
string[] lines = File.ReadAllLines(configIni);

foreach (string line in lines)
{
string kv = line.Trim();
if (kv.StartsWith("cps="))
{
if (kv.EndsWith("bilibili"))
{
return IsAvailabled = true;
}
break;
}
}
}
catch
{
}
return IsAvailabled = false;
}

public static async Task<bool> Login()
{
return await Task.Run(async () =>
{
if (Process.GetProcessesByName("YuanShen").FirstOrDefault() is Process p)
{
IntPtr hwndLogin = IntPtr.Zero;
_ = NativeMethods.EnumWindows((IntPtr hwnd, int lParam) =>
{
try
{
_ = NativeMethods.GetWindowThreadProcessId(hwnd, out int pid);
if (pid == p.Id)
{
string title = NativeMethods.GetWindowTitle(hwnd);
if (!string.IsNullOrEmpty(title))
{
Logger.Info($"[BilibiliServer] {title}");
hwndLogin = hwnd;
return false;
}
}
}
catch
{
}
return true;
}, 0);
if (hwndLogin == IntPtr.Zero) return false;
NativeMethods.Focus(hwndLogin);
NativeMethods.CursorCenterPos(hwndLogin, offsetY: 110);
UserSimulator.Input.Mouse.LeftButtonClick();
return true;
}
return false;
});
}

[Conditional("DEBUG")]
public static void DebugSearch()
{
using ManagementObjectSearcher searcher = new("SELECT ProcessId, ExecutablePath, CommandLine FROM Win32_Process");
using ManagementObjectCollection results = searcher.Get();
var query = from ps in Process.GetProcesses()
join mo in results.Cast<ManagementObject>()
on ps.Id equals (int)(uint)mo["ProcessId"]
select new
{
Process = ps,
Path = (string)mo["ExecutablePath"],
CommandLine = (string)mo["CommandLine"],
};
foreach (var item in query)
{
Logger.Info($"[{item.Process.Id}] {item.Path}|{item.CommandLine}");
}
}
}
9 changes: 9 additions & 0 deletions src/GenshinWoodmen/Core/Compatible/CompatibleEntry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace GenshinWoodmen.Core;

internal static class CompatibleEntry
{
public static void Ensure()
{
CompatibleBilibili.RefreshAvailabled();
}
}
8 changes: 8 additions & 0 deletions src/GenshinWoodmen/Core/JiggingProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public static async void Processing()
{
bool lastAutoLogout = false;

CompatibleEntry.Ensure();
await SetMute(true);
while (!IsCanceled)
{
Expand Down Expand Up @@ -90,6 +91,13 @@ public static async void Processing()
{
if (lastAutoLogout)
{
if (CompatibleBilibili.IsAvailabled)
{
TraceStatus("Login Compatible for bilibili");
await Delay(Settings.DelayLaunch.Get() / 2);
await CompatibleBilibili.Login();
TraceStatus("Login Logined for bilibili");
}
TraceStatus("Login Chattering");
await Delay(Settings.DelayLaunch.Get());
TraceStatus("Login Chattered");
Expand Down
45 changes: 45 additions & 0 deletions src/GenshinWoodmen/Core/NativeMethods.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
using System;
using System.Management;
using System.Runtime.InteropServices;
using System.Text;

namespace GenshinWoodmen.Core;

internal static class NativeMethods
{
public const int WM_SYSCOMMAND = 0x0112;
public const int WM_HOTKEY = 0x0312;
public const int WM_LBUTTONDOWN = 0x0201;

public const int SC_RESTORE = 0xF120;

Expand Down Expand Up @@ -124,6 +126,38 @@ internal static class NativeMethods
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

[DllImport("user32.dll")]
public static extern IntPtr FindWindowEx(int hwndParent, int hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string strclassName, string strWindowName);

[DllImport("user32.dll")]
public static extern int GetLastActivePopup(IntPtr hWnd);

[DllImport("user32.dll")]
public static extern int AnyPopup();

[DllImport("user32.dll")]
public static extern int GetWindowTextLength(IntPtr hWnd);

[DllImport("user32.dll")]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

[DllImport("user32.dll")]
public static extern int EnumThreadWindows(int dwThreadId, EnumWindowsCallBack lpfn, int lParam);

[DllImport("user32.dll")]
public static extern int EnumWindows(EnumWindowsCallBack lpfn, int lParam);

[DllImport("user32.dll")]
public static extern int EnumChildWindows(IntPtr hWndParent, EnumWindowsCallBack lpfn, int lParam);

public delegate bool EnumWindowsCallBack(IntPtr hwnd, int lParam);

[DllImport("user32.dll")]
public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int PID);

[DllImport("winmm.dll", EntryPoint = "mciSendString")]
public static extern uint MciSendString(string lpstrCommand, string lpstrReturnString, uint uReturnLength, uint hWndCallback);

Expand Down Expand Up @@ -285,6 +319,17 @@ public static void SetTopMost(IntPtr hwnd, bool topMost = true)
_ = GetWindowRect(hwnd, ref rect);
_ = SetWindowPos(hwnd, topMost ? HWND_TOPMOST : HWND_NOTOPMOST, rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top, 0);
}

public static string GetWindowTitle(IntPtr hwnd)
{
int capacity = GetWindowTextLength(hwnd);
StringBuilder title = new(capacity + 1);
_ = GetWindowText(hwnd, title, title.Capacity);
return title.ToString();
}

public static int MAKELPARAM(int l, int h) => MAKELONG(l, h);
public static int MAKELONG(int a, int b) => a | (b << 16);
}

[StructLayout(LayoutKind.Sequential)]
Expand Down
6 changes: 3 additions & 3 deletions src/GenshinWoodmen/GenshinWoodmen.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
<ApplicationIcon>Resources\favicon.ico</ApplicationIcon>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Platforms>x64</Platforms>
<AssemblyVersion>1.6.8</AssemblyVersion>
<FileVersion>1.6.8</FileVersion>
<Version>$(VersionPrefix)1.6.8</Version>
<AssemblyVersion>1.7.0</AssemblyVersion>
<FileVersion>1.7.0</FileVersion>
<Version>$(VersionPrefix)1.7.0</Version>
<Authors>GenshinMatrix</Authors>
<Company>GenshinMatrix</Company>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/GenshinWoodmenSetup/Package.appxmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<Identity
Name="c17bc862-e10e-4618-b717-e47dd2bf65c8"
Publisher="CN=ema"
Version="1.6.8.0" />
Version="1.7.0.0" />

<Properties>
<DisplayName>GenshinWoodmen</DisplayName>
Expand Down

0 comments on commit bd6a80c

Please sign in to comment.