diff --git a/app/Protocols/General.php b/app/Protocols/General.php index 9945926..bf8ad72 100644 --- a/app/Protocols/General.php +++ b/app/Protocols/General.php @@ -18,6 +18,7 @@ class General extends AbstractProtocol Server::TYPE_TROJAN, Server::TYPE_HYSTERIA, Server::TYPE_SOCKS, + Server::TYPE_TUIC, ]; protected $protocolRequirements = [ @@ -39,6 +40,7 @@ class General extends AbstractProtocol Server::TYPE_TROJAN => self::buildTrojan($item['password'], $item), Server::TYPE_HYSTERIA => self::buildHysteria($item['password'], $item), Server::TYPE_SOCKS => self::buildSocks($item['password'], $item), + Server::TYPE_TUIC => self::buildTuic($item['password'], $item), default => '', }; } @@ -135,6 +137,7 @@ class General extends AbstractProtocol $config['security'] = "tls"; if ($serverName = data_get($protocol_settings, 'tls_settings.server_name')) { $config['sni'] = $serverName; + $config['fp'] = Helper::getRandFingerprint(); } break; case 2: //reality @@ -254,6 +257,59 @@ class General extends AbstractProtocol return $uri; } + + + public static function buildTuic($password, $server) + { + $protocol_settings = data_get($server, 'protocol_settings', []); + $name = rawurlencode($server['name']); + $addr = Helper::wrapIPv6($server['host']); + $port = $server['port']; + $uuid = $password; // v2rayN格式里,uuid和password都是密码部分 + $pass = $password; + + $queryParams = []; + + // 填充sni参数 + if ($sni = data_get($protocol_settings, 'tls.server_name')) { + $queryParams['sni'] = $sni; + } + + // alpn参数,支持多值时用逗号连接 + if ($alpn = data_get($protocol_settings, 'alpn')) { + if (is_array($alpn)) { + $queryParams['alpn'] = implode(',', $alpn); + } else { + $queryParams['alpn'] = $alpn; + } + } + + // congestion_controller参数,默认cubic + $congestion = data_get($protocol_settings, 'congestion_control', 'cubic'); + $queryParams['congestion_control'] = $congestion; + + // udp_relay_mode参数,默认native + $udpRelay = data_get($protocol_settings, 'udp_relay_mode', 'native'); + $queryParams['udp-relay-mode'] = $udpRelay; + + $query = http_build_query($queryParams); + + // 构造完整URI,格式: + // Tuic://uuid:password@host:port?sni=xxx&alpn=xxx&congestion_controller=xxx&udp_relay_mode=xxx#别名 + $uri = "tuic://{$uuid}:{$pass}@{$addr}:{$port}"; + + if (!empty($query)) { + $uri .= "?{$query}"; + } + + $uri .= "#{$name}\r\n"; + + return $uri; + } + + + + public static function buildSocks($password, $server) {