"; 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__($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; } private function mod_to_ss__($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_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_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_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; } 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; } }