mirror of
https://github.com/Qv2ray/Qv2ray.git
synced 2025-05-20 02:40:20 +08:00
[Added] Import config from file.
This commit is contained in:
parent
e16466ffe9
commit
220f202c61
@ -10,6 +10,8 @@
|
||||
#define DROOT QJsonObject root;
|
||||
#define RROOT return root;
|
||||
|
||||
#define JSON_ROOT_TRY_REMOVE(obj) if (root.contains(obj)) { root.remove(obj); }
|
||||
|
||||
namespace Qv2ray
|
||||
{
|
||||
namespace ConfigOperations
|
||||
@ -32,15 +34,24 @@ namespace Qv2ray
|
||||
//
|
||||
// Misc
|
||||
template<typename T>
|
||||
QJsonObject GetRootObject(T out);
|
||||
QJsonObject GetRootObject(T t)
|
||||
{
|
||||
auto json = StructToJSON(t);
|
||||
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromStdString(json.toStdString()));
|
||||
return doc.object();
|
||||
}
|
||||
template QJsonObject GetRootObject<StreamSettingsObject>(StreamSettingsObject t);
|
||||
template QJsonObject GetRootObject<VMessOut>(VMessOut t);
|
||||
//
|
||||
// -------------------------- BEGIN CONFIG VALIDATIONS ---------------------------------------------
|
||||
int VerifyVMessProtocolString(QString vmess);
|
||||
//
|
||||
// -------------------------- BEGIN CONFIG CONVERSIONS ---------------------------------------------
|
||||
// Save Connection Config
|
||||
int SaveConnectionConfig(QJsonObject obj, const QString *alias);
|
||||
// VMess Protocol
|
||||
QJsonObject ConvertOutboundFromVMessString(QString vmess);
|
||||
QJsonObject ConvertConfigFromVMessString(QString vmess);
|
||||
QJsonObject ConvertConfigFromFile(QString sourceFilePath, bool overrideInbounds);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -17,5 +17,112 @@ namespace Qv2ray
|
||||
SaveStringToFile(doc.toJson(), &config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This generates an "OutBoundObject"
|
||||
QJsonObject ConvertConfigFromVMessString(QString str)
|
||||
{
|
||||
DROOT
|
||||
QStringRef vmessJsonB64(&str, 8, str.length() - 8);
|
||||
auto vmessConf = StructFromJSON<VMessProtocolConfigObject>(Base64Decode(vmessJsonB64.toString()).toStdString());
|
||||
VMessOut vConf;
|
||||
VMessOut::ServerObject serv;
|
||||
serv.port = stoi(vmessConf.port);
|
||||
serv.address = vmessConf.add;
|
||||
// User
|
||||
VMessOut::ServerObject::UserObject user;
|
||||
user.id = vmessConf.id;
|
||||
user.alterId = stoi(vmessConf.aid);
|
||||
// Server
|
||||
serv.users.push_back(user);
|
||||
// VMess root config
|
||||
vConf.vnext.push_back(serv);
|
||||
//
|
||||
// Stream Settings
|
||||
StreamSettingsObject streaming;
|
||||
|
||||
// Fill hosts for HTTP
|
||||
foreach (auto host, QString::fromStdString(vmessConf.host).split(',')) {
|
||||
streaming.httpSettings.host.push_back(host.toStdString());
|
||||
}
|
||||
|
||||
// hosts for ws, h2 and security for QUIC
|
||||
streaming.wsSettings.headers.insert(make_pair("Host", vmessConf.host));
|
||||
streaming.quicSettings.security = vmessConf.host;
|
||||
//
|
||||
// Fake type for tcp, kcp and QUIC
|
||||
streaming.tcpSettings.header.type = vmessConf.type;
|
||||
streaming.kcpSettings.header.type = vmessConf.type;
|
||||
streaming.quicSettings.header.type = vmessConf.type;
|
||||
//
|
||||
// Path for ws, h2, Quic
|
||||
streaming.wsSettings.path = vmessConf.path;
|
||||
streaming.httpSettings.path = vmessConf.path;
|
||||
streaming.quicSettings.key = vmessConf.path;
|
||||
streaming.security = vmessConf.tls;
|
||||
//
|
||||
// Network type
|
||||
streaming.network = vmessConf.net;
|
||||
//
|
||||
// Root
|
||||
root.insert("sendThrough", "0.0.0.0");
|
||||
root.insert("protocol", "vmess");
|
||||
root.insert("settings", GetRootObject(vConf));
|
||||
root.insert("tag", OUTBOUND_TAG_PROXY);
|
||||
root.insert("streamSettings", GetRootObject(streaming));
|
||||
root.insert("QV2RAY_ALIAS", QString::fromStdString(vmessConf.ps));
|
||||
RROOT
|
||||
}
|
||||
|
||||
QJsonObject ConvertConfigFromFile(QString sourceFilePath, bool overrideInbounds)
|
||||
{
|
||||
auto globalConf = GetGlobalConfig();
|
||||
QFile configFile(sourceFilePath);
|
||||
configFile.open(QIODevice::ReadOnly | QIODevice::ExistingOnly);
|
||||
QByteArray allData = configFile.readAll();
|
||||
configFile.close();
|
||||
QJsonDocument v2conf = QJsonDocument::fromJson(allData);
|
||||
QJsonObject root = v2conf.object();
|
||||
|
||||
if (overrideInbounds) {
|
||||
JSON_ROOT_TRY_REMOVE("inbounds")
|
||||
}
|
||||
|
||||
//
|
||||
JSON_ROOT_TRY_REMOVE("log")
|
||||
JSON_ROOT_TRY_REMOVE("api")
|
||||
JSON_ROOT_TRY_REMOVE("stats")
|
||||
JSON_ROOT_TRY_REMOVE("policy")
|
||||
JSON_ROOT_TRY_REMOVE("dns")
|
||||
//
|
||||
return root;
|
||||
}
|
||||
/*
|
||||
* {
|
||||
QFile configFile(path);
|
||||
|
||||
if (!configFile.open(QIODevice::ReadOnly)) {
|
||||
QvMessageBox(this, tr("ImportConfig"), tr("CannotOpenFile"));
|
||||
qDebug() << "ImportConfig::CannotOpenFile";
|
||||
return -1;
|
||||
}
|
||||
|
||||
QByteArray allData = configFile.readAll();
|
||||
configFile.close();
|
||||
QJsonDocument v2conf(QJsonDocument::fromJson(allData));
|
||||
QJsonObject rootobj = v2conf.object();
|
||||
QJsonObject outbound;
|
||||
|
||||
if (rootobj.contains("outbounds")) {
|
||||
outbound = rootobj.value("outbounds").toArray().first().toObject();
|
||||
} else {
|
||||
outbound = rootobj.value("outbound").toObject();
|
||||
}
|
||||
|
||||
if (!QFile::copy(path, "newFile")) {
|
||||
QvMessageBox(this, tr("ImportConfig"), tr("CannotCopyCustomConfig"));
|
||||
qDebug() << "ImportConfig::CannotCopyCustomConfig";
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -62,14 +62,6 @@ namespace Qv2ray
|
||||
RROOT
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
QJsonObject GetRootObject(T out)
|
||||
{
|
||||
auto json = StructToJSON(out);
|
||||
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromStdString(json.toStdString()));
|
||||
return doc.object();
|
||||
}
|
||||
|
||||
QJsonObject GenerateShadowSocksServerOUT(QString email, QString address, int port, QString method, QString password, bool ota, int level)
|
||||
{
|
||||
DROOT
|
||||
@ -122,62 +114,6 @@ namespace Qv2ray
|
||||
JADD(auth, accounts, udp, ip, userLevel)
|
||||
RROOT
|
||||
}
|
||||
|
||||
// This generates an "OutBoundObject"
|
||||
QJsonObject ConvertOutboundFromVMessString(QString str)
|
||||
{
|
||||
DROOT
|
||||
QStringRef vmessJsonB64(&str, 8, str.length() - 8);
|
||||
auto vmessConf = StructFromJSON<VMessProtocolConfigObject>(Base64Decode(vmessJsonB64.toString()).toStdString());
|
||||
VMessOut vConf;
|
||||
VMessOut::ServerObject serv;
|
||||
serv.port = stoi(vmessConf.port);
|
||||
serv.address = vmessConf.add;
|
||||
// User
|
||||
VMessOut::ServerObject::UserObject user;
|
||||
user.id = vmessConf.id;
|
||||
user.alterId = stoi(vmessConf.aid);
|
||||
// Server
|
||||
serv.users.push_back(user);
|
||||
// VMess root config
|
||||
vConf.vnext.push_back(serv);
|
||||
//
|
||||
// Stream Settings
|
||||
StreamSettingsObject streaming;
|
||||
|
||||
// Fill hosts for HTTP
|
||||
foreach (auto host, QString::fromStdString(vmessConf.host).split(',')) {
|
||||
streaming.httpSettings.host.push_back(host.toStdString());
|
||||
}
|
||||
|
||||
// hosts for ws, h2 and security for QUIC
|
||||
streaming.wsSettings.headers.insert(make_pair("Host", vmessConf.host));
|
||||
streaming.quicSettings.security = vmessConf.host;
|
||||
//
|
||||
// Fake type for tcp, kcp and QUIC
|
||||
streaming.tcpSettings.header.type = vmessConf.type;
|
||||
streaming.kcpSettings.header.type = vmessConf.type;
|
||||
streaming.quicSettings.header.type = vmessConf.type;
|
||||
//
|
||||
// Path for ws, h2, Quic
|
||||
streaming.wsSettings.path = vmessConf.path;
|
||||
streaming.httpSettings.path = vmessConf.path;
|
||||
streaming.quicSettings.key = vmessConf.path;
|
||||
streaming.security = vmessConf.tls;
|
||||
//
|
||||
// Network type
|
||||
streaming.network = vmessConf.net;
|
||||
//
|
||||
// Root
|
||||
root.insert("sendThrough", "0.0.0.0");
|
||||
root.insert("protocol", "vmess");
|
||||
root.insert("settings", GetRootObject(vConf));
|
||||
root.insert("tag", OUTBOUND_TAG_PROXY);
|
||||
root.insert("streamSettings", GetRootObject(streaming));
|
||||
root.insert("QV2RAY_ALIAS", QString::fromStdString(vmessConf.ps));
|
||||
RROOT
|
||||
}
|
||||
|
||||
// -------------------------- END CONFIG GENERATIONS ------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
@ -5,11 +5,14 @@
|
||||
|
||||
namespace Qv2ray
|
||||
{
|
||||
bool Qv2Instance::checkConfigFile(const QString path)
|
||||
bool Qv2Instance::VerifyVConfigFile(const QString path)
|
||||
{
|
||||
if (checkCoreExe()) {
|
||||
if (ValidateV2rayCoreExe()) {
|
||||
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||
env.insert("V2RAY_LOCATION_ASSET", QString::fromStdString(GetGlobalConfig().v2AssetsPath));
|
||||
QProcess process;
|
||||
process.start(QString::fromStdString(Utils::GetGlobalConfig().v2Path), QStringList() << "-test"
|
||||
process.setProcessEnvironment(env);
|
||||
process.start(QString::fromStdString(Utils::GetGlobalConfig().v2CorePath), QStringList() << "-test"
|
||||
<< "-config" << path,
|
||||
QIODevice::ReadWrite | QIODevice::Text);
|
||||
|
||||
@ -37,9 +40,9 @@ namespace Qv2ray
|
||||
Status = STOPPED;
|
||||
}
|
||||
|
||||
bool Qv2Instance::checkCoreExe()
|
||||
bool Qv2Instance::ValidateV2rayCoreExe()
|
||||
{
|
||||
auto path = QString::fromStdString(Utils::GetGlobalConfig().v2Path);
|
||||
auto path = QString::fromStdString(Utils::GetGlobalConfig().v2CorePath);
|
||||
|
||||
if (!QFile::exists(path)) {
|
||||
Utils::QvMessageBox(nullptr, QObject::tr("CoreNotFound"), QObject::tr("CoreFileNotFoundExplainationAt:") + path);
|
||||
@ -47,7 +50,7 @@ namespace Qv2ray
|
||||
} else return true;
|
||||
}
|
||||
|
||||
bool Qv2Instance::start()
|
||||
bool Qv2Instance::Start()
|
||||
{
|
||||
if (Status != STOPPED) {
|
||||
return false;
|
||||
@ -55,23 +58,28 @@ namespace Qv2ray
|
||||
|
||||
Status = STARTING;
|
||||
|
||||
if (checkCoreExe()) {
|
||||
if (checkConfigFile(QV2RAY_GENERATED_CONFIG_DIRPATH + "config.json")) {
|
||||
if (ValidateV2rayCoreExe()) {
|
||||
if (VerifyVConfigFile(QV2RAY_GENERATED_CONFIG_DIRPATH + "config.json")) {
|
||||
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||
env.insert("V2RAY_LOCATION_ASSET", QString::fromStdString(GetGlobalConfig().v2AssetsPath));
|
||||
vProcess->setProcessEnvironment(env);
|
||||
vProcess->start(QString::fromStdString(_config.v2CorePath), QStringList() << "-config"
|
||||
<< QV2RAY_GENERATED_CONFIG_DIRPATH + "config.json",
|
||||
QIODevice::ReadWrite | QIODevice::Text);
|
||||
vProcess->waitForStarted();
|
||||
Status = STARTED;
|
||||
return true;
|
||||
} else {
|
||||
Status = STOPPED;
|
||||
return false;
|
||||
}
|
||||
|
||||
vProcess->start(QString::fromStdString(_config.v2Path), QStringList() << "-config"
|
||||
<< QV2RAY_GENERATED_CONFIG_DIRPATH + "config.json",
|
||||
QIODevice::ReadWrite | QIODevice::Text);
|
||||
vProcess->waitForStarted();
|
||||
Status = STARTED;
|
||||
return true;
|
||||
} else {
|
||||
Status = STOPPED;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Qv2Instance::stop()
|
||||
void Qv2Instance::Stop()
|
||||
{
|
||||
vProcess->close();
|
||||
Status = STOPPED;
|
||||
@ -84,7 +92,7 @@ namespace Qv2ray
|
||||
|
||||
Qv2Instance::~Qv2Instance()
|
||||
{
|
||||
stop();
|
||||
Stop();
|
||||
delete vProcess;
|
||||
}
|
||||
}
|
||||
|
@ -17,13 +17,13 @@ namespace Qv2ray
|
||||
public:
|
||||
explicit Qv2Instance(QWidget *parent = nullptr);
|
||||
|
||||
bool start();
|
||||
void stop();
|
||||
bool Start();
|
||||
void Stop();
|
||||
|
||||
QString readOutput();
|
||||
V2RAY_INSTANCE_STARTUP_STATUS Status;
|
||||
static bool checkConfigFile(QString path);
|
||||
static bool checkCoreExe();
|
||||
static bool VerifyVConfigFile(QString path);
|
||||
static bool ValidateV2rayCoreExe();
|
||||
|
||||
~Qv2Instance();
|
||||
private:
|
||||
|
@ -41,22 +41,24 @@ namespace Qv2ray
|
||||
struct Qv2Config {
|
||||
string language;
|
||||
bool runAsRoot;
|
||||
string logLevel;
|
||||
string v2Path;
|
||||
int logLevel;
|
||||
string v2CorePath;
|
||||
string v2AssetsPath;
|
||||
QvInbondSetting httpSetting;
|
||||
QvInbondSetting socksSetting;
|
||||
list<string> configs;
|
||||
Qv2Config(): language(), runAsRoot(), logLevel(), httpSetting(), socksSetting(), configs() { }
|
||||
Qv2Config(string lang, string exePath, string log, QvInbondSetting httpIn, QvInbondSetting socksIN): Qv2Config()
|
||||
Qv2Config(): httpSetting(), socksSetting(), configs() { }
|
||||
Qv2Config(string lang, string exePath, string assetsPath, int log, QvInbondSetting httpIn, QvInbondSetting socksIN): Qv2Config()
|
||||
{
|
||||
v2Path = exePath;
|
||||
language = lang;
|
||||
v2CorePath = exePath;
|
||||
v2AssetsPath = assetsPath;
|
||||
logLevel = log;
|
||||
httpSetting = httpIn;
|
||||
socksSetting = socksIN;
|
||||
runAsRoot = false;
|
||||
}
|
||||
XTOSTRUCT(O(language, v2Path, runAsRoot, logLevel, httpSetting, socksSetting, configs))
|
||||
XTOSTRUCT(O(language, v2CorePath, v2AssetsPath, runAsRoot, logLevel, httpSetting, socksSetting, configs))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -78,14 +78,17 @@ namespace Qv2ray
|
||||
{
|
||||
return dir->entryList(QStringList() << "*" << "*.*", QDir::Hidden | QDir::Files);
|
||||
}
|
||||
|
||||
bool CheckFile(QDir *dir, QString fileName)
|
||||
{
|
||||
return GetFileList(dir).indexOf(fileName) >= 0;
|
||||
}
|
||||
|
||||
void QvMessageBox(QWidget *parent, QString title, QString text)
|
||||
{
|
||||
QMessageBox::warning(parent, title, text, QMessageBox::Ok | QMessageBox::Default, 0);
|
||||
}
|
||||
|
||||
QTranslator *getTranslator(QString lang)
|
||||
{
|
||||
QTranslator *translator = new QTranslator();
|
||||
|
11
src/main.cpp
11
src/main.cpp
@ -16,17 +16,20 @@ bool initializeQv()
|
||||
/// Qv2ray Config Path and ends with "/"
|
||||
QString configPath = "";
|
||||
QString exeDefaultPath = "";
|
||||
QString v2AssetsPath = "";
|
||||
#if defined(__WIN32) || defined(__APPLE__)
|
||||
// For Windows and MacOS, there's no such 'installation' of a software
|
||||
// package, So as what ShadowSocks and v2rayX does, save config files next to
|
||||
// the executable.
|
||||
configPath = "./qv2ray.conf.d";
|
||||
exeDefaultPath = "./v2ray";
|
||||
configPath = "./qv2ray.d";
|
||||
exeDefaultPath = "./qv2ray.d/v2ray";
|
||||
v2AssetsPath = "./qv2ray.d";
|
||||
#else
|
||||
// However, for linux, this software can be and/or will be provided as a
|
||||
// package and install to whatever /usr/bin or /usr/local/bin or even /opt/
|
||||
// Thus we save config files in the user's home directory.
|
||||
configPath = QDir::homePath() + "/.qv2ray/";
|
||||
configPath = QDir::homePath() + "/.qv2ray";
|
||||
v2AssetsPath = "/etc/v2ray";
|
||||
exeDefaultPath = "/bin/v2ray";
|
||||
#endif
|
||||
SetConfigDirPath(configPath);
|
||||
@ -60,7 +63,7 @@ bool initializeQv()
|
||||
// These below genenrated very basic global config.
|
||||
QvInbondSetting inHttp = QvInbondSetting(true, "127.0.0.1", 8080);
|
||||
QvInbondSetting inSocks = QvInbondSetting(true, "127.0.0.1", 1080);
|
||||
Qv2Config conf = Qv2Config("zh-CN", exeDefaultPath.toStdString(), "info", inHttp, inSocks);
|
||||
Qv2Config conf = Qv2Config("zh-CN", exeDefaultPath.toStdString(), v2AssetsPath.toStdString(), 2, inHttp, inSocks);
|
||||
//
|
||||
// Save initial config.
|
||||
SetGlobalConfig(conf);
|
||||
|
@ -25,84 +25,56 @@ ImportConfigWindow::~ImportConfigWindow()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ImportConfigWindow::on_pushButton_clicked()
|
||||
void ImportConfigWindow::on_importSourceCombo_currentIndexChanged(int index)
|
||||
{
|
||||
ui->stackedWidget->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
void ImportConfigWindow::on_selectFileBtn_clicked()
|
||||
{
|
||||
QString dir = QFileDialog::getOpenFileName(this, tr("OpenConfigFile"), "~/");
|
||||
ui->fileLineTxt->setText(dir);
|
||||
}
|
||||
|
||||
void ImportConfigWindow::savefromFile(QString path, QString alias)
|
||||
{
|
||||
Q_UNUSED(path)
|
||||
Q_UNUSED(alias)
|
||||
QFile configFile(path);
|
||||
|
||||
if (!configFile.open(QIODevice::ReadOnly)) {
|
||||
QvMessageBox(this, tr("ImportConfig"), tr("CannotOpenFile"));
|
||||
qDebug() << "ImportConfig::CannotOpenFile";
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray allData = configFile.readAll();
|
||||
configFile.close();
|
||||
QJsonDocument v2conf(QJsonDocument::fromJson(allData));
|
||||
QJsonObject rootobj = v2conf.object();
|
||||
QJsonObject outbound;
|
||||
|
||||
if (rootobj.contains("outbounds")) {
|
||||
outbound = rootobj.value("outbounds").toArray().first().toObject();
|
||||
} else {
|
||||
outbound = rootobj.value("outbound").toObject();
|
||||
}
|
||||
|
||||
if (!QFile::copy(path, "newFile")) {
|
||||
QvMessageBox(this, tr("ImportConfig"), tr("CannotCopyCustomConfig"));
|
||||
qDebug() << "ImportConfig::CannotCopyCustomConfig";
|
||||
}
|
||||
}
|
||||
|
||||
void ImportConfigWindow::on_buttonBox_accepted()
|
||||
void ImportConfigWindow::on_buttonBox_clicked(QAbstractButton *button)
|
||||
{
|
||||
QString alias = ui->nameTxt->text();
|
||||
QJsonObject config;
|
||||
|
||||
if (ui->importSourceCombo->currentIndex() == 0) { // From File...
|
||||
bool overrideInBound = ui->useCurrentSettingRidBtn->isChecked();
|
||||
on_verifyFileBtn_clicked();
|
||||
bool overrideInBound = ui->keepInboundCheckBox->isChecked();
|
||||
|
||||
if (!Qv2Instance::VerifyVConfigFile(ui->fileLineTxt->text())) {
|
||||
QvMessageBox(this, tr("#InvalidConfigFile"), tr("ConfigFileCheckFailed"));
|
||||
return;
|
||||
}
|
||||
|
||||
QString path = ui->fileLineTxt->text();
|
||||
savefromFile(path, alias);
|
||||
// !!! TODO
|
||||
config = ConvertConfigFromFile(path, overrideInBound);
|
||||
} else {
|
||||
on_verifyVMessBtn_clicked();
|
||||
auto config = ConvertOutboundFromVMessString(ui->vmessConnectionStringTxt->toPlainText());
|
||||
QString vmess = ui->vmessConnectionStringTxt->toPlainText();
|
||||
int result = VerifyVMessProtocolString(vmess);
|
||||
|
||||
if (result == 0) {
|
||||
//QvMessageBox(this, tr("#VMessCheck"), tr("#AbleToImportConfig"));
|
||||
} else if (result == -1) {
|
||||
QvMessageBox(this, tr("#VMessCheck"), tr("#NotValidVMessProtocolString"));
|
||||
done(0);
|
||||
return;
|
||||
} else {
|
||||
QvMessageBox(this, tr("#VMessCheck"), tr("#INTERNAL_ERROR"));
|
||||
return;
|
||||
}
|
||||
|
||||
config = ConvertConfigFromVMessString(ui->vmessConnectionStringTxt->toPlainText());
|
||||
//
|
||||
alias = alias != "" ? alias : config["QV2RAY_ALIAS"].toString();
|
||||
config.remove("QV2RAY_ALIAS");
|
||||
Qv2Config conf = GetGlobalConfig();
|
||||
conf.configs.push_back(alias.toStdString());
|
||||
SetGlobalConfig(conf);
|
||||
SaveConnectionConfig(config, &alias);
|
||||
emit s_reload_config();
|
||||
}
|
||||
}
|
||||
|
||||
void ImportConfigWindow::on_verifyVMessBtn_clicked()
|
||||
{
|
||||
QString vmess = ui->vmessConnectionStringTxt->toPlainText();
|
||||
int result = VerifyVMessProtocolString(vmess);
|
||||
|
||||
if (result == 0) {
|
||||
QvMessageBox(this, tr("#VMessCheck"), tr("#AbleToImportConfig"));
|
||||
} else if (result == -1) {
|
||||
QvMessageBox(this, tr("#VMessCheck"), tr("#NotValidVMessProtocolString"));
|
||||
} else {
|
||||
QvMessageBox(this, tr("#VMessCheck"), tr("#INTERNAL_ERROR"));
|
||||
}
|
||||
}
|
||||
|
||||
void ImportConfigWindow::on_verifyFileBtn_clicked()
|
||||
{
|
||||
if (!Qv2Instance::checkConfigFile(ui->fileLineTxt->text())) {
|
||||
QvMessageBox(this, tr("#InvalidConfigFile"), tr("ConfigFileCheckFailed"));
|
||||
} else {
|
||||
QvMessageBox(this, tr("#VConfigFileCheckPassed"), tr("#AbleToImportConfig"));
|
||||
}
|
||||
Qv2Config conf = GetGlobalConfig();
|
||||
conf.configs.push_back(alias.toStdString());
|
||||
SetGlobalConfig(conf);
|
||||
SaveConnectionConfig(config, &alias);
|
||||
emit s_reload_config();
|
||||
}
|
||||
|
@ -15,18 +15,19 @@ class ImportConfigWindow : public QDialog
|
||||
|
||||
public:
|
||||
explicit ImportConfigWindow(QWidget *parent = nullptr);
|
||||
void savefromFile(QString path, QString alias);
|
||||
~ImportConfigWindow();
|
||||
signals:
|
||||
void s_reload_config();
|
||||
private slots:
|
||||
void on_pushButton_clicked();
|
||||
void on_buttonBox_accepted();
|
||||
void on_verifyVMessBtn_clicked();
|
||||
void on_verifyFileBtn_clicked();
|
||||
void on_importSourceCombo_currentIndexChanged(int index);
|
||||
|
||||
void on_selectFileBtn_clicked();
|
||||
|
||||
void on_buttonBox_clicked(QAbstractButton *button);
|
||||
|
||||
private:
|
||||
Ui::ImportConfigWindow *ui;
|
||||
|
||||
};
|
||||
|
||||
#endif // IMPORTCONF_H
|
||||
|
@ -6,174 +6,165 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>650</width>
|
||||
<height>350</height>
|
||||
<width>370</width>
|
||||
<height>420</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>650</width>
|
||||
<height>350</height>
|
||||
<width>370</width>
|
||||
<height>420</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>370</width>
|
||||
<height>420</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Import file</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0" columnstretch="1,1">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,6">
|
||||
<item>
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="aliasLabel">
|
||||
<property name="text">
|
||||
<string>#Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="nameTxt"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>#ImportFrom</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="importSourceCombo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Existing File</string>
|
||||
<string>#ExistingFile</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>VMess Connection String</string>
|
||||
<string>#VMessConnectionString</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QGroupBox" name="fromVMessGroupBox">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>#From VMess Connection String</string>
|
||||
<string>#Import</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>#VMess Connection String</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="vmessConnectionStringTxt"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="verifyVMessBtn">
|
||||
<property name="text">
|
||||
<string>Verify</string>
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="fileLabel">
|
||||
<property name="text">
|
||||
<string>#Path</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="fileLineTxt">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="selectFileBtn">
|
||||
<property name="text">
|
||||
<string>#SelectFile</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>#Inbound</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="keepInboundCheckBox">
|
||||
<property name="text">
|
||||
<string>#KeepImportedInbounds</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>#VMess Connection String</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="vmessConnectionStringTxt"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
<set>QDialogButtonBox::Discard|QDialogButtonBox::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="fromFileGroupBox">
|
||||
<property name="title">
|
||||
<string>#FromFile</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="fileLabel">
|
||||
<property name="text">
|
||||
<string>#Path</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="fileLineTxt">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="selectFileBtn">
|
||||
<property name="text">
|
||||
<string>#SelectFile</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="aliasLabel">
|
||||
<property name="text">
|
||||
<string>#Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="nameTxt"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>#Inbound</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="useCurrentSettingRidBtn">
|
||||
<property name="text">
|
||||
<string>#UseCurrent</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="useImportedRidBtn">
|
||||
<property name="text">
|
||||
<string>#UseImported</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="verifyFileBtn">
|
||||
<property name="text">
|
||||
<string>Verify</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>importSourceCombo</tabstop>
|
||||
<tabstop>fileLineTxt</tabstop>
|
||||
<tabstop>selectFileBtn</tabstop>
|
||||
<tabstop>nameTxt</tabstop>
|
||||
<tabstop>useCurrentSettingRidBtn</tabstop>
|
||||
<tabstop>useImportedRidBtn</tabstop>
|
||||
<tabstop>vmessConnectionStringTxt</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
|
@ -101,7 +101,7 @@ void MainWindow::UpdateLog()
|
||||
void MainWindow::on_startButton_clicked()
|
||||
{
|
||||
ui->logText->clear();
|
||||
bool startFlag = this->vinstance->start();
|
||||
bool startFlag = this->vinstance->Start();
|
||||
trayMenu->actions()[2]->setEnabled(!startFlag);
|
||||
trayMenu->actions()[3]->setEnabled(startFlag);
|
||||
trayMenu->actions()[4]->setEnabled(startFlag);
|
||||
@ -109,7 +109,7 @@ void MainWindow::on_startButton_clicked()
|
||||
|
||||
void MainWindow::on_stopButton_clicked()
|
||||
{
|
||||
this->vinstance->stop();
|
||||
this->vinstance->Stop();
|
||||
ui->logText->clear();
|
||||
trayMenu->actions()[2]->setEnabled(true);
|
||||
trayMenu->actions()[3]->setEnabled(false);
|
||||
|
@ -14,7 +14,7 @@ PrefrencesWindow::PrefrencesWindow(QWidget *parent) : QDialog(parent),
|
||||
CurrentConfig = GetGlobalConfig();
|
||||
ui->languageComboBox->setCurrentText(QString::fromStdString(CurrentConfig.language));
|
||||
ui->runAsRootCheckBox->setChecked(CurrentConfig.runAsRoot);
|
||||
ui->logLevelCheckBox->setCurrentText(QString::fromStdString(CurrentConfig.logLevel));
|
||||
ui->logLevelComboBox->setCurrentIndex(CurrentConfig.logLevel);
|
||||
//
|
||||
ui->httpCB->setChecked(CurrentConfig.httpSetting.enabled);
|
||||
ui->httpPortLE->setText(QString::fromStdString(to_string(CurrentConfig.httpSetting.port)));
|
||||
@ -29,7 +29,7 @@ PrefrencesWindow::PrefrencesWindow(QWidget *parent) : QDialog(parent),
|
||||
ui->socksAuthUsernameTxt->setText(QString::fromStdString(CurrentConfig.socksSetting.authUsername));
|
||||
ui->socksAuthPasswordTxt->setText(QString::fromStdString(CurrentConfig.socksSetting.authPassword));
|
||||
//
|
||||
ui->vCoreExePathTxt->setText(QString::fromStdString(CurrentConfig.v2Path));
|
||||
ui->vCoreExePathTxt->setText(QString::fromStdString(CurrentConfig.v2CorePath));
|
||||
//
|
||||
ui->httpPortLE->setValidator(new QIntValidator());
|
||||
ui->socksPortLE->setValidator(new QIntValidator());
|
||||
@ -98,7 +98,7 @@ void PrefrencesWindow::on_runAsRootCheckBox_stateChanged(int arg1)
|
||||
{
|
||||
Q_UNUSED(arg1)
|
||||
#ifdef _WIN32
|
||||
showWarnMessageBox(this, tr("Prefrences"), tr("RunAsRootNotOnWindows"));
|
||||
QvMessageBox(this, tr("Prefrences"), tr("RunAsRootNotOnWindows"));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="logLevelCheckBox">
|
||||
<widget class="QComboBox" name="logLevelComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
@ -336,7 +336,7 @@
|
||||
<tabstops>
|
||||
<tabstop>languageComboBox</tabstop>
|
||||
<tabstop>runAsRootCheckBox</tabstop>
|
||||
<tabstop>logLevelCheckBox</tabstop>
|
||||
<tabstop>logLevelComboBox</tabstop>
|
||||
<tabstop>muxEnabledCB</tabstop>
|
||||
<tabstop>muxConcurrencyTxt</tabstop>
|
||||
<tabstop>httpCB</tabstop>
|
||||
|
@ -262,135 +262,91 @@
|
||||
<context>
|
||||
<name>ImportConfigWindow</name>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="20"/>
|
||||
<location filename="../src/w_ImportConfig.ui" line="26"/>
|
||||
<source>Import file</source>
|
||||
<translation>Import file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="28"/>
|
||||
<location filename="../src/w_ImportConfig.ui" line="50"/>
|
||||
<source>#ImportFrom</source>
|
||||
<translation>Import From</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="36"/>
|
||||
<source>Existing File</source>
|
||||
<translation>Existing File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="41"/>
|
||||
<source>VMess Connection String</source>
|
||||
<translation>VMess Connection String</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="67"/>
|
||||
<location filename="../src/w_ImportConfig.ui" line="160"/>
|
||||
<source>Verify</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="87"/>
|
||||
<source>#FromFile</source>
|
||||
<translation>From file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="95"/>
|
||||
<location filename="../src/w_ImportConfig.ui" line="94"/>
|
||||
<source>#Path</source>
|
||||
<translation>Path</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="111"/>
|
||||
<location filename="../src/w_ImportConfig.ui" line="110"/>
|
||||
<source>#SelectFile</source>
|
||||
<translation>Select File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="120"/>
|
||||
<location filename="../src/w_ImportConfig.ui" line="40"/>
|
||||
<source>#Name</source>
|
||||
<translation>Name</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="130"/>
|
||||
<location filename="../src/w_ImportConfig.ui" line="64"/>
|
||||
<source>#ExistingFile</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="69"/>
|
||||
<source>#VMessConnectionString</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="79"/>
|
||||
<source>#Import</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="119"/>
|
||||
<source>#Inbound</source>
|
||||
<translation>Inbound Settings</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="126"/>
|
||||
<source>#KeepImportedInbounds</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="139"/>
|
||||
<source>#UseCurrent</source>
|
||||
<translation>Use Current Settings</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="149"/>
|
||||
<source>#UseImported</source>
|
||||
<translation>Use Imported Inbound Settings</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="51"/>
|
||||
<source>#From VMess Connection String</source>
|
||||
<translation>From VMess Connection String</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="57"/>
|
||||
<source>#VMess Connection String</source>
|
||||
<translation>VMess Connection String</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="30"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="35"/>
|
||||
<source>OpenConfigFile</source>
|
||||
<translation type="unfinished">Open Config File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="41"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="59"/>
|
||||
<source>ImportConfig</source>
|
||||
<translation type="unfinished">Import Config</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="41"/>
|
||||
<source>CannotOpenFile</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="59"/>
|
||||
<source>CannotCopyCustomConfig</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="95"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="61"/>
|
||||
<source>#NotValidVMessProtocolString</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="93"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="106"/>
|
||||
<source>#AbleToImportConfig</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="93"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="95"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="97"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="61"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="65"/>
|
||||
<source>#VMessCheck</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="97"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="65"/>
|
||||
<source>#INTERNAL_ERROR</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="104"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="48"/>
|
||||
<source>#InvalidConfigFile</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="104"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="48"/>
|
||||
<source>ConfigFileCheckFailed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="106"/>
|
||||
<source>#VConfigFileCheckPassed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -666,27 +622,27 @@
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="../src/main.cpp" line="89"/>
|
||||
<location filename="../src/main.cpp" line="92"/>
|
||||
<source>AnotherInstanceRunning</source>
|
||||
<translation>Another instance is already running</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/main.cpp" line="89"/>
|
||||
<location filename="../src/main.cpp" line="92"/>
|
||||
<source>Qv2ray</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/QvCoreInteractions.cpp" line="45"/>
|
||||
<location filename="../src/QvCoreInteractions.cpp" line="48"/>
|
||||
<source>CoreNotFound</source>
|
||||
<translation>Core files are not found</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/QvCoreInteractions.cpp" line="45"/>
|
||||
<location filename="../src/QvCoreInteractions.cpp" line="48"/>
|
||||
<source>CoreFileNotFoundExplainationAt:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/QvCoreInteractions.cpp" line="24"/>
|
||||
<location filename="../src/QvCoreInteractions.cpp" line="27"/>
|
||||
<source>ConfigurationError</source>
|
||||
<translation>Configuration Error</translation>
|
||||
</message>
|
||||
|
@ -262,135 +262,91 @@
|
||||
<context>
|
||||
<name>ImportConfigWindow</name>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="20"/>
|
||||
<location filename="../src/w_ImportConfig.ui" line="26"/>
|
||||
<source>Import file</source>
|
||||
<translation>导入文件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="28"/>
|
||||
<location filename="../src/w_ImportConfig.ui" line="50"/>
|
||||
<source>#ImportFrom</source>
|
||||
<translation>导入源</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="36"/>
|
||||
<source>Existing File</source>
|
||||
<translation>现有文件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="41"/>
|
||||
<source>VMess Connection String</source>
|
||||
<translation>VMess 连接字符串</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="67"/>
|
||||
<location filename="../src/w_ImportConfig.ui" line="160"/>
|
||||
<source>Verify</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="87"/>
|
||||
<source>#FromFile</source>
|
||||
<translation>从文件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="95"/>
|
||||
<location filename="../src/w_ImportConfig.ui" line="94"/>
|
||||
<source>#Path</source>
|
||||
<translation>路径</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="111"/>
|
||||
<location filename="../src/w_ImportConfig.ui" line="110"/>
|
||||
<source>#SelectFile</source>
|
||||
<translation>选择文件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="120"/>
|
||||
<location filename="../src/w_ImportConfig.ui" line="40"/>
|
||||
<source>#Name</source>
|
||||
<translation>名称</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="130"/>
|
||||
<location filename="../src/w_ImportConfig.ui" line="64"/>
|
||||
<source>#ExistingFile</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="69"/>
|
||||
<source>#VMessConnectionString</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="79"/>
|
||||
<source>#Import</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="119"/>
|
||||
<source>#Inbound</source>
|
||||
<translation>入站设置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="126"/>
|
||||
<source>#KeepImportedInbounds</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="139"/>
|
||||
<source>#UseCurrent</source>
|
||||
<translation>使用现有设置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="149"/>
|
||||
<source>#UseImported</source>
|
||||
<translation>使用导入的设置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="51"/>
|
||||
<source>#From VMess Connection String</source>
|
||||
<translation>从 VMess 连接字符串</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.ui" line="57"/>
|
||||
<source>#VMess Connection String</source>
|
||||
<translation>VMess 连接字符串</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="30"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="35"/>
|
||||
<source>OpenConfigFile</source>
|
||||
<translation type="unfinished">打开配置文件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="41"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="59"/>
|
||||
<source>ImportConfig</source>
|
||||
<translation type="unfinished">导入配置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="41"/>
|
||||
<source>CannotOpenFile</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="59"/>
|
||||
<source>CannotCopyCustomConfig</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="95"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="61"/>
|
||||
<source>#NotValidVMessProtocolString</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="93"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="106"/>
|
||||
<source>#AbleToImportConfig</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="93"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="95"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="97"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="61"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="65"/>
|
||||
<source>#VMessCheck</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="97"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="65"/>
|
||||
<source>#INTERNAL_ERROR</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="104"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="48"/>
|
||||
<source>#InvalidConfigFile</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="104"/>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="48"/>
|
||||
<source>ConfigFileCheckFailed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/w_ImportConfig.cpp" line="106"/>
|
||||
<source>#VConfigFileCheckPassed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -666,27 +622,27 @@
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="../src/main.cpp" line="89"/>
|
||||
<location filename="../src/main.cpp" line="92"/>
|
||||
<source>AnotherInstanceRunning</source>
|
||||
<translation>另一个实例正在运行</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/main.cpp" line="89"/>
|
||||
<location filename="../src/main.cpp" line="92"/>
|
||||
<source>Qv2ray</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/QvCoreInteractions.cpp" line="45"/>
|
||||
<location filename="../src/QvCoreInteractions.cpp" line="48"/>
|
||||
<source>CoreNotFound</source>
|
||||
<translation>核心文件未找到</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/QvCoreInteractions.cpp" line="45"/>
|
||||
<location filename="../src/QvCoreInteractions.cpp" line="48"/>
|
||||
<source>CoreFileNotFoundExplainationAt:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/QvCoreInteractions.cpp" line="24"/>
|
||||
<location filename="../src/QvCoreInteractions.cpp" line="27"/>
|
||||
<source>ConfigurationError</source>
|
||||
<translation>配置出错</translation>
|
||||
</message>
|
||||
|
Loading…
Reference in New Issue
Block a user