diff --git a/src/contexts/ServerContext.tsx b/src/contexts/ServerContext.tsx index e66d4b6..1c4c562 100644 --- a/src/contexts/ServerContext.tsx +++ b/src/contexts/ServerContext.tsx @@ -1,31 +1,27 @@ import { createContext, useContext, useState, useEffect } from 'react' import type { ReactNode } from 'react' -interface ServerInfo { +// Response from the new /api/server/statistics/list endpoint +interface ServerListResponse { + serverName: string + serverIP: string + serverPort: number + category: string + mapName: string + playerCount: number + botCount: number + maxPlayers?: number +} + +export interface ServerData { name: string ip: string port: number - category: 'Surf' | 'Kz' | 'Bhop' -} - -interface A2SResponse { - appID: number - botCount: number - environment: string - gameDescription: string - gameDirectory: string + category: string mapName: string - maxPlayers: number playerCount: number - serverName: string - serverType: string - vac: number - version: string - visibility: number -} - -export interface ServerData extends ServerInfo { - a2sData?: A2SResponse + botCount: number + maxPlayers: number status: 'online' | 'offline' | 'loading' error?: string } @@ -39,19 +35,6 @@ interface ServerContextType { const ServerContext = createContext(undefined) -// Server list from database export -const serverList: ServerInfo[] = [ - { name: 'Surf 66 Tick #1', ip: '14.103.233.1', port: 27015, category: 'Surf' }, - { name: 'Surf 66 Tick #2', ip: '14.103.233.1', port: 27016, category: 'Surf' }, - { name: 'Surf 66 Tick #3', ip: '14.103.233.1', port: 27017, category: 'Surf' }, - { name: 'Surf 100 Tick #1', ip: '14.103.233.1', port: 28015, category: 'Surf' }, - { name: 'Surf 100 Tick #2', ip: '14.103.233.1', port: 28016, category: 'Surf' }, - { name: 'Kz #1', ip: '14.103.233.1', port: 29015, category: 'Kz' }, - { name: 'Kz #2', ip: '14.103.233.1', port: 29016, category: 'Kz' }, - { name: 'Bhop #1', ip: '14.103.233.1', port: 30015, category: 'Bhop' }, - { name: 'Bhop #2', ip: '14.103.233.1', port: 30016, category: 'Bhop' } -] - export function ServerProvider({ children }: { children: ReactNode }) { const [servers, setServers] = useState([]) const [loading, setLoading] = useState(true) @@ -60,52 +43,32 @@ export function ServerProvider({ children }: { children: ReactNode }) { const fetchServerData = async () => { try { - // Batch query all servers in a single API call - const response = await fetch('/api/server/statistics/a2s-query', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - servers: serverList.map(server => ({ - serverIP: server.ip, - serverPort: server.port, - timeout: 3000 - })) - }) + // Fetch server list from the new API endpoint + const response = await fetch('/api/server/statistics/list', { + method: 'GET', + headers: { 'Content-Type': 'application/json' } }) if (!response.ok) { throw new Error(`HTTP ${response.status}`) } - const data = await response.json() + const data: ServerListResponse[] = await response.json() - // Update servers state with new data - setServers(prevServers => { - const results: ServerData[] = serverList.map((server, index) => { - const a2sData = data.results?.[index] - - if (a2sData) { - return { - ...server, - a2sData, - status: 'online' as const - } - } else { - // If no data for this server but we have previous data, keep the previous data - const prevServer = prevServers.find(s => s.ip === server.ip && s.port === server.port) - if (prevServer?.a2sData) { - return prevServer // Keep previous successful data - } - return { - ...server, - status: 'offline' as const, - error: 'No response from server' - } - } - }) - return results - }) + // Transform API response to ServerData format + const serverData: ServerData[] = data.map(server => ({ + name: server.serverName, + ip: server.serverIP, + port: server.serverPort, + category: server.category, + mapName: server.mapName, + playerCount: server.playerCount, + botCount: server.botCount, + maxPlayers: server.maxPlayers || 0, + status: 'online' as const + })) + setServers(serverData) setLoading(false) setLastUpdated(Date.now()) setHasInitialData(true) @@ -116,19 +79,14 @@ export function ServerProvider({ children }: { children: ReactNode }) { // Only show error state if this is the very first fetch attempt setServers(prevServers => { // Check if we have any previous successful data - const hasPreviousData = prevServers.some(s => s.a2sData) + const hasPreviousData = prevServers.length > 0 && prevServers.some(s => s.status === 'online') if (hasPreviousData) { // Keep previous data on polling errors return prevServers } else { - // First fetch failed, show offline state - const offlineServers: ServerData[] = serverList.map(server => ({ - ...server, - status: 'offline' as const, - error: error instanceof Error ? error.message : 'Unknown error' - })) - return offlineServers + // First fetch failed, return empty array + return [] } }) diff --git a/src/pages/Servers.tsx b/src/pages/Servers.tsx index 0c28bcc..e0b9ea9 100644 --- a/src/pages/Servers.tsx +++ b/src/pages/Servers.tsx @@ -238,7 +238,7 @@ function Servers() { fontSize: '0.9rem', color: 'var(--text-secondary)' }}> - 🗺️ {server.a2sData?.mapName || 'Loading...'} + 🗺️ {server.mapName || 'Loading...'} {server.category} @@ -264,7 +264,7 @@ function Servers() { fontWeight: 'bold', color: 'var(--text-primary)' }}> - {server.a2sData ? `${server.a2sData.playerCount - server.a2sData.botCount}/${server.a2sData.maxPlayers}` : 'Loading...'} + {server.status === 'online' ? `${server.playerCount - server.botCount}/${server.maxPlayers}` : 'Loading...'}
@@ -380,7 +380,7 @@ function Servers() { color: 'var(--accent-primary)', marginBottom: '0.5rem' }}> - {servers.reduce((sum, s) => sum + (s.a2sData ? (s.a2sData.playerCount - s.a2sData.botCount) : 0), 0)} + {servers.reduce((sum, s) => sum + (s.status === 'online' ? (s.playerCount - s.botCount) : 0), 0)}