33 lines
1.1 KiB
TypeScript
33 lines
1.1 KiB
TypeScript
/** Compare the address players enter in Minecraft; never resolve DNS aliases. */
|
|
export function normalizeServerAddress(
|
|
value: string | null | undefined,
|
|
): string | null {
|
|
const input = value?.trim().toLowerCase();
|
|
if (!input) return null;
|
|
if (input.length > 255) throw new Error("Server address is too long");
|
|
const match = /^(\[[0-9a-f:]+\]|[a-z0-9.-]+)(?::([0-9]{1,5}))?$/.exec(input);
|
|
if (!match)
|
|
throw new Error("Use a Minecraft hostname or IP, with an optional port");
|
|
let host = match[1];
|
|
if (host.startsWith("[")) {
|
|
try {
|
|
new URL(`http://${host}`);
|
|
} catch {
|
|
throw new Error("Invalid IPv6 address");
|
|
}
|
|
} else {
|
|
host = host.replace(/\.$/, "");
|
|
if (
|
|
host.length > 253 ||
|
|
host
|
|
.split(".")
|
|
.some((label) => !/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(label))
|
|
)
|
|
throw new Error("Invalid server hostname");
|
|
}
|
|
const port = match[2] ? Number(match[2]) : 25565;
|
|
if (port < 1 || port > 65535)
|
|
throw new Error("Server port must be between 1 and 65535");
|
|
return host + (port === 25565 ? "" : `:${port}`);
|
|
}
|