Files
bd2/go/internal/server/domain/battle/hunting/ap_refresh.go
T

68 lines
1.6 KiB
Go

package hunting
import (
"bd2server/internal/server/design/gamedata"
"bd2server/internal/server/domain/command"
"bd2server/internal/server/platform/versionconfig"
"bd2server/internal/server/storage/stateio"
"encoding/json"
"fmt"
"time"
)
type apClock struct {
Version string `json:"version"`
Next int64 `json:"next"`
}
func (s *Service) AttachAPRefresh(design gamedata.HuntingAPDesign) error {
if design.Max == 0 || design.Max > 2147483647 || design.ResetSeconds < 0 || design.ResetSeconds >= 86400 {
return fmt.Errorf("hunting: invalid AP refresh design")
}
s.apDesign = &design
s.now = time.Now
return nil
}
// The client clock is UTC+9. DailyResetTime is expressed in that clock.
func (s *Service) refreshAP(ctx command.Context) error {
if s.apDesign == nil {
return nil
}
now := s.now().UnixMilli()
offset := (s.apDesign.ResetSeconds - 9*3600) * 1000
day := (now - offset) / 86400000
nextTime := (day+1)*86400000 + offset
b, e := s.storage.Load(ctx.State, "huntingapclock")
if e != nil {
return e
}
clock := apClock{versionconfig.State(), nextTime}
if b != nil {
if e = stateio.RequireExactJSONObject(b, "version", "next"); e != nil {
return e
}
if e = json.Unmarshal(b, &clock); e != nil {
return e
}
if clock.Version != versionconfig.State() || clock.Next <= 0 {
return fmt.Errorf("hunting: invalid AP clock")
}
if now < clock.Next {
return nil
}
next := s.clone()
next.Free = s.apDesign.Max
if e = s.persist(ctx, next); e != nil {
return e
}
clock.Next = nextTime
}
raw, e := json.Marshal(clock)
if e != nil {
return e
}
return s.storage.Save(ctx.State, "huntingapclock", raw)
}