[update] Several code refactoring and added qvAppLog

This commit is contained in:
Leroy.H.Y 2019-12-02 09:50:05 +08:00
parent d0e79f2819
commit 7ae62e96fc
No known key found for this signature in database
GPG Key ID: 6AC1673B587DC37D
22 changed files with 407 additions and 308 deletions

View File

@ -1 +1 @@
1090
1282

View File

@ -4,6 +4,7 @@
#include <QtGui>
#include <QMap>
#include <vector>
#include <algorithm>
#include "QvTinyLog.hpp"
#include "QvCoreConfigObjects.hpp"
#include "QObjectMessageProxy.hpp"
@ -73,6 +74,19 @@
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
/*
* Generic function to find if an element of any type exists in list
*/
template<typename T>
bool contains(std::list<T> &listOfElements, const T &element)
{
// Find the iterator if element in list
auto it = std::find(listOfElements.begin(), listOfElements.end(), element);
//return if iterator points to end or not. It points to end then it means element
// does not exists in list
return it != listOfElements.end();
}
namespace Qv2ray
{
//

View File

@ -10,7 +10,7 @@ namespace Qv2ray
auto conf = CONFIGROOT(JsonFromString(jsonString));
if (conf.count() == 0) {
LOG(MODULE_CONFIG, "WARN: Possible file corruption, failed to load file: " << connection.toStdString())
LOG(MODULE_CONFIG, "WARN: Possible file corruption, failed to load file: " + connection.toStdString())
}
return conf;
@ -43,7 +43,7 @@ namespace Qv2ray
confName.chop(sizeof(QV2RAY_CONFIG_FILE_EXTENSION) - 1);
_config[confName] = _ReadConnection(QV2RAY_SUBSCRIPTION_DIR + QSTRING(singleSub) + "/" + _file);
} else {
LOG(MODULE_SUBSCRIPTION, "Found a file in subscription folder but without proper suffix: " << _file.toStdString())
LOG(MODULE_SUBSCRIPTION, "Found a file in subscription folder but without proper suffix: " + _file.toStdString())
}
}
@ -63,13 +63,6 @@ namespace Qv2ray
bool cRules = cRule && root["routing"].toObject()["rules"].toArray().count() > 0;
return cRules;
}
int StartPreparation(CONFIGROOT fullConfig)
{
// Writes the final configuration to the disk.
QString json = JsonToString(fullConfig);
StringToFile(&json, new QFile(QV2RAY_GENERATED_FILE_PATH));
return 0;
}
int FindIndexByTag(INOUTLIST list, const QString &tag)
{

View File

@ -19,7 +19,6 @@ namespace Qv2ray
QMap<QString, CONFIGROOT> GetRegularConnections(list<string> connections);
QMap<QString, QMap<QString, CONFIGROOT>> GetSubscriptionConnections(list<string> subscriptions);
bool CheckIsComplexConfig(CONFIGROOT root);
int StartPreparation(CONFIGROOT fullConfig);
int FindIndexByTag(INOUTLIST list, const QString &tag);
//

View File

@ -150,7 +150,7 @@ namespace Qv2ray
#undef C
//return flag ? 0 : 1;
} catch (exception *e) {
LOG(MODULE_CONNECTION_VMESS, "Failed to decode vmess string: " << e->what())
LOG(MODULE_CONNECTION_VMESS, "Failed to decode vmess string: " + string(e->what()))
*errMessage = QSTRING(e->what());
return CONFIGROOT();
}

View File

@ -1,5 +1,25 @@
#include "QvUtils.hpp"
#include <QTextStream>
#include <QQueue>
// Forwarded from QvTinyLog
static QQueue<QString> __loggerBuffer;
void _LOG(const std::string &module, const std::string &log)
{
string logString = "[" + module + "]: " + log + NEWLINE;
cout << logString;
__loggerBuffer.enqueue(logString.c_str());
}
const QString readLastLog()
{
QString result;
while (!__loggerBuffer.isEmpty()) {
result += __loggerBuffer.dequeue();
}
return result;
}
namespace Qv2ray
{
@ -241,5 +261,14 @@ namespace Qv2ray
}
}
void QFastAppendTextDocument(const QString &message, QTextDocument *doc)
{
QTextCursor cursor(doc);
cursor.movePosition(QTextCursor::End);
cursor.beginEditBlock();
cursor.insertBlock();
cursor.insertHtml(message);
cursor.endEditBlock();
}
}
}

View File

@ -87,6 +87,7 @@ namespace Qv2ray
//
//
QString ConvertGFWToPAC(const QString &rawContent, const QString &customProxyString);
void QFastAppendTextDocument(const QString &message, QTextDocument *doc);
}
}

View File

@ -5,14 +5,13 @@
#include "QvCoreConfigOperations.hpp"
#include "QvTinyLog.hpp"
#include "w_MainWindow.hpp"
using namespace v2ray::core::app::stats::command;
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
// Check 20 times before telling user that API has failed.
// Check 10 times before telling user that API has failed.
#define QV2RAY_API_CALL_FAILEDCHECK_THRESHOLD 10
namespace Qv2ray
@ -21,107 +20,135 @@ namespace Qv2ray
{
bool ConnectionInstance::ValidateConfig(const QString &path)
{
if (ValidateKernal()) {
auto conf = GetGlobalConfig();
if (QFile::exists(QSTRING(conf.v2CorePath))) {
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("V2RAY_LOCATION_ASSET", QString::fromStdString(GetGlobalConfig().v2AssetsPath));
env.insert("V2RAY_LOCATION_ASSET", QSTRING(conf.v2AssetsPath));
QProcess process;
process.setProcessEnvironment(env);
process.start(QSTRING(GetGlobalConfig().v2CorePath), QStringList() << "-test" << "-config" << path, QIODevice::ReadWrite | QIODevice::Text);
process.start(QSTRING(conf.v2CorePath), QStringList() << "-test" << "-config" << path, QIODevice::ReadWrite | QIODevice::Text);
if (!process.waitForFinished()) {
LOG(MODULE_VCORE, "v2ray core failed with exitcode: " << process.exitCode())
if (!process.waitForFinished(1000)) {
LOG(MODULE_VCORE, "v2ray core failed with exitcode: " + process.exitCode())
QvMessageBox(nullptr, tr("Cannot start v2ray"), tr("v2ray core failed with errcode:") + QString::number(process.exitCode()));
return false;
}
QString output = QString(process.readAllStandardOutput());
if (process.exitCode() != 0) {
Utils::QvMessageBox(nullptr, tr("Configuration Error"), output.mid(output.indexOf("anti-censorship.") + 17));
QvMessageBox(nullptr, tr("Configuration Error"), output.mid(output.indexOf("anti-censorship.") + 17));
return false;
}
return true;
} else {
QvMessageBox(nullptr, tr("Cannot start v2ray"),
tr("v2ray core file cannot be found at:") + NEWLINE +
QSTRING(conf.v2CorePath) + NEWLINE + NEWLINE +
tr("Please go to Prefrence Window to change the location.") + NEWLINE +
tr("Or place your v2ray core file in the location above."));
return false;
}
return false;
}
ConnectionInstance::ConnectionInstance(QWidget *parent) : apiFailedCounter(0), port(0)
ConnectionInstance::ConnectionInstance()
{
auto proc = new QProcess();
vProcess = proc;
connect(vProcess, &QProcess::readyReadStandardOutput, static_cast<MainWindow *>(parent), &MainWindow::UpdateLog);
connect(vProcess, &QProcess::readyReadStandardOutput, this, [this]() {
emit onProcessOutputReadyRead(vProcess->readAllStandardOutput().trimmed());
});
ConnectionStatus = STOPPED;
}
void ConnectionInstance::SetAPIPort(int port)
bool ConnectionInstance::StartConnection(CONFIGROOT root, bool useAPI, int apiPort)
{
// Config API
this->port = port;
Channel = grpc::CreateChannel("127.0.0.1:" + to_string(port), grpc::InsecureChannelCredentials());
StatsService service;
Stub = service.NewStub(Channel);
}
inboundTags.clear();
QString ConnectionInstance::ReadProcessOutput()
{
return vProcess->readAllStandardOutput();
}
for (auto item : root["inbounds"].toArray()) {
auto tag = item.toObject()["tag"].toString("");
bool ConnectionInstance::ValidateKernal()
{
if (!QFile::exists(QSTRING(GetGlobalConfig().v2CorePath))) {
Utils::QvMessageBox(nullptr, tr("Cannot start v2ray"),
tr("v2ray core file cannot be found at:") + NEWLINE +
QSTRING(GetGlobalConfig().v2CorePath) + NEWLINE + NEWLINE +
tr("Please go to prefrence window to change the location.") + NEWLINE +
tr("Or put v2ray core file in the location above."));
return false;
} else return true;
}
if (tag.isEmpty() || tag == QV2RAY_API_TAG_INBOUND)
continue;
inboundTags.append(tag);
}
LOG(MODULE_VCORE, "Found Inbound Tags: " + Stringify(inboundTags).toStdString())
QString json = JsonToString(root);
// Write the final configuration to the disk.
StringToFile(&json, new QFile(QV2RAY_GENERATED_FILE_PATH));
//
enableAPI = useAPI;
bool ConnectionInstance::StartV2rayCore()
{
if (ConnectionStatus != STOPPED) {
LOG(MODULE_VCORE, "Status is invalid, expect STOPPED when calling StartV2rayCore")
return false;
}
ConnectionStatus = STARTING;
auto filePath = QV2RAY_GENERATED_FILE_PATH;
if (ValidateKernal()) {
auto filePath = QV2RAY_GENERATED_FILE_PATH;
if (ValidateConfig(filePath)) {
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("V2RAY_LOCATION_ASSET", QSTRING(GetGlobalConfig().v2AssetsPath));
vProcess->setProcessEnvironment(env);
vProcess->start(QSTRING(GetGlobalConfig().v2CorePath), QStringList() << "-config" << filePath, QIODevice::ReadWrite | QIODevice::Text);
vProcess->waitForStarted();
ConnectionStatus = STARTED;
if (ValidateConfig(filePath)) {
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("V2RAY_LOCATION_ASSET", QSTRING(GetGlobalConfig().v2AssetsPath));
vProcess->setProcessEnvironment(env);
vProcess->start(QSTRING(GetGlobalConfig().v2CorePath), QStringList() << "-config" << filePath, QIODevice::ReadWrite | QIODevice::Text);
vProcess->waitForStarted();
ConnectionStatus = STARTED;
return true;
} else {
ConnectionStatus = STOPPED;
return false;
if (enableAPI) {
// Config API
this->apiPort = apiPort;
Channel = grpc::CreateChannel("127.0.0.1:" + to_string(apiPort), grpc::InsecureChannelCredentials());
StatsService service;
Stub = service.NewStub(Channel);
apiTimerId = startTimer(1000);
}
return true;
} else {
ConnectionStatus = STOPPED;
return false;
}
}
void ConnectionInstance::StopV2rayCore()
void ConnectionInstance::timerEvent(QTimerEvent *event)
{
QObject::timerEvent(event);
if (event->timerId() == apiTimerId) {
// Call API
for (auto tag : inboundTags) {
// Upload
auto valup = CallStatsAPIByName("inbound>>>" + tag + ">>>traffic>>>uplink");
auto dataup = valup - transferData[tag + "_up"];
transferData[tag + "_up"] = valup;
transferSpeed[tag + "_up"] = dataup;
// Download
auto valdown = CallStatsAPIByName("inbound>>>" + tag + ">>>traffic>>>downlink");
auto datadown = valdown - transferData[tag + "_down"];
transferData[tag + "_down"] = valdown;
transferSpeed[tag + "_down"] = datadown;
}
}
}
void ConnectionInstance::StopConnection()
{
vProcess->close();
killTimer(apiTimerId);
apiFailedCounter = 0;
totalDataTransfered.clear();
dataTransferSpeed.clear();
transferData.clear();
transferSpeed.clear();
ConnectionStatus = STOPPED;
}
ConnectionInstance::~ConnectionInstance()
{
StopV2rayCore();
StopConnection();
delete vProcess;
}
@ -135,8 +162,8 @@ namespace Qv2ray
if (apiFailedCounter == QV2RAY_API_CALL_FAILEDCHECK_THRESHOLD) {
LOG(MODULE_VCORE, "API call failure threshold reached, cancelling further API aclls.")
QvMessageBox(nullptr, tr("API Call Failed"), tr("Failed to get statistics data, please check if v2ray is running properly"));
totalDataTransfered.clear();
dataTransferSpeed.clear();
transferData.clear();
transferSpeed.clear();
apiFailedCounter++;
return 0;
} else if (apiFailedCounter > QV2RAY_API_CALL_FAILEDCHECK_THRESHOLD) {
@ -151,39 +178,68 @@ namespace Qv2ray
Status status = Stub->GetStats(&context, request, &response);
if (!status.ok()) {
LOG(MODULE_VCORE, "API call returns: " << status.error_code() << " (" << status.error_message() << ")")
LOG(MODULE_VCORE, "API call returns: " + to_string(status.error_code()) + " (" + status.error_message() + ")")
apiFailedCounter++;
}
return response.stat().value();
}
long ConnectionInstance::getTagLastUplink(const QString &tag)
// ------------------------------------------------------------- API FUNCTIONS --------------------------
long ConnectionInstance::getTagSpeedUp(const QString &tag)
{
auto val = CallStatsAPIByName("inbound>>>" + tag + ">>>traffic>>>uplink");
auto data = val - totalDataTransfered[tag + "_up"];
totalDataTransfered[tag + "_up"] = val;
dataTransferSpeed[tag + "_up"] = data;
return data;
return transferSpeed[tag + "_up"];
}
long ConnectionInstance::getTagLastDownlink(const QString &tag)
long ConnectionInstance::getTagSpeedDown(const QString &tag)
{
auto val = CallStatsAPIByName("inbound>>>" + tag + ">>>traffic>>>downlink");
auto data = val - totalDataTransfered[tag + "_down"];
totalDataTransfered[tag + "_down"] = val;
dataTransferSpeed[tag + "_down"] = data;
return data;
return transferSpeed[tag + "_down"];
}
long ConnectionInstance::getTagTotalUplink(const QString &tag)
long ConnectionInstance::getTagDataUp(const QString &tag)
{
return totalDataTransfered[tag + "_up"];
return transferData[tag + "_up"];
}
long ConnectionInstance::getTagTotalDownlink(const QString &tag)
long ConnectionInstance::getTagDataDown(const QString &tag)
{
return totalDataTransfered[tag + "_down"];
return transferData[tag + "_down"];
}
long ConnectionInstance::getAllDataUp()
{
long val = 0;
for (auto tag : inboundTags) {
val += transferData[tag + "_up"];
}
return val;
}
long ConnectionInstance::getAllDataDown()
{
long val = 0;
for (auto tag : inboundTags) {
val += transferData[tag + "_down"];
}
return val;
}
long ConnectionInstance::getAllSpeedUp()
{
long val = 0;
for (auto tag : inboundTags) {
val += transferSpeed[tag + "_up"];
}
return val;
}
long ConnectionInstance::getAllSpeedDown()
{
long val = 0;
for (auto tag : inboundTags) {
val += transferSpeed[tag + "_down"];
}
return val;
}
}
}

View File

@ -22,32 +22,44 @@ namespace Qv2ray
{
Q_OBJECT
public:
explicit ConnectionInstance(QWidget *parent = nullptr);
void SetAPIPort(int port);
explicit ConnectionInstance();
~ConnectionInstance() override;
//
long getTagTotalDownlink(const QString &tag);
long getTagTotalUplink(const QString &tag);
long getTagLastDownlink(const QString &tag);
long getTagLastUplink(const QString &tag);
// Speed
long getTagSpeedUp(const QString &tag);
long getTagSpeedDown(const QString &tag);
long getTagDataUp(const QString &tag);
long getTagDataDown(const QString &tag);
long getAllDataUp();
long getAllDataDown();
long getAllSpeedUp();
long getAllSpeedDown();
//
bool StartV2rayCore();
void StopV2rayCore();
bool StartConnection(CONFIGROOT root, bool useAPI, int apiPort);
void StopConnection();
QvInstanceStatus ConnectionStatus;
QString ReadProcessOutput();
//
static bool ValidateConfig(const QString &path);
static bool ValidateKernal();
~ConnectionInstance();
QMap<QString, long> totalDataTransfered;
QMap<QString, long> dataTransferSpeed;
signals:
void onProcessOutputReadyRead(QString);
private:
void timerEvent(QTimerEvent *event) override;
QStringList inboundTags;
bool enableAPI;
int apiTimerId;
int apiPort;
//
int apiFailedCounter;
long CallStatsAPIByName(QString name);
QProcess *vProcess;
//
QMap<QString, long> transferData;
QMap<QString, long> transferSpeed;
//
std::shared_ptr<::grpc::Channel> Channel;
std::unique_ptr<::v2ray::core::app::stats::command::StatsService::Stub> Stub;
int port;
};
}
}

View File

@ -106,6 +106,17 @@ namespace Qv2ray
rule.format = failedFormat;
highlightingRules.append(rule);
//
qvAppLogFormat.setFontWeight(QFont::Bold);
qvAppLogFormat.setForeground(darkMode ? Qt::cyan : Qt::darkCyan);
rule.pattern = QRegularExpression("\\[[A-Z]*\\]:");
rule.format = qvAppLogFormat;
highlightingRules.append(rule);
//
qvAppDebugLogFormat.setFontWeight(QFont::Bold);
qvAppDebugLogFormat.setForeground(darkMode ? Qt::yellow : Qt::darkYellow);
rule.pattern = QRegularExpression("\\[\\[DEBUG\\] - [A-Z]*\\]:");
rule.format = qvAppDebugLogFormat;
highlightingRules.append(rule);
}
void Highlighter::highlightBlock(const QString &text)

View File

@ -89,6 +89,9 @@ namespace Qv2ray
QTextCharFormat timeFormat;
QTextCharFormat ipHostFormat;
QTextCharFormat x;
//
QTextCharFormat qvAppLogFormat;
QTextCharFormat qvAppDebugLogFormat;
};
}
}

View File

@ -37,7 +37,7 @@ namespace Qv2ray
{ 303, QObject::tr("Uploaded Data for Specific Tag") },
{ 304, QObject::tr("Downloaded Data for Specific Tag") }
};
void StartProcessingPlugins(QWidget *mainWindow);
void StartProcessingPlugins();
void StopProcessingPlugins();
#ifdef Q_OS_WIN
namespace _win

View File

@ -74,11 +74,11 @@ bool initialiseQv2ray()
bool avail = verifyConfigAvaliability(path, true);
if (avail) {
DEBUG(MODULE_INIT, "Path: " << path.toStdString() << " is valid.")
DEBUG(MODULE_INIT, "Path: " + path.toStdString() + " is valid.")
configPath = path;
hasExistingConfig = true;
} else {
DEBUG(MODULE_INIT, "Path: " << path.toStdString() << " does not contain a valid config file.")
DEBUG(MODULE_INIT, "Path: " + path.toStdString() + " does not contain a valid config file.")
}
}
@ -304,7 +304,7 @@ int main(int argc, char *argv[])
if (themes.contains(QSTRING(confObject.uiConfig.theme))) {
_qApp.setStyle(QSTRING(confObject.uiConfig.theme));
LOG(MODULE_INIT " " MODULE_UI, "Setting Qv2ray UI themes.")
LOG(MODULE_INIT " " MODULE_UI, "Setting Qv2ray UI themes: " + confObject.uiConfig.theme)
}
#endif
@ -312,7 +312,9 @@ int main(int argc, char *argv[])
try {
// Show MainWindow
MainWindow w;
return _qApp.exec();
auto rcode = _qApp.exec();
LOG(MODULE_INIT, "Quitting normally")
return rcode;
} catch (...) {
QvMessageBox(nullptr, "ERROR", "There's something wrong happened and Qv2ray will quit now.");
LOG(MODULE_INIT, "EXCEPTION THROWN: " __FILE__)

View File

@ -9,7 +9,6 @@ namespace Qv2ray
{
namespace NetSpeedPlugin
{
static MainWindow *mainWindow;
static Qv2rayConfig config;
void StopProcessingPlugins()
{
@ -23,9 +22,8 @@ namespace Qv2ray
/// Public Function - CALL ONLY ONCE -
/// To start processing plugins' command.
void StartProcessingPlugins(QWidget *_mainWindow)
void StartProcessingPlugins()
{
mainWindow = static_cast<MainWindow *>(_mainWindow);
config = GetGlobalConfig();
#ifdef Q_OS_LINUX
_linux::StartMessageQThread();
@ -36,16 +34,18 @@ namespace Qv2ray
}
QString GetAnswerToRequest(const QString &pchRequest)
{
auto vinstance = mwInstance->vinstance;
//
auto req = pchRequest.trimmed();
config = GetGlobalConfig();
QString reply = "{}";
if (req == "START") {
emit mainWindow->Connect();
emit mwInstance->Connect();
} else if (req == "STOP") {
emit mainWindow->DisConnect();
emit mwInstance->DisConnect();
} else if (req == "RESTART") {
emit mainWindow->ReConnect();
emit mwInstance->ReConnect();
}
auto BarConfig = config.toolBarConfig;
@ -82,13 +82,13 @@ namespace Qv2ray
case 104: {
// Current Connection Name
CL.Message = mainWindow->CurrentConnectionName.toStdString();
CL.Message = mwInstance->CurrentConnectionName.toStdString();
break;
}
case 105: {
// Current Connection Status
switch (mainWindow->vinstance->ConnectionStatus) {
switch (mwInstance->vinstance->ConnectionStatus) {
case STARTED: {
CL.Message = QObject::tr("Connected").toStdString();
break;
@ -111,60 +111,56 @@ namespace Qv2ray
case 201: {
// Total upload speed;
STATS_ENABLE_CHECK
CL.Message = (mainWindow->totalSpeedUp + "/s").toStdString();
CL.Message = FormatBytes(vinstance->getAllSpeedUp()).toStdString() + "/s";
break;
}
case 202: {
// Total download speed;
STATS_ENABLE_CHECK
CL.Message = (mainWindow->totalSpeedDown + "/s").toStdString();
CL.Message = (FormatBytes(vinstance->getAllSpeedDown()) + "/s").toStdString();
break;
}
case 203: {
// Upload speed for tag
STATS_ENABLE_CHECK
auto data = mainWindow->vinstance->dataTransferSpeed[QSTRING(CL.Message) + "_up"];
CL.Message = FormatBytes(data).toStdString() + "/s";
CL.Message = FormatBytes(vinstance->getTagSpeedUp(QSTRING(CL.Message))).toStdString() + "/s";
break;
}
case 204: {
STATS_ENABLE_CHECK
// Download speed for tag
auto data = mainWindow->vinstance->dataTransferSpeed[QSTRING(CL.Message) + "_down"];
CL.Message = FormatBytes(data).toStdString() + "/s";
CL.Message = FormatBytes(vinstance->getTagSpeedDown(QSTRING(CL.Message))).toStdString() + "/s";
break;
}
case 301: {
// Total Upload
STATS_ENABLE_CHECK
CL.Message = (mainWindow->totalDataUp).toStdString();
CL.Message = FormatBytes(vinstance->getAllDataUp()).toStdString();
break;
}
case 302: {
// Total download
STATS_ENABLE_CHECK
CL.Message = (mainWindow->totalDataDown).toStdString();
CL.Message = FormatBytes(vinstance->getAllDataDown()).toStdString();
break;
}
case 303: {
// Upload for tag
STATS_ENABLE_CHECK
auto data = mainWindow->vinstance->totalDataTransfered[QSTRING(CL.Message) + "_up"];
CL.Message = FormatBytes(data).toStdString();
CL.Message = FormatBytes(vinstance->getTagDataUp(QSTRING(CL.Message))).toStdString();
break;
}
case 304: {
// Download for tag
STATS_ENABLE_CHECK
auto data = mainWindow->vinstance->totalDataTransfered[QSTRING(CL.Message) + "_down"];
CL.Message = FormatBytes(data).toStdString();
CL.Message = FormatBytes(vinstance->getTagDataDown(QSTRING(CL.Message))).toStdString();
break;
}

View File

@ -61,8 +61,8 @@ namespace Qv2ray
while (!isExiting) {
bool result = server->waitForNewConnection(200, &timeOut);
LOG(MODULE_PLUGIN, "Plugin thread listening failed: " << server->errorString().toStdString())
LOG(MODULE_PLUGIN, "waitForNewConnection: " << (result ? "true" : "false") << ", " << (timeOut ? "true" : "false"))
LOG(MODULE_PLUGIN, "Plugin thread listening failed: " + server->errorString().toStdString())
LOG(MODULE_PLUGIN, "waitForNewConnection: " + string(result ? "true" : "false") + ", " + string(timeOut ? "true" : "false"))
}
server->close();

View File

@ -29,7 +29,7 @@ namespace Qv2ray
auto hThread = CreateThread(nullptr, 0, NamedPipeMasterThread, nullptr, 0, nullptr);
if (hThread == nullptr) {
LOG(MODULE_PLUGIN, "CreateThread failed, GLE=" << GetLastError())
LOG(MODULE_PLUGIN, "CreateThread failed, GLE=" + to_string(GetLastError()))
return;
} else CloseHandle(hThread);
}
@ -47,7 +47,7 @@ namespace Qv2ray
hPipe = CreateNamedPipe(lpszPipename.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BUFSIZE, BUFSIZE, 0, nullptr);
if (hPipe == INVALID_HANDLE_VALUE) {
LOG(MODULE_PLUGIN, "CreateNamedPipe failed, GLE=" << GetLastError())
LOG(MODULE_PLUGIN, "CreateNamedPipe failed, GLE=" + to_string(GetLastError()))
return static_cast<DWORD>(-1);
}
@ -58,7 +58,7 @@ namespace Qv2ray
ThreadHandle = CreateThread(nullptr, 0, InstanceThread, hPipe, 0, &dwThreadId);
if (ThreadHandle == nullptr) {
LOG(MODULE_PLUGIN, "CreateThread failed, GLE=%d.\n" << GetLastError())
LOG(MODULE_PLUGIN, "CreateThread failed, GLE=" + to_string(GetLastError()))
return static_cast<DWORD>(-1);
} else CloseHandle(ThreadHandle);
} else CloseHandle(hPipe);
@ -79,7 +79,7 @@ namespace Qv2ray
if (!fSuccess || cbBytesRead == 0) {
if (GetLastError() == ERROR_BROKEN_PIPE) {
LOG(MODULE_PLUGIN, "InstanceThread: client disconnected.\n" + to_string(GetLastError()))
LOG(MODULE_PLUGIN, "InstanceThread: client disconnected, GLE=" + to_string(GetLastError()))
} else {
LOG(MODULE_PLUGIN, "InstanceThread ReadFile failed, GLE=" + to_string(GetLastError()))
}

View File

@ -27,6 +27,9 @@
#include "QvSystemProxyConfigurator.hpp"
#define TRAY_TOOLTIP_PREFIX "Qv2ray " QV2RAY_VERSION_STRING
#define vCoreLogBrowser this->logTextBrowsers[0]
#define qvAppLogBrowser this->logTextBrowsers[1]
#define currentLogBrowser this->logTextBrowsers[currentLogBrowserId]
#define SUBSCRIPTION_CONFIG_MODIFY_ASK(varName) \
if (!connections[varName].isRegularConnection) { \
if (QvMessageBoxAsk(this, tr("Editing a subscription config"), tr("You are trying to edit a config loaded from subscription.") + \
@ -36,27 +39,36 @@
} \
} \
MainWindow::MainWindow(QWidget *parent)
:
QMainWindow(parent),
vinstance(),
uploadList(),
downloadList(),
HTTPRequestHelper(),
hTray(new QSystemTrayIcon(this)),
highlighter()
MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent), vinstance(), uploadList(), downloadList(), HTTPRequestHelper(),
hTray(new QSystemTrayIcon(this)), vCoreLogHighlighter(), qvAppLogHighlighter()
{
mwInstance = this;
auto conf = GetGlobalConfig();
vinstance = new ConnectionInstance(this);
vinstance = new ConnectionInstance();
connect(vinstance, &ConnectionInstance::onProcessOutputReadyRead, this, &MainWindow::UpdateVCoreLog);
setupUi(this);
//
highlighter = new Highlighter(conf.uiConfig.useDarkTheme, vcoreLog.document());
logText->setDocument(vcoreLog.document());
logText->setFontPointSize(8);
vcoreLog.setFontPointSize(8);
qvAppLog.setFontPointSize(8);
// Two browsers
logTextBrowsers.append(new QTextBrowser());
logTextBrowsers.append(new QTextBrowser());
vCoreLogBrowser->setFontPointSize(8);
vCoreLogBrowser->setReadOnly(true);
vCoreLogBrowser->setLineWrapMode(QTextBrowser::LineWrapMode::NoWrap);
qvAppLogBrowser->setFontPointSize(8);
qvAppLogBrowser->setReadOnly(true);
qvAppLogBrowser->setLineWrapMode(QTextBrowser::LineWrapMode::NoWrap);
//
vCoreLogHighlighter = new Highlighter(conf.uiConfig.useDarkTheme, vCoreLogBrowser->document());
qvAppLogHighlighter = new Highlighter(conf.uiConfig.useDarkTheme, qvAppLogBrowser->document());
pacServer = new PACHandler();
currentLogBrowserId = 0;
masterLogBrowser->setDocument(currentLogBrowser->document());
masterLogBrowser->document()->setDocumentMargin(0);
masterLogBrowser->document()->adjustSize();
masterLogBrowser->setLineWrapMode(QTextBrowser::LineWrapMode::NoWrap);
//
logTimerId = startTimer(500);
//
this->setWindowIcon(QIcon(":/icons/qv2ray.png"));
hTray->setIcon(QIcon(conf.uiConfig.useDarkTrayIcon ? ":/icons/ui_dark/tray.png" : ":/icons/ui_light/tray.png"));
@ -103,7 +115,6 @@ MainWindow::MainWindow(QWidget *parent)
connect(action_Tray_Reconnect, &QAction::triggered, this, &MainWindow::on_reconnectButton_clicked);
connect(action_Tray_Quit, &QAction::triggered, this, &MainWindow::quit);
connect(hTray, &QSystemTrayIcon::activated, this, &MainWindow::on_activatedTray);
connect(logText, &QTextBrowser::textChanged, this, &MainWindow::QTextScrollToBottom);
connect(action_RCM_RenameConnection, &QAction::triggered, this, &MainWindow::on_action_RenameConnection_triggered);
connect(action_RCM_StartThis, &QAction::triggered, this, &MainWindow::on_action_StartThis_triggered);
connect(action_RCM_EditJson, &QAction::triggered, this, &MainWindow::on_action_RCM_EditJson_triggered);
@ -162,32 +173,25 @@ MainWindow::MainWindow(QWidget *parent)
auto layout = new QHBoxLayout(speedChart);
layout->addWidget(speedChartView);
speedChart->setLayout(layout);
//
bool hasAutoStart = vinstance->ValidateKernal();
if (hasAutoStart) {
// At least kernal is ready.
if (!conf.autoStartConfig.empty() && QList<string>::fromStdList(conf.configs).contains(conf.autoStartConfig)) {
// Has auto start.
CurrentConnectionName = QSTRING(conf.autoStartConfig);
auto item = connectionListWidget->findItems(QSTRING(conf.autoStartConfig), Qt::MatchExactly).front();
item->setSelected(true);
connectionListWidget->setCurrentItem(item);
on_connectionListWidget_itemClicked(item);
trayMenu->actions()[0]->setText(tr("Show"));
this->hide();
on_startButton_clicked();
} else if (connectionListWidget->count() != 0) {
// The first one is default.
connectionListWidget->setCurrentRow(0);
ShowAndSetConnection(connectionListWidget->item(0)->text(), true, false);
this->show();
}
} else {
if (!conf.autoStartConfig.empty() && contains(conf.configs, conf.autoStartConfig)) {
// Has auto start.
CurrentConnectionName = QSTRING(conf.autoStartConfig);
auto item = connectionListWidget->findItems(QSTRING(conf.autoStartConfig), Qt::MatchExactly).front();
item->setSelected(true);
connectionListWidget->setCurrentItem(item);
on_connectionListWidget_itemClicked(item);
trayMenu->actions()[0]->setText(tr("Show"));
this->hide();
on_startButton_clicked();
} else if (connectionListWidget->count() != 0) {
// The first one is default.
connectionListWidget->setCurrentRow(0);
ShowAndSetConnection(connectionListWidget->item(0)->text(), true, false);
this->show();
}
StartProcessingPlugins(this);
StartProcessingPlugins();
}
void MainWindow::mouseReleaseEvent(QMouseEvent *e)
@ -195,7 +199,14 @@ void MainWindow::mouseReleaseEvent(QMouseEvent *e)
Q_UNUSED(e)
if (logLabel->underMouse()) {
logText->setDocument(logSourceId++ % 2 == 0 ? vcoreLog.document() : qvAppLog.document());
//auto layout = masterLogBrowser->document()->setDocumentLayout()
currentLogBrowserId = (currentLogBrowserId + 1) % logTextBrowsers.count();
masterLogBrowser->setDocument(currentLogBrowser->document());
masterLogBrowser->document()->setDocumentMargin(4);
masterLogBrowser->document()->adjustSize();
masterLogBrowser->setLineWrapMode(QTextBrowser::LineWrapMode::NoWrap);
auto bar = masterLogBrowser->verticalScrollBar();
bar->setValue(bar->maximum());
}
}
@ -250,7 +261,6 @@ void MainWindow::VersionUpdate(QByteArray &data)
tr("Download Link: ") + link, QMessageBox::Ignore);
if (result == QMessageBox::Yes) {
CLOG(result)
QDesktopServices::openUrl(QUrl::fromUserInput(link));
} else if (result == QMessageBox::Ignore) {
conf.ignoredVersion = newversion.toString().toStdString();
@ -330,9 +340,20 @@ MainWindow::~MainWindow()
delete this->hTray;
delete this->vinstance;
}
void MainWindow::UpdateLog()
void MainWindow::UpdateVCoreLog(const QString &log)
{
vcoreLog.append(vinstance->ReadProcessOutput().trimmed());
vCoreLogBrowser->append(log);
setMasterLogHBar();
}
void MainWindow::setMasterLogHBar()
{
auto bar = masterLogBrowser->verticalScrollBar();
//LOG(bar->maximum(), bar->value())
auto max = bar->maximum();
auto val = bar->value();
if (val >= max * 0.8 || val >= max - 20)
bar->setValue(max);
}
void MainWindow::on_startButton_clicked()
{
@ -352,26 +373,23 @@ void MainWindow::on_startButton_clicked()
}
LOG(MODULE_VCORE, ("Connecting to: " + CurrentConnectionName).toStdString())
logText->clear();
vCoreLogBrowser->clear();
//
auto connectionRoot = connections[CurrentConnectionName].config;
//
auto conf = GetGlobalConfig();
CurrentFullConfig = GenerateRuntimeConfig(connectionRoot);
StartPreparation(CurrentFullConfig);
bool startFlag = this->vinstance->StartV2rayCore();
bool startFlag = this->vinstance->StartConnection(CurrentFullConfig, conf.connectionConfig.enableStats, conf.connectionConfig.statsPort);
if (startFlag) {
if (conf.connectionConfig.enableStats) {
speedTimerId = startTimer(1000);
}
this->hTray->showMessage("Qv2ray", tr("Connected To Server: ") + CurrentConnectionName);
hTray->setToolTip(TRAY_TOOLTIP_PREFIX "\r\n" + tr("Connected To Server: ") + CurrentConnectionName);
statusLabel->setText(tr("Connected") + ": " + CurrentConnectionName);
//
auto conf = GetGlobalConfig();
if (conf.connectionConfig.enableStats) {
vinstance->SetAPIPort(conf.connectionConfig.statsPort);
speedTimerId = startTimer(1000);
}
bool usePAC = conf.inboundConfig.pacConfig.enablePAC;
bool pacUseSocks = conf.inboundConfig.pacConfig.useSocksProxy;
bool httpEnabled = conf.inboundConfig.useHTTP;
@ -469,12 +487,12 @@ void MainWindow::on_stopButton_clicked()
{
if (vinstance->ConnectionStatus != STOPPED) {
// Is running or starting
this->vinstance->StopV2rayCore();
this->vinstance->StopConnection();
killTimer(speedTimerId);
hTray->setToolTip(TRAY_TOOLTIP_PREFIX);
QFile(QV2RAY_GENERATED_FILE_PATH).remove();
statusLabel->setText(tr("Disconnected"));
logText->setPlainText("");
vCoreLogBrowser->clear();
trayMenu->actions()[2]->setEnabled(true);
trayMenu->actions()[3]->setEnabled(false);
trayMenu->actions()[4]->setEnabled(false);
@ -554,12 +572,6 @@ void MainWindow::on_actionExit_triggered()
{
quit();
}
void MainWindow::QTextScrollToBottom()
{
auto bar = logText->verticalScrollBar();
if (bar->value() >= bar->maximum() - 10) bar->setValue(bar->maximum());
}
void MainWindow::ShowAndSetConnection(QString guiConnectionName, bool SetConnection, bool ApplyConnection)
{
// Check empty again...
@ -644,7 +656,7 @@ void MainWindow::on_connectionListWidget_doubleClicked(const QModelIndex &index)
}
void MainWindow::on_clearlogButton_clicked()
{
logText->clear();
vCoreLogBrowser->clear();
}
void MainWindow::on_connectionListWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
@ -675,7 +687,6 @@ void MainWindow::on_connectionListWidget_itemChanged(QListWidgetItem *item)
LOG(MODULE_CONNECTION, "RENAME: " + originalName.toStdString() + " -> " + item->text().toStdString())
auto newName = item->text();
auto config = GetGlobalConfig();
auto configList = QList<string>::fromStdList(config.configs);
if (newName.trimmed().isEmpty()) {
QvMessageBox(this, tr("Rename a Connection"), tr("The name cannot be empty"));
@ -683,6 +694,8 @@ void MainWindow::on_connectionListWidget_itemChanged(QListWidgetItem *item)
}
// If I really did some changes.
auto configList = QList<string>::fromStdList(config.configs);
if (originalName != newName) {
if (configList.contains(newName.toStdString())) {
QvMessageBox(this, tr("Rename a Connection"), tr("The name has been used already, Please choose another."));
@ -903,54 +916,52 @@ void MainWindow::timerEvent(QTimerEvent *event)
{
// Calling base class
QMainWindow::timerEvent(event);
//
Q_UNUSED(event)
auto inbounds = CurrentFullConfig["inbounds"].toArray();
long _totalSpeedUp = 0, _totalSpeedDown = 0, _totalDataUp = 0, _totalDataDown = 0;
foreach (auto inbound, inbounds) {
auto tag = inbound.toObject()["tag"].toString();
if (event->timerId() == speedTimerId) {
auto _totalSpeedUp = vinstance->getAllSpeedUp();
auto _totalSpeedDown = vinstance->getAllSpeedDown();
auto _totalDataUp = vinstance->getAllDataUp();
auto _totalDataDown = vinstance->getAllDataDown();
//
double max = 0;
double historyMax = 0;
auto graphVUp = _totalSpeedUp / 1024;
auto graphVDown = _totalSpeedDown / 1024;
// We don't want these two.
if (tag.isEmpty() || tag == QV2RAY_API_TAG_INBOUND) continue;
for (auto i = 0; i < 29; i++) {
historyMax = MAX(historyMax, MAX(uploadList[i + 1], downloadList[i + 1]));
uploadList[i] = uploadList[i + 1];
downloadList[i] = downloadList[i + 1];
uploadSerie->replace(i, i, uploadList[i + 1]);
downloadSerie->replace(i, i, downloadList[i + 1]);
}
_totalSpeedUp += vinstance->getTagLastUplink(tag);
_totalSpeedDown += vinstance->getTagLastDownlink(tag);
_totalDataUp += vinstance->getTagTotalUplink(tag);
_totalDataDown += vinstance->getTagTotalDownlink(tag);
uploadList[uploadList.count() - 1] = graphVUp;
downloadList[uploadList.count() - 1] = graphVDown;
uploadSerie->replace(29, 29, graphVUp);
downloadSerie->replace(29, 29, graphVDown);
//
max = MAX(MAX(graphVUp, graphVDown), historyMax);
speedChartObj->axes(Qt::Vertical).first()->setRange(0, max * 1.2);
//
//
auto totalSpeedUp = FormatBytes(_totalSpeedUp) + "/s";
auto totalSpeedDown = FormatBytes(_totalSpeedDown) + "/s";
auto totalDataUp = FormatBytes(_totalDataUp);
auto totalDataDown = FormatBytes(_totalDataDown);
//
netspeedLabel->setText(totalSpeedUp + NEWLINE + totalSpeedDown);
dataamountLabel->setText(totalDataUp + NEWLINE + totalDataDown);
//
hTray->setToolTip(TRAY_TOOLTIP_PREFIX NEWLINE + tr("Connected To Server: ") + CurrentConnectionName + NEWLINE
"Up: " + totalSpeedUp + " Down: " + totalSpeedDown);
} else if (event->timerId() == logTimerId) {
QString lastLog = readLastLog();
if (!lastLog.isEmpty()) {
qvAppLogBrowser->append(lastLog);
}
}
double max = 0;
double historyMax = 0;
auto graphVUp = _totalSpeedUp / 1024;
auto graphVDown = _totalSpeedDown / 1024;
for (auto i = 0; i < 29; i++) {
historyMax = MAX(historyMax, MAX(uploadList[i + 1], downloadList[i + 1]));
uploadList[i] = uploadList[i + 1];
downloadList[i] = downloadList[i + 1];
uploadSerie->replace(i, i, uploadList[i + 1]);
downloadSerie->replace(i, i, downloadList[i + 1]);
}
uploadList[uploadList.count() - 1] = graphVUp;
downloadList[uploadList.count() - 1] = graphVDown;
uploadSerie->replace(29, 29, graphVUp);
downloadSerie->replace(29, 29, graphVDown);
//
max = MAX(MAX(graphVUp, graphVDown), historyMax);
speedChartObj->axes(Qt::Vertical).first()->setRange(0, max * 1.2);
//
//
totalSpeedUp = FormatBytes(_totalSpeedUp);
totalSpeedDown = FormatBytes(_totalSpeedDown);
totalDataUp = FormatBytes(_totalDataUp);
totalDataDown = FormatBytes(_totalDataDown);
//
netspeedLabel->setText(totalSpeedUp + "/s\r\n" + totalSpeedDown + "/s");
dataamountLabel->setText(totalDataUp + "\r\n" + totalDataDown);
//
hTray->setToolTip(TRAY_TOOLTIP_PREFIX "\r\n" + tr("Connected To Server: ") + CurrentConnectionName + "\r\nUp: " + totalSpeedUp + "/s Down: " + totalSpeedDown + "/s");
}
void MainWindow::on_duplicateBtn_clicked()
{
@ -977,3 +988,8 @@ void MainWindow::on_duplicateBtn_clicked()
SetGlobalConfig(config);
this->OnConfigListChanged(false);
}
void MainWindow::on_masterLogBrowser_textChanged()
{
//setMasterLogHBar();
}

View File

@ -29,13 +29,14 @@ class MainWindow : public QMainWindow, Ui::MainWindow
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow() override;
signals:
void Connect();
void DisConnect();
void ReConnect();
void Connect() const;
void DisConnect() const;
void ReConnect() const;
public slots:
void UpdateLog();
void UpdateVCoreLog(const QString &log);
void OnConfigListChanged(bool need_restart);
private slots:
void setMasterLogHBar();
void on_action_RCM_ShareQR_triggered(bool checked = false);
void on_startButton_clicked();
void on_stopButton_clicked();
@ -45,7 +46,6 @@ class MainWindow : public QMainWindow, Ui::MainWindow
void ToggleVisibility();
void quit();
void on_actionExit_triggered();
void QTextScrollToBottom();
void on_connectionListWidget_itemClicked(QListWidgetItem *item);
@ -75,14 +75,12 @@ class MainWindow : public QMainWindow, Ui::MainWindow
void on_duplicateBtn_clicked();
void on_masterLogBrowser_textChanged();
public:
CONFIGROOT CurrentFullConfig;
QString CurrentConnectionName = "";
ConnectionInstance *vinstance;
QString totalDataUp;
QString totalDataDown;
QString totalSpeedUp;
QString totalSpeedDown;
protected:
@ -114,17 +112,20 @@ class MainWindow : public QMainWindow, Ui::MainWindow
QString originalName;
bool isRenamingInProgress;
//
int logTimerId;
int speedTimerId;
//
void ShowAndSetConnection(QString currentText, bool SetConnection, bool Apply);
void LoadConnections();
//
PACHandler *pacServer;
Highlighter *highlighter;
//
QTextEdit vcoreLog;
QTextEdit qvAppLog;
int logSourceId = 0;
Highlighter *vCoreLogHighlighter;
Highlighter *qvAppLogHighlighter;
QList<QTextBrowser *> logTextBrowsers;
int currentLogBrowserId = 0;
};
static const MainWindow *mwInstance;
#endif // MAINWINDOW_H

View File

@ -41,7 +41,7 @@
<height>530</height>
</size>
</property>
<layout class="QGridLayout" name="gridLayout_2" rowstretch="0,6,4,0" columnstretch="6,4">
<layout class="QGridLayout" name="gridLayout_4" rowstretch="0,5,4,0" columnstretch="6,5">
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1,0,1,0,0,0">
<property name="spacing">
@ -124,29 +124,11 @@
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="midLineWidth">
<number>0</number>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="defaultDropAction">
<enum>Qt::CopyAction</enum>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
@ -419,7 +401,7 @@
</widget>
</item>
<item row="2" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout" columnstretch="5,0">
<layout class="QGridLayout" name="gridLayout_3" rowstretch="0,1" columnstretch="7,0">
<item row="0" column="0">
<widget class="QLabel" name="logLabel">
<property name="text">
@ -440,25 +422,6 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QTextBrowser" name="logText">
<property name="font">
<font>
<pointsize>8</pointsize>
<italic>false</italic>
</font>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
<property name="lineWrapMode">
<enum>QTextEdit::NoWrap</enum>
</property>
<property name="openLinks">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_10">
<property name="text">
@ -466,6 +429,9 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QTextBrowser" name="masterLogBrowser"/>
</item>
</layout>
</item>
<item row="3" column="0" colspan="2">

View File

@ -356,7 +356,7 @@ void PrefrencesWindow::on_tProxyCheckBox_stateChanged(int arg1)
auto newPath = QFileInfo(QV2RAY_DEFAULT_VCORE_PATH).path();
//
LOG(MODULE_FILE, " --> Origin v2ctl file is at: " + v2ctlPath.toStdString())
LOG(MODULE_FILE, " --> New v2ray files will be placed in: " << newPath.toStdString())
LOG(MODULE_FILE, " --> New v2ray files will be placed in: " + newPath.toStdString())
//
LOG(MODULE_FILE, " --> Copying files....")
@ -364,14 +364,14 @@ void PrefrencesWindow::on_tProxyCheckBox_stateChanged(int arg1)
// Only trying to remove file when they are not in the default dir.
// (In other words...) Keep using the current files. <Because we don't know where else we can copy the file from...>
if (QFile(QV2RAY_DEFAULT_VCORE_PATH).exists()) {
LOG(MODULE_FILE, QV2RAY_DEFAULT_VCORE_PATH.toStdString() << ": File already exists.")
LOG(MODULE_FILE, QV2RAY_DEFAULT_VCORE_PATH.toStdString() << ": Deleting file.")
LOG(MODULE_FILE, QV2RAY_DEFAULT_VCORE_PATH.toStdString() + ": File already exists.")
LOG(MODULE_FILE, QV2RAY_DEFAULT_VCORE_PATH.toStdString() + ": Deleting file.")
QFile(QV2RAY_DEFAULT_VCORE_PATH).remove();
}
if (QFile(newPath + "/v2ctl").exists()) {
LOG(MODULE_FILE, newPath.toStdString() << "/v2ctl" << ": File already exists.")
LOG(MODULE_FILE, newPath.toStdString() << "/v2ctl" << ": Deleting file.")
LOG(MODULE_FILE, newPath.toStdString() + "/v2ctl : File already exists.")
LOG(MODULE_FILE, newPath.toStdString() + "/v2ctl : Deleting file.")
QFile(newPath + "/v2ctl").remove();
}

View File

@ -262,10 +262,9 @@ void RouteEditor::ShowRuleDetail(RuleObject rule)
netBothRB->setChecked(network.contains("tcp") && network.contains("udp"));
//
// Set protocol checkboxes.
auto protocols = QList<string>::fromStdList(CurrentRule.protocol);
routeProtocolHTTPCB->setChecked(protocols.contains("http"));
routeProtocolTLSCB->setChecked(protocols.contains("tls"));
routeProtocolBTCB->setChecked(protocols.contains("bittorrent"));
routeProtocolHTTPCB->setChecked(contains(CurrentRule.protocol, string("http")));
routeProtocolTLSCB->setChecked(contains(CurrentRule.protocol, string("tls")));
routeProtocolBTCB->setChecked(contains(CurrentRule.protocol, string("bittorrent")));
//
// Port
routePortTxt->setText(QSTRING(CurrentRule.port));

View File

@ -3,13 +3,17 @@
#include <iostream>
#include <QtDebug>
#include <QBuffer>
using namespace std;
/*
* Tiny log module.
*/
#define LOG(module, msg) cout << "[" << module << "]: " << msg << endl;
void _LOG(const std::string &module, const std::string &log);
const QString readLastLog();
#define LOG(module, msg) _LOG(module, msg);
#ifdef QT_DEBUG
#define DEBUG(module, msg) LOG("[DEBUG] - " module, msg)
@ -17,9 +21,6 @@ using namespace std;
#define DEBUG(module, msg)
#endif
#define CLOG(value) DEBUG("[CONTENT-LOG]", #value << ":" << value)
#define XLOG(module, level, msg) LOG(module, level << msg)
#define MODULE_INIT "INIT"
#define MODULE_UPDATE "UPDATE"
#define MODULE_VCORE "VCORE"