Add mine-when-idle, default banlist, and console parsing improvements
Mine-when-idle: - Auto-start/stop mining based on system idle time detection - Platform::getSystemIdleSeconds() via XScreenSaver (Linux) / GetLastInputInfo (Win) - Settings: mine_when_idle toggle + configurable delay (30s–10m) - Settings page UI with checkbox and delay combo Console tab: - Shell-like argument parsing with quote and JSON bracket support - Pass JSON objects/arrays directly as RPC params - Fix selection indices when lines are evicted from buffer Connection & status bar: - Reduce RPC connect timeout to 1s for localhost fast-fail - Fast retry timer on daemon startup and external daemon detection - Show pool mining hashrate in status bar; sidebar badge reflects pool state UI polish: - Add logo to About card in settings; expose logo dimensions on App - Header title offset-y support; adjust content-area margins - Fix banned peers row cursor position (rawRowPosB.x) Branding: - Update copyright to "DragonX Developers" in RC and About section - Replace logo/icon assets with updated versions Misc: - setup.sh: checkout dragonx branch before pulling - Remove stale prebuilt-binaries/xmrig/.gitkeep
This commit is contained in:
@@ -1630,12 +1630,39 @@ void ConsoleTab::executeCommand(const std::string& cmd, rpc::RPCClient* rpc, rpc
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse command and arguments
|
||||
// Parse command and arguments (shell-like: handles quotes and JSON brackets)
|
||||
std::vector<std::string> args;
|
||||
std::istringstream iss(cmd);
|
||||
std::string token;
|
||||
while (iss >> token) {
|
||||
args.push_back(token);
|
||||
{
|
||||
size_t i = 0;
|
||||
size_t len = cmd.size();
|
||||
while (i < len) {
|
||||
// Skip whitespace
|
||||
while (i < len && (cmd[i] == ' ' || cmd[i] == '\t')) i++;
|
||||
if (i >= len) break;
|
||||
|
||||
std::string tok;
|
||||
if (cmd[i] == '"' || cmd[i] == '\'') {
|
||||
// Quoted string — collect until matching close quote
|
||||
char quote = cmd[i++];
|
||||
while (i < len && cmd[i] != quote) tok += cmd[i++];
|
||||
if (i < len) i++; // skip closing quote
|
||||
} else if (cmd[i] == '[' || cmd[i] == '{') {
|
||||
// JSON array/object — collect until matching bracket
|
||||
char open = cmd[i];
|
||||
char close = (open == '[') ? ']' : '}';
|
||||
int depth = 0;
|
||||
while (i < len) {
|
||||
if (cmd[i] == open) depth++;
|
||||
else if (cmd[i] == close) depth--;
|
||||
tok += cmd[i++];
|
||||
if (depth == 0) break;
|
||||
}
|
||||
} else {
|
||||
// Unquoted token — collect until whitespace
|
||||
while (i < len && cmd[i] != ' ' && cmd[i] != '\t') tok += cmd[i++];
|
||||
}
|
||||
if (!tok.empty()) args.push_back(tok);
|
||||
}
|
||||
}
|
||||
|
||||
if (args.empty()) return;
|
||||
@@ -1647,24 +1674,31 @@ void ConsoleTab::executeCommand(const std::string& cmd, rpc::RPCClient* rpc, rpc
|
||||
for (size_t i = 1; i < args.size(); i++) {
|
||||
const std::string& arg = args[i];
|
||||
|
||||
// Try to parse as number
|
||||
try {
|
||||
if (arg.find('.') != std::string::npos) {
|
||||
params.push_back(std::stod(arg));
|
||||
} else {
|
||||
// Check for bool
|
||||
if (arg == "true") {
|
||||
params.push_back(true);
|
||||
} else if (arg == "false") {
|
||||
params.push_back(false);
|
||||
// Try to parse as JSON first (handles objects, arrays, etc.)
|
||||
if (!arg.empty() && (arg[0] == '{' || arg[0] == '[')) {
|
||||
auto parsed = nlohmann::json::parse(arg, nullptr, false);
|
||||
if (!parsed.is_discarded()) {
|
||||
params.push_back(parsed);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to parse as number or bool
|
||||
if (arg == "true") {
|
||||
params.push_back(true);
|
||||
} else if (arg == "false") {
|
||||
params.push_back(false);
|
||||
} else {
|
||||
try {
|
||||
if (arg.find('.') != std::string::npos) {
|
||||
params.push_back(std::stod(arg));
|
||||
} else {
|
||||
// Try as integer
|
||||
params.push_back(std::stoll(arg));
|
||||
}
|
||||
} catch (...) {
|
||||
// Keep as string
|
||||
params.push_back(arg);
|
||||
}
|
||||
} catch (...) {
|
||||
// Keep as string
|
||||
params.push_back(arg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1757,9 +1791,24 @@ void ConsoleTab::addLine(const std::string& line, ImU32 color)
|
||||
|
||||
lines_.push_back({line, color});
|
||||
|
||||
// Limit buffer size
|
||||
// Limit buffer size — adjust selection indices when lines are removed
|
||||
// from the front so the highlight stays on the text the user selected.
|
||||
int popped = 0;
|
||||
while (lines_.size() > 10000) {
|
||||
lines_.pop_front();
|
||||
popped++;
|
||||
}
|
||||
if (popped > 0 && has_selection_) {
|
||||
sel_anchor_.line -= popped;
|
||||
sel_end_.line -= popped;
|
||||
if (sel_anchor_.line < 0 && sel_end_.line < 0) {
|
||||
// Entire selection was in the removed range
|
||||
has_selection_ = false;
|
||||
is_selecting_ = false;
|
||||
} else {
|
||||
if (sel_anchor_.line < 0) { sel_anchor_.line = 0; sel_anchor_.col = 0; }
|
||||
if (sel_end_.line < 0) { sel_end_.line = 0; sel_end_.col = 0; }
|
||||
}
|
||||
}
|
||||
|
||||
// Track new output while user is scrolled up
|
||||
|
||||
@@ -907,7 +907,7 @@ void RenderPeersTab(App* app)
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
}
|
||||
|
||||
ImGui::SetCursorScreenPos(ImVec2(rowPos.x, rowEnd.y));
|
||||
ImGui::SetCursorScreenPos(ImVec2(rawRowPosB.x, rowEnd.y));
|
||||
|
||||
if (i < state.bannedPeers.size() - 1) {
|
||||
ImVec2 divStart = ImGui::GetCursorScreenPos();
|
||||
|
||||
Reference in New Issue
Block a user