Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Matoking committed Oct 22, 2011
0 parents commit 155be4a
Show file tree
Hide file tree
Showing 7 changed files with 1,171 additions and 0 deletions.
18 changes: 18 additions & 0 deletions EasyMiner.pro
@@ -0,0 +1,18 @@
#-------------------------------------------------
#
# Project created by QtCreator 2011-10-14T18:13:25
#
#-------------------------------------------------

QT += core gui

TARGET = ScryptMiner GUI
TEMPLATE = app


SOURCES += main.cpp\
mainwindow.cpp

HEADERS += mainwindow.h

FORMS += mainwindow.ui
400 changes: 400 additions & 0 deletions EasyMiner.pro.user

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions README.txt
@@ -0,0 +1,33 @@
ScryptMiner-GUI
===

A simple GUI for the scrypt-based cpuminer written in C++ using Qt.

To use, copy the minerd executable to the same directory as the GUI itself, alongside with any needed libraries.
After that, just run the GUI executable.

===

LICENSING INFORMATION

===

Copyright (C) 2011 by Matoking

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
11 changes: 11 additions & 0 deletions main.cpp
@@ -0,0 +1,11 @@
#include <QtGui/QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

return a.exec();
}
327 changes: 327 additions & 0 deletions mainwindow.cpp
@@ -0,0 +1,327 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

setFixedSize(400, 420);

checkSettings();

minerActive = false;

minerProcess = new QProcess(this);
minerProcess->setProcessChannelMode(QProcess::MergedChannels);

readTimer = new QTimer(this);

acceptedShares = 0;
rejectedShares = 0;

roundAcceptedShares = 0;
roundRejectedShares = 0;

initThreads = 0;

connect(readTimer, SIGNAL(timeout()), this, SLOT(readProcessOutput()));

connect(ui->startButton, SIGNAL(pressed()), this, SLOT(startPressed()));
connect(minerProcess, SIGNAL(started()), this, SLOT(minerStarted()));
connect(minerProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(minerError(QProcess::ProcessError)));
connect(minerProcess, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(minerFinished(int, QProcess::ExitStatus)));
connect(minerProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readProcessOutput()));
}

MainWindow::~MainWindow()
{
minerProcess->kill();

saveSettings();

delete ui;
}

void MainWindow::startPressed()
{
if (minerActive == false)
{
startMining();
ui->startButton->setText("Stop Mining");
minerActive = true;
}
else
{
stopMining();
ui->startButton->setText("Start Mining");
minerActive = false;
}

}

void MainWindow::startMining()
{
QStringList args;
QString url = ui->rpcServerLine->text();
if (!url.contains("http://"))
url.prepend("http://");
qDebug(url.toAscii());
QString urlLine = QString("%1:%2").arg(url, ui->portLine->text());
QString userpassLine = QString("%1:%2").arg(ui->usernameLine->text(), ui->passwordLine->text());
args << "--algo" << "scrypt";
args << "--s" << ui->scantimeLine->text().toAscii();
args << "--url" << urlLine.toAscii();
args << "--userpass" << userpassLine.toAscii();
args << "--threads" << ui->threadsBox->currentText().toAscii();
args << "-P";

threadSpeed.clear();

acceptedShares = 0;
rejectedShares = 0;

roundAcceptedShares = 0;
roundRejectedShares = 0;

initThreads = ui->threadsBox->currentText().toInt();

QString program = "minerd";

minerProcess->start(program,args);
minerProcess->waitForStarted(-1);

readTimer->start(500);
}

void MainWindow::stopMining()
{
reportToList("Miner stopped", 0, NULL);
ui->mineSpeedLabel->setText("N/A");
ui->shareCount->setText("Accepted: 0 - Rejected: 0");
minerProcess->kill();
readTimer->stop();
}

void MainWindow::saveSettings()
{
QSettings settings("easyminer.conf", QSettings::IniFormat);

settings.setValue("threads", ui->threadsBox->currentText());
settings.setValue("scantime", ui->scantimeLine->text());
settings.setValue("url", ui->rpcServerLine->text());
settings.setValue("username", ui->usernameLine->text());
settings.setValue("password", ui->passwordLine->text());
settings.setValue("port", ui->portLine->text());

settings.sync();
}

void MainWindow::checkSettings()
{
QSettings settings("easyminer.conf", QSettings::IniFormat);
if (settings.value("threads").isValid())
{
int threads = settings.value("threads").toInt();
threads--;
ui->threadsBox->setCurrentIndex(threads);
}

if (settings.value("scantime").isValid())
ui->scantimeLine->setText(settings.value("scantime").toString());
if (settings.value("url").isValid())
ui->rpcServerLine->setText(settings.value("url").toString());
if (settings.value("username").isValid())
ui->usernameLine->setText(settings.value("username").toString());
if (settings.value("password").isValid())
ui->passwordLine->setText(settings.value("password").toString());
if (settings.value("port").isValid())
ui->portLine->setText(settings.value("port").toString());
}

void MainWindow::readProcessOutput()
{
QByteArray output;

minerProcess->reset();

output = minerProcess->readAll();

QString outputString(output);

if (!outputString.isEmpty())
{
QStringList list = outputString.split("\n");
int i;
for (i=0; i<list.size(); i++)
{
QString line = list.at(i);
if (line.contains("PROOF OF WORK RESULT: true"))
reportToList("Share accepted", SHARE_SUCCESS, getTime(line));

else if (line.contains("PROOF OF WORK RESULT: false"))
reportToList("Share rejected", SHARE_FAIL, getTime(line));

else if (line.contains("LONGPOLL detected new block"))
reportToList("LONGPOLL detected a new block", LONGPOLL, getTime(line));

else if (line.contains("Supported options:"))
reportToList("Miner didn't start properly. Try checking your settings.", FATAL_ERROR, NULL);

else if (line.contains("The requested URL returned error: 403"))
reportToList("Couldn't connect. Try checking your username and password.", ERROR, NULL);
else if (line.contains("thread ") && line.contains("khash/sec"))
{
QString threadIDstr = line.at(line.indexOf("thread ")+7);
int threadID = threadIDstr.toInt();

int threadSpeedindx = line.indexOf(",");
QString threadSpeedstr = line.mid(threadSpeedindx);
threadSpeedstr.chop(10);
threadSpeedstr.remove(", ");
threadSpeedstr.remove(" ");
threadSpeedstr.remove('\n');
double speed=0;
speed = threadSpeedstr.toDouble();
qDebug(threadSpeedstr.toAscii());

threadSpeed[threadID] = speed;

updateSpeed();
}
}
}
}


void MainWindow::minerError(QProcess::ProcessError error)
{
QString errorMessage;
switch(error)
{
case QProcess::Crashed:
errorMessage = "Miner killed";
break;

case QProcess::FailedToStart:
errorMessage = "Miner failed to start";
break;

default:
errorMessage = "Unknown error";
break;
}

reportToList(errorMessage, ERROR, NULL);

}

void MainWindow::minerFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
QString exitMessage;
switch(exitStatus)
{
case QProcess::NormalExit:
exitMessage = "Miner exited normally";

case QProcess::CrashExit:
exitMessage = "Miner exited.";

default:
exitMessage = "Miner exited abnormally.";
}
}

void MainWindow::minerStarted()
{
reportToList("Miner started. It usually takes a minute until the program starts reporting information.", STARTED, NULL);
}

void MainWindow::updateSpeed()
{
double totalSpeed=0;
int totalThreads=0;
QMapIterator<int, double> iter(threadSpeed);
while(iter.hasNext())
{
iter.next();
totalSpeed += iter.value();
totalThreads++;
}

if (totalThreads != initThreads)
{
totalSpeed = (totalSpeed/totalThreads)*initThreads;
}

QString speedString = QString("%1").arg(totalSpeed);
QString threadsString = QString("%1").arg(initThreads);

QString acceptedString = QString("%1").arg(acceptedShares);
QString rejectedString = QString("%1").arg(rejectedShares);

QString roundAcceptedString = QString("%1").arg(roundAcceptedShares);
QString roundRejectedString = QString("%1").arg(roundRejectedShares);

if (totalThreads == initThreads)
ui->mineSpeedLabel->setText(QString("%1 khash/sec - %2 thread(s)").arg(speedString, threadsString));
else
ui->mineSpeedLabel->setText(QString("~%1 khash/sec - %2 thread(s)").arg(speedString, threadsString));

ui->shareCount->setText(QString("Accepted: %1 (%3) - Rejected: %2 (%4)").arg(acceptedString, rejectedString, roundAcceptedString, roundRejectedString));
}

void MainWindow::reportToList(QString msg, int type, QString time)
{
QString message;
if (time == NULL)
message = QString("[%1] - %2").arg(QTime::currentTime().toString(), msg);
else
message = QString("[%1] - %2").arg(time, msg);

switch(type)
{
case SHARE_SUCCESS:
acceptedShares++;
roundAcceptedShares++;
updateSpeed();
break;

case SHARE_FAIL:
rejectedShares++;
roundRejectedShares++;
updateSpeed();
break;

case FATAL_ERROR:
startPressed();
break;

case LONGPOLL:
roundAcceptedShares = 0;
roundRejectedShares = 0;
break;

default:
break;
}

ui->list->addItem(message);
ui->list->scrollToBottom();
}

QString MainWindow::getTime(QString time)
{
if (time.contains("["))
{
time.resize(21);
time.remove("[");
time.remove("]");
time.remove(1,11);

return time;
}
else
return NULL;
}

0 comments on commit 155be4a

Please sign in to comment.