package sdkserver import ( "fmt" "gac-hkrpg-go/internal/common" "net/http" "strconv" "strings" "time" ) func apiFakeTimeCommand(w http.ResponseWriter, cmd string) { parts := strings.Fields(cmd) usage := "Usage: /faketime [status | off | window | | ]. Window mode wraps the game clock at the end; off restores real time. Reopen the guide after the next heartbeat; relogin if it caches schedules." var now time.Time var err error arg := strings.TrimSpace(strings.TrimPrefix(cmd, parts[0])) switch strings.ToLower(arg) { case "", "status": now, err = common.GameTime() case "off", "reset", "real": now, err = common.SetGameTime(nil) default: if len(parts) > 1 && strings.EqualFold(parts[1], "window") { if len(parts) != 4 { err = fmt.Errorf("window requires begin and end Unix seconds") } else { begin, e1 := strconv.ParseInt(parts[2], 10, 64) end, e2 := strconv.ParseInt(parts[3], 10, 64) if e1 != nil || e2 != nil || begin < 0 || end > 253402300799 || end <= begin { err = fmt.Errorf("invalid window Unix seconds") } else { now, err = common.SetGameTimeWindow(time.Unix(begin, 0), time.Unix(end, 0)) } } break } var target time.Time if seconds, e := strconv.ParseInt(arg, 10, 64); e == nil { if seconds < 0 || seconds > 253402300799 { err = fmt.Errorf("Unix seconds outside supported calendar range") } else { target = time.Unix(seconds, 0) } } else { target, err = time.Parse(time.RFC3339, arg) } if err == nil { now, err = common.SetGameTime(&target) } } if err != nil { writeJSON(w, map[string]any{"success": false, "output": err.Error() + "\n" + usage}) return } state, err := common.ReadGameClock() if err != nil { writeJSON(w, map[string]any{"success": false, "output": err.Error()}) return } writeJSON(w, map[string]any{"success": true, "command": cmd, "game_time": now.UTC().Format(time.RFC3339), "unix_seconds": now.Unix(), "offset_ms": state.OffsetMS, "window_begin_ms": state.WindowBeginMS, "window_end_ms": state.WindowEndMS, "output": fmt.Sprintf("Game time: %s (offset %d ms, window %d..%d ms). %s", now.UTC().Format(time.RFC3339), state.OffsetMS, state.WindowBeginMS, state.WindowEndMS, usage)}) }