Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
322 changes: 321 additions & 1 deletion public/specs/service-player/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,30 @@
"format" : "date-time",
"examples" : [ "2022-03-10T16:15:50Z" ]
},
"KnownPlayerDirectoryResponse" : {
"type" : "object",
"required" : [ "players" ],
"properties" : {
"players" : {
"type" : "array",
"items" : {
"$ref" : "#/components/schemas/KnownPlayerName"
}
}
}
},
"KnownPlayerName" : {
"type" : "object",
"required" : [ "playerId", "playerName" ],
"properties" : {
"playerId" : {
"$ref" : "#/components/schemas/UUID"
},
"playerName" : {
"type" : "string"
}
}
},
"LoginRequest" : {
"description" : "A proxy claiming the network-wide session for a player.",
"type" : "object",
Expand Down Expand Up @@ -195,6 +219,30 @@
}
}
},
"OnlineCount" : {
"description" : "How many of the given players are online.",
"type" : "object",
"required" : [ "online" ],
"properties" : {
"online" : {
"type" : "integer",
"format" : "int32"
}
}
},
"OnlineCountRequest" : {
"description" : "The players to check, e.g. a friend list.",
"type" : "object",
"properties" : {
"playerIds" : {
"type" : [ "array", "null" ],
"items" : {
"type" : "string"
},
"description" : "Player UUIDs. Malformed ones do not count, and ids beyond the server's cap of 100 are ignored."
}
}
},
"PlayerLocale" : {
"description" : "A player's chosen interface language.",
"type" : "object",
Expand Down Expand Up @@ -252,6 +300,22 @@
}
}
},
"Playtime" : {
"description" : "How long a player has been online, across sessions.",
"type" : "object",
"properties" : {
"totalMillis" : {
"type" : "integer",
"format" : "int64",
"description" : "Time online on any server, the lobby included, in milliseconds."
},
"playMillis" : {
"type" : "integer",
"format" : "int64",
"description" : "The part of `totalMillis` spent on game servers: everything except lobbies and the time between servers."
}
}
},
"Problem" : {
"description" : "A failed request, in RFC 9457 problem-details form.",
"type" : "object",
Expand Down Expand Up @@ -279,6 +343,16 @@
}
}
},
"ProfileVisibilityResponse" : {
"type" : "object",
"properties" : {
"visibility" : {
"type" : [ "string", "null" ],
"description" : "public, friends or private. Null when never chosen (read as public).",
"enum" : [ "public", "friends", "private" ]
}
}
},
"ProxyCounts" : {
"description" : "Players per proxy and region, network-wide.",
"type" : "object",
Expand Down Expand Up @@ -358,6 +432,16 @@
}
}
},
"SetProfileVisibilityRequest" : {
"type" : "object",
"properties" : {
"visibility" : {
"type" : [ "string", "null" ],
"description" : "public, friends or private; null clears it.",
"enum" : [ "public", "friends", "private" ]
}
}
},
"SetRegionRequest" : {
"description" : "Store or clear a preferred region.",
"type" : "object",
Expand All @@ -369,6 +453,11 @@
}
}
},
"UUID" : {
"type" : "string",
"format" : "uuid",
"pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}"
},
"UpdateServerRequest" : {
"description" : "The backend server a player has moved to.",
"type" : "object",
Expand All @@ -393,7 +482,7 @@
"info" : {
"description" : "Network-wide player presence: who is online, on which proxy and backend server, under what name, and in which language they want to be spoken to.\n\nA proxy only knows the players connected to itself, so anything that spans proxies — a private message, a party invite, an accurate player count — has to ask here. The session table is the network's single answer to \"is this player online\"; a login is a claim on it, and a second one is refused.\n\nSessions are presence and are deleted on logout. Names outlive them: a separate, never-deleted index is written at every login, which is what lets a leaderboard or a match history show a name rather than a raw UUID.",
"title" : "Player API",
"version" : "v2.3.0"
"version" : "v2.6.1"
},
"tags" : [ {
"name" : "Counts",
Expand All @@ -404,6 +493,12 @@
}, {
"name" : "Names",
"description" : "The durable id-to-name index and tab-complete."
}, {
"name" : "Playtime",
"description" : "Accumulated online and game time per player."
}, {
"name" : "Profile visibility",
"description" : "Per-player web profile visibility."
}, {
"name" : "Region",
"description" : "Per-player preferred region."
Expand All @@ -412,6 +507,54 @@
"description" : "Live presence: login, logout, heartbeats, and session lookup."
} ],
"paths" : {
"/v1/players/counts/online" : {
"post" : {
"summary" : "How many of the given players are online",
"description" : "The lobby's \"friends online\": the caller already holds the id list (a friend list from service-social) and only needs the number. A POST because a full list of UUIDs as query parameters outgrows the request line.",
"tags" : [ "Counts" ],
"requestBody" : {
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/OnlineCountRequest"
}
}
},
"required" : true
},
"responses" : {
"200" : {
"description" : "The number of those players holding a session.",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/OnlineCount"
}
}
}
},
"401" : {
"description" : "Authentication is missing or invalid."
},
"503" : {
"description" : "The session store could not be read.",
"content" : {
"application/problem+json" : {
"schema" : {
"$ref" : "#/components/schemas/Problem"
}
}
}
},
"400" : {
"description" : "Bad Request"
}
},
"security" : [ {
"bearerAuth" : [ ]
} ]
}
},
"/v1/players/counts/proxies" : {
"get" : {
"summary" : "Players per proxy and region",
Expand Down Expand Up @@ -519,6 +662,51 @@
} ]
}
},
"/v1/players/names/known" : {
"get" : {
"summary" : "Search known player identities, including offline profiles",
"description" : "Supply either a prefix of at least two characters or an exact name. Prefix replies are capped at 25. Exact replies contain at most two identities so callers can reject ambiguous names. No online presence is implied.",
"tags" : [ "Names" ],
"parameters" : [ {
"name" : "limit",
"in" : "query",
"schema" : {
"type" : [ "integer", "null" ],
"format" : "int32"
},
"required" : true
}, {
"name" : "name",
"in" : "query",
"schema" : {
"type" : [ "string", "null" ]
},
"required" : true
}, {
"name" : "prefix",
"in" : "query",
"schema" : {
"type" : [ "string", "null" ]
},
"required" : true
} ],
"responses" : {
"200" : {
"description" : "OK",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/KnownPlayerDirectoryResponse"
}
}
}
}
},
"security" : [ {
"bearerAuth" : [ ]
} ]
}
},
"/v1/players/names/suggestions" : {
"get" : {
"summary" : "Prefix-search online player names",
Expand Down Expand Up @@ -824,6 +1012,138 @@
} ]
}
},
"/v1/players/{playerId}/playtime" : {
"get" : {
"summary" : "Read a player's playtime",
"description" : "Includes the segment that is still running, so the number ticks up while the player is online. A player who has never been seen reads as zero, not as a missing resource.",
"tags" : [ "Playtime" ],
"parameters" : [ {
"name" : "playerId",
"in" : "path",
"required" : true,
"schema" : {
"type" : "string"
}
} ],
"responses" : {
"200" : {
"description" : "Total and game time in milliseconds.",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/Playtime"
}
}
}
},
"400" : {
"description" : "`playerId` is not a UUID.",
"content" : {
"application/problem+json" : {
"schema" : {
"$ref" : "#/components/schemas/Problem"
}
}
}
},
"401" : {
"description" : "Authentication is missing or invalid."
},
"503" : {
"description" : "The store could not be read. Deliberately not zero.",
"content" : {
"application/problem+json" : {
"schema" : {
"$ref" : "#/components/schemas/Problem"
}
}
}
}
},
"security" : [ {
"bearerAuth" : [ ]
} ]
}
},
"/v1/players/{playerId}/profile-visibility" : {
"put" : {
"summary" : "Store or clear a player's profile visibility",
"description" : "One of `public`, `friends`, `private`; null clears it back to the default.",
"tags" : [ "Profile visibility" ],
"parameters" : [ {
"name" : "playerId",
"in" : "path",
"required" : true,
"schema" : {
"type" : "string"
}
} ],
"requestBody" : {
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/SetProfileVisibilityRequest"
}
}
},
"required" : true
},
"responses" : {
"204" : {
"description" : "The visibility was stored or cleared."
},
"400" : {
"description" : "`playerId` is not a UUID, or `visibility` is not one of the choices."
},
"404" : {
"description" : "This service has never seen the player, so there is no row to write."
},
"401" : {
"description" : "Authentication is missing or invalid."
}
},
"security" : [ {
"bearerAuth" : [ ]
} ]
},
"get" : {
"summary" : "Read a player's profile visibility",
"description" : "Null when the player has never chosen one; readers treat that as `public`. A read failure is a 503, never null, so a private profile is not shown by accident.",
"tags" : [ "Profile visibility" ],
"parameters" : [ {
"name" : "playerId",
"in" : "path",
"required" : true,
"schema" : {
"type" : "string"
}
} ],
"responses" : {
"200" : {
"description" : "The stored visibility, or null.",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/ProfileVisibilityResponse"
}
}
}
},
"400" : {
"description" : "`playerId` is not a UUID."
},
"401" : {
"description" : "Authentication is missing or invalid."
},
"503" : {
"description" : "The store could not be read."
}
},
"security" : [ {
"bearerAuth" : [ ]
} ]
}
},
"/v1/players/{playerId}/region" : {
"put" : {
"summary" : "Store or clear a player's preferred region",
Expand Down
Loading