#include "QvCoreConfigOperations.h" #include "QvUtils.h" namespace Qv2ray { namespace ConfigOperations { // -------------------------- BEGIN CONFIG VALIDATIONS ---------------------------------------------------------------------------- int VerifyVMessProtocolString(QString vmess) { if (!vmess.toLower().startsWith("vmess://")) { return -1; } try { QStringRef vmessJsonB64(&vmess, 8, vmess.length() - 8); auto vmessString = Base64Decode(vmessJsonB64.toString()); auto vmessConf = JsonFromString(vmessString); // C is a quick hack... #define C(k) vmessConf.contains(k) bool flag = true; flag = flag && C("id"); flag = flag && C("aid"); flag = flag && C("port"); flag = flag && C("add"); // Stream Settings auto net = vmessConf["net"].toString(); if (net == "tcp") flag = flag && C("type"); else if (net == "http" || net == "ws") flag = flag && C("host") && C("path"); else if (net == "kcp") flag = flag && C("type"); else if (net == "domainsocket") flag = flag && C("path"); else if (net == "quic") flag = flag && C("host") && C("type") && C("path"); flag = flag && C("tls"); flag = flag && C("net"); #undef C return flag ? 0 : 1; } catch (exception *e) { LOG(MODULE_CONNECTION, "Failed to decode vmess string: " << e->what()) return -2; } } QString GetVmessFromBase64OrPlain(QByteArray arr) { auto result = QString::fromUtf8(arr).trimmed(); return result.startsWith("vmess://") ? result : Base64Decode(result); } } }