playtime

package
v2.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 22, 2026 License: GPL-3.0 Imports: 14 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DefaultSessionResetTimeout is the default idle time before a session resets.
	// After this period of inactivity, the next game launch starts a fresh session.
	DefaultSessionResetTimeout = 20 * time.Minute

	// MinimumViableSession is the minimum time a session should run before being stoppable.
	// If remaining time < this value, the launch is blocked entirely rather than starting
	// a game that will be immediately killed.
	MinimumViableSession = 1 * time.Minute
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Broker

type Broker interface {
	Subscribe(bufferSize int) (<-chan models.Notification, int)
	Unsubscribe(id int)
}

Broker is the interface for subscribing to notifications.

type DailyLimitRule

type DailyLimitRule struct {
	Limit time.Duration
}

DailyLimitRule enforces a maximum total play time per day.

func (*DailyLimitRule) Evaluate

func (r *DailyLimitRule) Evaluate(ctx RuleContext) (allowed bool, remaining time.Duration, reason string)

Evaluate checks if today's total usage has exceeded the daily limit.

type LimitsManager

type LimitsManager struct {
	// contains filtered or unexported fields
}

LimitsManager enforces time limits and warnings for gameplay sessions.

func NewLimitsManager

func NewLimitsManager(
	db *database.Database,
	platform platforms.Platform,
	cfg *config.Instance,
	clock clockwork.Clock,
) *LimitsManager

NewLimitsManager creates a new LimitsManager instance.

func (*LimitsManager) CheckBeforeLaunch

func (tm *LimitsManager) CheckBeforeLaunch() error

CheckBeforeLaunch checks if launching new media would exceed daily or session limits. Returns an error if: - Daily or session limit is already exceeded - Remaining time < MinimumViableSession (prevents launching games that will be immediately killed) This implements the preventive check strategy - block launches before they start rather than trying to stop games immediately after they launch.

func (*LimitsManager) GetStatus

func (tm *LimitsManager) GetStatus() *StatusInfo

GetStatus returns the current playtime session and limit status. Always returns a StatusInfo struct with current state information.

func (*LimitsManager) IsEnabled

func (tm *LimitsManager) IsEnabled() bool

IsEnabled returns whether limits are currently enforced.

func (*LimitsManager) OnMediaStarted

func (tm *LimitsManager) OnMediaStarted()

OnMediaStarted handles media.started events and begins time tracking.

func (*LimitsManager) OnMediaStopped

func (tm *LimitsManager) OnMediaStopped()

OnMediaStopped handles media.stopped events and stops time tracking.

func (*LimitsManager) SetEnabled

func (tm *LimitsManager) SetEnabled(enabled bool)

SetEnabled enables or disables limit enforcement at runtime. When disabling, resets the session state completely (clears cooldown and cumulative time). When re-enabling, session starts fresh but daily usage from history is still enforced.

func (*LimitsManager) Start

func (tm *LimitsManager) Start(broker Broker, notificationsSend chan<- models.Notification)

Start begins monitoring for time limit enforcement. It subscribes to the broker to listen for media.started and media.stopped events.

func (*LimitsManager) Stop

func (tm *LimitsManager) Stop()

Stop shuts down the LimitsManager.

type Rule

type Rule interface {
	// Evaluate checks if the current context violates this rule's time limit.
	// Returns:
	//   - allowed: true if play can continue, false if limit reached
	//   - remaining: time left before limit (0 if already exceeded)
	//   - reason: reason for violation (e.g., "daily", "session")
	Evaluate(ctx RuleContext) (bool, time.Duration, string)
}

Rule evaluates time limit policies and determines if continued play is allowed.

type RuleContext

type RuleContext struct {
	// CurrentTime is the current time for evaluation
	CurrentTime time.Time

	// SessionDuration is how long the current session has been running
	SessionDuration time.Duration

	// DailyUsageToday is the total time used today (including current session)
	DailyUsageToday time.Duration

	// ClockReliable indicates whether the system clock is trustworthy.
	// False when clock appears to be unset (e.g., year < 2024) or has jumped suspiciously.
	// Daily limits are only enforced when ClockReliable is true.
	ClockReliable bool
}

RuleContext provides time and usage information for rule evaluation.

type SessionLimitRule

type SessionLimitRule struct {
	Limit time.Duration
}

SessionLimitRule enforces a maximum time per gaming session.

func (*SessionLimitRule) Evaluate

func (r *SessionLimitRule) Evaluate(ctx RuleContext) (allowed bool, remaining time.Duration, reason string)

Evaluate checks if the session has exceeded the session limit.

type SessionState

type SessionState int

SessionState represents the current state of a playtime session.

const (
	// StateReset indicates no active session, cumulative time is zero.
	StateReset SessionState = iota
	// StateActive indicates a game is currently running and time is being tracked.
	StateActive
	// StateCooldown indicates no game is running, but session may continue if another
	// game launches within the session reset timeout period.
	StateCooldown
)

func (SessionState) String

func (s SessionState) String() string

String returns the string representation of the session state.

type StatusInfo

type StatusInfo struct {
	SessionStarted        time.Time
	DailyUsageToday       *time.Duration
	DailyRemaining        *time.Duration
	State                 string
	SessionDuration       time.Duration
	SessionCumulativeTime time.Duration
	SessionRemaining      time.Duration
	CooldownRemaining     time.Duration
	SessionActive         bool
}

StatusInfo contains current playtime session and limit status.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL