Files
AX-Copilot-Codex/.decompiledproj/AxCopilot/Handlers/SystemCommandHandler.cs

271 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Threading;
using AxCopilot.Models;
using AxCopilot.SDK;
using AxCopilot.Services;
using AxCopilot.Views;
namespace AxCopilot.Handlers;
public class SystemCommandHandler : IActionHandler
{
private readonly SettingsService _settings;
private static readonly Regex _timerRe = new Regex("^(?:(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?)$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex _alarmRe = new Regex("^(\\d{1,2}):(\\d{2})$", RegexOptions.Compiled);
public string? Prefix => "/";
public PluginMetadata Metadata => new PluginMetadata("SystemCommands", "시스템 명령 — / 뒤에 명령 입력", "1.0", "AX");
public SystemCommandHandler(SettingsService settings)
{
_settings = settings;
}
public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
{
SystemCommandSettings cfg = _settings.Settings.SystemCommands;
string q = query.Trim().ToLowerInvariant();
if (q.StartsWith("timer"))
{
string text = q;
string text2 = text.Substring(5, text.Length - 5).Trim();
List<LauncherItem> list = new List<LauncherItem>();
if (string.IsNullOrEmpty(text2))
{
list.Add(new LauncherItem("타이머 — 시간을 입력하세요", "예: /timer 5m · /timer 1h30m · /timer 30s 회의", null, null, null, "\ue916"));
return Task.FromResult((IEnumerable<LauncherItem>)list);
}
string[] array = text2.Split(' ', 2);
string s = array[0];
string label = ((array.Length > 1) ? array[1].Trim() : "");
if (TryParseTimer(s, out var seconds) && seconds > 0)
{
string display = FormatDuration(seconds);
string title = (string.IsNullOrEmpty(label) ? ("타이머 " + display) : ("타이머 " + display + " — " + label));
list.Add(new LauncherItem(title, display + " 후 알림 · Enter로 시작", null, (Func<Task>)(() => StartTimerAsync(seconds, (label.Length > 0) ? label : display)), null, "\ue916"));
}
else
{
list.Add(new LauncherItem("형식 오류", "예: /timer 5m · /timer 1h30m · /timer 90s", null, null, null, "\uea39"));
}
return Task.FromResult((IEnumerable<LauncherItem>)list);
}
if (q.StartsWith("alarm"))
{
string text = q;
string text3 = text.Substring(5, text.Length - 5).Trim();
List<LauncherItem> list2 = new List<LauncherItem>();
if (string.IsNullOrEmpty(text3))
{
list2.Add(new LauncherItem("알람 — 시각을 입력하세요", "예: /alarm 14:30 · /alarm 9:00", null, null, null, "\ue916"));
return Task.FromResult((IEnumerable<LauncherItem>)list2);
}
Match match = _alarmRe.Match(text3.Split(' ')[0]);
if (match.Success)
{
int num = int.Parse(match.Groups[1].Value);
int num2 = int.Parse(match.Groups[2].Value);
object obj;
if (!text3.Contains(' '))
{
obj = "";
}
else
{
text = text3;
int num3 = text3.IndexOf(' ') + 1;
obj = text.Substring(num3, text.Length - num3);
}
string label2 = (string)obj;
if (num >= 0 && num <= 23 && num2 >= 0 && num2 <= 59)
{
DateTime dateTime = DateTime.Today.AddHours(num).AddMinutes(num2);
if (dateTime <= DateTime.Now)
{
dateTime = dateTime.AddDays(1.0);
}
int diff = (int)(dateTime - DateTime.Now).TotalSeconds;
string timeStr = dateTime.ToString("HH:mm");
list2.Add(new LauncherItem("알람 " + timeStr + " " + ((dateTime.Date > DateTime.Today) ? "(내일)" : ""), (FormatDuration(diff) + " 후 알림 · Enter로 시작 " + ((label2.Length > 0) ? ("— " + label2) : "")).Trim(), null, (Func<Task>)(() => StartTimerAsync(diff, (label2.Length > 0) ? label2 : (timeStr + " 알람"))), null, "\ue916"));
}
else
{
list2.Add(new LauncherItem("시각 범위 오류", "00:00 ~ 23:59 범위로 입력하세요", null, null, null, "\uea39"));
}
}
else
{
list2.Add(new LauncherItem("형식 오류", "예: /alarm 14:30 · /alarm 09:00", null, null, null, "\uea39"));
}
return Task.FromResult((IEnumerable<LauncherItem>)list2);
}
List<(string, string, string, string, bool, Func<Task>)> list3 = new List<(string, string, string, string, bool, Func<Task>)>();
list3.Add(("lock", "화면 잠금", "현재 세션을 잠급니다", "\ue72e", cfg.ShowLock, LockAsync));
list3.Add(("sleep", "절전 모드", "시스템을 절전 상태로 전환합니다", "\uec46", cfg.ShowSleep, SleepAsync));
list3.Add(("restart", "재시작", "컴퓨터를 재시작합니다", "\ue777", cfg.ShowRestart, RestartAsync));
list3.Add(("shutdown", "시스템 종료", "컴퓨터를 종료합니다", "\ue7e8", cfg.ShowShutdown, ShutdownAsync));
list3.Add(("hibernate", "최대 절전", "최대 절전 모드로 전환합니다", "\uec46", cfg.ShowHibernate, HibernateAsync));
list3.Add(("logout", "로그아웃", "현재 사용자 세션에서 로그아웃합니다", "\uf3b1", cfg.ShowLogout, LogoutAsync));
list3.Add(("recycle", "휴지통 비우기", "휴지통의 모든 파일을 영구 삭제합니다", "\ue74d", cfg.ShowRecycleBin, EmptyRecycleBinAsync));
list3.Add(("dock", "독 바 표시/숨기기", "화면 하단 독 바를 표시하거나 숨깁니다", "\ue8a0", true, ToggleDockAsync));
List<(string, string, string, string, bool, Func<Task>)> source = list3;
List<string> value;
IEnumerable<LauncherItem> source2 = from c in source
where c.Enabled
where string.IsNullOrEmpty(q) || c.Key.StartsWith(q) || c.Name.Contains(q) || (cfg.CommandAliases.TryGetValue(c.Key, out value) && value.Any((string a) => a.StartsWith(q, StringComparison.OrdinalIgnoreCase)))
select new LauncherItem(c.Name, c.Hint, null, c.Action, null, c.Symbol);
return Task.FromResult((IEnumerable<LauncherItem>)source2.ToList());
}
public async Task ExecuteAsync(LauncherItem item, CancellationToken ct)
{
object data = item.Data;
Func<Task> action = data as Func<Task>;
if (action != null)
{
await action();
}
}
private static async Task StartTimerAsync(int totalSeconds, string label)
{
await Task.Delay(TimeSpan.FromSeconds(totalSeconds));
NotificationService.Notify("⏰ 타이머 완료", label);
}
private static bool TryParseTimer(string s, out int totalSeconds)
{
totalSeconds = 0;
Match match = _timerRe.Match(s.ToLowerInvariant());
if (!match.Success)
{
return false;
}
int num = (match.Groups[1].Success ? int.Parse(match.Groups[1].Value) : 0);
int num2 = (match.Groups[2].Success ? int.Parse(match.Groups[2].Value) : 0);
int num3 = (match.Groups[3].Success ? int.Parse(match.Groups[3].Value) : 0);
totalSeconds = num * 3600 + num2 * 60 + num3;
return true;
}
private static string FormatDuration(int totalSeconds)
{
int num = totalSeconds / 3600;
int num2 = totalSeconds % 3600 / 60;
int num3 = totalSeconds % 60;
if (num > 0 && num2 > 0)
{
return $"{num}시간 {num2}분";
}
if (num <= 0)
{
if (num2 > 0 && num3 > 0)
{
return $"{num2}분 {num3}초";
}
if (num2 <= 0)
{
return $"{num3}초";
}
return $"{num2}분";
}
return $"{num}시간";
}
private static Task LockAsync()
{
LockWorkStation();
return Task.CompletedTask;
}
private static Task SleepAsync()
{
System.Windows.Forms.Application.SetSuspendState(PowerState.Suspend, force: false, disableWakeEvent: false);
return Task.CompletedTask;
}
private static Task HibernateAsync()
{
System.Windows.Forms.Application.SetSuspendState(PowerState.Hibernate, force: false, disableWakeEvent: false);
return Task.CompletedTask;
}
private static Task RestartAsync()
{
MessageBoxResult messageBoxResult = CustomMessageBox.Show("컴퓨터를 재시작하시겠습니까?\n저장되지 않은 작업이 있으면 먼저 저장하세요.", "재시작 확인", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (messageBoxResult == MessageBoxResult.Yes)
{
Process.Start(new ProcessStartInfo("shutdown", "/r /t 5 /c \"AX Copilot에 의해 재시작됩니다.\"")
{
UseShellExecute = true,
CreateNoWindow = true
});
}
return Task.CompletedTask;
}
private static Task ShutdownAsync()
{
MessageBoxResult messageBoxResult = CustomMessageBox.Show("컴퓨터를 종료하시겠습니까?\n저장되지 않은 작업이 있으면 먼저 저장하세요.", "종료 확인", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (messageBoxResult == MessageBoxResult.Yes)
{
Process.Start(new ProcessStartInfo("shutdown", "/s /t 5 /c \"AX Copilot에 의해 종료됩니다.\"")
{
UseShellExecute = true,
CreateNoWindow = true
});
}
return Task.CompletedTask;
}
private static Task LogoutAsync()
{
MessageBoxResult messageBoxResult = CustomMessageBox.Show("로그아웃하시겠습니까?", "로그아웃 확인", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (messageBoxResult == MessageBoxResult.Yes)
{
ExitWindowsEx(0u, 0u);
}
return Task.CompletedTask;
}
private static Task EmptyRecycleBinAsync()
{
MessageBoxResult messageBoxResult = CustomMessageBox.Show("휴지통을 비우시겠습니까?\n삭제된 파일은 복구할 수 없습니다.", "휴지통 비우기", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
if (messageBoxResult == MessageBoxResult.Yes)
{
SHEmptyRecycleBin(IntPtr.Zero, null, 7u);
}
return Task.CompletedTask;
}
private static Task ToggleDockAsync()
{
((DispatcherObject)System.Windows.Application.Current).Dispatcher.Invoke((Action)delegate
{
(System.Windows.Application.Current as App)?.ToggleDockBar();
});
return Task.CompletedTask;
}
[DllImport("user32.dll", SetLastError = true)]
private static extern bool LockWorkStation();
[DllImport("user32.dll", SetLastError = true)]
private static extern bool ExitWindowsEx(uint uFlags, uint dwReason);
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
private static extern uint SHEmptyRecycleBin(nint hwnd, string? pszRootPath, uint dwFlags);
}