diff --git a/app/Http/Controllers/Admin/Server/TrojanController.php b/app/Http/Controllers/Admin/Server/TrojanController.php index 1d156a96..006d2709 100644 --- a/app/Http/Controllers/Admin/Server/TrojanController.php +++ b/app/Http/Controllers/Admin/Server/TrojanController.php @@ -23,6 +23,7 @@ class TrojanController extends Controller } $server[$i]['group_id'] = json_decode($server[$i]['group_id']); $server[$i]['online'] = Cache::get(CacheKey::get('SERVER_TROJAN_ONLINE_USER', $server[$i]['id'])); + $server[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_TROJAN_LAST_CHECK_AT', $server[$i]['id'])); } return response([ 'data' => $server diff --git a/app/Http/Controllers/Client/ClientController.php b/app/Http/Controllers/Client/ClientController.php index dfb68170..089d5488 100644 --- a/app/Http/Controllers/Client/ClientController.php +++ b/app/Http/Controllers/Client/ClientController.php @@ -3,6 +3,8 @@ namespace App\Http\Controllers\Client; use App\Http\Controllers\Controller; +use App\Services\ServerService; +use App\Utils\Clash; use Illuminate\Http\Request; use App\Models\Server; use App\Utils\Helper; @@ -14,44 +16,36 @@ class ClientController extends Controller public function subscribe(Request $request) { $user = $request->user; - $server = []; // account not expired and is not banned. $userService = new UserService(); if ($userService->isAvailable($user)) { - $servers = Server::where('show', 1) - ->orderBy('sort', 'ASC') - ->get(); - foreach ($servers as $item) { - $groupId = json_decode($item['group_id']); - if (in_array($user->group_id, $groupId)) { - array_push($server, $item); - } - } + $serverService = new ServerService(); + $servers = $serverService->getAllServers($user); } if (isset($_SERVER['HTTP_USER_AGENT'])) { if (strpos($_SERVER['HTTP_USER_AGENT'], 'Quantumult%20X') !== false) { - die($this->quantumultX($user, $server)); + die($this->quantumultX($user, $servers['vmess'])); } if (strpos($_SERVER['HTTP_USER_AGENT'], 'Quantumult') !== false) { - die($this->quantumult($user, $server)); + die($this->quantumult($user, $servers['vmess'])); } if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'clash') !== false) { - die($this->clash($user, $server)); + die($this->clash($user, $servers['vmess'], $servers['trojan'])); } if (strpos($_SERVER['HTTP_USER_AGENT'], 'Surfboard') !== false) { - die($this->surfboard($user, $server)); + die($this->surfboard($user, $servers['vmess'])); } if (strpos($_SERVER['HTTP_USER_AGENT'], 'Surge') !== false) { - die($this->surge($user, $server)); + die($this->surge($user, $servers['vmess'])); } } - die($this->origin($user, $server)); + die($this->origin($user, $servers['vmess'])); } - private function quantumultX($user, $server) + private function quantumultX($user, $vmess) { $uri = ''; - foreach ($server as $item) { + foreach ($vmess as $item) { $uri .= "vmess=" . $item->host . ":" . $item->port . ", method=none, password=" . $user->uuid . ", fast-open=false, udp-relay=false, tag=" . $item->name; if ($item->tls) { $tlsSettings = json_decode($item->tlsSettings); @@ -77,11 +71,11 @@ class ClientController extends Controller return base64_encode($uri); } - private function quantumult($user, $server) + private function quantumult($user, $vmess) { $uri = ''; header('subscription-userinfo: upload=' . $user->u . '; download=' . $user->d . ';total=' . $user->transfer_enable); - foreach ($server as $item) { + foreach ($vmess as $item) { $str = ''; $str .= $item->name . '= vmess, ' . $item->host . ', ' . $item->port . ', chacha20-ietf-poly1305, "' . $user->uuid . '", over-tls=' . ($item->tls ? "true" : "false") . ', certificate=0, group=' . config('v2board.app_name', 'V2Board'); if ($item->network === 'ws') { @@ -97,20 +91,20 @@ class ClientController extends Controller return base64_encode($uri); } - private function origin($user, $server) + private function origin($user, $vmess) { $uri = ''; - foreach ($server as $item) { + foreach ($vmess as $item) { $uri .= Helper::buildVmessLink($item, $user); } return base64_encode($uri); } - private function surge($user, $server) + private function surge($user, $vmess) { $proxies = ''; $proxyGroup = ''; - foreach ($server as $item) { + foreach ($vmess as $item) { // [Proxy] $proxies .= $item->name . ' = vmess, ' . $item->host . ', ' . $item->port . ', username=' . $user->uuid . ', tfo=true'; if ($item->tls) { @@ -159,11 +153,11 @@ class ClientController extends Controller return $config; } - private function surfboard($user, $server) + private function surfboard($user, $vmess) { $proxies = ''; $proxyGroup = ''; - foreach ($server as $item) { + foreach ($vmess as $item) { // [Proxy] $proxies .= $item->name . ' = vmess, ' . $item->host . ', ' . $item->port . ', username=' . $user->uuid; if ($item->tls) { @@ -212,7 +206,7 @@ class ClientController extends Controller return $config; } - private function clash($user, $server) + private function clash($user, $vmess = [], $trojan = []) { $defaultConfig = base_path() . '/resources/rules/default.clash.yaml'; $customConfig = base_path() . '/resources/rules/custom.clash.yaml'; @@ -223,31 +217,14 @@ class ClientController extends Controller } $proxy = []; $proxies = []; - foreach ($server as $item) { - $array = []; - $array['name'] = $item->name; - $array['type'] = 'vmess'; - $array['server'] = $item->host; - $array['port'] = $item->port; - $array['uuid'] = $user->uuid; - $array['alterId'] = $user->v2ray_alter_id; - $array['cipher'] = 'auto'; - if ($item->tls) { - $tlsSettings = json_decode($item->tlsSettings); - $array['tls'] = true; - if (isset($tlsSettings->allowInsecure)) $array['skip-cert-verify'] = ($tlsSettings->allowInsecure ? true : false ); - } - if ($item->network == 'ws') { - $array['network'] = $item->network; - if ($item->networkSettings) { - $wsSettings = json_decode($item->networkSettings); - if (isset($wsSettings->path)) $array['ws-path'] = $wsSettings->path; - if (isset($wsSettings->headers->Host)) $array['ws-headers'] = [ - 'Host' => $wsSettings->headers->Host - ]; - } - } - array_push($proxy, $array); + foreach ($vmess as $item) { + array_push($proxy, Clash::buildVmess($user->uuid, $item)); + array_push($proxies, $item->name); + } + + + foreach ($trojan as $item) { + array_push($proxy, Clash::buildTrojan($user->uuid, $item)); array_push($proxies, $item->name); } diff --git a/app/Http/Controllers/Server/DeepbworkController.php b/app/Http/Controllers/Server/DeepbworkController.php index 5ab29d98..68c30297 100644 --- a/app/Http/Controllers/Server/DeepbworkController.php +++ b/app/Http/Controllers/Server/DeepbworkController.php @@ -111,7 +111,7 @@ class DeepbworkController extends Controller } $serverService = new ServerService(); try { - $json = $serverService->getConfig($nodeId, $localPort); + $json = $serverService->getVmessConfig($nodeId, $localPort); } catch (\Exception $e) { abort(500, $e->getMessage()); } diff --git a/app/Http/Controllers/Server/PoseidonController.php b/app/Http/Controllers/Server/PoseidonController.php index 28d29374..cd2e3955 100644 --- a/app/Http/Controllers/Server/PoseidonController.php +++ b/app/Http/Controllers/Server/PoseidonController.php @@ -101,7 +101,7 @@ class PoseidonController extends Controller $serverService = new ServerService(); try { - $json = $serverService->getConfig($nodeId, $localPort); + $json = $serverService->getVmessConfig($nodeId, $localPort); $json->poseidon = [ 'license_key' => (string)config('v2board.server_license'), ]; diff --git a/app/Http/Controllers/User/ServerController.php b/app/Http/Controllers/User/ServerController.php index 21e81204..42904e5e 100644 --- a/app/Http/Controllers/User/ServerController.php +++ b/app/Http/Controllers/User/ServerController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\User; use App\Http\Controllers\Controller; +use App\Services\ServerService; use App\Services\UserService; use App\Utils\CacheKey; use Illuminate\Http\Request; @@ -18,29 +19,14 @@ class ServerController extends Controller public function fetch(Request $request) { $user = User::find($request->session()->get('id')); - $server = []; + $servers = []; $userService = new UserService(); if ($userService->isAvailable($user)) { - $servers = Server::where('show', 1) - ->orderBy('sort', 'ASC') - ->get(); - foreach ($servers as $item) { - $groupId = json_decode($item['group_id']); - if (in_array($user->group_id, $groupId)) { - array_push($server, $item); - } - } - } - for ($i = 0; $i < count($server); $i++) { - $server[$i]['link'] = Helper::buildVmessLink($server[$i], $user); - if ($server[$i]['parent_id']) { - $server[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_LAST_CHECK_AT', $server[$i]['parent_id'])); - } else { - $server[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_LAST_CHECK_AT', $server[$i]['id'])); - } + $serverService = new ServerService(); + $servers = $serverService->getAllServers($user); } return response([ - 'data' => $server + 'data' => $servers ]); } diff --git a/app/Services/ServerService.php b/app/Services/ServerService.php index c94ba0df..a30da31d 100644 --- a/app/Services/ServerService.php +++ b/app/Services/ServerService.php @@ -5,12 +5,69 @@ namespace App\Services; use App\Models\ServerLog; use App\Models\User; use App\Models\Server; +use App\Models\ServerTrojan; +use App\Utils\CacheKey; +use App\Utils\Helper; +use Illuminate\Support\Facades\Cache; class ServerService { CONST SERVER_CONFIG = '{"api":{"services":["HandlerService","StatsService"],"tag":"api"},"dns":{},"stats":{},"inbound":{"port":443,"protocol":"vmess","settings":{"clients":[]},"sniffing":{"enabled":true,"destOverride":["http","tls"]},"streamSettings":{"network":"tcp"},"tag":"proxy"},"inboundDetour":[{"listen":"0.0.0.0","port":23333,"protocol":"dokodemo-door","settings":{"address":"0.0.0.0"},"tag":"api"}],"log":{"loglevel":"debug","access":"access.log","error":"error.log"},"outbound":{"protocol":"freedom","settings":{}},"outboundDetour":[{"protocol":"blackhole","settings":{},"tag":"block"}],"routing":{"rules":[{"inboundTag":"api","outboundTag":"api","type":"field"}]},"policy":{"levels":{"0":{"handshake":4,"connIdle":300,"uplinkOnly":5,"downlinkOnly":30,"statsUserUplink":true,"statsUserDownlink":true}}}}'; + public function getVmess(User $user, $all = false):array + { + $vmess = []; + $model = Server::orderBy('sort', 'ASC'); + if (!$all) { + $model->where('show', 1); + } + $vmesss = $model->get(); + foreach ($vmesss as $k => $v) { + $groupId = json_decode($vmesss[$k]['group_id']); + if (in_array($user->group_id, $groupId)) { + $vmesss[$k]['link'] = Helper::buildVmessLink($vmesss[$k], $user); + if ($vmesss[$k]['parent_id']) { + $vmesss[$k]['last_check_at'] = Cache::get(CacheKey::get('SERVER_LAST_CHECK_AT', $vmesss[$k]['parent_id'])); + } else { + $vmesss[$k]['last_check_at'] = Cache::get(CacheKey::get('SERVER_LAST_CHECK_AT', $vmesss[$k]['id'])); + } + array_push($vmess, $vmesss[$k]); + } + } + + + return $vmess; + } + + public function getTrojan(User $user, $all = false) + { + $trojan = []; + $model = ServerTrojan::orderBy('sort', 'ASC'); + if (!$all) { + $model->where('show', 1); + } + $trojans = $model->get(); + foreach ($trojans as $k => $v) { + $groupId = json_decode($trojans[$k]['group_id']); + if (in_array($user->group_id, $groupId)) { + $vmesss[$k]['last_check_at'] = Cache::get(CacheKey::get('SERVER_TROJAN_LAST_CHECK_AT', $trojans[$k]['id'])); + array_push($trojan, $trojans[$k]); + } + + } + return $trojan; + } + + public function getAllServers(User $user, $all = false) + { + return [ + 'vmess' => $this->getVmess($user, $all), + 'trojan' => $this->getTrojan($user, $all) + ]; + } + + public function getAvailableUsers($groupId) { return User::whereIn('group_id', $groupId) @@ -34,7 +91,7 @@ class ServerService ->get(); } - public function getConfig(int $nodeId, int $localPort) + public function getVmessConfig(int $nodeId, int $localPort) { $server = Server::find($nodeId); if (!$server) { diff --git a/app/Utils/Clash.php b/app/Utils/Clash.php new file mode 100644 index 00000000..3d3a450e --- /dev/null +++ b/app/Utils/Clash.php @@ -0,0 +1,46 @@ +name; + $array['type'] = 'vmess'; + $array['server'] = $server->host; + $array['port'] = $server->port; + $array['uuid'] = $uuid; + $array['alterId'] = 2; + $array['cipher'] = 'auto'; + if ($server->tls) { + $tlsSettings = json_decode($server->tlsSettings); + $array['tls'] = true; + if (isset($tlsSettings->allowInsecure)) $array['skip-cert-verify'] = ($tlsSettings->allowInsecure ? true : false ); + } + if ($server->network == 'ws') { + $array['network'] = $server->network; + if ($server->networkSettings) { + $wsSettings = json_decode($server->networkSettings); + if (isset($wsSettings->path)) $array['ws-path'] = $wsSettings->path; + if (isset($wsSettings->headers->Host)) $array['ws-headers'] = [ + 'Host' => $wsSettings->headers->Host + ]; + } + } + 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; + return $array; + } +}