123 lines
2.6 KiB
TypeScript
123 lines
2.6 KiB
TypeScript
class Vmess {
|
|
add?: string;
|
|
aid?: any; // This could be number or string depending on usage
|
|
alpn?: string;
|
|
fp?: string;
|
|
host?: string;
|
|
id?: string;
|
|
net?: string;
|
|
path?: string;
|
|
port?: any; // This could be a number or string
|
|
ps?: string;
|
|
scy?: string;
|
|
sni?: string;
|
|
tls?: string;
|
|
type?: string;
|
|
v?: string;
|
|
|
|
constructor(data: {
|
|
add?: string;
|
|
aid?: any;
|
|
alpn?: string;
|
|
fp?: string;
|
|
host?: string;
|
|
id?: string;
|
|
net?: string;
|
|
path?: string;
|
|
port?: any;
|
|
ps?: string;
|
|
scy?: string;
|
|
sni?: string;
|
|
tls?: string;
|
|
type?: string;
|
|
v?: string;
|
|
}) {
|
|
this.add = data.add;
|
|
this.aid = data.aid;
|
|
this.alpn = data.alpn;
|
|
this.fp = data.fp;
|
|
this.host = data.host;
|
|
this.id = data.id;
|
|
this.net = data.net;
|
|
this.path = data.path;
|
|
this.port = data.port;
|
|
this.ps = data.ps;
|
|
this.scy = data.scy;
|
|
this.sni = data.sni;
|
|
this.tls = data.tls;
|
|
this.type = data.type;
|
|
this.v = data.v;
|
|
}
|
|
|
|
// 编码 Vmess URL
|
|
encodeURL(): string {
|
|
// 如果备注为空,则使用服务器地址 + 端口
|
|
if (!this.ps) {
|
|
this.ps = `${this.add}:${this.port}`;
|
|
}
|
|
// 如果版本为空,则默认为 2
|
|
if (!this.v) {
|
|
this.v = '2';
|
|
}
|
|
|
|
const param = JSON.stringify(this);
|
|
return 'vmess://' + this.base64Encode(param);
|
|
}
|
|
|
|
// 解码 Vmess URL
|
|
static decodeURL(url: string): Vmess {
|
|
if (!url.startsWith('vmess://')) {
|
|
throw new Error(`Invalid vmess URL: ${url}`);
|
|
}
|
|
const param = url.slice(8); // Remove "vmess://"
|
|
const decoded = Vmess.base64Decode(param.trim());
|
|
|
|
try {
|
|
const parsed = JSON.parse(decoded);
|
|
if (parsed.scy === '') {
|
|
parsed.scy = 'auto';
|
|
}
|
|
if (!parsed.ps) {
|
|
parsed.ps = parsed.add + ':' + parsed.port;
|
|
}
|
|
return new Vmess(parsed);
|
|
} catch (error) {
|
|
throw new Error(`Failed to parse VMESS URL: ${error}`);
|
|
}
|
|
}
|
|
|
|
// Base64 编码
|
|
private base64Encode(str: string): string {
|
|
return Buffer.from(str, 'utf-8').toString('base64');
|
|
}
|
|
|
|
// Base64 解码
|
|
private static base64Decode(str: string): string {
|
|
return Buffer.from(str, 'base64').toString('utf-8');
|
|
}
|
|
}
|
|
|
|
// 开发者测试
|
|
function callVmessURL() {
|
|
const vmess = new Vmess({
|
|
add: 'xx.xxx.ru',
|
|
port: '2095',
|
|
aid: 0,
|
|
scy: 'auto',
|
|
net: 'ws',
|
|
type: 'none',
|
|
id: '7a737f41-b792-4260-94ff-3d864da67380',
|
|
host: 'xx.xxx.ru',
|
|
path: '/',
|
|
tls: ''
|
|
});
|
|
|
|
const encoded = vmess.encodeURL();
|
|
console.log('Encoded VMESS URL:', encoded);
|
|
|
|
const decoded = Vmess.decodeURL(encoded);
|
|
console.log('Decoded VMESS:', decoded);
|
|
}
|
|
|
|
callVmessURL();
|