mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-24 08:33:41 +01:00
feat(api): add GET /v2/server/info endpoint for launcher compatibility
Exposes the server's configured client mode in a form that mhf-outpost and other launcher tools can consume to warn users when their local game version does not match what the server expects. Returns clientMode (raw, e.g. "G9.1") and manifestId (normalized for mhf-outpost: lowercase, dots stripped, e.g. "g91"). No auth required.
This commit is contained in:
@@ -86,6 +86,7 @@ func (s *APIServer) Start() error {
|
||||
v2.HandleFunc("/version", s.Version).Methods("GET")
|
||||
v2.HandleFunc("/health", s.Health).Methods("GET")
|
||||
v2.HandleFunc("/server/status", s.ServerStatus).Methods("GET")
|
||||
v2.HandleFunc("/server/info", s.ServerInfo).Methods("GET")
|
||||
|
||||
// V2 authenticated routes
|
||||
v2Auth := v2.PathPrefix("").Subrouter()
|
||||
|
||||
@@ -156,6 +156,32 @@ func (s *APIServer) Version(w http.ResponseWriter, r *http.Request) {
|
||||
_ = json.NewEncoder(w).Encode(resp)
|
||||
}
|
||||
|
||||
// ServerInfoResponse is the JSON payload returned by GET /v2/server/info.
|
||||
// It exposes the server's configured game version in a form that launcher
|
||||
// tools (e.g. mhf-outpost) can use to check version compatibility.
|
||||
type ServerInfoResponse struct {
|
||||
// ClientMode is the version string as configured in Erupe (e.g. "ZZ", "G10.1").
|
||||
ClientMode string `json:"clientMode"`
|
||||
// ManifestID is the normalized form of ClientMode (lowercase, dots removed)
|
||||
// matching mhf-outpost manifest IDs (e.g. "zz", "g101").
|
||||
ManifestID string `json:"manifestId"`
|
||||
// Name is the server software name.
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// ServerInfo handles GET /v2/server/info, returning the server's configured
|
||||
// game version in a format compatible with mhf-outpost manifest IDs.
|
||||
func (s *APIServer) ServerInfo(w http.ResponseWriter, r *http.Request) {
|
||||
clientMode := s.erupeConfig.ClientMode
|
||||
resp := ServerInfoResponse{
|
||||
ClientMode: clientMode,
|
||||
ManifestID: strings.ToLower(strings.ReplaceAll(clientMode, ".", "")),
|
||||
Name: "Erupe-CE",
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_ = json.NewEncoder(w).Encode(resp)
|
||||
}
|
||||
|
||||
// Launcher handles GET /launcher and returns banners, messages, and links for the launcher UI.
|
||||
func (s *APIServer) Launcher(w http.ResponseWriter, r *http.Request) {
|
||||
var respData LauncherResponse
|
||||
|
||||
@@ -44,6 +44,56 @@ func TestVersionEndpoint(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerInfoEndpoint(t *testing.T) {
|
||||
tests := []struct {
|
||||
clientMode string
|
||||
wantID string
|
||||
}{
|
||||
{"ZZ", "zz"},
|
||||
{"GG", "gg"},
|
||||
{"G10.1", "g101"},
|
||||
{"G9.1", "g91"},
|
||||
{"FW.5", "fw5"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.clientMode, func(t *testing.T) {
|
||||
logger := NewTestLogger(t)
|
||||
c := NewTestConfig()
|
||||
c.ClientMode = tt.clientMode
|
||||
|
||||
server := &APIServer{
|
||||
logger: logger,
|
||||
erupeConfig: c,
|
||||
}
|
||||
|
||||
req := httptest.NewRequest("GET", "/v2/server/info", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
server.ServerInfo(rec, req)
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Errorf("status = %d, want 200", rec.Code)
|
||||
}
|
||||
if ct := rec.Header().Get("Content-Type"); ct != "application/json" {
|
||||
t.Errorf("Content-Type = %q, want application/json", ct)
|
||||
}
|
||||
|
||||
var resp ServerInfoResponse
|
||||
if err := json.NewDecoder(rec.Body).Decode(&resp); err != nil {
|
||||
t.Fatalf("decode error: %v", err)
|
||||
}
|
||||
if resp.ClientMode != tt.clientMode {
|
||||
t.Errorf("ClientMode = %q, want %q", resp.ClientMode, tt.clientMode)
|
||||
}
|
||||
if resp.ManifestID != tt.wantID {
|
||||
t.Errorf("ManifestID = %q, want %q", resp.ManifestID, tt.wantID)
|
||||
}
|
||||
if resp.Name != "Erupe-CE" {
|
||||
t.Errorf("Name = %q, want Erupe-CE", resp.Name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLandingPageEndpoint_Enabled(t *testing.T) {
|
||||
logger := NewTestLogger(t)
|
||||
c := NewTestConfig()
|
||||
|
||||
@@ -44,6 +44,7 @@ func newTestRouter(s *APIServer) *mux.Router {
|
||||
v2Auth.HandleFunc("/characters/{id}/export", s.ExportSave).Methods("GET")
|
||||
|
||||
v2.HandleFunc("/server/status", s.ServerStatus).Methods("GET")
|
||||
v2.HandleFunc("/server/info", s.ServerInfo).Methods("GET")
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user