mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-21 02:01:03 +07:00
fb5666057b
* update UI XRay, add new page PageProtocolXrayTransportSettings.qml PageProtocolXrayXmuxSettings.qml PageProtocolXrayXPaddingSettings.qml * add UI PageProtocolXrayConfigsSettings, PageProtocolXrayFlowSettings, PageProtocolXraySecuritySettings * add Xray-specific keys * add vars xray model * add new qml padding, update model * update model and export * rename file & update name class & update list xray * fixed ui * add save file in temp * remove debug macros * fixed build windows * fix path Windows * remove save config * fixed changes * fixed conf * fixed UI * fixed size & button save * fixed build iOS * fix: fixed headers base control --------- Co-authored-by: vkamn <vk@amnezia.org>
217 lines
5.8 KiB
C++
217 lines
5.8 KiB
C++
#include "xrayConfigSnapshotsModel.h"
|
|
|
|
#include <QJsonDocument>
|
|
#include <QUuid>
|
|
|
|
#include "core/repositories/secureAppSettingsRepository.h"
|
|
#include "core/utils/constants/configKeys.h"
|
|
|
|
QJsonObject XrayConfigSnapshot::toJson() const
|
|
{
|
|
QJsonObject obj;
|
|
obj["id"] = id;
|
|
obj["displayName"] = displayName;
|
|
obj["createdAt"] = createdAt.toString(Qt::ISODate);
|
|
obj["serverConfig"] = serverConfig.toJson();
|
|
return obj;
|
|
}
|
|
|
|
XrayConfigSnapshot XrayConfigSnapshot::fromJson(const QJsonObject &json)
|
|
{
|
|
XrayConfigSnapshot s;
|
|
s.id = json.value("id").toString();
|
|
s.displayName = json.value("displayName").toString();
|
|
s.createdAt = QDateTime::fromString(json.value("createdAt").toString(), Qt::ISODate);
|
|
s.serverConfig = amnezia::XrayServerConfig::fromJson(json.value("serverConfig").toObject());
|
|
return s;
|
|
}
|
|
|
|
XrayConfigSnapshotsModel::XrayConfigSnapshotsModel(SecureAppSettingsRepository *appSettings,
|
|
XrayConfigModel *xrayConfigModel, QObject *parent)
|
|
: QAbstractListModel(parent), m_appSettings(appSettings), m_xrayConfigModel(xrayConfigModel)
|
|
{
|
|
loadAll();
|
|
}
|
|
|
|
void XrayConfigSnapshotsModel::loadAll()
|
|
{
|
|
m_configs.clear();
|
|
QByteArray raw = m_appSettings->xraySavedConfigs();
|
|
if (raw.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
QJsonArray arr = QJsonDocument::fromJson(raw).array();
|
|
for (const QJsonValue &v : arr) {
|
|
m_configs.append(XrayConfigSnapshot::fromJson(v.toObject()));
|
|
}
|
|
}
|
|
|
|
void XrayConfigSnapshotsModel::persistAll()
|
|
{
|
|
QJsonArray arr;
|
|
for (const XrayConfigSnapshot &s : m_configs) {
|
|
arr.append(s.toJson());
|
|
}
|
|
m_appSettings->setXraySavedConfigs(QJsonDocument(arr).toJson(QJsonDocument::Compact));
|
|
}
|
|
|
|
int XrayConfigSnapshotsModel::rowCount(const QModelIndex &parent) const
|
|
{
|
|
Q_UNUSED(parent);
|
|
return m_configs.size();
|
|
}
|
|
|
|
QVariant XrayConfigSnapshotsModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
if (!index.isValid() || index.row() < 0 || index.row() >= m_configs.size()) {
|
|
return QVariant();
|
|
}
|
|
|
|
const XrayConfigSnapshot &s = m_configs.at(index.row());
|
|
|
|
switch (role) {
|
|
case IdRole: {
|
|
return s.id;
|
|
}
|
|
case DisplayNameRole: {
|
|
return s.displayName;
|
|
}
|
|
case CreatedAtRole: {
|
|
return s.createdAt.toString("dd.MM.yyyy HH:mm");
|
|
}
|
|
}
|
|
return QVariant();
|
|
}
|
|
|
|
QHash<int, QByteArray> XrayConfigSnapshotsModel::roleNames() const
|
|
{
|
|
QHash<int, QByteArray> roles;
|
|
roles[IdRole] = "configId";
|
|
roles[DisplayNameRole] = "configName";
|
|
roles[CreatedAtRole] = "configDate";
|
|
return roles;
|
|
}
|
|
|
|
void XrayConfigSnapshotsModel::reload()
|
|
{
|
|
beginResetModel();
|
|
loadAll();
|
|
endResetModel();
|
|
}
|
|
|
|
void XrayConfigSnapshotsModel::createFromCurrent(const amnezia::XrayServerConfig &serverConfig)
|
|
{
|
|
XrayConfigSnapshot snapshot;
|
|
snapshot.id = QUuid::createUuid().toString(QUuid::WithoutBraces);
|
|
snapshot.displayName = buildDisplayName(serverConfig);
|
|
snapshot.createdAt = QDateTime::currentDateTime();
|
|
snapshot.serverConfig = serverConfig;
|
|
|
|
beginInsertRows(QModelIndex(), m_configs.size(), m_configs.size());
|
|
m_configs.append(snapshot);
|
|
endInsertRows();
|
|
|
|
persistAll();
|
|
}
|
|
|
|
amnezia::XrayServerConfig XrayConfigSnapshotsModel::applyConfig(int index) const
|
|
{
|
|
if (index < 0 || index >= m_configs.size()) {
|
|
return amnezia::XrayServerConfig {};
|
|
}
|
|
|
|
return m_configs.at(index).serverConfig;
|
|
}
|
|
|
|
void XrayConfigSnapshotsModel::removeConfig(int index)
|
|
{
|
|
if (index < 0 || index >= m_configs.size()) {
|
|
return;
|
|
}
|
|
|
|
beginRemoveRows(QModelIndex(), index, index);
|
|
m_configs.removeAt(index);
|
|
endRemoveRows();
|
|
|
|
persistAll();
|
|
emit configRemoved(index);
|
|
}
|
|
|
|
QString XrayConfigSnapshotsModel::exportToJson(int index) const
|
|
{
|
|
if (index < 0 || index >= m_configs.size()) {
|
|
return {};
|
|
}
|
|
return QString::fromUtf8(QJsonDocument(m_configs.at(index).toJson()).toJson(QJsonDocument::Indented));
|
|
}
|
|
|
|
bool XrayConfigSnapshotsModel::importFromJson(const QString &jsonString)
|
|
{
|
|
QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8());
|
|
if (!doc.isObject()) {
|
|
emit importFailed(tr("Invalid JSON format"));
|
|
return false;
|
|
}
|
|
|
|
XrayConfigSnapshot snapshot = XrayConfigSnapshot::fromJson(doc.object());
|
|
if (snapshot.id.isEmpty()) {
|
|
snapshot.id = QUuid::createUuid().toString(QUuid::WithoutBraces);
|
|
}
|
|
if (snapshot.displayName.isEmpty()) {
|
|
snapshot.displayName = buildDisplayName(snapshot.serverConfig);
|
|
}
|
|
snapshot.createdAt = QDateTime::currentDateTime();
|
|
|
|
beginInsertRows(QModelIndex(), m_configs.size(), m_configs.size());
|
|
m_configs.append(snapshot);
|
|
endInsertRows();
|
|
|
|
persistAll();
|
|
return true;
|
|
}
|
|
|
|
QString XrayConfigSnapshotsModel::buildDisplayName(const amnezia::XrayServerConfig &cfg)
|
|
{
|
|
// Build a human-readable name: "XHTTP TLS Reality", "RAW Reality", etc.
|
|
QString transport;
|
|
if (cfg.transport == "xhttp") {
|
|
transport = "XHTTP";
|
|
} else if (cfg.transport == "mkcp") {
|
|
transport = "mKCP";
|
|
} else {
|
|
transport = "RAW (TCP)";
|
|
}
|
|
|
|
QString security;
|
|
if (cfg.security == "tls") {
|
|
security = "TLS";
|
|
} else if (cfg.security == "reality") {
|
|
security = "Reality";
|
|
} else {
|
|
security = "None";
|
|
}
|
|
|
|
return QString("%1 %2").arg(transport, security).trimmed();
|
|
}
|
|
|
|
void XrayConfigSnapshotsModel::createFromCurrentModel()
|
|
{
|
|
if (!m_xrayConfigModel) {
|
|
return;
|
|
}
|
|
createFromCurrent(m_xrayConfigModel->getProtocolConfig().serverConfig);
|
|
}
|
|
|
|
void XrayConfigSnapshotsModel::applyConfigToCurrentModel(int index)
|
|
{
|
|
if (!m_xrayConfigModel) {
|
|
return;
|
|
}
|
|
amnezia::XrayServerConfig cfg = applyConfig(index);
|
|
if (cfg.port.isEmpty()) {
|
|
return; // guard against invalid index
|
|
}
|
|
m_xrayConfigModel->applyServerConfig(cfg);
|
|
}
|