feat: preview edit custom

This commit is contained in:
arm64v8a
2023-01-02 16:13:12 +09:00
parent 5e1d0cdce4
commit 62aee79383
13 changed files with 269 additions and 168 deletions

View File

@@ -449,8 +449,28 @@ namespace NekoRay {
} }
// chain rules: this // chain rules: this
auto mapping_port = MkPort(); auto ext_mapping_port = 0;
auto ext_socks_port = 0;
auto thisExternalStat = ent->bean->NeedExternal(isFirstProfile, dataStore->running_spmode == SystemProxyMode::VPN); auto thisExternalStat = ent->bean->NeedExternal(isFirstProfile, dataStore->running_spmode == SystemProxyMode::VPN);
// determine port
if (thisExternalStat > 0) {
if (ent->type == "custom") {
auto bean = ent->CustomBean();
if (InRange(bean->mapping_port, 0, 65535)) {
ext_mapping_port = bean->mapping_port;
} else {
ext_mapping_port = MkPort();
}
if (InRange(bean->socks_port, 0, 65535)) {
ext_socks_port = bean->socks_port;
} else {
ext_socks_port = MkPort();
}
} else {
ext_mapping_port = MkPort();
ext_socks_port = MkPort();
}
}
if (thisExternalStat == 2) dataStore->need_keep_vpn_off = true; if (thisExternalStat == 2) dataStore->need_keep_vpn_off = true;
if (thisExternalStat == 1) { if (thisExternalStat == 1) {
// mapping // mapping
@@ -459,7 +479,7 @@ namespace NekoRay {
{"type", "direct"}, {"type", "direct"},
{"tag", tagOut + "-mapping"}, {"tag", tagOut + "-mapping"},
{"listen", "127.0.0.1"}, {"listen", "127.0.0.1"},
{"listen_port", mapping_port}, {"listen_port", ext_mapping_port},
{"override_address", ent->bean->serverAddress}, {"override_address", ent->bean->serverAddress},
{"override_port", ent->bean->serverPort}, {"override_port", ent->bean->serverPort},
}; };
@@ -468,7 +488,7 @@ namespace NekoRay {
{"protocol", "dokodemo-door"}, {"protocol", "dokodemo-door"},
{"tag", tagOut + "-mapping"}, {"tag", tagOut + "-mapping"},
{"listen", "127.0.0.1"}, {"listen", "127.0.0.1"},
{"port", mapping_port}, {"port", ext_mapping_port},
{"settings", QJsonObject{ {"settings", QJsonObject{
// to // to
{"address", ent->bean->serverAddress}, {"address", ent->bean->serverAddress},
@@ -497,12 +517,9 @@ namespace NekoRay {
// Outbound // Outbound
QJsonObject outbound; QJsonObject outbound;
fmt::CoreObjOutboundBuildResult coreR;
fmt::ExternalBuildResult extR;
if (thisExternalStat > 0) { if (thisExternalStat > 0) {
auto ext_socks_port = MkPort(); const auto extR = ent->bean->BuildExternal(ext_mapping_port, ext_socks_port, thisExternalStat);
extR = ent->bean->BuildExternal(mapping_port, ext_socks_port, thisExternalStat);
if (extR.program.isEmpty()) { if (extR.program.isEmpty()) {
status->result->error = QObject::tr("Core not found: %1").arg(ent->bean->DisplayType()); status->result->error = QObject::tr("Core not found: %1").arg(ent->bean->DisplayType());
return {}; return {};
@@ -530,14 +547,14 @@ namespace NekoRay {
} }
// EXTERNAL PROCESS // EXTERNAL PROCESS
auto extC = new sys::ExternalProcess(); QSharedPointer<sys::ExternalProcess> extC(new sys::ExternalProcess());
extC->tag = ent->bean->DisplayType(); extC->tag = ent->bean->DisplayType();
extC->program = extR.program; extC->program = extR.program;
extC->arguments = extR.arguments; extC->arguments = extR.arguments;
extC->env = extR.env; extC->env = extR.env;
status->result->ext += extC; status->result->exts.emplace_back(extR, extC);
} else { } else {
coreR = IS_NEKO_BOX ? ent->bean->BuildCoreObjSingBox() : ent->bean->BuildCoreObjV2Ray(); const auto coreR = IS_NEKO_BOX ? ent->bean->BuildCoreObjSingBox() : ent->bean->BuildCoreObjV2Ray();
if (coreR.outbound.isEmpty()) { if (coreR.outbound.isEmpty()) {
status->result->error = "unsupported outbound"; status->result->error = "unsupported outbound";
return {}; return {};

View File

@@ -14,7 +14,7 @@ namespace NekoRay {
QSharedPointer<traffic::TrafficData> outboundStat; // main QSharedPointer<traffic::TrafficData> outboundStat; // main
QStringList ignoreConnTag; QStringList ignoreConnTag;
QList<sys::ExternalProcess *> ext; std::list<std::pair<fmt::ExternalBuildResult, QSharedPointer<sys::ExternalProcess>>> exts; // extR to extC
}; };
class BuildConfigStatus { class BuildConfigStatus {

View File

@@ -20,7 +20,7 @@
auto TempFile = QFileInfo(f).absoluteFilePath(); auto TempFile = QFileInfo(f).absoluteFilePath();
namespace NekoRay::fmt { namespace NekoRay::fmt {
// 0: no external // 0: Internal
// 1: Mapping External // 1: Mapping External
// 2: Direct External // 2: Direct External
@@ -85,13 +85,10 @@ namespace NekoRay::fmt {
for (int i = 0; i < result.arguments.length(); i++) { for (int i = 0; i < result.arguments.length(); i++) {
auto arg = result.arguments[i]; auto arg = result.arguments[i];
if (arg.contains("%mapping_port%")) { arg = arg.replace("%mapping_port%", Int2String(mapping_port));
arg = arg.replace("%mapping_port%", Int2String(mapping_port)); arg = arg.replace("%socks_port%", Int2String(socks_port));
} else if (arg.contains("%socks_port%")) { arg = arg.replace("%server_addr%", serverAddress);
arg = arg.replace("%socks_port%", Int2String(socks_port)); arg = arg.replace("%server_port%", Int2String(serverPort));
} else {
continue;
}
result.arguments[i] = arg; result.arguments[i] = arg;
} }

View File

@@ -9,12 +9,16 @@ namespace NekoRay::fmt {
QList<QString> command; QList<QString> command;
QString config_suffix; QString config_suffix;
QString config_simple; QString config_simple;
int mapping_port = 0;
int socks_port = 0;
CustomBean() : AbstractBean(0) { CustomBean() : AbstractBean(0) {
_add(new configItem("core", &core, itemType::string)); _add(new configItem("core", &core, itemType::string));
_add(new configItem("cmd", &command, itemType::stringList)); _add(new configItem("cmd", &command, itemType::stringList));
_add(new configItem("cs", &config_simple, itemType::string)); _add(new configItem("cs", &config_simple, itemType::string));
_add(new configItem("cs_suffix", &config_suffix, itemType::string)); _add(new configItem("cs_suffix", &config_suffix, itemType::string));
_add(new configItem("mapping_port", &mapping_port, itemType::integer));
_add(new configItem("socks_port", &socks_port, itemType::integer));
}; };
QString DisplayType() override { QString DisplayType() override {

View File

@@ -5,12 +5,17 @@
#include <QApplication> #include <QApplication>
namespace NekoRay::sys { namespace NekoRay::sys {
ExternalProcess::ExternalProcess() : QProcess() {} ExternalProcess::ExternalProcess() : QProcess() {
// qDebug() << "[Debug] ExternalProcess()" << this << running_ext;
}
ExternalProcess::~ExternalProcess() {
// qDebug() << "[Debug] ~ExternalProcess()" << this << running_ext;
}
void ExternalProcess::Start() { void ExternalProcess::Start() {
if (started) return; if (started) return;
started = true; started = true;
if (managed) running_ext.push_back(this);
if (show_log) { if (show_log) {
connect(this, &QProcess::readyReadStandardOutput, this, [&]() { connect(this, &QProcess::readyReadStandardOutput, this, [&]() {
@@ -19,14 +24,11 @@ namespace NekoRay::sys {
connect(this, &QProcess::readyReadStandardError, this, [&]() { connect(this, &QProcess::readyReadStandardError, this, [&]() {
MW_show_log_ext_vt100(readAllStandardError().trimmed()); MW_show_log_ext_vt100(readAllStandardError().trimmed());
}); });
}
if (managed) {
connect(this, &QProcess::errorOccurred, this, [&](QProcess::ProcessError error) { connect(this, &QProcess::errorOccurred, this, [&](QProcess::ProcessError error) {
if (!killed) { if (!killed) {
crashed = true; crashed = true;
MW_show_log_ext(tag, "errorOccurred:" + errorString()); MW_show_log_ext(tag, "errorOccurred:" + errorString());
MW_dialog_message("ExternalProcess", "Crashed"); if (managed) MW_dialog_message("ExternalProcess", "Crashed");
} }
}); });
connect(this, &QProcess::stateChanged, this, [&](QProcess::ProcessState state) { connect(this, &QProcess::stateChanged, this, [&](QProcess::ProcessState state) {
@@ -37,7 +39,7 @@ namespace NekoRay::sys {
crashed = true; crashed = true;
MW_show_log_ext(tag, "[Error] Program exited accidentally: " + errorString()); MW_show_log_ext(tag, "[Error] Program exited accidentally: " + errorString());
Kill(); Kill();
MW_dialog_message("ExternalProcess", "Crashed"); if (managed) MW_dialog_message("ExternalProcess", "Crashed");
} }
} }
}); });
@@ -51,7 +53,6 @@ namespace NekoRay::sys {
void ExternalProcess::Kill() { void ExternalProcess::Kill() {
if (killed) return; if (killed) return;
killed = true; killed = true;
if (managed) running_ext.removeAll(this);
if (!crashed) { if (!crashed) {
QProcess::kill(); QProcess::kill();
@@ -59,7 +60,7 @@ namespace NekoRay::sys {
} }
} }
CoreProcess::CoreProcess(const QString &core_path, const QStringList &args) { CoreProcess::CoreProcess(const QString &core_path, const QStringList &args) : ExternalProcess() {
ExternalProcess::managed = false; ExternalProcess::managed = false;
ExternalProcess::show_log = false; ExternalProcess::show_log = false;
ExternalProcess::program = core_path; ExternalProcess::program = core_path;

View File

@@ -12,10 +12,11 @@ namespace NekoRay::sys {
QStringList arguments; QStringList arguments;
QStringList env; QStringList env;
bool managed = true; // running_ext & stateChanged bool managed = true; // MW_dialog_message
bool show_log = true; bool show_log = true;
ExternalProcess(); ExternalProcess();
~ExternalProcess();
// start & kill is one time // start & kill is one time
@@ -41,6 +42,6 @@ namespace NekoRay::sys {
int restart_id = -1; int restart_id = -1;
}; };
// start & kill change this list // 手动管理
inline QList<ExternalProcess *> running_ext; inline QList<QSharedPointer<ExternalProcess>> running_ext;
} // namespace NekoRay::sys } // namespace NekoRay::sys

View File

@@ -601,10 +601,6 @@
<source>Config Suffix</source> <source>Config Suffix</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Generator</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Please read the documentation. If you don&apos;t understand, use a share link instead.</source> <source>Please read the documentation. If you don&apos;t understand, use a share link instead.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -617,6 +613,22 @@
<source>Please pick a core.</source> <source>Please pick a core.</source>
<translation>لطفا یک هسته انتخاب کنید.</translation> <translation>لطفا یک هسته انتخاب کنید.</translation>
</message> </message>
<message>
<source>Random if it&apos;s empty or zero.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Preview</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Preview replace</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Preview config</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>EditNaive</name> <name>EditNaive</name>

View File

@@ -591,10 +591,6 @@
<source>Command</source> <source>Command</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<source>Generator</source>
<translation></translation>
</message>
<message> <message>
<source>Json Editor</source> <source>Json Editor</source>
<translation>JSON </translation> <translation>JSON </translation>
@@ -615,6 +611,22 @@
<source>Config Suffix</source> <source>Config Suffix</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<source>Random if it&apos;s empty or zero.</source>
<translation>使</translation>
</message>
<message>
<source>Preview</source>
<translation></translation>
</message>
<message>
<source>Preview replace</source>
<translation></translation>
</message>
<message>
<source>Preview config</source>
<translation></translation>
</message>
</context> </context>
<context> <context>
<name>EditNaive</name> <name>EditNaive</name>

View File

@@ -234,12 +234,11 @@ void DialogEditProfile::typeSelected(const QString &newType) {
delete old; delete old;
// 左边 bean inner editor // 左边 bean inner editor
innerEditor->get_edit_dialog = [&]() { innerEditor->get_edit_dialog = [&]() { return (QWidget *) this; };
return (QWidget *) this; innerEditor->get_edit_text_name = [&]() { return ui->name->text(); };
}; innerEditor->get_edit_text_serverAddress = [&]() { return ui->address->text(); };
innerEditor->editor_cache_updated = [=] { innerEditor->get_edit_text_serverPort = [&]() { return ui->port->text(); };
editor_cache_updated_impl(); innerEditor->editor_cache_updated = [=] { editor_cache_updated_impl(); };
};
innerEditor->onStart(ent); innerEditor->onStart(ent);
// 左边 common // 左边 common

View File

@@ -4,6 +4,11 @@
#include "qv2ray/v2/ui/widgets/editors/w_JsonEditor.hpp" #include "qv2ray/v2/ui/widgets/editors/w_JsonEditor.hpp"
#include "fmt/CustomBean.hpp" #include "fmt/CustomBean.hpp"
#include "fmt/Preset.hpp" #include "fmt/Preset.hpp"
#include "db/ConfigBuilder.hpp"
#include "db/Database.hpp"
#include <QMessageBox>
#include <QClipboard>
EditCustom::EditCustom(QWidget *parent) : QWidget(parent), ui(new Ui::EditCustom) { EditCustom::EditCustom(QWidget *parent) : QWidget(parent), ui(new Ui::EditCustom) {
ui->setupUi(this); ui->setupUi(this);
@@ -20,6 +25,14 @@ EditCustom::~EditCustom() {
delete ui; delete ui;
} }
#define SAVE_CUSTOM_BEAN \
P_SAVE_COMBO(core) \
bean->command = ui->command->text().split(" "); \
P_SAVE_STRING_QTEXTEDIT(config_simple) \
P_SAVE_COMBO(config_suffix) \
P_SAVE_INT(mapping_port) \
P_SAVE_INT(socks_port)
void EditCustom::onStart(QSharedPointer<NekoRay::ProxyEntity> _ent) { void EditCustom::onStart(QSharedPointer<NekoRay::ProxyEntity> _ent) {
this->ent = _ent; this->ent = _ent;
auto bean = this->ent->CustomBean(); auto bean = this->ent->CustomBean();
@@ -50,6 +63,8 @@ void EditCustom::onStart(QSharedPointer<NekoRay::ProxyEntity> _ent) {
ui->command->setText(bean->command.join(" ")); ui->command->setText(bean->command.join(" "));
P_LOAD_STRING(config_simple) P_LOAD_STRING(config_simple)
P_LOAD_COMBO(config_suffix) P_LOAD_COMBO(config_suffix)
P_LOAD_INT(mapping_port)
P_LOAD_INT(socks_port)
// custom external // custom external
if (!bean->core.isEmpty()) { if (!bean->core.isEmpty()) {
@@ -72,17 +87,46 @@ void EditCustom::onStart(QSharedPointer<NekoRay::ProxyEntity> _ent) {
ui->config_suffix_l->hide(); ui->config_suffix_l->hide();
} }
// Generators // Preview
ui->generator->setVisible(false); connect(ui->preview, &QPushButton::clicked, this, [=] {
// CustomBean::BuildExternal
QStringList th;
auto mapping_port = ui->mapping_port->text().toInt();
auto socks_port = ui->socks_port->text().toInt();
th << "%mapping_port% => " + (mapping_port <= 0 ? "Random" : Int2String(mapping_port));
th << "%socks_port% => " + (socks_port <= 0 ? "Random" : Int2String(socks_port));
th << "%server_addr% => " + get_edit_text_serverAddress();
th << "%server_port% => " + get_edit_text_serverPort();
MessageBoxInfo(tr("Preview replace"), th.join("\n"));
// EditCustom::onEnd
auto tmpEnt = NekoRay::ProfileManager::NewProxyEntity("custom");
auto bean = tmpEnt->CustomBean();
SAVE_CUSTOM_BEAN
if (bean->core.isEmpty()) return;
//
auto result = NekoRay::BuildConfig(tmpEnt, false, false);
if (!result->error.isEmpty()) {
MessageBoxInfo(software_name, result->error);
return;
}
for (const auto &ext: result->exts) {
auto extR = ext.first;
auto command = QStringList{extR.program};
command += extR.arguments;
auto btn = QMessageBox::information(this, tr("Preview config"),
QString("Command: %1\n\n%2").arg(QStringList2Command(command), extR.config_export),
"OK", "Copy", "", 0, 0);
if (btn == 1) {
QApplication::clipboard()->setText(extR.config_export);
}
}
});
} }
bool EditCustom::onEnd() { bool EditCustom::onEnd() {
auto bean = this->ent->CustomBean(); auto bean = this->ent->CustomBean();
P_SAVE_COMBO(core) SAVE_CUSTOM_BEAN
bean->command = ui->command->text().split(" ");
P_SAVE_STRING_QTEXTEDIT(config_simple)
P_SAVE_COMBO(config_suffix)
if (bean->core.isEmpty()) { if (bean->core.isEmpty()) {
MessageBoxWarning(software_name, tr("Please pick a core.")); MessageBoxWarning(software_name, tr("Please pick a core."));

View File

@@ -7,129 +7,136 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>400</width>
<height>400</height> <height>450</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string notr="true">EditCustom</string> <string notr="true">EditCustom</string>
</property> </property>
<layout class="QHBoxLayout" name="layout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <widget class="QLabel" name="core_l">
<item> <property name="sizePolicy">
<widget class="QLabel" name="core_l"> <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<property name="sizePolicy"> <horstretch>0</horstretch>
<sizepolicy hsizetype="Maximum" vsizetype="Preferred"> <verstretch>0</verstretch>
<horstretch>0</horstretch> </sizepolicy>
<verstretch>0</verstretch> </property>
</sizepolicy> <property name="text">
</property> <string>Core</string>
<property name="text"> </property>
<string>Core</string> </widget>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="core">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="as_json">
<property name="text">
<string>Json Editor</string>
</property>
</widget>
</item>
</layout>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <widget class="QComboBox" name="core">
<item> <property name="editable">
<widget class="QLabel" name="command_l"> <bool>true</bool>
<property name="text"> </property>
<string>Command</string> </widget>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="command">
<property name="placeholderText">
<string notr="true">%config%</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="config_suffix_l">
<property name="text">
<string>Config Suffix</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="config_suffix">
<property name="editable">
<bool>true</bool>
</property>
<item>
<property name="text">
<string notr="true"/>
</property>
</item>
<item>
<property name="text">
<string notr="true">json</string>
</property>
</item>
</widget>
</item>
</layout>
</item> </item>
<item> <item>
<widget class="QTextEdit" name="config_simple"> <widget class="QPushButton" name="as_json">
<property name="minimumSize"> <property name="text">
<size> <string>Json Editor</string>
<width>0</width>
<height>300</height>
</size>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="generator"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="title"> <item>
<string>Generator</string> <widget class="QLabel" name="command_l">
</property> <property name="text">
<layout class="QVBoxLayout" name="verticalLayout"> <string>Command</string>
<property name="leftMargin"> </property>
<number>0</number> </widget>
</property> </item>
<property name="topMargin"> <item>
<number>0</number> <widget class="QLineEdit" name="command">
</property> <property name="placeholderText">
<property name="rightMargin"> <string notr="true">%config%</string>
<number>0</number> </property>
</property> </widget>
<property name="bottomMargin"> </item>
<number>0</number> <item>
</property> <widget class="QLabel" name="config_suffix_l">
<item> <property name="text">
<widget class="QWidget" name="fake" native="true"> <string>Config Suffix</string>
<property name="sizePolicy"> </property>
<sizepolicy hsizetype="Maximum" vsizetype="Maximum"> </widget>
<horstretch>0</horstretch> </item>
<verstretch>0</verstretch> <item>
</sizepolicy> <widget class="QComboBox" name="config_suffix">
<property name="editable">
<bool>true</bool>
</property>
<item>
<property name="text">
<string notr="true"/>
</property> </property>
</widget> </item>
</item> <item>
</layout> <property name="text">
<string notr="true">json</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">yml</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label">
<property name="toolTip">
<string>Random if it's empty or zero.</string>
</property>
<property name="text">
<string notr="true">Mapping Port</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="mapping_port"/>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="toolTip">
<string>Random if it's empty or zero.</string>
</property>
<property name="text">
<string notr="true">Socks Port</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="socks_port"/>
</item>
<item>
<widget class="QPushButton" name="preview">
<property name="text">
<string>Preview</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTextEdit" name="config_simple">
<property name="minimumSize">
<size>
<width>0</width>
<height>300</height>
</size>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>
@@ -138,6 +145,11 @@
<tabstop>core</tabstop> <tabstop>core</tabstop>
<tabstop>as_json</tabstop> <tabstop>as_json</tabstop>
<tabstop>command</tabstop> <tabstop>command</tabstop>
<tabstop>config_suffix</tabstop>
<tabstop>mapping_port</tabstop>
<tabstop>socks_port</tabstop>
<tabstop>preview</tabstop>
<tabstop>config_simple</tabstop>
</tabstops> </tabstops>
<resources/> <resources/>
<connections/> <connections/>

View File

@@ -12,6 +12,9 @@ public:
virtual bool onEnd() = 0; virtual bool onEnd() = 0;
std::function<QWidget *()> get_edit_dialog; std::function<QWidget *()> get_edit_dialog;
std::function<QString()> get_edit_text_name;
std::function<QString()> get_edit_text_serverAddress;
std::function<QString()> get_edit_text_serverPort;
// cached editor // cached editor

View File

@@ -100,15 +100,15 @@ void MainWindow::speedtest_current_group(int mode) {
req.set_url(NekoRay::dataStore->test_url.toStdString()); req.set_url(NekoRay::dataStore->test_url.toStdString());
// //
QList<NekoRay::sys::ExternalProcess *> ext; std::list<std::pair<NekoRay::fmt::ExternalBuildResult, QSharedPointer<NekoRay::sys::ExternalProcess>>> exts;
if (mode == libcore::TestMode::UrlTest || mode == libcore::FullTest) { if (mode == libcore::TestMode::UrlTest || mode == libcore::FullTest) {
auto c = NekoRay::BuildConfig(profile, true, false); auto c = NekoRay::BuildConfig(profile, true, false);
// external test ??? // TODO refactor external test
if (!c->ext.isEmpty()) { if (!c->exts.empty()) {
ext = c->ext; exts = c->exts;
for (auto extC: ext) { for (const auto &ext: exts) {
extC->Start(); ext.second->Start();
} }
QThread::msleep(500); QThread::msleep(500);
} }
@@ -128,9 +128,8 @@ void MainWindow::speedtest_current_group(int mode) {
bool rpcOK; bool rpcOK;
auto result = defaultClient->Test(&rpcOK, req); auto result = defaultClient->Test(&rpcOK, req);
for (auto extC: ext) { for (const auto &ext: exts) {
extC->Kill(); ext.second->Kill();
extC->deleteLater();
} }
if (!rpcOK) return; if (!rpcOK) return;
@@ -236,8 +235,9 @@ void MainWindow::neko_start(int _id) {
NekoRay::traffic::trafficLooper->loop_enabled = true; NekoRay::traffic::trafficLooper->loop_enabled = true;
#endif #endif
for (auto extC: result->ext) { for (const auto &ext: result->exts) {
extC->Start(); NekoRay::sys::running_ext.push_back(ext.second);
ext.second->Start();
} }
NekoRay::dataStore->UpdateStartedId(ent->id); NekoRay::dataStore->UpdateStartedId(ent->id);
@@ -254,7 +254,6 @@ void MainWindow::neko_stop(bool crash) {
while (!NekoRay::sys::running_ext.isEmpty()) { while (!NekoRay::sys::running_ext.isEmpty()) {
auto extC = NekoRay::sys::running_ext.takeFirst(); auto extC = NekoRay::sys::running_ext.takeFirst();
extC->Kill(); extC->Kill();
extC->deleteLater();
} }
#ifndef NKR_NO_GRPC #ifndef NKR_NO_GRPC