"; 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 = []; // 分支 A:TCP + HTTP 伪装 if ($sV2rayNet === 'tcp' && $sV2rayType === 'http') { $aTransport['type'] = 'http'; $aTransport['path'] = $sPath; if (!empty($sHost)) { $aTransport['host'] = array_map('trim', explode(',', $sHost)); } } // 分支 B:WebSocket 传输 elseif ($sV2rayNet === 'ws') { $aTransport['type'] = 'ws'; $aTransport['path'] = $sPath; if (!empty($sHost)) { $aTransport['headers'] = ['Host' => $sHost]; } } // 分支 C:gRPC 传输 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; // } // 看看 }