| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- <?php
- declare(strict_types=1);
- namespace App\Services\Subscribe;
- use App\Services\Subscribe;
- use function array_merge;
- use function json_decode;
- use function yaml_emit;
- use const YAML_UTF8_ENCODING;
- final class Clash extends Base
- {
- public function getContent($user): string
- {
- $nodes = [];
- $clash_config = $_ENV['Clash_Config'];
- $clash_group_indexes = $_ENV['Clash_Group_Indexes'];
- $clash_group_config = $_ENV['Clash_Group_Config'];
- $nodes_raw = Subscribe::getUserNodes($user);
- foreach ($nodes_raw as $node_raw) {
- $node_custom_config = json_decode($node_raw->custom_config, true);
- switch ((int) $node_raw->sort) {
- case 0:
- $plugin = $node_custom_config['plugin'] ?? '';
- $plugin_option = $node_custom_config['plugin_option'] ?? null;
- // Clash 特定配置
- $udp = $node_custom_config['udp'] ?? true;
- $node = [
- 'name' => $node_raw->name,
- 'type' => 'ss',
- 'server' => $node_raw->server,
- 'port' => (int) $user->port,
- 'password' => $user->passwd,
- 'cipher' => $user->method,
- 'udp' => (bool) $udp,
- 'plugin' => $plugin,
- 'plugin-opts' => $plugin_option,
- ];
- break;
- case 1:
- $ss_2022_port = $node_custom_config['offset_port_user'] ??
- ($node_custom_config['offset_port_node'] ?? 443);
- $method = $node_custom_config['method'] ?? '2022-blake3-aes-128-gcm';
- $pk_len = match ($method) {
- '2022-blake3-aes-128-gcm' => 16,
- default => 32,
- };
- $user_pk = $user->getSs2022Pk($pk_len);
- // Clash 特定配置
- $udp = $node_custom_config['udp'] ?? true;
- $node = [
- 'name' => $node_raw->name,
- 'type' => 'ss',
- 'server' => $node_raw->server,
- 'port' => (int) $ss_2022_port,
- 'password' => $user_pk,
- 'cipher' => $method,
- 'udp' => (bool) $udp,
- ];
- break;
- case 2:
- $tuic_port = $node_custom_config['offset_port_user'] ??
- ($node_custom_config['offset_port_node'] ?? 443);
- $host = $node_custom_config['host'] ?? '';
- $congestion_control = $node_custom_config['congestion_control'] ?? 'bbr';
- // Only Clash.Meta core has TUIC support
- // Tuic V5 Only
- $node = [
- 'name' => $node_raw->name,
- 'type' => 'tuic',
- 'server' => $node_raw->server,
- 'port' => (int) $tuic_port,
- 'password' => $user->passwd,
- 'uuid' => $user->uuid,
- 'sni' => $host,
- 'congestion-controller' => $congestion_control,
- 'reduce-rtt' => true,
- ];
- break;
- case 11:
- $v2_port = $node_custom_config['offset_port_user'] ??
- ($node_custom_config['offset_port_node'] ?? 443);
- $security = $node_custom_config['security'] ?? 'none';
- $encryption = $node_custom_config['encryption'] ?? 'auto';
- $network = $node_custom_config['network'] ?? '';
- $host = $node_custom_config['header']['request']['headers']['Host'][0] ??
- $node_custom_config['host'] ?? '';
- $allow_insecure = $node_custom_config['allow_insecure'] ?? false;
- $tls = $security === 'tls';
- // Clash 特定配置
- $udp = $node_custom_config['udp'] ?? true;
- $ws_opts = $node_custom_config['ws-opts'] ?? $node_custom_config['ws_opts'] ?? null;
- $h2_opts = $node_custom_config['h2-opts'] ?? $node_custom_config['h2_opts'] ?? null;
- $http_opts = $node_custom_config['http-opts'] ?? $node_custom_config['http_opts'] ?? null;
- $grpc_opts = $node_custom_config['grpc-opts'] ?? $node_custom_config['grpc_opts'] ?? null;
- // HTTPUpgrade 在 Clash.Meta 内核中属于 ws 类型
- if ($network === 'httpupgrade') {
- $network = 'ws';
- }
- $node = [
- 'name' => $node_raw->name,
- 'type' => 'vmess',
- 'server' => $node_raw->server,
- 'port' => (int) $v2_port,
- 'uuid' => $user->uuid,
- 'alterId' => 0,
- 'cipher' => $encryption,
- 'udp' => (bool) $udp,
- 'tls' => $tls,
- 'skip-cert-verify' => (bool) $allow_insecure,
- 'servername' => $host,
- 'network' => $network,
- 'ws-opts' => $ws_opts,
- 'h2-opts' => $h2_opts,
- 'http-opts' => $http_opts,
- 'grpc-opts' => $grpc_opts,
- ];
- break;
- case 14:
- $trojan_port = $node_custom_config['offset_port_user'] ??
- ($node_custom_config['offset_port_node'] ?? 443);
- $network = $node_custom_config['header']['type'] ?? $node_custom_config['network'] ?? 'tcp';
- $host = $node_custom_config['host'] ?? '';
- $allow_insecure = $node_custom_config['allow_insecure'] ?? false;
- // Clash 特定配置
- $udp = $node_custom_config['udp'] ?? true;
- $ws_opts = $node_custom_config['ws-opts'] ?? $node_custom_config['ws_opts'] ?? null;
- $grpc_opts = $node_custom_config['grpc-opts'] ?? $node_custom_config['grpc_opts'] ?? null;
- // HTTPUpgrade 在 Clash.Meta 内核中属于 ws 类型
- if ($network === 'httpupgrade') {
- $network = 'ws';
- }
- $node = [
- 'name' => $node_raw->name,
- 'type' => 'trojan',
- 'server' => $node_raw->server,
- 'sni' => $host,
- 'port' => (int) $trojan_port,
- 'password' => $user->uuid,
- 'network' => $network,
- 'udp' => (bool) $udp,
- 'skip-cert-verify' => (bool) $allow_insecure,
- 'ws-opts' => $ws_opts,
- 'grpc-opts' => $grpc_opts,
- ];
- break;
- default:
- $node = [];
- break;
- }
- if ($node === []) {
- continue;
- }
- $nodes[] = $node;
- foreach ($clash_group_indexes as $index) {
- $clash_group_config['proxy-groups'][$index]['proxies'][] = $node_raw->name;
- }
- }
- $clash_nodes = [
- 'proxies' => $nodes,
- ];
- return yaml_emit(
- array_merge($clash_config, $clash_nodes, $clash_group_config),
- YAML_UTF8_ENCODING
- );
- }
- }
|