@@ -116,15 +116,19 @@ bool applyMatcher(const std::string &rule, std::string &real_rule, const Proxy &
116
116
std::string target, ret_real_rule;
117
117
static const std::string groupid_regex = R"( ^!!(?:GROUPID|INSERT)=([\d\-+!,]+)(?:!!(.*))?$)" , group_regex = R"( ^!!(?:GROUP)=(.+?)(?:!!(.*))?$)" ;
118
118
static const std::string type_regex = R"( ^!!(?:TYPE)=(.+?)(?:!!(.*))?$)" , port_regex = R"( ^!!(?:PORT)=(.+?)(?:!!(.*))?$)" , server_regex = R"( ^!!(?:SERVER)=(.+?)(?:!!(.*))?$)" ;
119
- static const std::map<ProxyType, const char *> types = {{ProxyType::Shadowsocks, " SS" },
120
- {ProxyType::ShadowsocksR, " SSR" },
121
- {ProxyType::VMess, " VMESS" },
122
- {ProxyType::Trojan, " TROJAN" },
123
- {ProxyType::Snell, " SNELL" },
124
- {ProxyType::HTTP, " HTTP" },
125
- {ProxyType::HTTPS, " HTTPS" },
126
- {ProxyType::SOCKS5, " SOCKS5" },
127
- {ProxyType::WireGuard, " WIREGUARD" }};
119
+ static const std::map<ProxyType, const char *> types = {
120
+ {ProxyType::Shadowsocks, " SS" },
121
+ {ProxyType::ShadowsocksR, " SSR" },
122
+ {ProxyType::VMess, " VMESS" },
123
+ {ProxyType::Trojan, " TROJAN" },
124
+ {ProxyType::Snell, " SNELL" },
125
+ {ProxyType::HTTP, " HTTP" },
126
+ {ProxyType::HTTPS, " HTTPS" },
127
+ {ProxyType::SOCKS5, " SOCKS5" },
128
+ {ProxyType::WireGuard, " WIREGUARD" },
129
+ {ProxyType::Hysteria, " HYSTERIA" },
130
+ {ProxyType::Hysteria2, " HYSTERIA2" }
131
+ };
128
132
if (startsWith (rule, " !!GROUP=" ))
129
133
{
130
134
regGetMatch (rule, group_regex, 3 , 0 , &target, &ret_real_rule);
@@ -478,6 +482,77 @@ void proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGr
478
482
if (x.Mtu > 0 )
479
483
singleproxy[" mtu" ] = x.Mtu ;
480
484
break ;
485
+ case ProxyType::Hysteria:
486
+ singleproxy[" type" ] = " hysteria" ;
487
+ if (!x.Ports .empty ())
488
+ singleproxy[" ports" ] = x.Ports ;
489
+ if (!x.Protocol .empty ())
490
+ singleproxy[" protocol" ] = x.Protocol ;
491
+ if (!x.OBFSParam .empty ())
492
+ singleproxy[" obfs-protocol" ] = x.OBFSParam ;
493
+ if (!x.Up .empty ())
494
+ singleproxy[" up" ] = x.Up ;
495
+ if (x.UpSpeed )
496
+ singleproxy[" up-speed" ] = x.UpSpeed ;
497
+ if (!x.Down .empty ())
498
+ singleproxy[" down" ] = x.Down ;
499
+ if (x.DownSpeed )
500
+ singleproxy[" down-speed" ] = x.DownSpeed ;
501
+ if (!x.AuthStr .empty ())
502
+ {
503
+ singleproxy[" auth-str" ] = x.AuthStr ;
504
+ singleproxy[" auth" ] = base64Encode (x.AuthStr );
505
+ }
506
+ if (!x.OBFS .empty ())
507
+ singleproxy[" obfs" ] = x.OBFS ;
508
+ if (!x.SNI .empty ())
509
+ singleproxy[" sni" ] = x.SNI ;
510
+ if (!scv.is_undef ())
511
+ singleproxy[" skip-cert-verify" ] = scv.get ();
512
+ if (!x.Fingerprint .empty ())
513
+ singleproxy[" fingerprint" ] = x.Fingerprint ;
514
+ if (!x.Alpn .empty ())
515
+ singleproxy[" alpn" ] = x.Alpn ;
516
+ if (!x.Ca .empty ())
517
+ singleproxy[" ca" ] = x.Ca ;
518
+ if (!x.CaStr .empty ())
519
+ singleproxy[" ca-str" ] = x.CaStr ;
520
+ if (x.RecvWindowConn )
521
+ singleproxy[" recv-window-conn" ] = x.RecvWindowConn ;
522
+ if (x.RecvWindow )
523
+ singleproxy[" recv-window" ] = x.RecvWindow ;
524
+ if (!x.DisableMtuDiscovery .is_undef ())
525
+ singleproxy[" disable-mtu-discovery" ] = x.DisableMtuDiscovery .get ();
526
+ if (!x.TCPFastOpen .is_undef ())
527
+ singleproxy[" fast-open" ] = x.TCPFastOpen .get ();
528
+ if (x.HopInterval )
529
+ singleproxy[" hop-interval" ] = x.HopInterval ;
530
+ break ;
531
+ case ProxyType::Hysteria2:
532
+ singleproxy[" type" ] = " hysteria2" ;
533
+ if (!x.Up .empty ())
534
+ singleproxy[" up" ] = x.UpSpeed ;
535
+ if (!x.Down .empty ())
536
+ singleproxy[" down" ] = x.DownSpeed ;
537
+ if (!x.Password .empty ())
538
+ singleproxy[" password" ] = x.Password ;
539
+ if (!x.OBFS .empty ())
540
+ singleproxy[" obfs" ] = x.OBFS ;
541
+ if (!x.OBFSParam .empty ())
542
+ singleproxy[" obfs-password" ] = x.OBFSParam ;
543
+ if (!x.SNI .empty ())
544
+ singleproxy[" sni" ] = x.SNI ;
545
+ if (!scv.is_undef ())
546
+ singleproxy[" skip-cert-verify" ] = scv.get ();
547
+ if (!x.Alpn .empty ())
548
+ singleproxy[" alpn" ] = x.Alpn ;
549
+ if (!x.Ca .empty ())
550
+ singleproxy[" ca" ] = x.Ca ;
551
+ if (!x.CaStr .empty ())
552
+ singleproxy[" ca-str" ] = x.CaStr ;
553
+ if (x.CWND )
554
+ singleproxy[" cwnd" ] = x.CWND ;
555
+ break ;
481
556
default :
482
557
continue ;
483
558
}
@@ -860,6 +935,20 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
860
935
ini.set (real_section, " keepalive" , std::to_string (x.KeepAlive ));
861
936
ini.set (real_section, " peer" , " (" + generatePeer (x) + " )" );
862
937
break ;
938
+ case ProxyType::Hysteria2:
939
+ if (surge_ver < 4 )
940
+ continue ;
941
+ proxy = " hysteria, " + hostname + " , " + port + " , password=" + password;
942
+ if (x.DownSpeed )
943
+ proxy += " , download-bandwidth=" + x.DownSpeed ;
944
+
945
+ if (!scv.is_undef ())
946
+ proxy += " ,skip-cert-verify=" + std::string (scv.get () ? " true" : " false" );
947
+ if (!x.Fingerprint .empty ())
948
+ proxy += " ,server-cert-fingerprint-sha256=" + x.Fingerprint ;
949
+ if (!x.SNI .empty ())
950
+ proxy += " ,sni=" + x.SNI ;
951
+ break ;
863
952
default :
864
953
continue ;
865
954
}
@@ -2168,7 +2257,6 @@ void proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::v
2168
2257
udp.define (x.UDP );
2169
2258
tfo.define (x.TCPFastOpen );
2170
2259
scv.define (x.AllowInsecure );
2171
-
2172
2260
rapidjson::Value proxy (rapidjson::kObjectType );
2173
2261
switch (x.Type )
2174
2262
{
@@ -2255,6 +2343,92 @@ void proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::v
2255
2343
proxy.AddMember (" mtu" , x.Mtu , allocator);
2256
2344
break ;
2257
2345
}
2346
+ case ProxyType::Hysteria:
2347
+ {
2348
+ addSingBoxCommonMembers (proxy, x, " hysteria" , allocator);
2349
+ if (!x.Up .empty ())
2350
+ proxy.AddMember (" up_mbps" , x.UpSpeed , allocator);
2351
+ if (!x.Down .empty ())
2352
+ proxy.AddMember (" down_mbps" , x.DownSpeed , allocator);
2353
+ if (!x.OBFS .empty ())
2354
+ {
2355
+ proxy.AddMember (" obfs" , rapidjson::StringRef (x.OBFS .c_str ()), allocator);
2356
+ }
2357
+
2358
+ if (!x.AuthStr .empty ())
2359
+ {
2360
+ proxy.AddMember (" auth_str" , rapidjson::StringRef (x.AuthStr .c_str ()), allocator);
2361
+ rapidjson::Value auth_str;
2362
+ auth_str.SetString (base64Encode (x.AuthStr ).c_str (), allocator);
2363
+ proxy.AddMember (" auth" , auth_str, allocator);
2364
+ }
2365
+ if (x.RecvWindowConn )
2366
+ proxy.AddMember (" recv_window_conn" , x.RecvWindowConn , allocator);
2367
+ if (x.RecvWindow )
2368
+ proxy.AddMember (" recv_window" , x.RecvWindow , allocator);
2369
+ if (!x.DisableMtuDiscovery .is_undef ())
2370
+ proxy.AddMember (" disable_mtu_discovery" , x.DisableMtuDiscovery .get (), allocator);
2371
+
2372
+ rapidjson::Value tls (rapidjson::kObjectType );
2373
+ tls.AddMember (" enabled" , true , allocator);
2374
+ if (!scv.is_undef ())
2375
+ tls.AddMember (" insecure" , scv.get (), allocator);
2376
+ if (!x.Alpn .empty ())
2377
+ {
2378
+ rapidjson::Value alpn (rapidjson::kArrayType );
2379
+ alpn.PushBack (rapidjson::StringRef (x.Alpn [0 ].c_str ()), allocator);
2380
+ tls.AddMember (" alpn" , alpn, allocator);
2381
+ }
2382
+ if (!x.Ca .empty ())
2383
+ {
2384
+ rapidjson::Value ca_str;
2385
+ ca_str.SetString (x.Ca .c_str (), allocator);
2386
+ tls.AddMember (" certificate" , ca_str, allocator);
2387
+ }
2388
+ if (!x.CaStr .empty ())
2389
+ tls.AddMember (" certificate" , rapidjson::StringRef (x.CaStr .c_str ()), allocator);
2390
+ proxy.AddMember (" tls" , tls, allocator);
2391
+ break ;
2392
+ }
2393
+ case ProxyType::Hysteria2:
2394
+ {
2395
+ addSingBoxCommonMembers (proxy, x, " hysteria2" , allocator);
2396
+ if (!x.Up .empty ())
2397
+ proxy.AddMember (" up_mbps" , x.UpSpeed , allocator);
2398
+ if (!x.Down .empty ())
2399
+ proxy.AddMember (" down_mbps" , x.DownSpeed , allocator);
2400
+ if (!x.OBFS .empty ())
2401
+ {
2402
+ rapidjson::Value obfs (rapidjson::kObjectType );
2403
+ obfs.AddMember (" type" , rapidjson::StringRef (x.OBFS .c_str ()), allocator);
2404
+ if (!x.OBFSParam .empty ())
2405
+ obfs.AddMember (" password" , rapidjson::StringRef (x.OBFSParam .c_str ()), allocator);
2406
+ proxy.AddMember (" obfs" , obfs, allocator);
2407
+ }
2408
+ if (!x.Password .empty ())
2409
+ proxy.AddMember (" password" , rapidjson::StringRef (x.Password .c_str ()), allocator);
2410
+
2411
+ rapidjson::Value tls (rapidjson::kObjectType );
2412
+ tls.AddMember (" enabled" , true , allocator);
2413
+ if (!scv.is_undef ())
2414
+ tls.AddMember (" insecure" , scv.get (), allocator);
2415
+ if (!x.Alpn .empty ())
2416
+ {
2417
+ rapidjson::Value alpn (rapidjson::kArrayType );
2418
+ alpn.PushBack (rapidjson::StringRef (x.Alpn [0 ].c_str ()), allocator);
2419
+ tls.AddMember (" alpn" , alpn, allocator);
2420
+ }
2421
+ if (!x.Ca .empty ())
2422
+ {
2423
+ rapidjson::Value ca_str (rapidjson::kStringType );
2424
+ ca_str.SetString (x.Ca .c_str (), allocator);
2425
+ tls.AddMember (" certificate" , ca_str, allocator);
2426
+ }
2427
+ if (!x.CaStr .empty ())
2428
+ tls.AddMember (" certificate" , rapidjson::StringRef (x.CaStr .c_str ()), allocator);
2429
+ proxy.AddMember (" tls" , tls, allocator);
2430
+ break ;
2431
+ }
2258
2432
case ProxyType::HTTP:
2259
2433
case ProxyType::HTTPS:
2260
2434
{
0 commit comments