mirror of
				https://github.com/v2board/v2board.git
				synced 2025-10-31 17:31:49 +08:00 
			
		
		
		
	update: code
This commit is contained in:
		| @@ -4,15 +4,7 @@ namespace App\Http\Controllers\Client; | ||||
|  | ||||
| use App\Http\Controllers\Controller; | ||||
| use App\Services\ServerService; | ||||
| use App\Utils\Clash; | ||||
| use App\Utils\Origin; | ||||
| use App\Utils\QuantumultX; | ||||
| use App\Utils\Shadowrocket; | ||||
| use App\Utils\Shadowsocks; | ||||
| use App\Utils\Surge; | ||||
| use App\Utils\Surfboard; | ||||
| use Illuminate\Http\Request; | ||||
| use Symfony\Component\Yaml\Yaml; | ||||
| use App\Services\UserService; | ||||
|  | ||||
| class ClientController extends Controller | ||||
| @@ -31,227 +23,15 @@ class ClientController extends Controller | ||||
|             $serverService = new ServerService(); | ||||
|             $servers = $serverService->getAvailableServers($user); | ||||
|             if ($flag) { | ||||
|                 if (strpos($flag, 'quantumult%20x') !== false) { | ||||
|                     die($this->quantumultX($user, $servers)); | ||||
|                 } | ||||
|                 if (strpos($flag, 'clash') !== false) { | ||||
|                     die($this->clash($user, $servers)); | ||||
|                 } | ||||
|                 if (strpos($flag, 'surfboard') !== false) { | ||||
|                     die($this->surfboard($user, $servers)); | ||||
|                 } | ||||
|                 if (strpos($flag, 'surge') !== false) { | ||||
|                     die($this->surge($user, $servers)); | ||||
|                 } | ||||
|                 if (strpos($flag, 'shadowrocket') !== false) { | ||||
|                     die($this->shadowrocket($user, $servers)); | ||||
|                 } | ||||
|                 if (strpos($flag, 'shadowsocks') !== false) { | ||||
|                     die($this->shaodowsocksSIP008($user, $servers)); | ||||
|                 foreach (glob(app_path('Http//Controllers//Client//Protocols') . '/*.php') as $file) { | ||||
|                     $file = 'App\\Http\\Controllers\\Client\\Protocols\\' . basename($file, '.php'); | ||||
|                     $class = new $file($user, $servers); | ||||
|                     if (strpos($flag, $class->flag) !== false) { | ||||
|                         die($class->handle()); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             die('该客户端暂不支持进行订阅'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private function origin($user, $servers = []) | ||||
|     { | ||||
|         $uri = ''; | ||||
|         foreach ($servers as $item) { | ||||
|             if ($item['type'] === 'shadowsocks') { | ||||
|                 $uri .= Origin::buildShadowsocks($item, $user); | ||||
|             } | ||||
|             if ($item['type'] === 'v2ray') { | ||||
|                 $uri .= Origin::buildVmess($item, $user); | ||||
|             } | ||||
|             if ($item['type'] === 'trojan') { | ||||
|                 $uri .= Origin::buildTrojan($item, $user); | ||||
|             } | ||||
|         } | ||||
|         return base64_encode($uri); | ||||
|     } | ||||
|  | ||||
|     private function shadowrocket($user, $servers = []) | ||||
|     { | ||||
|         $uri = ''; | ||||
|         //display remaining traffic and expire date | ||||
|         $upload = round($user['u'] / (1024*1024*1024), 2); | ||||
|         $download = round($user['d'] / (1024*1024*1024), 2); | ||||
|         $totalTraffic = round($user['transfer_enable'] / (1024*1024*1024), 2); | ||||
|         $expiredDate = date('Y-m-d', $user['expired_at']); | ||||
|         $uri .= "STATUS=🚀↑:{$upload}GB,↓:{$download}GB,TOT:{$totalTraffic}GB💡Expires:{$expiredDate}\r\n"; | ||||
|         foreach ($servers as $item) { | ||||
|             if ($item['type'] === 'shadowsocks') { | ||||
|                 $uri .= Shadowrocket::buildShadowsocks($user['uuid'], $item); | ||||
|             } | ||||
|             if ($item['type'] === 'v2ray') { | ||||
|                 $uri .= Shadowrocket::buildVmess($user['uuid'], $item); | ||||
|             } | ||||
|             if ($item['type'] === 'trojan') { | ||||
|                 $uri .= Shadowrocket::buildTrojan($user['uuid'], $item); | ||||
|             } | ||||
|         } | ||||
|         return base64_encode($uri); | ||||
|     } | ||||
|  | ||||
|     private function quantumultX($user, $servers = []) | ||||
|     { | ||||
|         $uri = ''; | ||||
|         header("subscription-userinfo: upload={$user['u']}; download={$user['d']}; total={$user['transfer_enable']}; expire={$user['expired_at']}"); | ||||
|         foreach ($servers as $item) { | ||||
|             if ($item['type'] === 'shadowsocks') { | ||||
|                 $uri .= QuantumultX::buildShadowsocks($user['uuid'], $item); | ||||
|             } | ||||
|             if ($item['type'] === 'v2ray') { | ||||
|                 $uri .= QuantumultX::buildVmess($user['uuid'], $item); | ||||
|             } | ||||
|             if ($item['type'] === 'trojan') { | ||||
|                 $uri .= QuantumultX::buildTrojan($user['uuid'], $item); | ||||
|             } | ||||
|         } | ||||
|         return base64_encode($uri); | ||||
|     } | ||||
|  | ||||
|     private function shaodowsocksSIP008($user, $servers = []) | ||||
|     { | ||||
|         $configs = []; | ||||
|         $subs = []; | ||||
|         $subs['servers'] = []; | ||||
|         $subs['bytes_used'] = ''; | ||||
|         $subs['bytes_remaining'] = ''; | ||||
|  | ||||
|         $bytesUsed = $user['u'] + $user['d']; | ||||
|         $bytesRemaining = $user['transfer_enable'] - $bytesUsed; | ||||
|  | ||||
|         foreach ($servers as $item) { | ||||
|             if ($item['type'] === 'shadowsocks') { | ||||
|                 array_push($configs, Shadowsocks::SIP008($item, $user)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $subs['version'] = 1; | ||||
|         $subs['bytes_used'] = $bytesUsed; | ||||
|         $subs['bytes_remaining'] = $bytesRemaining; | ||||
|         $subs['servers'] = array_merge($subs['servers'] ? $subs['servers'] : [], $configs); | ||||
|  | ||||
|         return json_encode($subs, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT); | ||||
|     } | ||||
|  | ||||
|     private function surge($user, $servers = []) | ||||
|     { | ||||
|         $proxies = ''; | ||||
|         $proxyGroup = ''; | ||||
|  | ||||
|         foreach ($servers as $item) { | ||||
|             if ($item['type'] === 'shadowsocks') { | ||||
|                 // [Proxy] | ||||
|                 $proxies .= Surge::buildShadowsocks($user['uuid'], $item); | ||||
|                 // [Proxy Group] | ||||
|                 $proxyGroup .= $item['name'] . ', '; | ||||
|             } | ||||
|             if ($item['type'] === 'v2ray') { | ||||
|                 // [Proxy] | ||||
|                 $proxies .= Surge::buildVmess($user['uuid'], $item); | ||||
|                 // [Proxy Group] | ||||
|                 $proxyGroup .= $item['name'] . ', '; | ||||
|             } | ||||
|             if ($item['type'] === 'trojan') { | ||||
|                 // [Proxy] | ||||
|                 $proxies .= Surge::buildTrojan($user['uuid'], $item); | ||||
|                 // [Proxy Group] | ||||
|                 $proxyGroup .= $item['name'] . ', '; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $defaultConfig = base_path() . '/resources/rules/default.surge.conf'; | ||||
|         $customConfig = base_path() . '/resources/rules/custom.surge.conf'; | ||||
|         if (\File::exists($customConfig)) { | ||||
|             $config = file_get_contents("$customConfig"); | ||||
|         } else { | ||||
|             $config = file_get_contents("$defaultConfig"); | ||||
|         } | ||||
|  | ||||
|         // Subscription link | ||||
|         $subsURL = config('v2board.subscribe_url', config('v2board.app_url', env('APP_URL'))) . '/api/v1/client/subscribe?token=' . $user['token']; | ||||
|  | ||||
|         $config = str_replace('$subs_link', $subsURL, $config); | ||||
|         $config = str_replace('$proxies', $proxies, $config); | ||||
|         $config = str_replace('$proxy_group', rtrim($proxyGroup, ', '), $config); | ||||
|         return $config; | ||||
|     } | ||||
|  | ||||
|     private function surfboard($user, $servers = []) | ||||
|     { | ||||
|         $proxies = ''; | ||||
|         $proxyGroup = ''; | ||||
|  | ||||
|         foreach ($servers as $item) { | ||||
|             if ($item['type'] === 'shadowsocks') { | ||||
|                 // [Proxy] | ||||
|                 $proxies .= Surfboard::buildShadowsocks($user['uuid'], $item); | ||||
|                 // [Proxy Group] | ||||
|                 $proxyGroup .= $item['name'] . ', '; | ||||
|             } | ||||
|             if ($item['type'] === 'v2ray') { | ||||
|                 // [Proxy] | ||||
|                 $proxies .= Surfboard::buildVmess($user['uuid'], $item); | ||||
|                 // [Proxy Group] | ||||
|                 $proxyGroup .= $item['name'] . ', '; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $defaultConfig = base_path() . '/resources/rules/default.surfboard.conf'; | ||||
|         $customConfig = base_path() . '/resources/rules/custom.surfboard.conf'; | ||||
|         if (\File::exists($customConfig)) { | ||||
|             $config = file_get_contents("$customConfig"); | ||||
|         } else { | ||||
|             $config = file_get_contents("$defaultConfig"); | ||||
|         } | ||||
|  | ||||
|         // Subscription link | ||||
|         $subsURL = config('v2board.subscribe_url', config('v2board.app_url', env('APP_URL'))) . '/api/v1/client/subscribe?token=' . $user['token']; | ||||
|  | ||||
|         $config = str_replace('$subs_link', $subsURL, $config); | ||||
|         $config = str_replace('$proxies', $proxies, $config); | ||||
|         $config = str_replace('$proxy_group', rtrim($proxyGroup, ', '), $config); | ||||
|         return $config; | ||||
|     } | ||||
|  | ||||
|     private function clash($user, $servers = []) | ||||
|     { | ||||
|         header("subscription-userinfo: upload={$user['u']}; download={$user['d']}; total={$user['transfer_enable']}; expire={$user['expired_at']}"); | ||||
|         $defaultConfig = base_path() . '/resources/rules/default.clash.yaml'; | ||||
|         $customConfig = base_path() . '/resources/rules/custom.clash.yaml'; | ||||
|         if (\File::exists($customConfig)) { | ||||
|             $config = Yaml::parseFile($customConfig); | ||||
|         } else { | ||||
|             $config = Yaml::parseFile($defaultConfig); | ||||
|         } | ||||
|         $proxy = []; | ||||
|         $proxies = []; | ||||
|  | ||||
|         foreach ($servers as $item) { | ||||
|             if ($item['type'] === 'shadowsocks') { | ||||
|                 array_push($proxy, Clash::buildShadowsocks($user['uuid'], $item)); | ||||
|                 array_push($proxies, $item['name']); | ||||
|             } | ||||
|             if ($item['type'] === 'v2ray') { | ||||
|                 array_push($proxy, Clash::buildVmess($user['uuid'], $item)); | ||||
|                 array_push($proxies, $item['name']); | ||||
|             } | ||||
|             if ($item['type'] === 'trojan') { | ||||
|                 array_push($proxy, Clash::buildTrojan($user['uuid'], $item)); | ||||
|                 array_push($proxies, $item['name']); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $config['proxies'] = array_merge($config['proxies'] ? $config['proxies'] : [], $proxy); | ||||
|         foreach ($config['proxy-groups'] as $k => $v) { | ||||
|             if (!is_array($config['proxy-groups'][$k]['proxies'])) continue; | ||||
|             $config['proxy-groups'][$k]['proxies'] = array_merge($config['proxy-groups'][$k]['proxies'], $proxies); | ||||
|         } | ||||
|         $yaml = Yaml::dump($config); | ||||
|         $yaml = str_replace('$app_name', config('v2board.app_name', 'V2Board'), $yaml); | ||||
|         return $yaml; | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										129
									
								
								app/Http/Controllers/Client/Protocols/Clash.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								app/Http/Controllers/Client/Protocols/Clash.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Http\Controllers\Client\Protocols; | ||||
|  | ||||
| use Symfony\Component\Yaml\Yaml; | ||||
|  | ||||
| class Clash | ||||
| { | ||||
|     public $flag = 'clash'; | ||||
|     private $servers; | ||||
|     private $user; | ||||
|  | ||||
|     public function __construct($user, $servers) | ||||
|     { | ||||
|         $this->user = $user; | ||||
|         $this->servers = $servers; | ||||
|     } | ||||
|  | ||||
|     public function handle() | ||||
|     { | ||||
|         $servers = $this->servers; | ||||
|         $user = $this->user; | ||||
|         header("subscription-userinfo: upload={$user['u']}; download={$user['d']}; total={$user['transfer_enable']}; expire={$user['expired_at']}"); | ||||
|         $defaultConfig = base_path() . '/resources/rules/default.clash.yaml'; | ||||
|         $customConfig = base_path() . '/resources/rules/custom.clash.yaml'; | ||||
|         if (\File::exists($customConfig)) { | ||||
|             $config = Yaml::parseFile($customConfig); | ||||
|         } else { | ||||
|             $config = Yaml::parseFile($defaultConfig); | ||||
|         } | ||||
|         $proxy = []; | ||||
|         $proxies = []; | ||||
|  | ||||
|         foreach ($servers as $item) { | ||||
|             if ($item['type'] === 'shadowsocks') { | ||||
|                 array_push($proxy, self::buildShadowsocks($user['uuid'], $item)); | ||||
|                 array_push($proxies, $item['name']); | ||||
|             } | ||||
|             if ($item['type'] === 'v2ray') { | ||||
|                 array_push($proxy, self::buildVmess($user['uuid'], $item)); | ||||
|                 array_push($proxies, $item['name']); | ||||
|             } | ||||
|             if ($item['type'] === 'trojan') { | ||||
|                 array_push($proxy, self::buildTrojan($user['uuid'], $item)); | ||||
|                 array_push($proxies, $item['name']); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $config['proxies'] = array_merge($config['proxies'] ? $config['proxies'] : [], $proxy); | ||||
|         foreach ($config['proxy-groups'] as $k => $v) { | ||||
|             if (!is_array($config['proxy-groups'][$k]['proxies'])) continue; | ||||
|             $config['proxy-groups'][$k]['proxies'] = array_merge($config['proxy-groups'][$k]['proxies'], $proxies); | ||||
|         } | ||||
|         $yaml = Yaml::dump($config); | ||||
|         $yaml = str_replace('$app_name', config('v2board.app_name', 'V2Board'), $yaml); | ||||
|         return $yaml; | ||||
|     } | ||||
|  | ||||
|     public static function buildShadowsocks($uuid, $server) | ||||
|     { | ||||
|         $array = []; | ||||
|         $array['name'] = $server['name']; | ||||
|         $array['type'] = 'ss'; | ||||
|         $array['server'] = $server['host']; | ||||
|         $array['port'] = $server['port']; | ||||
|         $array['cipher'] = $server['cipher']; | ||||
|         $array['password'] = $uuid; | ||||
|         $array['udp'] = true; | ||||
|         return $array; | ||||
|     } | ||||
|  | ||||
|     public static function buildVmess($uuid, $server) | ||||
|     { | ||||
|         $array = []; | ||||
|         $array['name'] = $server['name']; | ||||
|         $array['type'] = 'vmess'; | ||||
|         $array['server'] = $server['host']; | ||||
|         $array['port'] = $server['port']; | ||||
|         $array['uuid'] = $uuid; | ||||
|         $array['alterId'] = $server['alter_id']; | ||||
|         $array['cipher'] = 'auto'; | ||||
|         $array['udp'] = true; | ||||
|  | ||||
|         if ($server['tls']) { | ||||
|             $array['tls'] = true; | ||||
|             if ($server['tlsSettings']) { | ||||
|                 $tlsSettings = json_decode($server['tlsSettings'], true); | ||||
|                 if (isset($tlsSettings['allowInsecure']) && !empty($tlsSettings['allowInsecure'])) | ||||
|                     $array['skip-cert-verify'] = ($tlsSettings['allowInsecure'] ? true : false); | ||||
|                 if (isset($tlsSettings['serverName']) && !empty($tlsSettings['serverName'])) | ||||
|                     $array['servername'] = $tlsSettings['serverName']; | ||||
|             } | ||||
|         } | ||||
|         if ($server['network'] === 'ws') { | ||||
|             $array['network'] = 'ws'; | ||||
|             if ($server['networkSettings']) { | ||||
|                 $wsSettings = json_decode($server['networkSettings'], true); | ||||
|                 if (isset($wsSettings['path']) && !empty($wsSettings['path'])) | ||||
|                     $array['ws-path'] = $wsSettings['path']; | ||||
|                 if (isset($wsSettings['headers']['Host']) && !empty($wsSettings['headers']['Host'])) | ||||
|                     $array['ws-headers'] = ['Host' => $wsSettings['headers']['Host']]; | ||||
|             } | ||||
|         } | ||||
|         if ($server['network'] === 'grpc') { | ||||
|             $array['network'] = 'grpc'; | ||||
|             if ($server['networkSettings']) { | ||||
|                 $grpcObject = json_decode($server['networkSettings'], true); | ||||
|                 $array['grpc-opts'] = []; | ||||
|                 $array['grpc-opts']['grpc-service-name'] = $grpcObject['serviceName']; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $array; | ||||
|     } | ||||
|  | ||||
|     public static function buildTrojan($password, $server) | ||||
|     { | ||||
|         $array = []; | ||||
|         $array['name'] = $server['name']; | ||||
|         $array['type'] = 'trojan'; | ||||
|         $array['server'] = $server['host']; | ||||
|         $array['port'] = $server['port']; | ||||
|         $array['password'] = $password; | ||||
|         $array['udp'] = true; | ||||
|         if (!empty($server['server_name'])) $array['sni'] = $server['server_name']; | ||||
|         if (!empty($server['allow_insecure'])) $array['skip-cert-verify'] = ($server['allow_insecure'] ? true : false); | ||||
|         return $array; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										116
									
								
								app/Http/Controllers/Client/Protocols/QuantumultX.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								app/Http/Controllers/Client/Protocols/QuantumultX.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Http\Controllers\Client\Protocols; | ||||
|  | ||||
|  | ||||
| class QuantumultX | ||||
| { | ||||
|     public $flag = 'quantumult x'; | ||||
|     private $servers; | ||||
|     private $user; | ||||
|  | ||||
|     public function __construct($user, $servers) | ||||
|     { | ||||
|         $this->user = $user; | ||||
|         $this->servers = $servers; | ||||
|     } | ||||
|  | ||||
|     public function handle() | ||||
|     { | ||||
|         $servers = $this->servers; | ||||
|         $user = $this->user; | ||||
|         $uri = ''; | ||||
|         header("subscription-userinfo: upload={$user['u']}; download={$user['d']}; total={$user['transfer_enable']}; expire={$user['expired_at']}"); | ||||
|         foreach ($servers as $item) { | ||||
|             if ($item['type'] === 'shadowsocks') { | ||||
|                 $uri .= self::buildShadowsocks($user['uuid'], $item); | ||||
|             } | ||||
|             if ($item['type'] === 'v2ray') { | ||||
|                 $uri .= self::buildVmess($user['uuid'], $item); | ||||
|             } | ||||
|             if ($item['type'] === 'trojan') { | ||||
|                 $uri .= self::buildTrojan($user['uuid'], $item); | ||||
|             } | ||||
|         } | ||||
|         return base64_encode($uri); | ||||
|     } | ||||
|  | ||||
|     public static function buildShadowsocks($password, $server) | ||||
|     { | ||||
|         $config = [ | ||||
|             "shadowsocks={$server['host']}:{$server['port']}", | ||||
|             "method={$server['cipher']}", | ||||
|             "password={$password}", | ||||
|             'fast-open=true', | ||||
|             'udp-relay=true', | ||||
|             "tag={$server['name']}" | ||||
|         ]; | ||||
|         $config = array_filter($config); | ||||
|         $uri = implode(',', $config); | ||||
|         $uri .= "\r\n"; | ||||
|         return $uri; | ||||
|     } | ||||
|  | ||||
|     public static function buildVmess($uuid, $server) | ||||
|     { | ||||
|         $config = [ | ||||
|             "vmess={$server['host']}:{$server['port']}", | ||||
|             'method=chacha20-poly1305', | ||||
|             "password={$uuid}", | ||||
|             'fast-open=true', | ||||
|             'udp-relay=true', | ||||
|             "tag={$server['name']}" | ||||
|         ]; | ||||
|  | ||||
|         if ($server['tls']) { | ||||
|             if ($server['network'] === 'tcp') | ||||
|                 array_push($config, 'obfs=over-tls'); | ||||
|             if ($server['tlsSettings']) { | ||||
|                 $tlsSettings = json_decode($server['tlsSettings'], true); | ||||
|                 if (isset($tlsSettings['allowInsecure']) && !empty($tlsSettings['allowInsecure'])) | ||||
|                     array_push($config, 'tls-verification=' . ($tlsSettings['allowInsecure'] ? 'false' : 'true')); | ||||
|                 if (isset($tlsSettings['serverName']) && !empty($tlsSettings['serverName'])) | ||||
|                     $host = $tlsSettings['serverName']; | ||||
|             } | ||||
|         } | ||||
|         if ($server['network'] === 'ws') { | ||||
|             if ($server['tls']) | ||||
|                 array_push($config, 'obfs=wss'); | ||||
|             else | ||||
|                 array_push($config, 'obfs=ws'); | ||||
|             if ($server['networkSettings']) { | ||||
|                 $wsSettings = json_decode($server['networkSettings'], true); | ||||
|                 if (isset($wsSettings['path']) && !empty($wsSettings['path'])) | ||||
|                     array_push($config, "obfs-uri={$wsSettings['path']}"); | ||||
|                 if (isset($wsSettings['headers']['Host']) && !empty($wsSettings['headers']['Host']) && !isset($host)) | ||||
|                     $host = $wsSettings['headers']['Host']; | ||||
|             } | ||||
|         } | ||||
|         if (isset($host)) { | ||||
|             array_push($config, "obfs-host={$host}"); | ||||
|         } | ||||
|  | ||||
|         $uri = implode(',', $config); | ||||
|         $uri .= "\r\n"; | ||||
|         return $uri; | ||||
|     } | ||||
|  | ||||
|     public static function buildTrojan($password, $server) | ||||
|     { | ||||
|         $config = [ | ||||
|             "trojan={$server['host']}:{$server['port']}", | ||||
|             "password={$password}", | ||||
|             'over-tls=true', | ||||
|             $server['server_name'] ? "tls-host={$server['server_name']}" : "", | ||||
|             // Tips: allowInsecure=false = tls-verification=true | ||||
|             $server['allow_insecure'] ? 'tls-verification=false' : 'tls-verification=true', | ||||
|             'fast-open=true', | ||||
|             'udp-relay=true', | ||||
|             "tag={$server['name']}" | ||||
|         ]; | ||||
|         $config = array_filter($config); | ||||
|         $uri = implode(',', $config); | ||||
|         $uri .= "\r\n"; | ||||
|         return $uri; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										113
									
								
								app/Http/Controllers/Client/Protocols/Shadowrocket.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								app/Http/Controllers/Client/Protocols/Shadowrocket.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Http\Controllers\Client\Protocols; | ||||
|  | ||||
| class Shadowrocket | ||||
| { | ||||
|     public $flag = 'shadowrocket'; | ||||
|     private $servers; | ||||
|     private $user; | ||||
|  | ||||
|     public function __construct($user, $servers) | ||||
|     { | ||||
|         $this->user = $user; | ||||
|         $this->servers = $servers; | ||||
|     } | ||||
|  | ||||
|     public function handle() | ||||
|     { | ||||
|         $servers = $this->servers; | ||||
|         $user = $this->user; | ||||
|  | ||||
|         $uri = ''; | ||||
|         //display remaining traffic and expire date | ||||
|         $upload = round($user['u'] / (1024*1024*1024), 2); | ||||
|         $download = round($user['d'] / (1024*1024*1024), 2); | ||||
|         $totalTraffic = round($user['transfer_enable'] / (1024*1024*1024), 2); | ||||
|         $expiredDate = date('Y-m-d', $user['expired_at']); | ||||
|         $uri .= "STATUS=🚀↑:{$upload}GB,↓:{$download}GB,TOT:{$totalTraffic}GB💡Expires:{$expiredDate}\r\n"; | ||||
|         foreach ($servers as $item) { | ||||
|             if ($item['type'] === 'shadowsocks') { | ||||
|                 $uri .= self::buildShadowsocks($user['uuid'], $item); | ||||
|             } | ||||
|             if ($item['type'] === 'v2ray') { | ||||
|                 $uri .= self::buildVmess($user['uuid'], $item); | ||||
|             } | ||||
|             if ($item['type'] === 'trojan') { | ||||
|                 $uri .= self::buildTrojan($user['uuid'], $item); | ||||
|             } | ||||
|         } | ||||
|         return base64_encode($uri); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public static function buildShadowsocks($password, $server) | ||||
|     { | ||||
|         $name = rawurlencode($server['name']); | ||||
|         $str = str_replace( | ||||
|             ['+', '/', '='], | ||||
|             ['-', '_', ''], | ||||
|             base64_encode("{$server['cipher']}:{$password}") | ||||
|         ); | ||||
|         return "ss://{$str}@{$server['host']}:{$server['port']}#{$name}\r\n"; | ||||
|     } | ||||
|  | ||||
|     public static function buildVmess($uuid, $server) | ||||
|     { | ||||
|         $userinfo = base64_encode('auto:' . $uuid . '@' . $server['host'] . ':' . $server['port']); | ||||
|         $config = [ | ||||
|             'tfo' => 1, | ||||
|             'remark' => $server['name'], | ||||
|             'alterId' => $server['alter_id'] | ||||
|         ]; | ||||
|         if ($server['tls']) { | ||||
|             $config['tls'] = 1; | ||||
|             if ($server['tlsSettings']) { | ||||
|                 $tlsSettings = json_decode($server['tlsSettings'], true); | ||||
|                 if (isset($tlsSettings['allowInsecure']) && !empty($tlsSettings['allowInsecure'])) | ||||
|                     $config['allowInsecure'] = (int)$tlsSettings['allowInsecure']; | ||||
|                 if (isset($tlsSettings['serverName']) && !empty($tlsSettings['serverName'])) | ||||
|                     $config['peer'] = $tlsSettings['serverName']; | ||||
|             } | ||||
|         } | ||||
|         if ($server['network'] === 'ws') { | ||||
|             $config['obfs'] = "websocket"; | ||||
|             if ($server['networkSettings']) { | ||||
|                 $wsSettings = json_decode($server['networkSettings'], true); | ||||
|                 if (isset($wsSettings['path']) && !empty($wsSettings['path'])) | ||||
|                     $config['path'] = $wsSettings['path']; | ||||
|                 if (isset($wsSettings['headers']['Host']) && !empty($wsSettings['headers']['Host'])) | ||||
|                     $config['obfsParam'] = $wsSettings['headers']['Host']; | ||||
|             } | ||||
|         } | ||||
|         if ($server['network'] === 'grpc') { | ||||
|             $config['obfs'] = "grpc"; | ||||
|             if ($server['networkSettings']) { | ||||
|                 $grpcSettings = json_decode($server['networkSettings'], true); | ||||
|                 if (isset($grpcSettings['serviceName']) && !empty($grpcSettings['serviceName'])) | ||||
|                     $config['path'] = $grpcSettings['serviceName']; | ||||
|             } | ||||
|             if (isset($tlsSettings)) { | ||||
|                 $config['host'] = $tlsSettings['serverName']; | ||||
|             } else { | ||||
|                 $config['host'] = $server['host']; | ||||
|             } | ||||
|         } | ||||
|         $query = http_build_query($config, '', '&', PHP_QUERY_RFC3986); | ||||
|         $uri = "vmess://{$userinfo}?{$query}"; | ||||
|         $uri .= "\r\n"; | ||||
|         return $uri; | ||||
|     } | ||||
|  | ||||
|     public static function buildTrojan($password, $server) | ||||
|     { | ||||
|         $name = rawurlencode($server['name']); | ||||
|         $query = http_build_query([ | ||||
|             'allowInsecure' => $server['allow_insecure'], | ||||
|             'peer' => $server['server_name'] | ||||
|         ]); | ||||
|         $uri = "trojan://{$password}@{$server['host']}:{$server['port']}?{$query}&tfo=1#{$name}"; | ||||
|         $uri .= "\r\n"; | ||||
|         return $uri; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										57
									
								
								app/Http/Controllers/Client/Protocols/Shadowsocks.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								app/Http/Controllers/Client/Protocols/Shadowsocks.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Http\Controllers\Client\Protocols; | ||||
|  | ||||
| class Shadowsocks | ||||
| { | ||||
|     public $flag = 'shadowsocks'; | ||||
|     private $servers; | ||||
|     private $user; | ||||
|  | ||||
|     public function __construct($user, $servers) | ||||
|     { | ||||
|         $this->user = $user; | ||||
|         $this->servers = $servers; | ||||
|     } | ||||
|  | ||||
|     public function handle() | ||||
|     { | ||||
|         $servers = $this->servers; | ||||
|         $user = $this->user; | ||||
|  | ||||
|         $configs = []; | ||||
|         $subs = []; | ||||
|         $subs['servers'] = []; | ||||
|         $subs['bytes_used'] = ''; | ||||
|         $subs['bytes_remaining'] = ''; | ||||
|  | ||||
|         $bytesUsed = $user['u'] + $user['d']; | ||||
|         $bytesRemaining = $user['transfer_enable'] - $bytesUsed; | ||||
|  | ||||
|         foreach ($servers as $item) { | ||||
|             if ($item['type'] === 'shadowsocks') { | ||||
|                 array_push($configs, self::SIP008($item, $user)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $subs['version'] = 1; | ||||
|         $subs['bytes_used'] = $bytesUsed; | ||||
|         $subs['bytes_remaining'] = $bytesRemaining; | ||||
|         $subs['servers'] = array_merge($subs['servers'] ? $subs['servers'] : [], $configs); | ||||
|  | ||||
|         return json_encode($subs, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT); | ||||
|     } | ||||
|  | ||||
|     public static function SIP008($server, $user) | ||||
|     { | ||||
|         $config = [ | ||||
|             "id" => $server['id'], | ||||
|             "remarks" => $server['name'], | ||||
|             "server" => $server['host'], | ||||
|             "server_port" => $server['port'], | ||||
|             "password" => $user['uuid'], | ||||
|             "method" => $server['cipher'] | ||||
|         ]; | ||||
|         return $config; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										113
									
								
								app/Http/Controllers/Client/Protocols/Surfboard.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								app/Http/Controllers/Client/Protocols/Surfboard.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Http\Controllers\Client\Protocols; | ||||
|  | ||||
|  | ||||
| class Surfboard | ||||
| { | ||||
|     public $flag = 'surfboard'; | ||||
|     private $servers; | ||||
|     private $user; | ||||
|  | ||||
|     public function __construct($user, $servers) | ||||
|     { | ||||
|         $this->user = $user; | ||||
|         $this->servers = $servers; | ||||
|     } | ||||
|  | ||||
|     public function handle() | ||||
|     { | ||||
|         $servers = $this->servers; | ||||
|         $user = $this->user; | ||||
|  | ||||
|         $proxies = ''; | ||||
|         $proxyGroup = ''; | ||||
|  | ||||
|         foreach ($servers as $item) { | ||||
|             if ($item['type'] === 'shadowsocks') { | ||||
|                 // [Proxy] | ||||
|                 $proxies .= Surfboard::buildShadowsocks($user['uuid'], $item); | ||||
|                 // [Proxy Group] | ||||
|                 $proxyGroup .= $item['name'] . ', '; | ||||
|             } | ||||
|             if ($item['type'] === 'v2ray') { | ||||
|                 // [Proxy] | ||||
|                 $proxies .= Surfboard::buildVmess($user['uuid'], $item); | ||||
|                 // [Proxy Group] | ||||
|                 $proxyGroup .= $item['name'] . ', '; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $defaultConfig = base_path() . '/resources/rules/default.surfboard.conf'; | ||||
|         $customConfig = base_path() . '/resources/rules/custom.surfboard.conf'; | ||||
|         if (\File::exists($customConfig)) { | ||||
|             $config = file_get_contents("$customConfig"); | ||||
|         } else { | ||||
|             $config = file_get_contents("$defaultConfig"); | ||||
|         } | ||||
|  | ||||
|         // Subscription link | ||||
|         $subsURL = config('v2board.subscribe_url', config('v2board.app_url', env('APP_URL'))) . '/api/v1/client/subscribe?token=' . $user['token']; | ||||
|  | ||||
|         $config = str_replace('$subs_link', $subsURL, $config); | ||||
|         $config = str_replace('$proxies', $proxies, $config); | ||||
|         $config = str_replace('$proxy_group', rtrim($proxyGroup, ', '), $config); | ||||
|         return $config; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public static function buildShadowsocks($password, $server) | ||||
|     { | ||||
|         $config = [ | ||||
|             "{$server['name']}=custom", | ||||
|             "{$server['host']}", | ||||
|             "{$server['port']}", | ||||
|             "{$server['cipher']}", | ||||
|             "{$password}", | ||||
|             'https://raw.githubusercontent.com/Hackl0us/proxy-tool-backup/master/SSEncrypt.module', | ||||
|             'tfo=true', | ||||
|             'udp-relay=true' | ||||
|         ]; | ||||
|         $config = array_filter($config); | ||||
|         $uri = implode(',', $config); | ||||
|         $uri .= "\r\n"; | ||||
|         return $uri; | ||||
|     } | ||||
|  | ||||
|     public static function buildVmess($uuid, $server) | ||||
|     { | ||||
|         $config = [ | ||||
|             "{$server['name']}=vmess", | ||||
|             "{$server['host']}", | ||||
|             "{$server['port']}", | ||||
|             "username={$uuid}", | ||||
|             'tfo=true', | ||||
|             'udp-relay=true' | ||||
|         ]; | ||||
|  | ||||
|         if ($server['tls']) { | ||||
|             array_push($config, 'tls=true'); | ||||
|             if ($server['tlsSettings']) { | ||||
|                 $tlsSettings = json_decode($server['tlsSettings'], true); | ||||
|                 if (isset($tlsSettings['allowInsecure']) && !empty($tlsSettings['allowInsecure'])) | ||||
|                     array_push($config, 'skip-cert-verify=' . ($tlsSettings['allowInsecure'] ? 'true' : 'false')); | ||||
|                 if (isset($tlsSettings['serverName']) && !empty($tlsSettings['serverName'])) | ||||
|                     array_push($config, "sni={$tlsSettings['serverName']}"); | ||||
|             } | ||||
|         } | ||||
|         if ($server['network'] === 'ws') { | ||||
|             array_push($config, 'ws=true'); | ||||
|             if ($server['networkSettings']) { | ||||
|                 $wsSettings = json_decode($server['networkSettings'], true); | ||||
|                 if (isset($wsSettings['path']) && !empty($wsSettings['path'])) | ||||
|                     array_push($config, "ws-path={$wsSettings['path']}"); | ||||
|                 if (isset($wsSettings['headers']['Host']) && !empty($wsSettings['headers']['Host'])) | ||||
|                     array_push($config, "ws-headers=Host:{$wsSettings['headers']['Host']}"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $uri = implode(',', $config); | ||||
|         $uri .= "\r\n"; | ||||
|         return $uri; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										137
									
								
								app/Http/Controllers/Client/Protocols/Surge.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								app/Http/Controllers/Client/Protocols/Surge.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,137 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Http\Controllers\Client\Protocols; | ||||
|  | ||||
| class Surge | ||||
| { | ||||
|     public $flag = 'surge'; | ||||
|     private $servers; | ||||
|     private $user; | ||||
|  | ||||
|     public function __construct($user, $servers) | ||||
|     { | ||||
|         $this->user = $user; | ||||
|         $this->servers = $servers; | ||||
|     } | ||||
|  | ||||
|     public function handle() | ||||
|     { | ||||
|         $servers = $this->servers; | ||||
|         $user = $this->user; | ||||
|  | ||||
|         $proxies = ''; | ||||
|         $proxyGroup = ''; | ||||
|  | ||||
|         foreach ($servers as $item) { | ||||
|             if ($item['type'] === 'shadowsocks') { | ||||
|                 // [Proxy] | ||||
|                 $proxies .= self::buildShadowsocks($user['uuid'], $item); | ||||
|                 // [Proxy Group] | ||||
|                 $proxyGroup .= $item['name'] . ', '; | ||||
|             } | ||||
|             if ($item['type'] === 'v2ray') { | ||||
|                 // [Proxy] | ||||
|                 $proxies .= self::buildVmess($user['uuid'], $item); | ||||
|                 // [Proxy Group] | ||||
|                 $proxyGroup .= $item['name'] . ', '; | ||||
|             } | ||||
|             if ($item['type'] === 'trojan') { | ||||
|                 // [Proxy] | ||||
|                 $proxies .= self::buildTrojan($user['uuid'], $item); | ||||
|                 // [Proxy Group] | ||||
|                 $proxyGroup .= $item['name'] . ', '; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $defaultConfig = base_path() . '/resources/rules/default.surge.conf'; | ||||
|         $customConfig = base_path() . '/resources/rules/custom.surge.conf'; | ||||
|         if (\File::exists($customConfig)) { | ||||
|             $config = file_get_contents("$customConfig"); | ||||
|         } else { | ||||
|             $config = file_get_contents("$defaultConfig"); | ||||
|         } | ||||
|  | ||||
|         // Subscription link | ||||
|         $subsURL = config('v2board.subscribe_url', config('v2board.app_url', env('APP_URL'))) . '/api/v1/client/subscribe?token=' . $user['token']; | ||||
|  | ||||
|         $config = str_replace('$subs_link', $subsURL, $config); | ||||
|         $config = str_replace('$proxies', $proxies, $config); | ||||
|         $config = str_replace('$proxy_group', rtrim($proxyGroup, ', '), $config); | ||||
|         return $config; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public static function buildShadowsocks($password, $server) | ||||
|     { | ||||
|         $config = [ | ||||
|             "{$server['name']}=ss", | ||||
|             "{$server['host']}", | ||||
|             "{$server['port']}", | ||||
|             "encrypt-method={$server['cipher']}", | ||||
|             "password={$password}", | ||||
|             'tfo=true', | ||||
|             'udp-relay=true' | ||||
|         ]; | ||||
|         $config = array_filter($config); | ||||
|         $uri = implode(',', $config); | ||||
|         $uri .= "\r\n"; | ||||
|         return $uri; | ||||
|     } | ||||
|  | ||||
|     public static function buildVmess($uuid, $server) | ||||
|     { | ||||
|         $config = [ | ||||
|             "{$server['name']}=vmess", | ||||
|             "{$server['host']}", | ||||
|             "{$server['port']}", | ||||
|             "username={$uuid}", | ||||
|             'tfo=true', | ||||
|             'udp-relay=true' | ||||
|         ]; | ||||
|  | ||||
|         if ($server['tls']) { | ||||
|             array_push($config, 'tls=true'); | ||||
|             if ($server['tlsSettings']) { | ||||
|                 $tlsSettings = json_decode($server['tlsSettings'], true); | ||||
|                 if (isset($tlsSettings['allowInsecure']) && !empty($tlsSettings['allowInsecure'])) | ||||
|                     array_push($config, 'skip-cert-verify=' . ($tlsSettings['allowInsecure'] ? 'true' : 'false')); | ||||
|                 if (isset($tlsSettings['serverName']) && !empty($tlsSettings['serverName'])) | ||||
|                     array_push($config, "sni={$tlsSettings['serverName']}"); | ||||
|             } | ||||
|         } | ||||
|         if ($server['network'] === 'ws') { | ||||
|             array_push($config, 'ws=true'); | ||||
|             if ($server['networkSettings']) { | ||||
|                 $wsSettings = json_decode($server['networkSettings'], true); | ||||
|                 if (isset($wsSettings['path']) && !empty($wsSettings['path'])) | ||||
|                     array_push($config, "ws-path={$wsSettings['path']}"); | ||||
|                 if (isset($wsSettings['headers']['Host']) && !empty($wsSettings['headers']['Host'])) | ||||
|                     array_push($config, "ws-headers=Host:{$wsSettings['headers']['Host']}"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $uri = implode(',', $config); | ||||
|         $uri .= "\r\n"; | ||||
|         return $uri; | ||||
|     } | ||||
|  | ||||
|     public static function buildTrojan($password, $server) | ||||
|     { | ||||
|         $config = [ | ||||
|             "{$server['name']}=trojan", | ||||
|             "{$server['host']}", | ||||
|             "{$server['port']}", | ||||
|             "password={$password}", | ||||
|             $server['server_name'] ? "sni={$server['server_name']}" : "", | ||||
|             'tfo=true', | ||||
|             'udp-relay=true' | ||||
|         ]; | ||||
|         if (!empty($server['allow_insecure'])) { | ||||
|             array_push($config, $server['allow_insecure'] ? 'skip-cert-verify=true' : 'skip-cert-verify=false'); | ||||
|         } | ||||
|         $config = array_filter($config); | ||||
|         $uri = implode(',', $config); | ||||
|         $uri .= "\r\n"; | ||||
|         return $uri; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user