From 9f2c83a21eff1a068397498729b78428a50c4d1f Mon Sep 17 00:00:00 2001 From: v2board Date: Wed, 8 Mar 2023 02:28:00 +0800 Subject: [PATCH] update: add hysteria --- .../Admin/Server/HysteriaController.php | 114 ++++++++++++++++++ .../Admin/Server/ManageController.php | 7 ++ .../Client/Protocols/ClashMeta.php | 4 +- .../Client/Protocols/Shadowrocket.php | 4 +- .../Controllers/Client/Protocols/V2rayN.php | 4 +- .../Controllers/Server/UniProxyController.php | 16 ++- app/Http/Routes/AdminRoute.php | 10 ++ app/Models/ServerHysteria.php | 19 +++ app/Services/ServerService.php | 42 ++++++- app/Utils/CacheKey.php | 3 + app/Utils/Helper.php | 2 +- 11 files changed, 213 insertions(+), 12 deletions(-) create mode 100644 app/Http/Controllers/Admin/Server/HysteriaController.php create mode 100755 app/Models/ServerHysteria.php diff --git a/app/Http/Controllers/Admin/Server/HysteriaController.php b/app/Http/Controllers/Admin/Server/HysteriaController.php new file mode 100644 index 00000000..2447b297 --- /dev/null +++ b/app/Http/Controllers/Admin/Server/HysteriaController.php @@ -0,0 +1,114 @@ +validate([ + 'show' => '', + 'name' => 'required', + 'group_id' => 'required|array', + 'route_id' => 'nullable|array', + 'parent_id' => 'nullable|integer', + 'host' => 'required', + 'port' => 'required', + 'server_port' => 'required', + 'tls' => 'required', + 'tags' => 'nullable|array', + 'rate' => 'required|numeric', + 'up_mbps' => 'required|numeric|min:1', + 'down_mbps' => 'required|numeric|min:1', + 'server_name' => 'nullable', + 'insecure' => 'required|in:0,1' + ]); + + if ($request->input('id')) { + $server = ServerHysteria::find($request->input('id')); + if (!$server) { + abort(500, '服务器不存在'); + } + try { + $server->update($params); + } catch (\Exception $e) { + abort(500, '保存失败'); + } + return response([ + 'data' => true + ]); + } + + if (!ServerHysteria::create($params)) { + abort(500, '创建失败'); + } + + return response([ + 'data' => true + ]); + } + + public function drop(Request $request) + { + if ($request->input('id')) { + $server = ServerHysteria::find($request->input('id')); + if (!$server) { + abort(500, '节点ID不存在'); + } + } + return response([ + 'data' => $server->delete() + ]); + } + + public function update(Request $request) + { + $request->validate([ + 'show' => 'in:0,1' + ], [ + 'show.in' => '显示状态格式不正确' + ]); + $params = $request->only([ + 'show', + ]); + + $server = ServerHysteria::find($request->input('id')); + + if (!$server) { + abort(500, '该服务器不存在'); + } + try { + $server->update($params); + } catch (\Exception $e) { + abort(500, '保存失败'); + } + + return response([ + 'data' => true + ]); + } + + public function copy(Request $request) + { + $server = ServerHysteria::find($request->input('id')); + $server->show = 0; + if (!$server) { + abort(500, '服务器不存在'); + } + if (!ServerHysteria::create($server->toArray())) { + abort(500, '复制失败'); + } + + return response([ + 'data' => true + ]); + } +} diff --git a/app/Http/Controllers/Admin/Server/ManageController.php b/app/Http/Controllers/Admin/Server/ManageController.php index 7e2d622e..73137669 100644 --- a/app/Http/Controllers/Admin/Server/ManageController.php +++ b/app/Http/Controllers/Admin/Server/ManageController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Admin\Server; +use App\Models\ServerHysteria; use App\Models\ServerVmess; use App\Models\ServerShadowsocks; use App\Models\ServerTrojan; @@ -44,6 +45,12 @@ class ManageController extends Controller abort(500, '保存失败'); } break; + case 'hysteria': + if (!ServerHysteria::find($v['value'])->update(['sort' => $v['sort']])) { + DB::rollBack(); + abort(500, '保存失败'); + } + break; } } DB::commit(); diff --git a/app/Http/Controllers/Client/Protocols/ClashMeta.php b/app/Http/Controllers/Client/Protocols/ClashMeta.php index e9e2ca7a..67a9858b 100644 --- a/app/Http/Controllers/Client/Protocols/ClashMeta.php +++ b/app/Http/Controllers/Client/Protocols/ClashMeta.php @@ -82,12 +82,12 @@ class ClashMeta public static function buildShadowsocks($password, $server) { if ($server['cipher'] === '2022-blake3-aes-128-gcm') { - $serverKey = Helper::getShadowsocksServerKey($server['created_at'], 16); + $serverKey = Helper::getServerKey($server['created_at'], 16); $userKey = Helper::uuidToBase64($password, 16); $password = "{$serverKey}:{$userKey}"; } if ($server['cipher'] === '2022-blake3-aes-256-gcm') { - $serverKey = Helper::getShadowsocksServerKey($server['created_at'], 32); + $serverKey = Helper::getServerKey($server['created_at'], 32); $userKey = Helper::uuidToBase64($password, 32); $password = "{$serverKey}:{$userKey}"; } diff --git a/app/Http/Controllers/Client/Protocols/Shadowrocket.php b/app/Http/Controllers/Client/Protocols/Shadowrocket.php index edbfd62a..31425863 100644 --- a/app/Http/Controllers/Client/Protocols/Shadowrocket.php +++ b/app/Http/Controllers/Client/Protocols/Shadowrocket.php @@ -46,12 +46,12 @@ class Shadowrocket public static function buildShadowsocks($password, $server) { if ($server['cipher'] === '2022-blake3-aes-128-gcm') { - $serverKey = Helper::getShadowsocksServerKey($server['created_at'], 16); + $serverKey = Helper::getServerKey($server['created_at'], 16); $userKey = Helper::uuidToBase64($password, 16); $password = "{$serverKey}:{$userKey}"; } if ($server['cipher'] === '2022-blake3-aes-256-gcm') { - $serverKey = Helper::getShadowsocksServerKey($server['created_at'], 32); + $serverKey = Helper::getServerKey($server['created_at'], 32); $userKey = Helper::uuidToBase64($password, 32); $password = "{$serverKey}:{$userKey}"; } diff --git a/app/Http/Controllers/Client/Protocols/V2rayN.php b/app/Http/Controllers/Client/Protocols/V2rayN.php index d5e1c00b..d71b4e0d 100644 --- a/app/Http/Controllers/Client/Protocols/V2rayN.php +++ b/app/Http/Controllers/Client/Protocols/V2rayN.php @@ -40,12 +40,12 @@ class V2rayN public static function buildShadowsocks($password, $server) { if ($server['cipher'] === '2022-blake3-aes-128-gcm') { - $serverKey = Helper::getShadowsocksServerKey($server['created_at'], 16); + $serverKey = Helper::getServerKey($server['created_at'], 16); $userKey = Helper::uuidToBase64($password, 16); $password = "{$serverKey}:{$userKey}"; } if ($server['cipher'] === '2022-blake3-aes-256-gcm') { - $serverKey = Helper::getShadowsocksServerKey($server['created_at'], 32); + $serverKey = Helper::getServerKey($server['created_at'], 32); $userKey = Helper::uuidToBase64($password, 32); $password = "{$serverKey}:{$userKey}"; } diff --git a/app/Http/Controllers/Server/UniProxyController.php b/app/Http/Controllers/Server/UniProxyController.php index 75d95b3b..d9bfed99 100644 --- a/app/Http/Controllers/Server/UniProxyController.php +++ b/app/Http/Controllers/Server/UniProxyController.php @@ -87,10 +87,10 @@ class UniProxyController extends Controller ]; if ($this->nodeInfo->cipher === '2022-blake3-aes-128-gcm') { - $response['server_key'] = Helper::getShadowsocksServerKey($this->nodeInfo->created_at, 16); + $response['server_key'] = Helper::getServerKey($this->nodeInfo->created_at, 16); } if ($this->nodeInfo->cipher === '2022-blake3-aes-256-gcm') { - $response['server_key'] = Helper::getShadowsocksServerKey($this->nodeInfo->created_at, 32); + $response['server_key'] = Helper::getServerKey($this->nodeInfo->created_at, 32); } break; case 'vmess': @@ -105,7 +105,17 @@ class UniProxyController extends Controller $response = [ 'host' => $this->nodeInfo->host, 'server_port' => $this->nodeInfo->server_port, - 'server_name' => $this->nodeInfo->server_name + 'server_name' => $this->nodeInfo->server_name, + ]; + break; + case 'hysteria': + $response = [ + 'host' => $this->nodeInfo->host, + 'server_port' => $this->nodeInfo->server_port, + 'server_name' => $this->nodeInfo->server_name, + 'up_mbps' => $this->nodeInfo->up_mbps, + 'down_mbps' => $this->nodeInfo->down_mbps, + 'obfs' => Helper::getServerKey($this->nodeInfo->created_at, 16) ]; break; } diff --git a/app/Http/Routes/AdminRoute.php b/app/Http/Routes/AdminRoute.php index 7f6bbbe1..471dabf1 100644 --- a/app/Http/Routes/AdminRoute.php +++ b/app/Http/Routes/AdminRoute.php @@ -64,6 +64,16 @@ class AdminRoute $router->post('copy', 'Admin\\Server\\ShadowsocksController@copy'); $router->post('sort', 'Admin\\Server\\ShadowsocksController@sort'); }); + $router->group([ + 'prefix' => 'server/hysteria' + ], function ($router) { + $router->get ('fetch', 'Admin\\Server\\HysteriaController@fetch'); + $router->post('save', 'Admin\\Server\\HysteriaController@save'); + $router->post('drop', 'Admin\\Server\\HysteriaController@drop'); + $router->post('update', 'Admin\\Server\\HysteriaController@update'); + $router->post('copy', 'Admin\\Server\\HysteriaController@copy'); + $router->post('sort', 'Admin\\Server\\HysteriaController@sort'); + }); // Order $router->get ('/order/fetch', 'Admin\\OrderController@fetch'); $router->post('/order/update', 'Admin\\OrderController@update'); diff --git a/app/Models/ServerHysteria.php b/app/Models/ServerHysteria.php new file mode 100755 index 00000000..11aac8f1 --- /dev/null +++ b/app/Models/ServerHysteria.php @@ -0,0 +1,19 @@ + 'timestamp', + 'updated_at' => 'timestamp', + 'group_id' => 'array', + 'route_id' => 'array', + 'tags' => 'array' + ]; +} diff --git a/app/Services/ServerService.php b/app/Services/ServerService.php index 5aa1ba1c..6841a846 100644 --- a/app/Services/ServerService.php +++ b/app/Services/ServerService.php @@ -2,6 +2,7 @@ namespace App\Services; +use App\Models\ServerHysteria; use App\Models\ServerLog; use App\Models\ServerRoute; use App\Models\ServerShadowsocks; @@ -61,6 +62,28 @@ class ServerService return $servers; } + public function getAvailableHysteria(User $user) + { + $availableServers = []; + $model = ServerHysteria::orderBy('sort', 'ASC'); + $servers = $model->get()->keyBy('id'); + foreach ($servers as $key => $v) { + if (!$v['show']) continue; + $servers[$key]['type'] = 'hysteria'; + $servers[$key]['last_check_at'] = Cache::get(CacheKey::get('SERVER_HYSTERIA_LAST_CHECK_AT', $v['id'])); + if (!in_array($user->group_id, $v['group_id'])) continue; + if (strpos($v['port'], '-') !== false) { + $servers[$key]['port'] = Helper::randomPort($v['port']); + } + if (isset($servers[$v['parent_id']])) { + $servers[$key]['last_check_at'] = Cache::get(CacheKey::get('SERVER_HYSTERIA_LAST_CHECK_AT', $v['parent_id'])); + $servers[$key]['created_at'] = $servers[$v['parent_id']]['created_at']; + } + $availableServers[] = $servers[$key]->toArray(); + } + return $availableServers; + } + public function getAvailableShadowsocks(User $user) { $servers = []; @@ -88,7 +111,8 @@ class ServerService $servers = array_merge( $this->getAvailableShadowsocks($user), $this->getAvailableVmess($user), - $this->getAvailableTrojan($user) + $this->getAvailableTrojan($user), + $this->getAvailableHysteria($user) ); $tmp = array_column($servers, 'sort'); array_multisort($tmp, SORT_ASC, $servers); @@ -182,6 +206,17 @@ class ServerService return $servers; } + public function getAllHysteria() + { + $servers = ServerHysteria::orderBy('sort', 'ASC') + ->get() + ->toArray(); + foreach ($servers as $k => $v) { + $servers[$k]['type'] = 'hysteria'; + } + return $servers; + } + private function mergeData(&$servers) { foreach ($servers as $k => $v) { @@ -204,7 +239,8 @@ class ServerService $servers = array_merge( $this->getAllShadowsocks(), $this->getAllVMess(), - $this->getAllTrojan() + $this->getAllTrojan(), + $this->getAllHysteria() ); $this->mergeData($servers); $tmp = array_column($servers, 'sort'); @@ -233,6 +269,8 @@ class ServerService return ServerShadowsocks::find($serverId); case 'trojan': return ServerTrojan::find($serverId); + case 'hysteria': + return ServerHysteria::find($serverId); default: return false; } diff --git a/app/Utils/CacheKey.php b/app/Utils/CacheKey.php index afb37410..6b6222d9 100644 --- a/app/Utils/CacheKey.php +++ b/app/Utils/CacheKey.php @@ -16,6 +16,9 @@ class CacheKey 'SERVER_SHADOWSOCKS_ONLINE_USER' => 'ss节点在线用户', 'SERVER_SHADOWSOCKS_LAST_CHECK_AT' => 'ss节点最后检查时间', 'SERVER_SHADOWSOCKS_LAST_PUSH_AT' => 'ss节点最后推送时间', + 'SERVER_HYSTERIA_ONLINE_USER' => 'hysteria节点在线用户', + 'SERVER_HYSTERIA_LAST_CHECK_AT' => 'hysteria节点最后检查时间', + 'SERVER_HYSTERIA_LAST_PUSH_AT' => 'hysteria节点最后推送时间', 'TEMP_TOKEN' => '临时令牌', 'LAST_SEND_EMAIL_REMIND_TRAFFIC' => '最后发送流量邮件提醒', 'SCHEDULE_LAST_CHECK_AT' => '计划任务最后检查时间', diff --git a/app/Utils/Helper.php b/app/Utils/Helper.php index 5f7dd587..e6ec1b9f 100644 --- a/app/Utils/Helper.php +++ b/app/Utils/Helper.php @@ -9,7 +9,7 @@ class Helper return base64_encode(substr($uuid, 0, $length)); } - public static function getShadowsocksServerKey($timestamp, $length) + public static function getServerKey($timestamp, $length) { return base64_encode(substr(md5($timestamp), 0, $length)); }