diff --git a/Cargo.lock b/Cargo.lock
index 6b6fbb0..3ef473c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1275,15 +1275,6 @@ dependencies = [
  "bytemuck",
 ]
 
-[[package]]
-name = "encoding_rs"
-version = "0.8.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b"
-dependencies = [
- "cfg-if",
-]
-
 [[package]]
 name = "enum-ordinalize"
 version = "3.1.12"
@@ -1920,7 +1911,6 @@ dependencies = [
  "openssl",
  "rand 0.8.5",
  "regex",
- "reqwest",
  "rfd",
  "rusqlite",
  "serde",
@@ -1937,25 +1927,6 @@ dependencies = [
  "zip",
 ]
 
-[[package]]
-name = "h2"
-version = "0.3.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4"
-dependencies = [
- "bytes",
- "fnv",
- "futures-core",
- "futures-sink",
- "futures-util",
- "http",
- "indexmap",
- "slab",
- "tokio",
- "tokio-util",
- "tracing",
-]
-
 [[package]]
 name = "half"
 version = "2.1.0"
@@ -2106,7 +2077,6 @@ dependencies = [
  "futures-channel",
  "futures-core",
  "futures-util",
- "h2",
  "http",
  "http-body",
  "httparse",
@@ -2223,12 +2193,6 @@ dependencies = [
  "web-sys",
 ]
 
-[[package]]
-name = "ipnet"
-version = "2.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745"
-
 [[package]]
 name = "itertools"
 version = "0.10.5"
@@ -2438,12 +2402,6 @@ dependencies = [
  "zeroize",
 ]
 
-[[package]]
-name = "mime"
-version = "0.3.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
-
 [[package]]
 name = "minimal-lexical"
 version = "0.2.1"
@@ -3339,43 +3297,6 @@ dependencies = [
  "winapi",
 ]
 
-[[package]]
-name = "reqwest"
-version = "0.11.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c"
-dependencies = [
- "base64",
- "bytes",
- "encoding_rs",
- "futures-core",
- "futures-util",
- "h2",
- "http",
- "http-body",
- "hyper",
- "hyper-tls",
- "ipnet",
- "js-sys",
- "log",
- "mime",
- "native-tls",
- "once_cell",
- "percent-encoding",
- "pin-project-lite",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "tokio",
- "tokio-native-tls",
- "tower-service",
- "url",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
- "winreg",
-]
-
 [[package]]
 name = "retain_mut"
 version = "0.1.9"
@@ -3661,18 +3582,6 @@ dependencies = [
  "serde",
 ]
 
-[[package]]
-name = "serde_urlencoded"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
-dependencies = [
- "form_urlencoded",
- "itoa",
- "ryu",
- "serde",
-]
-
 [[package]]
 name = "serde_with"
 version = "1.14.0"
@@ -4275,7 +4184,6 @@ dependencies = [
  "futures-sink",
  "pin-project-lite",
  "tokio",
- "tracing",
 ]
 
 [[package]]
@@ -5439,15 +5347,6 @@ dependencies = [
  "x11-dl",
 ]
 
-[[package]]
-name = "winreg"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
-dependencies = [
- "winapi",
-]
-
 [[package]]
 name = "winres"
 version = "0.1.12"
diff --git a/Cargo.toml b/Cargo.toml
index 3c4ec49..891132c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -39,7 +39,7 @@ num_cpus = "1.13.1"
 num-format = "0.4.0"
 rand = "0.8.5"
 regex = "1.6.0"
-reqwest = { version = "0.11.12", features = ["blocking", "json"] }
+#reqwest = { version = "0.11.12", features = ["blocking", "json"] }
 rfd = "0.10.0"
 rusqlite = { version = "0.28.0", features = ["bundled"] }
 serde = { version = "1.0.145", features = ["rc", "derive"] }
diff --git a/images/ferris/happy.png b/images/ferris/happy.png
new file mode 100644
index 0000000..84d84ad
Binary files /dev/null and b/images/ferris/happy.png differ
diff --git a/src/constants.rs b/src/constants.rs
index 77ca9f5..c21250d 100644
--- a/src/constants.rs
+++ b/src/constants.rs
@@ -85,7 +85,7 @@ r#"Use advanced settings:
     - P2Pool Main/Mini selection
     - Out/In peer setting
     - Log level setting"#;
-pub const P2POOL_NAME: &'static str = "Add a unique name to identify this node; Only [A-Za-z0-9-_] and spaces allowed; Max length = 30 characters";
+pub const P2POOL_NAME: &'static str = "Add a unique name to identify this node; Only [A-Za-z0-9-_] and spaces allowed, if the name already exists, the current settings will be saved to the already existing entry; Max length = 30 characters";
 pub const P2POOL_NODE_IP: &'static str = "Specify the Monero Node IP to connect to with P2Pool; It must be a valid IPv4 address or a valid domain name; Max length = 255 characters";
 pub const P2POOL_RPC_PORT: &'static str = "Specify the RPC port of the Monero node; [1-65535]";
 pub const P2POOL_ZMQ_PORT: &'static str = "Specify the ZMQ port of the Monero node; [1-65535]";
@@ -106,15 +106,17 @@ pub const XMRIG_PRIORITY: &'static str = "Set process priority (0 idle, 2 normal
 
 // CLI argument messages
 pub const ARG_HELP: &'static str =
-r#"USAGE: ./gupax [--flags]
+r#"USAGE: ./gupax [--flag]
 
-    -h | --help         Print this help message
-    -v | --version      Print version and build info
-    -l | --node-list    Print the manual node list
-    -s | --state        Print Gupax state
-    -n | --no-startup   Disable all auto-startup settings for this instance
-    -r | --reset        Reset all Gupax state and the manual node list
-    -f | --ferris       Print an extremely cute crab
+    --help         Print this help message
+    --version      Print version and build info
+    --state        Print Gupax state
+    --nodes        Print the manual node list
+    --no-startup   Disable all auto-startup settings for this instance
+    --reset-state  Reset all Gupax state (your settings)
+    --reset-nodes  Reset the manual node list in the [P2Pool] tab
+    --reset-all    Reset both the state and the manual node list
+    --ferris       Print an extremely cute crab
 
 To view more detailed console debug information, start Gupax with
 the environment variable [RUST_LOG] set to a log level like so:
diff --git a/src/disk.rs b/src/disk.rs
index 76a07fc..28ef127 100644
--- a/src/disk.rs
+++ b/src/disk.rs
@@ -179,7 +179,7 @@ impl State {
 	}
 
 	// Convert [String] to [State]
-	pub fn from_string(string: String) -> Result<Self, TomlError> {
+	pub fn from_string(string: &String) -> Result<Self, TomlError> {
 		match toml::de::from_str(&string) {
 			Ok(state) => {
 				info!("State | Parse ... OK");
@@ -187,7 +187,7 @@ impl State {
 				Ok(state)
 			}
 			Err(err) => {
-				error!("State | String -> State ... FAIL ... {}", err);
+				warn!("State | String -> State ... FAIL ... {}", err);
 				Err(TomlError::Deserialize(err))
 			},
 		}
@@ -207,11 +207,20 @@ impl State {
 			// Create
 			_ => {
 				Self::create_new()?;
-				read_to_string(file, &path)?
+				match read_to_string(file, &path) {
+					Ok(s) => s,
+					Err(e) => return Err(e),
+				}
 			},
 		};
-		// Deserialize
-		Self::from_string(string)
+		// Deserialize, attempt merge if failed
+		match Self::from_string(&string) {
+			Ok(s) => Ok(s),
+			Err(e) => {
+				warn!("State | Attempting merge...");
+				Self::merge(string)
+			},
+		}
 	}
 
 	// Completely overwrite current [state.toml]
@@ -250,22 +259,17 @@ impl State {
 		}
 	}
 
-	// Take [Self] as input, merge it with whatever the current [default] is,
+	// Take [String] as input, merge it with whatever the current [default] is,
 	// leaving behind old keys+values and updating [default] with old valid ones.
 	// Automatically overwrite current file.
-	pub fn merge(old: &Self) -> Result<Self, TomlError> {
-		info!("Starting TOML merge...");
-		let old = match toml::ser::to_string(&old) {
-			Ok(string) => { info!("Old TOML parse ... OK"); string },
-			Err(err) => { error!("Couldn't parse old TOML into string"); return Err(TomlError::Serialize(err)) },
-		};
+	pub fn merge(old: String) -> Result<Self, TomlError> {
 		let default = match toml::ser::to_string(&Self::new()) {
-			Ok(string) => { info!("Default TOML parse ... OK"); string },
-			Err(err) => { error!("Couldn't parse default TOML into string"); return Err(TomlError::Serialize(err)) },
+			Ok(string) => { info!("State | Default TOML parse ... OK"); string },
+			Err(err) => { error!("State | Couldn't parse default TOML into string"); return Err(TomlError::Serialize(err)) },
 		};
 		let mut new: Self = match Figment::new().merge(Toml::string(&old)).merge(Toml::string(&default)).extract() {
-			Ok(new) => { info!("TOML merge ... OK"); new },
-			Err(err) => { error!("Couldn't merge default + old TOML"); return Err(TomlError::Merge(err)) },
+			Ok(new) => { info!("State | TOML merge ... OK"); new },
+			Err(err) => { error!("State | Couldn't merge default + old TOML"); return Err(TomlError::Merge(err)) },
 		};
 		// Attempt save
 		Self::save(&mut new)?;
@@ -298,7 +302,7 @@ impl Node {
 	}
 
 	// Convert [String] to [Node] Vec
-	pub fn from_string(string: String) -> Result<Vec<(String, Self)>, TomlError> {
+	pub fn from_string_to_vec(string: &String) -> Result<Vec<(String, Self)>, TomlError> {
 		let nodes: toml::map::Map<String, toml::Value> = match toml::de::from_str(&string) {
 			Ok(map) => {
 				info!("Node | Parse ... OK");
@@ -312,7 +316,6 @@ impl Node {
 		let size = nodes.keys().len();
 		let mut vec = Vec::with_capacity(size);
 		for (key, values) in nodes.iter() {
-//			println!("{:#?}", values.get("ip")); std::process::exit(0);
 			let node = Node {
 				ip: values.get("ip").unwrap().as_str().unwrap().to_string(),
 				rpc: values.get("rpc").unwrap().as_str().unwrap().to_string(),
@@ -357,8 +360,8 @@ impl Node {
 				read_to_string(file, &path)?
 			},
 		};
-		// Deserialize
-		Self::from_string(string)
+		// Deserialize, attempt merge if failed
+		Self::from_string_to_vec(&string)
 	}
 
 	// Completely overwrite current [node.toml]
@@ -380,26 +383,19 @@ impl Node {
 		let string = Self::to_string(vec);
 		match fs::write(path, string) {
 			Ok(_) => { info!("TOML save ... OK"); Ok(()) },
-			Err(err) => { error!("Couldn't overwrite TOML file"); return Err(TomlError::Io(err)) },
+			Err(err) => { error!("Couldn't overwrite TOML file"); Err(TomlError::Io(err)) },
 		}
 	}
 
-//	// Take [Self] as input, merge it with whatever the current [default] is,
-//	// leaving behind old keys+values and updating [default] with old valid ones.
-//	// Automatically overwrite current file.
-//	pub fn merge(old: &Self) -> Result<Self, TomlError> {
-//		info!("Starting TOML merge...");
-//		let old = match toml::ser::to_string(&old) {
-//			Ok(string) => { info!("Old TOML parse ... OK"); string },
-//			Err(err) => { error!("Couldn't parse old TOML into string"); return Err(TomlError::Serialize(err)) },
-//		};
+//	pub fn merge(old: &String) -> Result<Self, TomlError> {
+//		info!("Node | Starting TOML merge...");
 //		let default = match toml::ser::to_string(&Self::new()) {
-//			Ok(string) => { info!("Default TOML parse ... OK"); string },
-//			Err(err) => { error!("Couldn't parse default TOML into string"); return Err(TomlError::Serialize(err)) },
+//			Ok(string) => { info!("Node | Default TOML parse ... OK"); string },
+//			Err(err) => { error!("Node | Couldn't parse default TOML into string"); return Err(TomlError::Serialize(err)) },
 //		};
 //		let mut new: Self = match Figment::new().merge(Toml::string(&old)).merge(Toml::string(&default)).extract() {
-//			Ok(new) => { info!("TOML merge ... OK"); new },
-//			Err(err) => { error!("Couldn't merge default + old TOML"); return Err(TomlError::Merge(err)) },
+//			Ok(new) => { info!("Node | TOML merge ... OK"); new },
+//			Err(err) => { error!("Node | Couldn't merge default + old TOML"); return Err(TomlError::Merge(err)) },
 //		};
 //		// Attempt save
 //		Self::save(&mut new)?;
@@ -408,15 +404,24 @@ impl Node {
 }
 
 //---------------------------------------------------------------------------------------------------- Custom Error [TomlError]
+#[derive(Debug)]
+pub enum TomlError {
+	Io(std::io::Error),
+	Path(String),
+	Serialize(toml::ser::Error),
+	Deserialize(toml::de::Error),
+	Merge(figment::Error),
+}
+
 impl Display for TomlError {
-	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
 		use TomlError::*;
 		match self {
-			Io(err)          => write!(f, "{}: {} | {}", ERROR, self, err),
-			Path(err)        => write!(f, "{}: {} | {}", ERROR, self, err),
-			Serialize(err)   => write!(f, "{}: {} | {}", ERROR, self, err),
-			Deserialize(err) => write!(f, "{}: {} | {}", ERROR, self, err),
-			Merge(err)       => write!(f, "{}: {} | {}", ERROR, self, err),
+			Io(err)          => write!(f, "{}: IO | {}", ERROR, err),
+			Path(err)        => write!(f, "{}: Path | {}", ERROR, err),
+			Serialize(err)   => write!(f, "{}: Serialize | {}", ERROR, err),
+			Deserialize(err) => write!(f, "{}: Deserialize | {}", ERROR, err),
+			Merge(err)       => write!(f, "{}: Merge | {}", ERROR, err),
 		}
 	}
 }
@@ -447,16 +452,6 @@ pub const DEFAULT_XMRIG_PATH: &'static str = r"XMRig\xmrig.exe";
 #[cfg(target_family = "unix")]
 pub const DEFAULT_XMRIG_PATH: &'static str = "xmrig/xmrig";
 
-//---------------------------------------------------------------------------------------------------- Error Enum
-#[derive(Debug)]
-pub enum TomlError {
-	Io(std::io::Error),
-	Path(String),
-	Serialize(toml::ser::Error),
-	Deserialize(toml::de::Error),
-	Merge(figment::Error),
-}
-
 //---------------------------------------------------------------------------------------------------- [File] Enum (for matching which file)
 #[derive(Clone,Copy,Eq,PartialEq,Debug,Deserialize,Serialize)]
 pub enum File {
diff --git a/src/ferris.rs b/src/ferris.rs
index 08eb09c..759e20b 100644
--- a/src/ferris.rs
+++ b/src/ferris.rs
@@ -17,6 +17,7 @@
 
 // Some images of ferris in byte form for error messages, etc
 
+pub const FERRIS_HAPPY: &[u8] = include_bytes!("../images/ferris/happy.png");
 pub const FERRIS_OOPS: &[u8] = include_bytes!("../images/ferris/oops.png");
 pub const FERRIS_ERROR: &[u8] = include_bytes!("../images/ferris/error.png");
 pub const FERRIS_PANIC: &[u8] = include_bytes!("../images/ferris/panic.png"); // This isnt technically ferris but its ok since its spooky
@@ -35,7 +36,6 @@ pub const FERRIS_PANIC: &[u8] = include_bytes!("../images/ferris/panic.png"); //
 
 
 
-
 // This is the ANSI representation of Ferris in string form.
 // Calling [println!] on this straight up prints a 256-bit color Ferris to the terminal.
 // The ANSI codes were generated with [https://docs.rs/ansipix], but there is no reason to include the library and
diff --git a/src/main.rs b/src/main.rs
index 83e5e19..f779404 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -86,7 +86,6 @@ pub struct App {
 	xmrig: bool, // Is xmrig online?
 	// State from [--flags]
 	no_startup: bool,
-	reset: bool,
 	// Static stuff
 	now: Instant, // Internal timer
 	exe: String, // Path for [Gupax] binary
@@ -128,7 +127,6 @@ impl App {
 			p2pool: false,
 			xmrig: false,
 			no_startup: false,
-			reset: false,
 			now: Instant::now(),
 			exe: "".to_string(),
 			dir: "".to_string(),
@@ -157,18 +155,42 @@ impl App {
 			Ok(dir) => dir,
 			Err(err) => { panic_main(err.to_string()); exit(1); },
 		};
-		// Read disk state if no [--reset] arg
-		if app.reset == false {
-			app.og = match State::get() {
-				Ok(toml) => Arc::new(Mutex::new(toml)),
-				Err(err) => { panic_main(err.to_string()); exit(1); },
-			};
-		}
-		let mut og = app.og.lock().unwrap(); // Lock [og]
-		app.state = og.clone();
-		// Get node list
-		app.og_node_vec = Node::get().unwrap();
+		// Read disk state
+		use TomlError::*;
+		app.state = match State::get() {
+			Ok(toml) => toml,
+			Err(err) => {
+				error!("State ... {}", err);
+				match err {
+					Io(e) => app.error_state.set(true, format!("State file: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
+					Path(e) => app.error_state.set(true, format!("State file: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
+					Serialize(e) => app.error_state.set(true, format!("State file: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
+					Deserialize(e) => app.error_state.set(true, format!("State file: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
+					Merge(e) => app.error_state.set(true, format!("State file: {}", e), ErrorFerris::Error, ErrorButtons::ResetState),
+				};
+				State::new()
+			},
+		};
+		app.og = Arc::new(Mutex::new(app.state.clone()));
+		// Read node list
+		app.og_node_vec = match Node::get() {
+			Ok(toml) => toml,
+			Err(err) => {
+				error!("Node ... {}", err);
+				match err {
+					Io(e) => app.error_state.set(true, format!("Node list: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
+					Path(e) => app.error_state.set(true, format!("Node list: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
+					Serialize(e) => app.error_state.set(true, format!("Node list: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
+					Deserialize(e) => app.error_state.set(true, format!("Node list: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
+					Merge(e) => app.error_state.set(true, format!("Node list: {}", e), ErrorFerris::Error, ErrorButtons::ResetState),
+				};
+				Node::new_vec()
+			},
+		};
 		app.node_vec = app.og_node_vec.clone();
+
+
+		let mut og = app.og.lock().unwrap(); // Lock [og]
 		// Handle max threads
 		og.xmrig.max_threads = num_cpus::get();
 		let current = og.xmrig.current_threads;
@@ -222,7 +244,7 @@ impl Default for Tab {
 //---------------------------------------------------------------------------------------------------- [ErrorState] struct
 pub struct ErrorState {
 	error: bool, // Is there an error?
-	msg: &'static str, // What message to display?
+	msg: String, // What message to display?
 	ferris: ErrorFerris, // Which ferris to display?
 	buttons: ErrorButtons, // Which buttons to display?
 }
@@ -231,17 +253,17 @@ impl ErrorState {
 	pub fn new() -> Self {
 		Self {
 			error: false,
-			msg: "Unknown Error",
+			msg: "Unknown Error".to_string(),
 			ferris: ErrorFerris::Oops,
 			buttons: ErrorButtons::Okay,
 		}
 	}
 
 	// Convenience function to set the [App] error state
-	pub fn set(&mut self, error: bool, msg: &'static str, ferris: ErrorFerris, buttons: ErrorButtons) {
+	pub fn set(&mut self, error: bool, msg: impl Into<String>, ferris: ErrorFerris, buttons: ErrorButtons) {
 		*self = Self {
 			error,
-			msg,
+			msg: msg.into(),
 			ferris,
 			buttons,
 		};
@@ -253,12 +275,15 @@ impl ErrorState {
 pub enum ErrorButtons {
 	YesNo,
 	StayQuit,
+	ResetState,
+	ResetNode,
 	Okay,
 	Quit,
 }
 
 #[derive(Clone, Copy, Debug, PartialEq)]
 pub enum ErrorFerris {
+	Happy,
 	Oops,
 	Error,
 	Panic,
@@ -267,6 +292,7 @@ pub enum ErrorFerris {
 //---------------------------------------------------------------------------------------------------- [Images] struct
 struct Images {
 	banner: RetainedImage,
+	happy: RetainedImage,
 	oops: RetainedImage,
 	error: RetainedImage,
 	panic: RetainedImage,
@@ -276,6 +302,7 @@ impl Images {
 	fn new() -> Self {
 		Self {
 			banner: RetainedImage::from_image_bytes("banner.png", BYTES_BANNER).unwrap(),
+			happy: RetainedImage::from_image_bytes("happy.png", FERRIS_HAPPY).unwrap(),
 			oops: RetainedImage::from_image_bytes("oops.png", FERRIS_OOPS).unwrap(),
 			error: RetainedImage::from_image_bytes("error.png", FERRIS_ERROR).unwrap(),
 			panic: RetainedImage::from_image_bytes("panic.png", FERRIS_PANIC).unwrap(),
@@ -388,6 +415,9 @@ fn init_auto(app: &App) {
 	if app.no_startup {
 		info!("[--no-startup] flag passed, skipping init_auto()...");
 		return
+	} else if app.error_state.error {
+		info!("App error detected, skipping init_auto()...");
+		return
 	} else {
 		info!("Starting init_auto()...");
 	}
@@ -442,17 +472,31 @@ fn init_auto(app: &App) {
 	}
 }
 
-fn reset() {
-	let mut code = 0;
+fn reset_state() -> Result<(), TomlError> {
 	info!("Resetting [state.toml]...");
 	match State::create_new() {
-		Ok(_)  => info!("Resetting [state.toml] ... OK"),
-		Err(e) => { error!("Resetting [state.toml] ... FAIL ... {}", e); code = 1; },
+		Ok(_)  => { info!("Resetting [state.toml] ... OK"); Ok(()) },
+		Err(e) => { error!("Resetting [state.toml] ... FAIL ... {}", e); Err(e) },
 	}
+}
+
+fn reset_nodes() -> Result<(), TomlError> {
 	info!("Resetting [node.toml]...");
 	match Node::create_new() {
-		Ok(_)  => info!("Resetting [node.toml] ... OK"),
-		Err(e) => { error!("Resetting [node.toml] ... FAIL ... {}", e); code = 1; },
+		Ok(_)  => { info!("Resetting [node.toml] ... OK"); Ok(()) },
+		Err(e) => { error!("Resetting [node.toml] ... FAIL ... {}", e); Err(e) },
+	}
+}
+
+fn reset() {
+	let mut code = 0;
+	match reset_state() {
+		Ok(_) => (),
+		Err(_) => code = 1,
+	}
+	match reset_nodes() {
+		Ok(_) => (),
+		Err(_) => code = 1,
 	}
 	match code {
 		0 => println!("\nGupax files were reset successfully."),
@@ -469,23 +513,25 @@ fn parse_args(mut app: App) -> App {
 	// [help/version], exit early
 	for arg in &args {
 		match arg.as_str() {
-			"-h"|"--help"    => { println!("{}", ARG_HELP); exit(0); },
-			"-v"|"--version" => {
+			"--help"    => { println!("{}", ARG_HELP); exit(0); },
+			"--version" => {
 				println!("Gupax {} [OS: {}, Commit: {}]\n\n{}", GUPAX_VERSION, OS_NAME, &COMMIT[..40], ARG_COPYRIGHT);
 				exit(0);
 			},
-			"-f"|"--ferris" => { println!("{}", FERRIS_ANSI); exit(0); },
+			"--ferris" => { println!("{}", FERRIS_ANSI); exit(0); },
 			_ => (),
 		}
 	}
 	// Everything else
 	for arg in args {
 		match arg.as_str() {
-			"-l"|"--node-list"  => { info!("Printing node list..."); print_disk_file(File::Node); }
-			"-s"|"--state"      => { info!("Printing state..."); print_disk_file(File::State); }
-			"-r"|"--reset"      => { reset(); }
-			"-n"|"--no-startup" => { app.no_startup = true; }
-			_                   => { eprintln!("[Gupax error] Invalid option: [{}]\nFor help, use: [--help]", arg); exit(1); },
+			"--nodes"       => { info!("Printing node list..."); print_disk_file(File::Node); }
+			"--state"       => { info!("Printing state..."); print_disk_file(File::State); }
+			"--reset-state" => if let Ok(()) = reset_state() { exit(0) } else { exit(1) },
+			"--reset-nodes" => if let Ok(()) = reset_nodes() { exit(0) } else { exit(1) },
+			"--reset-all"   => reset(),
+			"--no-startup"  => app.no_startup = true,
+			_               => { eprintln!("[Gupax error] Invalid option: [{}]\nFor help, use: [--help]", arg); exit(1); },
 		}
 	}
 	app
@@ -604,14 +650,6 @@ fn main() {
 }
 
 impl eframe::App for App {
-//	pub fn new() -> Self {
-//		Self {
-//			error: false,
-//			msg: String::new(),
-//			image: RetainedImage::from_image_bytes("banner.png", FERRIS_ERROR).unwrap(),
-//			buttons: ErrorButtons::Okay,
-//		}
-//	}
 	fn on_close_event(&mut self) -> bool {
 		if self.state.gupax.ask_before_quit {
 			self.error_state.set(true, "", ErrorFerris::Oops, ErrorButtons::StayQuit);
@@ -652,8 +690,10 @@ impl eframe::App for App {
 
 				// Display ferris
 				use ErrorFerris::*;
+				use ErrorButtons::*;
 				let ferris = match self.error_state.ferris {
-					Oops => &self.img.oops,
+					Happy => &self.img.happy,
+					Oops  => &self.img.oops,
 					Error => &self.img.error,
 					Panic => &self.img.panic,
 				};
@@ -669,12 +709,23 @@ impl eframe::App for App {
 						ui.add_sized([width, height], Label::new("--- Are you sure you want to quit? ---"));
 						ui.add_sized([width, height], Label::new(text))
 					},
+					ResetState => {
+						ui.add_sized([width, height], Label::new(format!("--- Gupax has encountered an error! ---\n{}", &self.error_state.msg)));
+						ui.add_sized([width, height], Label::new("Reset Gupax state? (Your settings)"))
+					},
+					ResetNode  => {
+						ui.add_sized([width, height], Label::new(format!("--- Gupax has encountered an error! ---\n{}", &self.error_state.msg)));
+						ui.add_sized([width, height], Label::new("Reset the manual node list?"))
+					},
 					_ => {
-						ui.add_sized([width, height], Label::new("--- Gupax has encountered an error! ---"));
-						ui.add_sized([width, height], Label::new(self.error_state.msg))
+						match self.error_state.ferris {
+							Panic => ui.add_sized([width, height], Label::new("--- Gupax has encountered an un-recoverable error! ---")),
+							Happy => ui.add_sized([width, height], Label::new("--- Success! ---")),
+							_ => ui.add_sized([width, height], Label::new("--- Gupax has encountered an error! ---")),
+						};
+						ui.add_sized([width, height], Label::new(&self.error_state.msg))
 					},
 				};
-				use ErrorButtons::*;
 				let height = ui.available_height();
 
 				// Capture [Esc] key
@@ -693,8 +744,47 @@ impl eframe::App for App {
 						}
 						if ui.add_sized([width, height/2.0], egui::Button::new("Quit")).clicked() { exit(0); }
 					},
+					// This code handles the [state.toml/node.toml] resetting, [panic!]'ing if it errors once more
+					// Another error after this either means an IO error or permission error, which Gupax can't fix.
+					// [Yes/No] buttons
+					ResetState => {
+						if ui.add_sized([width, height/2.0], egui::Button::new("Yes")).clicked() {
+							match reset_state() {
+								Ok(_)  => {
+									match State::get() {
+										Ok(s) => {
+											self.state = s;
+											self.og = Arc::new(Mutex::new(self.state.clone()));
+											self.error_state.set(true, "State read OK", ErrorFerris::Happy, ErrorButtons::Okay);
+										},
+										Err(e) => self.error_state.set(true, format!("State read fail: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
+									}
+								},
+								Err(e) => self.error_state.set(true, format!("State reset fail: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
+							};
+						}
+				        if esc || ui.add_sized([width, height/2.0], egui::Button::new("No")).clicked() { self.error_state = ErrorState::new() }
+					},
+					ResetNode => {
+						if ui.add_sized([width, height/2.0], egui::Button::new("Yes")).clicked() {
+							match reset_nodes() {
+								Ok(_)  => {
+									match Node::get() {
+										Ok(s) => {
+											self.node_vec = s;
+											self.og_node_vec = self.node_vec.clone();
+											self.error_state.set(true, "Node read OK", ErrorFerris::Happy, ErrorButtons::Okay);
+										},
+										Err(e) => self.error_state.set(true, format!("Node read fail: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
+									}
+								},
+								Err(e) => self.error_state.set(true, format!("Node reset fail: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
+							};
+						}
+				        if esc || ui.add_sized([width, height/2.0], egui::Button::new("No")).clicked() { self.error_state = ErrorState::new() }
+					},
 					Okay => if esc || ui.add_sized([width, height], egui::Button::new("Okay")).clicked() { self.error_state = ErrorState::new(); },
-					Quit => if ui.add_sized([width, height], egui::Button::new("Quit")).clicked() { exit(0); },
+					Quit => if ui.add_sized([width, height], egui::Button::new("Quit")).clicked() { exit(1); },
 				}
 			})});
 			return
@@ -777,13 +867,21 @@ impl eframe::App for App {
 						self.node_vec = self.og_node_vec.clone();
 					}
 					if ui.add_sized([width, height], egui::Button::new("Save")).on_hover_text("Save changes").clicked() {
-						let mut og = self.og.lock().unwrap();
-						og.gupax = self.state.gupax.clone();
-						og.p2pool = self.state.p2pool.clone();
-						og.xmrig = self.state.xmrig.clone();
-						self.og_node_vec = self.node_vec.clone();
-						self.state.save();
-						Node::save(&self.og_node_vec);
+						match self.state.save() {
+							Ok(_) => {
+								let mut og = self.og.lock().unwrap();
+								og.gupax = self.state.gupax.clone();
+								og.p2pool = self.state.p2pool.clone();
+								og.xmrig = self.state.xmrig.clone();
+							},
+							Err(e) => {
+								self.error_state.set(true, format!("State file: {}", e), ErrorFerris::Error, ErrorButtons::Okay);
+							},
+						};
+						match Node::save(&self.og_node_vec) {
+							Ok(_) => self.og_node_vec = self.node_vec.clone(),
+							Err(e) => self.error_state.set(true, format!("Node list: {}", e), ErrorFerris::Error, ErrorButtons::Okay),
+						};
 					}
 				});
 
@@ -872,7 +970,7 @@ impl eframe::App for App {
 
 						ui.add_space(ui.available_height()/2.0);
 						ui.hyperlink_to("Powered by egui", "https://github.com/emilk/egui");
-						ui.hyperlink_to(format!("{} {}", GITHUB, "Gupax made by hinto-janaiyo"), "https://www.github.com/hinto-janaiyo/gupax");
+						ui.hyperlink_to(format!("{} {}", GITHUB, "Made by hinto-janaiyo"), "https://gupax.io");
 						ui.label("egui is licensed under MIT & Apache-2.0");
 						ui.label("Gupax, P2Pool, and XMRig are licensed under GPLv3");
 					});
diff --git a/src/node.rs b/src/node.rs
index f714a1e..bf447e0 100644
--- a/src/node.rs
+++ b/src/node.rs
@@ -27,8 +27,6 @@ use log::*;
 //	header::{HeaderValue,LOCATION},
 //};
 
-use reqwest::blocking::ClientBuilder;
-
 //---------------------------------------------------------------------------------------------------- Node list
 // Community Monerod nodes. All of these have ZMQ on 18083.
 // Adding/removing nodes will need changes to pretty
diff --git a/src/p2pool.rs b/src/p2pool.rs
index 363d1ab..3134156 100644
--- a/src/p2pool.rs
+++ b/src/p2pool.rs
@@ -332,7 +332,7 @@ impl P2pool {
 				let text = format!("{}\n    Currently selected node: {}. {}\n    Current amount of nodes: {}/1000", text, self.selected_index, self.selected_name, node_vec_len);
 				// If the node already exists, show [Save] and mutate the already existing node
 				if exists {
-					ui.set_enabled(save_diff);
+					ui.set_enabled(!incorrect_input && save_diff);
 					if ui.add_sized([width, text_edit], Button::new("Save")).on_hover_text(text).clicked() {
 						let node = Node {
 							ip: self.ip.clone(),