Browse Source

Code:ReSettings and cleanup; Func: AIME RW; Func: MainWindowMove

HOME 3 weeks ago
parent
commit
85afb176b5

+ 2 - 2
ChildProcessHolder/ChildProcessKind.cs

@@ -1,10 +1,10 @@
 namespace SinMaiLauncher.ChildProcessHolder;
 
-public enum ChildProcessKind
+internal enum ChildProcessKind
 {
     Invalid = 0,
     MariaDb,
-    AquaDxJava,
+    AquaDx,
     Injector,
     SinMai,
 }

+ 6 - 4
ChildProcessHolder/ChildProcessStateBag.cs

@@ -2,11 +2,11 @@
 
 namespace SinMaiLauncher.ChildProcessHolder;
 
-public abstract class ChildProcessStateBag(ChildProcessKind kind, IProcessStartInfo startInfo)
+internal abstract class ChildProcessStateBag(ChildProcessKind kind, IProcessStartInfo startInfo)
 {
     public ChildProcessKind Kind { get; } = kind;
 
-    public event EventHandler<EventArgs> StatusChanged;
+    public event EventHandler<EventArgs> StatusUpdated;
 
     private Process? process;
     public bool IsAlive => process?.HasExited == false;
@@ -15,11 +15,11 @@ public abstract class ChildProcessStateBag(ChildProcessKind kind, IProcessStartI
 
     public ChildProcessStatus Status
     {
-        get => field;
+        get;
         protected set
         {
             field = value;
-            StatusChanged?.Invoke(this, EventArgs.Empty);
+            StatusUpdated?.Invoke(this, EventArgs.Empty);
         }
     }
 
@@ -77,4 +77,6 @@ public abstract class ChildProcessStateBag(ChildProcessKind kind, IProcessStartI
 
     protected nint? MainWindowHWnd => IsAlive ? process!.MainWindowHandle : null;
     protected bool CloseMainForm() => IsAlive && process!.CloseMainWindow();
+
+    protected void RefreshProcess() => process?.Refresh();
 }

+ 1 - 1
ChildProcessHolder/ChildProcessStateBagForConsole.cs

@@ -2,7 +2,7 @@
 
 namespace SinMaiLauncher.ChildProcessHolder;
 
-public class ChildProcessStateBagForConsole(ChildProcessKind kind, IProcessStartInfo startInfo) : ChildProcessStateBag(kind, startInfo)
+internal class ChildProcessStateBagForConsole(ChildProcessKind kind, IProcessStartInfo startInfo) : ChildProcessStateBag(kind, startInfo)
 {
     public nint? HWndConsole { get; private set; }
 

+ 6 - 8
ChildProcessHolder/ChildProcessStateBagForWin.cs

@@ -1,23 +1,21 @@
 namespace SinMaiLauncher.ChildProcessHolder;
 
-public class ChildProcessStateBagForWin(ChildProcessKind kind, IProcessStartInfo startInfo) : ChildProcessStateBag(kind, startInfo)
+internal class ChildProcessStateBagForWin(ChildProcessKind kind, IProcessStartInfo startInfo) : ChildProcessStateBag(kind, startInfo)
 {
-    public nint? HWndMainWindow { get; private set; }
+    public nint? HWndMainWindow => MainWindowHWnd;
 
     protected override async Task<bool> CheckReadyAsync()
     {
         Status = ChildProcessStatus.WaitingReady;
         if (await WaitForInputIdleAsync(TimeSpan.FromSeconds(5)) == false) return false;
-        HWndMainWindow = IsAlive ? MainWindowHWnd : null;
-        return HWndMainWindow != null;
+        return true;
     }
 
-    public override Task StopAsync(TimeSpan timeout)
+    public override async Task StopAsync(TimeSpan timeout)
     {
         Status = ChildProcessStatus.Stopping;
         CloseMainForm();
-        HWndMainWindow = null;
-        return base.StopAsync(timeout);
-
+        await Task.WhenAny(Task.Delay(timeout), WaitForExitAsync());
+        await base.StopAsync(timeout);
     }
 }

+ 1 - 1
ChildProcessHolder/ChildProcessStatus.cs

@@ -1,6 +1,6 @@
 namespace SinMaiLauncher.ChildProcessHolder;
 
-public enum ChildProcessStatus
+internal enum ChildProcessStatus
 {
     NoLaunched,
     PreLaunching,

+ 1 - 1
ChildProcessHolder/IProcessStartInfo.cs

@@ -1,6 +1,6 @@
 namespace SinMaiLauncher.ChildProcessHolder;
 
-public interface IProcessStartInfo
+internal interface IProcessStartInfo
 {
     public string WorkingDir { get; }
     public string Exe { get; }

+ 5 - 3
ChildProcessHolder/ProcessStateBagAquaDx.cs

@@ -3,7 +3,7 @@ using SinMaiLauncher.Models;
 
 namespace SinMaiLauncher.ChildProcessHolder;
 
-public class ProcessStateBagAquaDx(ILogger<ProcessStateBagAquaDx> logger, InfraSettingReader infra) : ChildProcessStateBagForConsole(ChildProcessKind.AquaDxJava, infra.AquaDx)
+internal class ProcessStateBagAquaDx(ILogger<ProcessStateBagAquaDx> logger, SettingReader infra) : ChildProcessStateBagForConsole(ChildProcessKind.AquaDx, infra.AquaDx)
 {
     protected override async Task<bool> CheckReadyAsync()
     {
@@ -15,13 +15,15 @@ public class ProcessStateBagAquaDx(ILogger<ProcessStateBagAquaDx> logger, InfraS
             const int retryIntervalMs = 1000; // 每秒重试一次
             var startTime = DateTime.Now;
 
+            var settings = infra.Settings.Infra.AquaDx;
+
             while (DateTime.Now - startTime < TimeSpan.FromSeconds(timeoutSecond))
             {
                 try
                 {
                     using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
-                    logger.LogInformation("Attempting to connect to AquaDx at {Host}:{Port}", infra.Settings.AquaDx.Host, infra.Settings.AquaDx.Port);
-                    await socket.ConnectAsync(infra.Settings.AquaDx.Host, infra.Settings.AquaDx.Port);
+                    logger.LogInformation("Attempting to connect to AquaDx at {Host}:{Port}", settings.Host, settings.Port);
+                    await socket.ConnectAsync(settings.Host, settings.Port);
 
                     return true; // 连接成功
                 }

+ 6 - 3
ChildProcessHolder/ProcessStateBagMariaDb.cs

@@ -3,7 +3,7 @@ using SinMaiLauncher.Models;
 
 namespace SinMaiLauncher.ChildProcessHolder;
 
-public class ProcessStateBagMariaDb(ILogger<ProcessStateBagMariaDb> logger, InfraSettingReader infra) : ChildProcessStateBagForConsole(ChildProcessKind.MariaDb, infra.Maria)
+internal class ProcessStateBagMariaDb(ILogger<ProcessStateBagMariaDb> logger, SettingReader infra) : ChildProcessStateBagForConsole(ChildProcessKind.MariaDb, infra.Maria)
 {
     protected override async Task<bool> CheckReadyAsync()
     {
@@ -14,14 +14,17 @@ public class ProcessStateBagMariaDb(ILogger<ProcessStateBagMariaDb> logger, Infr
             const int retryIntervalMs = 1000; // 每秒重试一次
             var startTime = DateTime.Now;
 
-            var connectionString = $"Server={infra.Settings.MariaDb.Host};Port={infra.Settings.MariaDb.Port};Uid={infra.Settings.MariaDb.Usr};Pwd={infra.Settings.MariaDb.Pwd};";
+
+            var setting = infra.Settings.Infra.MariaDb;
+
+            var connectionString = $"Server={setting.Host};Port={setting.Port};Uid={setting.Usr};Pwd={setting.Pwd};";
 
             while (DateTime.Now - startTime < TimeSpan.FromSeconds(timeoutSecond))
             {
                 try
                 {
                     await using var connection = new MySqlConnection(connectionString);
-                    logger.LogInformation($"Attempting to connect to MySQL at {infra.Settings.MariaDb.Host}:{infra.Settings.MariaDb.Port}");
+                    logger.LogInformation($"Attempting to connect to MySQL at {setting.Host}:{setting.Port}");
                     await connection.OpenAsync();
 
                     return true; // 连接成功

+ 1 - 1
Interops/ConsoleInterops.cs

@@ -115,7 +115,7 @@ internal static class ConsoleInterops
             WindowInterops.SetParent(consoleHandle, container.Handle);
 
             // 修改控制台窗口样式,去掉边框
-            WindowInterops.RemoveBorder(consoleHandle);
+            WindowInterops.RemoveBorderVisible(consoleHandle);
         }
 
         public static void ConsoleWindowFill(Control container)

+ 50 - 4
Interops/WindowInterops.cs

@@ -1,5 +1,4 @@
-using System.ComponentModel;
-using System.Runtime.InteropServices;
+using System.Runtime.InteropServices;
 
 namespace SinMaiLauncher.Interops
 {
@@ -13,9 +12,17 @@ namespace SinMaiLauncher.Interops
             [DllImport("user32.dll", SetLastError = true)]
             public static extern bool SetWindowLong(nint hWnd, int nIndex, uint dwNewLong);
 
+            // 获取窗口样式
+            [DllImport("user32.dll")]
+            public static extern uint GetWindowLong(IntPtr hWnd, int nIndex);
+
             [DllImport("user32.dll", SetLastError = true)]
             public static extern bool GetWindowRect(nint hWnd, out RECT lpRect);
 
+            [DllImport("user32.dll")]
+            [return: MarshalAs(UnmanagedType.Bool)]
+            private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
+
             [DllImport("user32.dll", SetLastError = true)]
             public static extern bool MoveWindow(nint hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
 
@@ -51,9 +58,11 @@ namespace SinMaiLauncher.Interops
             }
         }
 
-        public static void RemoveBorder(IntPtr hWnd)
+        public static void RemoveBorderVisible(IntPtr hWnd)
         {
-            NativeWindow.SetWindowLong(hWnd, NativeWindow.GWL_STYLE, NativeWindow.WindowStyles.WS_VISIBLE);
+            var oldVal = NativeWindow.GetWindowLong(hWnd, NativeWindow.GWL_STYLE);
+            if (oldVal != NativeWindow.WindowStyles.WS_VISIBLE)
+                NativeWindow.SetWindowLong(hWnd, NativeWindow.GWL_STYLE, NativeWindow.WindowStyles.WS_VISIBLE);
         }
 
         public static void SetParent(IntPtr hWnd, IntPtr hWndContainer)
@@ -68,5 +77,42 @@ namespace SinMaiLauncher.Interops
             // 调整控制台窗口大小,使其填满容器
             NativeWindow.MoveWindow(hWnd, rect.Left, rect.Top, rect.Width, rect.Height, true);
         }
+
+        public static bool RemoveBorderPopup(IntPtr hWnd)
+        {
+            var oldVal = NativeWindow.GetWindowLong(hWnd, NativeWindow.GWL_STYLE);
+            if (oldVal != NativeWindow.WindowStyles.WS_POPUP)
+                return NativeWindow.SetWindowLong(hWnd, NativeWindow.GWL_STYLE, NativeWindow.WindowStyles.WS_POPUP);
+            return true;
+        }
+
+        public enum MoveWindowResult
+        {
+            Success,
+            NoChange,
+            FailGet,
+            FailSet,
+        }
+
+        public static MoveWindowResult MoveWindow(IntPtr hWnd, int x, int y, int w, int h)
+        {
+            if (NativeWindow.GetWindowRect(hWnd, out var rc))
+            {
+                if (x != rc.Left ||
+                    y != rc.Top ||
+                    w != (rc.Right - rc.Left) ||
+                    h != (rc.Bottom - rc.Top))
+                {
+                    return NativeWindow.MoveWindow(hWnd, x, y, w, h, false)
+                        ? MoveWindowResult.Success
+                        : MoveWindowResult.FailSet
+                        ;
+                }
+
+                return MoveWindowResult.NoChange;
+            }
+
+            return MoveWindowResult.FailGet;
+        }
     }
 }

+ 233 - 195
MainForm.Designer.cs

@@ -29,51 +29,54 @@
         private void InitializeComponent()
         {
             components = new System.ComponentModel.Container();
-            GroupBox groupBox2;
             Label label11;
             Label label9;
             Label label1;
-            GroupBox groupBoxExplorer;
             Label label3;
-            GroupBox groupBox11;
             Label label4;
-            GroupBox groupBox9;
-            Label label17;
-            GroupBox groupBox7;
-            GroupBox groupBox3;
             Label label2;
             Label label6;
-            GroupBox groupBox6;
             Label label12;
             Label label5;
-            GroupBox groupBox4;
             Label label18;
             Label label8;
-            GroupBox groupBox8;
             Label label15;
             Label label7;
+            Label label10;
+            Label label13;
+            groupBox2 = new GroupBox();
             btnProcessLoopBackVirtualNic = new Button();
             lblProcessLoopBackVirtualNic = new Label();
+            groupBox10 = new GroupBox();
             chkExplorerAuto = new CheckBox();
             btnExplorerRestore = new Button();
             btnExplorerKill = new Button();
-            button17 = new Button();
+            groupBox11 = new GroupBox();
+            btnAppDataOverwrite = new Button();
+            groupBox9 = new GroupBox();
+            label14 = new Label();
             cboAimeCard = new SinMaiLauncher.CustomControls.AimeComboBox();
-            button9 = new Button();
+            btnAimeRefresh = new Button();
+            btnAimeWrite = new Button();
+            groupBox7 = new GroupBox();
             chkWinTrickAuto = new CheckBox();
             btnWinTrick = new Button();
+            groupBox3 = new GroupBox();
             lblPidMaria = new Label();
             lblSubControlMaria = new Label();
             btnSubControlMariaStop = new Button();
             btnSubControlMariaStart = new Button();
+            groupBox6 = new GroupBox();
             lblPidAquaDx = new Label();
             lblSubControlAquaDx = new Label();
             btnSubControlAquaDxStop = new Button();
             btnSubControlAquaDxStart = new Button();
+            groupBox4 = new GroupBox();
             lblPidSinMai = new Label();
             lblSubControlSinMai = new Label();
             btnSubControlSinMaiStop = new Button();
             btnSubControlSinMaiStart = new Button();
+            groupBox8 = new GroupBox();
             lblPidInjector = new Label();
             lblSubControlInjector = new Label();
             btnSubControlInjectorStop = new Button();
@@ -94,33 +97,25 @@
             tpConsoleAquaDx = new TabPage();
             tpConsoleInjector = new TabPage();
             tabPageCamera = new TabPage();
-            timer1 = new System.Windows.Forms.Timer(components);
             tpRecordScreen = new TabPage();
-            groupBox2 = new GroupBox();
+            tmrMain = new System.Windows.Forms.Timer(components);
             label11 = new Label();
             label9 = new Label();
             label1 = new Label();
-            groupBoxExplorer = new GroupBox();
             label3 = new Label();
-            groupBox11 = new GroupBox();
             label4 = new Label();
-            groupBox9 = new GroupBox();
-            label17 = new Label();
-            groupBox7 = new GroupBox();
-            groupBox3 = new GroupBox();
             label2 = new Label();
             label6 = new Label();
-            groupBox6 = new GroupBox();
             label12 = new Label();
             label5 = new Label();
-            groupBox4 = new GroupBox();
             label18 = new Label();
             label8 = new Label();
-            groupBox8 = new GroupBox();
             label15 = new Label();
             label7 = new Label();
+            label10 = new Label();
+            label13 = new Label();
             groupBox2.SuspendLayout();
-            groupBoxExplorer.SuspendLayout();
+            groupBox10.SuspendLayout();
             groupBox11.SuspendLayout();
             groupBox9.SuspendLayout();
             groupBox7.SuspendLayout();
@@ -136,8 +131,146 @@
             tpSubControls.SuspendLayout();
             tpConsoles.SuspendLayout();
             tcConsoles.SuspendLayout();
+            tabPageCamera.SuspendLayout();
+            tpRecordScreen.SuspendLayout();
             SuspendLayout();
             // 
+            // label11
+            // 
+            label11.AutoSize = true;
+            label11.Location = new Point(56, 22);
+            label11.Name = "label11";
+            label11.Size = new Size(194, 17);
+            label11.TabIndex = 3;
+            label11.Text = "按需自动配置 Loopback 虚拟网卡";
+            // 
+            // label9
+            // 
+            label9.AutoSize = true;
+            label9.Location = new Point(57, 44);
+            label9.Name = "label9";
+            label9.Size = new Size(44, 17);
+            label9.TabIndex = 3;
+            label9.Text = "状态:";
+            // 
+            // label1
+            // 
+            label1.AutoSize = true;
+            label1.Font = new Font("Microsoft YaHei UI", 20F);
+            label1.Location = new Point(8, 56);
+            label1.Name = "label1";
+            label1.Size = new Size(150, 35);
+            label1.TabIndex = 4;
+            label1.Text = "主控状态:";
+            // 
+            // label3
+            // 
+            label3.AutoSize = true;
+            label3.Location = new Point(108, 23);
+            label3.Name = "label3";
+            label3.Size = new Size(296, 17);
+            label3.TabIndex = 4;
+            label3.Text = "杀死前会记住你打开的文件夹窗口,复活之后重新打开";
+            // 
+            // label4
+            // 
+            label4.AutoSize = true;
+            label4.Location = new Point(11, 25);
+            label4.Name = "label4";
+            label4.Size = new Size(140, 34);
+            label4.TabIndex = 3;
+            label4.Text = "尝试解决因闭店设定无效\r\n而无法游玩的问题";
+            // 
+            // label2
+            // 
+            label2.AutoSize = true;
+            label2.Location = new Point(6, 65);
+            label2.Name = "label2";
+            label2.Size = new Size(40, 17);
+            label2.TabIndex = 3;
+            label2.Text = "PID:";
+            // 
+            // label6
+            // 
+            label6.AutoSize = true;
+            label6.Location = new Point(6, 48);
+            label6.Name = "label6";
+            label6.Size = new Size(44, 17);
+            label6.TabIndex = 3;
+            label6.Text = "状态:";
+            // 
+            // label12
+            // 
+            label12.AutoSize = true;
+            label12.Location = new Point(6, 65);
+            label12.Name = "label12";
+            label12.Size = new Size(40, 17);
+            label12.TabIndex = 3;
+            label12.Text = "PID:";
+            // 
+            // label5
+            // 
+            label5.AutoSize = true;
+            label5.Location = new Point(6, 48);
+            label5.Name = "label5";
+            label5.Size = new Size(44, 17);
+            label5.TabIndex = 3;
+            label5.Text = "状态:";
+            // 
+            // label18
+            // 
+            label18.AutoSize = true;
+            label18.Location = new Point(6, 65);
+            label18.Name = "label18";
+            label18.Size = new Size(40, 17);
+            label18.TabIndex = 3;
+            label18.Text = "PID:";
+            // 
+            // label8
+            // 
+            label8.AutoSize = true;
+            label8.Location = new Point(6, 48);
+            label8.Name = "label8";
+            label8.Size = new Size(44, 17);
+            label8.TabIndex = 3;
+            label8.Text = "状态:";
+            // 
+            // label15
+            // 
+            label15.AutoSize = true;
+            label15.Location = new Point(10, 67);
+            label15.Name = "label15";
+            label15.Size = new Size(40, 17);
+            label15.TabIndex = 3;
+            label15.Text = "PID:";
+            // 
+            // label7
+            // 
+            label7.AutoSize = true;
+            label7.Location = new Point(10, 50);
+            label7.Name = "label7";
+            label7.Size = new Size(44, 17);
+            label7.TabIndex = 3;
+            label7.Text = "状态:";
+            // 
+            // label10
+            // 
+            label10.AutoSize = true;
+            label10.Location = new Point(20, 14);
+            label10.Name = "label10";
+            label10.Size = new Size(56, 17);
+            label10.TabIndex = 0;
+            label10.Text = "还没做!";
+            // 
+            // label13
+            // 
+            label13.AutoSize = true;
+            label13.Location = new Point(50, 32);
+            label13.Name = "label13";
+            label13.Size = new Size(56, 17);
+            label13.TabIndex = 1;
+            label13.Text = "还没做!";
+            // 
             // groupBox2
             // 
             groupBox2.Controls.Add(btnProcessLoopBackVirtualNic);
@@ -159,15 +292,7 @@
             btnProcessLoopBackVirtualNic.TabIndex = 0;
             btnProcessLoopBackVirtualNic.Text = "处理";
             btnProcessLoopBackVirtualNic.UseVisualStyleBackColor = true;
-            // 
-            // label11
-            // 
-            label11.AutoSize = true;
-            label11.Location = new Point(56, 22);
-            label11.Name = "label11";
-            label11.Size = new Size(194, 17);
-            label11.TabIndex = 3;
-            label11.Text = "按需自动配置 Loopback 虚拟网卡";
+            btnProcessLoopBackVirtualNic.Click += btnProcessLoopBackVirtualNic_Click;
             // 
             // lblProcessLoopBackVirtualNic
             // 
@@ -178,37 +303,18 @@
             lblProcessLoopBackVirtualNic.TabIndex = 3;
             lblProcessLoopBackVirtualNic.Text = "待检测";
             // 
-            // label9
-            // 
-            label9.AutoSize = true;
-            label9.Location = new Point(57, 44);
-            label9.Name = "label9";
-            label9.Size = new Size(44, 17);
-            label9.TabIndex = 3;
-            label9.Text = "状态:";
-            // 
-            // label1
-            // 
-            label1.AutoSize = true;
-            label1.Font = new Font("Microsoft YaHei UI", 20F);
-            label1.Location = new Point(8, 56);
-            label1.Name = "label1";
-            label1.Size = new Size(150, 35);
-            label1.TabIndex = 4;
-            label1.Text = "主控状态:";
-            // 
-            // groupBoxExplorer
+            // groupBox10
             // 
-            groupBoxExplorer.Controls.Add(chkExplorerAuto);
-            groupBoxExplorer.Controls.Add(label3);
-            groupBoxExplorer.Controls.Add(btnExplorerRestore);
-            groupBoxExplorer.Controls.Add(btnExplorerKill);
-            groupBoxExplorer.Location = new Point(275, 6);
-            groupBoxExplorer.Name = "groupBoxExplorer";
-            groupBoxExplorer.Size = new Size(417, 70);
-            groupBoxExplorer.TabIndex = 2;
-            groupBoxExplorer.TabStop = false;
-            groupBoxExplorer.Text = "资源管理器托管:避免滑动屏幕边缘出现任务视图打断影响体验";
+            groupBox10.Controls.Add(chkExplorerAuto);
+            groupBox10.Controls.Add(label3);
+            groupBox10.Controls.Add(btnExplorerRestore);
+            groupBox10.Controls.Add(btnExplorerKill);
+            groupBox10.Location = new Point(275, 6);
+            groupBox10.Name = "groupBox10";
+            groupBox10.Size = new Size(417, 70);
+            groupBox10.TabIndex = 2;
+            groupBox10.TabStop = false;
+            groupBox10.Text = "资源管理器托管:避免滑动屏幕边缘出现任务视图打断影响体验";
             // 
             // chkExplorerAuto
             // 
@@ -222,15 +328,6 @@
             chkExplorerAuto.Text = "启动前后自动托管";
             chkExplorerAuto.UseVisualStyleBackColor = true;
             // 
-            // label3
-            // 
-            label3.AutoSize = true;
-            label3.Location = new Point(108, 23);
-            label3.Name = "label3";
-            label3.Size = new Size(296, 17);
-            label3.TabIndex = 4;
-            label3.Text = "杀死前会记住你打开的文件夹窗口,复活之后重新打开";
-            // 
             // btnExplorerRestore
             // 
             btnExplorerRestore.Location = new Point(57, 20);
@@ -239,6 +336,7 @@
             btnExplorerRestore.TabIndex = 2;
             btnExplorerRestore.Text = "复活";
             btnExplorerRestore.UseVisualStyleBackColor = true;
+            btnExplorerRestore.Click += btnExplorerRestore_Click;
             // 
             // btnExplorerKill
             // 
@@ -248,10 +346,11 @@
             btnExplorerKill.TabIndex = 2;
             btnExplorerKill.Text = "杀死";
             btnExplorerKill.UseVisualStyleBackColor = true;
+            btnExplorerKill.Click += btnExplorerKill_Click;
             // 
             // groupBox11
             // 
-            groupBox11.Controls.Add(button17);
+            groupBox11.Controls.Add(btnAppDataOverwrite);
             groupBox11.Controls.Add(label4);
             groupBox11.Location = new Point(284, 6);
             groupBox11.Name = "groupBox11";
@@ -260,62 +359,66 @@
             groupBox11.TabStop = false;
             groupBox11.Text = "覆盖APPDATA";
             // 
-            // button17
+            // btnAppDataOverwrite
             // 
-            button17.Location = new Point(163, 19);
-            button17.Name = "button17";
-            button17.Size = new Size(45, 45);
-            button17.TabIndex = 0;
-            button17.Text = "处理";
-            button17.UseVisualStyleBackColor = true;
-            // 
-            // label4
-            // 
-            label4.AutoSize = true;
-            label4.Location = new Point(11, 25);
-            label4.Name = "label4";
-            label4.Size = new Size(140, 34);
-            label4.TabIndex = 3;
-            label4.Text = "尝试解决因闭店设定无效\r\n而无法游玩的问题";
+            btnAppDataOverwrite.Location = new Point(163, 19);
+            btnAppDataOverwrite.Name = "btnAppDataOverwrite";
+            btnAppDataOverwrite.Size = new Size(45, 45);
+            btnAppDataOverwrite.TabIndex = 0;
+            btnAppDataOverwrite.Text = "处理";
+            btnAppDataOverwrite.UseVisualStyleBackColor = true;
+            btnAppDataOverwrite.Click += btnAppDataOverwrite_Click;
             // 
             // groupBox9
             // 
+            groupBox9.Controls.Add(label14);
             groupBox9.Controls.Add(cboAimeCard);
-            groupBox9.Controls.Add(label17);
-            groupBox9.Controls.Add(button9);
+            groupBox9.Controls.Add(btnAimeRefresh);
+            groupBox9.Controls.Add(btnAimeWrite);
             groupBox9.Location = new Point(8, 6);
             groupBox9.Name = "groupBox9";
-            groupBox9.Size = new Size(269, 70);
+            groupBox9.Size = new Size(333, 100);
             groupBox9.TabIndex = 9;
             groupBox9.TabStop = false;
-            groupBox9.Text = "Aime卡:帮你写进aime.txt";
+            groupBox9.Text = "Aime卡";
+            // 
+            // label14
+            // 
+            label14.AutoSize = true;
+            label14.Location = new Point(8, 57);
+            label14.Name = "label14";
+            label14.Size = new Size(248, 34);
+            label14.TabIndex = 11;
+            label14.Text = "帮你写进aime.txt\r\n数据库启动后按刷新可以列出目前用过的卡号";
             // 
             // cboAimeCard
             // 
             cboAimeCard.FormattingEnabled = true;
-            cboAimeCard.Location = new Point(5, 22);
+            cboAimeCard.Location = new Point(64, 22);
             cboAimeCard.MaxLength = 24;
             cboAimeCard.Name = "cboAimeCard";
             cboAimeCard.Size = new Size(195, 25);
             cboAimeCard.TabIndex = 10;
             // 
-            // label17
+            // btnAimeRefresh
             // 
-            label17.AutoSize = true;
-            label17.Location = new Point(6, 49);
-            label17.Name = "label17";
-            label17.Size = new Size(164, 17);
-            label17.TabIndex = 4;
-            label17.Text = "写过的卡号会记录在下拉列表";
+            btnAimeRefresh.Location = new Point(5, 22);
+            btnAimeRefresh.Name = "btnAimeRefresh";
+            btnAimeRefresh.Size = new Size(53, 23);
+            btnAimeRefresh.TabIndex = 2;
+            btnAimeRefresh.Text = "刷新";
+            btnAimeRefresh.UseVisualStyleBackColor = true;
+            btnAimeRefresh.Click += btnAimeRefresh_Click;
             // 
-            // button9
+            // btnAimeWrite
             // 
-            button9.Location = new Point(206, 22);
-            button9.Name = "button9";
-            button9.Size = new Size(37, 23);
-            button9.TabIndex = 2;
-            button9.Text = "写";
-            button9.UseVisualStyleBackColor = true;
+            btnAimeWrite.Location = new Point(265, 22);
+            btnAimeWrite.Name = "btnAimeWrite";
+            btnAimeWrite.Size = new Size(37, 23);
+            btnAimeWrite.TabIndex = 2;
+            btnAimeWrite.Text = "写";
+            btnAimeWrite.UseVisualStyleBackColor = true;
+            btnAimeWrite.Click += btnAimeWrite_Click;
             // 
             // groupBox7
             // 
@@ -348,6 +451,7 @@
             btnWinTrick.TabIndex = 2;
             btnWinTrick.Text = "调整";
             btnWinTrick.UseVisualStyleBackColor = true;
+            btnWinTrick.Click += btnWinTrick_Click;
             // 
             // groupBox3
             // 
@@ -373,15 +477,6 @@
             lblPidMaria.TabIndex = 3;
             lblPidMaria.Text = "-";
             // 
-            // label2
-            // 
-            label2.AutoSize = true;
-            label2.Location = new Point(6, 65);
-            label2.Name = "label2";
-            label2.Size = new Size(40, 17);
-            label2.TabIndex = 3;
-            label2.Text = "PID:";
-            // 
             // lblSubControlMaria
             // 
             lblSubControlMaria.AutoSize = true;
@@ -391,15 +486,6 @@
             lblSubControlMaria.TabIndex = 3;
             lblSubControlMaria.Text = "未启动";
             // 
-            // label6
-            // 
-            label6.AutoSize = true;
-            label6.Location = new Point(6, 48);
-            label6.Name = "label6";
-            label6.Size = new Size(44, 17);
-            label6.TabIndex = 3;
-            label6.Text = "状态:";
-            // 
             // btnSubControlMariaStop
             // 
             btnSubControlMariaStop.Location = new Point(62, 22);
@@ -442,15 +528,6 @@
             lblPidAquaDx.TabIndex = 4;
             lblPidAquaDx.Text = "-";
             // 
-            // label12
-            // 
-            label12.AutoSize = true;
-            label12.Location = new Point(6, 65);
-            label12.Name = "label12";
-            label12.Size = new Size(40, 17);
-            label12.TabIndex = 3;
-            label12.Text = "PID:";
-            // 
             // lblSubControlAquaDx
             // 
             lblSubControlAquaDx.AutoSize = true;
@@ -460,15 +537,6 @@
             lblSubControlAquaDx.TabIndex = 4;
             lblSubControlAquaDx.Text = "未启动";
             // 
-            // label5
-            // 
-            label5.AutoSize = true;
-            label5.Location = new Point(6, 48);
-            label5.Name = "label5";
-            label5.Size = new Size(44, 17);
-            label5.TabIndex = 3;
-            label5.Text = "状态:";
-            // 
             // btnSubControlAquaDxStop
             // 
             btnSubControlAquaDxStop.Location = new Point(62, 22);
@@ -520,15 +588,6 @@
             lblSubControlSinMai.TabIndex = 5;
             lblSubControlSinMai.Text = "未启动";
             // 
-            // label18
-            // 
-            label18.AutoSize = true;
-            label18.Location = new Point(6, 65);
-            label18.Name = "label18";
-            label18.Size = new Size(40, 17);
-            label18.TabIndex = 3;
-            label18.Text = "PID:";
-            // 
             // btnSubControlSinMaiStop
             // 
             btnSubControlSinMaiStop.Location = new Point(62, 22);
@@ -538,15 +597,6 @@
             btnSubControlSinMaiStop.Text = "停止";
             btnSubControlSinMaiStop.UseVisualStyleBackColor = true;
             // 
-            // label8
-            // 
-            label8.AutoSize = true;
-            label8.Location = new Point(6, 48);
-            label8.Name = "label8";
-            label8.Size = new Size(44, 17);
-            label8.TabIndex = 3;
-            label8.Text = "状态:";
-            // 
             // btnSubControlSinMaiStart
             // 
             btnSubControlSinMaiStart.Location = new Point(6, 22);
@@ -589,15 +639,6 @@
             lblSubControlInjector.TabIndex = 5;
             lblSubControlInjector.Text = "未启动";
             // 
-            // label15
-            // 
-            label15.AutoSize = true;
-            label15.Location = new Point(10, 67);
-            label15.Name = "label15";
-            label15.Size = new Size(40, 17);
-            label15.TabIndex = 3;
-            label15.Text = "PID:";
-            // 
             // btnSubControlInjectorStop
             // 
             btnSubControlInjectorStop.Location = new Point(62, 22);
@@ -607,15 +648,6 @@
             btnSubControlInjectorStop.Text = "停止";
             btnSubControlInjectorStop.UseVisualStyleBackColor = true;
             // 
-            // label7
-            // 
-            label7.AutoSize = true;
-            label7.Location = new Point(10, 50);
-            label7.Name = "label7";
-            label7.Size = new Size(44, 17);
-            label7.TabIndex = 3;
-            label7.Text = "状态:";
-            // 
             // btnSubControlInjectorStart
             // 
             btnSubControlInjectorStart.Location = new Point(9, 22);
@@ -675,7 +707,6 @@
             tcMain.SelectedIndex = 0;
             tcMain.Size = new Size(724, 157);
             tcMain.TabIndex = 5;
-            tcMain.SelectedIndexChanged += tcMain_SelectedIndexChanged;
             // 
             // tpMainControl
             // 
@@ -705,7 +736,7 @@
             // tpUtils
             // 
             tpUtils.Controls.Add(groupBox7);
-            tpUtils.Controls.Add(groupBoxExplorer);
+            tpUtils.Controls.Add(groupBox10);
             tpUtils.Location = new Point(4, 26);
             tpUtils.Name = "tpUtils";
             tpUtils.Padding = new Padding(3);
@@ -807,6 +838,7 @@
             // 
             // tabPageCamera
             // 
+            tabPageCamera.Controls.Add(label10);
             tabPageCamera.Location = new Point(4, 26);
             tabPageCamera.Name = "tabPageCamera";
             tabPageCamera.Padding = new Padding(3);
@@ -815,14 +847,9 @@
             tabPageCamera.Text = "摄像头";
             tabPageCamera.UseVisualStyleBackColor = true;
             // 
-            // timer1
-            // 
-            timer1.Enabled = true;
-            timer1.Interval = 200;
-            timer1.Tick += timer1_Tick;
-            // 
             // tpRecordScreen
             // 
+            tpRecordScreen.Controls.Add(label13);
             tpRecordScreen.Location = new Point(4, 26);
             tpRecordScreen.Name = "tpRecordScreen";
             tpRecordScreen.Padding = new Padding(3);
@@ -831,6 +858,12 @@
             tpRecordScreen.Text = "录屏";
             tpRecordScreen.UseVisualStyleBackColor = true;
             // 
+            // tmrMain
+            // 
+            tmrMain.Enabled = true;
+            tmrMain.Interval = 200;
+            tmrMain.Tick += tmrMain_Tick;
+            // 
             // MainForm
             // 
             AutoScaleDimensions = new SizeF(7F, 17F);
@@ -847,8 +880,8 @@
             Shown += MainForm_Shown;
             groupBox2.ResumeLayout(false);
             groupBox2.PerformLayout();
-            groupBoxExplorer.ResumeLayout(false);
-            groupBoxExplorer.PerformLayout();
+            groupBox10.ResumeLayout(false);
+            groupBox10.PerformLayout();
             groupBox11.ResumeLayout(false);
             groupBox11.PerformLayout();
             groupBox9.ResumeLayout(false);
@@ -872,6 +905,10 @@
             tpSubControls.ResumeLayout(false);
             tpConsoles.ResumeLayout(false);
             tcConsoles.ResumeLayout(false);
+            tabPageCamera.ResumeLayout(false);
+            tabPageCamera.PerformLayout();
+            tpRecordScreen.ResumeLayout(false);
+            tpRecordScreen.PerformLayout();
             ResumeLayout(false);
         }
 
@@ -879,7 +916,7 @@
         private GroupBox groupBox2;
         private Button btnProcessLoopBackVirtualNic;
         private Button btnMainControlStart;
-        private GroupBox groupBoxExplorer;
+        private GroupBox groupBox10;
         private Label label3;
         private Button btnExplorerRestore;
         private Button btnExplorerKill;
@@ -888,7 +925,7 @@
         private Label label1;
         private GroupBox groupBox11;
         private Label label4;
-        private Button button17;
+        private Button btnAppDataOverwrite;
         private Label label11;
         private Label lblMainControlStatus;
         private TabControl tcMain;
@@ -909,8 +946,7 @@
         private TabPage tpSubControls;
         private TabPage tpAimeCard;
         private GroupBox groupBox9;
-        private Label label17;
-        private Button button9;
+        private Button btnAimeWrite;
         private GroupBox groupBox3;
         private Label lblSubControlMaria;
         private Label label6;
@@ -931,7 +967,7 @@
         private Button btnSubControlInjectorStop;
         private Label label7;
         private Button btnSubControlInjectorStart;
-        private System.Windows.Forms.Timer timer1;
+        private System.Windows.Forms.Timer tmrMain;
         private TabPage tabPageCamera;
         private CustomControls.AimeComboBox cboAimeCard;
         private Label lblPidMaria;
@@ -939,5 +975,7 @@
         private Label lblPidSinMai;
         private Label lblPidInjector;
         private TabPage tpRecordScreen;
+        private Button btnAimeRefresh;
+        private Label label14;
     }
 }

+ 195 - 69
MainForm.cs

@@ -1,13 +1,8 @@
-using System.Diagnostics;
-using System.Net.Sockets;
-using Microsoft.Extensions.Hosting;
 using Microsoft.Extensions.Logging.Console;
 using MySql.Data.MySqlClient;
 using SinMaiLauncher.ChildProcessHolder;
 using SinMaiLauncher.Interops;
 using SinMaiLauncher.Models;
-using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
-using static Google.Protobuf.WellKnownTypes.Field.Types;
 
 namespace SinMaiLauncher;
 
@@ -17,11 +12,12 @@ public partial class MainForm : Form
 
     private readonly IEnumerator<string> txtAni = TextAnimation.LoadingTextSeq(8).GetEnumerator();
 
-    private InfraSettingReader infra;
+    private SettingReader setting;
 
     private Dictionary<ChildProcessKind, ChildProcessControlGroup> childProcessControlGroups;
 
     private string mainControlStatusText = "摸鱼中";
+    private bool mainControlStatusTextAnimation = false;
 
     public MainForm()
     {
@@ -72,24 +68,24 @@ public partial class MainForm : Form
         logger = services.GetRequiredService<ILogger<MainForm>>();
         var conf = services.GetRequiredService<IConfiguration>();
 
-        var infraSettings = new InfraSettings();
-        conf.GetSection("Infra").Bind(infraSettings);
-        infra = new(infraSettings);
+        var settingModel = new SinMaiLauncherSettingModel();
+        conf.GetSection("SinMaiLauncher").Bind(settingModel);
+        setting = new(settingModel);
 
         childProcessControlGroups = new Dictionary<ChildProcessKind, ChildProcessControlGroup>
         {
             {
                 ChildProcessKind.MariaDb, new ChildProcessControlGroup
                 {
-                    StateBag = new ProcessStateBagMariaDb(services.GetRequiredService<ILogger<ProcessStateBagMariaDb>>(), infra),
+                    StateBag = new ProcessStateBagMariaDb(services.GetRequiredService<ILogger<ProcessStateBagMariaDb>>(), setting),
                     ConsoleTab = tpConsoleMaria, PidLabel = lblPidMaria, StatusLabel = lblSubControlMaria,
                     StartButton = btnSubControlMariaStart, StopButton = btnSubControlMariaStop
                 }
             },
             {
-                ChildProcessKind.AquaDxJava, new ChildProcessControlGroup
+                ChildProcessKind.AquaDx, new ChildProcessControlGroup
                 {
-                    StateBag = new ProcessStateBagAquaDx(services.GetRequiredService<ILogger<ProcessStateBagAquaDx>>(), infra),
+                    StateBag = new ProcessStateBagAquaDx(services.GetRequiredService<ILogger<ProcessStateBagAquaDx>>(), setting),
                     Dep = ChildProcessKind.MariaDb,
                     ConsoleTab = tpConsoleAquaDx, PidLabel = lblPidAquaDx, StatusLabel = lblSubControlAquaDx,
                     StartButton = btnSubControlAquaDxStart, StopButton = btnSubControlAquaDxStop
@@ -98,8 +94,8 @@ public partial class MainForm : Form
             {
                 ChildProcessKind.Injector, new ChildProcessControlGroup
                 {
-                    StateBag = new ChildProcessStateBagForConsole(ChildProcessKind.Injector, infra.Injector),
-                    Dep = ChildProcessKind.AquaDxJava,
+                    StateBag = new ChildProcessStateBagForConsole(ChildProcessKind.Injector, setting.Injector),
+                    Dep = ChildProcessKind.AquaDx,
                     ConsoleTab = tpConsoleInjector, PidLabel = lblPidInjector, StatusLabel = lblSubControlInjector,
                     StartButton = btnSubControlInjectorStart, StopButton = btnSubControlInjectorStop
                 }
@@ -107,7 +103,7 @@ public partial class MainForm : Form
             {
                 ChildProcessKind.SinMai, new ChildProcessControlGroup
                 {
-                    StateBag = new ChildProcessStateBagForWin(ChildProcessKind.SinMai, infra.SinMai),
+                    StateBag = new ChildProcessStateBagForWin(ChildProcessKind.SinMai, setting.SinMai),
                     Dep = ChildProcessKind.Injector,
                     ConsoleTab = null, PidLabel = lblPidSinMai, StatusLabel = lblSubControlSinMai,
                     StartButton = btnSubControlSinMaiStart, StopButton = btnSubControlSinMaiStop
@@ -162,9 +158,9 @@ public partial class MainForm : Form
                 await cpb.StopAsync(TimeSpan.FromSeconds(5));
             };
 
-            cpb.StatusChanged += async delegate
+            cpb.StatusUpdated += async delegate
             {
-                var action = () =>
+                void UpdateUi()
                 {
                     lblPid.Text = cpb.Pid.HasValue ? cpb.Pid.Value.ToString() : "-";
 
@@ -182,24 +178,28 @@ public partial class MainForm : Form
                         _ => "?"
                     };
 
-                    if (cpb.Status == ChildProcessStatus.WaitingReady && cpb is ChildProcessStateBagForConsole con &&
-                        cpb.IsAlive && cpb.Pid.HasValue && con.HWndConsole.HasValue)
+                    if (cpb.Status == ChildProcessStatus.WaitingReady && cpb is ChildProcessStateBagForConsole con && cpb.IsAlive && cpb.Pid.HasValue && con.HWndConsole.HasValue)
                     {
                         if (tab != null)
                         {
                             //console 收纳
                             Program.DisableQuickEdit(cpb.Pid.Value);
-                            WindowInterops.RemoveBorder(con.HWndConsole.Value);
+                            WindowInterops.RemoveBorderVisible(con.HWndConsole.Value);
                             WindowInterops.SetParent(con.HWndConsole.Value, tab.Handle);
                             WindowInterops.FillWindow(con.HWndConsole.Value, tab);
                             Height++;
                             Height--;
                         }
                     }
-                };
 
-                if (InvokeRequired) await InvokeAsync(action);
-                else action();
+                    if (cpb.Status == ChildProcessStatus.Ready && cpb is ChildProcessStateBagForWin win)
+                    {
+                        //chkExplorerAuto
+                    }
+                }
+
+                if (InvokeRequired) await InvokeAsync(UpdateUi);
+                else UpdateUi();
             };
         }
 
@@ -219,47 +219,22 @@ public partial class MainForm : Form
 
     private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
     {
-#if DEBUG
-        return;
-#else
-        e.Cancel = MessageBox.Show($"为了避免进度数据裂开,请确保安全停止再关闭。{Environment.NewLine}要关闭启动器吗?", "关闭启动器", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) ==
-                   DialogResult.No;
-#endif
+        if (
+            childProcessControlGroups[ChildProcessKind.MariaDb].StateBag.Status == ChildProcessStatus.Ready
+            || childProcessControlGroups[ChildProcessKind.AquaDx].StateBag.Status == ChildProcessStatus.Ready
+        )
+        {
+            e.Cancel = MessageBox.Show($"基础设施进程仍在运行。{Environment.NewLine}为了避免进度数据裂开,请确保安全停止再关闭。{Environment.NewLine}要强制关闭吗?", "关闭启动器", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.No;
+        }
     }
 
     private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
     {
         //Kill all child process
-    }
-
-    private void timer1_Tick(object sender, EventArgs e)
-    {
-        txtAni.MoveNext();
-        lblMainControlStatus.Text = $"{mainControlStatusText} {txtAni.Current}";
-    }
-
-    //private TabPage? lasTabPage;
-    private void tcMain_SelectedIndexChanged(object sender, EventArgs e)
-    {
-        //if (tcMain.SelectedTab == tabPageCamera)
-        //{
-        //    var loc = tcMain.PointToScreen(Point.Empty);
-        //    FormBorderStyle = FormBorderStyle.None;
-        //    Location = loc;
-        //}
-        //else if (lasTabPage == tabPageCamera)
-        //{
-        //    var loc1 = tcMain.PointToScreen(Point.Empty);
-        //    FormBorderStyle = FormBorderStyle.Sizable;
-        //    var loc2 = tcMain.PointToScreen(Point.Empty);
-
-        //    var diff= new Point( loc1.X-loc2.X , loc1.Y - loc2.Y);
-        //    var now = Location;
-        //    now.Offset(diff);
-        //    Location = now;
-        //}
-
-        //lasTabPage = tcMain.SelectedTab;
+        childProcessControlGroups[ChildProcessKind.SinMai].StateBag.StopAsync(TimeSpan.FromSeconds(10)).Wait(TimeSpan.FromSeconds(10));
+        childProcessControlGroups[ChildProcessKind.Injector].StateBag.StopAsync(TimeSpan.FromSeconds(10)).Wait(TimeSpan.FromSeconds(10));
+        childProcessControlGroups[ChildProcessKind.AquaDx].StateBag.StopAsync(TimeSpan.FromSeconds(10)).Wait(TimeSpan.FromSeconds(10));
+        childProcessControlGroups[ChildProcessKind.MariaDb].StateBag.StopAsync(TimeSpan.FromSeconds(10)).Wait(TimeSpan.FromSeconds(10));
     }
 
     private void tcConsoles_SelectedIndexChanged(object sender, EventArgs e)
@@ -282,11 +257,12 @@ public partial class MainForm : Form
     private async void btnMainControlStart_Click(object sender, EventArgs e)
     {
         btnMainControlStart.Enabled = false;
+        mainControlStatusTextAnimation = true;
 
         var orderedProcesses = new List<(ChildProcessKind kind, TimeSpan timeout)>
         {
             (ChildProcessKind.MariaDb, TimeSpan.FromSeconds(30)),
-            (ChildProcessKind.AquaDxJava,TimeSpan.FromSeconds(90)),
+            (ChildProcessKind.AquaDx,TimeSpan.FromSeconds(90)),
             (ChildProcessKind.Injector,TimeSpan.FromSeconds(10)),
             (ChildProcessKind.SinMai,TimeSpan.FromSeconds(10)),
         };
@@ -308,7 +284,6 @@ public partial class MainForm : Form
 
                 mainControlStatusText = $"正在启动 {kind}";
 
-
                 await cpb.StartAsync();
                 await WaitForReadyAsync(cpb, timeout);
 
@@ -319,12 +294,11 @@ public partial class MainForm : Form
                     return;
                 }
                 startedProcesses.Add(kind);
-
             }
 
             mainControlStatusText = $"已启动!";
             btnMainControlStop.Enabled = true;
-            //窗口调整
+            mainControlStatusTextAnimation = false;
         }
         catch (Exception exception)
         {
@@ -349,11 +323,11 @@ public partial class MainForm : Form
                     || cpb.Status == ChildProcessStatus.Stopped
                    )
                 {
-                    cpb.StatusChanged -= handler;
+                    cpb.StatusUpdated -= handler;
                     tcs.TrySetResult(true);
                 }
             };
-            cpb.StatusChanged += handler;
+            cpb.StatusUpdated += handler;
 
             try
             {
@@ -361,13 +335,13 @@ public partial class MainForm : Form
                 await Task.WhenAny(tcs.Task, Task.Delay(timeout));
                 if (!tcs.Task.IsCompleted)
                 {
-                    cpb.StatusChanged -= handler;
+                    cpb.StatusUpdated -= handler;
                     throw new TimeoutException($"{cpb.Kind} did not reach Ready state within {timeout.TotalSeconds} seconds.");
                 }
             }
             finally
             {
-                cpb.StatusChanged -= handler; // 确保清理
+                cpb.StatusUpdated -= handler; // 确保清理
             }
         }
 
@@ -391,6 +365,7 @@ public partial class MainForm : Form
 
             mainControlStatusText = "启动失败,已回滚到启动之前";
             btnMainControlStart.Enabled = true;
+            mainControlStatusTextAnimation = false;
         }
     }
 
@@ -398,9 +373,9 @@ public partial class MainForm : Form
     {
         var orderedProcesses = new List<(ChildProcessKind kind, TimeSpan timeout)>
         {
-            (ChildProcessKind.SinMai,TimeSpan.FromSeconds(10)),
+            (ChildProcessKind.SinMai,TimeSpan.FromSeconds(5)),
             (ChildProcessKind.Injector,TimeSpan.FromSeconds(10)),
-            (ChildProcessKind.AquaDxJava,TimeSpan.FromSeconds(90)),
+            (ChildProcessKind.AquaDx,TimeSpan.FromSeconds(90)),
             (ChildProcessKind.MariaDb, TimeSpan.FromSeconds(30)),
         };
 
@@ -418,6 +393,157 @@ public partial class MainForm : Form
         btnMainControlStart.Enabled = true;
         btnMainControlStop.Enabled = false;
         mainControlStatusText = $"已停止";
+        mainControlStatusTextAnimation = false;
+    }
+
+    private DateTime lastCheckWin = DateTime.Now;
+
+    private void tmrMain_Tick(object sender, EventArgs e)
+    {
+        if (mainControlStatusTextAnimation)
+        {
+            txtAni.MoveNext();
+            lblMainControlStatus.Text = $"{mainControlStatusText} {txtAni.Current}";
+        }
+        else
+        {
+            lblMainControlStatus.Text = $"{mainControlStatusText}";
+        }
+
+        //窗口调整
+        if (chkWinTrickAuto.Checked && lastCheckWin < DateTime.Now.AddSeconds(-5))
+        {
+            lastCheckWin = DateTime.Now;
+
+            var pb = (ChildProcessStateBagForWin)childProcessControlGroups[ChildProcessKind.SinMai].StateBag;
+
+            if (pb.Status == ChildProcessStatus.Ready && pb.HWndMainWindow.HasValue)
+            {
+                MoveSinMaiMainWindow();
+            }
+        }
+    }
+
+    private void btnAimeWrite_Click(object sender, EventArgs e)
+    {
+        var input = cboAimeCard.Text;
+
+        if (string.IsNullOrEmpty(input))
+        {
+            MessageBox.Show("倒是输入aime卡号啊?");
+            return;
+        }
+
+        if (Directory.Exists(setting.AimeFleSinMaiDir) == false)
+        {
+            MessageBox.Show("找不到写aime卡文件的目录");
+            return;
+        }
+
+        if (Directory.Exists(setting.AimeFleSinMaiPath))
+        {
+            MessageBox.Show("找不到写aime卡的文件");
+            return;
+        }
 
+        var aime = input.Replace("-", "");
+
+        File.WriteAllText(setting.AimeFleSinMaiPath, aime);
+    }
+
+    private void btnWinTrick_Click(object sender, EventArgs e)
+    {
+        var pb = (ChildProcessStateBagForWin)childProcessControlGroups[ChildProcessKind.SinMai].StateBag;
+
+        if (pb.Status != ChildProcessStatus.Ready || !pb.HWndMainWindow.HasValue)
+        {
+            MessageBox.Show("游戏启动之后再点这个按钮");
+            return;
+        }
+
+        var moveWindowResult = MoveSinMaiMainWindow();
+        switch (moveWindowResult)
+        {
+            case WindowInterops.MoveWindowResult.FailGet:
+                MessageBox.Show("操作不成功:读取失败");
+                break;
+
+            case WindowInterops.MoveWindowResult.FailSet:
+                MessageBox.Show("操作不成功:设置失败");
+                break;
+
+            case WindowInterops.MoveWindowResult.Success:
+                MessageBox.Show("操作成功");
+                break;
+
+            case WindowInterops.MoveWindowResult.NoChange:
+                MessageBox.Show("没有改变");
+                break;
+        }
+    }
+
+    private WindowInterops.MoveWindowResult MoveSinMaiMainWindow()
+    {
+        var pb = (ChildProcessStateBagForWin)childProcessControlGroups[ChildProcessKind.SinMai].StateBag;
+
+        //WS_CLIPSIBLINGS WS_POPUPWINDOW WS_VISIBLE
+
+        var rc = setting.Settings.AutoRect;
+        return WindowInterops.MoveWindow(pb.HWndMainWindow.Value, rc.Left, rc.Top, rc.Width, rc.Height);
+    }
+
+    private void btnAimeRefresh_Click(object sender, EventArgs e)
+    {
+        if (childProcessControlGroups[ChildProcessKind.MariaDb].StateBag.Status != ChildProcessStatus.Ready)
+        {
+            MessageBox.Show("启动数据库先啊!");
+            return;
+        }
+
+        var conf = setting.Settings.Infra.MariaDb;
+
+        var connectionString = $"Server={conf.Host};Port={conf.Port};Uid={conf.Usr};Pwd={conf.Pwd};";
+
+        using var conn = new MySqlConnection(connectionString);
+        conn.Open();
+        using var cmd = conn.CreateCommand();
+        cmd.CommandText = "SELECT `luid` FROM `aqua`.`sega_card`";
+        using var dr = cmd.ExecuteReader();
+        cboAimeCard.Items.Clear();
+
+        while (dr.Read())
+        {
+            var aimeR = dr["luid"].ToString();
+            var aimeH = string.Join("-",
+                aimeR.Substring(0, 4),
+                aimeR.Substring(4, 4),
+                aimeR.Substring(8, 4),
+                aimeR.Substring(12, 4),
+                aimeR.Substring(16, 4));
+
+            cboAimeCard.Items.Add(aimeH);
+        }
+
+        MessageBox.Show($"从数据库中读取到 {cboAimeCard.Items.Count} 个卡号已载入下拉列表");
+    }
+
+    private void btnExplorerKill_Click(object sender, EventArgs e)
+    {
+        MessageBox.Show("还没做!");
+    }
+
+    private void btnExplorerRestore_Click(object sender, EventArgs e)
+    {
+        MessageBox.Show("还没做!");
+    }
+
+    private void btnProcessLoopBackVirtualNic_Click(object sender, EventArgs e)
+    {
+        MessageBox.Show("还没做!");
+    }
+
+    private void btnAppDataOverwrite_Click(object sender, EventArgs e)
+    {
+        MessageBox.Show("还没做!");
     }
 }

+ 7 - 31
MainForm.resx

@@ -117,9 +117,6 @@
   <resheader name="writer">
     <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
-  <metadata name="groupBox2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
-    <value>False</value>
-  </metadata>
   <metadata name="label11.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>False</value>
   </metadata>
@@ -129,64 +126,43 @@
   <metadata name="label1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>False</value>
   </metadata>
-  <metadata name="groupBoxExplorer.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
-    <value>False</value>
-  </metadata>
   <metadata name="label3.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>False</value>
   </metadata>
-  <metadata name="groupBox11.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
-    <value>False</value>
-  </metadata>
   <metadata name="label4.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>False</value>
   </metadata>
-  <metadata name="groupBox9.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
-    <value>False</value>
-  </metadata>
-  <metadata name="label17.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
-    <value>False</value>
-  </metadata>
-  <metadata name="groupBox7.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
-    <value>False</value>
-  </metadata>
-  <metadata name="groupBox3.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
-    <value>False</value>
-  </metadata>
   <metadata name="label2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>False</value>
   </metadata>
   <metadata name="label6.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>False</value>
   </metadata>
-  <metadata name="groupBox6.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
-    <value>False</value>
-  </metadata>
   <metadata name="label12.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>False</value>
   </metadata>
   <metadata name="label5.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>False</value>
   </metadata>
-  <metadata name="groupBox4.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
-    <value>False</value>
-  </metadata>
   <metadata name="label18.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>False</value>
   </metadata>
   <metadata name="label8.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>False</value>
   </metadata>
-  <metadata name="groupBox8.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
-    <value>False</value>
-  </metadata>
   <metadata name="label15.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>False</value>
   </metadata>
   <metadata name="label7.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>False</value>
   </metadata>
-  <metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+  <metadata name="label10.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>False</value>
+  </metadata>
+  <metadata name="label13.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>False</value>
+  </metadata>
+  <metadata name="tmrMain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>17, 17</value>
   </metadata>
 </root>

+ 0 - 50
Models/InfraSettingReader.cs

@@ -1,50 +0,0 @@
-using System.Drawing.Drawing2D;
-using SinMaiLauncher.ChildProcessHolder;
-
-namespace SinMaiLauncher.Models
-{
-    public class InfraSettingReader
-    {
-        public readonly string BaseDir = Environment.CurrentDirectory;
-        public readonly string InfraDir;
-
-        public IProcessStartInfo Maria;
-        public IProcessStartInfo AquaDx;
-        public IProcessStartInfo Injector;
-        public IProcessStartInfo SinMai;
-
-        public InfraSettings Settings { get; }
-
-        public InfraSettingReader(InfraSettings settings)
-        {
-            Settings = settings;
-            InfraDir = Path.GetFullPath(Path.Combine(BaseDir, settings.InfraPath));
-
-            var mariaDir = Path.GetFullPath(Path.Combine(InfraDir, settings.MariaDb.WorkingDir));
-            var mariaExe = Path.GetFullPath(Path.Combine(mariaDir, settings.MariaDb.MySqlServerExe));
-            var mariaArg = settings.MariaDb.MySqlServerArgs;
-            Maria = new ProcessStartInfoImpl(mariaDir, mariaExe, mariaArg);
-
-            var aquaDxDir = Path.GetFullPath(Path.Combine(InfraDir, settings.AquaDx.WorkingDir));
-            var aquaDxJavaExe = Path.GetFullPath(Path.Combine(aquaDxDir, settings.AquaDx.JavaPath));
-            var aquaDxJavaArg = settings.AquaDx.JavaArgs;
-            AquaDx = new ProcessStartInfoImpl(aquaDxDir, aquaDxJavaExe, aquaDxJavaArg);
-
-            var sinMaiDir = Path.GetFullPath(Path.Combine(InfraDir, settings.SinMai.WorkingDir));
-            var injectorExe = Path.GetFullPath(Path.Combine(sinMaiDir, settings.SinMai.InjectExe));
-            var injectorArg = settings.SinMai.InjectArgs;
-            Injector = new ProcessStartInfoImpl(sinMaiDir, injectorExe, injectorArg);
-
-            var sinMaiExe = Path.GetFullPath(Path.Combine(sinMaiDir, settings.SinMai.SinMaiExe));
-            var sinMaiArg = settings.SinMai.SinMaiArgs;
-            SinMai = new ProcessStartInfoImpl(sinMaiDir, sinMaiExe, sinMaiArg);
-        }
-
-        private class ProcessStartInfoImpl(string workingDir, string exe, string arg) : IProcessStartInfo
-        {
-            public string WorkingDir { get; } = workingDir;
-            public string Exe { get; } = exe;
-            public string Arg { get; } = arg;
-        }
-    }
-}

+ 0 - 41
Models/InfraSettings.cs

@@ -1,41 +0,0 @@
-namespace SinMaiLauncher.Models;
-
-public class InfraSettings
-{
-    public string InfraPath { get; set; }
-
-    public MariaDbSettings MariaDb { get; set; }
-    public AquaDxSettings AquaDx { get; set; }
-    public SinMaiSettings SinMai { get; set; }
-
-
-    public class MariaDbSettings
-    {
-        public string WorkingDir { get; set; }
-        public string MySqlServerExe { get; set; }
-        public string MySqlServerArgs { get; set; }
-        public string Host { get; set; }
-        public int Port { get; set; }
-        public string Usr { get; set; }
-        public string Pwd { get; set; }
-    }
-
-    public class AquaDxSettings
-    {
-        public string WorkingDir { get; set; }
-        public string JavaPath { get; set; }
-        public string JavaArgs { get; set; }
-        public string Host { get; set; }
-        public int Port { get; set; }
-    }
-
-
-    public class SinMaiSettings
-    {
-        public string WorkingDir { get; set; }
-        public string InjectExe { get; set; }
-        public string InjectArgs { get; set; }
-        public string SinMaiExe { get; set; }
-        public string SinMaiArgs { get; set; }
-    }
-}

+ 56 - 0
Models/SettingReader.cs

@@ -0,0 +1,56 @@
+using SinMaiLauncher.ChildProcessHolder;
+
+namespace SinMaiLauncher.Models;
+
+internal class SettingReader
+{
+    public readonly string BaseDir = Environment.CurrentDirectory;
+    public readonly string InfraDir;
+
+    public IProcessStartInfo Maria;
+    public IProcessStartInfo AquaDx;
+    public IProcessStartInfo Injector;
+    public IProcessStartInfo SinMai;
+
+    public string AimeFleSinMaiDir { get; set; }
+    public string AimeFleSinMaiPath { get; set; }
+
+    public SinMaiLauncherSettingModel Settings { get; }
+
+    public SettingReader(SinMaiLauncherSettingModel settings)
+    {
+        Settings = settings;
+
+        InfraDir = Path.GetFullPath(Path.Combine(BaseDir, settings.Infra.InfraPath));
+
+        var mariaDir = Path.GetFullPath(Path.Combine(InfraDir, settings.Infra.MariaDb.WorkingDir));
+        var mariaExe = Path.GetFullPath(Path.Combine(mariaDir, settings.Infra.MariaDb.MySqlServerExe));
+        var mariaArg = settings.Infra.MariaDb.MySqlServerArgs;
+        Maria = new ProcessStartInfoImpl(mariaDir, mariaExe, mariaArg);
+
+        var aquaDxDir = Path.GetFullPath(Path.Combine(InfraDir, settings.Infra.AquaDx.WorkingDir));
+        var aquaDxJavaExe = Path.GetFullPath(Path.Combine(aquaDxDir, settings.Infra.AquaDx.JavaPath));
+        var aquaDxJavaArg = settings.Infra.AquaDx.JavaArgs;
+        AquaDx = new ProcessStartInfoImpl(aquaDxDir, aquaDxJavaExe, aquaDxJavaArg);
+
+        var sinMaiDir = Path.GetFullPath(Path.Combine(InfraDir, settings.SinMai.WorkingDir));
+        var injectorExe = Path.GetFullPath(Path.Combine(sinMaiDir, settings.SinMai.InjectExe));
+        var injectorArg = settings.SinMai.InjectArgs;
+        Injector = new ProcessStartInfoImpl(sinMaiDir, injectorExe, injectorArg);
+
+        var sinMaiExe = Path.GetFullPath(Path.Combine(sinMaiDir, settings.SinMai.SinMaiExe));
+        var sinMaiArg = settings.SinMai.SinMaiArgs;
+        SinMai = new ProcessStartInfoImpl(sinMaiDir, sinMaiExe, sinMaiArg);
+
+        AimeFleSinMaiDir = Path.GetFullPath(Path.Combine(sinMaiDir, settings.SinMai.AimeFileDir));
+        AimeFleSinMaiPath = Path.GetFullPath(Path.Combine(AimeFleSinMaiDir, settings.SinMai.AimeFileName));
+
+    }
+
+    private class ProcessStartInfoImpl(string workingDir, string exe, string arg) : IProcessStartInfo
+    {
+        public string WorkingDir { get; } = workingDir;
+        public string Exe { get; } = exe;
+        public string Arg { get; } = arg;
+    }
+}

+ 60 - 0
Models/SinMaiLauncherSettingModel.cs

@@ -0,0 +1,60 @@
+namespace SinMaiLauncher.Models;
+
+internal class SinMaiLauncherSettingModel
+{
+    public RectModel AutoRect { get; set; }
+
+    public InfraSettings Infra { get; set; }
+
+    public class InfraSettings
+    {
+        public string InfraPath { get; set; }
+
+        public MariaDbSettings MariaDb { get; set; }
+        public AquaDxSettings AquaDx { get; set; }
+
+        public class MariaDbSettings
+        {
+            public string WorkingDir { get; set; }
+            public string MySqlServerExe { get; set; }
+            public string MySqlServerArgs { get; set; }
+            public string Host { get; set; }
+            public int Port { get; set; }
+            public string Usr { get; set; }
+            public string Pwd { get; set; }
+        }
+
+        public class AquaDxSettings
+        {
+            public string WorkingDir { get; set; }
+            public string JavaPath { get; set; }
+            public string JavaArgs { get; set; }
+            public string Host { get; set; }
+            public int Port { get; set; }
+        }
+    }
+
+    public SinMaiSettings SinMai { get; set; }
+
+    public class SinMaiSettings
+    {
+        public string WorkingDir { get; set; }
+
+        public string InjectExe { get; set; }
+        public string InjectArgs { get; set; }
+
+        public string SinMaiExe { get; set; }
+        public string SinMaiArgs { get; set; }
+
+        public string AimeFileDir { get; set; }
+        public string AimeFileName { get; set; }
+    }
+
+    public class RectModel
+    {
+        public int Left { get; set; }
+        public int Top { get; set; }
+        public int Width { get; set; }
+        public int Height { get; set; }
+    }
+}

+ 0 - 1
Program.cs

@@ -25,7 +25,6 @@ internal static class Program
             return 0;
         }
 
-
         //args:
         // get-console-window <pid>
         // ctrl-c <pid>

+ 28 - 17
appsettings.json

@@ -1,21 +1,30 @@
 {
-    "Infra": {
-        "InfraPath": "../Infra",
-        "MariaDb": {
-            "WorkingDir": "MariaDb",
-            "MySqlServerExe": "mysqld.exe",
-            "MySqlServerArgs": "--defaults-file=.\\my.ini --console",
-            "Host": "localhost",
-            "Port": 3306,
-            "Usr": "aqua",
-            "Pwd": "aqua"
+    "SinMaiLauncher": {
+        "AutoRect": {
+            "Left": -540,
+            "Top": 0,
+            "Width": 2160,
+            "Height": 1920
         },
-        "AquaDx": {
-            "WorkingDir": "AquaDx",
-            "JavaPath": "jre21-linked/bin/java.exe",
-            "JavaArgs": "-jar aqua.jar",
-            "Host": "localhost",
-            "Port": 22345
+        "AppDataFileForReplace": "Files/appfile.dat",
+        "Infra": {
+            "InfraPath": "../Infra",
+            "MariaDb": {
+                "WorkingDir": "MariaDb",
+                "MySqlServerExe": "mysqld.exe",
+                "MySqlServerArgs": "--defaults-file=.\\my.ini --console",
+                "Host": "localhost",
+                "Port": 3306,
+                "Usr": "aqua",
+                "Pwd": "aqua"
+            },
+            "AquaDx": {
+                "WorkingDir": "AquaDx",
+                "JavaPath": "jre21-linked/bin/java.exe",
+                "JavaArgs": "-jar aqua.jar",
+                "Host": "localhost",
+                "Port": 22345
+            }
         },
         "SinMai": {
             "WorkingDir": "../Package",
@@ -23,7 +32,9 @@
             "InjectArgs": "-d -k mai2hook.dll amdaemon.exe -f -c config_common.json -c config_server.json -c config_client.json",
             "SinMaiExe": "sinmai.exe",
             "SinMaiArgs": "-screen-fullscreen 0 -popupwindow -screen-width 2160 -screen-height 1920",
-            "AimeFile": "DEVICE/aime.txt"
+            "AimeFileDir": "DEVICE",
+            "AimeFileName": "aime.txt",
+            "AppFilePath": "appdata/SDEZ/appfile.dat"
         }
     }
 }