Skip to content

Commit 3863dfa

Browse files
feat: /@me/status public api (#21)
* feat: start public apis * chore: dont omit if empty
1 parent 62a9a64 commit 3863dfa

File tree

6 files changed

+224
-0
lines changed

6 files changed

+224
-0
lines changed

api/v1Public/model_player.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package v1Public
2+
3+
import (
4+
"github.com/hollow-cube/api-server/internal/db"
5+
)
6+
7+
type PlayerActivityType string
8+
9+
const (
10+
PlayerActivityUnknown PlayerActivityType = "unknown"
11+
PlayerActivityHub PlayerActivityType = "hub"
12+
PlayerActivityPlaying PlayerActivityType = "playing"
13+
PlayerActivityVerifying PlayerActivityType = "verifying"
14+
PlayerActivityBuilding PlayerActivityType = "building"
15+
)
16+
17+
type PlayerActivity struct {
18+
Type PlayerActivityType `json:"type"`
19+
Name *string `json:"name"`
20+
Id *string `json:"id"`
21+
Code *string `json:"code"`
22+
}
23+
24+
type PlayerStatus struct {
25+
Online bool `json:"online"`
26+
Activity *PlayerActivity `json:"activity"`
27+
}
28+
29+
func GetPlayerActivityTypeFromSession(session db.PlayerSession) PlayerActivityType {
30+
if session.PType != nil {
31+
switch *session.PType {
32+
case "mapmaker:hub":
33+
return PlayerActivityHub
34+
case "mapmaker:map":
35+
if session.PState != nil {
36+
switch *session.PState {
37+
case "editing":
38+
fallthrough
39+
case "testing":
40+
return PlayerActivityBuilding
41+
case "verifying":
42+
return PlayerActivityVerifying
43+
case "playing":
44+
fallthrough
45+
case "spectating":
46+
return PlayerActivityPlaying
47+
}
48+
}
49+
}
50+
}
51+
return PlayerActivityUnknown
52+
}

api/v1Public/openapi.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
openapi: 3.0.3
2+
info:
3+
title: Server API
4+
version: "1.0"
5+
paths:
6+
/@me/status:
7+
get:
8+
operationId: getPlayerStatus
9+
parameters:
10+
- name: x-auth-user
11+
in: header
12+
required: true
13+
schema:
14+
type: string
15+
responses:
16+
"200":
17+
description: Successful response
18+
content:
19+
application/json:
20+
schema:
21+
type: object

api/v1Public/server.gen.go

Lines changed: 37 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1Public/server.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//go:generate go run ../../cmd/ox/main.go generate ./.Server
2+
3+
package v1Public
4+
5+
import (
6+
sessiondb "github.com/hollow-cube/api-server/internal/db"
7+
"github.com/hollow-cube/api-server/internal/interaction"
8+
"github.com/hollow-cube/api-server/internal/mapdb"
9+
"github.com/hollow-cube/api-server/internal/pkg/notification"
10+
"github.com/hollow-cube/api-server/internal/playerdb"
11+
"go.uber.org/fx"
12+
"go.uber.org/zap"
13+
)
14+
15+
type ServerParams struct {
16+
fx.In
17+
18+
Log *zap.SugaredLogger
19+
PlayerStore *playerdb.Store
20+
MapStore *mapdb.Store
21+
SessionStore *sessiondb.Queries
22+
23+
Notifications notification.Manager
24+
Interactions *interaction.Handler
25+
}
26+
27+
type Server struct {
28+
log *zap.SugaredLogger
29+
30+
playerStore *playerdb.Store
31+
mapStore *mapdb.Store
32+
sessionStore *sessiondb.Queries
33+
34+
notifications notification.Manager
35+
interactions *interaction.Handler
36+
}
37+
38+
type AuthenticatedRequest struct {
39+
PlayerID string `header:"x-auth-user"`
40+
}
41+
42+
func NewServer(p ServerParams) (*Server, error) {
43+
s := &Server{
44+
log: p.Log,
45+
playerStore: p.PlayerStore,
46+
mapStore: p.MapStore,
47+
sessionStore: p.SessionStore,
48+
notifications: p.Notifications,
49+
interactions: p.Interactions,
50+
}
51+
52+
return s, nil
53+
}

api/v1Public/server_player.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package v1Public
2+
3+
import (
4+
"context"
5+
"database/sql"
6+
"errors"
7+
"fmt"
8+
"github.com/hollow-cube/api-server/internal/mapdb"
9+
)
10+
11+
// GET /@me/status
12+
func (s *Server) GetPlayerStatus(ctx context.Context, request AuthenticatedRequest) (*PlayerStatus, error) {
13+
session, err := s.sessionStore.GetPlayerSession(ctx, request.PlayerID)
14+
if err != nil && !errors.Is(err, sql.ErrNoRows) {
15+
return nil, err
16+
}
17+
18+
if session == nil || session.Hidden || errors.Is(err, sql.ErrNoRows) {
19+
return &PlayerStatus{Online: false, Activity: nil}, nil
20+
} else {
21+
var sessionType = GetPlayerActivityTypeFromSession(*session)
22+
var sessionName *string = nil
23+
var sessionId *string = nil
24+
var sessionCode *string = nil
25+
26+
if sessionType == PlayerActivityPlaying && session.PMapID != nil {
27+
mapData, err := s.mapStore.GetPublishedMapById(ctx, *session.PMapID)
28+
if err != nil && !errors.Is(err, mapdb.ErrNoRows) {
29+
return nil, err
30+
} else if err == nil && mapData.OptName != nil && mapData.PublishedID != nil {
31+
var code = fmt.Sprintf("%03d-%03d-%03d", *mapData.PublishedID/1000000, (*mapData.PublishedID/1000)%1000, *mapData.PublishedID%1000)
32+
33+
sessionName = mapData.OptName
34+
sessionId = &mapData.ID
35+
sessionCode = &code
36+
}
37+
}
38+
39+
return &PlayerStatus{
40+
Online: true,
41+
Activity: &PlayerActivity{
42+
Type: sessionType,
43+
Name: sessionName,
44+
Id: sessionId,
45+
Code: sessionCode,
46+
},
47+
}, nil
48+
}
49+
}

cmd/api-server/main.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7+
"github.com/hollow-cube/api-server/api/v1Public"
78
"net"
89
"net/http"
910

@@ -152,6 +153,7 @@ func main() {
152153
fx.Provide(newDynamicExporter),
153154
tracefx.Module,
154155
fx.Provide(
156+
v1Public.NewServer,
155157
v4Internal.NewServer,
156158

157159
v2Public.NewServer,
@@ -189,6 +191,7 @@ func newKubernetesClient(conf *config.Config) (*kubernetes.Clientset, error) {
189191
}
190192

191193
type routeHandlerImpl struct {
194+
v1p *v1Public.Server
192195
v4i *v4Internal.Server
193196

194197
public v2Public.StrictServerInterface
@@ -214,6 +217,13 @@ func (v *routeHandlerImpl) Apply(r chi.Router) {
214217
})
215218
r.Handle("/v4/internal/*", v4mux)
216219

220+
v1Mux := http.NewServeMux()
221+
v1Public.RegisterRoutes(v.v1p, v1Public.RegisterParams{
222+
Mux: v1Mux,
223+
BaseURL: "/v1",
224+
})
225+
r.Handle("/v1/*", v1Mux)
226+
217227
r.Handle("/v2/players/*", v2Public.HandlerFromMuxWithBaseURL(v2Public.NewStrictHandler(v.public, nil), nil, "/v2/players"))
218228
r.Handle("/v2/internal/*", v2Internal.HandlerFromMuxWithBaseURL(v2Internal.NewStrictHandler(v.internal, nil), nil, "/v2/internal"))
219229
r.Handle("/v2/payments/*", v2Payments.HandlerFromMuxWithBaseURL(v.payments, nil, "/v2/payments"))
@@ -241,6 +251,7 @@ func (v *routeHandlerImpl) Apply(r chi.Router) {
241251
func makeV2RouteHandler(p struct {
242252
fx.In
243253

254+
V1P *v1Public.Server
244255
V4I *v4Internal.Server
245256
Public v2Public.StrictServerInterface
246257
Internal v2Internal.StrictServerInterface
@@ -253,6 +264,7 @@ func makeV2RouteHandler(p struct {
253264
Discord *discord.Handler
254265
}) httpTransport.RouteProvider {
255266
return &routeHandlerImpl{
267+
v1p: p.V1P,
256268
v4i: p.V4I,
257269
public: p.Public,
258270
internal: p.Internal,

0 commit comments

Comments
 (0)