87 lines
3.9 KiB
TypeScript
Executable File
87 lines
3.9 KiB
TypeScript
Executable File
import minecraftProtocol from "@wp2508/minecraft-protocol";
|
|
import type { ProxyOptions } from '@wp2508/mineflayer';
|
|
import {
|
|
validate_code_map,
|
|
type validate_username_code,
|
|
type validate_host_code,
|
|
type validate_port_code,
|
|
type validate_version_code,
|
|
type validate_proxy_code,
|
|
} from './validate_code_map';
|
|
|
|
const supportedVersions = minecraftProtocol.supportedVersions;
|
|
|
|
const username_code = validate_code_map.username;
|
|
const host_code = validate_code_map.host;
|
|
const port_code = validate_code_map.port;
|
|
const version_code = validate_code_map.version;
|
|
const proxy_code = validate_code_map.proxy;
|
|
|
|
// 检查 username 是否符合 Minecraft 用户名规则,返回错误码;0 表示通过
|
|
export function validate_username(username: string): validate_username_code {
|
|
if (typeof username !== 'string') return username_code.invalid_type;
|
|
if (username.length === 0) return username_code.empty;
|
|
if (username.length < 3) return username_code.too_short;
|
|
if (username.length > 16) return username_code.over_length;
|
|
if (!/^[A-Za-z0-9_]+$/.test(username)) return username_code.invalid_char;
|
|
return username_code.ok;
|
|
}
|
|
|
|
const IPV4_REGEX = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$/;
|
|
const DOMAIN_REGEX = /^(?=.{1,253}$)([A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z]{2,63}$/;
|
|
|
|
function is_valid_ipv6(host: string): boolean {
|
|
const value = host.startsWith('[') && host.endsWith(']') ? host.slice(1, -1) : host;
|
|
if (!value.includes(':')) return false;
|
|
try {
|
|
const url = new URL(`http://[${value}]`);
|
|
return url.hostname.length > 0;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// 检查是否为 ip 地址或者域名,返回错误码;0 表示通过
|
|
export function validate_host(host: string): validate_host_code {
|
|
if (typeof host !== 'string') return host_code.invalid_type;
|
|
if (host.length === 0) return host_code.empty;
|
|
if (host.length > 253) return host_code.over_length;
|
|
if (IPV4_REGEX.test(host)) return host_code.ok;
|
|
if (is_valid_ipv6(host)) return host_code.ok;
|
|
if (DOMAIN_REGEX.test(host)) return host_code.ok;
|
|
return host_code.invalid_format;
|
|
}
|
|
|
|
// 检查端口是否在 0-65535 之间,返回错误码;0 表示通过
|
|
export function validate_port(port: number): validate_port_code {
|
|
if (typeof port !== 'number') return port_code.invalid_type;
|
|
if (Number.isNaN(port)) return port_code.not_number;
|
|
if (!Number.isInteger(port)) return port_code.not_integer;
|
|
if (port < 0 || port > 65535) return port_code.out_of_range;
|
|
return port_code.ok;
|
|
}
|
|
|
|
// 检查版本是否在版本列表中,返回错误码;0 表示通过
|
|
export function validate_version(version: string): validate_version_code {
|
|
if (typeof version !== 'string') return version_code.invalid_type;
|
|
if (version.length === 0) return version_code.empty;
|
|
if (!supportedVersions.includes(version)) return version_code.unsupported;
|
|
return version_code.ok;
|
|
}
|
|
|
|
const PROXY_TYPES = ['socks5', 'sock5', 'http', 'https'] as const;
|
|
|
|
// 检查代理配置是否合理,返回错误码;0 表示通过
|
|
export function validate_proxy(proxy: ProxyOptions): validate_proxy_code {
|
|
if (typeof proxy !== 'object' || proxy === null) return proxy_code.invalid_type;
|
|
if (!proxy.type) return proxy_code.missing_type;
|
|
if (!PROXY_TYPES.includes(proxy.type)) return proxy_code.invalid_type_value;
|
|
if (!proxy.host) return proxy_code.missing_host;
|
|
if (validate_host(proxy.host) !== host_code.ok) return proxy_code.invalid_host;
|
|
if (proxy.port === undefined || proxy.port === null) return proxy_code.missing_port;
|
|
if (validate_port(proxy.port) !== port_code.ok) return proxy_code.invalid_port;
|
|
if (proxy.username != null && typeof proxy.username !== 'string') return proxy_code.invalid_username;
|
|
if (proxy.password != null && typeof proxy.password !== 'string') return proxy_code.invalid_password;
|
|
return proxy_code.ok;
|
|
}
|