mirror of
https://github.com/Qv2ray/Qv2ray.git
synced 2025-05-20 02:40:20 +08:00
add: added SIP008 subscription support
This commit is contained in:
parent
21bf0fd27e
commit
eb2a1284bc
@ -1 +1 @@
|
||||
5939
|
||||
5940
|
||||
|
@ -1 +1,77 @@
|
||||
#include "SubscriptionAdapter.hpp"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QUrl>
|
||||
#include <QUrlQuery>
|
||||
|
||||
QString SafeBase64Decode(QString string)
|
||||
{
|
||||
QByteArray ba = string.replace(QChar('-'), QChar('+')).replace(QChar('_'), QChar('/')).toUtf8();
|
||||
return QByteArray::fromBase64(ba, QByteArray::Base64Option::OmitTrailingEquals);
|
||||
}
|
||||
|
||||
QString SafeBase64Encode(const QString &string)
|
||||
{
|
||||
QString base64 = string.toUtf8().toBase64();
|
||||
return base64.replace(QChar('+'), QChar('-')).replace(QChar('/'), QChar('_'));
|
||||
}
|
||||
|
||||
// Simple Base64 Decoder
|
||||
SubscriptionDecoder::SubscriptionDecodeResult SimpleBase64Decoder::DecodeData(const QByteArray &data) const
|
||||
{
|
||||
auto source = QString::fromUtf8(data).trimmed();
|
||||
const auto resultList = source.contains("://") ? source : SafeBase64Decode(source);
|
||||
//
|
||||
SubscriptionDecodeResult result;
|
||||
result.links = SplitLines(resultList);
|
||||
return result;
|
||||
}
|
||||
|
||||
// SIP008 Decoder
|
||||
SubscriptionDecoder::SubscriptionDecodeResult SIP008Decoder::DecodeData(const QByteArray &data) const
|
||||
{
|
||||
const auto root = QJsonDocument::fromJson(data).object();
|
||||
//
|
||||
const auto version = root["version"].toString();
|
||||
const auto username = root["username"].toString();
|
||||
const auto user_uuid = root["user_uuid"].toString();
|
||||
const auto servers = root["servers"].toArray();
|
||||
|
||||
// ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpwYXNzQGhvc3Q6MTIzNA/?plugin=plugin%3Bopt#sssip003
|
||||
|
||||
SubscriptionDecodeResult result;
|
||||
#define GetVal(x) const auto x = serverObj[#x].toString()
|
||||
for (const auto &servVal : servers)
|
||||
{
|
||||
const auto serverObj = servVal.toObject();
|
||||
GetVal(server);
|
||||
GetVal(password);
|
||||
GetVal(method);
|
||||
GetVal(plugin);
|
||||
GetVal(plugin_opts);
|
||||
GetVal(remarks);
|
||||
GetVal(id);
|
||||
const auto server_port = serverObj["server_port"].toInt();
|
||||
bool isSIP003 = !plugin.isEmpty();
|
||||
const auto userInfo = SafeBase64Encode(method + ":" + password);
|
||||
//
|
||||
QUrl link;
|
||||
link.setScheme("ss");
|
||||
link.setUserInfo(userInfo);
|
||||
link.setHost(server);
|
||||
link.setPort(server_port);
|
||||
link.setFragment(remarks);
|
||||
if (isSIP003)
|
||||
{
|
||||
QUrlQuery q;
|
||||
q.addQueryItem("plugin", QUrl::toPercentEncoding(plugin + ";" + plugin_opts));
|
||||
link.setQuery(q);
|
||||
}
|
||||
result.links << link.toString(QUrl::FullyEncoded);
|
||||
}
|
||||
#undef GetVal
|
||||
return result;
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include "CommonTypes.hpp"
|
||||
#include "QvPluginProcessor.hpp"
|
||||
|
||||
using namespace Qv2rayPlugin;
|
||||
|
||||
const inline QStringList SplitLines(const QString &_string)
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
@ -13,43 +15,47 @@ const inline QStringList SplitLines(const QString &_string)
|
||||
#endif
|
||||
}
|
||||
|
||||
class BuiltinSerializer : public Qv2rayPlugin::SubscriptionDecoder
|
||||
class SimpleBase64Decoder : public Qv2rayPlugin::SubscriptionDecoder
|
||||
{
|
||||
public:
|
||||
explicit BuiltinSerializer() : Qv2rayPlugin::SubscriptionDecoder(){};
|
||||
SubscriptionDecodeResult DecodeData(const QByteArray &data) const override
|
||||
{
|
||||
const static auto SafeBase64Decode = [](QString string) -> QString {
|
||||
QByteArray ba = string.replace(QChar('-'), QChar('+')).replace(QChar('_'), QChar('/')).toUtf8();
|
||||
return QByteArray::fromBase64(ba, QByteArray::Base64Option::OmitTrailingEquals);
|
||||
};
|
||||
|
||||
auto source = QString::fromUtf8(data).trimmed();
|
||||
const auto resultList = source.contains("://") ? source : SafeBase64Decode(source);
|
||||
//
|
||||
SubscriptionDecodeResult result;
|
||||
result.links = SplitLines(resultList);
|
||||
return result;
|
||||
}
|
||||
explicit SimpleBase64Decoder() : SubscriptionDecoder(){};
|
||||
SubscriptionDecodeResult DecodeData(const QByteArray &data) const override;
|
||||
};
|
||||
|
||||
class BuiltinSubscriptionAdapterInterface : public Qv2rayPlugin::SubscriptionInterface
|
||||
class SIP008Decoder : public Qv2rayPlugin::SubscriptionDecoder
|
||||
{
|
||||
public:
|
||||
explicit BuiltinSubscriptionAdapterInterface() : Qv2rayPlugin::SubscriptionInterface()
|
||||
explicit SIP008Decoder() : SubscriptionDecoder(){};
|
||||
SubscriptionDecodeResult DecodeData(const QByteArray &data) const override;
|
||||
};
|
||||
|
||||
class BuiltinSubscriptionAdapterInterface : public SubscriptionInterface
|
||||
{
|
||||
public:
|
||||
explicit BuiltinSubscriptionAdapterInterface() : SubscriptionInterface()
|
||||
{
|
||||
simple_base64 = std::make_shared<BuiltinSerializer>();
|
||||
simple_base64 = std::make_shared<SimpleBase64Decoder>();
|
||||
sip008 = std::make_shared<SIP008Decoder>();
|
||||
}
|
||||
|
||||
QList<Qv2rayPlugin::ProtocolInfoObject> SupportedSubscriptionTypes() const override
|
||||
{
|
||||
// "simple_base64" = magic value in Qv2ray main application
|
||||
return { Qv2rayPlugin::ProtocolInfoObject{ "simple_base64", "Basic Base64" } };
|
||||
return { //
|
||||
ProtocolInfoObject{ "simple_base64", "Basic Base64" }, //
|
||||
ProtocolInfoObject{ "sip008", "SIP008" }
|
||||
};
|
||||
}
|
||||
|
||||
std::shared_ptr<Qv2rayPlugin::SubscriptionDecoder> GetSubscriptionDecoder(const QString &type) const override
|
||||
{
|
||||
if (type == "simple_base64")
|
||||
return simple_base64;
|
||||
if (type == "sip008")
|
||||
return sip008;
|
||||
return nullptr;
|
||||
}
|
||||
std::shared_ptr<Qv2rayPlugin::SubscriptionDecoder> simple_base64;
|
||||
|
||||
std::shared_ptr<SubscriptionDecoder> simple_base64;
|
||||
std::shared_ptr<SubscriptionDecoder> sip008;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user