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();
}
}