mirror of
https://github.com/lkddi/Xboard.git
synced 2026-04-24 12:07:28 +08:00
feat: new xboard
This commit is contained in:
@@ -1,222 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\V1\Server;
|
||||
|
||||
use App\Exceptions\ApiException;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\ServerVmess;
|
||||
use App\Services\ServerService;
|
||||
use App\Services\UserService;
|
||||
use App\Utils\CacheKey;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
/*
|
||||
* V2ray Aurora
|
||||
* Github: https://github.com/tokumeikoi/aurora
|
||||
*/
|
||||
class DeepbworkController extends Controller
|
||||
{
|
||||
CONST V2RAY_CONFIG = '{"log":{"loglevel":"debug","access":"access.log","error":"error.log"},"api":{"services":["HandlerService","StatsService"],"tag":"api"},"dns":{},"stats":{},"inbounds":[{"port":443,"protocol":"vmess","settings":{"clients":[]},"sniffing":{"enabled":true,"destOverride":["http","tls"]},"streamSettings":{"network":"tcp"},"tag":"proxy"},{"listen":"127.0.0.1","port":23333,"protocol":"dokodemo-door","settings":{"address":"0.0.0.0"},"tag":"api"}],"outbounds":[{"protocol":"freedom","settings":{}},{"protocol":"blackhole","settings":{},"tag":"block"}],"routing":{"rules":[{"type":"field","inboundTag":"api","outboundTag":"api"}]},"policy":{"levels":{"0":{"handshake":4,"connIdle":300,"uplinkOnly":5,"downlinkOnly":30,"statsUserUplink":true,"statsUserDownlink":true}}}}';
|
||||
|
||||
// 后端获取用户
|
||||
public function user(Request $request)
|
||||
{
|
||||
ini_set('memory_limit', -1);
|
||||
$nodeId = $request->input('node_id');
|
||||
$server = ServerVmess::find($nodeId);
|
||||
if (!$server) {
|
||||
return $this->fail([400,'节点不存在']);
|
||||
}
|
||||
Cache::put(CacheKey::get('SERVER_VMESS_LAST_CHECK_AT', $server->id), time(), 3600);
|
||||
$users = ServerService::getAvailableUsers($server->group_id);
|
||||
$result = [];
|
||||
foreach ($users as $user) {
|
||||
$user->v2ray_user = [
|
||||
"uuid" => $user->uuid,
|
||||
"email" => sprintf("%s@v2board.user", $user->uuid),
|
||||
"alter_id" => 0,
|
||||
"level" => 0,
|
||||
];
|
||||
unset($user->uuid);
|
||||
array_push($result, $user);
|
||||
}
|
||||
$eTag = sha1(json_encode($result));
|
||||
if (strpos($request->header('If-None-Match'), $eTag) !== false ) {
|
||||
return response(null,304);
|
||||
}
|
||||
return response([
|
||||
'msg' => 'ok',
|
||||
'data' => $result,
|
||||
])->header('ETag', "\"{$eTag}\"");
|
||||
}
|
||||
|
||||
// 后端提交数据
|
||||
public function submit(Request $request)
|
||||
{
|
||||
$server = ServerVmess::find($request->input('node_id'));
|
||||
if (!$server) {
|
||||
return response([
|
||||
'ret' => 0,
|
||||
'msg' => 'server is not found'
|
||||
]);
|
||||
}
|
||||
$data = get_request_content();
|
||||
$data = json_decode($data, true);
|
||||
Cache::put(CacheKey::get('SERVER_VMESS_ONLINE_USER', $server->id), count($data), 3600);
|
||||
Cache::put(CacheKey::get('SERVER_VMESS_LAST_PUSH_AT', $server->id), time(), 3600);
|
||||
$userService = new UserService();
|
||||
$formatData = [];
|
||||
|
||||
foreach ($data as $item) {
|
||||
$formatData[$item['user_id']] = [$item['u'], $item['d']];
|
||||
}
|
||||
$userService->trafficFetch($server->toArray(), 'vmess', $formatData);
|
||||
|
||||
return response([
|
||||
'ret' => 1,
|
||||
'msg' => 'ok'
|
||||
]);
|
||||
}
|
||||
|
||||
// 后端获取配置
|
||||
public function config(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'node_id' => 'required',
|
||||
'local_port' => 'required'
|
||||
],[
|
||||
'node_id.required' => '节点ID不能为空',
|
||||
'local_port.required' => '本地端口不能为空'
|
||||
]);
|
||||
try {
|
||||
$json = $this->getV2RayConfig($request->input('node_id'), $request->input('local_port'));
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
throw new ApiException($e->getMessage());
|
||||
}
|
||||
|
||||
return(json_encode($json, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
private function getV2RayConfig(int $nodeId, int $localPort)
|
||||
{
|
||||
$server = ServerVmess::find($nodeId);
|
||||
if (!$server) {
|
||||
return $this->fail([400,'节点不存在']);
|
||||
}
|
||||
$json = json_decode(self::V2RAY_CONFIG);
|
||||
$json->log->loglevel = (int)admin_setting('server_log_enable') ? 'debug' : 'none';
|
||||
$json->inbounds[1]->port = (int)$localPort;
|
||||
$json->inbounds[0]->port = (int)$server->server_port;
|
||||
$json->inbounds[0]->streamSettings->network = $server->network;
|
||||
$this->setDns($server, $json);
|
||||
$this->setNetwork($server, $json);
|
||||
$this->setRule($server, $json);
|
||||
$this->setTls($server, $json);
|
||||
|
||||
return $json;
|
||||
}
|
||||
|
||||
private function setDns(ServerVmess $server, object $json)
|
||||
{
|
||||
if ($server->dnsSettings) {
|
||||
$dns = $server->dnsSettings;
|
||||
if (isset($dns->servers)) {
|
||||
array_push($dns->servers, '1.1.1.1');
|
||||
array_push($dns->servers, 'localhost');
|
||||
}
|
||||
$json->dns = $dns;
|
||||
$json->outbounds[0]->settings->domainStrategy = 'UseIP';
|
||||
}
|
||||
}
|
||||
|
||||
private function setNetwork(ServerVmess $server, object $json)
|
||||
{
|
||||
if ($server->networkSettings) {
|
||||
switch ($server->network) {
|
||||
case 'tcp':
|
||||
$json->inbounds[0]->streamSettings->tcpSettings = $server->networkSettings;
|
||||
break;
|
||||
case 'kcp':
|
||||
$json->inbounds[0]->streamSettings->kcpSettings = $server->networkSettings;
|
||||
break;
|
||||
case 'ws':
|
||||
$json->inbounds[0]->streamSettings->wsSettings = $server->networkSettings;
|
||||
break;
|
||||
case 'http':
|
||||
$json->inbounds[0]->streamSettings->httpSettings = $server->networkSettings;
|
||||
break;
|
||||
case 'domainsocket':
|
||||
$json->inbounds[0]->streamSettings->dsSettings = $server->networkSettings;
|
||||
break;
|
||||
case 'quic':
|
||||
$json->inbounds[0]->streamSettings->quicSettings = $server->networkSettings;
|
||||
break;
|
||||
case 'grpc':
|
||||
$json->inbounds[0]->streamSettings->grpcSettings = $server->networkSettings;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function setRule(ServerVmess $server, object $json)
|
||||
{
|
||||
$domainRules = array_filter(explode(PHP_EOL, admin_setting('server_v2ray_domain')));
|
||||
$protocolRules = array_filter(explode(PHP_EOL, admin_setting('server_v2ray_protocol')));
|
||||
if ($server->ruleSettings) {
|
||||
$ruleSettings = $server->ruleSettings;
|
||||
// domain
|
||||
if (isset($ruleSettings->domain)) {
|
||||
$ruleSettings->domain = array_filter($ruleSettings->domain);
|
||||
if (!empty($ruleSettings->domain)) {
|
||||
$domainRules = array_merge($domainRules, $ruleSettings->domain);
|
||||
}
|
||||
}
|
||||
// protocol
|
||||
if (isset($ruleSettings->protocol)) {
|
||||
$ruleSettings->protocol = array_filter($ruleSettings->protocol);
|
||||
if (!empty($ruleSettings->protocol)) {
|
||||
$protocolRules = array_merge($protocolRules, $ruleSettings->protocol);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($domainRules)) {
|
||||
$domainObj = new \StdClass();
|
||||
$domainObj->type = 'field';
|
||||
$domainObj->domain = $domainRules;
|
||||
$domainObj->outboundTag = 'block';
|
||||
array_push($json->routing->rules, $domainObj);
|
||||
}
|
||||
if (!empty($protocolRules)) {
|
||||
$protocolObj = new \StdClass();
|
||||
$protocolObj->type = 'field';
|
||||
$protocolObj->protocol = $protocolRules;
|
||||
$protocolObj->outboundTag = 'block';
|
||||
array_push($json->routing->rules, $protocolObj);
|
||||
}
|
||||
if (empty($domainRules) && empty($protocolRules)) {
|
||||
$json->inbounds[0]->sniffing->enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private function setTls(ServerVMess $server, object $json)
|
||||
{
|
||||
if ((int)$server->tls) {
|
||||
$tlsSettings = $server->tlsSettings;
|
||||
$json->inbounds[0]->streamSettings->security = 'tls';
|
||||
$tls = (object)[
|
||||
'certificateFile' => '/root/.cert/server.crt',
|
||||
'keyFile' => '/root/.cert/server.key'
|
||||
];
|
||||
$json->inbounds[0]->streamSettings->tlsSettings = new \StdClass();
|
||||
if (isset($tlsSettings->serverName)) {
|
||||
$json->inbounds[0]->streamSettings->tlsSettings->serverName = (string)$tlsSettings->serverName;
|
||||
}
|
||||
if (isset($tlsSettings->allowInsecure)) {
|
||||
$json->inbounds[0]->streamSettings->tlsSettings->allowInsecure = (int)$tlsSettings->allowInsecure ? true : false;
|
||||
}
|
||||
$json->inbounds[0]->streamSettings->tlsSettings->certificates[0] = $tls;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,13 +21,9 @@ class ShadowsocksTidalabController extends Controller
|
||||
public function user(Request $request)
|
||||
{
|
||||
ini_set('memory_limit', -1);
|
||||
$nodeId = $request->input('node_id');
|
||||
$server = ServerShadowsocks::find($nodeId);
|
||||
if (!$server) {
|
||||
return $this->fail([400,'节点不存在']);
|
||||
}
|
||||
$server = $request->input('node_info');
|
||||
Cache::put(CacheKey::get('SERVER_SHADOWSOCKS_LAST_CHECK_AT', $server->id), time(), 3600);
|
||||
$users = ServerService::getAvailableUsers($server->group_id);
|
||||
$users = ServerService::getAvailableUsers($server->group_ids);
|
||||
$result = [];
|
||||
foreach ($users as $user) {
|
||||
array_push($result, [
|
||||
@@ -49,15 +45,8 @@ class ShadowsocksTidalabController extends Controller
|
||||
// 后端提交数据
|
||||
public function submit(Request $request)
|
||||
{
|
||||
$server = ServerShadowsocks::find($request->input('node_id'));
|
||||
if (!$server) {
|
||||
return response([
|
||||
'ret' => 0,
|
||||
'msg' => 'server is not found'
|
||||
]);
|
||||
}
|
||||
$data = get_request_content();
|
||||
$data = json_decode($data, true);
|
||||
$server = $request->input('node_info');
|
||||
$data = json_decode(request()->getContent(), true);
|
||||
Cache::put(CacheKey::get('SERVER_SHADOWSOCKS_ONLINE_USER', $server->id), count($data), 3600);
|
||||
Cache::put(CacheKey::get('SERVER_SHADOWSOCKS_LAST_PUSH_AT', $server->id), time(), 3600);
|
||||
$userService = new UserService();
|
||||
@@ -73,4 +62,4 @@ class ShadowsocksTidalabController extends Controller
|
||||
'msg' => 'ok'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,9 +23,8 @@ class TrojanTidalabController extends Controller
|
||||
public function user(Request $request)
|
||||
{
|
||||
ini_set('memory_limit', -1);
|
||||
$nodeId = $request->input('node_id');
|
||||
$server = ServerTrojan::find($nodeId);
|
||||
if (!$server) {
|
||||
$server = $request->input('node_info');
|
||||
if ($server->type !== 'trojan') {
|
||||
return $this->fail([400, '节点不存在']);
|
||||
}
|
||||
Cache::put(CacheKey::get('SERVER_TROJAN_LAST_CHECK_AT', $server->id), time(), 3600);
|
||||
@@ -51,15 +50,11 @@ class TrojanTidalabController extends Controller
|
||||
// 后端提交数据
|
||||
public function submit(Request $request)
|
||||
{
|
||||
$server = ServerTrojan::find($request->input('node_id'));
|
||||
if (!$server) {
|
||||
return response([
|
||||
'ret' => 0,
|
||||
'msg' => 'server is not found'
|
||||
]);
|
||||
$server = $request->input('node_info');
|
||||
if ($server->type !== 'trojan') {
|
||||
return $this->fail([400, '节点不存在']);
|
||||
}
|
||||
$data = get_request_content();
|
||||
$data = json_decode($data, true);
|
||||
$data = json_decode(request()->getContent(), true);
|
||||
Cache::put(CacheKey::get('SERVER_TROJAN_ONLINE_USER', $server->id), count($data), 3600);
|
||||
Cache::put(CacheKey::get('SERVER_TROJAN_LAST_PUSH_AT', $server->id), time(), 3600);
|
||||
$userService = new UserService();
|
||||
@@ -78,6 +73,10 @@ class TrojanTidalabController extends Controller
|
||||
// 后端获取配置
|
||||
public function config(Request $request)
|
||||
{
|
||||
$server = $request->input('node_info');
|
||||
if ($server->type !== 'trojan') {
|
||||
return $this->fail([400, '节点不存在']);
|
||||
}
|
||||
$request->validate([
|
||||
'node_id' => 'required',
|
||||
'local_port' => 'required'
|
||||
@@ -86,7 +85,7 @@ class TrojanTidalabController extends Controller
|
||||
'local_port.required' => '本地端口不能为空'
|
||||
]);
|
||||
try {
|
||||
$json = $this->getTrojanConfig($request->input('node_id'), $request->input('local_port'));
|
||||
$json = $this->getTrojanConfig($server, $request->input('local_port'));
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
return $this->fail([500, '配置获取失败']);
|
||||
@@ -95,19 +94,15 @@ class TrojanTidalabController extends Controller
|
||||
return (json_encode($json, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
private function getTrojanConfig(int $nodeId, int $localPort)
|
||||
private function getTrojanConfig($server, int $localPort)
|
||||
{
|
||||
$server = ServerTrojan::find($nodeId);
|
||||
if (!$server) {
|
||||
return $this->fail([400, '节点不存在']);
|
||||
}
|
||||
|
||||
$protocolSettings = $server->protocol_settings;
|
||||
$json = json_decode(self::TROJAN_CONFIG);
|
||||
$json->local_port = $server->server_port;
|
||||
$json->ssl->sni = $server->server_name ? $server->server_name : $server->host;
|
||||
$json->ssl->sni = data_get($protocolSettings, 'server_name', $server->host);
|
||||
$json->ssl->cert = "/root/.cert/server.crt";
|
||||
$json->ssl->key = "/root/.cert/server.key";
|
||||
$json->api->api_port = $localPort;
|
||||
return $json;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,22 +9,30 @@ use App\Utils\CacheKey;
|
||||
use App\Utils\Helper;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\Services\UserOnlineService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class UniProxyController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private readonly UserOnlineService $userOnlineService
|
||||
) {
|
||||
}
|
||||
|
||||
// 后端获取用户
|
||||
public function user(Request $request)
|
||||
{
|
||||
ini_set('memory_limit', -1);
|
||||
Cache::put(CacheKey::get('SERVER_' . strtoupper($request->input('node_type')) . '_LAST_CHECK_AT', $request->input('node_id')), time(), 3600);
|
||||
$users = ServerService::getAvailableUsers($request->input('node_info')->group_id)->toArray();
|
||||
$node = $request->input('node_info');
|
||||
$nodeType = $node->type;
|
||||
$nodeId = $node->id;
|
||||
Cache::put(CacheKey::get('SERVER_' . strtoupper($nodeType) . '_LAST_CHECK_AT', $nodeId), time(), 3600);
|
||||
$users = ServerService::getAvailableUsers($node->group_ids);
|
||||
|
||||
$response['users'] = $users;
|
||||
|
||||
$eTag = sha1(json_encode($response));
|
||||
if (strpos($request->header('If-None-Match'), $eTag) !== false) {
|
||||
if (strpos($request->header('If-None-Match', ''), $eTag) !== false) {
|
||||
return response(null, 304);
|
||||
}
|
||||
|
||||
@@ -34,131 +42,142 @@ class UniProxyController extends Controller
|
||||
// 后端提交数据
|
||||
public function push(Request $request)
|
||||
{
|
||||
$res = json_decode(get_request_content(), true);
|
||||
$data = array_filter($res, function ($item) {
|
||||
return is_array($item) && count($item) === 2 && is_numeric($item[0]) && is_numeric($item[1]);
|
||||
});
|
||||
$nodeType = $request->input('node_type');
|
||||
$nodeId = $request->input('node_id');
|
||||
// 增加单节点多服务器统计在线人数
|
||||
$ip = $request->ip();
|
||||
$id = $request->input("id");
|
||||
$time = time();
|
||||
$cacheKey = CacheKey::get('MULTI_SERVER_' . strtoupper($nodeType) . '_ONLINE_USER', $nodeId);
|
||||
|
||||
// 1、获取节点节点在线人数缓存
|
||||
$onlineUsers = Cache::get($cacheKey) ?? [];
|
||||
$onlineCollection = collect($onlineUsers);
|
||||
// 过滤掉超过600秒的记录
|
||||
$onlineCollection = $onlineCollection->reject(function ($item) use ($time) {
|
||||
return $item['time'] < ($time - 600);
|
||||
});
|
||||
// 定义数据
|
||||
$updatedItem = [
|
||||
'id' => $id ?? $ip,
|
||||
'ip' => $ip,
|
||||
'online_user' => count($data),
|
||||
'time' => $time
|
||||
];
|
||||
|
||||
$existingItemIndex = $onlineCollection->search(function ($item) use ($updatedItem) {
|
||||
return ($item['id'] ?? '') === $updatedItem['id'];
|
||||
});
|
||||
if ($existingItemIndex !== false) {
|
||||
$onlineCollection[$existingItemIndex] = $updatedItem;
|
||||
} else {
|
||||
$onlineCollection->push($updatedItem);
|
||||
$res = json_decode(request()->getContent(), true);
|
||||
if (!is_array($res)) {
|
||||
return $this->fail([422, 'Invalid data format']);
|
||||
}
|
||||
$onlineUsers = $onlineCollection->all();
|
||||
Cache::put($cacheKey, $onlineUsers, 3600);
|
||||
$data = array_filter($res, function ($item) {
|
||||
return is_array($item)
|
||||
&& count($item) === 2
|
||||
&& is_numeric($item[0])
|
||||
&& is_numeric($item[1]);
|
||||
});
|
||||
if (empty($data)) {
|
||||
return $this->success(true);
|
||||
}
|
||||
$node = $request->input('node_info');
|
||||
$nodeType = $node->type;
|
||||
$nodeId = $node->id;
|
||||
|
||||
Cache::put(
|
||||
CacheKey::get('SERVER_' . strtoupper($nodeType) . '_ONLINE_USER', $nodeId),
|
||||
count($data),
|
||||
3600
|
||||
);
|
||||
Cache::put(
|
||||
CacheKey::get('SERVER_' . strtoupper($nodeType) . '_LAST_PUSH_AT', $nodeId),
|
||||
time(),
|
||||
3600
|
||||
);
|
||||
|
||||
$online_user = $onlineCollection->sum('online_user');
|
||||
Cache::put(CacheKey::get('SERVER_' . strtoupper($nodeType) . '_ONLINE_USER', $nodeId), $online_user, 3600);
|
||||
Cache::put(CacheKey::get('SERVER_' . strtoupper($nodeType) . '_LAST_PUSH_AT', $nodeId), time(), 3600);
|
||||
$userService = new UserService();
|
||||
$userService->trafficFetch($request->input('node_info')->toArray(), $nodeType, $data, $ip);
|
||||
$userService->trafficFetch($node->toArray(), $nodeType, $data);
|
||||
return $this->success(true);
|
||||
}
|
||||
|
||||
// 后端获取配置
|
||||
public function config(Request $request)
|
||||
{
|
||||
$nodeType = $request->input('node_type');
|
||||
$nodeInfo = $request->input('node_info');
|
||||
switch ($nodeType) {
|
||||
case 'shadowsocks':
|
||||
$response = [
|
||||
'server_port' => $nodeInfo->server_port,
|
||||
'cipher' => $nodeInfo->cipher,
|
||||
'obfs' => $nodeInfo->obfs,
|
||||
'obfs_settings' => $nodeInfo->obfs_settings
|
||||
];
|
||||
$node = $request->input('node_info');
|
||||
$nodeType = $node->type;
|
||||
$protocolSettings = $node->protocol_settings;
|
||||
|
||||
$serverPort = $node->server_port;
|
||||
$host = $node->host;
|
||||
|
||||
$baseConfig = [
|
||||
'server_port' => (int) $serverPort,
|
||||
'network' => data_get($protocolSettings, 'network'),
|
||||
'networkSettings' => data_get($protocolSettings, 'network_settings') ?: null,
|
||||
];
|
||||
|
||||
$response = match ($nodeType) {
|
||||
'shadowsocks' => [
|
||||
...$baseConfig,
|
||||
'cipher' => $protocolSettings['cipher'],
|
||||
'obfs' => $protocolSettings['obfs'],
|
||||
'obfs_settings' => $protocolSettings['obfs_settings'],
|
||||
'server_key' => match ($protocolSettings['cipher']) {
|
||||
'2022-blake3-aes-128-gcm' => Helper::getServerKey($node->created_at, 16),
|
||||
'2022-blake3-aes-256-gcm' => Helper::getServerKey($node->created_at, 32),
|
||||
default => null
|
||||
}
|
||||
],
|
||||
'vmess' => [
|
||||
...$baseConfig,
|
||||
'tls' => (int) $protocolSettings['tls']
|
||||
],
|
||||
'trojan' => [
|
||||
...$baseConfig,
|
||||
'host' => $host,
|
||||
'server_name' => $protocolSettings['server_name'],
|
||||
],
|
||||
'vless' => [
|
||||
...$baseConfig,
|
||||
'tls' => (int) $protocolSettings['tls'],
|
||||
'flow' => $protocolSettings['flow'],
|
||||
'tls_settings' =>
|
||||
match ((int) $protocolSettings['tls']) {
|
||||
2 => $protocolSettings['reality_settings'],
|
||||
default => $protocolSettings['tls_settings']
|
||||
}
|
||||
],
|
||||
'hysteria' => [
|
||||
'server_port' => (int) $serverPort,
|
||||
'version' => (int) $protocolSettings['version'],
|
||||
'host' => $host,
|
||||
'server_name' => $protocolSettings['tls']['server_name'],
|
||||
'up_mbps' => (int) $protocolSettings['bandwidth']['up'],
|
||||
'down_mbps' => (int) $protocolSettings['bandwidth']['down'],
|
||||
...match ((int) $protocolSettings['version']) {
|
||||
1 => ['obfs' => $protocolSettings['obfs']['password'] ?? null],
|
||||
2 => [
|
||||
'obfs' => $protocolSettings['obfs']['open'] ? $protocolSettings['obfs']['type'] : null,
|
||||
'obfs-password' => $protocolSettings['obfs']['password'] ?? null
|
||||
],
|
||||
default => []
|
||||
}
|
||||
],
|
||||
default => []
|
||||
};
|
||||
|
||||
if ($nodeInfo->cipher === '2022-blake3-aes-128-gcm') {
|
||||
$response['server_key'] = Helper::getServerKey($nodeInfo->created_at, 16);
|
||||
}
|
||||
if ($nodeInfo->cipher === '2022-blake3-aes-256-gcm') {
|
||||
$response['server_key'] = Helper::getServerKey($nodeInfo->created_at, 32);
|
||||
}
|
||||
break;
|
||||
case 'vmess':
|
||||
$response = [
|
||||
'server_port' => $nodeInfo->server_port,
|
||||
'network' => $nodeInfo->network,
|
||||
'networkSettings' => $nodeInfo->networkSettings,
|
||||
'tls' => $nodeInfo->tls
|
||||
];
|
||||
break;
|
||||
case 'trojan':
|
||||
$response = [
|
||||
'host' => $nodeInfo->host,
|
||||
'server_port' => $nodeInfo->server_port,
|
||||
'server_name' => $nodeInfo->server_name,
|
||||
'network' => $nodeInfo->network,
|
||||
'networkSettings' => $nodeInfo->networkSettings,
|
||||
];
|
||||
break;
|
||||
case 'hysteria':
|
||||
$response = [
|
||||
'version' => $nodeInfo->version,
|
||||
'host' => $nodeInfo->host,
|
||||
'server_port' => $nodeInfo->server_port,
|
||||
'server_name' => $nodeInfo->server_name,
|
||||
'up_mbps' => $nodeInfo->up_mbps,
|
||||
'down_mbps' => $nodeInfo->down_mbps,
|
||||
'obfs' => $nodeInfo->is_obfs ? Helper::getServerKey($nodeInfo->created_at, 16) : null
|
||||
];
|
||||
break;
|
||||
case "vless":
|
||||
$response = [
|
||||
'server_port' => $nodeInfo->server_port,
|
||||
'network' => $nodeInfo->network,
|
||||
'network_settings' => $nodeInfo->network_settings,
|
||||
'networkSettings' => $nodeInfo->network_settings,
|
||||
'tls' => $nodeInfo->tls,
|
||||
'flow' => $nodeInfo->flow,
|
||||
'tls_settings' => $nodeInfo->tls_settings
|
||||
];
|
||||
break;
|
||||
}
|
||||
$response['base_config'] = [
|
||||
'push_interval' => (int) admin_setting('server_push_interval', 60),
|
||||
'pull_interval' => (int) admin_setting('server_pull_interval', 60)
|
||||
];
|
||||
if ($nodeInfo['route_id']) {
|
||||
$response['routes'] = ServerService::getRoutes($nodeInfo['route_id']);
|
||||
}
|
||||
$eTag = sha1(json_encode($response));
|
||||
if (strpos($request->header('If-None-Match'), $eTag) !== false) {
|
||||
return response(null, 304);
|
||||
|
||||
if (!empty($node['route_ids'])) {
|
||||
$response['routes'] = ServerService::getRoutes($node['route_ids']);
|
||||
}
|
||||
|
||||
$eTag = sha1(json_encode($response));
|
||||
if (strpos($request->header('If-None-Match', '') ?? '', $eTag) !== false) {
|
||||
return response(null, 304);
|
||||
}
|
||||
return response($response)->header('ETag', "\"{$eTag}\"");
|
||||
}
|
||||
|
||||
// 后端提交在线数据
|
||||
public function alive(Request $request)
|
||||
// 获取在线用户数据(wyx2685
|
||||
public function alivelist(Request $request): JsonResponse
|
||||
{
|
||||
return $this->success(true);
|
||||
$node = $request->input('node_info');
|
||||
$deviceLimitUsers = ServerService::getAvailableUsers($node->group_ids)
|
||||
->where('device_limit', '>', 0);
|
||||
$alive = $this->userOnlineService->getAliveList($deviceLimitUsers);
|
||||
return response()->json(['alive' => (object) $alive]);
|
||||
}
|
||||
|
||||
// 后端提交在线数据
|
||||
public function alive(Request $request): JsonResponse
|
||||
{
|
||||
$node = $request->input('node_info');
|
||||
$data = json_decode(request()->getContent(), true);
|
||||
if ($data === null) {
|
||||
return response()->json([
|
||||
'error' => 'Invalid online data'
|
||||
], 400);
|
||||
}
|
||||
$this->userOnlineService->updateAliveData($data, $node->type, $node->id);
|
||||
return response()->json(['data' => true]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user