Files
browser/platform/api/game_client_bridge_handlers.go
2026-07-20 16:42:33 +08:00

140 lines
4.6 KiB
Go

package api
import (
"net/http"
"strconv"
"time"
"browser.local/platform/domain"
"browser.local/platform/dto"
"browser.local/platform/repo"
)
func (h *coreHandlers) serverGameClientBridgeStatus(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
writeMethodNotAllowed(w, http.MethodGet)
return
}
status, err := h.core.GetGameClientBridgeStatusForSession(bearerToken(r), r.PathValue("id"))
if err != nil {
writeServiceError(w, err)
return
}
writeJSON(w, http.StatusOK, dto.GameClientBridgeStatusFromDomain(status))
}
func (h *coreHandlers) serverGameClientBridgeCommands(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
commands, err := h.core.ListGameClientBridgeCommandsForSession(bearerToken(r), domain.GameClientBridgeCommandFilter{ServerInstanceID: r.PathValue("id"), ProfileKey: r.URL.Query().Get("profileKey"), State: domain.GameClientBridgeCommandState(r.URL.Query().Get("state")), CommandType: r.URL.Query().Get("commandType")})
if err != nil {
writeServiceError(w, err)
return
}
writeJSON(w, http.StatusOK, dto.GameClientBridgeCommandsFromDomain(commands))
case http.MethodPost:
request, err := decodeJSON[dto.GameClientBridgeQueueRequest](r)
if err != nil {
writeDecodeError(w, err)
return
}
instance, err := h.core.GetServerInstanceForSession(bearerToken(r), r.PathValue("id"))
if err != nil {
writeServiceError(w, err)
return
}
command, err := h.core.QueueGameClientBridgeCommandForSession(bearerToken(r), request.ToDomain(instance.ID, instance.PluginID))
if err != nil {
writeServiceError(w, err)
return
}
writeJSON(w, http.StatusAccepted, dto.GameClientBridgeCommandFromDomain(command))
default:
w.Header().Set("Allow", http.MethodGet+", "+http.MethodPost)
writeAPIError(w, http.StatusMethodNotAllowed, errorCodeMethodNotAllowed, "method not allowed", nil)
}
}
func (h *coreHandlers) serverGameClientBridgeCommandDetail(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
writeMethodNotAllowed(w, http.MethodGet)
return
}
command, err := h.core.GetGameClientBridgeCommandForSession(bearerToken(r), r.PathValue("commandId"))
if err != nil {
writeServiceError(w, err)
return
}
if command.ServerInstanceID != r.PathValue("id") {
writeServiceError(w, repo.ErrNotFound)
return
}
writeJSON(w, http.StatusOK, dto.GameClientBridgeCommandFromDomain(command))
}
func (h *coreHandlers) serverGameClientBridgeCommandCancel(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
writeMethodNotAllowed(w, http.MethodPost)
return
}
request, err := decodeJSON[dto.GameClientBridgeCancelRequest](r)
if err != nil {
writeDecodeError(w, err)
return
}
command, err := h.core.GetGameClientBridgeCommandForSession(bearerToken(r), r.PathValue("commandId"))
if err != nil {
writeServiceError(w, err)
return
}
if command.ServerInstanceID != r.PathValue("id") {
writeServiceError(w, repo.ErrNotFound)
return
}
cancelled, err := h.core.CancelGameClientBridgeCommandForSession(bearerToken(r), request.ToDomain(command.ID))
if err != nil {
writeServiceError(w, err)
return
}
writeJSON(w, http.StatusOK, dto.GameClientBridgeCancelFromDomain(cancelled))
}
func (h *coreHandlers) serverGameClientBridgeSnapshots(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
writeMethodNotAllowed(w, http.MethodGet)
return
}
instance, err := h.core.GetServerInstanceForSession(bearerToken(r), r.PathValue("id"))
if err != nil {
writeServiceError(w, err)
return
}
limit, err := optionalPositiveInt(r.URL.Query().Get("limit"))
if err != nil {
writeAPIError(w, http.StatusBadRequest, errorCodeBadRequest, "invalid snapshot limit", nil)
return
}
var observedAfter time.Time
if value := r.URL.Query().Get("observedAfter"); value != "" {
observedAfter, err = time.Parse(time.RFC3339Nano, value)
if err != nil {
writeAPIError(w, http.StatusBadRequest, errorCodeBadRequest, "invalid observedAfter timestamp", nil)
return
}
}
query := dto.GameClientBridgeSnapshotQuery{ProfileKey: r.URL.Query().Get("profileKey"), Type: r.URL.Query().Get("type"), StreamKey: r.URL.Query().Get("streamKey"), ObservedAfter: observedAfter, Limit: limit}
snapshots, err := h.core.QueryGameClientBridgeSnapshotsForSession(bearerToken(r), query.ToDomain(instance.ID, instance.PluginID))
if err != nil {
writeServiceError(w, err)
return
}
writeJSON(w, http.StatusOK, dto.GameClientBridgeSnapshotsFromDomain(snapshots))
}
func optionalPositiveInt(value string) (int, error) {
if value == "" {
return 0, nil
}
return strconv.Atoi(value)
}