// DO NOT INCLUDE THIS #include #include #include #include // inline QString software_name = "NekoRay"; inline QString software_core_name = "V2Ray"; inline std::function release_runguard; // Dialogs inline std::function showLog; inline std::function showLog_ext; inline std::function showLog_ext_vt100; inline std::function dialog_message; // Utils #define QJSONARRAY_ADD(arr, add) for(const auto &a: (add)) { (arr) += a; } #define QJSONOBJECT_COPY(src, dst, key) if (src.contains(key)) dst[key] = src[key]; #define QJSONOBJECT_COPY2(src, dst, src_key, dst_key) if (src.contains(src_key)) dst[dst_key] = src[src_key]; inline QString SubStrBefore(QString str, const QString &sub) { if (!str.contains(sub)) return str; return str.left(str.indexOf(sub)); } inline QString SubStrAfter(QString str, const QString &sub) { if (!str.contains(sub)) return str; return str.right(str.length() - str.indexOf(sub) - sub.length()); } inline QString QStringList2Command(const QStringList &list) { QStringList new_list; for (auto str: list) { auto q = "\"" + str.replace("\"", "\\\"") + "\""; new_list << q; } return new_list.join(" "); } inline QString DecodeB64IfValid(const QString &input, QByteArray::Base64Option options = QByteArray::Base64Option::Base64Encoding) { auto result = QByteArray::fromBase64Encoding(input.toUtf8(), options | QByteArray::Base64Option::AbortOnBase64DecodingErrors); if (result) { return result.decoded; } return ""; } #define GetQuery(url) QUrlQuery((url).query(QUrl::ComponentFormattingOption::FullyDecoded)); QString GetQueryValue(const QUrlQuery &q, const QString &key, const QString &def = ""); inline QString Int2String(int i) { return QVariant(i).toString(); } inline QString Int2String(qint64 i) { return QVariant(i).toString(); } QString GetRandomString(int randomStringLength); // QString >> QJson inline QJsonObject QString2QJsonObject(const QString &jsonString) { QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonString.toUtf8()); QJsonObject jsonObject = jsonDocument.object(); return jsonObject; } // QJson >> QString inline QString QJsonObject2QString(const QJsonObject &jsonObject, bool compact) { return QString(QJsonDocument(jsonObject).toJson(compact ? QJsonDocument::Compact : QJsonDocument::Indented)); } template inline QJsonArray QList2QJsonArray(const QList &list) { QVariantList list2; for (auto &item: list) list2.append(item); return QJsonArray::fromVariantList(list2); } inline QList QJsonArray2QListInt(const QJsonArray &arr) { QList list2; for (auto item: arr) list2.append(item.toInt()); return list2; } inline QList QJsonArray2QListString(const QJsonArray &arr) { QList list2; for (auto item: arr) list2.append(item.toString()); return list2; } inline QString UrlSafe_encode(const QString &s) { return s.toUtf8().toPercentEncoding().replace(" ", "%20"); } inline bool InRange(unsigned x, unsigned low, unsigned high) { return (low <= x && x <= high); } inline QStringList SplitLines(const QString &_string) { return _string.split(QRegularExpression("[\r\n]"), Qt::SplitBehaviorFlags::SkipEmptyParts); } QByteArray ReadFile(const QString &path); QString ReadFileText(const QString &path); // Net int MkPort(); // Validators bool IsIpAddress(const QString &str); bool IsIpAddressV4(const QString &str); bool IsIpAddressV6(const QString &str); // [2001:4860:4860::8888] -> 2001:4860:4860::8888 inline QString UnwrapIPV6Host(QString &str) { return str.replace("[", "").replace("]", ""); } // [2001:4860:4860::8888] or 2001:4860:4860::8888 -> [2001:4860:4860::8888] inline QString WrapIPV6Host(QString &str) { if (!IsIpAddressV6(str)) return str; return "[" + UnwrapIPV6Host(str) + "]"; } inline QString DisplayAddress(QString serverAddress, int serverPort) { if (serverAddress.isEmpty() && serverPort == 0) return {}; return WrapIPV6Host(serverAddress) + ":" + Int2String(serverPort); }; // Format inline QString DisplayTime(long long time, QLocale::FormatType formatType = QLocale::LongFormat) { QDateTime t; t.setSecsSinceEpoch(time); return QLocale().toString(t, formatType); } inline QString ReadableSize(const qint64 &size) { double sizeAsDouble = size; static QStringList measures; if (measures.isEmpty()) measures << "B" << "KiB" << "MiB" << "GiB" << "TiB" << "PiB" << "EiB" << "ZiB" << "YiB"; QStringListIterator it(measures); QString measure(it.next()); while (sizeAsDouble >= 1024.0 && it.hasNext()) { measure = it.next(); sizeAsDouble /= 1024.0; } return QString::fromLatin1("%1 %2").arg(sizeAsDouble, 0, 'f', 2).arg(measure); } // UI QWidget *GetMessageBoxParent(); int MessageBoxWarning(const QString &title, const QString &text); int MessageBoxInfo(const QString &title, const QString &text); void runOnUiThread(const std::function &callback, QObject *parent = nullptr); void runOnNewThread(const std::function &callback); template inline void connectOnce(EMITTER *emitter, SIGNAL signal, RECEIVER *receiver, ReceiverFunc f, Qt::ConnectionType connectionType = Qt::AutoConnection) { auto connection = std::make_shared(); auto onTriggered = [connection, f](auto... arguments) { std::invoke(f, arguments...); QObject::disconnect(*connection); }; *connection = QObject::connect(emitter, signal, receiver, onTriggered, connectionType); } void setTimeout(const std::function &callback, QObject *obj, int timeout = 0);