diff --git a/app/Protocols/Loon.php b/app/Protocols/Loon.php index b38823d..9e13b44 100644 --- a/app/Protocols/Loon.php +++ b/app/Protocols/Loon.php @@ -14,6 +14,7 @@ class Loon extends AbstractProtocol Server::TYPE_VMESS, Server::TYPE_TROJAN, Server::TYPE_HYSTERIA, + Server::TYPE_VLESS, ]; protected $protocolRequirements = [ @@ -42,6 +43,9 @@ class Loon extends AbstractProtocol if ($item['type'] === Server::TYPE_HYSTERIA) { $uri .= self::buildHysteria($item['password'], $item, $user); } + if ($item['type'] === Server::TYPE_VLESS) { + $uri .= self::buildVless($item['password'], $item); + } } return response($uri) ->header('content-type', 'text/plain') @@ -176,58 +180,77 @@ class Loon extends AbstractProtocol return $uri; } - public static function buildVless($uuid, $server) - { - $protocol_settings = $server['protocol_settings']; - $config = [ - "{$server['name']}=vless", - $server['host'], - $server['port'], - $uuid, - 'fast-open=false', - 'udp=true', - 'alterId=0' - ]; - switch ((int) data_get($protocol_settings, 'tls')) { - case 1: - $config[] = 'over-tls=true'; - $tlsSettings = data_get($protocol_settings, 'tls_settings', []); - if ($tlsSettings) { - $config[] = 'skip-cert-verify=' . (data_get($tlsSettings, 'allow_insecure') ? 'true' : 'false'); - if ($serverName = data_get($tlsSettings, 'server_name')) { - $config[] = "tls-name={$serverName}"; - } - } - break; - case 2: - return ''; - } - $network_settings = data_get($protocol_settings, 'network_settings', []); - switch ((string) data_get($network_settings, 'network')) { - case 'tcp': - $config[] = 'transport=tcp'; - if ($headerType = data_get($network_settings, 'header.type')) { - $config = collect($config)->map(function ($item) use ($headerType) { - return $item === 'transport=tcp' ? "transport={$headerType}" : $item; - })->toArray(); - } - if ($paths = data_get($network_settings, 'header.request.path')) { - $config[] = 'path=' . $paths[array_rand($paths)]; - } - break; - case 'ws': - $config[] = 'transport=ws'; - if ($path = data_get($network_settings, 'path')) { - $config[] = "path={$path}"; - } + public static function buildVless($password, $server) + { + $protocol_settings = data_get($server, 'protocol_settings', []); - if ($host = data_get($network_settings, 'headers.Host')) { - $config[] = "host={$host}"; - } - break; - } - return implode(',', $config) . "\r\n"; - } + $config = [ + "{$server['name']}=VLESS", + "{$server['host']}", + "{$server['port']}", + "{$password}", + "alterId=0", + "udp=true" + ]; + + // flow + if ($flow = data_get($protocol_settings, 'flow')) { + $config[] = "flow={$flow}"; + } + + // TLS/Reality + switch (data_get($protocol_settings, 'tls')) { + case 1: + $config[] = "over-tls=true"; + $config[] = "skip-cert-verify=" . (data_get($protocol_settings, 'tls_settings.allow_insecure', false) ? "true" : "false"); + if ($serverName = data_get($protocol_settings, 'tls_settings.server_name')) { + $config[] = "sni={$serverName}"; + } + break; + case 2: + $config[] = "over-tls=true"; + $config[] = "skip-cert-verify=" . (data_get($protocol_settings, 'reality_settings.allow_insecure', false) ? "true" : "false"); + if ($serverName = data_get($protocol_settings, 'reality_settings.server_name')) { + $config[] = "sni={$serverName}"; + } + if ($pubkey = data_get($protocol_settings, 'reality_settings.public_key')) { + $config[] = "public-key={$pubkey}"; + } + if ($shortid = data_get($protocol_settings, 'reality_settings.short_id')) { + $config[] = "short-id={$shortid}"; + } + break; + default: + $config[] = "over-tls=false"; + break; + } + + // network + switch (data_get($protocol_settings, 'network')) { + case 'ws': + $config[] = "transport=ws"; + if ($path = data_get($protocol_settings, 'network_settings.path')) { + $config[] = "path={$path}"; + } + if ($host = data_get($protocol_settings, 'network_settings.headers.Host')) { + $config[] = "host={$host}"; + } + break; + case 'grpc': + $config[] = "transport=grpc"; + if ($serviceName = data_get($protocol_settings, 'network_settings.serviceName')) { + $config[] = "grpc-service-name={$serviceName}"; + } + break; + default: + $config[] = "transport=tcp"; + break; + } + + $config = array_filter($config); + $uri = implode(',', $config) . "\r\n"; + return $uri; + } public static function buildHysteria($password, $server, $user) {