|
@@ -0,0 +1,178 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Components\Protocols;
|
|
|
+
|
|
|
+use App\Components\Client\SingBoxBuildProxy;
|
|
|
+use App\Models\User;
|
|
|
+use File;
|
|
|
+
|
|
|
+class SingBox
|
|
|
+{
|
|
|
+ function NewSingBox(User $user,$server)
|
|
|
+ {
|
|
|
+ $defaultConfig = base_path().'/resources/rules/default.sing-box.json';
|
|
|
+ $customConfig = base_path().'/resources/rules/custom.sing-box.json';
|
|
|
+
|
|
|
+ if (File::exists($customConfig)) {
|
|
|
+ $configContent = file_get_contents($customConfig);
|
|
|
+ $config = json_decode($configContent, true);
|
|
|
+ } else {
|
|
|
+ $configContent = file_get_contents($defaultConfig);
|
|
|
+ $config = json_decode($configContent, true);
|
|
|
+ }
|
|
|
+ $outbounds = $config['outbounds'];
|
|
|
+ $proxies = [];
|
|
|
+ foreach ($server as $item) {
|
|
|
+ if ($item['type'] === 'shadowsocks') {
|
|
|
+ $ssConfig = SingBoxBuildProxy::buildShadowsocks( $item);
|
|
|
+ $proxies[] = $ssConfig;
|
|
|
+ }
|
|
|
+ if ($item['type'] === 'trojan') {
|
|
|
+ $trojanConfig = SingBoxBuildProxy::buildTrojan($item);
|
|
|
+ $proxies[] = $trojanConfig;
|
|
|
+ }
|
|
|
+ if ($item['type'] === 'v2ray') {
|
|
|
+ if ($item['vless'] == 1){
|
|
|
+ $vlessConfig = SingBoxBuildProxy::buildVless($item);
|
|
|
+ $proxies[] = $vlessConfig;
|
|
|
+ } else {
|
|
|
+ $vmess = SingBoxBuildProxy::buildVmess($item);
|
|
|
+ $proxies[] = $vmess;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ return $this->updateConfigWithProxies($user,$config, $proxies);
|
|
|
+ }
|
|
|
+
|
|
|
+ function updateConfigWithProxies(User $user,$config, $proxies) {
|
|
|
+
|
|
|
+ $uri = "到期时间:{$user->expired_at}";
|
|
|
+ // 定义地区及其对应的正则表达式
|
|
|
+ $regions = [
|
|
|
+ "hk" => '/香港/',
|
|
|
+ "us" => '/美国/',
|
|
|
+ "tw" => '/台湾/',
|
|
|
+ "jp" => '/日本/',
|
|
|
+
|
|
|
+ ];
|
|
|
+
|
|
|
+ $usedTags = [];
|
|
|
+ $regionTags = [];
|
|
|
+
|
|
|
+// $upload = flowAutoShow($user->u);
|
|
|
+// $download = flowAutoShow($user->d);
|
|
|
+// $totalTraffic = flowAutoShow($user->transfer_enable);
|
|
|
+
|
|
|
+ $userConfig= [
|
|
|
+ 'tag' => $uri,
|
|
|
+ 'type' => 'shadowsocks',
|
|
|
+ 'server' => "dudu02.ddnsguru.com",
|
|
|
+ 'server_port' => 13223,
|
|
|
+ 'password' => "2yYbPmksa221233",
|
|
|
+ 'method' => "aes-128-gcm",
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 先创建 "proxy" 组并添加到配置的最前面
|
|
|
+ $proxyOutbound = $this->buildOutbound("proxy", "selector", "hk", []);
|
|
|
+ array_unshift($config['outbounds'], $proxyOutbound);
|
|
|
+
|
|
|
+ // 创建每个地区的代理组
|
|
|
+ foreach ($regions as $regionTag => $pattern) {
|
|
|
+ $tags = $this->buildTags($proxies, $pattern);
|
|
|
+ $this->updateOrAddOutbound($config['outbounds'], $this->buildOutbound($regionTag, "selector", "", $tags));
|
|
|
+ $usedTags = array_merge($usedTags, $tags);
|
|
|
+ $regionTags[] = $regionTag;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建 "其他" 代理组
|
|
|
+ $allTags = array_column($proxies, 'tag');
|
|
|
+ $otherTags = array_diff($allTags, $usedTags);
|
|
|
+ $this->updateOrAddOutbound($config['outbounds'], $this->buildOutbound("other", "selector", "", $otherTags));
|
|
|
+ $regionTags[] = "other";
|
|
|
+ $this->updateOrAddOutbound($config['outbounds'],$this->buildOutbound("dns", "selector", "", $this->buildTags($proxies,"")));
|
|
|
+
|
|
|
+// $this->updateOrAddOutbound($config['outbounds'],$this->buildOutbound("用户中心", "selector", "", [$uri]));
|
|
|
+ $this->updateOrAddOutbound($config['outbounds'], $userConfig);
|
|
|
+
|
|
|
+ $usedCus = array_merge($regionTags, [$uri]);
|
|
|
+ // 更新 "proxy" 组,包含所有地区和其他代理组的 tag
|
|
|
+ $config['outbounds'][0]['outbounds'] = $usedCus;
|
|
|
+ //$config['outbounds'][0]['outbounds'] = ;
|
|
|
+ // 将所有 $proxies 加入到 $config['outbounds']
|
|
|
+ foreach ($proxies as $proxy) {
|
|
|
+ $this->updateOrAddOutbound($config['outbounds'], $proxy);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // 返回更新后的配置 JSON 字符串
|
|
|
+ return json_encode($config, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ function buildOutbound($tag, $type, $default, $outbounds) {
|
|
|
+ if ($type === "urltest")
|
|
|
+ {
|
|
|
+ return [
|
|
|
+ "tag" => $tag,
|
|
|
+ "type" => $type,
|
|
|
+ "outbounds" => array_values($outbounds)
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ return [
|
|
|
+ "tag" => $tag,
|
|
|
+ "type" => $type,
|
|
|
+ "default" => $default ,
|
|
|
+ "outbounds" => array_values($outbounds)
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ function updateOrAddOutbound(&$outbounds, $newOutbound) {
|
|
|
+ $found = false;
|
|
|
+ foreach ($outbounds as &$outbound) {
|
|
|
+ if ($outbound['tag'] == $newOutbound['tag']) {
|
|
|
+ $outbound = $newOutbound;
|
|
|
+ $found = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!$found) {
|
|
|
+ $outbounds[] = $newOutbound;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function buildTags($proxies, $pattern = '') {
|
|
|
+ if (empty($pattern)) {
|
|
|
+ // 如果没有提供正则表达式模式,返回所有代理的 tag 列表
|
|
|
+ return array_column($proxies, 'tag');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 使用正则表达式筛选代理
|
|
|
+ $filteredProxies = array_filter($proxies, function($proxy) use ($pattern) {
|
|
|
+ return preg_match($pattern, $proxy['tag']);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 提取代理的 tag 列表
|
|
|
+ return array_column($filteredProxies, 'tag');
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ function buildTtype($proxies, $pattern = '') {
|
|
|
+ if (empty($pattern)) {
|
|
|
+ // 如果没有提供正则表达式模式,返回所有代理的 tag 列表
|
|
|
+ return array_column($proxies, 'type');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 使用正则表达式筛选代理
|
|
|
+ $filteredProxies = array_filter($proxies, function($proxy) use ($pattern) {
|
|
|
+ return $pattern == $proxy['type'];
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ // 提取代理的 tag 列表
|
|
|
+ return array_column($filteredProxies, 'tag');
|
|
|
+ }
|
|
|
+
|
|
|
+}
|