Class PlayitApiService
- Namespace
- McServerLauncher.Services
- Assembly
- McServerLauncher.dll
Playit.gg API client.
- Preferred: a per-user self-managed agent secret key from the partner setup-code flow
(PlayitPartnerService), set app-wide via SetAgentKey(string?) and used as
agent-keyfor both reads AND writes. - Fallback (legacy): the agent's secret_key from playit.toml (reads) and a user-pasted write key (writes, sent as Api-Key/Agent-Key). Auth is resolved by trying the schemes in order, so a caller doesn't need to know which kind of key it holds.
public class PlayitApiService
- Inheritance
-
PlayitApiService
- Inherited Members
Methods
CanManageTunnelsAsync(string, CancellationToken)
Whether this key may change tunnels, found out without changing any: a rename of a tunnel id that does not exist. Null when Playit could not be asked.
public Task<bool?> CanManageTunnelsAsync(string key, CancellationToken ct = default)
Parameters
keystringctCancellationToken
Returns
Remarks
A key that can write is told the tunnel does not exist; a read-only one is refused before Playit looks. Asked once per key and remembered — the answer does not change while the app runs.
DeleteTunnelAsync(string, string, CancellationToken)
Deletes one specific tunnel. For duplicates, where "the tunnel on port 25565" is ambiguous and DeleteTunnelForPortAsync(string, int, bool, CancellationToken) would remove whichever the account lists first.
public Task DeleteTunnelAsync(string key, string tunnelId, CancellationToken ct = default)
Parameters
keystringtunnelIdstringctCancellationToken
Returns
DeleteTunnelForPortAsync(string, int, bool, CancellationToken)
Deletes the tunnel with this local port and this protocol. True if one was deleted.
key is the per-user agent secret key (preferred) or a legacy write key.
public Task<bool> DeleteTunnelForPortAsync(string key, int localPort, bool udp, CancellationToken ct = default)
Parameters
keystringlocalPortintudpboolctCancellationToken
Returns
Remarks
The protocol is half the identity, the same as in GetTunnelAsync(int, bool, bool, CancellationToken) and EnsureMinecraftTunnelAsync(string, string, int, TunnelEdition, CancellationToken): a crossplay server owns two tunnels, Java over TCP and Bedrock over UDP, and matching on the port alone deletes whichever the account happens to list first. Deleting a tunnel is not undoable, so this is the one place where guessing is least acceptable.
EnsureMinecraftTunnelAsync(string, string, int, TunnelEdition, CancellationToken)
Creates a tunnel for the server if one doesn't already exist for that port and edition.
Returns true if it created one, false if it already existed. key is the
per-user agent secret key (preferred) or a legacy write key.
public Task<bool> EnsureMinecraftTunnelAsync(string key, string name, int localPort, PlayitApiService.TunnelEdition edition = TunnelEdition.Java, CancellationToken ct = default)
Parameters
keystringnamestringlocalPortinteditionPlayitApiService.TunnelEditionctCancellationToken
Returns
GetRunDataAsync(string, CancellationToken)
Reads agent_id and tunnels using key (agent secret or write key).
public Task<(string AgentId, List<PlayitApiService.PlayitTunnel> Tunnels)> GetRunDataAsync(string key, CancellationToken ct = default)
Parameters
keystringctCancellationToken
Returns
GetTunnelAsync(int, bool, bool, CancellationToken)
The tunnel on a local port for one protocol, or null.
public Task<PlayitApiService.PlayitTunnel?> GetTunnelAsync(int localPort, bool udp, bool fresh = false, CancellationToken ct = default)
Parameters
localPortintThe port on this machine the tunnel forwards to.
udpboolTrue for the Bedrock half of a crossplay server.
freshboolSkips the shared cache. See GetTunnelsSharedAsync(CancellationToken, bool).
ctCancellationTokenCancels the wait, not the shared fetch itself.
Returns
Remarks
Matched on the protocol as well as the port, because a crossplay server has two tunnels and the port alone would return whichever came first. There used to be a second lookup beside this one that returned an address and nothing else, and it did match on the port alone — so the box labelled Java could show the address players are meant to type into Bedrock, which is an answer that looks entirely plausible and does not connect.
The whole tunnel rather than its address: the callers need to tell a tunnel playit has not published an address for yet, which resolves itself in seconds, from no tunnel at all, which needs the user to press a button. A null address cannot say which of the two it is.
GetUdpTunnelPortsAsync(CancellationToken)
Local ports of every UDP tunnel on the account, or null when the account could not be asked.
public Task<IReadOnlyCollection<int>?> GetUdpTunnelPortsAsync(CancellationToken ct = default)
Parameters
Returns
Remarks
For picking a Bedrock port. The system's UDP table only knows what is bound right now, and the app only knows its own servers, so neither sees a tunnel left behind by a deleted server, one made by hand on playit's site, or one belonging to another machine on the same account. Creating a tunnel on a port one of those already holds does not fail — it silently adopts the other tunnel, and two servers end up advertising one address.
Null rather than an empty set on failure, so "the account has no UDP tunnels" cannot be confused with "I could not reach playit".
ReadSecretKey()
Reads the (read-only) secret_key from playit.toml (cached ~30 s). Null if not found.
public string? ReadSecretKey()
Returns
RenameTunnelAsync(string, string, string, CancellationToken)
Gives a tunnel a new name. The name is the only thing about a tunnel that is ours to change.
public Task RenameTunnelAsync(string key, string tunnelId, string name, CancellationToken ct = default)
Parameters
keystringtunnelIdstringnamestringctCancellationToken
Returns
Remarks
Named by id, not by port: a rename is harmless, but the id is what the account actually keys a tunnel on, and two tunnels can share a port (that is one of the things the tunnels screen exists to point out).
SetAgentKey(string?)
Sets (or clears) the per-user agent secret key used for all Playit API auth. Called once at startup from settings and again after the setup-code flow mints a new key. Drops the shared tunnel cache so the next refresh uses the new credential.
public static void SetAgentKey(string? agentSecretKey)
Parameters
agentSecretKeystring
TryGetTunnelsAsync(bool, CancellationToken)
The account's tunnels from the shared cache, or null when the account could not be asked.
An empty list is an answer: "there are none". fresh skips the cache.
public Task<List<PlayitApiService.PlayitTunnel>?> TryGetTunnelsAsync(bool fresh = false, CancellationToken ct = default)
Parameters
freshboolctCancellationToken