refactor: refactor subscription delivery logic, change payment return_url to origin_url concatenation

- Unify protocol filter configuration to client.type.field (dot-path, three-segment) format, support strict whitelist mode
- Refactor AbstractProtocol and all protocol classes for more flexible and maintainable subscription delivery
- Change payment callback logic: use origin_url concatenation instead of return_url for more accurate redirects
This commit is contained in:
xboard
2025-07-18 15:42:58 +08:00
parent e2d7b6a5e0
commit 508caebdcd
14 changed files with 334 additions and 183 deletions
+14 -6
View File
@@ -2,6 +2,7 @@
namespace App\Protocols;
use App\Models\Server;
use Illuminate\Support\Facades\File;
use Symfony\Component\Yaml\Yaml;
use App\Support\AbstractProtocol;
@@ -12,6 +13,13 @@ class Clash extends AbstractProtocol
const CUSTOM_TEMPLATE_FILE = 'resources/rules/custom.clash.yaml';
const DEFAULT_TEMPLATE_FILE = 'resources/rules/default.clash.yaml';
public $allowedProtocols = [
Server::TYPE_SHADOWSOCKS,
Server::TYPE_VMESS,
Server::TYPE_TROJAN,
Server::TYPE_SOCKS,
Server::TYPE_HTTP,
];
public function handle()
{
$servers = $this->servers;
@@ -30,7 +38,7 @@ class Clash extends AbstractProtocol
foreach ($servers as $item) {
if (
$item['type'] === 'shadowsocks'
$item['type'] === Server::TYPE_SHADOWSOCKS
&& in_array(data_get($item['protocol_settings'], 'cipher'), [
'aes-128-gcm',
'aes-192-gcm',
@@ -41,19 +49,19 @@ class Clash extends AbstractProtocol
array_push($proxy, self::buildShadowsocks($item['password'], $item));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'vmess') {
if ($item['type'] === Server::TYPE_VMESS) {
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'] === Server::TYPE_TROJAN) {
array_push($proxy, self::buildTrojan($item['password'], $item));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'socks') {
if ($item['type'] === Server::TYPE_SOCKS) {
array_push($proxy, self::buildSocks5($item['password'], $item));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'http') {
if ($item['type'] === Server::TYPE_HTTP) {
array_push($proxy, self::buildHttp($item['password'], $item));
array_push($proxies, $item['name']);
}
+45 -49
View File
@@ -2,6 +2,7 @@
namespace App\Protocols;
use App\Models\Server;
use App\Utils\Helper;
use Illuminate\Support\Facades\File;
use Symfony\Component\Yaml\Yaml;
@@ -13,49 +14,48 @@ class ClashMeta extends AbstractProtocol
const CUSTOM_TEMPLATE_FILE = 'resources/rules/custom.clashmeta.yaml';
const CUSTOM_CLASH_TEMPLATE_FILE = 'resources/rules/custom.clash.yaml';
const DEFAULT_TEMPLATE_FILE = 'resources/rules/default.clash.yaml';
public $allowedProtocols = [
Server::TYPE_SHADOWSOCKS,
Server::TYPE_VMESS,
Server::TYPE_TROJAN,
Server::TYPE_VLESS,
Server::TYPE_HYSTERIA,
Server::TYPE_TUIC,
Server::TYPE_ANYTLS,
Server::TYPE_SOCKS,
Server::TYPE_HTTP,
Server::TYPE_MIERU,
];
protected $protocolRequirements = [
'nekobox' => [
'hysteria' => [
'protocol_settings.version' => [
'2' => '1.2.7'
],
'*.vless.protocol_settings.network' => [
'whitelist' => [
'tcp' => '0.0.0',
'ws' => '0.0.0',
'grpc' => '0.0.0',
'http' => '0.0.0',
'h2' => '0.0.0',
],
'strict' => true,
],
'clashmetaforandroid' => [
'hysteria' => [
'protocol_settings.version' => [
'2' => '2.9.0'
],
],
'nekobox.hysteria.protocol_settings.version' => [
1 => '0.0.0',
2 => '1.2.7',
],
'nekoray' => [
'hysteria' => [
'protocol_settings.version' => [
'2' => '3.24'
],
],
'clashmetaforandroid.hysteria.protocol_settings.version' => [
2 => '2.9.0',
],
'verge' => [
'hysteria' => [
'protocol_settings.version' => [
'2' => '1.3.8'
],
],
'nekoray.hysteria.protocol_settings.version' => [
2 => '3.24',
],
'ClashX Meta' => [
'hysteria' => [
'protocol_settings.version' => [
'2' => '1.3.5'
],
],
'verge.hysteria.protocol_settings.version' => [
2 => '1.3.8',
],
'flclash' => [
'hysteria' => [
'protocol_settings.version' => [
'2' => '0.8.0'
],
],
'ClashX Meta.hysteria.protocol_settings.version' => [
2 => '1.3.5',
],
'flclash.hysteria.protocol_settings.version' => [
2 => '0.8.0',
],
];
@@ -78,47 +78,43 @@ class ClashMeta extends AbstractProtocol
$proxies = [];
foreach ($servers as $item) {
$protocol_settings = $item['protocol_settings'];
if ($item['type'] === 'shadowsocks') {
if ($item['type'] === Server::TYPE_SHADOWSOCKS) {
array_push($proxy, self::buildShadowsocks($item['password'], $item));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'vmess') {
if ($item['type'] === Server::TYPE_VMESS) {
array_push($proxy, self::buildVmess($item['password'], $item));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'trojan') {
if ($item['type'] === Server::TYPE_TROJAN) {
array_push($proxy, self::buildTrojan($item['password'], $item));
array_push($proxies, $item['name']);
}
if (
$item['type'] === 'vless'
&& in_array(data_get($protocol_settings, 'network'), ['tcp', 'ws', 'grpc', 'http', 'h2'])
) {
if ($item['type'] === Server::TYPE_VLESS) {
array_push($proxy, self::buildVless($item['password'], $item));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'hysteria') {
if ($item['type'] === Server::TYPE_HYSTERIA) {
array_push($proxy, self::buildHysteria($item['password'], $item, $user));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'tuic') {
if ($item['type'] === Server::TYPE_TUIC) {
array_push($proxy, self::buildTuic($item['password'], $item));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'anytls') {
if ($item['type'] === Server::TYPE_ANYTLS) {
array_push($proxy, self::buildAnyTLS($item['password'], $item));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'socks') {
if ($item['type'] === Server::TYPE_SOCKS) {
array_push($proxy, self::buildSocks5($item['password'], $item));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'http') {
if ($item['type'] === Server::TYPE_HTTP) {
array_push($proxy, self::buildHttp($item['password'], $item));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'mieru') {
if ($item['type'] === Server::TYPE_MIERU) {
array_push($proxy, self::buildMieru($item['password'], $item));
array_push($proxies, $item['name']);
}
+21 -32
View File
@@ -2,6 +2,7 @@
namespace App\Protocols;
use App\Models\Server;
use App\Utils\Helper;
use Illuminate\Support\Arr;
use App\Support\AbstractProtocol;
@@ -10,21 +11,18 @@ class General extends AbstractProtocol
{
public $flags = ['general', 'v2rayn', 'v2rayng', 'passwall', 'ssrplus', 'sagernet'];
public $allowedProtocols = [
Server::TYPE_VMESS,
Server::TYPE_VLESS,
Server::TYPE_SHADOWSOCKS,
Server::TYPE_TROJAN,
Server::TYPE_HYSTERIA,
Server::TYPE_SOCKS,
];
protected $protocolRequirements = [
'v2rayng' => [
'hysteria' => [
'protocol_settings.version' => [
'2' => '1.9.5'
],
],
],
'v2rayN' => [
'hysteria' => [
'protocol_settings.version' => [
'2' => '6.31'
],
],
],
'v2rayng.hysteria.protocol_settings.version' => [2 => '1.9.5'],
'v2rayn.hysteria.protocol_settings.version' => [2 => '6.31'],
];
public function handle()
@@ -34,24 +32,15 @@ class General extends AbstractProtocol
$uri = '';
foreach ($servers as $item) {
if ($item['type'] === 'vmess') {
$uri .= self::buildVmess($item['password'], $item);
}
if ($item['type'] === 'vless') {
$uri .= self::buildVless($item['password'], $item);
}
if ($item['type'] === 'shadowsocks') {
$uri .= self::buildShadowsocks($item['password'], $item);
}
if ($item['type'] === 'trojan') {
$uri .= self::buildTrojan($item['password'], $item);
}
if ($item['type'] === 'hysteria') {
$uri .= self::buildHysteria($item['password'], $item);
}
if ($item['type'] === 'socks') {
$uri .= self::buildSocks($item['password'], $item);
}
$uri .= match ($item['type']) {
Server::TYPE_VMESS => self::buildVmess($item['password'], $item),
Server::TYPE_VLESS => self::buildVless($item['password'], $item),
Server::TYPE_SHADOWSOCKS => self::buildShadowsocks($item['password'], $item),
Server::TYPE_TROJAN => self::buildTrojan($item['password'], $item),
Server::TYPE_HYSTERIA => self::buildHysteria($item['password'], $item),
Server::TYPE_SOCKS => self::buildSocks($item['password'], $item),
default => '',
};
}
return response(base64_encode($uri))->header('content-type', 'text/plain');
}
+13 -11
View File
@@ -3,19 +3,21 @@
namespace App\Protocols;
use App\Support\AbstractProtocol;
use App\Models\Server;
class Loon extends AbstractProtocol
{
public $flags = ['loon'];
public $allowedProtocols = [
Server::TYPE_SHADOWSOCKS,
Server::TYPE_VMESS,
Server::TYPE_TROJAN,
Server::TYPE_HYSTERIA,
];
protected $protocolRequirements = [
'loon' => [
'hysteria' => [
'protocol_settings.version' => [
'2' => '637'
],
],
],
'loon.hysteria.protocol_settings.version' => [2 => '637'],
];
public function handle()
@@ -27,17 +29,17 @@ class Loon extends AbstractProtocol
foreach ($servers as $item) {
if (
$item['type'] === 'shadowsocks'
$item['type'] === Server::TYPE_SHADOWSOCKS
) {
$uri .= self::buildShadowsocks($item['password'], $item);
}
if ($item['type'] === 'vmess') {
if ($item['type'] === Server::TYPE_VMESS) {
$uri .= self::buildVmess($item['password'], $item);
}
if ($item['type'] === 'trojan') {
if ($item['type'] === Server::TYPE_TROJAN) {
$uri .= self::buildTrojan($item['password'], $item);
}
if ($item['type'] === 'hysteria') {
if ($item['type'] === Server::TYPE_HYSTERIA) {
$uri .= self::buildHysteria($item['password'], $item, $user);
}
}
+9 -3
View File
@@ -3,10 +3,16 @@
namespace App\Protocols;
use App\Support\AbstractProtocol;
use App\Models\Server;
class QuantumultX extends AbstractProtocol
{
public $flags = ['quantumult%20x', 'quantumult-x'];
public $allowedProtocols = [
Server::TYPE_SHADOWSOCKS,
Server::TYPE_VMESS,
Server::TYPE_TROJAN,
];
public function handle()
{
@@ -14,13 +20,13 @@ class QuantumultX extends AbstractProtocol
$user = $this->user;
$uri = '';
foreach ($servers as $item) {
if ($item['type'] === 'shadowsocks') {
if ($item['type'] === Server::TYPE_SHADOWSOCKS) {
$uri .= self::buildShadowsocks($item['password'], $item);
}
if ($item['type'] === 'vmess') {
if ($item['type'] === Server::TYPE_VMESS) {
$uri .= self::buildVmess($item['password'], $item);
}
if ($item['type'] === 'trojan') {
if ($item['type'] === Server::TYPE_TROJAN) {
$uri .= self::buildTrojan($item['password'], $item);
}
}
+21 -18
View File
@@ -4,22 +4,25 @@ namespace App\Protocols;
use App\Utils\Helper;
use App\Support\AbstractProtocol;
use App\Models\Server;
class Shadowrocket extends AbstractProtocol
{
public $flags = ['shadowrocket'];
public $allowedProtocols = [
Server::TYPE_SHADOWSOCKS,
Server::TYPE_VMESS,
Server::TYPE_VLESS,
Server::TYPE_TROJAN,
Server::TYPE_HYSTERIA,
Server::TYPE_TUIC,
Server::TYPE_ANYTLS,
Server::TYPE_SOCKS,
];
protected $protocolRequirements = [
'shadowrocket' => [
'hysteria' => [
'protocol_settings.version' => [
'2' => '1993'
],
],
'anytls' => [
'base_version' => '2592'
],
],
'shadowrocket.hysteria.protocol_settings.version' => [2 => '1993'],
'shadowrocket.anytls.base_version' => '2592',
];
public function handle()
@@ -35,28 +38,28 @@ class Shadowrocket extends AbstractProtocol
$expiredDate = date('Y-m-d', $user['expired_at']);
$uri .= "STATUS=🚀↑:{$upload}GB,↓:{$download}GB,TOT:{$totalTraffic}GB💡Expires:{$expiredDate}\r\n";
foreach ($servers as $item) {
if ($item['type'] === 'shadowsocks') {
if ($item['type'] === Server::TYPE_SHADOWSOCKS) {
$uri .= self::buildShadowsocks($item['password'], $item);
}
if ($item['type'] === 'vmess') {
if ($item['type'] === Server::TYPE_VMESS) {
$uri .= self::buildVmess($item['password'], $item);
}
if ($item['type'] === 'vless') {
if ($item['type'] === Server::TYPE_VLESS) {
$uri .= self::buildVless($item['password'], $item);
}
if ($item['type'] === 'trojan') {
if ($item['type'] === Server::TYPE_TROJAN) {
$uri .= self::buildTrojan($item['password'], $item);
}
if ($item['type'] === 'hysteria') {
if ($item['type'] === Server::TYPE_HYSTERIA) {
$uri .= self::buildHysteria($item['password'], $item);
}
if ($item['type'] === 'tuic') {
if ($item['type'] === Server::TYPE_TUIC) {
$uri .= self::buildTuic($item['password'], $item);
}
if ($item['type'] === 'anytls') {
if ($item['type'] === Server::TYPE_ANYTLS) {
$uri .= self::buildAnyTLS($item['password'], $item);
}
if ($item['type'] === 'socks') {
if ($item['type'] === Server::TYPE_SOCKS) {
$uri .= self::buildSocks($item['password'], $item);
}
}
+5
View File
@@ -3,11 +3,16 @@
namespace App\Protocols;
use App\Support\AbstractProtocol;
use App\Models\Server;
class Shadowsocks extends AbstractProtocol
{
public $flags = ['shadowsocks'];
public $allowedProtocols = [
Server::TYPE_SHADOWSOCKS,
];
public function handle()
{
$servers = $this->servers;
+21 -10
View File
@@ -4,12 +4,23 @@ namespace App\Protocols;
use App\Utils\Helper;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use App\Support\AbstractProtocol;
use App\Models\Server;
class SingBox extends AbstractProtocol
{
public $flags = ['sing-box', 'hiddify', 'sfm'];
public $allowedProtocols = [
Server::TYPE_SHADOWSOCKS,
Server::TYPE_TROJAN,
Server::TYPE_VMESS,
Server::TYPE_VLESS,
Server::TYPE_HYSTERIA,
Server::TYPE_TUIC,
Server::TYPE_ANYTLS,
Server::TYPE_SOCKS,
Server::TYPE_HTTP,
];
private $config;
const CUSTOM_TEMPLATE_FILE = 'resources/rules/custom.sing-box.json';
const DEFAULT_TEMPLATE_FILE = 'resources/rules/default.sing-box.json';
@@ -85,42 +96,42 @@ class SingBox extends AbstractProtocol
$proxies = [];
foreach ($this->servers as $item) {
$protocol_settings = $item['protocol_settings'];
if ($item['type'] === 'shadowsocks') {
if ($item['type'] === Server::TYPE_SHADOWSOCKS) {
$ssConfig = $this->buildShadowsocks($item['password'], $item);
$proxies[] = $ssConfig;
}
if ($item['type'] === 'trojan') {
if ($item['type'] === Server::TYPE_TROJAN) {
$trojanConfig = $this->buildTrojan($this->user['uuid'], $item);
$proxies[] = $trojanConfig;
}
if ($item['type'] === 'vmess') {
if ($item['type'] === Server::TYPE_VMESS) {
$vmessConfig = $this->buildVmess($this->user['uuid'], $item);
$proxies[] = $vmessConfig;
}
if (
$item['type'] === 'vless'
$item['type'] === Server::TYPE_VLESS
&& in_array(data_get($protocol_settings, 'network'), ['tcp', 'ws', 'grpc', 'http', 'quic', 'httpupgrade'])
) {
$vlessConfig = $this->buildVless($this->user['uuid'], $item);
$proxies[] = $vlessConfig;
}
if ($item['type'] === 'hysteria') {
if ($item['type'] === Server::TYPE_HYSTERIA) {
$hysteriaConfig = $this->buildHysteria($this->user['uuid'], $item);
$proxies[] = $hysteriaConfig;
}
if ($item['type'] === 'tuic') {
if ($item['type'] === Server::TYPE_TUIC) {
$tuicConfig = $this->buildTuic($this->user['uuid'], $item);
$proxies[] = $tuicConfig;
}
if ($item['type'] === 'anytls') {
if ($item['type'] === Server::TYPE_ANYTLS) {
$anytlsConfig = $this->buildAnyTLS($this->user['uuid'], $item);
$proxies[] = $anytlsConfig;
}
if ($item['type'] === 'socks') {
if ($item['type'] === Server::TYPE_SOCKS) {
$socksConfig = $this->buildSocks($this->user['uuid'], $item);
$proxies[] = $socksConfig;
}
if ($item['type'] === 'http') {
if ($item['type'] === Server::TYPE_HTTP) {
$httpConfig = $this->buildHttp($this->user['uuid'], $item);
$proxies[] = $httpConfig;
}
+20 -8
View File
@@ -6,10 +6,22 @@ use Symfony\Component\Yaml\Yaml;
use App\Utils\Helper;
use Illuminate\Support\Facades\File;
use App\Support\AbstractProtocol;
use App\Models\Server;
class Stash extends AbstractProtocol
{
public $flags = ['stash'];
public $allowedProtocols = [
Server::TYPE_SHADOWSOCKS,
Server::TYPE_VMESS,
Server::TYPE_VLESS,
Server::TYPE_HYSTERIA,
Server::TYPE_TROJAN,
Server::TYPE_TUIC,
// Server::TYPE_ANYTLS,
Server::TYPE_SOCKS,
Server::TYPE_HTTP,
];
protected $protocolRequirements = [
'stash' => [
'anytls' => [
@@ -80,27 +92,27 @@ class Stash extends AbstractProtocol
$proxies = [];
foreach ($servers as $item) {
if ($item['type'] === 'shadowsocks') {
if ($item['type'] === Server::TYPE_SHADOWSOCKS) {
array_push($proxy, self::buildShadowsocks($item['password'], $item));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'vmess') {
if ($item['type'] === Server::TYPE_VMESS) {
array_push($proxy, self::buildVmess($item['password'], $item));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'vless') {
if ($item['type'] === Server::TYPE_VLESS) {
array_push($proxy, $this->buildVless($item['password'], $item));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'hysteria') {
if ($item['type'] === Server::TYPE_HYSTERIA) {
array_push($proxy, self::buildHysteria($item['password'], $item));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'trojan') {
if ($item['type'] === Server::TYPE_TROJAN) {
array_push($proxy, self::buildTrojan($item['password'], $item));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'tuic') {
if ($item['type'] === Server::TYPE_TUIC) {
array_push($proxy, self::buildTuic($item['password'], $item));
array_push($proxies, $item['name']);
}
@@ -108,11 +120,11 @@ class Stash extends AbstractProtocol
// array_push($proxy, self::buildAnyTLS($item['password'], $item));
// array_push($proxies, $item['name']);
// }
if ($item['type'] === 'socks') {
if ($item['type'] === Server::TYPE_SOCKS) {
array_push($proxy, self::buildSocks5($item['password'], $item));
array_push($proxies, $item['name']);
}
if ($item['type'] === 'http') {
if ($item['type'] === Server::TYPE_HTTP) {
array_push($proxy, self::buildHttp($item['password'], $item));
array_push($proxies, $item['name']);
}
+9 -3
View File
@@ -5,10 +5,16 @@ namespace App\Protocols;
use App\Utils\Helper;
use Illuminate\Support\Facades\File;
use App\Support\AbstractProtocol;
use App\Models\Server;
class Surfboard extends AbstractProtocol
{
public $flags = ['surfboard'];
public $allowedProtocols = [
Server::TYPE_SHADOWSOCKS,
Server::TYPE_VMESS,
Server::TYPE_TROJAN,
];
const CUSTOM_TEMPLATE_FILE = 'resources/rules/custom.surfboard.conf';
const DEFAULT_TEMPLATE_FILE = 'resources/rules/default.surfboard.conf';
@@ -25,7 +31,7 @@ class Surfboard extends AbstractProtocol
foreach ($servers as $item) {
if (
$item['type'] === 'shadowsocks'
$item['type'] === Server::TYPE_SHADOWSOCKS
&& in_array(data_get($item, 'protocol_settings.cipher'), [
'aes-128-gcm',
'aes-192-gcm',
@@ -38,13 +44,13 @@ class Surfboard extends AbstractProtocol
// [Proxy Group]
$proxyGroup .= $item['name'] . ', ';
}
if ($item['type'] === 'vmess') {
if ($item['type'] === Server::TYPE_VMESS) {
// [Proxy]
$proxies .= self::buildVmess($item['password'], $item);
// [Proxy Group]
$proxyGroup .= $item['name'] . ', ';
}
if ($item['type'] === 'trojan') {
if ($item['type'] === Server::TYPE_TROJAN) {
// [Proxy]
$proxies .= self::buildTrojan($item['password'], $item);
// [Proxy Group]
+12 -11
View File
@@ -5,6 +5,7 @@ namespace App\Protocols;
use App\Utils\Helper;
use Illuminate\Support\Facades\File;
use App\Support\AbstractProtocol;
use App\Models\Server;
class Surge extends AbstractProtocol
{
@@ -12,14 +13,14 @@ class Surge extends AbstractProtocol
const CUSTOM_TEMPLATE_FILE = 'resources/rules/custom.surge.conf';
const DEFAULT_TEMPLATE_FILE = 'resources/rules/default.surge.conf';
public $allowedProtocols = [
Server::TYPE_SHADOWSOCKS,
Server::TYPE_VMESS,
Server::TYPE_TROJAN,
Server::TYPE_HYSTERIA,
];
protected $protocolRequirements = [
'surge' => [
'hysteria' => [
'protocol_settings.version' => [
'2' => '2398'
],
],
],
'surge.hysteria.protocol_settings.version' => [2 => '2398'],
];
public function handle()
@@ -34,7 +35,7 @@ class Surge extends AbstractProtocol
foreach ($servers as $item) {
if (
$item['type'] === 'shadowsocks'
$item['type'] === Server::TYPE_SHADOWSOCKS
&& in_array(data_get($item, 'protocol_settings.cipher'), [
'aes-128-gcm',
'aes-192-gcm',
@@ -45,15 +46,15 @@ class Surge extends AbstractProtocol
$proxies .= self::buildShadowsocks($item['password'], $item);
$proxyGroup .= $item['name'] . ', ';
}
if ($item['type'] === 'vmess') {
if ($item['type'] === Server::TYPE_VMESS) {
$proxies .= self::buildVmess($item['password'], $item);
$proxyGroup .= $item['name'] . ', ';
}
if ($item['type'] === 'trojan') {
if ($item['type'] === Server::TYPE_TROJAN) {
$proxies .= self::buildTrojan($item['password'], $item);
$proxyGroup .= $item['name'] . ', ';
}
if ($item['type'] === 'hysteria') {
if ($item['type'] === Server::TYPE_HYSTERIA) {
$proxies .= self::buildHysteria($item['password'], $item);
$proxyGroup .= $item['name'] . ', ';
}