mirror of
				https://github.com/v2board/v2board.git
				synced 2025-10-31 09:21:46 +08:00 
			
		
		
		
	update: add hysteria
This commit is contained in:
		
							
								
								
									
										114
									
								
								app/Http/Controllers/Admin/Server/HysteriaController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								app/Http/Controllers/Admin/Server/HysteriaController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace App\Http\Controllers\Admin\Server; | ||||||
|  |  | ||||||
|  | use App\Http\Requests\Admin\ServerVmessSave; | ||||||
|  | use App\Http\Requests\Admin\ServerVmessUpdate; | ||||||
|  | use App\Models\ServerHysteria; | ||||||
|  | use App\Services\ServerService; | ||||||
|  | use Illuminate\Http\Request; | ||||||
|  | use App\Http\Controllers\Controller; | ||||||
|  | use App\Models\ServerVmess; | ||||||
|  |  | ||||||
|  | class HysteriaController extends Controller | ||||||
|  | { | ||||||
|  |     public function save(Request $request) | ||||||
|  |     { | ||||||
|  |         $params = $request->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 | ||||||
|  |         ]); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -2,6 +2,7 @@ | |||||||
|  |  | ||||||
| namespace App\Http\Controllers\Admin\Server; | namespace App\Http\Controllers\Admin\Server; | ||||||
|  |  | ||||||
|  | use App\Models\ServerHysteria; | ||||||
| use App\Models\ServerVmess; | use App\Models\ServerVmess; | ||||||
| use App\Models\ServerShadowsocks; | use App\Models\ServerShadowsocks; | ||||||
| use App\Models\ServerTrojan; | use App\Models\ServerTrojan; | ||||||
| @@ -44,6 +45,12 @@ class ManageController extends Controller | |||||||
|                         abort(500, '保存失败'); |                         abort(500, '保存失败'); | ||||||
|                     } |                     } | ||||||
|                     break; |                     break; | ||||||
|  |                 case 'hysteria': | ||||||
|  |                     if (!ServerHysteria::find($v['value'])->update(['sort' => $v['sort']])) { | ||||||
|  |                         DB::rollBack(); | ||||||
|  |                         abort(500, '保存失败'); | ||||||
|  |                     } | ||||||
|  |                     break; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         DB::commit(); |         DB::commit(); | ||||||
|   | |||||||
| @@ -82,12 +82,12 @@ class ClashMeta | |||||||
|     public static function buildShadowsocks($password, $server) |     public static function buildShadowsocks($password, $server) | ||||||
|     { |     { | ||||||
|         if ($server['cipher'] === '2022-blake3-aes-128-gcm') { |         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); |             $userKey = Helper::uuidToBase64($password, 16); | ||||||
|             $password = "{$serverKey}:{$userKey}"; |             $password = "{$serverKey}:{$userKey}"; | ||||||
|         } |         } | ||||||
|         if ($server['cipher'] === '2022-blake3-aes-256-gcm') { |         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); |             $userKey = Helper::uuidToBase64($password, 32); | ||||||
|             $password = "{$serverKey}:{$userKey}"; |             $password = "{$serverKey}:{$userKey}"; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -46,12 +46,12 @@ class Shadowrocket | |||||||
|     public static function buildShadowsocks($password, $server) |     public static function buildShadowsocks($password, $server) | ||||||
|     { |     { | ||||||
|         if ($server['cipher'] === '2022-blake3-aes-128-gcm') { |         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); |             $userKey = Helper::uuidToBase64($password, 16); | ||||||
|             $password = "{$serverKey}:{$userKey}"; |             $password = "{$serverKey}:{$userKey}"; | ||||||
|         } |         } | ||||||
|         if ($server['cipher'] === '2022-blake3-aes-256-gcm') { |         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); |             $userKey = Helper::uuidToBase64($password, 32); | ||||||
|             $password = "{$serverKey}:{$userKey}"; |             $password = "{$serverKey}:{$userKey}"; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -40,12 +40,12 @@ class V2rayN | |||||||
|     public static function buildShadowsocks($password, $server) |     public static function buildShadowsocks($password, $server) | ||||||
|     { |     { | ||||||
|         if ($server['cipher'] === '2022-blake3-aes-128-gcm') { |         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); |             $userKey = Helper::uuidToBase64($password, 16); | ||||||
|             $password = "{$serverKey}:{$userKey}"; |             $password = "{$serverKey}:{$userKey}"; | ||||||
|         } |         } | ||||||
|         if ($server['cipher'] === '2022-blake3-aes-256-gcm') { |         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); |             $userKey = Helper::uuidToBase64($password, 32); | ||||||
|             $password = "{$serverKey}:{$userKey}"; |             $password = "{$serverKey}:{$userKey}"; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -87,10 +87,10 @@ class UniProxyController extends Controller | |||||||
|                 ]; |                 ]; | ||||||
|  |  | ||||||
|                 if ($this->nodeInfo->cipher === '2022-blake3-aes-128-gcm') { |                 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') { |                 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; |                 break; | ||||||
|             case 'vmess': |             case 'vmess': | ||||||
| @@ -105,7 +105,17 @@ class UniProxyController extends Controller | |||||||
|                 $response = [ |                 $response = [ | ||||||
|                     'host' => $this->nodeInfo->host, |                     'host' => $this->nodeInfo->host, | ||||||
|                     'server_port' => $this->nodeInfo->server_port, |                     '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; |                 break; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -64,6 +64,16 @@ class AdminRoute | |||||||
|                 $router->post('copy', 'Admin\\Server\\ShadowsocksController@copy'); |                 $router->post('copy', 'Admin\\Server\\ShadowsocksController@copy'); | ||||||
|                 $router->post('sort', 'Admin\\Server\\ShadowsocksController@sort'); |                 $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 |             // Order | ||||||
|             $router->get ('/order/fetch', 'Admin\\OrderController@fetch'); |             $router->get ('/order/fetch', 'Admin\\OrderController@fetch'); | ||||||
|             $router->post('/order/update', 'Admin\\OrderController@update'); |             $router->post('/order/update', 'Admin\\OrderController@update'); | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								app/Models/ServerHysteria.php
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										19
									
								
								app/Models/ServerHysteria.php
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace App\Models; | ||||||
|  |  | ||||||
|  | use Illuminate\Database\Eloquent\Model; | ||||||
|  |  | ||||||
|  | class ServerHysteria extends Model | ||||||
|  | { | ||||||
|  |     protected $table = 'v2_server_hysteria'; | ||||||
|  |     protected $dateFormat = 'U'; | ||||||
|  |     protected $guarded = ['id']; | ||||||
|  |     protected $casts = [ | ||||||
|  |         'created_at' => 'timestamp', | ||||||
|  |         'updated_at' => 'timestamp', | ||||||
|  |         'group_id' => 'array', | ||||||
|  |         'route_id' => 'array', | ||||||
|  |         'tags' => 'array' | ||||||
|  |     ]; | ||||||
|  | } | ||||||
| @@ -2,6 +2,7 @@ | |||||||
|  |  | ||||||
| namespace App\Services; | namespace App\Services; | ||||||
|  |  | ||||||
|  | use App\Models\ServerHysteria; | ||||||
| use App\Models\ServerLog; | use App\Models\ServerLog; | ||||||
| use App\Models\ServerRoute; | use App\Models\ServerRoute; | ||||||
| use App\Models\ServerShadowsocks; | use App\Models\ServerShadowsocks; | ||||||
| @@ -61,6 +62,28 @@ class ServerService | |||||||
|         return $servers; |         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) |     public function getAvailableShadowsocks(User $user) | ||||||
|     { |     { | ||||||
|         $servers = []; |         $servers = []; | ||||||
| @@ -88,7 +111,8 @@ class ServerService | |||||||
|         $servers = array_merge( |         $servers = array_merge( | ||||||
|             $this->getAvailableShadowsocks($user), |             $this->getAvailableShadowsocks($user), | ||||||
|             $this->getAvailableVmess($user), |             $this->getAvailableVmess($user), | ||||||
|             $this->getAvailableTrojan($user) |             $this->getAvailableTrojan($user), | ||||||
|  |             $this->getAvailableHysteria($user) | ||||||
|         ); |         ); | ||||||
|         $tmp = array_column($servers, 'sort'); |         $tmp = array_column($servers, 'sort'); | ||||||
|         array_multisort($tmp, SORT_ASC, $servers); |         array_multisort($tmp, SORT_ASC, $servers); | ||||||
| @@ -182,6 +206,17 @@ class ServerService | |||||||
|         return $servers; |         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) |     private function mergeData(&$servers) | ||||||
|     { |     { | ||||||
|         foreach ($servers as $k => $v) { |         foreach ($servers as $k => $v) { | ||||||
| @@ -204,7 +239,8 @@ class ServerService | |||||||
|         $servers = array_merge( |         $servers = array_merge( | ||||||
|             $this->getAllShadowsocks(), |             $this->getAllShadowsocks(), | ||||||
|             $this->getAllVMess(), |             $this->getAllVMess(), | ||||||
|             $this->getAllTrojan() |             $this->getAllTrojan(), | ||||||
|  |             $this->getAllHysteria() | ||||||
|         ); |         ); | ||||||
|         $this->mergeData($servers); |         $this->mergeData($servers); | ||||||
|         $tmp = array_column($servers, 'sort'); |         $tmp = array_column($servers, 'sort'); | ||||||
| @@ -233,6 +269,8 @@ class ServerService | |||||||
|                 return ServerShadowsocks::find($serverId); |                 return ServerShadowsocks::find($serverId); | ||||||
|             case 'trojan': |             case 'trojan': | ||||||
|                 return ServerTrojan::find($serverId); |                 return ServerTrojan::find($serverId); | ||||||
|  |             case 'hysteria': | ||||||
|  |                 return ServerHysteria::find($serverId); | ||||||
|             default: |             default: | ||||||
|                 return false; |                 return false; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -16,6 +16,9 @@ class CacheKey | |||||||
|         'SERVER_SHADOWSOCKS_ONLINE_USER' => 'ss节点在线用户', |         'SERVER_SHADOWSOCKS_ONLINE_USER' => 'ss节点在线用户', | ||||||
|         'SERVER_SHADOWSOCKS_LAST_CHECK_AT' => 'ss节点最后检查时间', |         'SERVER_SHADOWSOCKS_LAST_CHECK_AT' => 'ss节点最后检查时间', | ||||||
|         'SERVER_SHADOWSOCKS_LAST_PUSH_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' => '临时令牌', |         'TEMP_TOKEN' => '临时令牌', | ||||||
|         'LAST_SEND_EMAIL_REMIND_TRAFFIC' => '最后发送流量邮件提醒', |         'LAST_SEND_EMAIL_REMIND_TRAFFIC' => '最后发送流量邮件提醒', | ||||||
|         'SCHEDULE_LAST_CHECK_AT' => '计划任务最后检查时间', |         'SCHEDULE_LAST_CHECK_AT' => '计划任务最后检查时间', | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ class Helper | |||||||
|         return base64_encode(substr($uuid, 0, $length)); |         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)); |         return base64_encode(substr(md5($timestamp), 0, $length)); | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user