diff --git a/appveyor.yml b/appveyor.yml index cc7cbb2c..c7af5ae5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -28,10 +28,11 @@ build_script: - cmake -G "Visual Studio 15 2017 Win64" -T v141,host=x64 .. - msbuild xmrig.sln /p:Configuration=Release + after_build: - cd c:\xmrigCC -- cmd: 7z a xmrigCC-win64.zip "c:\xmrigCC\build\Release\*.*" "c:\xmrigCC\src\*config*" "c:\xmrigCC\index.html" +- cmd: 7z a xmrigCC-mvc-win64.zip "c:\xmrigCC\build\Release\*.*" "c:\xmrigCC\src\*config*" "c:\xmrigCC\index.html" - cmd: dir artifacts: -- path: xmrigCC-win64.zip +- path: xmrigCC-mvc-win64.zip diff --git a/index.html b/index.html index e4c09bf2..88048abf 100644 --- a/index.html +++ b/index.html @@ -27,19 +27,14 @@ $.fn.dataTable.ext.search.push( function( settings, data, dataIndex ) { var hide = document.getElementById("hideOffline").checked; - var lastStatus = settings.aoData[dataIndex]._aData.client_status.last_status_update * 1000; - var threshold = new Date().getTime() - 60 * 1000; - - if (lastStatus > threshold || !hide) { - return true; - } - else { - return false; - } + return (isOnline(settings.aoData[dataIndex]._aData.client_status.last_status_update * 1000) || !hide); } ); $(document).ready(function() { + + var latestRelease = ""; + var table = $('#clientStatusList').DataTable({ dom: '<"toolbar">frtip', processing : true, @@ -80,63 +75,35 @@ $(document).ready(function() { "footerCallback": function ( row, data, start, end, display ) { var api = this.api(); - sumHashrateShort = round(api - .column(4) - .data() - .reduce( function (a, b) { - return a + b; - }, 0 )); + var sumHashrateShort = 0; + var sumHashrateMedium = 0; + var sumHashrateLong = 0; + var sumHashrateHighest = 0; + var sumHashesTotal = 0; + var avgTimeTotal = 0; + var sumSharesGood = 0; + var sumSharedTotal = 0; - sumHashrateMedium = round(api - .column(5) - .data() - .reduce( function (a, b) { - return a + b; - }, 0 )); + for (var i = 0; i < data.length; ++i) { + if (isOnline(data[i].client_status.last_status_update * 1000)) { + sumHashrateShort += data[i].client_status.hashrate_short; + sumHashrateMedium += data[i].client_status.hashrate_medium; + sumHashrateLong += data[i].client_status.hashrate_long; + sumHashrateHighest += data[i].client_status.hashrate_highest; + sumHashesTotal += data[i].client_status.hashes_total; + avgTimeTotal = (avgTimeTotal + data[i].client_status.avg_time) / 2; + sumSharesGood += data[i].client_status.shares_good; + sumSharedTotal += data[i].client_status.shares_total; + } + } - sumHashrateLong = round(api - .column(6) - .data() - .reduce( function (a, b) { - return a + b; - }, 0 )); + sumHashrateShort = round(sumHashrateShort); + sumHashrateMedium = round(sumHashrateMedium); + sumHashrateLong = round(sumHashrateLong); + sumHashrateHighest = round(sumHashrateHighest); + avgTimeTotal = round(avgTimeTotal); - sumHashrateHighest = round(api - .column(7) - .data() - .reduce( function (a, b) { - return a + b; - }, 0 )); - - sumHashesTotal = api - .column(8) - .data() - .reduce( function (a, b) { - return a + b; - }, 0 ); - - avgTimeTotal = round(api - .column(9) - .data() - .reduce( function (a, b) { - return a + b; - }, 0 )/end); - - sumSharesGood = api - .column(10) - .data() - .reduce( function (a, b) { - return a + b; - }, 0 ); - - sumSharedTotal = api - .column(11) - .data() - .reduce( function (a, b) { - return a + b; - }, 0 ); - - // Update footer + // update footer $(api.column(4).footer()).html(sumHashrateShort); $(api.column(5).footer()).html(sumHashrateMedium); $(api.column(6).footer()).html(sumHashrateLong); @@ -145,6 +112,24 @@ $(document).ready(function() { $(api.column(9).footer()).html(avgTimeTotal); $(api.column(10).footer()).html(sumSharesGood); $(api.column(11).footer()).html(sumSharedTotal); + + // check version + if (latestRelease === "" && $(api).context[0].json !== undefined) { + $.ajax({ + url: "https://api.github.com/repos/Bendr0id/xmrigCC/releases/latest", + type: 'GET', + dataType: "json", + success: function (release) { + latestRelease = release.tag_name; + if (latestRelease !== $(api).context[0].json.current_version) { + $("#notificationBar").html('
' + + '×' + + 'Update! XMRigCC v' + latestRelease + ' is available for download\n' + + '
'); + } + } + }); + } } }); @@ -232,26 +217,27 @@ function laststatus( data, type, row ) { function clientInfo( data, type, row ) { if (type !== 'sort') { - var tooltip = "CPU: " + row.client_status.cpu_brand + " [" + row.client_status.cpu_cores + " cores]"; - tooltip += '\n'; - tooltip += "CPU Flags: " + (row.client_status.cpu_has_aes ? "AES-NI " : ""); - tooltip += (row.client_status.cpu_is_x64 ? "x64" : ""); - tooltip += '\n'; - tooltip += "CPU Cache L2/L3: " + (row.client_status.cpu_l2 / 1024) + " MB/"+ (row.client_status.cpu_l3 / 1024) + " MB"; - tooltip += '\n'; - tooltip += "Huge Pages: " + (row.client_status.hugepages_available ? " available, " : " unavailable, "); - tooltip += (row.client_status.hugepages_enabled ? "enabled" : "disabled"); - tooltip += '\n'; - tooltip += "Used Threads: " + row.client_status.current_threads; - tooltip += (row.client_status.double_hash_mode ? " [double hash mode]" :""); - tooltip += '\n'; - tooltip += "Client IP: " + row.client_status.external_ip; - tooltip += '\n'; - tooltip += "Status: "; + var tooltip = "CPU: " + row.client_status.cpu_brand + " [" + row.client_status.cpu_cores + " cores]"; + tooltip += '\n'; + tooltip += "CPU Flags: " + (row.client_status.cpu_has_aes ? "AES-NI " : ""); + tooltip += (row.client_status.cpu_is_x64 ? "x64" : ""); + tooltip += '\n'; + tooltip += "CPU Cache L2/L3: " + (row.client_status.cpu_l2 / 1024) + " MB/"+ (row.client_status.cpu_l3 / 1024) + " MB"; + tooltip += '\n'; + tooltip += "Huge Pages: " + (row.client_status.hugepages_available ? " available, " : " unavailable, "); + tooltip += (row.client_status.hugepages_enabled ? "enabled" : "disabled"); + tooltip += '\n'; + tooltip += "Used Threads: " + row.client_status.current_threads; + tooltip += (row.client_status.double_hash_mode ? " [double hash mode]" :""); + tooltip += '\n'; + tooltip += "Client IP: " + row.client_status.external_ip; + tooltip += '\n'; + tooltip += "Version: " + row.client_status.version; + tooltip += '\n'; + tooltip += "Status: "; var lastStatus = row.client_status.last_status_update * 1000; - var threshold = new Date().getTime() - 60 * 1000; - if (lastStatus > threshold) { + if (isOnline(lastStatus)) { tooltip += "Online"; return '
' + data + '
'; } @@ -268,12 +254,22 @@ function round( data, type, row ) { return Math.round(data * 100) / 100; } +function isOnline(lastStatus) { + var threshold = new Date().getTime() - 60 * 1000; + if (lastStatus > threshold) { + return true; + } else { + return false; + } +} +
+

XMRigCC Dashboard

diff --git a/src/cc/CCClient.cpp b/src/cc/CCClient.cpp index cf059eed..30c672bd 100644 --- a/src/cc/CCClient.cpp +++ b/src/cc/CCClient.cpp @@ -25,6 +25,7 @@ #include #include <3rdparty/rapidjson/stringbuffer.h> #include <3rdparty/rapidjson/prettywriter.h> +#include #include "CCClient.h" #include "App.h" @@ -41,16 +42,18 @@ #if _WIN32 # include "winsock2.h" #else + # include "unistd.h" + #endif -CCClient *CCClient::m_self = nullptr; +CCClient* CCClient::m_self = nullptr; uv_mutex_t CCClient::m_mutex; CCClient::CCClient(Options* options, uv_async_t* async) - : m_options(options), - m_async(async) + : m_options(options), + m_async(async) { uv_mutex_init(&m_mutex); @@ -59,10 +62,10 @@ CCClient::CCClient(Options* options, uv_async_t* async) std::string clientId; if (m_options->ccWorkerId()) { clientId = m_options->ccWorkerId(); - } else{ + } else { char hostname[128]; memset(hostname, 0, sizeof(hostname)); - gethostname(hostname, sizeof(hostname)-1); + gethostname(hostname, sizeof(hostname) - 1); clientId = std::string(hostname); } @@ -76,6 +79,7 @@ CCClient::CCClient(Options* options, uv_async_t* async) m_clientStatus.setHugepages(Mem::isHugepagesAvailable()); m_clientStatus.setDoubleHashMode(Mem::isDoubleHash()); + m_clientStatus.setVersion(Version::string()); m_clientStatus.setCpuBrand(Cpu::brand()); m_clientStatus.setCpuAES(Cpu::hasAES()); m_clientStatus.setCpuCores(Cpu::cores()); @@ -98,7 +102,7 @@ CCClient::~CCClient() m_self = nullptr; } -void CCClient::updateHashrate(const Hashrate *hashrate) +void CCClient::updateHashrate(const Hashrate* hashrate) { if (m_self) { uv_mutex_lock(&m_mutex); @@ -113,7 +117,7 @@ void CCClient::updateHashrate(const Hashrate *hashrate) } -void CCClient::updateNetworkState(const NetworkState &network) +void CCClient::updateNetworkState(const NetworkState& network) { if (m_self) { uv_mutex_lock(&m_mutex); @@ -139,7 +143,7 @@ void CCClient::publishClientStatusReport() LOG_ERR("[CC-Client] error: unable to performRequest POST -> http://%s:%d%s", m_self->m_options->ccHost(), m_self->m_options->ccPort(), requestUrl.c_str()); } else if (res->status != 200) { - LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status, m_self->m_options->ccHost(), + LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status, m_self->m_options->ccHost(), m_self->m_options->ccPort(), requestUrl.c_str()); } else { ControlCommand controlCommand; @@ -161,7 +165,7 @@ void CCClient::publishClientStatusReport() LOG_WARN("[CC-Client] Command: SHUTDOWN received -> shutdown"); } - m_self->m_async->data = reinterpret_cast(controlCommand.getCommand()); + m_self->m_async->data = reinterpret_cast(controlCommand.getCommand()); uv_async_send(m_self->m_async); } else { LOG_ERR("[CC-Client] Unknown command received from CC Server."); @@ -179,7 +183,7 @@ void CCClient::updateConfig() LOG_ERR("[CC-Client] error: unable to performRequest GET -> http://%s:%d%s", m_self->m_options->ccHost(), m_self->m_options->ccPort(), requestUrl.c_str()); } else if (res->status != 200) { - LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status, m_self->m_options->ccHost(), + LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status, m_self->m_options->ccHost(), m_self->m_options->ccPort(), requestUrl.c_str()); } else { rapidjson::Document document; @@ -198,7 +202,7 @@ void CCClient::updateConfig() } else { LOG_ERR("[CC-Client] Not able to store client config to file %s.", m_self->m_options->configFile()); } - } else{ + } else { LOG_ERR("[CC-Client] Not able to store client config. received client config is broken!"); } } @@ -244,7 +248,7 @@ void CCClient::onThreadStarted(void* handle) uv_run(&m_self->m_client_loop, UV_RUN_DEFAULT); } -void CCClient::onReport(uv_timer_t *handle) +void CCClient::onReport(uv_timer_t* handle) { if (m_self) { m_self->publishClientStatusReport(); diff --git a/src/cc/ClientStatus.cpp b/src/cc/ClientStatus.cpp index d8126c2e..491800e5 100644 --- a/src/cc/ClientStatus.cpp +++ b/src/cc/ClientStatus.cpp @@ -115,6 +115,16 @@ void ClientStatus::setExternalIp(const std::string& externalIp) m_externalIp = externalIp; } +std::string ClientStatus::getVersion() const +{ + return m_version; +} + +void ClientStatus::setVersion(const std::string& version) +{ + m_version = version; +} + bool ClientStatus::hasHugepages() const { return m_hasHugepages; @@ -321,6 +331,10 @@ bool ClientStatus::parseFromJson(const rapidjson::Document& document) m_externalIp = clientStatus["external_ip"].GetString(); } + if (clientStatus.HasMember("version")) { + m_version = clientStatus["version"].GetString(); + } + if (clientStatus.HasMember("hugepages_available")) { m_hasHugepages = clientStatus["hugepages_available"].GetBool(); } @@ -411,6 +425,7 @@ rapidjson::Value ClientStatus::toJson(rapidjson::MemoryPoolAllocator #include <3rdparty/rapidjson/error/en.h> #include <3rdparty/rapidjson/prettywriter.h> +#include #include "log/Log.h" #include "Service.h" @@ -194,6 +195,7 @@ unsigned Service::getClientStatusList(std::string& resp) clientStatusList.PushBack(clientStatusEntry, allocator); } + document.AddMember("current_version", rapidjson::StringRef(Version::string().c_str()), allocator); document.AddMember("client_status_list", clientStatusList, allocator); rapidjson::StringBuffer buffer(0, 4096); diff --git a/src/version.h b/src/version.h index 8ffebafc..ec19a1b5 100644 --- a/src/version.h +++ b/src/version.h @@ -36,14 +36,14 @@ #define APP_DESC "XMRigCC CPU miner" #define APP_COPYRIGHT "Copyright (C) 2017- BenDr0id" #endif -#define APP_VERSION "1.1.0 (based on XMRig 2.4.2)" +#define APP_VERSION "1.1.1 (based on XMRig 2.4.2)" #define APP_DOMAIN "" #define APP_SITE "https://github.com/Bendr0id/xmrigCC" #define APP_KIND "cpu" #define APP_VER_MAJOR 1 #define APP_VER_MINOR 1 -#define APP_VER_BUILD 0 +#define APP_VER_BUILD 1 #define APP_VER_REV 0 #ifdef _MSC_VER @@ -62,4 +62,24 @@ # endif #endif +#include + +class Version +{ +public: + inline static std::string string() + { + std::string version = std::to_string(APP_VER_MAJOR) + std::string(".") + std::to_string(APP_VER_MINOR) + + std::string(".") + std::to_string(APP_VER_BUILD); + + return version; + } + + inline static int code() + { + std::string version = std::to_string(APP_VER_MAJOR) + std::to_string(APP_VER_MINOR) + std::to_string(APP_VER_BUILD); + + return std::stoi(version); + } +}; #endif /* __VERSION_H__ */