Brings back the mining tab and adds support for solo mining.

- Automatically sets the receiving address and spendkey to the current wallet
- The ability to specify CPU threads
- The ability to download the latest wownerod release from within wowlet (via: wowlet/wowlet-backend#18)
- Explanation on how to mine via the 'How-To' tab
- Console has a buffer of 2000 lines (auto-clears)
solo-mining
dsc 2 years ago
parent 8b215c1e73
commit d6dfd678b8

@ -10,7 +10,6 @@ set(VERSION_REVISION "0")
set(VERSION "beta-4") set(VERSION "beta-4")
option(FETCH_DEPS "Download dependencies if they are not found" ON) option(FETCH_DEPS "Download dependencies if they are not found" ON)
option(XMRIG "Include XMRig module")
option(OPENVR "Include OpenVR support") option(OPENVR "Include OpenVR support")
option(QML "Include QtQuick (QML)") option(QML "Include QtQuick (QML)")
option(ANDROID "Android deployment") option(ANDROID "Android deployment")

@ -172,10 +172,6 @@ if(TOR_BIN)
target_compile_definitions(wowlet PRIVATE HAS_TOR_BIN=1) target_compile_definitions(wowlet PRIVATE HAS_TOR_BIN=1)
endif() endif()
if(XMRIG)
target_compile_definitions(wowlet PRIVATE HAS_XMRIG=1)
endif()
if(ANDROID) if(ANDROID)
target_compile_definitions(wowlet PRIVATE HAS_ANDROID=1) target_compile_definitions(wowlet PRIVATE HAS_ANDROID=1)
endif() endif()
@ -389,7 +385,6 @@ message(STATUS "VERSION_REVISION: ${VERSION_REVISION}")
message(STATUS "STATIC: ${STATIC}") message(STATUS "STATIC: ${STATIC}")
message(STATUS "Include QtQuick (QML): ${QML}") message(STATUS "Include QtQuick (QML): ${QML}")
message(STATUS "VERSION: ${VERSION}") message(STATUS "VERSION: ${VERSION}")
message(STATUS "Include the XMRIG tab: ${XMRIG}")
message(STATUS "Include Valve's OpenVR library: ${OPENVR}") message(STATUS "Include Valve's OpenVR library: ${OPENVR}")
message(STATUS "This build is for Android: ${ANDROID}") message(STATUS "This build is for Android: ${ANDROID}")
message(STATUS "This build is for testing the Android app on desktop: ${ANDROID_DEBUG}") message(STATUS "This build is for testing the Android app on desktop: ${ANDROID_DEBUG}")

@ -163,10 +163,8 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
AppContext::prices = new Prices(); AppContext::prices = new Prices();
// XMRig // XMRig
#ifdef HAS_XMRIG
this->XMRig = new XmRig(this->configDirectory, this); this->XMRig = new XmRig(this->configDirectory, this);
this->XMRig->prepare(); this->XMRig->prepare();
#endif
this->walletManager = WalletManager::instance(); this->walletManager = WalletManager::instance();
QString logPath = QString("%1/daemon.log").arg(configDirectory); QString logPath = QString("%1/daemon.log").arg(configDirectory);
@ -447,11 +445,12 @@ void AppContext::onWSMessage(const QJsonObject &msg) {
else if(cmd == "rpc_nodes") { else if(cmd == "rpc_nodes") {
this->onWSNodes(msg.value("data").toArray()); this->onWSNodes(msg.value("data").toArray());
} }
#if defined(HAS_XMRIG)
else if(cmd == "xmrig") { else if(cmd == "xmrig") {
this->XMRigDownloads(msg.value("data").toObject()); this->XMRigDownloads(msg.value("data").toObject());
} }
#endif else if(cmd == "wownerod_releases") {
emit WownerodDownloads(msg.value("data").toObject());
}
else if(cmd == "crypto_rates") { else if(cmd == "crypto_rates") {
QJsonArray crypto_rates = msg.value("data").toArray(); QJsonArray crypto_rates = msg.value("data").toArray();
AppContext::prices->cryptoPricesReceived(crypto_rates); AppContext::prices->cryptoPricesReceived(crypto_rates);

@ -215,6 +215,7 @@ signals:
void yellowUpdated(); void yellowUpdated();
void nodeSourceChanged(NodeSource nodeSource); void nodeSourceChanged(NodeSource nodeSource);
void XMRigDownloads(const QJsonObject &data); void XMRigDownloads(const QJsonObject &data);
void WownerodDownloads(const QJsonObject &data);
void pinLookupReceived(QString address, QString pin); void pinLookupReceived(QString address, QString pin);
void pinLookupErrorReceived(); void pinLookupErrorReceived();
void pinReceived(QString pin); void pinReceived(QString pin);

@ -37,6 +37,7 @@
<file>assets/images/eye_blind.png</file> <file>assets/images/eye_blind.png</file>
<file>assets/images/wowlet.png</file> <file>assets/images/wowlet.png</file>
<file>assets/images/file.png</file> <file>assets/images/file.png</file>
<file>assets/images/fire.png</file>
<file>assets/images/gnome-calc.png</file> <file>assets/images/gnome-calc.png</file>
<file>assets/images/history.png</file> <file>assets/images/history.png</file>
<file>assets/images/info.png</file> <file>assets/images/info.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

@ -171,22 +171,21 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
connect(m_ctx->nodes, &Nodes::WSNodeExhausted, this, &MainWindow::showWSNodeExhaustedMessage); connect(m_ctx->nodes, &Nodes::WSNodeExhausted, this, &MainWindow::showWSNodeExhaustedMessage);
// XMRig // XMRig
#ifdef HAS_XMRIG
m_xmrig = new XMRigWidget(m_ctx, this); m_xmrig = new XMRigWidget(m_ctx, this);
ui->xmrRigLayout->addWidget(m_xmrig); ui->xmrRigLayout->addWidget(m_xmrig);
connect(m_ctx->XMRig, &XmRig::output, m_xmrig, &XMRigWidget::onProcessOutput); connect(m_ctx->XMRig, &XmRig::output, m_xmrig, &XMRigWidget::onProcessOutput);
connect(m_ctx->XMRig, &XmRig::error, m_xmrig, &XMRigWidget::onProcessError); connect(m_ctx->XMRig, &XmRig::error, m_xmrig, &XMRigWidget::onProcessError);
connect(m_ctx->XMRig, &XmRig::stopped, m_xmrig, &XMRigWidget::onStopped);
connect(m_ctx->XMRig, &XmRig::blockReward, m_xmrig, &XMRigWidget::onBlockReward);
connect(m_ctx->XMRig, &XmRig::hashrate, m_xmrig, &XMRigWidget::onHashrate); connect(m_ctx->XMRig, &XmRig::hashrate, m_xmrig, &XMRigWidget::onHashrate);
connect(m_ctx, &AppContext::walletClosed, m_xmrig, &XMRigWidget::onWalletClosed); connect(m_ctx, &AppContext::walletClosed, m_xmrig, &XMRigWidget::onWalletClosed);
connect(m_ctx, &AppContext::walletOpened, m_xmrig, &XMRigWidget::onWalletOpened); connect(m_ctx, &AppContext::walletOpened, m_xmrig, &XMRigWidget::onWalletOpened);
connect(m_ctx, &AppContext::XMRigDownloads, m_xmrig, &XMRigWidget::onDownloads); connect(m_ctx, &AppContext::XMRigDownloads, m_xmrig, &XMRigWidget::onRigDownloads);
connect(m_ctx, &AppContext::WownerodDownloads, m_xmrig, &XMRigWidget::onWownerodDownloads);
connect(m_xmrig, &XMRigWidget::miningStarted, [=]{ m_ctx->setWindowTitle(true); }); connect(m_xmrig, &XMRigWidget::miningStarted, [=]{ m_ctx->setWindowTitle(true); });
connect(m_xmrig, &XMRigWidget::miningEnded, [=]{ m_ctx->setWindowTitle(false); }); connect(m_xmrig, &XMRigWidget::miningEnded, [=]{ m_ctx->setWindowTitle(false); });
#else
ui->tabWidget->setTabVisible(Tabs::XMRIG, false);
#endif
connect(ui->ccsWidget, &CCSWidget::selected, this, &MainWindow::showSendScreen); connect(ui->ccsWidget, &CCSWidget::selected, this, &MainWindow::showSendScreen);
connect(m_ctx, &AppContext::ccsUpdated, ui->ccsWidget->model(), &CCSModel::updateEntries); connect(m_ctx, &AppContext::ccsUpdated, ui->ccsWidget->model(), &CCSModel::updateEntries);
@ -421,13 +420,9 @@ void MainWindow::initMenu() {
m_tabShowHideMapper["Calc"] = new ToggleTab(ui->tabCalc, "Calc", "Calc", ui->actionShow_calc, Config::showTabCalc); m_tabShowHideMapper["Calc"] = new ToggleTab(ui->tabCalc, "Calc", "Calc", ui->actionShow_calc, Config::showTabCalc);
m_tabShowHideSignalMapper->setMapping(ui->actionShow_calc, "Calc"); m_tabShowHideSignalMapper->setMapping(ui->actionShow_calc, "Calc");
#if defined(HAS_XMRIG)
connect(ui->actionShow_XMRig, &QAction::triggered, m_tabShowHideSignalMapper, QOverload<>::of(&QSignalMapper::map)); connect(ui->actionShow_XMRig, &QAction::triggered, m_tabShowHideSignalMapper, QOverload<>::of(&QSignalMapper::map));
m_tabShowHideMapper["Mining"] = new ToggleTab(ui->tabXmrRig, "Mining", "Mining", ui->actionShow_XMRig, Config::showTabXMRig); m_tabShowHideMapper["Mining"] = new ToggleTab(ui->tabXmrRig, "Mining", "Mining", ui->actionShow_XMRig, Config::showTabXMRig);
m_tabShowHideSignalMapper->setMapping(ui->actionShow_XMRig, "Mining"); m_tabShowHideSignalMapper->setMapping(ui->actionShow_XMRig, "Mining");
#else
ui->actionShow_XMRig->setVisible(false);
#endif
for (const auto &key: m_tabShowHideMapper.keys()) { for (const auto &key: m_tabShowHideMapper.keys()) {
const auto toggleTab = m_tabShowHideMapper.value(key); const auto toggleTab = m_tabShowHideMapper.value(key);

@ -207,6 +207,20 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tabXmrRig">
<attribute name="icon">
<iconset resource="assets.qrc">
<normaloff>:/assets/images/mining.png</normaloff>:/assets/images/mining.png</iconset>
</attribute>
<attribute name="title">
<string>Mining</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QGridLayout" name="xmrRigLayout"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabHistory"> <widget class="QWidget" name="tabHistory">
<attribute name="icon"> <attribute name="icon">
<iconset resource="assets.qrc"> <iconset resource="assets.qrc">
@ -330,20 +344,6 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tabXmrRig">
<attribute name="icon">
<iconset resource="assets.qrc">
<normaloff>:/assets/images/mining.png</normaloff>:/assets/images/mining.png</iconset>
</attribute>
<attribute name="title">
<string>Mining</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QGridLayout" name="xmrRigLayout"/>
</item>
</layout>
</widget>
</widget> </widget>
</item> </item>
</layout> </layout>

@ -33,14 +33,14 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
{Config::autoOpenWalletPath,{QS("autoOpenWalletPath"), ""}}, {Config::autoOpenWalletPath,{QS("autoOpenWalletPath"), ""}},
{Config::walletPath,{QS("walletPath"), ""}}, {Config::walletPath,{QS("walletPath"), ""}},
{Config::xmrigPath,{QS("xmrigPath"), ""}}, {Config::xmrigPath,{QS("xmrigPath"), ""}},
{Config::xmrigPool,{QS("xmrigPool"), "cryptonote.social:2223"}}, {Config::wownerodPath, {QS("wownerodPath"), ""}},
{Config::nodes,{QS("nodes"), "{}"}}, {Config::nodes,{QS("nodes"), "{}"}},
{Config::websocketEnabled,{QS("websocketEnabled"), true}}, {Config::websocketEnabled,{QS("websocketEnabled"), true}},
{Config::nodeSource,{QS("nodeSource"), 0}}, {Config::nodeSource,{QS("nodeSource"), 0}},
{Config::useOnionNodes,{QS("useOnionNodes"), false}}, {Config::useOnionNodes,{QS("useOnionNodes"), false}},
{Config::showTabHome,{QS("showTabHome"), true}}, {Config::showTabHome,{QS("showTabHome"), true}},
{Config::showTabCoins,{QS("showTabCoins"), false}}, {Config::showTabCoins,{QS("showTabCoins"), false}},
{Config::showTabXMRig,{QS("showTabXMRig"), false}}, {Config::showTabXMRig,{QS("showTabXMRig"), true}},
{Config::showTabCalc,{QS("showTabCalc"), false}}, {Config::showTabCalc,{QS("showTabCalc"), false}},
{Config::geometry, {QS("geometry"), {}}}, {Config::geometry, {QS("geometry"), {}}},
{Config::windowState, {QS("windowState"), {}}}, {Config::windowState, {QS("windowState"), {}}},

@ -35,7 +35,7 @@ public:
walletDirectory, walletDirectory,
walletPath, walletPath,
xmrigPath, xmrigPath,
xmrigPool, wownerodPath,
nodes, nodes,
websocketEnabled, websocketEnabled,
nodeSource, nodeSource,

@ -7,10 +7,17 @@
#include "utils/utils.h" #include "utils/utils.h"
#include "utils/xmrig.h" #include "utils/xmrig.h"
#include "appcontext.h" #include "mainwindow.h"
XmRig::XmRig(const QString &configDir, QObject *parent) : QObject(parent) { XmRig::XmRig(const QString &configDir, QObject *parent) :
this->rigDir = QDir(configDir).filePath("xmrig"); QObject(parent),
m_statusTimer(new QTimer(this))
{
m_statusTimer->setInterval(5000);
connect(m_statusTimer, &QTimer::timeout, [this]{
if(mining_started && m_process.state() == QProcess::Running)
m_process.write("status\n");
});
} }
void XmRig::prepare() { void XmRig::prepare() {
@ -28,74 +35,82 @@ void XmRig::stop() {
m_process.terminate(); m_process.terminate();
#endif #endif
} }
m_statusTimer->stop();
} }
void XmRig::start(const QString &path, bool XmRig::start(const QString &path, int threads) {
int threads, m_ctx = MainWindow::getContext();
const QString &address,
const QString &username,
const QString &password,
bool tor, bool tls) {
auto state = m_process.state(); auto state = m_process.state();
if (state == QProcess::ProcessState::Running || state == QProcess::ProcessState::Starting) { if (state == QProcess::ProcessState::Running || state == QProcess::ProcessState::Starting) {
emit error("Can't start XMRig, already running or starting"); emit error("Can't start wownerod, already running or starting");
return; return false;
} }
if(path.isEmpty()) { if(path.isEmpty()) {
emit error("XmRig->Start path parameter missing."); emit error("wownerod path seems to be empty.");
return; return false;
} }
if(!Utils::fileExists(path)) { if(!Utils::fileExists(path)) {
emit error(QString("Path to XMRig binary invalid; file does not exist: %1").arg(path)); emit error(QString("Path to wownerod binary is invalid; file does not exist: %1").arg(path));
return; return false;
} }
auto privateSpendKey = m_ctx->currentWallet->getSecretSpendKey();
QStringList arguments; QStringList arguments;
arguments << "-o" << address; arguments << "--mining-threads" << QString::number(threads);
arguments << "-a" << "rx/wow"; arguments << "--start-mining" << m_ctx->currentWallet->address(0, 0);
arguments << "-u" << username; arguments << "--spendkey" << privateSpendKey;
if(!password.isEmpty())
arguments << "-p" << password;
arguments << "--no-color";
arguments << "-t" << QString::number(threads);
if(tor)
arguments << "-x" << QString("%1:%2").arg(Tor::torHost).arg(Tor::torPort);
if(tls)
arguments << "--tls";
arguments << "--donate-level" << "1";
QString cmd = QString("%1 %2").arg(path, arguments.join(" ")); QString cmd = QString("%1 %2").arg(path, arguments.join(" "));
cmd = cmd.replace(privateSpendKey, "[redacted]");
emit output(cmd.toUtf8()); emit output(cmd.toUtf8());
m_process.start(path, arguments); m_process.start(path, arguments);
m_statusTimer->start();
return true;
} }
void XmRig::stateChanged(QProcess::ProcessState state) { void XmRig::stateChanged(QProcess::ProcessState state) {
if(state == QProcess::ProcessState::Running) if(state == QProcess::ProcessState::Running)
emit output("XMRig started"); emit output("wownerod started");
else if (state == QProcess::ProcessState::NotRunning) else if (state == QProcess::ProcessState::NotRunning) {
emit output("XMRig stopped"); emit output("wownerod stopped");
this->mining_started = false;
emit stopped();
}
} }
void XmRig::handleProcessOutput() { void XmRig::handleProcessOutput() {
QByteArray _output = m_process.readAllStandardOutput(); QByteArray data = m_process.readAllStandardOutput();
if(_output.contains("miner") && _output.contains("speed")) {
// detect hashrate for(auto &line: data.split('\n')) {
auto str = Utils::barrayToString(_output); if(line.indexOf("\tI") >= 20)
auto spl = str.mid(str.indexOf("speed")).split(" "); line = line.remove(0, line.indexOf("\tI") + 2);
auto rate = spl.at(2) + "H/s"; if(line.trimmed().isEmpty() || line.startsWith("status")) continue;
qDebug() << "mining hashrate: " << rate; if(line.contains("Mining started. Good luck"))
emit hashrate(rate); this->mining_started = true;
} else if(line.contains("you won a block reward"))
emit blockReward();
else if(line.contains("mining at")) {
auto rate = line.remove(0, line.indexOf("mining at"));
rate = rate.remove(rate.indexOf(","), rate.length());
rate = rate.remove(0, 9);
rate = rate.trimmed();
emit hashrate(rate);
}
emit output(_output); emit output(line);
}
} }
void XmRig::handleProcessError(QProcess::ProcessError err) { void XmRig::handleProcessError(QProcess::ProcessError err) {
if (err == QProcess::ProcessError::Crashed) if (err == QProcess::ProcessError::Crashed)
emit error("XMRig crashed or killed"); emit error("wownerod crashed or killed");
else if (err == QProcess::ProcessError::FailedToStart) { else if (err == QProcess::ProcessError::FailedToStart) {
auto path = config()->get(Config::xmrigPath).toString(); auto path = config()->get(Config::wownerodPath).toString();
emit error(QString("XMRig binary failed to start: %1").arg(path)); emit error(QString("wownerod binary failed to start: %1").arg(path));
} }
this->mining_started = false;
} }

@ -14,6 +14,7 @@
#include "utils/childproc.h" #include "utils/childproc.h"
class AppContext;
class XmRig : public QObject class XmRig : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -22,15 +23,14 @@ public:
explicit XmRig(const QString &configDir, QObject *parent = nullptr); explicit XmRig(const QString &configDir, QObject *parent = nullptr);
void prepare(); void prepare();
void start(const QString &path, int threads, const QString &address, const QString &username, const QString &password, bool tor = false, bool tls = true); bool start(const QString &path, int threads);
void stop(); void stop();
QString rigDir;
QString rigPath;
signals: signals:
void error(const QString &msg); void error(const QString &msg);
void output(const QByteArray &data); void output(const QByteArray &data);
void stopped();
void blockReward();
void hashrate(const QString &rate); void hashrate(const QString &rate);
private slots: private slots:
@ -40,6 +40,9 @@ private slots:
private: private:
ChildProcess m_process; ChildProcess m_process;
AppContext *m_ctx;
QTimer *m_statusTimer;
bool mining_started = false;
}; };
#endif //WOWLET_XMRIG_H #endif //WOWLET_XMRIG_H

@ -15,19 +15,28 @@ XMRigWidget::XMRigWidget(AppContext *ctx, QWidget *parent) :
QWidget(parent), QWidget(parent),
ui(new Ui::XMRigWidget), ui(new Ui::XMRigWidget),
m_ctx(ctx), m_ctx(ctx),
m_model(new QStandardItemModel(this)), m_modelRig(new QStandardItemModel(this)),
m_contextMenu(new QMenu(this)) m_modelWownerod(new QStandardItemModel(this)),
m_contextMenuRig(new QMenu(this)),
m_contextMenuWownerod(new QMenu(this))
{ {
ui->setupUi(this); ui->setupUi(this);
QPixmap p(":assets/images/mining.png"); QPixmap p(":assets/images/fire.png");
ui->lbl_logo->setPixmap(p.scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation)); ui->lbl_logo->setPixmap(p.scaled(268, 271, Qt::KeepAspectRatio, Qt::SmoothTransformation));
ui->lbl_reward->hide();
// table // table XMRig
ui->tableView->setModel(this->m_model); ui->tableRig->setModel(this->m_modelRig);
m_contextMenu->addAction(QIcon(":/assets/images/network.png"), "Download file", this, &XMRigWidget::linkClicked); m_contextMenuRig->addAction(QIcon(":/assets/images/network.png"), "Download file", this, &XMRigWidget::rigLinkClicked);
connect(ui->tableView, &QHeaderView::customContextMenuRequested, this, &XMRigWidget::showContextMenu); connect(ui->tableRig, &QHeaderView::customContextMenuRequested, this, &XMRigWidget::showContextRigMenu);
connect(ui->tableView, &QTableView::doubleClicked, this, &XMRigWidget::linkClicked); connect(ui->tableRig, &QTableView::doubleClicked, this, &XMRigWidget::rigLinkClicked);
// table wownerod
ui->tableWownerod->setModel(this->m_modelWownerod);
m_contextMenuWownerod->addAction(QIcon(":/assets/images/network.png"), "Download file", this, &XMRigWidget::wownerodLinkClicked);
connect(ui->tableWownerod, &QHeaderView::customContextMenuRequested, this, &XMRigWidget::showContextWownerodMenu);
connect(ui->tableWownerod, &QTableView::doubleClicked, this, &XMRigWidget::wownerodLinkClicked);
// threads // threads
ui->threadSlider->setMinimum(1); ui->threadSlider->setMinimum(1);
@ -47,75 +56,49 @@ XMRigWidget::XMRigWidget(AppContext *ctx, QWidget *parent) :
// defaults // defaults
ui->btn_stop->setEnabled(false); ui->btn_stop->setEnabled(false);
ui->check_autoscroll->setChecked(true); ui->check_autoscroll->setChecked(true);
ui->relayTor->setChecked(false); #ifdef Q_OS_WIN
ui->check_tls->setChecked(true); ui->label_path->setText("Path to wownerod.exe");
#endif
ui->label_status->setTextInteractionFlags(Qt::TextSelectableByMouse); ui->label_status->setTextInteractionFlags(Qt::TextSelectableByMouse);
ui->label_status->hide(); ui->label_status->hide();
ui->soloFrame->hide();
ui->poolFrame->hide();
// XMRig binary // wownerod binary
auto path = config()->get(Config::xmrigPath).toString(); auto path = config()->get(Config::wownerodPath).toString();
if(!path.isEmpty()) { if(!path.isEmpty())
ui->lineEdit_path->setText(path); ui->lineEdit_path->setText(path);
}
// pools connect(ui->lineEdit_path, &QLineEdit::textChanged, [=] {
ui->poolFrame->show(); config()->set(Config::wownerodPath, ui->lineEdit_path->text().trimmed());
ui->combo_pools->insertItems(0, m_pools); });
auto preferredPool = config()->get(Config::xmrigPool).toString();
if (m_pools.contains(preferredPool))
ui->combo_pools->setCurrentIndex(m_pools.indexOf(preferredPool));
else {
preferredPool = m_pools.at(0);
config()->set(Config::xmrigPool, preferredPool);
}
connect(ui->combo_pools, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &XMRigWidget::onPoolChanged);
// info // info
ui->console->appendPlainText(QString("Detected %1 CPU threads.").arg(threads)); this->appendText(QString("Detected %1 CPU threads.").arg(threads));
if(!path.isEmpty() && !Utils::fileExists(path)) if(path.isEmpty())
ui->console->appendPlainText("Invalid path to XMRig binary detected. Please reconfigure on the Settings tab."); this->appendText(QString("wownerod path is empty - please point towards the wownerod executable.").arg(path));
else else if(!Utils::fileExists(path))
ui->console->appendPlainText(QString("XMRig path set to %1").arg(path)); this->appendText("Invalid path to the wownerod executable detected. Please set the correct path.");
else {
ui->console->appendPlainText("Ready to mine."); this->appendText(QString("wownerod path set to '%1'").arg(path));
this->appendText("Ready to mine.");
// username/password }
connect(ui->lineEdit_password, &QLineEdit::editingFinished, [=]() { }
m_ctx->currentWallet->setCacheAttribute("wowlet.xmrig_password", ui->lineEdit_password->text());
m_ctx->storeWallet();
});
connect(ui->lineEdit_address, &QLineEdit::editingFinished, [=]() {
m_ctx->currentWallet->setCacheAttribute("wowlet.xmrig_username", ui->lineEdit_address->text());
m_ctx->storeWallet();
});
// checkbox connects void XMRigWidget::appendText(const QString &line) {
connect(ui->check_solo, &QCheckBox::stateChanged, this, &XMRigWidget::onSoloChecked); ui->console->appendPlainText(line);
m_consoleBuffer += 1;
if(m_consoleBuffer >= m_consoleBufferMax) {
ui->console->clear();
m_consoleBuffer = 0;
}
} }
void XMRigWidget::onWalletClosed() { void XMRigWidget::onWalletClosed() {
this->onStopClicked(); this->onStopClicked();
this->onClearClicked(); this->onClearClicked();
ui->lineEdit_password->setText("");
ui->lineEdit_address->setText("");
} }
void XMRigWidget::onWalletOpened(Wallet *wallet){ void XMRigWidget::onWalletOpened(Wallet *wallet){
// Xmrig username int egiwoge = 1;
auto username = m_ctx->currentWallet->getCacheAttribute("wowlet.xmrig_username");
if(!username.isEmpty())
ui->lineEdit_address->setText(username);
// Xmrig passwd
auto password = m_ctx->currentWallet->getCacheAttribute("wowlet.xmrig_password");
if(!password.isEmpty()) {
ui->lineEdit_password->setText(password);
} else {
ui->lineEdit_password->setText("wowlet");
m_ctx->currentWallet->setCacheAttribute("wowlet.xmrig_password", ui->lineEdit_password->text());
}
} }
void XMRigWidget::onThreadsValueChanged(int threads) { void XMRigWidget::onThreadsValueChanged(int threads) {
@ -123,50 +106,28 @@ void XMRigWidget::onThreadsValueChanged(int threads) {
ui->label_threads->setText(QString("CPU threads: %1").arg(m_threads)); ui->label_threads->setText(QString("CPU threads: %1").arg(m_threads));
} }
void XMRigWidget::onPoolChanged(int pos) {
config()->set(Config::xmrigPool, m_pools.at(pos));
}
void XMRigWidget::onBrowseClicked() { void XMRigWidget::onBrowseClicked() {
QString fileName = QFileDialog::getOpenFileName( QString fileName = QFileDialog::getOpenFileName(
this, "Path to XMRig executable", QDir::homePath()); this, "Path to wownerod executable", QDir::homePath());
if (fileName.isEmpty()) return; if (fileName.isEmpty()) return;
config()->set(Config::xmrigPath, fileName); config()->set(Config::wownerodPath, fileName);
ui->lineEdit_path->setText(fileName); ui->lineEdit_path->setText(fileName);
} }
void XMRigWidget::onBlockReward() {
QDateTime date = QDateTime::currentDateTime();
QString formattedTime = date.toString("yyyy/MM/dd hh:mm");
ui->lbl_reward->setText(QString("Congrats: new block found at %1").arg(formattedTime));
ui->lbl_reward->show();
}
void XMRigWidget::onClearClicked() { void XMRigWidget::onClearClicked() {
ui->console->clear(); ui->console->clear();
} }
void XMRigWidget::onStartClicked() { void XMRigWidget::onStartClicked() {
QString xmrigPath; auto binPath = config()->get(Config::wownerodPath).toString();
bool solo = ui->check_solo->isChecked(); if(!m_ctx->XMRig->start(binPath, m_threads)) return;
xmrigPath = config()->get(Config::xmrigPath).toString();
// username is receiving address usually
auto username = m_ctx->currentWallet->getCacheAttribute("wowlet.xmrig_username");
auto password = m_ctx->currentWallet->getCacheAttribute("wowlet.xmrig_password");
if(username.isEmpty()) {
QString err = "Please specify a receiving address on the Settings screen";
ui->console->appendPlainText(err);
QMessageBox::warning(this, "Error", err);
return;
}
QString address;
if(solo)
address = ui->lineEdit_solo->text().trimmed();
else
address = config()->get(Config::xmrigPool).toString();
if(address.contains("cryptonote.social") && !username.contains(".")) {
// cryptonote social requires <addr>.<username>, we'll just grab a few chars from primary addy
username = QString("%1.%2").arg(username, m_ctx->currentWallet->address(0, 0).mid(0, 6));
}
m_ctx->XMRig->start(xmrigPath, m_threads, address, username, password, ui->relayTor->isChecked(), ui->check_tls->isChecked());
ui->btn_start->setEnabled(false); ui->btn_start->setEnabled(false);
ui->btn_stop->setEnabled(true); ui->btn_stop->setEnabled(true);
@ -175,10 +136,6 @@ void XMRigWidget::onStartClicked() {
void XMRigWidget::onStopClicked() { void XMRigWidget::onStopClicked() {
m_ctx->XMRig->stop(); m_ctx->XMRig->stop();
ui->btn_start->setEnabled(true);
ui->btn_stop->setEnabled(false);
ui->label_status->hide();
emit miningEnded();
} }
void XMRigWidget::onProcessOutput(const QByteArray &data) { void XMRigWidget::onProcessOutput(const QByteArray &data) {
@ -186,14 +143,21 @@ void XMRigWidget::onProcessOutput(const QByteArray &data) {
if(output.endsWith("\n")) if(output.endsWith("\n"))
output = output.trimmed(); output = output.trimmed();
ui->console->appendPlainText(output); this->appendText(output);
if(ui->check_autoscroll->isChecked()) if(ui->check_autoscroll->isChecked())
ui->console->verticalScrollBar()->setValue(ui->console->verticalScrollBar()->maximum()); ui->console->verticalScrollBar()->setValue(ui->console->verticalScrollBar()->maximum());
} }
void XMRigWidget::onStopped() {
ui->btn_start->setEnabled(true);
ui->btn_stop->setEnabled(false);
ui->label_status->hide();
emit miningEnded();
}
void XMRigWidget::onProcessError(const QString &msg) { void XMRigWidget::onProcessError(const QString &msg) {
ui->console->appendPlainText("\n" + msg); this->appendText(msg);
ui->btn_start->setEnabled(true); ui->btn_start->setEnabled(true);
ui->btn_stop->setEnabled(false); ui->btn_stop->setEnabled(false);
ui->label_status->hide(); ui->label_status->hide();
@ -205,17 +169,62 @@ void XMRigWidget::onHashrate(const QString &hashrate) {
ui->label_status->setText(QString("Mining at %1").arg(hashrate)); ui->label_status->setText(QString("Mining at %1").arg(hashrate));
} }
void XMRigWidget::onDownloads(const QJsonObject &data) { void XMRigWidget::onWownerodDownloads(const QJsonObject &data) {
// For the downloads table we'll manually update the table m_modelWownerod->clear();
// with items once, as opposed to creating a class in m_urlsWownerod.clear();
// src/models/. Saves effort; full-blown model
// is unnecessary in this case. auto version = data.value("version").toString();
ui->label_latest_version_wownerod->setText(QString("Latest version: %1").arg(version));
QJsonObject assets = data.value("assets").toObject();
const auto _linux = assets.value("linux").toArray();
const auto macos = assets.value("macos").toArray();
const auto windows = assets.value("windows").toArray();
m_model->clear(); auto info = QSysInfo::productType();
m_urls.clear(); QJsonArray *os_assets;
if(info == "osx") {
os_assets = const_cast<QJsonArray *>(&macos);
} else if (info == "windows") {
os_assets = const_cast<QJsonArray *>(&windows);
} else {
// assume linux
os_assets = const_cast<QJsonArray *>(&_linux);
}
int i = 0;
for(const auto &entry: *os_assets) {
auto _obj = entry.toObject();
auto _name = _obj.value("name").toString();
auto _url = _obj.value("url").toString();
auto _created_at = _obj.value("created_at").toString();
m_urlsWownerod.append(_url);
auto download_count = _obj.value("download_count").toInt();
m_modelWownerod->setItem(i, 0, Utils::qStandardItem(_name));
m_modelWownerod->setItem(i, 1, Utils::qStandardItem(_created_at));
m_modelWownerod->setItem(i, 2, Utils::qStandardItem(QString::number(download_count)));
i++;
}
m_modelWownerod->setHeaderData(0, Qt::Horizontal, tr("Filename"), Qt::DisplayRole);
m_modelWownerod->setHeaderData(1, Qt::Horizontal, tr("Date"), Qt::DisplayRole);
m_modelWownerod->setHeaderData(2, Qt::Horizontal, tr("Downloads"), Qt::DisplayRole);
ui->tableWownerod->verticalHeader()->setVisible(false);
ui->tableWownerod->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableWownerod->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
ui->tableWownerod->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
ui->tableWownerod->setColumnWidth(2, 100);
}
void XMRigWidget::onRigDownloads(const QJsonObject &data) {
m_modelRig->clear();
m_urlsRig.clear();
auto version = data.value("version").toString(); auto version = data.value("version").toString();
ui->label_latest_version->setText(QString("Latest version: %1").arg(version)); ui->label_latest_version_rig->setText(QString("Latest version: %1").arg(version));
QJsonObject assets = data.value("assets").toObject(); QJsonObject assets = data.value("assets").toObject();
const auto _linux = assets.value("linux").toArray(); const auto _linux = assets.value("linux").toArray();
@ -240,54 +249,54 @@ void XMRigWidget::onDownloads(const QJsonObject &data) {
auto _url = _obj.value("url").toString(); auto _url = _obj.value("url").toString();
auto _created_at = _obj.value("created_at").toString(); auto _created_at = _obj.value("created_at").toString();
m_urls.append(_url); m_urlsRig.append(_url);
auto download_count = _obj.value("download_count").toInt(); auto download_count = _obj.value("download_count").toInt();
m_model->setItem(i, 0, Utils::qStandardItem(_name)); m_modelRig->setItem(i, 0, Utils::qStandardItem(_name));
m_model->setItem(i, 1, Utils::qStandardItem(_created_at)); m_modelRig->setItem(i, 1, Utils::qStandardItem(_created_at));
m_model->setItem(i, 2, Utils::qStandardItem(QString::number(download_count))); m_modelRig->setItem(i, 2, Utils::qStandardItem(QString::number(download_count)));
i++; i++;
} }
m_model->setHeaderData(0, Qt::Horizontal, tr("Filename"), Qt::DisplayRole); m_modelRig->setHeaderData(0, Qt::Horizontal, tr("Filename"), Qt::DisplayRole);
m_model->setHeaderData(1, Qt::Horizontal, tr("Date"), Qt::DisplayRole); m_modelRig->setHeaderData(1, Qt::Horizontal, tr("Date"), Qt::DisplayRole);
m_model->setHeaderData(2, Qt::Horizontal, tr("Downloads"), Qt::DisplayRole); m_modelRig->setHeaderData(2, Qt::Horizontal, tr("Downloads"), Qt::DisplayRole);
ui->tableView->verticalHeader()->setVisible(false); ui->tableRig->verticalHeader()->setVisible(false);
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows); ui->tableRig->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); ui->tableRig->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
ui->tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); ui->tableRig->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
ui->tableView->setColumnWidth(2, 100); ui->tableRig->setColumnWidth(2, 100);
} }
void XMRigWidget::showContextMenu(const QPoint &pos) { void XMRigWidget::showContextRigMenu(const QPoint &pos) {
QModelIndex index = ui->tableView->indexAt(pos); QModelIndex index = ui->tableRig->indexAt(pos);
if (!index.isValid()) { if (!index.isValid())
return; return;
} m_contextMenuRig->exec(ui->tableRig->viewport()->mapToGlobal(pos));
m_contextMenu->exec(ui->tableView->viewport()->mapToGlobal(pos));
} }
void XMRigWidget::onSoloChecked(int state) { void XMRigWidget::showContextWownerodMenu(const QPoint &pos) {
if(state == 2) { QModelIndex index = ui->tableWownerod->indexAt(pos);
ui->poolFrame->hide(); if (!index.isValid())
ui->soloFrame->show(); return;
ui->check_tls->setChecked(false); m_contextMenuRig->exec(ui->tableWownerod->viewport()->mapToGlobal(pos));
} }
else {
ui->poolFrame->show(); void XMRigWidget::wownerodLinkClicked() {
ui->soloFrame->hide(); QModelIndex index = ui->tableRig->currentIndex();
} auto download_link = m_urlsRig.at(index.row());
Utils::externalLinkWarning(this, download_link);
} }
void XMRigWidget::linkClicked() { void XMRigWidget::rigLinkClicked() {
QModelIndex index = ui->tableView->currentIndex(); QModelIndex index = ui->tableRig->currentIndex();
auto download_link = m_urls.at(index.row()); auto download_link = m_urlsRig.at(index.row());
Utils::externalLinkWarning(this, download_link); Utils::externalLinkWarning(this, download_link);
} }
QStandardItemModel *XMRigWidget::model() { QStandardItemModel *XMRigWidget::model() {
return m_model; return m_modelRig;
} }
XMRigWidget::~XMRigWidget() { XMRigWidget::~XMRigWidget() {

@ -30,33 +30,41 @@ public slots:
void onWalletOpened(Wallet *wallet); void onWalletOpened(Wallet *wallet);
void onStartClicked(); void onStartClicked();
void onStopClicked(); void onStopClicked();
void onStopped();
void onClearClicked(); void onClearClicked();
void onDownloads(const QJsonObject &data); void onBlockReward();
void linkClicked(); void onRigDownloads(const QJsonObject &data);
void onWownerodDownloads(const QJsonObject &data);
void rigLinkClicked();
void wownerodLinkClicked();
void onProcessError(const QString &msg); void onProcessError(const QString &msg);
void onProcessOutput(const QByteArray &msg); void onProcessOutput(const QByteArray &msg);
void onHashrate(const QString &hashrate); void onHashrate(const QString &hashrate);
void onSoloChecked(int state);
private slots: private slots:
void onBrowseClicked(); void onBrowseClicked();
void onThreadsValueChanged(int date); void onThreadsValueChanged(int date);
void onPoolChanged(int pos);
signals: signals:
void miningStarted(); void miningStarted();
void miningEnded(); void miningEnded();
private: private:
void showContextMenu(const QPoint &pos); void showContextRigMenu(const QPoint &pos);
void showContextWownerodMenu(const QPoint &pos);
void appendText(const QString &line);
AppContext *m_ctx; AppContext *m_ctx;
Ui::XMRigWidget *ui; Ui::XMRigWidget *ui;
QStandardItemModel *m_model; QStandardItemModel *m_modelRig;
QMenu *m_contextMenu; QStandardItemModel *m_modelWownerod;
QMenu *m_contextMenuRig;
QMenu *m_contextMenuWownerod;
int m_threads; int m_threads;
QStringList m_urls; QStringList m_urlsRig;
QStringList m_pools{"cryptonote.social:2223", "pool.hashvault.pro:8888"}; QStringList m_urlsWownerod;
unsigned int m_consoleBuffer = 0;
unsigned int m_consoleBufferMax = 2000;
}; };
#endif // REDDITWIDGET_H #endif // REDDITWIDGET_H

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1329</width> <width>959</width>
<height>540</height> <height>534</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -29,14 +29,66 @@
<item row="0" column="0"> <item row="0" column="0">
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>1</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="tab"> <widget class="QWidget" name="tab">
<attribute name="title"> <attribute name="title">
<string>Mining</string> <string>Mining</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QGridLayout" name="gridLayout_5">
<item> <item row="4" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="btn_clear">
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="check_autoscroll">
<property name="text">
<string>auto-scroll</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_status">
<property name="text">
<string>Mining at</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_stop">
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_start">
<property name="text">
<string>Start mining</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QFrame" name="outputFrame"> <widget class="QFrame" name="outputFrame">
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
@ -44,7 +96,7 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Plain</enum> <enum>QFrame::Plain</enum>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
@ -57,378 +109,189 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item row="0" column="0">
<widget class="QPlainTextEdit" name="console"> <widget class="QPlainTextEdit" name="console">
<property name="readOnly"> <property name="readOnly">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="btn_clear">
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="check_autoscroll">
<property name="text">
<string>auto-scroll</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_status">
<property name="text">
<string>Mining at</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_stop">
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_start">
<property name="text">
<string>Start mining</string>
</property>
</widget>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="2" column="0">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Executable</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="lineEdit_path">
<property name="placeholderText">
<string>Path to wownerod...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_browse">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_threads">
<property name="text">
<string>CPU threads</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QSlider" name="threadSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lbl_reward">
<property name="text">
<string>rewardtxt</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab_3"> <widget class="QWidget" name="tab_3">
<attribute name="title"> <attribute name="title">
<string>Settings</string> <string>How-To</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_9"> <layout class="QGridLayout" name="gridLayout_6">
<item> <item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_6"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>12</number>
</property>
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout_6"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_11"> <widget class="QLabel" name="lbl_logo">
<item> <property name="text">
<layout class="QVBoxLayout" name="verticalLayout"> <string>img</string>
<item> </property>
<widget class="QLabel" name="label_threads"> </widget>
<property name="text">
<string>Threads: </string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QSlider" name="threadSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item> </item>
<item> <item>
<widget class="QFrame" name="pathFrame"> <spacer name="verticalSpacer_2">
<property name="frameShape"> <property name="orientation">
<enum>QFrame::NoFrame</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="frameShadow"> <property name="sizeHint" stdset="0">
<enum>QFrame::Plain</enum> <size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>How to solo mine</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_3">
<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>
</layout>
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <widget class="QLabel" name="label">
<item> <property name="text">
<widget class="QCheckBox" name="check_tls"> <string>1. Go to the 'wownerod' tab</string>
<property name="text"> </property>
<string>TLS</string> </widget>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="relayTor">
<property name="text">
<string>Tor</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="check_solo">
<property name="text">
<string>Solo mine</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_12"> <widget class="QLabel" name="label_3">
<item> <property name="text">
<widget class="QFrame" name="poolFrame"> <string>2. Download the latest wownerod archive (right-click)</string>
<property name="frameShape"> </property>
<enum>QFrame::NoFrame</enum> </widget>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<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 row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Pool</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="combo_pools">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="soloFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<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 row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Node address</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_solo">
<property name="text">
<string>127.0.0.1:18081</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item> </item>
<item> <item>
<layout class="QFormLayout" name="formLayout"> <widget class="QLabel" name="label_6">
<item row="0" column="0"> <property name="text">
<widget class="QLabel" name="label_2"> <string>3. Unpack/extract the archive</string>
<property name="text"> </property>
<string>Receiving address</string> </widget>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_address"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Password (optional)</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_password"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>XMRig executable</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLineEdit" name="lineEdit_path">
<property name="placeholderText">
<string>/path/to/xmrig</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_browse">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item> </item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>24</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item> <item>
<widget class="QLabel" name="lbl_logo"> <widget class="QLabel" name="label_4">
<property name="text"> <property name="text">
<string>logoimg</string> <string>4. Go to the 'Mining' tab</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>5. Click 'browse' and select the previously extracted wownerod executable</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>6. Click 'Start mining' to start solo-mining. Goodluck!</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<string>P.S: Do not start multiple wownerod instances, i.e if you already have one running on your machine, things will (probably) crash and burn.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
@ -447,32 +310,85 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</item> </item>
<item> </layout>
<spacer name="verticalSpacer_3"> </widget>
<property name="orientation"> <widget class="QWidget" name="tab_4">
<enum>Qt::Vertical</enum> <attribute name="title">
<string>wownerod</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QLabel" name="label_latest_version_wownerod">
<property name="text">
<string>Latest version:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_version_2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>(right-click to download)</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QTableView" name="tableWownerod">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="editTriggers">
<size> <set>QAbstractItemView::NoEditTriggers</set>
<width>20</width>
<height>0</height>
</size>
</property> </property>
</spacer> <property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab_2"> <widget class="QWidget" name="tab_2">
<attribute name="title"> <attribute name="title">
<string>Downloads</string> <string>XMRig</string>
</attribute> </attribute>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0"> <item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_7"> <layout class="QHBoxLayout" name="horizontalLayout_7">
<item> <item>
<widget class="QLabel" name="label_latest_version"> <widget class="QLabel" name="label_latest_version_rig">
<property name="text"> <property name="text">
<string>Latest version:</string> <string>Latest version:</string>
</property> </property>
@ -494,7 +410,7 @@
</layout> </layout>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QTableView" name="tableView"> <widget class="QTableView" name="tableRig">
<property name="contextMenuPolicy"> <property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum> <enum>Qt::CustomContextMenu</enum>
</property> </property>

Loading…
Cancel
Save