mirror of
https://github.com/Cyrix126/gupaxx.git
synced 2024-12-22 14:49:21 +00:00
connect functions with [State/state.rs]
This commit is contained in:
parent
dafb8fc18e
commit
ed7ddeeda1
7 changed files with 273 additions and 361 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1085,6 +1085,7 @@ dependencies = [
|
||||||
"monero",
|
"monero",
|
||||||
"num-format",
|
"num-format",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
|
"rand",
|
||||||
"regex",
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
| `main.rs` | Struct/enum/impl for `App/Tab/State`, init functions, main function
|
| `main.rs` | Struct/enum/impl for `App/Tab/State`, init functions, main function
|
||||||
| `node.rs` | Struct/impl for Community Nodes
|
| `node.rs` | Struct/impl for Community Nodes
|
||||||
| `p2pool.rs` | Struct/impl for `P2Pool` tab
|
| `p2pool.rs` | Struct/impl for `P2Pool` tab
|
||||||
|
| `state.rs` | Struct/impl for `gupax.toml`, the disk state
|
||||||
| `status.rs` | Struct/impl for `Status` tab
|
| `status.rs` | Struct/impl for `Status` tab
|
||||||
| `toml.rs` | Struct/impl for `gupax.toml`, the disk state
|
|
||||||
| `xmrig.rs` | Struct/impl for `XMRig` tab
|
| `xmrig.rs` | Struct/impl for `XMRig` tab
|
||||||
|
|
||||||
## Bootstrap
|
## Bootstrap
|
||||||
|
@ -42,7 +42,7 @@ This is how Gupax works internally when starting up, divided into 3 sections.
|
||||||
- Kill processes, kill connections, exit
|
- Kill processes, kill connections, exit
|
||||||
|
|
||||||
## State
|
## State
|
||||||
Internal state is saved in the "OS data folder" as `gupax.toml`, using the [TOML](https://github.com/toml-lang/toml) format. If the version can't be parsed (not in the `vX.X.X` or `vX.X` format), the auto-updater will be skipped. [If not found, a default `gupax.toml` file will be created with `Toml::default`.](https://github.com/hinto-janaiyo/gupax/blob/main/src/toml.rs) Gupax will `panic!` if `gupax.toml` has IO or parsing issues.
|
Internal state is saved in the "OS data folder" as `gupax.toml`, using the [TOML](https://github.com/toml-lang/toml) format. If the version can't be parsed (not in the `vX.X.X` or `vX.X` format), the auto-updater will be skipped. [If not found, a default `gupax.toml` file will be created with `State::default`.](https://github.com/hinto-janaiyo/gupax/blob/main/src/state.rs) Gupax will `panic!` if `gupax.toml` has IO or parsing issues.
|
||||||
|
|
||||||
| OS | Data Folder | Example |
|
| OS | Data Folder | Example |
|
||||||
|----------|----------------------------------------- |-----------------------------------------------------------|
|
|----------|----------------------------------------- |-----------------------------------------------------------|
|
||||||
|
|
267
src/main.rs
267
src/main.rs
|
@ -16,135 +16,98 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
|
||||||
use eframe::{egui,NativeOptions};
|
|
||||||
use egui::{Vec2,Pos2};
|
|
||||||
use std::process::exit;
|
|
||||||
use std::thread;
|
|
||||||
use egui::color::Color32;
|
|
||||||
use egui::Stroke;
|
|
||||||
use egui::FontId;
|
|
||||||
use egui::FontFamily::Proportional;
|
|
||||||
use egui::TextStyle::{Body,Button,Heading,Monospace,Name,Small};
|
|
||||||
use egui::RichText;
|
|
||||||
use egui::Label;
|
|
||||||
use regex::Regex;
|
|
||||||
use egui_extras::RetainedImage;
|
|
||||||
use log::*;
|
|
||||||
use env_logger::Builder;
|
|
||||||
use env_logger::WriteStyle;
|
|
||||||
use std::io::Write;
|
|
||||||
use std::time::Instant;
|
|
||||||
use std::sync::{Arc,Mutex};
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------- Imports
|
||||||
|
// egui/eframe
|
||||||
|
use egui::TextStyle::*;
|
||||||
|
use egui::color::Color32;
|
||||||
|
use egui::FontFamily::Proportional;
|
||||||
|
use egui::{FontId,Label,RichText,Stroke,Vec2,Pos2};
|
||||||
|
use egui_extras::RetainedImage;
|
||||||
|
use eframe::{egui,NativeOptions};
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
use log::*;
|
||||||
|
use env_logger::{Builder,WriteStyle};
|
||||||
|
|
||||||
|
// std
|
||||||
|
use std::io::Write;
|
||||||
|
use std::process::exit;
|
||||||
|
use std::sync::{Arc,Mutex};
|
||||||
|
use std::thread;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
// Modules
|
||||||
mod constants;
|
mod constants;
|
||||||
mod node;
|
mod node;
|
||||||
mod toml;
|
mod state;
|
||||||
mod about;
|
mod about;
|
||||||
mod status;
|
mod status;
|
||||||
mod gupax;
|
mod gupax;
|
||||||
mod p2pool;
|
mod p2pool;
|
||||||
mod xmrig;
|
mod xmrig;
|
||||||
use {constants::*,node::*,crate::toml::*,about::*,status::*,gupax::*,p2pool::*,xmrig::*};
|
use {constants::*,node::*,state::*,about::*,status::*,gupax::*,p2pool::*,xmrig::*};
|
||||||
|
|
||||||
// The state of the outer [App].
|
//---------------------------------------------------------------------------------------------------- Struct + Impl
|
||||||
// See the [State] struct for the
|
// The state of the outer main [App].
|
||||||
// actual inner state of the settings.
|
// See the [State] struct in [state.rs] for the
|
||||||
|
// actual inner state of the tab settings.
|
||||||
pub struct App {
|
pub struct App {
|
||||||
|
// Misc state
|
||||||
|
tab: Tab, // What tab are we on?
|
||||||
|
quit: bool, // Did user click quit button?
|
||||||
|
quit_confirm: bool, // Did user confirm to quit?
|
||||||
|
ping: bool, // Did user click the ping button?
|
||||||
|
ping_prog: Arc<Mutex<bool>>, // Are we in the progress of pinging?
|
||||||
|
node: Arc<Mutex<NodeStruct>>, // Data on community nodes
|
||||||
|
// State:
|
||||||
|
// og = Old state to compare against
|
||||||
|
// state = Working state (current settings)
|
||||||
|
// Instead of comparing [og == state] every frame,
|
||||||
|
// the [diff] bool will be the signal for [Reset/Save].
|
||||||
|
og: State,
|
||||||
|
state: State,
|
||||||
|
diff: bool,
|
||||||
|
// Static stuff
|
||||||
|
now: Instant,
|
||||||
|
resolution: Vec2,
|
||||||
|
os: &'static str,
|
||||||
version: String,
|
version: String,
|
||||||
name_version: String,
|
name_version: String,
|
||||||
tab: Tab,
|
|
||||||
changed: bool,
|
|
||||||
os: &'static str,
|
|
||||||
current_threads: u16,
|
|
||||||
max_threads: u16,
|
|
||||||
resolution: Vec2,
|
|
||||||
banner: RetainedImage,
|
banner: RetainedImage,
|
||||||
|
|
||||||
|
// TEMPORARY FIXME
|
||||||
p2pool: bool,
|
p2pool: bool,
|
||||||
xmrig: bool,
|
xmrig: bool,
|
||||||
state: State,
|
|
||||||
og: State,
|
|
||||||
allowed_to_close: bool,
|
|
||||||
show_confirmation_dialog: bool,
|
|
||||||
now: Instant,
|
|
||||||
ping: bool,
|
|
||||||
ping_prog: Arc<Mutex<bool>>,
|
|
||||||
node: Arc<Mutex<NodeStruct>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
fn new(cc: &eframe::CreationContext<'_>) -> Self {
|
fn new(cc: &eframe::CreationContext<'_>) -> Self {
|
||||||
let version = String::from("v0.0.1");
|
|
||||||
let name_version = String::from("Gupax v0.0.1");
|
|
||||||
let tab = Tab::default();
|
|
||||||
let max_threads = num_cpus::get().try_into().unwrap();
|
|
||||||
let current_threads: u16;
|
|
||||||
let changed = false;
|
|
||||||
let os = OS;
|
|
||||||
if max_threads != 1 {
|
|
||||||
current_threads = max_threads / 2
|
|
||||||
} else {
|
|
||||||
current_threads = 1
|
|
||||||
}
|
|
||||||
let resolution = cc.integration_info.window_info.size;
|
|
||||||
init_text_styles(&cc.egui_ctx, resolution[0] as f32);
|
|
||||||
let banner = match RetainedImage::from_image_bytes("banner.png", BYTES_BANNER) {
|
|
||||||
Ok(banner) => { info!("Banner loading ... OK"); banner },
|
|
||||||
Err(err) => { error!("{}", err); panic!("{}", err); },
|
|
||||||
};
|
|
||||||
let mut state = State::new();
|
|
||||||
let mut og = State::new();
|
|
||||||
info!("Frame resolution ... {:#?}", resolution);
|
|
||||||
Self {
|
Self {
|
||||||
version,
|
tab: Tab::default(),
|
||||||
name_version,
|
quit: false,
|
||||||
tab,
|
quit_confirm: false,
|
||||||
current_threads,
|
|
||||||
max_threads,
|
|
||||||
changed,
|
|
||||||
resolution,
|
|
||||||
os,
|
|
||||||
banner,
|
|
||||||
p2pool: false,
|
|
||||||
xmrig: false,
|
|
||||||
state,
|
|
||||||
og,
|
|
||||||
allowed_to_close: false,
|
|
||||||
show_confirmation_dialog: false,
|
|
||||||
now: Instant::now(),
|
|
||||||
node: Arc::new(Mutex::new(NodeStruct::default())),
|
|
||||||
ping: false,
|
ping: false,
|
||||||
ping_prog: Arc::new(Mutex::new(false)),
|
ping_prog: Arc::new(Mutex::new(false)),
|
||||||
|
node: Arc::new(Mutex::new(NodeStruct::default())),
|
||||||
|
og: State::default(),
|
||||||
|
state: State::default(),
|
||||||
|
diff: false,
|
||||||
|
now: Instant::now(),
|
||||||
|
resolution: cc.integration_info.window_info.size,
|
||||||
|
os: OS,
|
||||||
|
version: "v0.0.1".to_string(),
|
||||||
|
name_version: "Gupax v0.0.1".to_string(),
|
||||||
|
banner: RetainedImage::from_image_bytes("banner.png", BYTES_BANNER).expect("oops"),
|
||||||
|
|
||||||
|
// TEMPORARY FIXME
|
||||||
|
p2pool: false,
|
||||||
|
xmrig: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inner state holding all
|
//---------------------------------------------------------------------------------------------------- Enum + Impl
|
||||||
// mutable tab structs.
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
||||||
struct State {
|
|
||||||
gupax: Gupax,
|
|
||||||
p2pool: P2pool,
|
|
||||||
xmrig: Xmrig,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl State {
|
|
||||||
fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
gupax: Gupax::new(),
|
|
||||||
p2pool: P2pool::new(),
|
|
||||||
xmrig: Xmrig::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn save(new: State) -> Self {
|
|
||||||
Self {
|
|
||||||
gupax: new.gupax,
|
|
||||||
p2pool: new.p2pool,
|
|
||||||
xmrig: new.xmrig,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The tabs inside [App].
|
// The tabs inside [App].
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
enum Tab {
|
enum Tab {
|
||||||
|
@ -154,12 +117,14 @@ enum Tab {
|
||||||
P2pool,
|
P2pool,
|
||||||
Xmrig,
|
Xmrig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Tab {
|
impl Default for Tab {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::About
|
Self::About
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------- Init functions
|
||||||
fn init_text_styles(ctx: &egui::Context, width: f32) {
|
fn init_text_styles(ctx: &egui::Context, width: f32) {
|
||||||
let scale = width / 26.666;
|
let scale = width / 26.666;
|
||||||
let mut style = (*ctx.style()).clone();
|
let mut style = (*ctx.style()).clone();
|
||||||
|
@ -230,23 +195,7 @@ fn init_options() -> NativeOptions {
|
||||||
options
|
options
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
//---------------------------------------------------------------------------------------------------- [App] frame for [Panic] situations
|
||||||
init_logger();
|
|
||||||
let toml = match Toml::get() {
|
|
||||||
Ok(toml) => toml,
|
|
||||||
Err(err) => {
|
|
||||||
error!("{}", err);
|
|
||||||
let error_msg = err.to_string();
|
|
||||||
let options = Panic::options();
|
|
||||||
eframe::run_native("Gupax", options, Box::new(|cc| Box::new(Panic::new(cc, error_msg))),);
|
|
||||||
exit(1);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
let options = init_options();
|
|
||||||
eframe::run_native("Gupax", options, Box::new(|cc| Box::new(App::new(cc))),);
|
|
||||||
}
|
|
||||||
|
|
||||||
// [App] frame for Panic situations.
|
|
||||||
struct Panic { error_msg: String, }
|
struct Panic { error_msg: String, }
|
||||||
impl Panic {
|
impl Panic {
|
||||||
fn options() -> NativeOptions {
|
fn options() -> NativeOptions {
|
||||||
|
@ -288,15 +237,35 @@ impl eframe::App for Panic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------- Main [App] frame
|
||||||
|
fn main() {
|
||||||
|
init_logger();
|
||||||
|
// let toml = match State::get() {
|
||||||
|
// Ok(toml) => toml,
|
||||||
|
// Err(err) => {
|
||||||
|
// error!("{}", err);
|
||||||
|
// let error_msg = err.to_string();
|
||||||
|
// let options = Panic::options();
|
||||||
|
// eframe::run_native("Gupax", options, Box::new(|cc| Box::new(Panic::new(cc, error_msg))),);
|
||||||
|
// exit(1);
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
let state = State::default();
|
||||||
|
let options = init_options();
|
||||||
|
eframe::run_native("Gupax", options, Box::new(|cc| Box::new(App::new(cc))),);
|
||||||
|
}
|
||||||
|
|
||||||
impl eframe::App for App {
|
impl eframe::App for App {
|
||||||
fn on_close_event(&mut self) -> bool {
|
fn on_close_event(&mut self) -> bool {
|
||||||
// self.show_confirmation_dialog = true;
|
self.quit = true;
|
||||||
self.ping = true;
|
self.quit_confirm
|
||||||
self.allowed_to_close
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
|
fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
|
||||||
|
init_text_styles(ctx, 1280.0);
|
||||||
|
|
||||||
// Close confirmation.
|
// Close confirmation.
|
||||||
if self.show_confirmation_dialog {
|
if self.quit {
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
let width = ui.available_width();
|
let width = ui.available_width();
|
||||||
let width = width - 10.0;
|
let width = width - 10.0;
|
||||||
|
@ -306,10 +275,10 @@ impl eframe::App for App {
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
if ui.add_sized([width, height/10.0], egui::Button::new("Yes")).clicked() {
|
if ui.add_sized([width, height/10.0], egui::Button::new("Yes")).clicked() {
|
||||||
info!("Quit confirmation = yes ... goodbye!");
|
info!("Quit confirmation = yes ... goodbye!");
|
||||||
exit(0);
|
self.quit_confirm = true;
|
||||||
|
frame.close();
|
||||||
} else if ui.add_sized([width, height/10.0], egui::Button::new("No")).clicked() {
|
} else if ui.add_sized([width, height/10.0], egui::Button::new("No")).clicked() {
|
||||||
info!("Quit confirmation = no ... returning!");
|
self.quit = false;
|
||||||
self.show_confirmation_dialog = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -329,25 +298,25 @@ impl eframe::App for App {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if *self.ping_prog.lock().unwrap() {
|
// if *self.ping_prog.lock().unwrap() {
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
// egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
let width = ui.available_width();
|
// let width = ui.available_width();
|
||||||
let width = width - 10.0;
|
// let width = width - 10.0;
|
||||||
let height = ui.available_height();
|
// let height = ui.available_height();
|
||||||
init_text_styles(ctx, width);
|
// init_text_styles(ctx, width);
|
||||||
ui.add_sized([width, height/2.0], Label::new(format!("In progress: {}", *self.ping_prog.lock().unwrap())));
|
// ui.add_sized([width, height/2.0], Label::new(format!("In progress: {}", *self.ping_prog.lock().unwrap())));
|
||||||
ui.group(|ui| {
|
// ui.group(|ui| {
|
||||||
if ui.add_sized([width, height/10.0], egui::Button::new("Yes")).clicked() {
|
// if ui.add_sized([width, height/10.0], egui::Button::new("Yes")).clicked() {
|
||||||
info!("Quit confirmation = yes ... goodbye!");
|
// info!("Quit confirmation = yes ... goodbye!");
|
||||||
exit(0);
|
// exit(0);
|
||||||
} else if ui.add_sized([width, height/10.0], egui::Button::new("No")).clicked() {
|
// } else if ui.add_sized([width, height/10.0], egui::Button::new("No")).clicked() {
|
||||||
info!("Quit confirmation = no ... returning!");
|
// info!("Quit confirmation = no ... returning!");
|
||||||
self.show_confirmation_dialog = false;
|
// self.show_confirmation_dialog = false;
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Top: Tabs
|
// Top: Tabs
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
|
@ -390,6 +359,9 @@ impl eframe::App for App {
|
||||||
ui.add_sized([width, height], Label::new(self.os));
|
ui.add_sized([width, height], Label::new(self.os));
|
||||||
ui.separator();
|
ui.separator();
|
||||||
ui.add_sized([width/1.5, height], Label::new("P2Pool"));
|
ui.add_sized([width/1.5, height], Label::new("P2Pool"));
|
||||||
|
// TODO
|
||||||
|
// self.p2pool + self.xmrig
|
||||||
|
// This is for process online/offline status
|
||||||
if self.p2pool == true {
|
if self.p2pool == true {
|
||||||
ui.add_sized([width/4.0, height], Label::new(RichText::new("⏺").color(Color32::from_rgb(100, 230, 100))));
|
ui.add_sized([width/4.0, height], Label::new(RichText::new("⏺").color(Color32::from_rgb(100, 230, 100))));
|
||||||
} else {
|
} else {
|
||||||
|
@ -469,7 +441,8 @@ impl eframe::App for App {
|
||||||
Status::show(self, ctx, ui);
|
Status::show(self, ctx, ui);
|
||||||
}
|
}
|
||||||
Tab::Gupax => {
|
Tab::Gupax => {
|
||||||
Gupax::show(&mut self.state.gupax, ctx, ui);
|
// Gupax::show(self.state.gupax, ctx, ui);
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
Tab::P2pool => {
|
Tab::P2pool => {
|
||||||
P2pool::show(&mut self.state.p2pool, ctx, ui);
|
P2pool::show(&mut self.state.p2pool, ctx, ui);
|
||||||
|
|
12
src/node.rs
12
src/node.rs
|
@ -55,12 +55,18 @@ pub struct Data {
|
||||||
pub ip: String,
|
pub ip: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy,Clone,Debug,Deserialize,Serialize)]
|
#[derive(Copy,Clone,Eq,PartialEq,Debug,Deserialize,Serialize)]
|
||||||
pub enum NodeEnum {
|
pub enum NodeEnum {
|
||||||
C3pool, Cake, CakeEu, CakeUk, CakeUs, Monerujo, Rino,
|
C3pool, Cake, CakeEu, CakeUk, CakeUs, Monerujo, Rino,
|
||||||
Selsta, Seth, SupportXmr, SupportXmrIr, XmrVsBeast,
|
Selsta, Seth, SupportXmr, SupportXmrIr, XmrVsBeast,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for NodeEnum {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(f, "{:#?}", self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PingResult {
|
pub struct PingResult {
|
||||||
pub node: NodeStruct,
|
pub node: NodeStruct,
|
||||||
|
@ -146,7 +152,7 @@ impl NodeStruct {
|
||||||
};
|
};
|
||||||
let mut timeout = false;
|
let mut timeout = false;
|
||||||
let mut mid = Duration::new(0, 0);
|
let mut mid = Duration::new(0, 0);
|
||||||
let max = rng::thread_rng().gen_range(1..5);
|
let max = rand::thread_rng().gen_range(1..5);
|
||||||
for i in 1..=max {
|
for i in 1..=max {
|
||||||
let client = reqwest::blocking::ClientBuilder::new();
|
let client = reqwest::blocking::ClientBuilder::new();
|
||||||
let client = reqwest::blocking::ClientBuilder::timeout(client, timeout_sec);
|
let client = reqwest::blocking::ClientBuilder::timeout(client, timeout_sec);
|
||||||
|
@ -156,7 +162,7 @@ impl NodeStruct {
|
||||||
match client.post(http).json(&get_info).send() {
|
match client.post(http).json(&get_info).send() {
|
||||||
Ok(r) => mid += now.elapsed(),
|
Ok(r) => mid += now.elapsed(),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Timeout on [{}: {}] (over 5 seconds)", id, ip);
|
error!("Timeout on [{:#?}: {}] (over 5 seconds)", id, ip);
|
||||||
mid += timeout_sec;
|
mid += timeout_sec;
|
||||||
timeout = true;
|
timeout = true;
|
||||||
},
|
},
|
||||||
|
|
112
src/p2pool.rs
112
src/p2pool.rs
|
@ -16,77 +16,25 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::App;
|
use crate::App;
|
||||||
use monero::util::address::Address;
|
|
||||||
use std::str::FromStr;
|
|
||||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
|
||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
|
use crate::state::P2pool;
|
||||||
|
use crate::node::NodeEnum;
|
||||||
|
use crate::node::{RINO,SETH,SELSTA};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
// pub simple: bool,
|
||||||
pub enum Node {
|
// pub mini: bool,
|
||||||
Rino,
|
// pub out_peers: u8,
|
||||||
Seth,
|
// pub in_peers: u8,
|
||||||
Selsta,
|
// pub log_level: u8,
|
||||||
}
|
// pub node: crate::node::NodeEnum,
|
||||||
|
// pub monerod: String,
|
||||||
impl Node {
|
|
||||||
pub fn ip(self) -> String {
|
|
||||||
match self {
|
|
||||||
Node::Rino => String::from("node.community.rino.io:18081"),
|
|
||||||
Node::Seth => String::from("node.sethforprivacy.com:18089"),
|
|
||||||
Node::Selsta => String::from("selsta1.featherwallet.net:18081"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn name(self) -> String {
|
|
||||||
match self {
|
|
||||||
Node::Rino => String::from("Rino"),
|
|
||||||
Node::Seth => String::from("Seth"),
|
|
||||||
Node::Selsta => String::from("Selsta"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main data structure for the P2Pool tab
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
||||||
pub struct P2pool {
|
|
||||||
pub version: String,
|
|
||||||
pub sha256: String,
|
|
||||||
pub manual: bool,
|
|
||||||
pub mini: bool,
|
|
||||||
pub rpc: String,
|
|
||||||
pub zmq: String,
|
|
||||||
// pub rpc: u16,
|
// pub rpc: u16,
|
||||||
// pub zmq: u16,
|
// pub zmq: u16,
|
||||||
pub out_peers: u16,
|
// pub address: String,
|
||||||
pub in_peers: u16,
|
|
||||||
pub log: u8,
|
|
||||||
pub monerod: String,
|
|
||||||
// pub monerod: std::net::SocketAddr,
|
|
||||||
pub community: Node,
|
|
||||||
pub address: String,
|
|
||||||
// pub address: monero::util::address::Address,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl P2pool {
|
impl P2pool {
|
||||||
pub fn new() -> Self {
|
pub fn show(&mut self, ctx: &egui::Context, ui: &mut egui::Ui) {
|
||||||
Self {
|
|
||||||
version: String::from("v2.4"),
|
|
||||||
sha256: String::from("asdf"),
|
|
||||||
manual: false,
|
|
||||||
mini: true,
|
|
||||||
rpc: String::from(""),
|
|
||||||
zmq: String::from(""),
|
|
||||||
out_peers: 10,
|
|
||||||
in_peers: 10,
|
|
||||||
log: 3,
|
|
||||||
// monerod: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 18081),
|
|
||||||
monerod: String::from(""),
|
|
||||||
address: String::from(""),
|
|
||||||
community: Node::Rino,
|
|
||||||
// address: Address::from_str("44hintoFpuo3ugKfcqJvh5BmrsTRpnTasJmetKC4VXCt6QDtbHVuixdTtsm6Ptp7Y8haXnJ6j8Gj2dra8CKy5ewz7Vi9CYW").unwrap(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn show(state: &mut P2pool, ctx: &egui::Context, ui: &mut egui::Ui) {
|
|
||||||
let height = ui.available_height() / 10.0;
|
let height = ui.available_height() / 10.0;
|
||||||
let mut width = ui.available_width() - 50.0;
|
let mut width = ui.available_width() - 50.0;
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
|
@ -100,61 +48,61 @@ impl P2pool {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.group(|ui| { ui.vertical(|ui| {
|
ui.group(|ui| { ui.vertical(|ui| {
|
||||||
ui.group(|ui| { ui.horizontal(|ui| {
|
ui.group(|ui| { ui.horizontal(|ui| {
|
||||||
if ui.add_sized([width/4.0, height/5.0], egui::SelectableLabel::new(state.mini == false, "P2Pool Main")).on_hover_text(P2POOL_MAIN).clicked() { state.mini = false; };
|
if ui.add_sized([width/4.0, height/5.0], egui::SelectableLabel::new(self.mini == false, "P2Pool Main")).on_hover_text(P2POOL_MAIN).clicked() { self.mini = false; };
|
||||||
if ui.add_sized([width/4.0, height/5.0], egui::SelectableLabel::new(state.mini == true, "P2Pool Mini")).on_hover_text(P2POOL_MINI).clicked() { state.mini = true; };
|
if ui.add_sized([width/4.0, height/5.0], egui::SelectableLabel::new(self.mini == true, "P2Pool Mini")).on_hover_text(P2POOL_MINI).clicked() { self.mini = true; };
|
||||||
})});
|
})});
|
||||||
|
|
||||||
let width = (width/4.0);
|
let width = width/4.0;
|
||||||
style.spacing.slider_width = width*1.25;
|
style.spacing.slider_width = width*1.25;
|
||||||
ctx.set_style(style);
|
ctx.set_style(style);
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add_sized([width/8.0, height/5.0], egui::Label::new("Out peers [10-450]:"));
|
ui.add_sized([width/8.0, height/5.0], egui::Label::new("Out peers [10-450]:"));
|
||||||
ui.add_sized([width, height/5.0], egui::Slider::new(&mut state.out_peers, 10..=450)).on_hover_text(P2POOL_OUT);
|
ui.add_sized([width, height/5.0], egui::Slider::new(&mut self.out_peers, 10..=450)).on_hover_text(P2POOL_OUT);
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add_sized([width/8.0, height/5.0], egui::Label::new(" In peers [10-450]:"));
|
ui.add_sized([width/8.0, height/5.0], egui::Label::new(" In peers [10-450]:"));
|
||||||
ui.add_sized([width, height/5.0], egui::Slider::new(&mut state.in_peers, 10..=450)).on_hover_text(P2POOL_IN);
|
ui.add_sized([width, height/5.0], egui::Slider::new(&mut self.in_peers, 10..=450)).on_hover_text(P2POOL_IN);
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add_sized([width/8.0, height/5.0], egui::Label::new(" Log level [0-6]:"));
|
ui.add_sized([width/8.0, height/5.0], egui::Label::new(" Log level [0-6]:"));
|
||||||
ui.add_sized([width, height/5.0], egui::Slider::new(&mut state.log, 0..=6)).on_hover_text(P2POOL_LOG);
|
ui.add_sized([width, height/5.0], egui::Slider::new(&mut self.log_level, 0..=6)).on_hover_text(P2POOL_LOG);
|
||||||
});
|
});
|
||||||
})});
|
})});
|
||||||
|
|
||||||
ui.group(|ui| { ui.vertical(|ui| {
|
ui.group(|ui| { ui.vertical(|ui| {
|
||||||
ui.group(|ui| { ui.horizontal(|ui| {
|
ui.group(|ui| { ui.horizontal(|ui| {
|
||||||
if ui.add_sized([width/4.0, height/5.0], egui::SelectableLabel::new(state.manual == false, "Community Monero Node")).on_hover_text(P2POOL_COMMUNITY).clicked() { state.manual = false; };
|
if ui.add_sized([width/4.0, height/5.0], egui::SelectableLabel::new(self.simple == false, "Community Monero Node")).on_hover_text(P2POOL_COMMUNITY).clicked() { self.simple = false; };
|
||||||
if ui.add_sized([width/4.0, height/5.0], egui::SelectableLabel::new(state.manual == true, "Manual Monero Node")).on_hover_text(P2POOL_MANUAL).clicked() { state.manual = true; };
|
if ui.add_sized([width/4.0, height/5.0], egui::SelectableLabel::new(self.simple == true, "Manual Monero Node")).on_hover_text(P2POOL_MANUAL).clicked() { self.simple = true; };
|
||||||
})});
|
})});
|
||||||
ui.add_space(8.0);
|
ui.add_space(8.0);
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
// ui.add_sized([width/8.0, height/5.0],
|
// ui.add_sized([width/8.0, height/5.0],
|
||||||
egui::ComboBox::from_label(Node::name(state.community.clone())).selected_text(Node::ip(state.community.clone())).show_ui(ui, |ui| {
|
egui::ComboBox::from_label(self.node.to_string()).selected_text(RINO).show_ui(ui, |ui| {
|
||||||
ui.selectable_value(&mut state.community, Node::Rino, Node::ip(Node::Rino));
|
ui.selectable_value(&mut self.node, NodeEnum::Rino, RINO);
|
||||||
ui.selectable_value(&mut state.community, Node::Seth, Node::ip(Node::Seth));
|
ui.selectable_value(&mut self.node, NodeEnum::Seth, SETH);
|
||||||
ui.selectable_value(&mut state.community, Node::Selsta, Node::ip(Node::Selsta));
|
ui.selectable_value(&mut self.node, NodeEnum::Selsta, SELSTA);
|
||||||
});
|
});
|
||||||
// );
|
// );
|
||||||
});
|
});
|
||||||
|
|
||||||
if state.manual == false { ui.set_enabled(false); }
|
if self.simple == false { ui.set_enabled(false); }
|
||||||
let width = (width/4.0);
|
let width = (width/4.0);
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add_sized([width/8.0, height/7.8], egui::Label::new("Monero Node IP:"));
|
ui.add_sized([width/8.0, height/7.8], egui::Label::new("Monero Node IP:"));
|
||||||
ui.spacing_mut().text_edit_width = ui.available_width() - 35.0;
|
ui.spacing_mut().text_edit_width = ui.available_width() - 35.0;
|
||||||
ui.text_edit_singleline(&mut state.monerod);
|
ui.text_edit_singleline(&mut self.monerod);
|
||||||
});
|
});
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add_sized([width/8.0, height/7.8], egui::Label::new("Monero Node RPC Port:"));
|
ui.add_sized([width/8.0, height/7.8], egui::Label::new("Monero Node RPC Port:"));
|
||||||
ui.spacing_mut().text_edit_width = ui.available_width() - 35.0;
|
ui.spacing_mut().text_edit_width = ui.available_width() - 35.0;
|
||||||
ui.text_edit_singleline(&mut state.rpc);
|
ui.text_edit_singleline(&mut self.rpc.to_string());
|
||||||
});
|
});
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add_sized([width/8.0, height/7.8], egui::Label::new("Monero Node ZMQ Port:"));
|
ui.add_sized([width/8.0, height/7.8], egui::Label::new("Monero Node ZMQ Port:"));
|
||||||
ui.spacing_mut().text_edit_width = ui.available_width() - 35.0;
|
ui.spacing_mut().text_edit_width = ui.available_width() - 35.0;
|
||||||
ui.text_edit_singleline(&mut state.zmq);
|
ui.text_edit_singleline(&mut self.zmq.to_string());
|
||||||
});
|
});
|
||||||
|
|
||||||
})});
|
})});
|
||||||
|
@ -164,7 +112,7 @@ impl P2pool {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.spacing_mut().text_edit_width = ui.available_width();
|
ui.spacing_mut().text_edit_width = ui.available_width();
|
||||||
ui.label("Address:");
|
ui.label("Address:");
|
||||||
ui.text_edit_singleline(&mut state.address);
|
ui.text_edit_singleline(&mut self.address);
|
||||||
})});
|
})});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
// This handles reading/parsing the state file: [gupax.toml]
|
// This handles reading/parsing the state file: [gupax.toml]
|
||||||
// The TOML format is used. This struct hierarchy directly
|
// The TOML format is used. This struct hierarchy directly
|
||||||
// translates into the TOML parser:
|
// translates into the TOML parser:
|
||||||
// Toml/
|
// State/
|
||||||
// ├─ Gupax/
|
// ├─ Gupax/
|
||||||
// │ ├─ ...
|
// │ ├─ ...
|
||||||
// ├─ P2pool/
|
// ├─ P2pool/
|
||||||
|
@ -31,13 +31,12 @@
|
||||||
use std::{fs,env};
|
use std::{fs,env};
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::path::{Path,PathBuf};
|
use std::path::{Path,PathBuf};
|
||||||
|
use std::result::Result;
|
||||||
use serde_derive::{Serialize,Deserialize};
|
use serde_derive::{Serialize,Deserialize};
|
||||||
use log::*;
|
use log::*;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Impl
|
//---------------------------------------------------------------------------------------------------- Impl
|
||||||
// Since [State] is already used in [main.rs] to represent
|
impl State {
|
||||||
// working state, [Toml] is used to represent disk state.
|
|
||||||
impl Toml {
|
|
||||||
pub fn default() -> Self {
|
pub fn default() -> Self {
|
||||||
use crate::constants::{P2POOL_VERSION,XMRIG_VERSION};
|
use crate::constants::{P2POOL_VERSION,XMRIG_VERSION};
|
||||||
Self {
|
Self {
|
||||||
|
@ -64,7 +63,9 @@ impl Toml {
|
||||||
tls: false,
|
tls: false,
|
||||||
nicehash: false,
|
nicehash: false,
|
||||||
keepalive: false,
|
keepalive: false,
|
||||||
threads: 1,
|
hugepages_jit: true,
|
||||||
|
current_threads: 1,
|
||||||
|
max_threads: 1,
|
||||||
priority: 2,
|
priority: 2,
|
||||||
pool: "localhost:3333".to_string(),
|
pool: "localhost:3333".to_string(),
|
||||||
address: "".to_string(),
|
address: "".to_string(),
|
||||||
|
@ -76,7 +77,7 @@ impl Toml {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get() -> Result<Toml, TomlError> {
|
pub fn get_path() -> Result<PathBuf, TomlError> {
|
||||||
// Get OS data folder
|
// Get OS data folder
|
||||||
// Linux | $XDG_DATA_HOME or $HOME/.local/share | /home/alice/.local/state
|
// Linux | $XDG_DATA_HOME or $HOME/.local/share | /home/alice/.local/state
|
||||||
// macOS | $HOME/Library/Application Support | /Users/Alice/Library/Application Support
|
// macOS | $HOME/Library/Application Support | /Users/Alice/Library/Application Support
|
||||||
|
@ -89,36 +90,67 @@ impl Toml {
|
||||||
},
|
},
|
||||||
None => { error!("Couldn't get OS PATH for data"); return Err(TomlError::Path(PATH_ERROR.to_string())) },
|
None => { error!("Couldn't get OS PATH for data"); return Err(TomlError::Path(PATH_ERROR.to_string())) },
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create directory
|
// Create directory
|
||||||
fs::create_dir_all(&path)?;
|
fs::create_dir_all(&path)?;
|
||||||
|
|
||||||
// Attempt to read file, create default if not found
|
|
||||||
path.push(FILENAME);
|
path.push(FILENAME);
|
||||||
let file = match fs::read_to_string(&path) {
|
info!("TOML path ... {}", path.display());
|
||||||
Ok(file) => file,
|
Ok(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempts to read [gupax.toml] or
|
||||||
|
// attempts to create if not found.
|
||||||
|
pub fn read_or_create(path: PathBuf) -> Result<String, TomlError> {
|
||||||
|
// Attempt to read file, create default if not found
|
||||||
|
match fs::read_to_string(&path) {
|
||||||
|
Ok(string) => {
|
||||||
|
info!("TOML read ... OK");
|
||||||
|
Ok(string)
|
||||||
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("TOML not found, attempting to create default");
|
error!("TOML not found, attempting to create default");
|
||||||
let default = match toml::ser::to_string(&Toml::default()) {
|
let default = match toml::ser::to_string(&State::default()) {
|
||||||
Ok(o) => { info!("TOML serialization ... OK"); o },
|
Ok(o) => { info!("TOML serialization ... OK"); o },
|
||||||
Err(e) => { error!("Couldn't serialize default TOML file: {}", e); return Err(TomlError::Serialize(e)) },
|
Err(e) => { error!("Couldn't serialize default TOML file: {}", e); return Err(TomlError::Serialize(e)) },
|
||||||
};
|
};
|
||||||
fs::write(&path, default)?;
|
fs::write(&path, &default)?;
|
||||||
info!("TOML write ... OK");
|
info!("TOML write ... OK");
|
||||||
fs::read_to_string(&path)?
|
Ok(fs::read_to_string(default)?)
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
info!("TOML path ... {}", path.display());
|
}
|
||||||
info!("TOML read ... OK");
|
|
||||||
|
|
||||||
// Attempt to parse, return Result
|
// Attempt to parse from String
|
||||||
match toml::from_str(&file) {
|
pub fn parse(string: String) -> Result<State, TomlError> {
|
||||||
|
match toml::de::from_str(&string) {
|
||||||
Ok(toml) => {
|
Ok(toml) => {
|
||||||
info!("TOML parse ... OK");
|
info!("TOML parse ... OK");
|
||||||
eprint!("{}", file);
|
eprint!("{}", string);
|
||||||
Ok(toml)
|
Ok(toml)
|
||||||
},
|
},
|
||||||
Err(err) => { error!("Couldn't parse TOML file"); Err(TomlError::Parse(err)) },
|
Err(err) => { error!("Couldn't parse TOML from string"); Err(TomlError::Deserialize(err)) },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last three functions combined
|
||||||
|
// get_path() -> read_or_create() -> parse()
|
||||||
|
// pub fn get() -> Result<State, TomlError> {
|
||||||
|
// let path = Self::path();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Overwrite disk Toml with memory State (save state)
|
||||||
|
pub fn overwrite(state: State, path: PathBuf) -> Result<(), TomlError> {
|
||||||
|
info!("Starting TOML overwrite...");
|
||||||
|
let string = match toml::ser::to_string(&state) {
|
||||||
|
Ok(string) => {
|
||||||
|
info!("TOML parse ... OK");
|
||||||
|
eprint!("{}", string);
|
||||||
|
string
|
||||||
|
},
|
||||||
|
Err(err) => { error!("Couldn't parse TOML into string"); return Err(TomlError::Serialize(err)) },
|
||||||
|
};
|
||||||
|
match fs::write(&path, string) {
|
||||||
|
Ok(_) => { info!("TOML overwrite ... OK"); Ok(()) },
|
||||||
|
Err(err) => { error!("Couldn't overwrite TOML file"); return Err(TomlError::Io(err)) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,8 +161,8 @@ impl Display for TomlError {
|
||||||
match self {
|
match self {
|
||||||
Io(err) => write!(f, "{} | {}", ERROR, err),
|
Io(err) => write!(f, "{} | {}", ERROR, err),
|
||||||
Path(err) => write!(f, "{} | {}", ERROR, err),
|
Path(err) => write!(f, "{} | {}", ERROR, err),
|
||||||
Parse(err) => write!(f, "{} | {}", ERROR, err),
|
|
||||||
Serialize(err) => write!(f, "{} | {}", ERROR, err),
|
Serialize(err) => write!(f, "{} | {}", ERROR, err),
|
||||||
|
Deserialize(err) => write!(f, "{} | {}", ERROR, err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,17 +173,10 @@ impl From<std::io::Error> for TomlError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let state = match Toml::get() {
|
|
||||||
Ok(state) => { println!("OK"); state },
|
|
||||||
Err(err) => panic!(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Const
|
//---------------------------------------------------------------------------------------------------- Const
|
||||||
const FILENAME: &'static str = "gupax.toml";
|
const FILENAME: &'static str = "gupax.toml";
|
||||||
const ERROR: &'static str = "TOML Error";
|
const ERROR: &'static str = "TOML Error";
|
||||||
const PATH_ERROR: &'static str = "PATH for state directory could not be not found";
|
const PATH_ERROR: &'static str = "PATH for state directory could not be not found";
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
const DIRECTORY: &'static str = "Gupax";
|
const DIRECTORY: &'static str = "Gupax";
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
|
@ -176,55 +201,57 @@ const DEFAULT_XMRIG_PATH: &'static str = "xmrig/xmrig";
|
||||||
pub enum TomlError {
|
pub enum TomlError {
|
||||||
Io(std::io::Error),
|
Io(std::io::Error),
|
||||||
Path(String),
|
Path(String),
|
||||||
Parse(toml::de::Error),
|
|
||||||
Serialize(toml::ser::Error),
|
Serialize(toml::ser::Error),
|
||||||
|
Deserialize(toml::de::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Structs
|
//---------------------------------------------------------------------------------------------------- Structs
|
||||||
#[derive(Debug,Deserialize,Serialize)]
|
#[derive(Clone,Eq,PartialEq,Debug,Deserialize,Serialize)]
|
||||||
pub struct Toml {
|
pub struct State {
|
||||||
gupax: Gupax,
|
pub gupax: Gupax,
|
||||||
p2pool: P2pool,
|
pub p2pool: P2pool,
|
||||||
xmrig: Xmrig,
|
pub xmrig: Xmrig,
|
||||||
version: Version,
|
pub version: Version,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug,Deserialize,Serialize)]
|
#[derive(Clone,Eq,PartialEq,Debug,Deserialize,Serialize)]
|
||||||
struct Gupax {
|
pub struct Gupax {
|
||||||
auto_update: bool,
|
pub auto_update: bool,
|
||||||
ask_before_quit: bool,
|
pub ask_before_quit: bool,
|
||||||
p2pool_path: String,
|
pub p2pool_path: String,
|
||||||
xmrig_path: String,
|
pub xmrig_path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug,Deserialize,Serialize)]
|
#[derive(Clone,Eq,PartialEq,Debug,Deserialize,Serialize)]
|
||||||
struct P2pool {
|
pub struct P2pool {
|
||||||
simple: bool,
|
pub simple: bool,
|
||||||
mini: bool,
|
pub mini: bool,
|
||||||
out_peers: u8,
|
pub out_peers: u16,
|
||||||
in_peers: u8,
|
pub in_peers: u16,
|
||||||
log_level: u8,
|
pub log_level: u8,
|
||||||
node: crate::node::NodeEnum,
|
pub node: crate::node::NodeEnum,
|
||||||
monerod: String,
|
pub monerod: String,
|
||||||
rpc: u16,
|
pub rpc: u16,
|
||||||
zmq: u16,
|
pub zmq: u16,
|
||||||
address: String,
|
pub address: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug,Deserialize,Serialize)]
|
#[derive(Clone,Eq,PartialEq,Debug,Deserialize,Serialize)]
|
||||||
struct Xmrig {
|
pub struct Xmrig {
|
||||||
simple: bool,
|
pub simple: bool,
|
||||||
tls: bool,
|
pub tls: bool,
|
||||||
nicehash: bool,
|
pub nicehash: bool,
|
||||||
keepalive: bool,
|
pub keepalive: bool,
|
||||||
threads: u16,
|
pub hugepages_jit: bool,
|
||||||
priority: u8,
|
pub max_threads: u16,
|
||||||
pool: String,
|
pub current_threads: u16,
|
||||||
address: String,
|
pub priority: u8,
|
||||||
|
pub pool: String,
|
||||||
|
pub address: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug,Deserialize,Serialize)]
|
#[derive(Clone,Eq,PartialEq,Debug,Deserialize,Serialize)]
|
||||||
struct Version {
|
pub struct Version {
|
||||||
p2pool: String,
|
pub p2pool: String,
|
||||||
xmrig: String,
|
pub xmrig: String,
|
||||||
}
|
}
|
71
src/xmrig.rs
71
src/xmrig.rs
|
@ -20,54 +20,11 @@ use monero::util::address::Address;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||||
use num_cpus;
|
use num_cpus;
|
||||||
use crate::State;
|
|
||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
|
use crate::state::Xmrig;
|
||||||
// Main data structure for the XMRig tab
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
||||||
pub struct Xmrig {
|
|
||||||
pub version: String,
|
|
||||||
pub sha256: String,
|
|
||||||
pub manual: bool,
|
|
||||||
pub tls: bool,
|
|
||||||
pub nicehash: bool,
|
|
||||||
pub keepalive: bool,
|
|
||||||
pub hugepages_jit: bool,
|
|
||||||
pub threads: u16,
|
|
||||||
pub priority: u8,
|
|
||||||
pub pool: String,
|
|
||||||
pub address: String,
|
|
||||||
// pub pool: std::net::SocketAddr,
|
|
||||||
// pub address: monero::util::address::Address,
|
|
||||||
pub max_threads: u16,
|
|
||||||
pub current_threads: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Xmrig {
|
impl Xmrig {
|
||||||
pub fn new() -> Self {
|
pub fn show(&mut self, ctx: &egui::Context, ui: &mut egui::Ui) {
|
||||||
let max_threads = num_cpus::get().try_into().unwrap();
|
|
||||||
let current_threads: u16;
|
|
||||||
if max_threads == 1 { current_threads = 1 } else { current_threads = max_threads/2 }
|
|
||||||
Self {
|
|
||||||
version: String::from("v6.18.0"),
|
|
||||||
sha256: String::from("asdf"),
|
|
||||||
manual: false,
|
|
||||||
tls: false,
|
|
||||||
nicehash: false,
|
|
||||||
keepalive: false,
|
|
||||||
hugepages_jit: true,
|
|
||||||
threads: 16,
|
|
||||||
priority: 2,
|
|
||||||
pool: String::from(""),
|
|
||||||
address: String::from(""),
|
|
||||||
// pool: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 3333),
|
|
||||||
// address: Address::from_str("44hintoFpuo3ugKfcqJvh5BmrsTRpnTasJmetKC4VXCt6QDtbHVuixdTtsm6Ptp7Y8haXnJ6j8Gj2dra8CKy5ewz7Vi9CYW").unwrap(),
|
|
||||||
max_threads,
|
|
||||||
current_threads,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn show(state: &mut Xmrig, ctx: &egui::Context, ui: &mut egui::Ui) {
|
|
||||||
let height = ui.available_height() / 10.0;
|
let height = ui.available_height() / 10.0;
|
||||||
let mut width = ui.available_width() - 10.0;
|
let mut width = ui.available_width() - 10.0;
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
|
@ -81,18 +38,18 @@ impl Xmrig {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.group(|ui| { ui.vertical(|ui| {
|
ui.group(|ui| { ui.vertical(|ui| {
|
||||||
ui.group(|ui| { ui.horizontal(|ui| {
|
ui.group(|ui| { ui.horizontal(|ui| {
|
||||||
if ui.add_sized([width/2.0, height/6.0], egui::SelectableLabel::new(state.manual == false, "P2Pool Mode")).on_hover_text(XMRIG_P2POOL).clicked() { state.manual = false; };
|
if ui.add_sized([width/2.0, height/6.0], egui::SelectableLabel::new(self.simple == false, "P2Pool Mode")).on_hover_text(XMRIG_P2POOL).clicked() { self.simple = false; };
|
||||||
if ui.add_sized([width/2.0, height/6.0], egui::SelectableLabel::new(state.manual == true, "Manual Mode")).on_hover_text(XMRIG_MANUAL).clicked() { state.manual = true; };
|
if ui.add_sized([width/2.0, height/6.0], egui::SelectableLabel::new(self.simple == true, "Manual Mode")).on_hover_text(XMRIG_MANUAL).clicked() { self.simple = true; };
|
||||||
})});
|
})});
|
||||||
ui.group(|ui| { ui.horizontal(|ui| {
|
ui.group(|ui| { ui.horizontal(|ui| {
|
||||||
let width = width - 58.0;
|
let width = width - 58.0;
|
||||||
ui.add_sized([width/4.0, height/6.0], egui::Checkbox::new(&mut state.tls, "TLS Connection")).on_hover_text(XMRIG_TLS);
|
ui.add_sized([width/4.0, height/6.0], egui::Checkbox::new(&mut self.tls, "TLS Connection")).on_hover_text(XMRIG_TLS);
|
||||||
ui.separator();
|
ui.separator();
|
||||||
ui.add_sized([width/4.0, height/6.0], egui::Checkbox::new(&mut state.hugepages_jit, "Hugepages JIT")).on_hover_text(XMRIG_HUGEPAGES_JIT);
|
ui.add_sized([width/4.0, height/6.0], egui::Checkbox::new(&mut self.hugepages_jit, "Hugepages JIT")).on_hover_text(XMRIG_HUGEPAGES_JIT);
|
||||||
ui.separator();
|
ui.separator();
|
||||||
ui.add_sized([width/4.0, height/6.0], egui::Checkbox::new(&mut state.nicehash, "Nicehash")).on_hover_text(XMRIG_NICEHASH);
|
ui.add_sized([width/4.0, height/6.0], egui::Checkbox::new(&mut self.nicehash, "Nicehash")).on_hover_text(XMRIG_NICEHASH);
|
||||||
ui.separator();
|
ui.separator();
|
||||||
ui.add_sized([width/4.0, height/6.0], egui::Checkbox::new(&mut state.keepalive, "Keepalive")).on_hover_text(XMRIG_KEEPALIVE);
|
ui.add_sized([width/4.0, height/6.0], egui::Checkbox::new(&mut self.keepalive, "Keepalive")).on_hover_text(XMRIG_KEEPALIVE);
|
||||||
})});
|
})});
|
||||||
})});
|
})});
|
||||||
});
|
});
|
||||||
|
@ -101,28 +58,28 @@ impl Xmrig {
|
||||||
style.spacing.slider_width = ui.available_width()/1.25;
|
style.spacing.slider_width = ui.available_width()/1.25;
|
||||||
ctx.set_style(style);
|
ctx.set_style(style);
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add_sized([width/8.0, height/8.0], egui::Label::new(format!("Threads [1-{}]:", state.max_threads)));
|
ui.add_sized([width/8.0, height/8.0], egui::Label::new(format!("Threads [1-{}]:", self.max_threads)));
|
||||||
ui.add_sized([width, height/8.0], egui::Slider::new(&mut state.current_threads, 1..=state.max_threads)).on_hover_text(XMRIG_THREADS);
|
ui.add_sized([width, height/8.0], egui::Slider::new(&mut self.current_threads, 1..=self.max_threads)).on_hover_text(XMRIG_THREADS);
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add_sized([width/8.0, height/8.0], egui::Label::new("CPU Priority [0-5]:"));
|
ui.add_sized([width/8.0, height/8.0], egui::Label::new("CPU Priority [0-5]:"));
|
||||||
ui.add_sized([width, height/8.0], egui::Slider::new(&mut state.priority, 0..=5)).on_hover_text(XMRIG_PRIORITY);
|
ui.add_sized([width, height/8.0], egui::Slider::new(&mut self.priority, 0..=5)).on_hover_text(XMRIG_PRIORITY);
|
||||||
});
|
});
|
||||||
// });
|
// });
|
||||||
|
|
||||||
// ui.group(|ui| {
|
// ui.group(|ui| {
|
||||||
if state.manual == false { ui.set_enabled(false); }
|
if self.simple == false { ui.set_enabled(false); }
|
||||||
let width = (width/4.0);
|
let width = (width/4.0);
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add_sized([width/8.0, height/8.0], egui::Label::new("Pool IP:"));
|
ui.add_sized([width/8.0, height/8.0], egui::Label::new("Pool IP:"));
|
||||||
ui.spacing_mut().text_edit_width = ui.available_width() - 35.0;
|
ui.spacing_mut().text_edit_width = ui.available_width() - 35.0;
|
||||||
ui.text_edit_singleline(&mut state.pool);
|
ui.text_edit_singleline(&mut self.pool);
|
||||||
});
|
});
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add_sized([width/8.0, height/8.0], egui::Label::new("Address:"));
|
ui.add_sized([width/8.0, height/8.0], egui::Label::new("Address:"));
|
||||||
ui.spacing_mut().text_edit_width = ui.available_width() - 35.0;
|
ui.spacing_mut().text_edit_width = ui.available_width() - 35.0;
|
||||||
ui.text_edit_singleline(&mut state.address);
|
ui.text_edit_singleline(&mut self.address);
|
||||||
});
|
});
|
||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue