Help us shape the future of Go! Take the 2026 Go Developer Survey

session

package
v0.1.51 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 36 Imported by: 0

Documentation

Overview

Package session runs a play session: modlock-host with the mods, a Deadlock client that joins it, and the control link that reports the mods' progress and reloads them.

Index

Constants

View Source
const BridgePath = "/app/relay/bridge.html"

BridgePath is the relay page's path under its origin. The page reads the screen from the loopback port its query names as port, or from DefaultInterfacePort.

View Source
const DeadlockAppID = "1422450"

DeadlockAppID is Deadlock's Steam application ID.

View Source
const DefaultInterfacePort = 4320

DefaultInterfacePort is the loopback port the relay page reads the mods' interfaces from when its URL names none.

View Source
const DefaultPort = 27067

DefaultPort is the server's default UDP port.

View Source
const DefaultRelay = "https://hyperline.gg"

DefaultRelay hosts the relay page the game reads the mods' interfaces through.

View Source
const FrameGap = 50 * time.Millisecond

FrameGap is the least time between two frames on one stream. The relay page acknowledges each frame before it reads the next, so a mod that changes its interface every server frame would otherwise queue frames in the socket faster than the game draws them; the stream sends the newest screen instead.

View Source
const HostArchive = "modlock-host-windows-x64.zip"

HostArchive is the release asset that holds the Windows host.

View Source
const RelayAgent = "Source2 HTML"

RelayAgent marks the game's own HTML panels in their User-Agent. Requiring it keeps the relay page, opened in an ordinary browser, from reading the player's screen. A Steam beta client names its branch after the marker, as "Source2 HTML [Steam Beta Update]/".

Variables

View Source
var ErrNoGame = errors.New("this computer cannot run Deadlock")

ErrNoGame marks the errors that mean this computer cannot run a Deadlock server: the system is not Windows or Linux, or Steam or the game is missing.

Functions

func Changes added in v0.1.13

func Changes(from, to *ui.Screen) map[string]*ui.Change

Changes returns each mod's change that turns the screen from into to: the nodes set or removed in a tree both hold, a whole new tree as a reset, and a reset with no nodes for a tree that is gone. It returns nothing when the screens match.

func DownloadHost

func DownloadHost(ctx context.Context, version string) (string, error)

DownloadHost returns modlock-host.exe from the release tagged version, downloading and extracting it into the user cache the first time.

func FindHost

func FindHost(ctx context.Context, version string) (string, error)

FindHost returns modlock-host.exe: MODLOCK_HOST when set, else the release matching version, downloaded once into the user cache.

func Loopback added in v0.1.8

func Loopback(request *http.Request) bool

Loopback reports whether request names a loopback host, which keeps DNS rebinding from reaching a server that listens on loopback.

func ReadContent added in v0.1.19

func ReadContent(mods []string) (fstest.MapFS, error)

ReadContent returns the content addons of the mods built at mods: their compiled Panorama content and assets, each already under its addon's name, and the archive of each map a mod ships, as maps/<map>.vpk.

func SameOrigin added in v0.1.8

func SameOrigin(request *http.Request) bool

SameOrigin reports whether request comes from a page this server served, or from no page at all.

func StartInterface added in v0.1.13

func StartInterface(config Interface) (stop func())

StartInterface mounts the renderer and the mods' content in the game and serves the screen to the relay page, and returns the call that stops both. Each part is optional: a game that cannot take the package or another program on the address reports a failure and leaves the session running. Start it before the server and the game, which load the package only when they start.

func WindowsPath

func WindowsPath(path string) string

WindowsPath names an absolute Linux path as Wine's Z: drive sees it.

Types

type Chat added in v0.1.13

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

Chat keeps the newest lines said on a server, numbered in order, for streams that send each line once. A stream that falls more than chatKept lines behind skips the oldest.

func NewChat added in v0.1.13

func NewChat() *Chat

NewChat returns a chat with no lines.

func (*Chat) Add added in v0.1.13

func (c *Chat) Add(line *control.PlayerChat)

Add records a line and wakes every stream.

func (*Chat) Since added in v0.1.13

func (c *Chat) Since(from uint64) ([]*control.PlayerChat, uint64, <-chan struct{})

Since returns the lines kept from number from on, the number of the next line, and a channel that closes when another line is said. A stream that starts at the next line passes the largest number.

type Config

type Config struct {
	// Version is the command line's release, whose host the session runs
	// unless MODLOCK_HOST names one.
	Version string
	// Mods lists the built mods to load.
	Mods []string
	// Port is the server's UDP port.
	Port uint16
	// Map is the map the server starts, or empty for the default.
	Map string
	// Args are passed to each mod's start handlers.
	Args []string
	// Settings is the file that keeps players' settings, or empty to keep
	// them for the session only.
	Settings string
	// Files is the directory that keeps the files mods write, or empty to
	// refuse their writes.
	Files string
	// Launch starts the Deadlock client once the server is ready.
	Launch bool
	// HostOutput receives the host's console output.
	HostOutput io.Writer
	// Interface is the loopback address the player's game reads the mods'
	// interfaces from, or empty to serve none.
	Interface string
	// Relay is the origin of the https page the game reads them through.
	Relay string
	// Renderer is the built renderer, which the session mounts in the game so
	// it draws the interfaces, or nil to leave the game unchanged.
	Renderer *Renderer
	// Events receives each host event, on one goroutine.
	Events func(*control.HostEvent)
}

Config describes a play session.

type Control

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

Control is the controller's end of the control link. It listens on a loopback port and modlock-host dials it with --control; then the host streams its events and takes reloads, each message framed by its length as control.proto describes.

func NewControl

func NewControl() (*Control, error)

NewControl listens on a free loopback port.

func (*Control) Address

func (c *Control) Address() string

Address returns the address to pass to modlock-host --control.

func (*Control) Close

func (c *Control) Close() error

Close stops listening for the host.

func (*Control) Reload

func (c *Control) Reload(ctx context.Context, path string) error

Reload asks the host to replace the running mod named by the build at path. Requests made before the host connects wait for it.

func (*Control) Run

func (c *Control) Run(ctx context.Context, handle func(*control.HostEvent)) error

Run accepts the host's connection and passes each host event to handle until the host disconnects or ctx ends. It returns nil when the host disconnects.

type Host

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

Host is a running modlock-host process.

func StartHost

func StartHost(ctx context.Context, config HostConfig) (*Host, error)

StartHost starts modlock-host as a listen server with the mods. On Windows the host runs directly; on Linux it runs through Steam's Proton in a prefix of its own.

func (*Host) Stop

func (h *Host) Stop()

Stop ends the host and, under Proton, every process in its prefix.

func (*Host) Wait

func (h *Host) Wait() error

Wait waits for the host to exit.

type HostConfig

type HostConfig struct {
	// Executable is modlock-host.exe, beside its libraries.
	Executable string
	// GameDir is the Deadlock installation directory.
	GameDir string
	// Mods lists the built mods to load, as directories with mod.json.
	Mods []string
	// Control is the address of the controller's Control link.
	Control string
	// Port is the server's UDP port.
	Port uint16
	// Map is the map the server starts, or empty for the host's default.
	Map string
	// Args are passed to each mod's start handlers.
	Args []string
	// Settings is the file that keeps players' settings, or empty to keep
	// them for the run only.
	Settings string
	// Files is the directory that keeps the files mods write, or empty to
	// refuse their writes.
	Files string
	// Steam is the Steam installation; on Linux its Proton runs the host.
	Steam *Steam
	// Output receives the host's console output.
	Output io.Writer
}

HostConfig describes one modlock-host run.

type Interface added in v0.1.13

type Interface struct {
	// Address is the loopback address the relay page reads from, or empty to
	// serve no interfaces.
	Address string
	// Relay is the relay page's origin.
	Relay string
	// Renderer is the built renderer; nil leaves the game without it, so the
	// interfaces show only in the browser preview.
	Renderer *Renderer
	// Content is the mods' content addons the game loads, as ReadContent
	// returns them.
	Content fstest.MapFS
	// GameDir is the Deadlock installation the renderer mounts in.
	GameDir string
	// Screen is the player's screen.
	Screen ScreenSource
	// Events receives a failure that turns part of the interfaces off.
	Events func(*control.HostEvent)
}

Interface configures serving a player's mod interfaces and content to their game.

type Mirror added in v0.1.13

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

Mirror keeps a copy of one player's screen that another PC sends as changes, for a Relay on the player's own PC.

func NewMirror added in v0.1.13

func NewMirror() *Mirror

NewMirror returns an empty screen.

func (*Mirror) Apply added in v0.1.13

func (m *Mirror) Apply(changes map[string]*ui.Change, reset bool)

Apply applies each mod's change to the screen, first clearing it on reset, when changes hold the whole screen.

func (*Mirror) Screen added in v0.1.13

func (m *Mirror) Screen() (*ui.Screen, <-chan struct{})

Screen returns the screen and a channel that closes when it changes.

type Proton

type Proton struct {
	// Dir is the Proton installation directory.
	Dir string
	// Prefix is the compatibility data directory of the host's prefix.
	Prefix string
	// Runtime is the run script of the Steam Linux Runtime the Proton
	// requires, or empty for a Proton that runs on the host.
	Runtime string
	// contains filtered or unexported fields
}

Proton is one Steam Proton installation with the prefix modlock-host runs in. The prefix is the command line's own: the host must not share the game's prefix, because Steam runs the client under its own Proton, whose wineserver would wait for this one to exit.

func FindProton

func FindProton(steam *Steam) (*Proton, error)

FindProton returns MODLOCK_PROTON when set, else the newest numbered Proton in the Steam libraries, else Proton Experimental.

func (*Proton) Command

func (p *Proton) Command(ctx context.Context, path string, arguments ...string) *exec.Cmd

Command returns a command that runs the Windows program at path in the prefix. runinprefix starts it directly; run would wrap it in Proton's steam.exe, which leaves its console output silent.

func (*Proton) Kill

func (p *Proton) Kill()

Kill ends every process in the prefix.

func (*Proton) Prepare

func (p *Proton) Prepare(ctx context.Context) error

Prepare creates the prefix when it does not exist yet. Proton sets a prefix up for every verb except runinprefix; getcompatpath does so and exits.

type Relay added in v0.1.13

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

Relay serves one player's screen to their game on loopback. Deadlock loads only https pages into its HTML panels, so the game's renderer reads through a relay page from another origin: the page streams the screen from GET /panorama/stream, one binary ui.Screen per line, packed by panorama.AppendPackedLine. The game presses buttons with a console command to the server, not through this page.

func NewRelay added in v0.1.13

func NewRelay(origin string, screen ScreenSource) *Relay

NewRelay returns a Relay serving screen to the relay page at origin.

func (*Relay) ServeHTTP added in v0.1.13

func (r *Relay) ServeHTTP(w http.ResponseWriter, request *http.Request)

ServeHTTP serves the screen stream to the relay page.

type Renderer added in v0.1.14

type Renderer struct {
	// Script draws each mod's tree; it installs as scripts/modlock/ui.js.
	Script []byte
	// Layout is the library a mod's layout includes to read its data and
	// routes; it installs as scripts/modlock/layout.js.
	Layout []byte
}

Renderer is the built scripts that draw the mods' interfaces in the game.

type ScreenSource added in v0.1.13

type ScreenSource func() (*ui.Screen, <-chan struct{})

ScreenSource returns a player's screen and a channel that closes when it may have changed.

type Screens

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

Screens keeps what the mods show each player on a server, following the host's events. It serves the local player's screen to a Relay, and any player's screen to a host that streams it to a guest.

func NewScreens

func NewScreens(account uint64) *Screens

NewScreens returns screens whose local player has the Steam ID account.

func (*Screens) Handle

func (s *Screens) Handle(event *control.HostEvent)

Handle follows one host event: a join that binds a person's slot, a leave that frees it, or a mod's change to a player's interface.

func (*Screens) Player added in v0.1.13

func (s *Screens) Player(account uint64) (*ui.Screen, <-chan struct{})

Player returns the screen of the person with the Steam ID account, empty while they are not in the server, and a channel that closes when it may have changed.

func (*Screens) Screen

func (s *Screens) Screen() (*ui.Screen, <-chan struct{})

Screen returns the local player's screen and a channel that closes when it may have changed.

func (*Screens) Snapshot added in v0.1.13

func (s *Screens) Snapshot() []*control.HostEvent

Snapshot returns the events that bring new Screens to this one's state: each person's join, then each tree as a reset change.

type Session

type Session struct {
	// Executable is the modlock-host.exe the session runs: MODLOCK_HOST, or
	// the downloaded release.
	Executable string
	// contains filtered or unexported fields
}

Session is a running play session: the host with the mods and, once the server is ready, the Deadlock client joined to it.

func Start

func Start(ctx context.Context, config Config) (*Session, error)

Start starts the host with the mods and serves its control link. It returns an error marked ErrNoGame when this computer cannot run the game.

func (*Session) Reload

func (s *Session) Reload(ctx context.Context, path string) error

Reload asks the host to replace the running mod built at path.

func (*Session) Stop

func (s *Session) Stop()

Stop unmounts the mods from the player's game, then ends the host. The unmount comes first because the game, once its server stops, holds gameinfo.gi while it reloads its search paths; the running server and game keep the package they loaded.

func (*Session) Wait

func (s *Session) Wait() error

Wait waits for the host to exit and its last events to arrive.

type Steam

type Steam struct {
	// Root is the Steam installation directory.
	Root string
	// Libraries lists every library directory, Root first.
	Libraries []string
}

Steam is the local Steam installation: the client that launches games and the libraries they are installed in.

func FindSteam

func FindSteam() (*Steam, error)

FindSteam locates the Steam installation and reads its library folders.

func (*Steam) Account

func (s *Steam) Account() uint64

Account returns the Steam ID of the account signed in to Steam last, or zero when Steam names none.

func (*Steam) App

func (s *Steam) App(name string) (string, bool)

App returns the installation directory of the app installed as name, such as "Deadlock", in the first library that has it.

func (*Steam) Deadlock

func (s *Steam) Deadlock() (string, error)

Deadlock returns the Deadlock installation directory: DEADLOCK_DIR, or the one in the Steam libraries.

func (*Steam) LaunchDeadlock

func (s *Steam) LaunchDeadlock(ctx context.Context, options ...string) error

LaunchDeadlock starts Deadlock through the running Steam client with the given launch options, such as +connect. It returns once Steam took the request; the game keeps running on its own.

Jump to

Keyboard shortcuts

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