Files
oslstats/pkg/slapshotapi/lobbies.go
2026-02-21 14:45:14 +11:00

188 lines
4.3 KiB
Go

package slapshotapi
import (
"context"
"encoding/json"
"fmt"
"net/http"
"strings"
"github.com/pkg/errors"
)
// --- Get Lobby ---
type endpointGetLobby struct {
lobbyID string
}
func getEndpointGetLobby(lobbyID string) *endpointGetLobby {
return &endpointGetLobby{lobbyID: lobbyID}
}
func (ep *endpointGetLobby) path() string {
return fmt.Sprintf("/api/public/lobbies/%s", ep.lobbyID)
}
func (ep *endpointGetLobby) method() string {
return "GET"
}
// ErrLobbyNotFound is returned when a lobby ID does not match any known lobby
var ErrLobbyNotFound = errors.New("lobby not found")
// GetLobby retrieves details for a specific lobby by its ID.
func (c *SlapAPI) GetLobby(
ctx context.Context,
lobbyID string,
) (*Lobby, error) {
if lobbyID == "" {
return nil, errors.New("lobbyID cannot be empty")
}
endpoint := getEndpointGetLobby(lobbyID)
data, err := c.request(ctx, endpoint)
if err != nil {
if strings.Contains(err.Error(), "404") {
return nil, ErrLobbyNotFound
}
return nil, errors.Wrap(err, "c.request")
}
lobby, err := unmarshal[Lobby](data)
if err != nil {
return nil, errors.Wrap(err, "unmarshal")
}
return lobby, nil
}
// --- Get Lobby Matches ---
type endpointGetLobbyMatches struct {
lobbyID string
}
func getEndpointGetLobbyMatches(lobbyID string) *endpointGetLobbyMatches {
return &endpointGetLobbyMatches{lobbyID: lobbyID}
}
func (ep *endpointGetLobbyMatches) path() string {
return fmt.Sprintf("/api/public/lobbies/%s/matches", ep.lobbyID)
}
func (ep *endpointGetLobbyMatches) method() string {
return "GET"
}
// GetLobbyMatches retrieves the list of matches played in a specific lobby.
func (c *SlapAPI) GetLobbyMatches(
ctx context.Context,
lobbyID string,
) ([]Game, error) {
if lobbyID == "" {
return nil, errors.New("lobbyID cannot be empty")
}
endpoint := getEndpointGetLobbyMatches(lobbyID)
data, err := c.request(ctx, endpoint)
if err != nil {
if strings.Contains(err.Error(), "404") {
return nil, ErrLobbyNotFound
}
return nil, errors.Wrap(err, "c.request")
}
var games []Game
err = json.Unmarshal(data, &games)
if err != nil {
return nil, errors.Wrap(err, "json.Unmarshal")
}
return games, nil
}
// --- Create Lobby ---
type endpointCreateLobby struct {
request LobbyCreationRequest
}
func getEndpointCreateLobby(req LobbyCreationRequest) *endpointCreateLobby {
return &endpointCreateLobby{request: req}
}
func (ep *endpointCreateLobby) path() string {
return "/api/public/lobbies"
}
func (ep *endpointCreateLobby) method() string {
return "POST"
}
func (ep *endpointCreateLobby) body() ([]byte, error) {
data, err := json.Marshal(ep.request)
if err != nil {
return nil, errors.Wrap(err, "json.Marshal")
}
return data, nil
}
// CreateLobby creates a new custom lobby with the specified settings.
func (c *SlapAPI) CreateLobby(
ctx context.Context,
req LobbyCreationRequest,
) (*LobbyCreationResponse, error) {
if req.Region == "" {
return nil, errors.New("region cannot be empty")
}
if req.Name == "" {
return nil, errors.New("name cannot be empty")
}
if req.CreatorName == "" {
return nil, errors.New("creator_name cannot be empty")
}
endpoint := getEndpointCreateLobby(req)
data, err := c.request(ctx, endpoint)
if err != nil {
return nil, errors.Wrap(err, "c.request")
}
resp, err := unmarshal[LobbyCreationResponse](data)
if err != nil {
return nil, errors.Wrap(err, "unmarshal")
}
return resp, nil
}
// --- Delete Lobby ---
type endpointDeleteLobby struct {
lobbyID string
}
func getEndpointDeleteLobby(lobbyID string) *endpointDeleteLobby {
return &endpointDeleteLobby{lobbyID: lobbyID}
}
func (ep *endpointDeleteLobby) path() string {
return fmt.Sprintf("/api/public/lobbies/%s", ep.lobbyID)
}
func (ep *endpointDeleteLobby) method() string {
return "DELETE"
}
// DeleteLobby deletes an existing lobby by its ID.
// Returns true if the lobby was successfully deleted.
func (c *SlapAPI) DeleteLobby(
ctx context.Context,
lobbyID string,
) (bool, error) {
if lobbyID == "" {
return false, errors.New("lobbyID cannot be empty")
}
endpoint := getEndpointDeleteLobby(lobbyID)
status, body, err := c.requestRaw(ctx, endpoint)
if err != nil {
return false, errors.Wrap(err, "c.requestRaw")
}
if status == http.StatusNotFound {
return false, ErrLobbyNotFound
}
return string(body) == "OK", nil
}