mirror of
https://github.com/lkddi/Xboard.git
synced 2026-05-01 00:47:28 +08:00
feat: Add client.subscribe.servers hook for plugin-based server extension
- Add HookManager::filter('client.subscribe.servers') hook in ClientController::subscribe()
- Allow plugins to inject custom servers into subscription responses
- Update protocol classes to support extended server configurations
- Enable dynamic server list modification before protocol processing
This commit is contained in:
@@ -56,6 +56,7 @@ class ClientController extends Controller
|
|||||||
?? General::class;
|
?? General::class;
|
||||||
|
|
||||||
$servers = ServerService::getAvailableServers($user);
|
$servers = ServerService::getAvailableServers($user);
|
||||||
|
$servers = HookManager::filter('client.subscribe.servers', $servers, $user, $request);
|
||||||
|
|
||||||
$serversFiltered = $this->filterServers(
|
$serversFiltered = $this->filterServers(
|
||||||
servers: $servers,
|
servers: $servers,
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ class Server extends Model
|
|||||||
$this->attributes['protocol_settings'] = json_encode($castedSettings);
|
$this->attributes['protocol_settings'] = json_encode($castedSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generateShadowsocksPassword(User $user): string
|
public function generateServerPassword(User $user): string
|
||||||
{
|
{
|
||||||
if ($this->type !== self::TYPE_SHADOWSOCKS) {
|
if ($this->type !== self::TYPE_SHADOWSOCKS) {
|
||||||
return $user->uuid;
|
return $user->uuid;
|
||||||
|
|||||||
@@ -42,19 +42,19 @@ class Clash extends AbstractProtocol
|
|||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'vmess') {
|
if ($item['type'] === 'vmess') {
|
||||||
array_push($proxy, self::buildVmess($user['uuid'], $item));
|
array_push($proxy, self::buildVmess($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'trojan') {
|
if ($item['type'] === 'trojan') {
|
||||||
array_push($proxy, self::buildTrojan($user['uuid'], $item));
|
array_push($proxy, self::buildTrojan($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'socks') {
|
if ($item['type'] === 'socks') {
|
||||||
array_push($proxy, self::buildSocks5($user['uuid'], $item));
|
array_push($proxy, self::buildSocks5($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'http') {
|
if ($item['type'] === 'http') {
|
||||||
array_push($proxy, self::buildHttp($user['uuid'], $item));
|
array_push($proxy, self::buildHttp($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,42 +84,42 @@ class ClashMeta extends AbstractProtocol
|
|||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'vmess') {
|
if ($item['type'] === 'vmess') {
|
||||||
array_push($proxy, self::buildVmess($user['uuid'], $item));
|
array_push($proxy, self::buildVmess($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'trojan') {
|
if ($item['type'] === 'trojan') {
|
||||||
array_push($proxy, self::buildTrojan($user['uuid'], $item));
|
array_push($proxy, self::buildTrojan($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
$item['type'] === 'vless'
|
$item['type'] === 'vless'
|
||||||
&& in_array(data_get($protocol_settings, 'network'), ['tcp', 'ws', 'grpc', 'http', 'h2'])
|
&& in_array(data_get($protocol_settings, 'network'), ['tcp', 'ws', 'grpc', 'http', 'h2'])
|
||||||
) {
|
) {
|
||||||
array_push($proxy, self::buildVless($user['uuid'], $item));
|
array_push($proxy, self::buildVless($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'hysteria') {
|
if ($item['type'] === 'hysteria') {
|
||||||
array_push($proxy, self::buildHysteria($user['uuid'], $item, $user));
|
array_push($proxy, self::buildHysteria($item['password'], $item, $user));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'tuic') {
|
if ($item['type'] === 'tuic') {
|
||||||
array_push($proxy, self::buildTuic($user['uuid'], $item));
|
array_push($proxy, self::buildTuic($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'anytls') {
|
if ($item['type'] === 'anytls') {
|
||||||
array_push($proxy, self::buildAnyTLS($user['uuid'], $item));
|
array_push($proxy, self::buildAnyTLS($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'socks') {
|
if ($item['type'] === 'socks') {
|
||||||
array_push($proxy, self::buildSocks5($user['uuid'], $item));
|
array_push($proxy, self::buildSocks5($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'http') {
|
if ($item['type'] === 'http') {
|
||||||
array_push($proxy, self::buildHttp($user['uuid'], $item));
|
array_push($proxy, self::buildHttp($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'mieru') {
|
if ($item['type'] === 'mieru') {
|
||||||
array_push($proxy, self::buildMieru($user['uuid'], $item));
|
array_push($proxy, self::buildMieru($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,22 +35,22 @@ class General extends AbstractProtocol
|
|||||||
|
|
||||||
foreach ($servers as $item) {
|
foreach ($servers as $item) {
|
||||||
if ($item['type'] === 'vmess') {
|
if ($item['type'] === 'vmess') {
|
||||||
$uri .= self::buildVmess($user['uuid'], $item);
|
$uri .= self::buildVmess($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'vless') {
|
if ($item['type'] === 'vless') {
|
||||||
$uri .= self::buildVless($user['uuid'], $item);
|
$uri .= self::buildVless($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'shadowsocks') {
|
if ($item['type'] === 'shadowsocks') {
|
||||||
$uri .= self::buildShadowsocks($item['password'], $item);
|
$uri .= self::buildShadowsocks($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'trojan') {
|
if ($item['type'] === 'trojan') {
|
||||||
$uri .= self::buildTrojan($user['uuid'], $item);
|
$uri .= self::buildTrojan($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'hysteria') {
|
if ($item['type'] === 'hysteria') {
|
||||||
$uri .= self::buildHysteria($user['uuid'], $item);
|
$uri .= self::buildHysteria($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'socks') {
|
if ($item['type'] === 'socks') {
|
||||||
$uri .= self::buildSocks($user['uuid'], $item);
|
$uri .= self::buildSocks($item['password'], $item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return response(base64_encode($uri))->header('content-type', 'text/plain');
|
return response(base64_encode($uri))->header('content-type', 'text/plain');
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ class Loon extends AbstractProtocol
|
|||||||
$uri .= self::buildShadowsocks($item['password'], $item);
|
$uri .= self::buildShadowsocks($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'vmess') {
|
if ($item['type'] === 'vmess') {
|
||||||
$uri .= self::buildVmess($user['uuid'], $item);
|
$uri .= self::buildVmess($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'trojan') {
|
if ($item['type'] === 'trojan') {
|
||||||
$uri .= self::buildTrojan($user['uuid'], $item);
|
$uri .= self::buildTrojan($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'hysteria') {
|
if ($item['type'] === 'hysteria') {
|
||||||
$uri .= self::buildHysteria($user['uuid'], $item, $user);
|
$uri .= self::buildHysteria($item['password'], $item, $user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return response($uri)
|
return response($uri)
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ class QuantumultX extends AbstractProtocol
|
|||||||
$uri .= self::buildShadowsocks($item['password'], $item);
|
$uri .= self::buildShadowsocks($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'vmess') {
|
if ($item['type'] === 'vmess') {
|
||||||
$uri .= self::buildVmess($user['uuid'], $item);
|
$uri .= self::buildVmess($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'trojan') {
|
if ($item['type'] === 'trojan') {
|
||||||
$uri .= self::buildTrojan($user['uuid'], $item);
|
$uri .= self::buildTrojan($item['password'], $item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return response(base64_encode($uri))
|
return response(base64_encode($uri))
|
||||||
|
|||||||
@@ -39,25 +39,25 @@ class Shadowrocket extends AbstractProtocol
|
|||||||
$uri .= self::buildShadowsocks($item['password'], $item);
|
$uri .= self::buildShadowsocks($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'vmess') {
|
if ($item['type'] === 'vmess') {
|
||||||
$uri .= self::buildVmess($user['uuid'], $item);
|
$uri .= self::buildVmess($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'vless') {
|
if ($item['type'] === 'vless') {
|
||||||
$uri .= self::buildVless($user['uuid'], $item);
|
$uri .= self::buildVless($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'trojan') {
|
if ($item['type'] === 'trojan') {
|
||||||
$uri .= self::buildTrojan($user['uuid'], $item);
|
$uri .= self::buildTrojan($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'hysteria') {
|
if ($item['type'] === 'hysteria') {
|
||||||
$uri .= self::buildHysteria($user['uuid'], $item);
|
$uri .= self::buildHysteria($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'tuic') {
|
if ($item['type'] === 'tuic') {
|
||||||
$uri .= self::buildTuic($user['uuid'], $item);
|
$uri .= self::buildTuic($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'anytls') {
|
if ($item['type'] === 'anytls') {
|
||||||
$uri .= self::buildAnyTLS($user['uuid'], $item);
|
$uri .= self::buildAnyTLS($item['password'], $item);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'socks') {
|
if ($item['type'] === 'socks') {
|
||||||
$uri .= self::buildSocks($user['uuid'], $item);
|
$uri .= self::buildSocks($item['password'], $item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return response(base64_encode($uri))
|
return response(base64_encode($uri))
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class Shadowsocks extends AbstractProtocol
|
|||||||
"remarks" => $server['name'],
|
"remarks" => $server['name'],
|
||||||
"server" => $server['host'],
|
"server" => $server['host'],
|
||||||
"server_port" => $server['port'],
|
"server_port" => $server['port'],
|
||||||
"password" => $user['uuid'],
|
"password" => $item['password'],
|
||||||
"method" => data_get($server, 'protocol_settings.cipher')
|
"method" => data_get($server, 'protocol_settings.cipher')
|
||||||
];
|
];
|
||||||
return $config;
|
return $config;
|
||||||
|
|||||||
@@ -85,35 +85,35 @@ class Stash extends AbstractProtocol
|
|||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'vmess') {
|
if ($item['type'] === 'vmess') {
|
||||||
array_push($proxy, self::buildVmess($user['uuid'], $item));
|
array_push($proxy, self::buildVmess($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'vless') {
|
if ($item['type'] === 'vless') {
|
||||||
array_push($proxy, $this->buildVless($user['uuid'], $item));
|
array_push($proxy, $this->buildVless($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'hysteria') {
|
if ($item['type'] === 'hysteria') {
|
||||||
array_push($proxy, self::buildHysteria($user['uuid'], $item));
|
array_push($proxy, self::buildHysteria($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'trojan') {
|
if ($item['type'] === 'trojan') {
|
||||||
array_push($proxy, self::buildTrojan($user['uuid'], $item));
|
array_push($proxy, self::buildTrojan($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'tuic') {
|
if ($item['type'] === 'tuic') {
|
||||||
array_push($proxy, self::buildTuic($user['uuid'], $item));
|
array_push($proxy, self::buildTuic($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
// if ($item['type'] === 'anytls') {
|
// if ($item['type'] === 'anytls') {
|
||||||
// array_push($proxy, self::buildAnyTLS($user['uuid'], $item));
|
// array_push($proxy, self::buildAnyTLS($item['password'], $item));
|
||||||
// array_push($proxies, $item['name']);
|
// array_push($proxies, $item['name']);
|
||||||
// }
|
// }
|
||||||
if ($item['type'] === 'socks') {
|
if ($item['type'] === 'socks') {
|
||||||
array_push($proxy, self::buildSocks5($user['uuid'], $item));
|
array_push($proxy, self::buildSocks5($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'http') {
|
if ($item['type'] === 'http') {
|
||||||
array_push($proxy, self::buildHttp($user['uuid'], $item));
|
array_push($proxy, self::buildHttp($item['password'], $item));
|
||||||
array_push($proxies, $item['name']);
|
array_push($proxies, $item['name']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,13 +40,13 @@ class Surfboard extends AbstractProtocol
|
|||||||
}
|
}
|
||||||
if ($item['type'] === 'vmess') {
|
if ($item['type'] === 'vmess') {
|
||||||
// [Proxy]
|
// [Proxy]
|
||||||
$proxies .= self::buildVmess($user['uuid'], $item);
|
$proxies .= self::buildVmess($item['password'], $item);
|
||||||
// [Proxy Group]
|
// [Proxy Group]
|
||||||
$proxyGroup .= $item['name'] . ', ';
|
$proxyGroup .= $item['name'] . ', ';
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'trojan') {
|
if ($item['type'] === 'trojan') {
|
||||||
// [Proxy]
|
// [Proxy]
|
||||||
$proxies .= self::buildTrojan($user['uuid'], $item);
|
$proxies .= self::buildTrojan($item['password'], $item);
|
||||||
// [Proxy Group]
|
// [Proxy Group]
|
||||||
$proxyGroup .= $item['name'] . ', ';
|
$proxyGroup .= $item['name'] . ', ';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,15 +46,15 @@ class Surge extends AbstractProtocol
|
|||||||
$proxyGroup .= $item['name'] . ', ';
|
$proxyGroup .= $item['name'] . ', ';
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'vmess') {
|
if ($item['type'] === 'vmess') {
|
||||||
$proxies .= self::buildVmess($user['uuid'], $item);
|
$proxies .= self::buildVmess($item['password'], $item);
|
||||||
$proxyGroup .= $item['name'] . ', ';
|
$proxyGroup .= $item['name'] . ', ';
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'trojan') {
|
if ($item['type'] === 'trojan') {
|
||||||
$proxies .= self::buildTrojan($user['uuid'], $item);
|
$proxies .= self::buildTrojan($item['password'], $item);
|
||||||
$proxyGroup .= $item['name'] . ', ';
|
$proxyGroup .= $item['name'] . ', ';
|
||||||
}
|
}
|
||||||
if ($item['type'] === 'hysteria') {
|
if ($item['type'] === 'hysteria') {
|
||||||
$proxies .= self::buildHysteria($user['uuid'], $item);
|
$proxies .= self::buildHysteria($item['password'], $item);
|
||||||
$proxyGroup .= $item['name'] . ', ';
|
$proxyGroup .= $item['name'] . ', ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class ServerService
|
|||||||
} else {
|
} else {
|
||||||
$server->port = (int) $server->port;
|
$server->port = (int) $server->port;
|
||||||
}
|
}
|
||||||
$server->password = $server->generateShadowsocksPassword($user);
|
$server->password = $server->generateServerPassword($user);
|
||||||
return $server;
|
return $server;
|
||||||
})->toArray();
|
})->toArray();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user