ZeroBot-Plugin/plugin_manager/timer/sleep.go
2021-10-27 23:50:46 +08:00

165 lines
3.6 KiB
Go

package timer
import (
"time"
"github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
)
func firstWeek(date *time.Time, week time.Weekday) (d time.Time) {
d = date.AddDate(0, 0, 1-date.Day())
for d.Weekday() != week {
d = d.AddDate(0, 0, 1)
}
return
}
func (ts *Timer) nextWakeTime() (date time.Time) {
date = time.Now()
m := ts.Month
d := ts.Day
h := ts.Hour
mn := ts.Minute
w := ts.Week
unit := time.Duration(int(ts.Minute)-date.Minute()) * time.Minute
logrus.Debugln("[timer] unit init:", unit)
if mn >= 0 {
switch {
case h < 0:
if unit <= time.Second {
unit += time.Hour
}
case d < 0 || w < 0:
if unit <= time.Second {
unit += time.Hour * 24
}
case d == 0 && w >= 0:
delta := time.Hour * 24 * time.Duration(int(w)-int(date.Weekday()))
if delta < 0 {
delta += time.Hour * 24 * 7
}
unit += delta
case m < 0:
unit = -1
}
} else {
unit = time.Minute
}
logrus.Debugln("[timer] unit:", unit)
stable := 0
if mn < 0 {
mn = int32(date.Minute())
}
if h < 0 {
h = int32(date.Hour())
} else {
stable |= 0x8
}
if d < 0 {
d = int32(date.Day())
} else if d > 0 {
stable |= 0x4
} else {
d = int32(date.Day())
if w >= 0 {
stable |= 0x2
}
}
if m < 0 {
m = int32(date.Month())
} else {
stable |= 0x1
}
switch stable {
case 0b0101:
if ts.Day != int32(time.Now().Day()) || ts.Month != int32(time.Now().Month()) {
h = 0
}
case 0b1001:
if ts.Month != int32(time.Now().Month()) {
d = 0
}
case 0b0001:
if ts.Month != int32(time.Now().Month()) {
d = 0
h = 0
}
}
logrus.Debugln("[timer] stable:", stable)
logrus.Debugln("[timer] m:", m, "d:", d, "h:", h, "mn:", mn, "w:", w)
date = time.Date(date.Year(), time.Month(m), int(d), int(h), int(mn), date.Second(), date.Nanosecond(), date.Location())
logrus.Debugln("[timer] date original:", date)
if unit > 0 {
date = date.Add(unit)
}
logrus.Debugln("[timer] date after add:", date)
if time.Until(date) <= 0 {
if ts.Month < 0 {
if ts.Day > 0 || (ts.Day == 0 && ts.Week >= 0) {
date = date.AddDate(0, 1, 0)
} else if ts.Day < 0 || ts.Week < 0 {
if ts.Hour > 0 {
date = date.AddDate(0, 0, 1)
} else if ts.Minute > 0 {
date = date.Add(time.Hour)
}
}
} else {
date = date.AddDate(1, 0, 0)
}
}
logrus.Debugln("[timer] date after fix:", date)
if stable&0x8 != 0 && date.Hour() != int(h) {
switch {
case stable&0x4 == 0:
date = date.AddDate(0, 0, 1).Add(-time.Hour)
case stable&0x2 == 0:
date = date.AddDate(0, 0, 7).Add(-time.Hour)
case stable*0x1 == 0:
date = date.AddDate(0, 1, 0).Add(-time.Hour)
default:
date = date.AddDate(1, 0, 0).Add(-time.Hour)
}
}
logrus.Debugln("[timer] date after s8:", date)
if stable&0x4 != 0 && date.Day() != int(d) {
switch {
case stable*0x1 == 0:
date = date.AddDate(0, 1, -1)
default:
date = date.AddDate(1, 0, -1)
}
}
logrus.Debugln("[timer] date after s4:", date)
if stable&0x2 != 0 && int32(date.Weekday()) != w {
switch {
case stable*0x1 == 0:
date = date.AddDate(0, 1, 0)
default:
date = date.AddDate(1, 0, 0)
}
date = firstWeek(&date, time.Weekday(w))
}
logrus.Debugln("[timer] date after s2:", date)
if time.Until(date) <= 0 {
date = time.Now().Add(time.Minute)
}
return date
}
func (ts *Timer) judgeHM(grp int64) {
if ts.Hour < 0 || ts.Hour == int32(time.Now().Hour()) {
if ts.Minute < 0 || ts.Minute == int32(time.Now().Minute()) {
if ts.Selfid != 0 {
ts.sendmsg(grp, zero.GetBot(ts.Selfid))
} else {
zero.RangeBot(func(id int64, ctx *zero.Ctx) (_ bool) {
ts.sendmsg(grp, ctx)
return
})
}
}
}
}