using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using JXHelper.Common; using JXHelper.Config; using JXHelper.Platform; namespace JXHelper.Core; /// /// Động cơ điều khiển & tiện ích bổ trợ (INV-BG-INPUT-NO-HIJACK). /// Quản lý Ẩn/Hiện game, Auto Tiên Thảo Lộ x2, Tự nhận Party (Ctrl+P), và Hẹn giờ tắt máy. /// public class ControlEngine : IDisposable { private CancellationTokenSource? _cts; private Task? _loopTask; public event Action? OnLog; public void Start(IntPtr hWnd, BotConfig config) { Stop(); _cts = new CancellationTokenSource(); var ct = _cts.Token; _loopTask = Task.Run(() => WorkerLoopAsync(hWnd, config, ct), ct); } public void Stop() { _cts?.Cancel(); _cts?.Dispose(); _cts = null; _loopTask = null; } private async Task WorkerLoopAsync(IntPtr hWnd, BotConfig config, CancellationToken ct) { var startTime = DateTime.UtcNow; var lastPartyCheck = DateTime.UtcNow; while (!ct.IsCancellationRequested && NativeMethods.IsWindow(hWnd)) { try { var now = DateTime.UtcNow; // 1. Tự động nhận Party (Ctrl+P) if (config.AutoPartyEnabled && (now - lastPartyCheck).TotalSeconds >= 15) { lastPartyCheck = now; // Gửi phím 'P' hoặc Ctrl+P để mở/nhận lời mời tổ đội await BackgroundInput.SendKeyAsync(hWnd, 0x50); // VK_P ('P') await Task.Delay(200, ct); // Gửi phím 'Enter' hoặc 'Space' để đồng ý await BackgroundInput.SendKeyAsync(hWnd, 0x0D); // VK_RETURN } // 2. Tự dùng Tiên Thảo Lộ (TTL x2 EXP) if (config.AutoTtlEnabled) { long currentUnix = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); long intervalSec = (long)config.TtlIntervalMinutes * 60; if (config.LastTtlUseTimestamp == 0 || (currentUnix - config.LastTtlUseTimestamp) >= intervalSec) { OnLog?.Invoke("[TIỆN ÍCH] Tự động sử dụng Tiên Thảo Lộ (x2 EXP)..."); await UseTtlItemAsync(hWnd, config, ct); config.LastTtlUseTimestamp = currentUnix; config.Save(); OnLog?.Invoke("[TIỆN ÍCH] Đã dùng Tiên Thảo Lộ thành công."); } } // 3. Hẹn giờ thoát game if (config.ScheduledExitGameEnabled) { double elapsedMinutes = (now - startTime).TotalMinutes; if (elapsedMinutes >= config.ExitGameMinutes) { OnLog?.Invoke("[HẸN GIỜ] Đã hết thời gian chơi. Đang đóng cửa sổ game..."); NativeMethods.PostMessage(hWnd, 0x0010, IntPtr.Zero, IntPtr.Zero); // WM_CLOSE break; } } // 4. Hẹn giờ tắt máy if (config.ScheduledShutdownEnabled) { double elapsedMinutes = (now - startTime).TotalMinutes; if (elapsedMinutes >= config.ShutdownMinutes) { OnLog?.Invoke("[HẸN GIỜ] Đã hết thời gian cắm máy. Đang tắt máy tính trong 60 giây..."); try { Process.Start("shutdown", "/s /t 60"); } catch (Exception ex) { OnLog?.Invoke($"[LỖI TẮT MÁY] {ex.Message}"); } break; } } await Task.Delay(1000, ct); } catch (OperationCanceledException) { break; } catch (Exception ex) { OnLog?.Invoke($"[LỖI CONTROL] {ex.Message}"); await Task.Delay(2000, ct); } } } private static async Task UseTtlItemAsync(IntPtr hWnd, BotConfig config, CancellationToken ct) { // Mở rương F4 await BackgroundInput.SendKeyAsync(hWnd, config.KeyBagVirtualCode); await Task.Delay(400, ct); // Click chuột phải vào ô Tiên Thảo Lộ await BackgroundInput.SendRightClickAsync(hWnd, config.TtlItemX, config.TtlItemY); await Task.Delay(400, ct); // Đóng rương F4 await BackgroundInput.SendKeyAsync(hWnd, config.KeyBagVirtualCode); await Task.Delay(300, ct); } /// /// Ẩn cửa sổ game để giảm 70-80% GPU/RAM khi cắm nhiều tab. /// public static void HideGame(IntPtr hWnd) { if (hWnd != IntPtr.Zero && NativeMethods.IsWindow(hWnd)) { NativeMethods.ShowWindow(hWnd, NativeMethods.SW_HIDE); } } /// /// Hiện lại cửa sổ game về trạng thái bình thường. /// public static void ShowGame(IntPtr hWnd) { if (hWnd != IntPtr.Zero && NativeMethods.IsWindow(hWnd)) { NativeMethods.ShowWindow(hWnd, NativeMethods.SW_RESTORE); } } /// /// Đảo trạng thái Ẩn/Hiện của cửa sổ game. /// public static bool ToggleGame(IntPtr hWnd) { if (hWnd == IntPtr.Zero || !NativeMethods.IsWindow(hWnd)) return false; bool isVis = NativeMethods.IsWindowVisible(hWnd); if (isVis) { HideGame(hWnd); return false; } else { ShowGame(hWnd); return true; } } public void Dispose() { Stop(); } }