Class SessionControl
Actions affect an attached game, never launch or terminate its process. Mod readiness is separate.
public sealed class SessionControl
- Inheritance
-
objectSessionControl
Constructors
SessionControl(GameActor)
Actions affect an attached game, never launch or terminate its process. Mod readiness is separate.
public SessionControl(GameActor actor)
Parameters
actorGameActor
Methods
EnableDevcommands()
Turns the client's devcommands on at its menu: Ensure(GameActor, TestActorRole, bool) as ClientMenu,
which reads ValheimCLI's cli_access, toggles once only if needed and verifies the result. ValheimCLI refuses
mutating extension commands, the session join among them, until devcommands is on, and a fresh game starts with it
off. Cheats are acknowledged after joining (ClientRounds does it for an owned client). On a client joined
to a server, Valheim 1.0 also needs ValheimCLI's AllowOnServerClients = true for mutating test commands.
public void EnableDevcommands()
Join(string, string, string?, bool)
Joins a server. Turns devcommands on first unless enableDevcommands is false, because the
join is refused without it; pass false when an operator manages that flag and the join should fail instead.
Credentials stay in the game host's environment, never in command text or transcripts. The join invalidates the
actor's pins; verify the destination world, then WaitForWorld(string, TimeSpan, CancellationToken, bool), which protects the joined player.
public void Join(string address, string character, string? passwordEnvironmentVariable = null, bool enableDevcommands = true)
Parameters
addressstringcharacterstringpasswordEnvironmentVariablestringenableDevcommandsbool
JoinCrossplay(string, string, string, string, TimeSpan, bool, CancellationToken, string?)
Joins a crossplay (PlayFab) server's lobby with the given existing character: cli_select_character, then
cli_connect_playfab_user <remotePlayerId> exactly once (devcommands first, as Join(string, string, string?, bool)), each
reply read back. remotePlayerId comes from the server (WaitForLobby(GameActor, string, TimeSpan, CancellationToken)).
No password is passed: the command would carry it as text, so a crossplay fixture server runs private without one.
The command only starts the join, so this then re-pins the client with menuExpectations (plugins
only) and waits, reading the session state, until the client is connected in worldUid with its
player ready, as the session join does. Fails when the game reports a load error or another world, or returns to
the menu with an error status after the join started. Then verify the world pins and WaitForWorld(string, TimeSpan, CancellationToken, bool).
A strict client refuses its menu pins as soon as the join loads the world between two reads ("loaded but not
listed"); with worldExpectations (the plugins and the server's world, as
WorldExpectations(string) gives them) the client is then re-pinned to that world, once, and the wait
goes on; another world fails that pin check. The same holds when the join loads the world before the menu pins are
first checked. Found in the native crossplay run: the join completes within a read.
public SessionState JoinCrossplay(string remotePlayerId, string character, string worldUid, string menuExpectations, TimeSpan timeout, bool enableDevcommands = true, CancellationToken cancellation = default, string? worldExpectations = null)
Parameters
remotePlayerIdstringcharacterstringworldUidstringmenuExpectationsstringtimeoutTimeSpanenableDevcommandsboolcancellationCancellationTokenworldExpectationsstring
Returns
JoinExpectingRefusal(string, string, GameConnectionStatus, string, TimeSpan, string?, bool, CancellationToken)
Joins a server that must refuse this client with expected, for example
ErrorVersion (3) from a mod's version check. Issues the session join exactly
once (devcommands first, as Join(string, string, string?, bool)), requires ValheimCLI to report that the game refused it
(join_failed: the new connection ended in an error status), re-pins the client with
menuExpectations (plugins only, such as MenuExpectations), waits within
timeout until the client is back at its main menu, then reads cli_connection_status, which
the game keeps until the next join, and requires the expected status. Fails when the join succeeds (the client is
then in the server's world: leave it before another join), when it ends any other way (another ValheimCLI code, a
timeout or a lost reply: nothing is retried) and when the refusal has another status. On success the client is at
its menu, pinned, and a normal Join(string, string, string?, bool) may follow.
public JoinRefusal JoinExpectingRefusal(string address, string character, GameConnectionStatus expected, string menuExpectations, TimeSpan timeout, string? passwordEnvironmentVariable = null, bool enableDevcommands = true, CancellationToken cancellation = default)
Parameters
addressstringcharacterstringexpectedGameConnectionStatusmenuExpectationsstringtimeoutTimeSpanpasswordEnvironmentVariablestringenableDevcommandsboolcancellationCancellationToken
Returns
JoinHost(ClientRunPlan, GameActor, string, bool, CancellationToken)
Joins a client plan's disposable character, a host's peer (JoinsHost), to the world a hosting
client hosts (HostingClientActor), whose in-game handle is host and world
worldUid. A listen server on the game's Steam backend is reached through Steam rather than at an address,
so this reads the host's multiplayer identity (cli_multiplayer_identity, read-only: it must be an open server), then
joins the host's Steam user once (cli_connect_steam_user <steamId>, after cli_select_character, with
devcommands first), and waits as a crossplay join does until the client is connected in the host's world with its player.
Then, as JoinWorld(ClientRunPlan, string, CrossplayLobby?, bool, CancellationToken): the world pins, the world awaited within the plan's join time, test access on an owned
client's character, and protection unless protectPlayer is false. A crossplay (PlayFab) host is refused:
its peer join is not supported yet.
public SessionState JoinHost(ClientRunPlan plan, GameActor host, string worldUid, bool protectPlayer = true, CancellationToken cancellation = default)
Parameters
planClientRunPlanhostGameActorworldUidstringprotectPlayerboolcancellationCancellationToken
Returns
JoinWorld(ClientRunPlan, string, CrossplayLobby?, bool, CancellationToken)
Joins a client plan's disposable character to the owned dedicated server whose world is worldUid:
the one join that ClientRounds, LogoutCycle and a scenario that joins several clients
itself all use. Devcommands first and the join exactly once, by the plan's address (Join(string, string, string?, bool)) or, for a
Crossplay plan, into the server's lobby (JoinCrossplay(string, string, string, string, TimeSpan, bool, CancellationToken, string?));
then the client's world pins (WorldExpectations(string)) are verified and the world awaited within
the plan's join seconds. An owned client then gets test access on its disposable character
(Ensure(GameActor, TestActorRole, bool) as ClientInWorld, requiring ValheimCLI's
AllowOnServerClients when the player is protected, since protection is a mutating command there); an operator's
attached client keeps devcommands only. Last, unless protectPlayer is false, the player is protected
(Protect(GameActor); see WaitForWorld(string, TimeSpan, CancellationToken, bool) for what protection changes).
public SessionState JoinWorld(ClientRunPlan plan, string worldUid, CrossplayLobby? lobby = null, bool protectPlayer = true, CancellationToken cancellation = default)
Parameters
planClientRunPlanworldUidstringlobbyCrossplayLobbyprotectPlayerboolcancellationCancellationToken
Returns
Leave()
public void Leave()
Read()
public SessionState Read()
Returns
Save(string, TimeSpan)
public uint Save(string worldUid, TimeSpan timeout)
Parameters
worldUidstringtimeoutTimeSpan
Returns
- uint
WaitForWorld(string, TimeSpan, CancellationToken, bool)
Waits until worldUid is loaded and ready, polling the read-only session state. Then, unless
protectPlayer is false, protects the game's local player (Protect(GameActor):
god, ghost and debug modes, read back), so a fall, the water or a mob between the join and the check cannot cost
the character. A protection the game does not confirm fails the wait; it is issued once and never toggled. Debug
fly stays off. A dedicated server has no local player and is left alone. A game hosting its own world reports
ready before its player spawns, so the wait goes on, within the same timeout, until that player exists.
Protection changes gameplay, as the game does in 1.0.16: monsters neither notice nor target a player in ghost mode, an egg hatches only near a player who is not, and a creature hit by a player in god or ghost mode is marked cheated, which marks the items it drops. Pass false for combat, aggro, taming, hatching or loot checks, when a check needs a vulnerable player, or when an operator manages these modes; call Protect(GameActor) yourself for the steps that should be protected.
public SessionState WaitForWorld(string worldUid, TimeSpan timeout, CancellationToken cancellation = default, bool protectPlayer = true)
Parameters
worldUidstringtimeoutTimeSpancancellationCancellationTokenprotectPlayerbool