-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpinger.ts
69 lines (54 loc) · 1.69 KB
/
pinger.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import type { StatusResult } from './protocol/status'
import type { Server } from './storage'
import { status } from './protocol/status'
interface ApiResponse {
online: boolean
players: { online: number; max: number }
icon?: string
favicon?: string
}
export async function ping(env: Env, server: Server) {
const attempts = env.PING_ATTEMPTS ?? 1
for (let i = 1; i < attempts; i++) {
const result = await tryPing(env, server)
if (!result) {
console.error(`Error during ping attempt ${i} for ${server.name}.`)
continue
}
return result
}
return tryPing(env, server)
}
async function tryPing(env: Env, server: Server) {
const hostAliases = env.PING_ALIASES ? JSON.parse(env.PING_ALIASES) : {}
const host = hostAliases[server.address] || server.address
const url = server.type === 'JAVA' ? env.STATUS_URL : env.BEDROCK_STATUS_URL
if (!url && server.type === 'JAVA') {
try {
return status(server.address)
} catch (e) {
console.error(`Unable to ping ${host}: ${e?.toString()}`)
return undefined
}
}
if (!url) {
console.error('You need to define BEDROCK_STATUS_URL for bedrock servers.')
return undefined
}
const response = await fetch(url.replace('{address}', host), {
headers: {
'Content-Type': 'application/json',
'User-Agent': 'CraftStats',
},
})
if (!response.ok) {
console.error(`Invalid status response for ${host}: ${response.status}`)
return undefined
}
const data = await response.json<ApiResponse>()
if (!data.online) {
console.error(`Server offline for ${host}`)
return undefined
}
return <StatusResult>{ players: data.players, favicon: data.icon || data.favicon }
}