@@ -19,6 +19,7 @@ class General extends AbstractProtocol
1919 Server::TYPE_HYSTERIA ,
2020 Server::TYPE_ANYTLS ,
2121 Server::TYPE_SOCKS ,
22+ Server::TYPE_TUIC ,
2223 ];
2324
2425 protected $ protocolRequirements = [
@@ -41,6 +42,7 @@ public function handle()
4142 Server::TYPE_HYSTERIA => self ::buildHysteria ($ item ['password ' ], $ item ),
4243 Server::TYPE_ANYTLS => self ::buildAnyTLS ($ item ['password ' ], $ item ),
4344 Server::TYPE_SOCKS => self ::buildSocks ($ item ['password ' ], $ item ),
45+ Server::TYPE_TUIC => self ::buildTuic ($ item ['password ' ], $ item ),
4446 default => '' ,
4547 };
4648 }
@@ -137,6 +139,7 @@ public static function buildVless($uuid, $server)
137139 $ config ['security ' ] = "tls " ;
138140 if ($ serverName = data_get ($ protocol_settings , 'tls_settings.server_name ' )) {
139141 $ config ['sni ' ] = $ serverName ;
142+ $ config ['fp ' ] = Helper::getRandFingerprint ();
140143 }
141144 break ;
142145 case 2 : //reality
@@ -256,6 +259,59 @@ public static function buildHysteria($password, $server)
256259
257260 return $ uri ;
258261 }
262+
263+
264+ public static function buildTuic ($ password , $ server )
265+ {
266+ $ protocol_settings = data_get ($ server , 'protocol_settings ' , []);
267+ $ name = rawurlencode ($ server ['name ' ]);
268+ $ addr = Helper::wrapIPv6 ($ server ['host ' ]);
269+ $ port = $ server ['port ' ];
270+ $ uuid = $ password ; // v2rayN格式里,uuid和password都是密码部分
271+ $ pass = $ password ;
272+
273+ $ queryParams = [];
274+
275+ // 填充sni参数
276+ if ($ sni = data_get ($ protocol_settings , 'tls.server_name ' )) {
277+ $ queryParams ['sni ' ] = $ sni ;
278+ }
279+
280+ // alpn参数,支持多值时用逗号连接
281+ if ($ alpn = data_get ($ protocol_settings , 'alpn ' )) {
282+ if (is_array ($ alpn )) {
283+ $ queryParams ['alpn ' ] = implode (', ' , $ alpn );
284+ } else {
285+ $ queryParams ['alpn ' ] = $ alpn ;
286+ }
287+ }
288+
289+ // congestion_controller参数,默认cubic
290+ $ congestion = data_get ($ protocol_settings , 'congestion_control ' , 'cubic ' );
291+ $ queryParams ['congestion_control ' ] = $ congestion ;
292+
293+ // udp_relay_mode参数,默认native
294+ $ udpRelay = data_get ($ protocol_settings , 'udp_relay_mode ' , 'native ' );
295+ $ queryParams ['udp-relay-mode ' ] = $ udpRelay ;
296+
297+ $ query = http_build_query ($ queryParams );
298+
299+ // 构造完整URI,格式:
300+ // Tuic://uuid:password@host:port?sni=xxx&alpn=xxx&congestion_controller=xxx&udp_relay_mode=xxx#别名
301+ $ uri = "tuic:// {$ uuid }: {$ pass }@ {$ addr }: {$ port }" ;
302+
303+ if (!empty ($ query )) {
304+ $ uri .= "? {$ query }" ;
305+ }
306+
307+ $ uri .= "# {$ name }\r\n" ;
308+
309+ return $ uri ;
310+ }
311+
312+
313+
314+
259315
260316 public static function buildAnyTLS ($ password , $ server )
261317 {
0 commit comments