mirror of
https://github.com/MatsuriDayo/nekoray.git
synced 2025-12-17 12:34:37 +03:00
feat: preview edit custom
This commit is contained in:
@@ -449,8 +449,28 @@ namespace NekoRay {
|
||||
}
|
||||
|
||||
// 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);
|
||||
// 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 == 1) {
|
||||
// mapping
|
||||
@@ -459,7 +479,7 @@ namespace NekoRay {
|
||||
{"type", "direct"},
|
||||
{"tag", tagOut + "-mapping"},
|
||||
{"listen", "127.0.0.1"},
|
||||
{"listen_port", mapping_port},
|
||||
{"listen_port", ext_mapping_port},
|
||||
{"override_address", ent->bean->serverAddress},
|
||||
{"override_port", ent->bean->serverPort},
|
||||
};
|
||||
@@ -468,7 +488,7 @@ namespace NekoRay {
|
||||
{"protocol", "dokodemo-door"},
|
||||
{"tag", tagOut + "-mapping"},
|
||||
{"listen", "127.0.0.1"},
|
||||
{"port", mapping_port},
|
||||
{"port", ext_mapping_port},
|
||||
{"settings", QJsonObject{
|
||||
// to
|
||||
{"address", ent->bean->serverAddress},
|
||||
@@ -497,12 +517,9 @@ namespace NekoRay {
|
||||
// Outbound
|
||||
|
||||
QJsonObject outbound;
|
||||
fmt::CoreObjOutboundBuildResult coreR;
|
||||
fmt::ExternalBuildResult extR;
|
||||
|
||||
if (thisExternalStat > 0) {
|
||||
auto ext_socks_port = MkPort();
|
||||
extR = ent->bean->BuildExternal(mapping_port, ext_socks_port, thisExternalStat);
|
||||
const auto extR = ent->bean->BuildExternal(ext_mapping_port, ext_socks_port, thisExternalStat);
|
||||
if (extR.program.isEmpty()) {
|
||||
status->result->error = QObject::tr("Core not found: %1").arg(ent->bean->DisplayType());
|
||||
return {};
|
||||
@@ -530,14 +547,14 @@ namespace NekoRay {
|
||||
}
|
||||
|
||||
// EXTERNAL PROCESS
|
||||
auto extC = new sys::ExternalProcess();
|
||||
QSharedPointer<sys::ExternalProcess> extC(new sys::ExternalProcess());
|
||||
extC->tag = ent->bean->DisplayType();
|
||||
extC->program = extR.program;
|
||||
extC->arguments = extR.arguments;
|
||||
extC->env = extR.env;
|
||||
status->result->ext += extC;
|
||||
status->result->exts.emplace_back(extR, extC);
|
||||
} 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()) {
|
||||
status->result->error = "unsupported outbound";
|
||||
return {};
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace NekoRay {
|
||||
QSharedPointer<traffic::TrafficData> outboundStat; // main
|
||||
QStringList ignoreConnTag;
|
||||
|
||||
QList<sys::ExternalProcess *> ext;
|
||||
std::list<std::pair<fmt::ExternalBuildResult, QSharedPointer<sys::ExternalProcess>>> exts; // extR to extC
|
||||
};
|
||||
|
||||
class BuildConfigStatus {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
auto TempFile = QFileInfo(f).absoluteFilePath();
|
||||
|
||||
namespace NekoRay::fmt {
|
||||
// 0: no external
|
||||
// 0: Internal
|
||||
// 1: Mapping External
|
||||
// 2: Direct External
|
||||
|
||||
@@ -85,13 +85,10 @@ namespace NekoRay::fmt {
|
||||
|
||||
for (int i = 0; i < result.arguments.length(); i++) {
|
||||
auto arg = result.arguments[i];
|
||||
if (arg.contains("%mapping_port%")) {
|
||||
arg = arg.replace("%mapping_port%", Int2String(mapping_port));
|
||||
} else if (arg.contains("%socks_port%")) {
|
||||
arg = arg.replace("%socks_port%", Int2String(socks_port));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
arg = arg.replace("%server_addr%", serverAddress);
|
||||
arg = arg.replace("%server_port%", Int2String(serverPort));
|
||||
result.arguments[i] = arg;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,16 @@ namespace NekoRay::fmt {
|
||||
QList<QString> command;
|
||||
QString config_suffix;
|
||||
QString config_simple;
|
||||
int mapping_port = 0;
|
||||
int socks_port = 0;
|
||||
|
||||
CustomBean() : AbstractBean(0) {
|
||||
_add(new configItem("core", &core, itemType::string));
|
||||
_add(new configItem("cmd", &command, itemType::stringList));
|
||||
_add(new configItem("cs", &config_simple, 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 {
|
||||
|
||||
@@ -5,12 +5,17 @@
|
||||
#include <QApplication>
|
||||
|
||||
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() {
|
||||
if (started) return;
|
||||
started = true;
|
||||
if (managed) running_ext.push_back(this);
|
||||
|
||||
if (show_log) {
|
||||
connect(this, &QProcess::readyReadStandardOutput, this, [&]() {
|
||||
@@ -19,14 +24,11 @@ namespace NekoRay::sys {
|
||||
connect(this, &QProcess::readyReadStandardError, this, [&]() {
|
||||
MW_show_log_ext_vt100(readAllStandardError().trimmed());
|
||||
});
|
||||
}
|
||||
|
||||
if (managed) {
|
||||
connect(this, &QProcess::errorOccurred, this, [&](QProcess::ProcessError error) {
|
||||
if (!killed) {
|
||||
crashed = true;
|
||||
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) {
|
||||
@@ -37,7 +39,7 @@ namespace NekoRay::sys {
|
||||
crashed = true;
|
||||
MW_show_log_ext(tag, "[Error] Program exited accidentally: " + errorString());
|
||||
Kill();
|
||||
MW_dialog_message("ExternalProcess", "Crashed");
|
||||
if (managed) MW_dialog_message("ExternalProcess", "Crashed");
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -51,7 +53,6 @@ namespace NekoRay::sys {
|
||||
void ExternalProcess::Kill() {
|
||||
if (killed) return;
|
||||
killed = true;
|
||||
if (managed) running_ext.removeAll(this);
|
||||
|
||||
if (!crashed) {
|
||||
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::show_log = false;
|
||||
ExternalProcess::program = core_path;
|
||||
|
||||
@@ -12,10 +12,11 @@ namespace NekoRay::sys {
|
||||
QStringList arguments;
|
||||
QStringList env;
|
||||
|
||||
bool managed = true; // running_ext & stateChanged
|
||||
bool managed = true; // MW_dialog_message
|
||||
bool show_log = true;
|
||||
|
||||
ExternalProcess();
|
||||
~ExternalProcess();
|
||||
|
||||
// start & kill is one time
|
||||
|
||||
@@ -41,6 +42,6 @@ namespace NekoRay::sys {
|
||||
int restart_id = -1;
|
||||
};
|
||||
|
||||
// start & kill change this list
|
||||
inline QList<ExternalProcess *> running_ext;
|
||||
// 手动管理
|
||||
inline QList<QSharedPointer<ExternalProcess>> running_ext;
|
||||
} // namespace NekoRay::sys
|
||||
|
||||
@@ -601,10 +601,6 @@
|
||||
<source>Config Suffix</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Generator</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please read the documentation. If you don't understand, use a share link instead.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
@@ -617,6 +613,22 @@
|
||||
<source>Please pick a core.</source>
|
||||
<translation>لطفا یک هسته انتخاب کنید.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Random if it'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>
|
||||
<name>EditNaive</name>
|
||||
|
||||
@@ -591,10 +591,6 @@
|
||||
<source>Command</source>
|
||||
<translation>命令</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Generator</source>
|
||||
<translation>生成器</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Json Editor</source>
|
||||
<translation>JSON 编辑器</translation>
|
||||
@@ -615,6 +611,22 @@
|
||||
<source>Config Suffix</source>
|
||||
<translation>配置文件后缀</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Random if it'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>
|
||||
<name>EditNaive</name>
|
||||
|
||||
@@ -234,12 +234,11 @@ void DialogEditProfile::typeSelected(const QString &newType) {
|
||||
delete old;
|
||||
|
||||
// 左边 bean inner editor
|
||||
innerEditor->get_edit_dialog = [&]() {
|
||||
return (QWidget *) this;
|
||||
};
|
||||
innerEditor->editor_cache_updated = [=] {
|
||||
editor_cache_updated_impl();
|
||||
};
|
||||
innerEditor->get_edit_dialog = [&]() { return (QWidget *) this; };
|
||||
innerEditor->get_edit_text_name = [&]() { return ui->name->text(); };
|
||||
innerEditor->get_edit_text_serverAddress = [&]() { return ui->address->text(); };
|
||||
innerEditor->get_edit_text_serverPort = [&]() { return ui->port->text(); };
|
||||
innerEditor->editor_cache_updated = [=] { editor_cache_updated_impl(); };
|
||||
innerEditor->onStart(ent);
|
||||
|
||||
// 左边 common
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
#include "qv2ray/v2/ui/widgets/editors/w_JsonEditor.hpp"
|
||||
#include "fmt/CustomBean.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) {
|
||||
ui->setupUi(this);
|
||||
@@ -20,6 +25,14 @@ EditCustom::~EditCustom() {
|
||||
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) {
|
||||
this->ent = _ent;
|
||||
auto bean = this->ent->CustomBean();
|
||||
@@ -50,6 +63,8 @@ void EditCustom::onStart(QSharedPointer<NekoRay::ProxyEntity> _ent) {
|
||||
ui->command->setText(bean->command.join(" "));
|
||||
P_LOAD_STRING(config_simple)
|
||||
P_LOAD_COMBO(config_suffix)
|
||||
P_LOAD_INT(mapping_port)
|
||||
P_LOAD_INT(socks_port)
|
||||
|
||||
// custom external
|
||||
if (!bean->core.isEmpty()) {
|
||||
@@ -72,17 +87,46 @@ void EditCustom::onStart(QSharedPointer<NekoRay::ProxyEntity> _ent) {
|
||||
ui->config_suffix_l->hide();
|
||||
}
|
||||
|
||||
// Generators
|
||||
ui->generator->setVisible(false);
|
||||
// Preview
|
||||
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() {
|
||||
auto bean = this->ent->CustomBean();
|
||||
|
||||
P_SAVE_COMBO(core)
|
||||
bean->command = ui->command->text().split(" ");
|
||||
P_SAVE_STRING_QTEXTEDIT(config_simple)
|
||||
P_SAVE_COMBO(config_suffix)
|
||||
SAVE_CUSTOM_BEAN
|
||||
|
||||
if (bean->core.isEmpty()) {
|
||||
MessageBoxWarning(software_name, tr("Please pick a core."));
|
||||
|
||||
@@ -7,15 +7,13 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>400</height>
|
||||
<height>450</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">EditCustom</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="layout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
@@ -85,6 +83,48 @@
|
||||
<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>
|
||||
@@ -100,44 +140,16 @@
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="generator">
|
||||
<property name="title">
|
||||
<string>Generator</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="fake" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>core</tabstop>
|
||||
<tabstop>as_json</tabstop>
|
||||
<tabstop>command</tabstop>
|
||||
<tabstop>config_suffix</tabstop>
|
||||
<tabstop>mapping_port</tabstop>
|
||||
<tabstop>socks_port</tabstop>
|
||||
<tabstop>preview</tabstop>
|
||||
<tabstop>config_simple</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
||||
@@ -12,6 +12,9 @@ public:
|
||||
virtual bool onEnd() = 0;
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -100,15 +100,15 @@ void MainWindow::speedtest_current_group(int mode) {
|
||||
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) {
|
||||
auto c = NekoRay::BuildConfig(profile, true, false);
|
||||
// external test ???
|
||||
if (!c->ext.isEmpty()) {
|
||||
ext = c->ext;
|
||||
for (auto extC: ext) {
|
||||
extC->Start();
|
||||
// TODO refactor external test
|
||||
if (!c->exts.empty()) {
|
||||
exts = c->exts;
|
||||
for (const auto &ext: exts) {
|
||||
ext.second->Start();
|
||||
}
|
||||
QThread::msleep(500);
|
||||
}
|
||||
@@ -128,9 +128,8 @@ void MainWindow::speedtest_current_group(int mode) {
|
||||
|
||||
bool rpcOK;
|
||||
auto result = defaultClient->Test(&rpcOK, req);
|
||||
for (auto extC: ext) {
|
||||
extC->Kill();
|
||||
extC->deleteLater();
|
||||
for (const auto &ext: exts) {
|
||||
ext.second->Kill();
|
||||
}
|
||||
if (!rpcOK) return;
|
||||
|
||||
@@ -236,8 +235,9 @@ void MainWindow::neko_start(int _id) {
|
||||
NekoRay::traffic::trafficLooper->loop_enabled = true;
|
||||
#endif
|
||||
|
||||
for (auto extC: result->ext) {
|
||||
extC->Start();
|
||||
for (const auto &ext: result->exts) {
|
||||
NekoRay::sys::running_ext.push_back(ext.second);
|
||||
ext.second->Start();
|
||||
}
|
||||
|
||||
NekoRay::dataStore->UpdateStartedId(ent->id);
|
||||
@@ -254,7 +254,6 @@ void MainWindow::neko_stop(bool crash) {
|
||||
while (!NekoRay::sys::running_ext.isEmpty()) {
|
||||
auto extC = NekoRay::sys::running_ext.takeFirst();
|
||||
extC->Kill();
|
||||
extC->deleteLater();
|
||||
}
|
||||
|
||||
#ifndef NKR_NO_GRPC
|
||||
|
||||
Reference in New Issue
Block a user