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 b24c5d8..6d15c2d 100644 Binary files a/server/2015Remote/2015Remote.rc and b/server/2015Remote/2015Remote.rc differ diff --git a/server/2015Remote/PluginSettingsDlg.cpp b/server/2015Remote/PluginSettingsDlg.cpp index b01ed91..24729a7 100644 --- a/server/2015Remote/PluginSettingsDlg.cpp +++ b/server/2015Remote/PluginSettingsDlg.cpp @@ -69,8 +69,11 @@ BOOL CPluginSettingsDlg::OnInitDialog() // 初始化调度模式下拉框 m_comboMode.InsertString(SCH_MODE_NONE, _TR("不自动执行")); m_comboMode.InsertString(SCH_MODE_STARTUP, _TR("启动执行")); - m_comboMode.InsertString(SCH_MODE_DAILY, _TR("每日定时[未实现]")); - m_comboMode.InsertString(SCH_MODE_WEEKLY, _TR("每周定时[未实现]")); + m_comboMode.InsertString(SCH_MODE_DAILY, _TR("每日定时")); + m_comboMode.InsertString(SCH_MODE_WEEKLY, _TR("每周定时")); + m_comboMode.InsertString(SCH_MODE_MONTHLY, _TR("每月定时")); + m_comboMode.InsertString(SCH_MODE_YEARLY, _TR("每年定时")); + m_comboMode.InsertString(SCH_MODE_OFF, _TR("关闭执行")); m_comboMode.SetCurSel(SCH_MODE_NONE); // 加载配置 diff --git a/server/2015Remote/lang/en_US.ini b/server/2015Remote/lang/en_US.ini index cc2bd7d..159e2b6 100644 --- a/server/2015Remote/lang/en_US.ini +++ b/server/2015Remote/lang/en_US.ini @@ -1784,8 +1784,11 @@ IOCP ׼FRPC[]=Standard FRPC [Unavailable] Զִ=No Auto Execute ִ=Execute on Startup -ÿնʱ[δʵ]=Daily Schedule [Not Implemented] -ÿܶʱ[δʵ]=Weekly Schedule [Not Implemented] +ÿնʱ=Daily Schedule +ÿܶʱ=Weekly Schedule +ÿ¶ʱ=Monthly Schedule +ÿ궨ʱ=Yearly Schedule +رִ=Turn OFF =Name С=Size =Run Type diff --git a/server/2015Remote/lang/zh_TW.ini b/server/2015Remote/lang/zh_TW.ini index 565d0ec..8973c0e 100644 --- a/server/2015Remote/lang/zh_TW.ini +++ b/server/2015Remote/lang/zh_TW.ini @@ -1776,8 +1776,11 @@ IOCP ׼FRPC[]=˜FRPC[] Զִ=Ԅӈ ִ=ӈ -ÿնʱ[δʵ]=ÿնr[δF] -ÿܶʱ[δʵ]=ÿLr[δF] +ÿնʱ=ÿնr +ÿܶʱ=ÿLr +ÿ¶ʱ=ÿ¶ʱ +ÿ궨ʱ=ÿ궨ʱ +رִ=رִ =Q С=С =