dd/app/Services/ServiceFnPoolV2rayTo.php
2026-08-12 14:00:47 +08:00

1061 lines
37 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace App\Services;
class ServiceFnPoolV2rayTo
{
public function singbox($cPoolV2ray)
{
$i = 0;
foreach ($cPoolV2ray as $aPoolV2ray) {
$i++;
// echo $i.":<br>";
if ($i <= 0) {
// continue;
}
if ($i >= 100) {
// continue;
}
$aPoolSingbox = $this->singbox_row($aPoolV2ray);
if (!$aPoolSingbox) continue; //测试用
t($aPoolV2ray);
t($aPoolSingbox);
echo "=======================================================";
}
exit;
}
public function singbox_row($aPoolV2ray)
{
$aNode = $aPoolV2ray;
if (isset($aPoolV2ray['protocolType'])) {
$aPoolV2ray['protocolType'] = $this->removeUtf8Bom($aPoolV2ray['protocolType']);
}
$sProtocol = $aPoolV2ray['protocolType'] ?? '';
if (isset($aPoolV2ray["config"]) && !is_array($aPoolV2ray["config"])) {
$aPoolV2ray["config"] = rawurldecode($aPoolV2ray["config"]);
}
$sModTo = 'mod_to_'.$sProtocol;
if (!method_exists($this, $sModTo)) {
return false; // 没做对应处理的直接排除
}
$aNode = $this->$sModTo($aPoolV2ray);
return $aNode;
}
private function mod_to_socks(array $aV2ray): array // 过关,可用性接近
{
$sConfigStr = $aV2ray['config'] ?? '';
if (empty($sConfigStr)) {
return $aV2ray;
}
// 1. 剥离尾部锚点 (#) 与 Query 参数 (?)
$sConfigStr = explode('#', $sConfigStr, 2)[0];
$sConfigStr = explode('?', $sConfigStr, 2)[0];
$sUsername = '';
$sPassword = '';
$sHostInfo = $sConfigStr;
// 2. 判断是否存在认证信息 (user:pass@host:port)
if (str_contains($sConfigStr, '@')) {
$aTmpParts = explode('@', $sConfigStr, 2);
$sAuthInfo = $aTmpParts[0] ?? '';
$sHostInfo = $aTmpParts[1] ?? '';
// 兼容处理:尝试 Base64 解码,若解不出或不含冒号则按明文处理
$sDecodedAuth = $this->tomBase64Decode($sAuthInfo);
if ($sDecodedAuth && str_contains($sDecodedAuth, ':')) {
$sAuthInfo = $sDecodedAuth;
}
$aAuthParts = explode(':', $sAuthInfo, 2);
$sUsername = rawurldecode($aAuthParts[0] ?? '');
$sPassword = rawurldecode($aAuthParts[1] ?? '');
}
// 3. 提取地址与端口
$aHostParts = explode(':', $sHostInfo, 2);
$sServer = $aHostParts[0] ?? '';
$iPort = (int) ($aHostParts[1] ?? 1080);
// 4. 组装 Sing-box Socks5 节点结构
$aNode = [
'type' => 'socks',
'tag' => (string) ($aV2ray['country'] ?? 'Socks_Node'),
'server' => $sServer,
'server_port' => $iPort,
];
// 只有当存在账号密码时才写入,避免空字符串影响 Sing-box 鉴权逻辑
if ($sUsername !== '') {
$aNode['username'] = $sUsername;
}
if ($sPassword !== '') {
$aNode['password'] = $sPassword;
}
$aV2ray['config'] = $aNode;
return $aV2ray;
}
private function mod_to_trojan(array $aV2ray): array // 过大关飙绿反而比原始v2ray可用更多了
{
$sConfigStr = $aV2ray['config'] ?? '';
if (empty($sConfigStr)) {
return $aV2ray;
}
// 1. 拆分密码与地址
$aTmpParts = explode('@', $sConfigStr, 2);
$sPassword = $aTmpParts[0] ?? '';
$sRestStr = $aTmpParts[1] ?? '';
// 2. 拆分地址端口与 Query 参数
$aTmpParts = explode('?', $sRestStr, 2);
$sAddrFull = $aTmpParts[0] ?? '';
$sQueryParamsStr = $aTmpParts[1] ?? '';
// 剥离尾部锚点 (#) 影响
$sAddrFull = explode('#', $sAddrFull, 2)[0];
$sQueryParamsStr = explode('#', $sQueryParamsStr, 2)[0];
// 3. 提取 Server IP/域名 及 Port
$aTmpParts = explode(':', $sAddrFull, 2);
$sServer = $aTmpParts[0] ?? '';
$iPort = (int) ($aTmpParts[1] ?? 443);
// 4. 解析 Query 查询参数
$aCustom = [];
if (!empty($sQueryParamsStr)) {
parse_str($sQueryParamsStr, $aCustom);
}
// 5. 组装 Trojan 基础节点
$aNode = [
'type' => 'trojan',
'tag' => (string) ($aV2ray['country'] ?? 'Trojan_Node'),
'server' => $sServer,
'server_port' => $iPort,
'password' => $sPassword,
];
// 6. Trojan 协议原生必须开启 TLS
$aTls = [
'enabled' => true,
];
// SNI 与 Host 逻辑对齐
$sSni = $aCustom['sni'] ?? $aCustom['host'] ?? '';
if (!empty($sSni)) {
$aTls['server_name'] = $this->parseServerName($sSni, $sSni);
}
if (!empty($aCustom['alpn'])) {
$aTls['alpn'] = array_filter(explode(',', $aCustom['alpn']));
}
// 正确解析 allowInsecure 字符串
if (isset($aCustom['allowInsecure'])) {
$sInsecure = (string) $aCustom['allowInsecure'];
$aTls['insecure'] = in_array(strtolower($sInsecure), ['1', 'true', 'yes'], true);
}
// uTLS 指纹伪装
if (!empty($aCustom['fp'])) {
$sFingerprint = $aCustom['fp'] === 'random' ? 'chrome' : $aCustom['fp'];
$aTls['utls'] = [
'enabled' => true,
'fingerprint' => $sFingerprint,
];
}
$aNode['tls'] = $aTls;
// 7. 构建 Transport 传输层配置
$sNetType = $aCustom['type'] ?? 'tcp';
$aTransport = [];
if ($sNetType === 'ws') {
$aTransport['type'] = 'ws';
if (!empty($aCustom['path'])) {
$aTransport['path'] = rawurldecode($aCustom['path']);
}
// WS 报头主机名兜底
$sHost = $aCustom['host'] ?? $aTls['server_name'] ?? '';
if (!empty($sHost)) {
$aTransport['headers'] = ['Host' => $sHost];
}
} elseif ($sNetType === 'grpc') {
$aTransport['type'] = 'grpc';
if (!empty($aCustom['serviceName'])) {
$aTransport['service_name'] = $aCustom['serviceName'];
}
}
if (!empty($aTransport)) {
$aNode['transport'] = $aTransport;
}
$aV2ray['config'] = $aNode;
return $aV2ray;
}
private function mod_to_hysteria2(array $aV2ray): array // 过关,可用性差不多
{
$sConfigStr = $aV2ray['config'] ?? '';
if (empty($sConfigStr)) {
return $aV2ray;
}
// 1. 拆分 Password 与 后续地址信息
$aTmpParts = explode('@', $sConfigStr, 2);
$sPassword = $aTmpParts[0] ?? '';
$sRestStr = $aTmpParts[1] ?? '';
// 2. 剥离尾部锚点 (#) 与 拆分 Query 参数 (?)
$sRestStr = explode('#', $sRestStr, 2)[0];
$aTmpParts = explode('?', $sRestStr, 2);
$sAddrFull = $aTmpParts[0] ?? '';
$sQueryParamsStr = $aTmpParts[1] ?? '';
// 3. 提取 Server IP/域名 及 Port
$aTmpParts = explode(':', $sAddrFull, 2);
$sServer = $aTmpParts[0] ?? '';
$iPort = (int) ($aTmpParts[1] ?? 443);
// 4. 原生解析 Query 查询参数
$aQueryParams = [];
if (!empty($sQueryParamsStr)) {
parse_str($sQueryParamsStr, $aQueryParams);
}
// 5. 组装 Hysteria2 基础节点结构
$aNode = [
'type' => 'hysteria2',
'tag' => (string) ($aV2ray['country'] ?? 'Hy2_Node'),
'server' => $sServer,
'server_port' => $iPort,
'password' => rawurldecode($sPassword),
];
// 6. Hysteria2 强制开启 TLS 配置
$aTls = [
'enabled' => true,
];
$sSni = $aQueryParams['sni'] ?? $aQueryParams['host'] ?? '';
if (!empty($sSni)) {
$aTls['server_name'] = $this->parseServerName($sSni, $sSni);
}
if (!empty($aQueryParams['alpn'])) {
$aTls['alpn'] = array_filter(explode(',', $aQueryParams['alpn']));
}
// 安全解析 insecure
if (isset($aQueryParams['insecure'])) {
$sInsecure = (string) $aQueryParams['insecure'];
$aTls['insecure'] = in_array(strtolower($sInsecure), ['1', 'true', 'yes'], true);
}
$aNode['tls'] = $aTls;
// 7. 构建 Obfs 混淆配置
$sObfsType = $aQueryParams['obfs'] ?? '';
$sObfsPwd = $aQueryParams['obfs-password'] ?? $aQueryParams['obfs_password'] ?? '';
if (!empty($sObfsType) || !empty($sObfsPwd)) {
$aNode['obfs'] = [
'type' => !empty($sObfsType) ? $sObfsType : 'salamander',
'password' => $sObfsPwd,
];
}
// 8. 支持带宽速率限制参数(若存在)
if (!empty($aQueryParams['up'])) {
$aNode['up_mbps'] = (int) $aQueryParams['up'];
}
if (!empty($aQueryParams['down'])) {
$aNode['down_mbps'] = (int) $aQueryParams['down'];
}
$aV2ray['config'] = $aNode;
return $aV2ray;
}
private function mod_to_ss(array $aV2ray) // 过关,两边都不可用,但无报错
{
$sConfigStr = $aV2ray['config'] ?? '';
if (empty($sConfigStr)) {
return false;
}
$sMethod = '';
$sPassword = '';
$sServer = '';
$iPort = 0;
// 1. 先尝试将整体进行 Base64 解码(兼容老的全 Base64 格式ss://BASE64#tag
$sDecodedAll = $this->tomBase64Decode(explode('#', $sConfigStr)[0] ?? '');
if ($sDecodedAll && str_contains($sDecodedAll, '@') && str_contains($sDecodedAll, ':')) {
// 解码成功且包含标准结构
$sConfigStr = $sDecodedAll;
}
// 2. 剥离 URL 锚点 (#) 与 Query 参数 (?)
$sConfigStr = explode('#', $sConfigStr, 2)[0];
$aUrlParts = explode('?', $sConfigStr, 2);
$sMainInfo = $aUrlParts[0]; // 剩下 method:password@host:port 或 Base64(method:password)@host:port
// 3. 拆分 账号信息 与 地址端口
$aTmpParts = explode('@', $sMainInfo, 2);
if (count($aTmpParts) < 2) {
return false;
}
$sUserInfo = $aTmpParts[0];
$sHostInfo = $aTmpParts[1];
// 4. 解析账号信息 (method:password)
// 先尝试 Base64 解码,解不出来则说明本身就是明文
$sDecodedUser = $this->tomBase64Decode($sUserInfo);
if ($sDecodedUser && str_contains($sDecodedUser, ':')) {
$sUserInfo = $sDecodedUser;
}
$aUserParts = explode(':', $sUserInfo, 2);
$sMethod = $aUserParts[0] ?? '';
$sPassword = $aUserParts[1] ?? '';
// 5. 解析地址与端口 (host:port)
$aHostParts = explode(':', $sHostInfo, 2);
$sServer = $aHostParts[0] ?? '';
$iPort = (int) ($aHostParts[1] ?? 0);
// 6. 核心加密算法白名单校验
$aAllowedCiphers = [
'2022-blake3-aes-128-gcm',
'2022-blake3-aes-256-gcm',
'2022-blake3-chacha20-poly1305',
'aes-128-gcm',
'aes-192-gcm',
'aes-256-gcm',
'chacha20-ietf-poly1305',
'xchacha20-ietf-poly1305',
];
if (!in_array(strtolower($sMethod), $aAllowedCiphers, true) || empty($sServer) || $iPort <= 0) {
return false;
}
// 7. 组装 Sing-box Shadowsocks 节点结构
$aNode = [
'type' => 'shadowsocks',
'tag' => (string) ($aV2ray['country'] ?? 'SS_Node'),
'server' => $sServer,
'server_port' => $iPort,
'method' => strtolower($sMethod),
'password' => $sPassword,
];
$aV2ray['config'] = $aNode;
return $aV2ray;
}
private function mod_to_vmess(array $aV2ray): array // 过关,都不可用,但是无报错
{
// 1. 类型安全防御:确保 $aConfig 一定是数组
$aConfig = $aV2ray['config'] ?? [];
if (is_string($aConfig)) {
$aConfig = json_decode($aConfig, true) ?? [];
}
if (!is_array($aConfig)) {
$aConfig = [];
}
// 2. 基础节点属性映射
$aNode = [
'type' => 'vmess',
'tag' => (string) ($aV2ray['country'] ?? ''),
'server' => (string) ($aConfig['add'] ?? ''),
'server_port' => (int) ($aConfig['port'] ?? 0),
'uuid' => (string) ($aConfig['id'] ?? ''),
'security' => !empty($aConfig['scy']) ? (string) $aConfig['scy'] : 'auto',
'alter_id' => (int) ($aConfig['aid'] ?? 0),
];
// 3. 传输层 (Transport) 映射逻辑
$sV2rayNet = strtolower((string) ($aConfig['net'] ?? 'tcp'));
$sV2rayType = strtolower((string) ($aConfig['type'] ?? 'none'));
$sRawPath = (string) ($aConfig['path'] ?? '');
$sPath = !empty($sRawPath) ? rawurldecode($sRawPath) : '/';
$sHost = (string) ($aConfig['host'] ?? '');
$aTransport = [];
// 分支 ATCP + HTTP 伪装
if ($sV2rayNet === 'tcp' && $sV2rayType === 'http') {
$aTransport['type'] = 'http';
$aTransport['path'] = $sPath;
if (!empty($sHost)) {
$aTransport['host'] = array_map('trim', explode(',', $sHost));
}
}
// 分支 BWebSocket 传输
elseif ($sV2rayNet === 'ws') {
$aTransport['type'] = 'ws';
$aTransport['path'] = $sPath;
if (!empty($sHost)) {
$aTransport['headers'] = ['Host' => $sHost];
}
}
// 分支 CgRPC 传输
elseif ($sV2rayNet === 'grpc') {
$aTransport['type'] = 'grpc';
$aTransport['service_name'] = $sRawPath;
}
// 分支 D其他非 TCP 传输(如 mkcp, quic
elseif (!in_array($sV2rayNet, ['tcp', 'none', 'raw', ''], true)) {
$aTransport['type'] = $sV2rayNet;
}
if (!empty($aTransport)) {
$aNode['transport'] = $aTransport;
}
// 4. TLS 配置映射
$sTlsType = strtolower((string) ($aConfig['tls'] ?? ''));
if ($sTlsType === 'tls') {
$sServerName = !empty($sHost) ? $sHost : $aNode['server'];
// 兼容类内 parseServerName 方法
if (method_exists($this, 'parseServerName')) {
$sServerName = $this->parseServerName($sServerName, $sServerName);
}
$aNode['tls'] = [
'enabled' => true,
'server_name' => $sServerName,
];
}
// 5. 替换配置并输出同等结构
$aV2ray['config'] = $aNode;
return $aV2ray;
}
private function mod_to_vless(array $aV2ray): array // 过关,可用性跟没转前差不多
{
$sConfigStr = $aV2ray['config'] ?? '';
// 1. 拆分 UUID 与 后续配置 (uuid@host:port?query)
$aTmpParts = explode('@', $sConfigStr, 2);
$sUuid = $aTmpParts[0] ?? '';
$sRestStr = $aTmpParts[1] ?? '';
// 2. 拆分 地址端口 与 Query 查询参数
$aTmpParts = explode('?', $sRestStr, 2);
$sAddrFull = $aTmpParts[0] ?? '';
$sQueryParamsStr = $aTmpParts[1] ?? '';
// 3. 提取 Server IP/域名 及 Port
$aTmpParts = explode(':', $sAddrFull, 2);
$sServer = $aTmpParts[0] ?? '';
$iPort = (int) ($aTmpParts[1] ?? 443);
// 4. 解析 Query 查询参数
$aQueryParams = [];
if (!empty($sQueryParamsStr)) {
parse_str($sQueryParamsStr, $aQueryParams);
}
// 5. 组装 Sing-box VLESS 基础节点属性
$aNode = [
'type' => 'vless',
'tag' => (string) ($aV2ray['country'] ?? 'VLESS_Node'),
'server' => $sServer,
'server_port' => $iPort,
'uuid' => $sUuid,
];
if (isset($aQueryParams['packetEncoding']) && $aQueryParams['packetEncoding'] !== 'none') {
$aNode['packet_encoding'] = $aQueryParams['packetEncoding'];
}
if (!empty($aQueryParams['flow'])) {
$aNode['flow'] = $aQueryParams['flow'];
}
// 6. 构建 Transport 传输层配置
$aTransport = [];
$sRawType = $aQueryParams['type'] ?? 'tcp';
$sHeaderType = $aQueryParams['headerType'] ?? '';
if ($sRawType === 'ws') {
$aTransport['type'] = 'ws';
if (!empty($aQueryParams['path'])) {
$aTransport['path'] = rawurldecode($aQueryParams['path']);
}
if (!empty($aQueryParams['host'])) {
$aTransport['headers'] = ['Host' => $aQueryParams['host']];
}
} elseif ($sRawType === 'grpc') {
$aTransport['type'] = 'grpc';
if (!empty($aQueryParams['serviceName'])) {
$aTransport['service_name'] = $aQueryParams['serviceName'];
}
} elseif ($sHeaderType === 'http' || $sRawType === 'http') {
$aTransport['type'] = 'http';
if (!empty($aQueryParams['path'])) {
$aTransport['path'] = rawurldecode($aQueryParams['path']);
}
if (!empty($aQueryParams['host'])) {
$aTransport['host'] = explode(',', $aQueryParams['host']);
}
}
if (!empty($aTransport)) {
$aNode['transport'] = $aTransport;
}
// 7. 构建 TLS / Reality / uTLS 配置
$aTls = [];
$sSecurity = $aQueryParams['security'] ?? '';
// 判断是否开启 TLS / Reality
if (in_array($sSecurity, ['tls', 'reality'])) {
$aTls['enabled'] = true;
if (!empty($aQueryParams['sni'])) {
$aTls['server_name'] = $this->parseServerName($aQueryParams['sni'], $aQueryParams['sni']);
}
if (!empty($aQueryParams['alpn'])) {
$aTls['alpn'] = array_filter(explode(',', $aQueryParams['alpn']));
}
// uTLS 伪装
if (!empty($aQueryParams['fp'])) {
$sFingerprint = $aQueryParams['fp'] === 'random' ? 'chrome' : $aQueryParams['fp'];
$aTls['utls'] = [
'enabled' => true,
'fingerprint' => $sFingerprint,
];
}
// Reality 特性
if ($sSecurity === 'reality') {
$aReality = ['enabled' => true];
if (!empty($aQueryParams['pbk'])) {
$aReality['public_key'] = $aQueryParams['pbk'];
}
if (isset($aQueryParams['sid'])) {
$aReality['short_id'] = (string) $aQueryParams['sid'];
}
$aTls['reality'] = $aReality;
}
$aNode['tls'] = $aTls;
}
$aV2ray['config'] = $aNode;
return $aV2ray;
}
private function tomBase64Decode(mixed $xInput): string
{
// 1. 防御性类型检查
if (!is_string($xInput) || $xInput === '') {
return (string) $xInput;
}
// 2. 开启严格模式解码
$sDecoded = base64_decode($xInput, true);
if ($sDecoded === false) {
return $xInput;
}
// 3. 反向验证:确保它不是像 humanity 这种恰好能被解码的纯普通文本
if (base64_encode($sDecoded) !== $xInput) {
return $xInput;
}
// 4. 核心:校验解码后的数据是否为合法 UTF-8 文本,且不包含不可打印控制字符(\x00-\x08, \x0B-\x0C, \x0E-\x1F
$bIsValidUtf8 = mb_check_encoding($sDecoded, 'UTF-8');
$bHasControlChars = (bool) preg_match('/[\x00-\x08\x0B\x0C\x0E-\x1F]/', $sDecoded);
if ($bIsValidUtf8 && !$bHasControlChars) {
return $sDecoded; // 解码出来是合法的正常文本(包含中文、英文、数字等)
}
// 解码出来包含真正的二进制控制符(乱码),说明输入原本就是纯字符串,返回原值
return rawurldecode($xInput);
}
public function test_allXieyi($cPoolV2ray)
{
$aXieyi = [];
foreach ($cPoolV2ray as $aV2ray) {
$sXieyi = $aV2ray["protocolType"];
$sXieyi = $this->removeUtf8Bom($sXieyi);
$iXieyi = $aXieyi[$sXieyi] ?? 0;
$iXieyi++;
$aXieyi[$sXieyi] = $iXieyi;
}
return $aXieyi;
}
private function removeUtf8Bom(string $sInput): string
{
if (str_starts_with($sInput, "\xEF\xBB\xBF")) {
return substr($sInput, 3);
}
return $sInput;
}
private function parseServerName(string $sSni, string $sFallbackServer): string
{
$sSni = trim($sSni);
$sSni = rawurldecode($sSni);
if (empty($sSni)) {
return $sFallbackServer;
}
// 针对包含 http:// 或 https:// 的情况进行解析
if (preg_match('#^https?://#i', $sSni)) {
$aUrl = parse_url($sSni);
$sSni = $aUrl['host'] ?? '';
}
// 剔除可能残余的路径与端口号 (例如 domain.com/path 或 domain.com:8080)
if (str_contains($sSni, '/')) {
$sSni = explode('/', $sSni)[0];
}
if (str_contains($sSni, ':')) {
$sSni = explode(':', $sSni)[0];
}
// 若提取后仍为空,回退到节点自身的 server 字段
return !empty($sSni) ? $sSni : $sFallbackServer;
}
// private function mod_to_vless($aV2ray)
// {
// $sConfig = $aV2ray['config'] ?? '';
//
// $aTmp = explode("@", $sConfig, 2);
// $sPwd = $aTmp[0] ?? ''; // *
// $sConfig = $aTmp[1] ?? '';
//
// $aTmp = explode("?", $sConfig, 2);
// $sAddrFull = $aTmp[0];
// $sConfig = $aTmp[1];
//
// $aTmp = explode(":", $sAddrFull, 2);
// $sAddr = $aTmp[0] ?? ''; // *
// $sPort = $aTmp[1] ?? ''; // *
//
// $aCustomTmp = explode("&", $sConfig);
// $aCustom = [];
// foreach ($aCustomTmp as $aCustomRow) {
// $aTmp = explode("=", $aCustomRow, 2);
// $k = $aTmp[0] ?? '';
// $v = $aTmp[1] ?? '';
// $aCustom[$k] = $v; // *
// }
//
// $aNode = [
// 'type' => 'vless',
// 'tag' => $aV2ray['country'] ?? '',
// 'server' => $sAddr,
// 'server_port' => (int) $sPort,
// 'uuid' => $sPwd,
// ];
// if (isset($aCustom["packetEncoding"]) && $aCustom["packetEncoding"] != "none") {
// $aNode["packet_encoding"] = $aCustom["packetEncoding"];
// }
// if (isset($aCustom["flow"])) {
// $aNode["flow"] = $aCustom["flow"];
// }
//
//
// $aTransport = [];
// if (isset($aCustom["type"]) && $aCustom["type"] != "raw") {
// $aTransport["type"] = $aCustom["type"];
// }
// if (isset($aCustom["headerType"]) && $aCustom["headerType"] == "http") {
// $aTransport["type"] = "http"; // 整个http覆盖默认tcp
// }
// if (isset($aCustom["path"])) {
// $aTransport["path"] = rawurldecode($aCustom["path"]);
// }
// if (isset($aCustom["host"])) {
// $aTransport["headers"]["Host"] = $aCustom["host"];
// }
// if (isset($aCustom["serviceName"])) {
// $aTransport["service_name"] = $aCustom["serviceName"];
// }
// if (!empty($aTransport)) {
// if (empty($aTransport["type"])) {
// $aTransport["type"] = "tcp";
// }
// $aNode["transport"] = $aTransport;
// }
//
//
// $aTls = []; // 本体
// $aUtls = []; // 二层
// $aReality = []; // 二层
//
// if (isset($aCustom["fp"])) { // 二层的utls构建
// if ($aCustom["fp"] == "random") {
// $aCustom["fp"] = "chrome";
// }
// $aUtls["fingerprint"] = $aCustom["fp"];
// }
// if (!empty($aUtls)) { // 二层的utls封装进tls
// $aUtls["enabled"] = true;
// $aTls["utls"] = $aUtls;
// }
// if (isset($aCustom["security"])) {
// $sSecurity = $aCustom["security"];
// if ($sSecurity == "reality") { // 二层的reality构建
// if (isset($aCustom["pbk"])) {
// $aReality["public_key"] = $aCustom["pbk"];
// }
// if (isset($aCustom["sid"])) {
// $aReality["short_id"] = (string) $aCustom["sid"];
// }
// }
// }
// if (!empty($aReality)) { // 二层的reality封建进tls
// $aReality["enabled"] = true;
// $aTls["reality"] = $aReality;
// }
//
// if (isset($aCustom["alpn"])) {
// $sTmp = $aCustom["alpn"] ?? "";
// $aTmp = explode(",", $sTmp);
// $aTls["alpn"] = $aTmp;
// }
// if (isset($aCustom["sni"])) { // 本体的tls构建
// $aTls["server_name"] = $this->parseServerName($aCustom["sni"], $aCustom["sni"]);
// }
// if (isset($aCustom["encryption"]) && $aCustom["encryption"] != "none") { // 本体的tls构建
// $aTls["encryption"] = $aCustom["encryption"];
// }
// if (!empty($aTls)) { // 本体的tls封装进node
// $aTls["enabled"] = true;
// $aNode["tls"] = $aTls;
// }
//
// $aV2ray["config"] = $aNode;
//
// return $aV2ray;
// } // 转换结果有问题像之前的mod_to_vmess那样给我弄好
// private function mod_to_vmess($aV2ray)
// {
// $aNode = [];
// $aConfig = $aV2ray["config"];
//
// $aNode["type"] = "vmess";
// $aNode["tag"] = $aV2ray['country'] ?? '';
// $aNode["server"] = $aConfig["add"] ?? '';
// $aNode["server_port"] = $aConfig["port"] ?? ''; // Cannot access offset of type string on string
// $aNode["server_port"] = (int) $aNode["server_port"];
// $aNode["uuid"] = $aConfig["id"] ?? '';
// $aNode["security"] = $aConfig["scy"] ?? 'auto';
// $aNode["alter_id"] = $aConfig["aid"] ?? 0; // 猜的
// $aNode["alter_id"] = (int) $aNode["alter_id"];
//
// $aTransport = [];
// if (isset($aConfig["net"]) && $aConfig["net"] != "none" && $aConfig["net"] != "raw") {
// $aTransport["type"] = $aConfig["net"];
// }
// if (isset($aConfig["path"])) {
// $aTransport["path"] = rawurldecode($aConfig["path"]);
// }
// if (isset($aConfig["host"])) {
// $aTransport["headers"]["Host"] = $aConfig["host"];
// }
// if (!empty($aTransport)) {
// if (empty($aTransport["type"])) {
// $aTransport["type"] = "tcp";
// }
// $aNode["transport"] = $aTransport;
// }
//
// $aTls = [];
// if (isset($aConfig["tls"])) {
// if ($aConfig["tls"] == "tls") {
// $aTls["server_name"] = !empty($aConfig['host']) ? $aConfig['host'] : $aConfig['add'];
// $aTls["server_name"] = $this->parseServerName($aTls["server_name"], $aTls["server_name"]);
// }
// }
// if (!empty($aTls)) {
// $aTls["enabled"] = true;
// $aNode["tls"] = $aTls;
// }
//
// $aV2ray["config"] = $aNode;
//
// return $aV2ray;
// } // 这是原版代码,不行。你给我重写。传入和返回值一致即可
// private function mod_to_ss__wo($aV2ray)
// {
// $sConfig = $aV2ray["config"] ?? '';
//
// $aTmp = explode("@", $sConfig, 2);
// $sPwd = $aTmp[0] ?? '';
// $sConfig = $aTmp[1] ?? '';
//
// $sPwd = $this->tomBase64Decode($sPwd);
//
// $aTmp = explode(":", $sPwd, 2);
// $sPwdType = $aTmp[0] ?? '';
// $sPwd = $aTmp[1] ?? '';
//
// $aTmp = explode(":", $sConfig, 2);
// $sAddr = $aTmp[0] ?? '';
// $iPort = $aTmp[1] ?? '';
//
// // 推荐的现代化 SS 算法白名单
// $aAllowedCiphers = [
// '2022-blake3-aes-128-gcm',
// '2022-blake3-aes-256-gcm',
// '2022-blake3-chacha20-poly1305',
// 'aes-128-gcm',
// 'aes-192-gcm',
// 'aes-256-gcm',
// 'chacha20-ietf-poly1305',
// 'xchacha20-ietf-poly1305',
// ];
//
// if (!in_array($sPwdType, $aAllowedCiphers, true)) {
// return false;
// }
//
// $aNode = [
// "type" => "shadowsocks",
// "tag" => $aV2ray['country'] ?? '',
// "server" => $sAddr,
// "server_port" => (int) $iPort,
// "method" => $sPwdType,
// "password" => $sPwd,
// ];
//
// $aV2ray["config"] = $aNode;
//
// return $aV2ray;
// } // 看看
// private function mod_to_socks__($aV2ray)
// {
// $sConfig = $aV2ray["config"] ?? '';
//
// $aTmp = explode("@", $sConfig, 2);
// $sPwd = $aTmp[0] ?? '';
// $sConfig = $aTmp[1] ?? '';
//
// $sPwd = $this->tomBase64Decode($sPwd);
// $aTmp = explode(":", $sPwd, 2);
// $sUser = $aTmp[0] ?? '';
// $sPwd = $aTmp[1] ?? '';
//
// $aTmp = explode(":", $sConfig, 2);
// $sAddr = $aTmp[0] ?? '';
// $iPort = $aTmp[1] ?? '';
//
// $aNode = [
// "type" => "socks",
// "tag" => $aV2ray['country'] ?? '',
// "server"=> $sAddr,
// "server_port" => (int) $iPort,
// "username" => $sUser,
// "password" => $sPwd
// ];
//
// $aV2ray["config"] = $aNode;
//
// return $aV2ray;
// } // 看看
// private function mod_to_trojan($aV2ray)
// {
// $sConfig = $aV2ray["config"] ?? '';
//
// $aTmp = explode("@", $sConfig, 2);
// $sPwd = $aTmp[0] ?? '';
// $sConfig = $aTmp[1] ?? '';
//
// $aTmp = explode("?", $sConfig, 2);
// $sAddrFull = $aTmp[0] ?? '';
// $sConfig = $aTmp[1] ?? '';
//
// $aTmp = explode(":", $sAddrFull, 2);
// $sAddr = $aTmp[0] ?? '';
// $iPort = $aTmp[1] ?? '';
//
// $aNode = [
// "type" => "trojan",
// "tag" => $aV2ray['country'] ?? '',
// "server"=> $sAddr,
// "server_port" => (int) $iPort,
// "password" => $sPwd
// ];
//
// $aCustomYuan = explode("&", $sConfig);
// $aCustom = [];
// foreach ($aCustomYuan as $sRow) {
// $aRow = explode("=", $sRow, 2);
// $k = $aRow[0] ?? '';
// $v = $aRow[1] ?? '';
// $aCustom[$k] = $v;
// }
//
// $aTls = []; // 层1的tls
// $aUtls = []; // 层2的utls
//
// if (isset($aCustom["sni"])) { // 写层1的tls
// $aTls["server_name"] = $this->parseServerName($aCustom["sni"], $aCustom["sni"]);
// }
// if (isset($aCustom["host"])) { // 写层1的tls -- host覆盖sni=host优先
// $aTls["server_name"] = $this->parseServerName($aCustom["host"], $aCustom["host"]);
// }
// if (isset($aCustom["alpn"])) { // 写层1的tls
// $aTls["alpn"] = explode(",", $aCustom["alpn"]);
// }
// if (isset($aCustom["allowInsecure"])) { // 写层1的tls
// $aTls["insecure"] = (bool) $aCustom["allowInsecure"];
// }
//
// if (isset($aCustom["fp"])) { // 写层2的utls
// $aUtls["fingerprint"] = $aCustom["fp"];
// }
// if (!empty($aUtls)) { // 层2的utls并入tls
// $aUtls["enabled"] = true;
// $aTls["utls"] = $aUtls;
// }
//
// if (!empty($aTls)) { // 层1的tlstls并入node
// $aTls["enabled"] = true;
// $aNode["tls"] = $aTls;
// }
//
// $aTransport = [];
// if ($aCustom["type"] == "ws" && isset($aTls["server_name"])) {
// $aTransport["headers"]["Host"] = $aTls["server_name"];
// }
//
//// if (isset($aCustom["type"]) && $aCustom["type"] != "tcp" && $aCustom["type"] != "none" && $aCustom["type"] != "raw") {
//// $aTransport["type"] = $aCustom["type"];
//// if ($aCustom["type"] == "ws" && isset($aTls["server_name"])) {
//// $aTransport["headers"]["Host"] = $aTls["server_name"];
//// }
//// }
// if (isset($aCustom["path"])) {
// $aTransport["path"] = rawurldecode($aCustom["path"]);
// }
// if (!empty($aTransport)) {
// if (isset($aCustom["type"]) && $aCustom["type"] != "none" && $aCustom["type"] != "raw") {
// $aTransport["type"] = $aCustom["type"];
// }
//// if (empty($aTransport["type"])) {
//// $aTransport["type"] = "tcp";
//// }
// $aNode["transport"] = $aTransport;
// }
//
// $aV2ray["config"] = $aNode;
//
// return $aV2ray;
// } // 看看
// private function mod_to_hysteria2($aV2ray)
// {
// $sConfig = $aV2ray["config"] ?? '';
//
// $aTmp = explode("@", $sConfig, 2);
// $sPwd = $aTmp[0] ?? '';
// $sConfig = $aTmp[1] ?? '';
//
// $aTmp = explode("?", $sConfig, 2);
// $sAddrFull = $aTmp[0] ?? '';
// $sConfig = $aTmp[1] ?? '';
// $aTmp = explode(":", $sAddrFull, 2);
// $sAddr = $aTmp[0] ?? '';
// $iPort = $aTmp[1] ?? '';
//
// $cCustom = explode("&", $sConfig);
// $aCustom = [];
// foreach ($cCustom as $sCustom) {
// $aTmp = explode("=", $sCustom);
// $k = $aTmp[0] ?? '';
// $v = $aTmp[1] ?? '';
// $aCustom[$k] = $v;
// }
//
// $aNode = [
// "type" => "hysteria2",
// "tag" => $aV2ray['country'] ?? '',
// "server"=> $sAddr,
// "server_port" => (int) $iPort,
// "password" => $sPwd
// ];
//
// $aTls = [];
// if (isset($aCustom['sni'])) {
// $aTls['server_name'] = $this->parseServerName($aCustom['sni'], $aCustom['sni']);
// }
// if (isset($aCustom['insecure'])) {
// $aTls['insecure'] = (bool) $aCustom['insecure'] ?? 0;
// }
// if (!empty($aTls)) {
// $aTls['enabled'] = true;
// $aNode["tls"] = $aTls;
// }
//
// $aObfs = [];
// if (isset($aCustom["obfs"])) {
// $aObfs["type"] = $aCustom["obfs"];
// }
// if (isset($aCustom["obfs-password"])) {
// $aObfs["password"] = $aCustom["obfs-password"];
// }
// if (!empty($aObfs)) {
// $aNode["obfs"] = $aObfs;
// }
//
// $aV2ray["config"] = $aNode;
//
// return $aV2ray;
// } // 看看
}