mirror of
https://github.com/Qv2ray/Qv2ray.git
synced 2025-05-19 10:20:49 +08:00
129 lines
5.5 KiB
C++
129 lines
5.5 KiB
C++
#include "Serialization.hpp"
|
|
|
|
#include "Generation.hpp"
|
|
#include "common/QvHelpers.hpp"
|
|
#include "components/plugins/QvPluginHost.hpp"
|
|
#include "core/CoreUtils.hpp"
|
|
#include "core/handler/ConfigHandler.hpp"
|
|
|
|
namespace Qv2ray::core::connection
|
|
{
|
|
namespace Serialization
|
|
{
|
|
QMultiHash<QString, CONFIGROOT> ConvertConfigFromString(const QString &link, QString *prefix, QString *errMessage, QString *newGroupName)
|
|
{
|
|
QMultiHash<QString, CONFIGROOT> connectionConf;
|
|
if (link.startsWith("vmess://"))
|
|
{
|
|
auto conf = ConvertConfigFromVMessString(link, prefix, errMessage);
|
|
//
|
|
if (GlobalConfig.advancedConfig.setAllowInsecureCiphers || GlobalConfig.advancedConfig.setAllowInsecure)
|
|
{
|
|
auto outbound = conf["outbounds"].toArray().first().toObject();
|
|
auto streamSettings = outbound["streamSettings"].toObject();
|
|
auto tlsSettings = streamSettings["tlsSettings"].toObject();
|
|
tlsSettings["allowInsecure"] = GlobalConfig.advancedConfig.setAllowInsecure;
|
|
tlsSettings["allowInsecureCiphers"] = GlobalConfig.advancedConfig.setAllowInsecureCiphers;
|
|
streamSettings["tlsSettings"] = tlsSettings;
|
|
outbound["streamSettings"] = streamSettings;
|
|
//
|
|
auto outbounds = conf["outbounds"].toArray();
|
|
outbounds[0] = outbound;
|
|
conf["outbounds"] = outbounds;
|
|
}
|
|
//
|
|
connectionConf.insert(*prefix, conf);
|
|
}
|
|
else if (link.startsWith("ss://"))
|
|
{
|
|
auto conf = ConvertConfigFromSSString(link, prefix, errMessage);
|
|
connectionConf.insert(*prefix, conf);
|
|
}
|
|
else if (link.startsWith("ssd://"))
|
|
{
|
|
QStringList errMessageList;
|
|
connectionConf = ConvertConfigFromSSDString(link, newGroupName, &errMessageList);
|
|
*errMessage = errMessageList.join(NEWLINE);
|
|
}
|
|
else
|
|
{
|
|
bool ok = false;
|
|
auto configs = PluginHost->TryDeserializeShareLink(link, prefix, errMessage, newGroupName, &ok);
|
|
for (const auto &key : configs.keys())
|
|
{
|
|
auto vals = configs.values(key);
|
|
for (const auto &val : vals)
|
|
{
|
|
CONFIGROOT root;
|
|
auto outbound = GenerateOutboundEntry(val.first, OUTBOUNDSETTING(val.second), {});
|
|
root.insert("outbounds", QJsonArray{ outbound });
|
|
connectionConf.insert(key, root);
|
|
}
|
|
}
|
|
if (!ok)
|
|
{
|
|
*errMessage = QObject::tr("Unsupported share link format.");
|
|
}
|
|
}
|
|
|
|
return connectionConf;
|
|
}
|
|
|
|
const QString ConvertConfigToString(const ConnectionId &id, bool isSip002)
|
|
{
|
|
auto alias = GetDisplayName(id);
|
|
if (IsComplexConfig(id))
|
|
{
|
|
DEBUG(MODULE_CONNECTION, "Ignored an complex config: " + alias)
|
|
return QV2RAY_SERIALIZATION_COMPLEX_CONFIG_PLACEHOLDER;
|
|
}
|
|
auto server = ConnectionManager->GetConnectionRoot(id);
|
|
return ConvertConfigToString(alias, GetDisplayName(GetConnectionGroupId(id)), server, isSip002);
|
|
}
|
|
|
|
const QString ConvertConfigToString(const QString &alias, const QString &groupName, const CONFIGROOT &server, bool isSip002)
|
|
{
|
|
const auto outbound = OUTBOUND(server["outbounds"].toArray().first().toObject());
|
|
const auto type = outbound["protocol"].toString();
|
|
const auto &settings = outbound["settings"].toObject();
|
|
QString sharelink = "";
|
|
if (type == "vmess")
|
|
{
|
|
auto vmessServer = VMessServerObject::fromJson(settings["vnext"].toArray().first().toObject());
|
|
auto transport = StreamSettingsObject::fromJson(outbound["streamSettings"].toObject());
|
|
sharelink = vmess::ConvertConfigToVMessString(transport, vmessServer, alias);
|
|
}
|
|
else if (type == "shadowsocks")
|
|
{
|
|
auto ssServer = ShadowSocksServerObject::fromJson(settings["servers"].toArray().first().toObject());
|
|
sharelink = ss::ConvertConfigToSSString(ssServer, alias, isSip002);
|
|
}
|
|
else
|
|
{
|
|
if (type.isEmpty())
|
|
{
|
|
DEBUG(MODULE_CONNECTION, "WARNING: Empty outbound type.")
|
|
}
|
|
else
|
|
{
|
|
bool ok = false;
|
|
sharelink = PluginHost->TrySerializeShareLink(type, settings, alias, groupName, &ok);
|
|
Q_UNUSED(ok)
|
|
}
|
|
}
|
|
|
|
return sharelink;
|
|
}
|
|
|
|
QString DecodeSubscriptionString(const QByteArray &arr)
|
|
{
|
|
// String may start with: vmess:// and ss://
|
|
// We only process vmess:// here
|
|
// Some subscription providers may use plain vmess:// saperated by
|
|
// lines But others may use base64 of above.
|
|
auto result = QString::fromUtf8(arr).trimmed();
|
|
return result.contains("://") ? result : Base64Decode(result);
|
|
}
|
|
} // namespace Serialization
|
|
} // namespace Qv2ray::core::connection
|