From b813d944861af7f796c1cd3aa3badfd14529ec90 Mon Sep 17 00:00:00 2001 From: yuanyuanxiang <962914132@qq.com> Date: Tue, 12 May 2026 22:53:17 +0200 Subject: [PATCH] Improve: Finish "scheduler.h" to support all running plan --- common/scheduler.h | 111 ++++++++++++++++++++++-- server/2015Remote/2015Remote.rc | Bin 154782 -> 154782 bytes server/2015Remote/PluginSettingsDlg.cpp | 7 +- server/2015Remote/lang/en_US.ini | 7 +- server/2015Remote/lang/zh_TW.ini | 7 +- 5 files changed, 121 insertions(+), 11 deletions(-) diff --git a/common/scheduler.h b/common/scheduler.h index 2643958..81c9ab3 100644 --- a/common/scheduler.h +++ b/common/scheduler.h @@ -1,11 +1,16 @@ #ifndef YAMA_SCHEDULER_H #define YAMA_SCHEDULER_H +#include + // 调度模式定义 #define SCH_MODE_NONE 0 // 默认模式:不自动执行 (仅手动) #define SCH_MODE_STARTUP 1 // 启动执行模式 #define SCH_MODE_DAILY 2 // 每日定时模式 #define SCH_MODE_WEEKLY 3 // 每周定时模式 +#define SCH_MODE_MONTHLY 4 // 每月定时模式 +#define SCH_MODE_YEARLY 5 // 每年定时模式 +#define SCH_MODE_OFF 6 // 关闭 #pragma pack(push, 1) // 严格定义 16 字节结构 @@ -40,6 +45,7 @@ class YamaTaskEngine { public: static bool ShouldExecute(const ScheduleParams* p) { // --- 1. 默认与基础拦截 --- + if (p->Mode == SCH_MODE_OFF) return false; if (p->Mode == SCH_MODE_NONE) return false; // Mode为0,默认不执行 if (p->Flags & 0x01) return false; // 显式禁用拦截 if (p->MaxCount > 0 && p->CurrentCount >= p->MaxCount) return false; @@ -63,9 +69,51 @@ public: SYSTEMTIME st; GetLocalTime(&st); unsigned short curMin = (unsigned short)(st.wHour * 60 + st.wMinute); + // TargetMin=0 表示 0:00 执行 if (curMin >= p->Config.Timed.TargetMin) { if (!IsSameDay(p->LastRunTime, now)) return true; } + return false; + } + + // --- 4. 每周定时逻辑 (Mode 3) --- + if (p->Mode == SCH_MODE_WEEKLY) { + SYSTEMTIME st; + GetLocalTime(&st); + unsigned short curMin = (unsigned short)(st.wHour * 60 + st.wMinute); + // DaysMask=0 表示周日 (wDayOfWeek: 0=周日, 1=周一, ...) + unsigned char targetDay = p->Config.Timed.DaysMask; + if (st.wDayOfWeek == targetDay && curMin >= p->Config.Timed.TargetMin) { + if (!IsSameWeek(p->LastRunTime, now)) return true; + } + return false; + } + + // --- 5. 每月定时逻辑 (Mode 4) --- + if (p->Mode == SCH_MODE_MONTHLY) { + SYSTEMTIME st; + GetLocalTime(&st); + unsigned short curMin = (unsigned short)(st.wHour * 60 + st.wMinute); + // DaysMask=0 表示每月第 1 天 + unsigned char targetDay = p->Config.Timed.DaysMask == 0 ? 1 : p->Config.Timed.DaysMask; + if (st.wDay == targetDay && curMin >= p->Config.Timed.TargetMin) { + if (!IsSameMonth(p->LastRunTime, now)) return true; + } + return false; + } + + // --- 6. 每年定时逻辑 (Mode 5) --- + if (p->Mode == SCH_MODE_YEARLY) { + SYSTEMTIME st; + GetLocalTime(&st); + unsigned short curMin = (unsigned short)(st.wHour * 60 + st.wMinute); + // DaysMask=0, Reserved=0 表示 1月1日 + unsigned char targetMonth = p->Config.Timed.DaysMask == 0 ? 1 : p->Config.Timed.DaysMask; + unsigned char targetDay = p->Config.Timed.Reserved == 0 ? 1 : p->Config.Timed.Reserved; + if (st.wMonth == targetMonth && st.wDay == targetDay && curMin >= p->Config.Timed.TargetMin) { + if (!IsSameYear(p->LastRunTime, now)) return true; + } + return false; } return false; @@ -88,13 +136,66 @@ private: static bool IsSameDay(unsigned __int64 ft1, unsigned __int64 ft2) { if (ft1 == 0 || ft2 == 0) return false; SYSTEMTIME st1, st2; - FILETIME f1, f2; - f1.dwLowDateTime = (DWORD)ft1; f1.dwHighDateTime = (DWORD)(ft1 >> 32); - f2.dwLowDateTime = (DWORD)ft2; f2.dwHighDateTime = (DWORD)(ft2 >> 32); - FileTimeToSystemTime(&f1, &st1); - FileTimeToSystemTime(&f2, &st2); + FTToST(ft1, &st1); + FTToST(ft2, &st2); return (st1.wYear == st2.wYear && st1.wMonth == st2.wMonth && st1.wDay == st2.wDay); } + + static bool IsSameWeek(unsigned __int64 ft1, unsigned __int64 ft2) { + if (ft1 == 0 || ft2 == 0) return false; + // 转换为本地时间的天数,再判断是否在同一周 + SYSTEMTIME st1, st2; + FTToST(ft1, &st1); + FTToST(ft2, &st2); + // 计算两个日期各自所在周的周日日期,相同则同一周 + int days1 = DaysSinceEpoch(st1.wYear, st1.wMonth, st1.wDay); + int days2 = DaysSinceEpoch(st2.wYear, st2.wMonth, st2.wDay); + // 回退到本周周日 (wDayOfWeek: 0=周日) + int weekStart1 = days1 - st1.wDayOfWeek; + int weekStart2 = days2 - st2.wDayOfWeek; + return (weekStart1 == weekStart2); + } + + static bool IsSameMonth(unsigned __int64 ft1, unsigned __int64 ft2) { + if (ft1 == 0 || ft2 == 0) return false; + SYSTEMTIME st1, st2; + FTToST(ft1, &st1); + FTToST(ft2, &st2); + return (st1.wYear == st2.wYear && st1.wMonth == st2.wMonth); + } + + static bool IsSameYear(unsigned __int64 ft1, unsigned __int64 ft2) { + if (ft1 == 0 || ft2 == 0) return false; + SYSTEMTIME st1, st2; + FTToST(ft1, &st1); + FTToST(ft2, &st2); + return (st1.wYear == st2.wYear); + } + + static void FTToST(unsigned __int64 ft, SYSTEMTIME* pSt) { + FILETIME ftUtc, ftLocal; + ftUtc.dwLowDateTime = (DWORD)ft; + ftUtc.dwHighDateTime = (DWORD)(ft >> 32); + FileTimeToLocalFileTime(&ftUtc, &ftLocal); + FileTimeToSystemTime(&ftLocal, pSt); + } + + // 简易计算从某基准日开始的天数 (用于周计算) + static int DaysSinceEpoch(int year, int month, int day) { + // 简化算法:相对于 2000-01-01 的天数 + int y = year - 2000; + int leapYears = (y > 0) ? ((y - 1) / 4 - (y - 1) / 100 + (y - 1) / 400 + 1) : 0; + int days = y * 365 + leapYears; + static const int daysBeforeMonth[] = { 0,31,59,90,120,151,181,212,243,273,304,334 }; + days += daysBeforeMonth[month - 1] + day - 1; + // 闰年 2 月后加 1 天 + if (month > 2 && IsLeapYear(year)) days++; + return days; + } + + static bool IsLeapYear(int year) { + return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); + } }; #endif #endif diff --git a/server/2015Remote/2015Remote.rc b/server/2015Remote/2015Remote.rc index b24c5d8b7e81f91912a3206690e95d5935d60f40..6d15c2d9bdceb1c423320677c56b78a0bc557193 100644 GIT binary patch delta 32 ocmbQYlXKoq&W0_FcOn=qr^kmgrcPd`YSdm5$+*2Fl1Ymh0N2tBw*UYD delta 30 mcmbQYlXKoq&W0_FcOs_8g)^p2UZ-l*UJ}W;y(E%Jix~jO@(X