SingBox.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <?php
  2. namespace App\Components\Protocols;
  3. use App\Components\Client\SingBoxBuildProxy;
  4. use App\Models\User;
  5. use File;
  6. class SingBox
  7. {
  8. function NewSingBox(User $user,$server)
  9. {
  10. $defaultConfig = base_path().'/resources/rules/default.sing-box.json';
  11. $customConfig = base_path().'/resources/rules/custom.sing-box.json';
  12. if (File::exists($customConfig)) {
  13. $configContent = file_get_contents($customConfig);
  14. $config = json_decode($configContent, true);
  15. } else {
  16. $configContent = file_get_contents($defaultConfig);
  17. $config = json_decode($configContent, true);
  18. }
  19. $outbounds = $config['outbounds'];
  20. $proxies = [];
  21. foreach ($server as $item) {
  22. if ($item['type'] === 'shadowsocks') {
  23. $ssConfig = SingBoxBuildProxy::buildShadowsocks( $item);
  24. $proxies[] = $ssConfig;
  25. }
  26. if ($item['type'] === 'trojan') {
  27. $trojanConfig = SingBoxBuildProxy::buildTrojan($item);
  28. $proxies[] = $trojanConfig;
  29. }
  30. if ($item['type'] === 'v2ray') {
  31. if ($item['vless'] == 1){
  32. $vlessConfig = SingBoxBuildProxy::buildVless($item);
  33. $proxies[] = $vlessConfig;
  34. } else {
  35. $vmess = SingBoxBuildProxy::buildVmess($item);
  36. $proxies[] = $vmess;
  37. }
  38. }
  39. }
  40. return $this->updateConfigWithProxies($user,$config, $proxies);
  41. }
  42. function updateConfigWithProxies(User $user,$config, $proxies) {
  43. $uri = "到期时间:{$user->expired_at}";
  44. // 定义地区及其对应的正则表达式
  45. $regions = [
  46. "hk" => '/香港/',
  47. "us" => '/美国/',
  48. "tw" => '/台湾/',
  49. "jp" => '/日本/',
  50. ];
  51. $usedTags = [];
  52. $regionTags = [];
  53. // $upload = flowAutoShow($user->u);
  54. // $download = flowAutoShow($user->d);
  55. // $totalTraffic = flowAutoShow($user->transfer_enable);
  56. $userConfig= [
  57. 'tag' => $uri,
  58. 'type' => 'shadowsocks',
  59. 'server' => "dudu02.ddnsguru.com",
  60. 'server_port' => 13223,
  61. 'password' => "2yYbPmksa221233",
  62. 'method' => "aes-128-gcm",
  63. ];
  64. // 先创建 "proxy" 组并添加到配置的最前面
  65. $proxyOutbound = $this->buildOutbound("proxy", "selector", "", []);
  66. array_unshift($config['outbounds'], $proxyOutbound);
  67. // 创建每个地区的代理组
  68. // foreach ($regions as $regionTag => $pattern) {
  69. // $tags = $this->buildTags($proxies, $pattern);
  70. // $this->updateOrAddOutbound($config['outbounds'], $this->buildOutbound($regionTag, "selector", "", $tags));
  71. // $usedTags = array_merge($usedTags, $tags);
  72. // $regionTags[] = $regionTag;
  73. // }
  74. // 创建 "其他" 代理组
  75. // $allTags = array_column($proxies, 'tag');
  76. // $otherTags = array_diff($allTags, $usedTags);
  77. // $this->updateOrAddOutbound($config['outbounds'], $this->buildOutbound("other", "selector", "", $otherTags));
  78. // $regionTags[] = "other";
  79. // $this->updateOrAddOutbound($config['outbounds'],$this->buildOutbound("dns", "selector", "", $this->buildTags($proxies,"")));
  80. // $this->updateOrAddOutbound($config['outbounds'],$this->buildOutbound("用户中心", "selector", "", [$uri]));
  81. $this->updateOrAddOutbound($config['outbounds'], $userConfig);
  82. foreach ($proxies as $proxy){
  83. $regionTags[] = $proxy["tag"];
  84. }
  85. $usedCus = array_merge($regionTags, [$uri]);
  86. // // 更新 "proxy" 组,包含所有地区和其他代理组的 tag
  87. $config['outbounds'][0]['outbounds'] = $usedCus;
  88. //$config['outbounds'][0]['outbounds'] = ;
  89. // 将所有 $proxies 加入到 $config['outbounds']
  90. foreach ($proxies as $proxy) {
  91. $this->updateOrAddOutbound($config['outbounds'], $proxy);
  92. }
  93. // 返回更新后的配置 JSON 字符串
  94. return json_encode($config, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
  95. }
  96. function buildOutbound($tag, $type, $default, $outbounds) {
  97. if ($type === "urltest")
  98. {
  99. return [
  100. "tag" => $tag,
  101. "type" => $type,
  102. "outbounds" => array_values($outbounds)
  103. ];
  104. }
  105. return [
  106. "tag" => $tag,
  107. "type" => $type,
  108. "default" => $default ,
  109. "outbounds" => array_values($outbounds)
  110. ];
  111. }
  112. function updateOrAddOutbound(&$outbounds, $newOutbound) {
  113. $found = false;
  114. foreach ($outbounds as &$outbound) {
  115. if ($outbound['tag'] == $newOutbound['tag']) {
  116. $outbound = $newOutbound;
  117. $found = true;
  118. break;
  119. }
  120. }
  121. if (!$found) {
  122. $outbounds[] = $newOutbound;
  123. }
  124. }
  125. function buildTags($proxies, $pattern = '') {
  126. if (empty($pattern)) {
  127. // 如果没有提供正则表达式模式,返回所有代理的 tag 列表
  128. return array_column($proxies, 'tag');
  129. }
  130. // 使用正则表达式筛选代理
  131. $filteredProxies = array_filter($proxies, function($proxy) use ($pattern) {
  132. return preg_match($pattern, $proxy['tag']);
  133. });
  134. // 提取代理的 tag 列表
  135. return array_column($filteredProxies, 'tag');
  136. }
  137. function buildTtype($proxies, $pattern = '') {
  138. if (empty($pattern)) {
  139. // 如果没有提供正则表达式模式,返回所有代理的 tag 列表
  140. return array_column($proxies, 'type');
  141. }
  142. // 使用正则表达式筛选代理
  143. $filteredProxies = array_filter($proxies, function($proxy) use ($pattern) {
  144. return $pattern == $proxy['type'];
  145. });
  146. // 提取代理的 tag 列表
  147. return array_column($filteredProxies, 'tag');
  148. }
  149. }