mirror of
https://github.com/Cyrix126/gupaxx.git
synced 2024-11-16 15:27:46 +00:00
add basic [--flags]
This commit is contained in:
parent
ed7ddeeda1
commit
773bc65593
4 changed files with 236 additions and 150 deletions
|
@ -15,7 +15,7 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// These are the versions bundled with Gupax.
|
||||
pub const GUPAX_VERSION: &'static str = "v0.1.0";
|
||||
pub const P2POOL_VERSION: &'static str = "v2.4";
|
||||
pub const XMRIG_VERSION: &'static str = "v6.18.0";
|
||||
|
||||
|
@ -23,6 +23,7 @@ pub const BYTES_ICON: &[u8] = include_bytes!("../images/png/icon.png");
|
|||
pub const BYTES_BANNER: &[u8] = include_bytes!("../images/png/banner.png");
|
||||
pub const P2POOL_BASE_ARGS: &'static str = "";
|
||||
pub const XMRIG_BASE_ARGS: &'static str = "--http-host=127.0.0.1 --http-port=18088 --algo=rx/0 --coin=Monero --randomx-cache-qos";
|
||||
pub const HORIZONTAL: &'static str = "--------------------------------------------";
|
||||
|
||||
// OS specific
|
||||
#[cfg(target_os = "windows")]
|
||||
|
@ -66,3 +67,19 @@ pub const XMRIG_NICEHASH: &'static str = "Enable nicehash.com support";
|
|||
pub const XMRIG_KEEPALIVE: &'static str = "Send keepalived packet to prevent timeout (needs pool support)";
|
||||
pub const XMRIG_THREADS: &'static str = "Number of CPU threads to use for mining";
|
||||
pub const XMRIG_PRIORITY: &'static str = "Set process priority (0 idle, 2 normal to 5 highest)";
|
||||
|
||||
// CLI argument messages
|
||||
pub const ARG_HELP: &'static str =
|
||||
r#"USAGE: gupax [--flags]
|
||||
|
||||
-h | --help Print this help message
|
||||
-v | --version Print versions
|
||||
-n | --no-startup Disable auto-update/node connections at startup
|
||||
-r | --reset Reset all Gupax configuration/state"#;
|
||||
pub const ARG_COPYRIGHT: &'static str =
|
||||
r#"For more information:
|
||||
https://github.com/hinto-janaiyo/gupax
|
||||
https://github.com/SChernykh/p2pool
|
||||
https://github.com/xmrig/xmrig
|
||||
|
||||
Gupax, P2Pool, and XMRig are licensed under GPLv3."#;
|
||||
|
|
196
src/main.rs
196
src/main.rs
|
@ -34,8 +34,9 @@ use env_logger::{Builder,WriteStyle};
|
|||
use std::io::Write;
|
||||
use std::process::exit;
|
||||
use std::sync::{Arc,Mutex};
|
||||
use std::thread;
|
||||
use std::{thread,env};
|
||||
use std::time::Instant;
|
||||
use std::path::PathBuf;
|
||||
|
||||
// Modules
|
||||
mod constants;
|
||||
|
@ -55,10 +56,10 @@ use {constants::*,node::*,state::*,about::*,status::*,gupax::*,p2pool::*,xmrig::
|
|||
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?
|
||||
quit: bool, // Was the quit button clicked?
|
||||
quit_confirm: bool, // Was the quit confirmed?
|
||||
ping: bool, // Was the ping button clicked?
|
||||
pinging: Arc<Mutex<bool>>, // Is a ping in progress?
|
||||
node: Arc<Mutex<NodeStruct>>, // Data on community nodes
|
||||
// State:
|
||||
// og = Old state to compare against
|
||||
|
@ -68,42 +69,58 @@ pub struct App {
|
|||
og: State,
|
||||
state: State,
|
||||
diff: bool,
|
||||
// Process/update state:
|
||||
// Doesn't make sense to save this on disk
|
||||
// so it's represented as a bool here.
|
||||
p2pool: bool, // Is p2pool online?
|
||||
xmrig: bool, // Is xmrig online?
|
||||
updating: bool, // Is an update in progress?
|
||||
// State from [--flags]
|
||||
startup: bool,
|
||||
reset: bool,
|
||||
// Static stuff
|
||||
now: Instant,
|
||||
resolution: Vec2,
|
||||
os: &'static str,
|
||||
version: String,
|
||||
name_version: String,
|
||||
banner: RetainedImage,
|
||||
|
||||
// TEMPORARY FIXME
|
||||
p2pool: bool,
|
||||
xmrig: bool,
|
||||
now: Instant, // Internal timer
|
||||
resolution: Vec2, // Frame resolution
|
||||
os: &'static str, // OS
|
||||
version: String, // Gupax version
|
||||
name_version: String, // [Gupax vX.X.X]
|
||||
banner: RetainedImage, // Gupax banner image
|
||||
}
|
||||
|
||||
impl App {
|
||||
fn new(cc: &eframe::CreationContext<'_>) -> Self {
|
||||
fn cc(cc: &eframe::CreationContext<'_>, app: Self) -> Self {
|
||||
let resolution = cc.integration_info.window_info.size;
|
||||
init_text_styles(&cc.egui_ctx, resolution[0] as f32);
|
||||
Self {
|
||||
resolution,
|
||||
..app
|
||||
}
|
||||
}
|
||||
|
||||
fn default() -> Self {
|
||||
let app = Self {
|
||||
tab: Tab::default(),
|
||||
quit: false,
|
||||
quit_confirm: false,
|
||||
ping: false,
|
||||
ping_prog: Arc::new(Mutex::new(false)),
|
||||
pinging: Arc::new(Mutex::new(false)),
|
||||
node: Arc::new(Mutex::new(NodeStruct::default())),
|
||||
og: State::default(),
|
||||
state: State::default(),
|
||||
diff: false,
|
||||
p2pool: false,
|
||||
xmrig: false,
|
||||
updating: false,
|
||||
startup: true,
|
||||
reset: false,
|
||||
now: Instant::now(),
|
||||
resolution: cc.integration_info.window_info.size,
|
||||
resolution: Vec2::new(1280.0, 720.0),
|
||||
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,
|
||||
}
|
||||
};
|
||||
parse_args(app)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,6 +170,10 @@ fn init_text_styles(ctx: &egui::Context, width: f32) {
|
|||
}
|
||||
|
||||
fn init_logger() {
|
||||
#[cfg(debug_assertions)]
|
||||
let filter = LevelFilter::Info;
|
||||
#[cfg(not(debug_assertions))]
|
||||
let filter = LevelFilter::Warn;
|
||||
use env_logger::fmt::Color;
|
||||
Builder::new().format(|buf, record| {
|
||||
let level;
|
||||
|
@ -173,7 +194,7 @@ fn init_logger() {
|
|||
buf.style().set_dimmed(true).value(record.line().unwrap_or(0)),
|
||||
record.args(),
|
||||
)
|
||||
}).filter_level(LevelFilter::Info).write_style(WriteStyle::Always).parse_default_env().format_timestamp_millis().init();
|
||||
}).filter_level(filter).write_style(WriteStyle::Always).parse_default_env().format_timestamp_millis().init();
|
||||
info!("init_logger() ... OK");
|
||||
}
|
||||
|
||||
|
@ -195,6 +216,45 @@ fn init_options() -> NativeOptions {
|
|||
options
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Misc functions
|
||||
fn into_absolute_path(path: String) -> Result<PathBuf, std::io::Error> {
|
||||
let path = PathBuf::from(path);
|
||||
if path.is_relative() {
|
||||
let mut dir = std::env::current_exe()?;
|
||||
dir.pop();
|
||||
dir.push(path);
|
||||
Ok(dir)
|
||||
} else {
|
||||
Ok(path)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_args(mut app: App) -> App {
|
||||
info!("Parsing CLI arguments...");
|
||||
let mut args: Vec<String> = env::args().collect();
|
||||
if args.len() == 1 { info!("No args ... OK"); return app } else { args.remove(0); info!("Args ... {:?}", args); }
|
||||
// [help/version], exit early
|
||||
for arg in &args {
|
||||
match arg.as_str() {
|
||||
"-h"|"--help" => { println!("{}", ARG_HELP); exit(0); },
|
||||
"-v"|"--version" => {
|
||||
println!("Gupax | {}\nP2Pool | {}\nXMRig | {}\n\n{}", GUPAX_VERSION, P2POOL_VERSION, XMRIG_VERSION, ARG_COPYRIGHT);
|
||||
exit(0);
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
// Everything else
|
||||
for arg in args {
|
||||
match arg.as_str() {
|
||||
"-n"|"--no-startup" => { info!("Disabling startup..."); app.startup = false; }
|
||||
"-r"|"--reset" => { info!("Resetting state..."); app.reset = true; }
|
||||
_ => { eprintln!("[Gupax error] Invalid option: [{}]\nFor help, use: [--help]", arg); exit(1); },
|
||||
}
|
||||
}
|
||||
app
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- [App] frame for [Panic] situations
|
||||
struct Panic { error_msg: String, }
|
||||
impl Panic {
|
||||
|
@ -240,19 +300,19 @@ 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 app = App::default();
|
||||
let options = init_options();
|
||||
eframe::run_native("Gupax", options, Box::new(|cc| Box::new(App::new(cc))),);
|
||||
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);
|
||||
},
|
||||
};
|
||||
eframe::run_native("Gupax", options, Box::new(|cc| Box::new(App::cc(cc, app))),);
|
||||
}
|
||||
|
||||
impl eframe::App for App {
|
||||
|
@ -262,49 +322,75 @@ impl eframe::App for App {
|
|||
}
|
||||
|
||||
fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
|
||||
init_text_styles(ctx, 1280.0);
|
||||
// init_text_styles(ctx, 1280.0);
|
||||
|
||||
// Close confirmation.
|
||||
if self.quit {
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
init_text_styles(ctx, ui.available_width());
|
||||
let width = ui.available_width();
|
||||
let width = width - 10.0;
|
||||
let height = ui.available_height();
|
||||
init_text_styles(ctx, width);
|
||||
ui.add_sized([width, height/2.0], Label::new("Are you sure you want to quit?"));
|
||||
// Detect processes or update
|
||||
if self.p2pool || self.xmrig {
|
||||
ui.add_sized([width, height/6.0], Label::new("Are you sure you want to quit?"));
|
||||
if self.p2pool { ui.add_sized([width, height/6.0], Label::new("P2Pool is online...!")); }
|
||||
if self.xmrig { ui.add_sized([width, height/6.0], Label::new("XMRig is online...!")); }
|
||||
// Else, just quit
|
||||
} else {
|
||||
if self.state.gupax.save_before_quit {
|
||||
info!("Saving before quit...");
|
||||
match self.state.save() {
|
||||
Err(err) => { error!("{}", err); exit(1); },
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
info!("No processes or update in progress ... goodbye!");
|
||||
exit(0);
|
||||
}
|
||||
egui::TopBottomPanel::bottom("quit").show(ctx, |ui| {
|
||||
ui.group(|ui| {
|
||||
if ui.add_sized([width, height/10.0], egui::Button::new("Yes")).clicked() {
|
||||
if ui.add_sized([width, height/8.0], egui::Button::new("Yes")).clicked() {
|
||||
if self.state.gupax.save_before_quit {
|
||||
info!("Saving before quit...");
|
||||
match self.state.save() {
|
||||
Err(err) => { error!("{}", err); exit(1); },
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
info!("Quit confirmation = yes ... goodbye!");
|
||||
self.quit_confirm = true;
|
||||
frame.close();
|
||||
} else if ui.add_sized([width, height/10.0], egui::Button::new("No")).clicked() {
|
||||
exit(0);
|
||||
} else if ui.add_sized([width, height/8.0], egui::Button::new("No")).clicked() {
|
||||
self.quit = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
return
|
||||
}
|
||||
|
||||
//
|
||||
// If ping was pressed, start thread
|
||||
if self.ping {
|
||||
self.ping = false;
|
||||
self.ping_prog = Arc::new(Mutex::new(true));
|
||||
self.pinging = Arc::new(Mutex::new(true));
|
||||
let node_clone = Arc::clone(&self.node);
|
||||
let prog_clone = Arc::clone(&self.ping_prog);
|
||||
let pinging_clone = Arc::clone(&self.pinging);
|
||||
thread::spawn(move|| {
|
||||
let result = NodeStruct::ping();
|
||||
*node_clone.lock().unwrap() = result.node;
|
||||
*prog_clone.lock().unwrap() = false;
|
||||
*node_clone.lock().unwrap() = result.nodes;
|
||||
*pinging_clone.lock().unwrap() = false;
|
||||
});
|
||||
}
|
||||
|
||||
// if *self.ping_prog.lock().unwrap() {
|
||||
// If ping-ING, display stats
|
||||
// if *self.pinging.lock().unwrap() {
|
||||
// egui::CentralPanel::default().show(ctx, |ui| {
|
||||
// let width = ui.available_width();
|
||||
// let width = width - 10.0;
|
||||
// let height = ui.available_height();
|
||||
// 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.pinging.lock().unwrap())));
|
||||
// ui.group(|ui| {
|
||||
// if ui.add_sized([width, height/10.0], egui::Button::new("Yes")).clicked() {
|
||||
// info!("Quit confirmation = yes ... goodbye!");
|
||||
|
@ -324,8 +410,8 @@ impl eframe::App for App {
|
|||
let width = (ui.available_width() - 90.0) / 5.0;
|
||||
let height = ui.available_height() / 10.0;
|
||||
ui.add_space(4.0);
|
||||
ui.style_mut().override_text_style = Some(Name("Tab".into()));
|
||||
ui.horizontal(|ui| {
|
||||
ui.style_mut().override_text_style = Some(Name("Tab".into()));
|
||||
ui.style_mut().visuals.widgets.inactive.fg_stroke.color = Color32::from_rgb(100, 100, 100);
|
||||
ui.style_mut().visuals.selection.bg_fill = Color32::from_rgb(255, 120, 120);
|
||||
ui.style_mut().visuals.selection.stroke = Stroke {
|
||||
|
@ -346,7 +432,6 @@ impl eframe::App for App {
|
|||
ui.separator();
|
||||
// });
|
||||
|
||||
|
||||
let height = height / 2.0;
|
||||
// Bottom: app info + state/process buttons
|
||||
egui::TopBottomPanel::bottom("bottom").show(ctx, |ui| {
|
||||
|
@ -359,9 +444,6 @@ impl eframe::App for App {
|
|||
ui.add_sized([width, height], Label::new(self.os));
|
||||
ui.separator();
|
||||
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 {
|
||||
ui.add_sized([width/4.0, height], Label::new(RichText::new("⏺").color(Color32::from_rgb(100, 230, 100))));
|
||||
} else {
|
||||
|
@ -428,10 +510,6 @@ impl eframe::App for App {
|
|||
});
|
||||
});
|
||||
|
||||
// Central: tab contents
|
||||
// Docs say to add central last, don't think it matters here but whatever:
|
||||
// [https://docs.rs/egui/latest/egui/containers/panel/struct.TopBottomPanel.html]
|
||||
// egui::TopBottomPanel::bottom("2").show(ctx, |ui| {
|
||||
ui.style_mut().override_text_style = Some(egui::TextStyle::Body);
|
||||
match self.tab {
|
||||
Tab::About => {
|
||||
|
@ -451,8 +529,6 @@ impl eframe::App for App {
|
|||
Xmrig::show(&mut self.state.xmrig, ctx, ui);
|
||||
}
|
||||
}
|
||||
// });
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
89
src/node.rs
89
src/node.rs
|
@ -41,6 +41,11 @@ pub const SUPPORTXMR: &'static str = "node.supportxmr.com:18081";
|
|||
pub const SUPPORTXMR_IR: &'static str = "node.supportxmr.ir:18081";
|
||||
pub const XMRVSBEAST: &'static str = "p2pmd.xmrvsbeast.com:18081";
|
||||
|
||||
pub const NODE_IPS: [&'static str; 12] = [
|
||||
C3POOL,CAKE,CAKE_EU,CAKE_UK,CAKE_US,MONERUJO,RINO,
|
||||
SELSTA,SETH,SUPPORTXMR,SUPPORTXMR_IR,XMRVSBEAST,
|
||||
];
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NodeStruct {
|
||||
c3pool: Data, cake: Data, cake_eu: Data, cake_uk: Data, cake_us: Data, monerujo: Data,
|
||||
|
@ -52,7 +57,7 @@ pub struct Data {
|
|||
pub ms: u128,
|
||||
pub color: Color32,
|
||||
pub id: NodeEnum,
|
||||
pub ip: String,
|
||||
pub ip: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Copy,Clone,Eq,PartialEq,Debug,Deserialize,Serialize)]
|
||||
|
@ -69,39 +74,31 @@ impl std::fmt::Display for NodeEnum {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct PingResult {
|
||||
pub node: NodeStruct,
|
||||
pub nodes: NodeStruct,
|
||||
pub fastest: NodeEnum,
|
||||
}
|
||||
|
||||
use crate::NodeEnum::*;
|
||||
impl NodeStruct {
|
||||
pub fn default() -> Self {
|
||||
use crate::NodeEnum::*;
|
||||
let ms = 0;
|
||||
let color = Color32::GRAY;
|
||||
Self {
|
||||
c3pool: Data { ms, color, id: C3pool, ip: C3POOL.to_string(), },
|
||||
cake: Data { ms, color, id: Cake, ip: CAKE.to_string(), },
|
||||
cake_eu: Data { ms, color, id: CakeEu, ip: CAKE_EU.to_string(), },
|
||||
cake_uk: Data { ms, color, id: CakeUk, ip: CAKE_UK.to_string(), },
|
||||
cake_us: Data { ms, color, id: CakeUs, ip: CAKE_US.to_string(), },
|
||||
monerujo: Data { ms, color, id: Monerujo, ip: MONERUJO.to_string(), },
|
||||
rino: Data { ms, color, id: Rino, ip: RINO.to_string(), },
|
||||
selsta: Data { ms, color, id: Selsta, ip: SELSTA.to_string(), },
|
||||
seth: Data { ms, color, id: Seth, ip: SETH.to_string(), },
|
||||
supportxmr: Data { ms, color, id: SupportXmr, ip: SUPPORTXMR.to_string(), },
|
||||
supportxmr_ir: Data { ms, color, id: SupportXmrIr, ip: SUPPORTXMR_IR.to_string(), },
|
||||
xmrvsbeast: Data { ms, color, id: XmrVsBeast, ip: XMRVSBEAST.to_string(), },
|
||||
c3pool: Data { ms, color, id: C3pool, ip: C3POOL, },
|
||||
cake: Data { ms, color, id: Cake, ip: CAKE, },
|
||||
cake_eu: Data { ms, color, id: CakeEu, ip: CAKE_EU, },
|
||||
cake_uk: Data { ms, color, id: CakeUk, ip: CAKE_UK, },
|
||||
cake_us: Data { ms, color, id: CakeUs, ip: CAKE_US, },
|
||||
monerujo: Data { ms, color, id: Monerujo, ip: MONERUJO, },
|
||||
rino: Data { ms, color, id: Rino, ip: RINO, },
|
||||
selsta: Data { ms, color, id: Selsta, ip: SELSTA, },
|
||||
seth: Data { ms, color, id: Seth, ip: SETH, },
|
||||
supportxmr: Data { ms, color, id: SupportXmr, ip: SUPPORTXMR, },
|
||||
supportxmr_ir: Data { ms, color, id: SupportXmrIr, ip: SUPPORTXMR_IR, },
|
||||
xmrvsbeast: Data { ms, color, id: XmrVsBeast, ip: XMRVSBEAST, },
|
||||
}
|
||||
}
|
||||
|
||||
// Return array of all IPs
|
||||
fn array() -> [&'static str; 12] {
|
||||
[
|
||||
C3POOL,CAKE,CAKE_EU,CAKE_UK,CAKE_US,MONERUJO,RINO,
|
||||
SELSTA,SETH,SUPPORTXMR,SUPPORTXMR_IR,XMRVSBEAST,
|
||||
]
|
||||
}
|
||||
|
||||
// This is for pinging the community nodes to
|
||||
// find the fastest/slowest one for the user.
|
||||
// The process:
|
||||
|
@ -123,9 +120,8 @@ impl NodeStruct {
|
|||
// timeout = BLACK
|
||||
// default = GRAY
|
||||
pub fn ping() -> PingResult {
|
||||
use crate::NodeEnum::*;
|
||||
info!("Starting community node pings...");
|
||||
let mut node = NodeStruct::default();
|
||||
let mut nodes = NodeStruct::default();
|
||||
let mut get_info = HashMap::new();
|
||||
get_info.insert("jsonrpc", "2.0");
|
||||
get_info.insert("id", "0");
|
||||
|
@ -134,7 +130,7 @@ impl NodeStruct {
|
|||
let fastest = false;
|
||||
let timeout_sec = Duration::from_millis(5000);
|
||||
|
||||
for ip in Self::array().iter() {
|
||||
for ip in NODE_IPS.iter() {
|
||||
let id = match *ip {
|
||||
C3POOL => C3pool,
|
||||
CAKE => Cake,
|
||||
|
@ -182,18 +178,18 @@ impl NodeStruct {
|
|||
color = Color32::LIGHT_GREEN
|
||||
}
|
||||
match id {
|
||||
C3pool => { node.c3pool.ms = ms; node.c3pool.color = color; },
|
||||
Cake => { node.cake.ms = ms; node.cake.color = color; },
|
||||
CakeEu => { node.cake_eu.ms = ms; node.cake_eu.color = color; },
|
||||
CakeUk => { node.cake_uk.ms = ms; node.cake_uk.color = color; },
|
||||
CakeUs => { node.cake_us.ms = ms; node.cake_us.color = color; },
|
||||
Monerujo => { node.monerujo.ms = ms; node.monerujo.color = color; },
|
||||
Rino => { node.rino.ms = ms; node.rino.color = color; },
|
||||
Selsta => { node.selsta.ms = ms; node.selsta.color = color; },
|
||||
Seth => { node.seth.ms = ms; node.seth.color = color; },
|
||||
SupportXmr => { node.supportxmr.ms = ms; node.supportxmr.color = color; },
|
||||
SupportXmrIr => { node.supportxmr_ir.ms = ms; node.supportxmr_ir.color = color; },
|
||||
XmrVsBeast => { node.xmrvsbeast.ms = ms; node.xmrvsbeast.color = color; },
|
||||
C3pool => { nodes.c3pool.ms = ms; nodes.c3pool.color = color; },
|
||||
Cake => { nodes.cake.ms = ms; nodes.cake.color = color; },
|
||||
CakeEu => { nodes.cake_eu.ms = ms; nodes.cake_eu.color = color; },
|
||||
CakeUk => { nodes.cake_uk.ms = ms; nodes.cake_uk.color = color; },
|
||||
CakeUs => { nodes.cake_us.ms = ms; nodes.cake_us.color = color; },
|
||||
Monerujo => { nodes.monerujo.ms = ms; nodes.monerujo.color = color; },
|
||||
Rino => { nodes.rino.ms = ms; nodes.rino.color = color; },
|
||||
Selsta => { nodes.selsta.ms = ms; nodes.selsta.color = color; },
|
||||
Seth => { nodes.seth.ms = ms; nodes.seth.color = color; },
|
||||
SupportXmr => { nodes.supportxmr.ms = ms; nodes.supportxmr.color = color; },
|
||||
SupportXmrIr => { nodes.supportxmr_ir.ms = ms; nodes.supportxmr_ir.color = color; },
|
||||
XmrVsBeast => { nodes.xmrvsbeast.ms = ms; nodes.xmrvsbeast.color = color; },
|
||||
}
|
||||
}
|
||||
let mut best_ms: u128 = vec[0].0;
|
||||
|
@ -208,22 +204,7 @@ impl NodeStruct {
|
|||
// The values don't update if not printed beforehand,
|
||||
// so the match below on [fastest] gets funky.
|
||||
info!("Fastest node ... {:#?} @ {:#?}ms", fastest, best_ms);
|
||||
let ip = match fastest {
|
||||
C3pool => C3POOL,
|
||||
Cake => CAKE,
|
||||
CakeEu => CAKE_EU,
|
||||
CakeUk => CAKE_UK,
|
||||
CakeUs => CAKE_US,
|
||||
Monerujo => MONERUJO,
|
||||
Rino => RINO,
|
||||
Selsta => SELSTA,
|
||||
Seth => SETH,
|
||||
SupportXmr => SUPPORTXMR,
|
||||
SupportXmrIr => SUPPORTXMR_IR,
|
||||
XmrVsBeast => XMRVSBEAST,
|
||||
};
|
||||
info!("Using IP ... {}", ip);
|
||||
info!("Community node ping ... OK");
|
||||
PingResult { node, fastest, }
|
||||
PingResult { nodes, fastest, }
|
||||
}
|
||||
}
|
||||
|
|
36
src/state.rs
36
src/state.rs
|
@ -33,6 +33,7 @@ use std::fmt::Display;
|
|||
use std::path::{Path,PathBuf};
|
||||
use std::result::Result;
|
||||
use serde_derive::{Serialize,Deserialize};
|
||||
use crate::constants::HORIZONTAL;
|
||||
use log::*;
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Impl
|
||||
|
@ -43,6 +44,7 @@ impl State {
|
|||
gupax: Gupax {
|
||||
auto_update: true,
|
||||
ask_before_quit: true,
|
||||
save_before_quit: true,
|
||||
p2pool_path: DEFAULT_P2POOL_PATH.to_string(),
|
||||
xmrig_path: DEFAULT_XMRIG_PATH.to_string(),
|
||||
},
|
||||
|
@ -107,14 +109,14 @@ impl State {
|
|||
Ok(string)
|
||||
},
|
||||
Err(err) => {
|
||||
error!("TOML not found, attempting to create default");
|
||||
warn!("TOML not found, attempting to create default");
|
||||
let default = match toml::ser::to_string(&State::default()) {
|
||||
Ok(o) => { info!("TOML serialization ... OK"); o },
|
||||
Err(e) => { error!("Couldn't serialize default TOML file: {}", e); return Err(TomlError::Serialize(e)) },
|
||||
};
|
||||
fs::write(&path, &default)?;
|
||||
info!("TOML write ... OK");
|
||||
Ok(fs::read_to_string(default)?)
|
||||
Ok(default)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +126,9 @@ impl State {
|
|||
match toml::de::from_str(&string) {
|
||||
Ok(toml) => {
|
||||
info!("TOML parse ... OK");
|
||||
eprint!("{}", string);
|
||||
info!("{}", HORIZONTAL);
|
||||
for i in string.lines() { info!("{}", i); }
|
||||
info!("{}", HORIZONTAL);
|
||||
Ok(toml)
|
||||
},
|
||||
Err(err) => { error!("Couldn't parse TOML from string"); Err(TomlError::Deserialize(err)) },
|
||||
|
@ -133,22 +137,25 @@ impl State {
|
|||
|
||||
// Last three functions combined
|
||||
// get_path() -> read_or_create() -> parse()
|
||||
// pub fn get() -> Result<State, TomlError> {
|
||||
// let path = Self::path();
|
||||
// }
|
||||
pub fn get() -> Result<State, TomlError> {
|
||||
Self::parse(Self::read_or_create(Self::get_path()?)?)
|
||||
}
|
||||
|
||||
// Overwrite disk Toml with memory State (save state)
|
||||
pub fn overwrite(state: State, path: PathBuf) -> Result<(), TomlError> {
|
||||
// Save [State] onto disk file [gupax.toml]
|
||||
pub fn save(&self) -> Result<(), TomlError> {
|
||||
let path = Self::get_path()?;
|
||||
info!("Starting TOML overwrite...");
|
||||
let string = match toml::ser::to_string(&state) {
|
||||
let string = match toml::ser::to_string(&self) {
|
||||
Ok(string) => {
|
||||
info!("TOML parse ... OK");
|
||||
eprint!("{}", string);
|
||||
info!("{}", HORIZONTAL);
|
||||
for i in string.lines() { info!("{}", i); }
|
||||
info!("{}", HORIZONTAL);
|
||||
string
|
||||
},
|
||||
Err(err) => { error!("Couldn't parse TOML into string"); return Err(TomlError::Serialize(err)) },
|
||||
};
|
||||
match fs::write(&path, string) {
|
||||
match fs::write(path, string) {
|
||||
Ok(_) => { info!("TOML overwrite ... OK"); Ok(()) },
|
||||
Err(err) => { error!("Couldn't overwrite TOML file"); return Err(TomlError::Io(err)) },
|
||||
}
|
||||
|
@ -176,7 +183,7 @@ impl From<std::io::Error> for TomlError {
|
|||
//---------------------------------------------------------------------------------------------------- Const
|
||||
const FILENAME: &'static str = "gupax.toml";
|
||||
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")]
|
||||
const DIRECTORY: &'static str = "Gupax";
|
||||
#[cfg(target_os = "macos")]
|
||||
|
@ -218,6 +225,7 @@ pub struct State {
|
|||
pub struct Gupax {
|
||||
pub auto_update: bool,
|
||||
pub ask_before_quit: bool,
|
||||
pub save_before_quit: bool,
|
||||
pub p2pool_path: String,
|
||||
pub xmrig_path: String,
|
||||
}
|
||||
|
@ -234,6 +242,8 @@ pub struct P2pool {
|
|||
pub rpc: u16,
|
||||
pub zmq: u16,
|
||||
pub address: String,
|
||||
// pub config: String,
|
||||
// pub args: String,
|
||||
}
|
||||
|
||||
#[derive(Clone,Eq,PartialEq,Debug,Deserialize,Serialize)]
|
||||
|
@ -248,6 +258,8 @@ pub struct Xmrig {
|
|||
pub priority: u8,
|
||||
pub pool: String,
|
||||
pub address: String,
|
||||
// pub config: String,
|
||||
// pub args: String,
|
||||
}
|
||||
|
||||
#[derive(Clone,Eq,PartialEq,Debug,Deserialize,Serialize)]
|
||||
|
|
Loading…
Reference in a new issue