mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2024-11-28 04:44:06 +00:00
Improve Error Handling (#459)
* Add error messages by changing unwrap() calls to expect() * Improve error messages by changing println! to info!/warn!/error! * Address nits * Change panic message * details in panic
This commit is contained in:
parent
b28522a6ce
commit
77f439a6eb
9 changed files with 150 additions and 105 deletions
113
Cargo.toml
113
Cargo.toml
|
@ -1,56 +1,57 @@
|
|||
[package]
|
||||
name = "training_modpack"
|
||||
version = "4.0.0"
|
||||
authors = ["jugeeya <jugeeya@live.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
skyline = { git = "https://github.com/ultimate-research/skyline-rs.git" }
|
||||
skyline_smash = { git = "https://github.com/ultimate-research/skyline-smash.git", branch = "no-cache" }
|
||||
skyline-web = { git = "https://github.com/skyline-rs/skyline-web.git" }
|
||||
bitflags = "1.2.1"
|
||||
parking_lot = { version = "0.12.0", features = ["nightly"] }
|
||||
lazy_static = "1.4.0"
|
||||
owo-colors = "2.1.0"
|
||||
once_cell = "1.12.0"
|
||||
ramhorns = "0.12.0"
|
||||
paste = "1.0"
|
||||
num = "0.4.0"
|
||||
num-derive = "0.3"
|
||||
num-traits = "0.2"
|
||||
wsl = "0.1.0"
|
||||
strum = "0.21.0"
|
||||
strum_macros = "0.21.0"
|
||||
minreq = { version = "2", features = ["https-native", "json-using-serde"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
toml = "0.5.9"
|
||||
training_mod_consts = { path = "training_mod_consts" }
|
||||
training_mod_tui = { path = "training_mod_tui" }
|
||||
native-tls = { version = "0.2.11", features = ["vendored"] }
|
||||
|
||||
[patch.crates-io]
|
||||
native-tls = { git = "https://github.com/skyline-rs/rust-native-tls", rev = "f202fca" }
|
||||
nnsdk = { git = "https://github.com/ultimate-research/nnsdk-rs" }
|
||||
|
||||
[profile.dev]
|
||||
panic = "abort"
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
lto = true
|
||||
|
||||
[package.metadata.skyline]
|
||||
titleid = "01006A800016E000"
|
||||
plugin-dependencies = [
|
||||
{ name = "libnro_hook.nro", url = "https://github.com/ultimate-research/nro-hook-plugin/releases/download/v0.4.0/libnro_hook.nro" },
|
||||
{ name = "libparam_hook.nro", url = "https://github.com/ultimate-research/params-hook-plugin/releases/download/v0.1.1/libparam_hook.nro" },
|
||||
{ name = "libnn_hid_hook.nro", url = "https://github.com/jugeeya/nn-hid-hook/releases/download/beta/libnn_hid_hook.nro" }
|
||||
]
|
||||
|
||||
[features]
|
||||
outside_training_mode = []
|
||||
web_session_single_thread = []
|
||||
[package]
|
||||
name = "training_modpack"
|
||||
version = "4.0.0"
|
||||
authors = ["jugeeya <jugeeya@live.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
skyline = { git = "https://github.com/ultimate-research/skyline-rs.git" }
|
||||
skyline_smash = { git = "https://github.com/ultimate-research/skyline-smash.git", branch = "no-cache" }
|
||||
skyline-web = { git = "https://github.com/skyline-rs/skyline-web.git" }
|
||||
bitflags = "1.2.1"
|
||||
parking_lot = { version = "0.12.0", features = ["nightly"] }
|
||||
lazy_static = "1.4.0"
|
||||
owo-colors = "2.1.0"
|
||||
once_cell = "1.12.0"
|
||||
ramhorns = "0.12.0"
|
||||
paste = "1.0"
|
||||
num = "0.4.0"
|
||||
num-derive = "0.3"
|
||||
num-traits = "0.2"
|
||||
wsl = "0.1.0"
|
||||
strum = "0.21.0"
|
||||
strum_macros = "0.21.0"
|
||||
minreq = { version = "2", features = ["https-native", "json-using-serde"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
toml = "0.5.9"
|
||||
training_mod_consts = { path = "training_mod_consts" }
|
||||
training_mod_tui = { path = "training_mod_tui" }
|
||||
native-tls = { version = "0.2.11", features = ["vendored"] }
|
||||
log = "0.4.17"
|
||||
|
||||
[patch.crates-io]
|
||||
native-tls = { git = "https://github.com/skyline-rs/rust-native-tls", rev = "f202fca" }
|
||||
nnsdk = { git = "https://github.com/ultimate-research/nnsdk-rs" }
|
||||
|
||||
[profile.dev]
|
||||
panic = "abort"
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
lto = true
|
||||
|
||||
[package.metadata.skyline]
|
||||
titleid = "01006A800016E000"
|
||||
plugin-dependencies = [
|
||||
{ name = "libnro_hook.nro", url = "https://github.com/ultimate-research/nro-hook-plugin/releases/download/v0.4.0/libnro_hook.nro" },
|
||||
{ name = "libparam_hook.nro", url = "https://github.com/ultimate-research/params-hook-plugin/releases/download/v0.1.1/libparam_hook.nro" },
|
||||
{ name = "libnn_hid_hook.nro", url = "https://github.com/jugeeya/nn-hid-hook/releases/download/beta/libnn_hid_hook.nro" }
|
||||
]
|
||||
|
||||
[features]
|
||||
outside_training_mode = []
|
||||
web_session_single_thread = []
|
||||
|
|
|
@ -61,7 +61,7 @@ struct TopLevelBtnComboConfig {
|
|||
}
|
||||
|
||||
pub fn validate_config(data: &str) -> bool {
|
||||
let conf: TopLevelBtnComboConfig = toml::from_str(data).unwrap();
|
||||
let conf: TopLevelBtnComboConfig = toml::from_str(data).expect("Custom button config has invalid schema");
|
||||
let conf = conf.button_config;
|
||||
let configs = [conf.open_menu, conf.save_state, conf.load_state];
|
||||
let bad_keys = configs
|
||||
|
@ -117,7 +117,7 @@ pub fn save_all_btn_config_from_defaults() {
|
|||
}
|
||||
|
||||
pub fn save_all_btn_config_from_toml(data: &str) {
|
||||
let conf: TopLevelBtnComboConfig = toml::from_str(data).unwrap();
|
||||
let conf: TopLevelBtnComboConfig = toml::from_str(data).expect("Could not parse button config");
|
||||
unsafe {
|
||||
// This println is necessary. Why?.......
|
||||
println!("{:?}", &conf.button_config.load_state.press);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::common::*;
|
||||
use crate::events::{Event, EVENT_QUEUE};
|
||||
use crate::training::frame_counter;
|
||||
use crate::logging::*;
|
||||
|
||||
use ramhorns::Template;
|
||||
use skyline::info::get_program_id;
|
||||
|
@ -57,11 +58,7 @@ pub unsafe fn write_menu() {
|
|||
.join(format!("{program_id:016X}"))
|
||||
.join(format!("manual_html/html-document/{htdocs_dir}.htdocs/"))
|
||||
.join("training_menu.html");
|
||||
|
||||
let write_resp = fs::write(menu_html_path, data);
|
||||
if write_resp.is_err() {
|
||||
println!("Error!: {}", write_resp.err().unwrap());
|
||||
}
|
||||
fs::write(menu_html_path, data).expect("Failed to write menu HTML file");
|
||||
}
|
||||
|
||||
const MENU_CONF_PATH: &str = "sd:/TrainingModpack/training_modpack_menu.json";
|
||||
|
@ -69,7 +66,7 @@ const MENU_CONF_PATH: &str = "sd:/TrainingModpack/training_modpack_menu.json";
|
|||
pub unsafe fn set_menu_from_json(message: &str) {
|
||||
let web_response = serde_json::from_str::<MenuJsonStruct>(message);
|
||||
let tui_response = serde_json::from_str::<TrainingModpackMenu>(message);
|
||||
println!("Received menu message: {message}");
|
||||
info!("Received menu message: {message}");
|
||||
if let Ok(message_json) = web_response {
|
||||
// Includes both MENU and DEFAULTS_MENU
|
||||
// From Web Applet
|
||||
|
@ -79,7 +76,7 @@ pub unsafe fn set_menu_from_json(message: &str) {
|
|||
MENU_CONF_PATH,
|
||||
serde_json::to_string_pretty(&message_json).unwrap(),
|
||||
)
|
||||
.expect("Failed to write menu settings file");
|
||||
.expect("Failed to write menu settings file from web response");
|
||||
} else if let Ok(message_json) = tui_response {
|
||||
// Only includes MENU
|
||||
// From TUI
|
||||
|
@ -90,7 +87,7 @@ pub unsafe fn set_menu_from_json(message: &str) {
|
|||
defaults_menu: DEFAULTS_MENU,
|
||||
};
|
||||
std::fs::write(MENU_CONF_PATH, serde_json::to_string_pretty(&conf).unwrap())
|
||||
.expect("Failed to write menu settings file");
|
||||
.expect("Failed to write menu settings file from quick menu response");
|
||||
} else {
|
||||
skyline::error::show_error(
|
||||
0x70,
|
||||
|
@ -348,10 +345,10 @@ pub unsafe fn quick_menu_loop() {
|
|||
static mut WEB_MENU_ACTIVE: bool = false;
|
||||
|
||||
unsafe fn spawn_web_session(session: WebSession) {
|
||||
println!("[Training Modpack] Opening menu session...");
|
||||
info!("Opening menu session...");
|
||||
let loaded_msg = session.recv();
|
||||
println!(
|
||||
"[Training Modpack] Received loaded message from web: {}",
|
||||
info!(
|
||||
"Received loaded message from web: {}",
|
||||
&loaded_msg
|
||||
);
|
||||
let message_send = MenuJsonStruct {
|
||||
|
@ -360,7 +357,7 @@ unsafe fn spawn_web_session(session: WebSession) {
|
|||
};
|
||||
session.send_json(&message_send);
|
||||
let message_recv = session.recv();
|
||||
println!("[Training Modpack] Tearing down Training Modpack menu session");
|
||||
info!("Tearing down Training Modpack menu session");
|
||||
session.exit();
|
||||
session.wait_for_exit();
|
||||
set_menu_from_json(&message_recv);
|
||||
|
@ -399,7 +396,7 @@ pub unsafe fn web_session_loop() {
|
|||
// Starting a new session causes some ingame lag.
|
||||
// Investigate whether we can minimize this lag by
|
||||
// waiting until the player is idle or using CPU boost mode
|
||||
println!("[Training Modpack] Starting new menu session...");
|
||||
info!("Starting new menu session...");
|
||||
web_session = Some(new_web_session(true));
|
||||
}
|
||||
} else {
|
||||
|
@ -407,7 +404,7 @@ pub unsafe fn web_session_loop() {
|
|||
// This will avoid conflicts with other web plugins, and helps with stability.
|
||||
// Having the session open too long, especially if the switch has been put to sleep, can cause freezes
|
||||
if let Some(web_session_to_kill) = web_session {
|
||||
println!("[Training Modpack] Tearing down Training Modpack menu session");
|
||||
info!("Tearing down Training Modpack menu session");
|
||||
web_session_to_kill.exit();
|
||||
web_session_to_kill.wait_for_exit();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use skyline_web::DialogOk;
|
||||
use std::fs;
|
||||
use crate::logging::*;
|
||||
|
||||
pub const CURRENT_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
const VERSION_FILE_PATH: &str = "sd:/TrainingModpack/version.txt";
|
||||
|
@ -44,9 +45,9 @@ pub fn version_check() {
|
|||
)
|
||||
);
|
||||
// Remove old menu selections, silently ignoring errors (i.e. if the file doesn't exist)
|
||||
fs::remove_file("sd:/TrainingModpack/training_modpack_menu.conf").unwrap();
|
||||
fs::remove_file("sd:/TrainingModpack/training_modpack_menu.json").unwrap();
|
||||
fs::remove_file("sd:/TrainingModpack/training_modpack_menu_defaults.conf").unwrap();
|
||||
fs::remove_file("sd:/TrainingModpack/training_modpack_menu.conf").unwrap_or_else(|_| error!("Couldn't remove training_modpack_menu.conf"));
|
||||
fs::remove_file("sd:/TrainingModpack/training_modpack_menu.json").unwrap_or_else(|_| error!("Couldn't remove training_modpack_menu.json"));
|
||||
fs::remove_file("sd:/TrainingModpack/training_modpack_menu_defaults.conf").unwrap_or_else(|_| error!("Couldn't remove training_modpack_menu_defaults.conf"));
|
||||
record_current_version(VERSION_FILE_PATH);
|
||||
}
|
||||
VersionCheck::NoFile => {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#![allow(unused_assignments)]
|
||||
#![allow(unused_variables)]
|
||||
use crate::common::consts::*;
|
||||
use crate::logging::*;
|
||||
use skyline::error::show_error;
|
||||
use skyline::hook;
|
||||
use skyline::hooks::A64InlineHook;
|
||||
|
@ -127,7 +128,7 @@ unsafe fn validate_hazards_addrs() -> std::result::Result<(), ()> {
|
|||
}
|
||||
|
||||
pub fn hazard_manager() {
|
||||
println!("[Training Modpack] Applying hazard control mods.");
|
||||
info!("Applying hazard control mods.");
|
||||
unsafe {
|
||||
if let Ok(()) = validate_hazards_addrs() {
|
||||
HAZARD_FLAG_ADDRESS = get_hazard_flag_address() as *mut u8;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::common::{consts::*, *};
|
||||
use crate::logging::*;
|
||||
use smash::app::{self, lua_bind::*, sv_animcmd, sv_system};
|
||||
use smash::lib::{lua_const::*, L2CAgent, L2CValue};
|
||||
use smash::phx::{Hash40, Vector3f};
|
||||
|
@ -369,6 +370,6 @@ unsafe fn mod_handle_handle_set_rebound(
|
|||
}
|
||||
|
||||
pub fn hitbox_visualization() {
|
||||
println!("[Training Modpack] Applying hitbox visualization mods.");
|
||||
info!("Applying hitbox visualization mods.");
|
||||
skyline::install_hooks!(handle_attack, handle_catch, handle_set_rebound);
|
||||
}
|
||||
|
|
47
src/lib.rs
47
src/lib.rs
|
@ -23,6 +23,7 @@ mod training;
|
|||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
mod logging;
|
||||
|
||||
use crate::common::*;
|
||||
use crate::events::{Event, EVENT_QUEUE};
|
||||
|
@ -34,8 +35,8 @@ use std::fs;
|
|||
use crate::menu::quick_menu_loop;
|
||||
#[cfg(feature = "web_session_preload")]
|
||||
use crate::menu::web_session_loop;
|
||||
use owo_colors::OwoColorize;
|
||||
use training_mod_consts::{MenuJsonStruct, OnOff};
|
||||
use crate::logging::*;
|
||||
|
||||
fn nro_main(nro: &NroInfo<'_>) {
|
||||
if nro.module.isLoaded {
|
||||
|
@ -70,21 +71,16 @@ pub fn main() {
|
|||
},
|
||||
};
|
||||
|
||||
let err_msg = format!("thread has panicked at '{msg}', {location}");
|
||||
let err_msg = format!("SSBU Training Modpack has panicked at '{msg}', {location}");
|
||||
skyline::error::show_error(
|
||||
69,
|
||||
"Skyline plugin has panicked! Please open the details and send a screenshot to the developer, then close the game.\n",
|
||||
"SSBU Training Modpack has panicked! Please open the details and send a screenshot to the developer, then close the game.\n",
|
||||
err_msg.as_str(),
|
||||
);
|
||||
}));
|
||||
init_logger().unwrap();
|
||||
|
||||
macro_rules! log {
|
||||
($($arg:tt)*) => {
|
||||
println!("{}{}", "[Training Modpack] ".green(), format!($($arg)*));
|
||||
};
|
||||
}
|
||||
|
||||
log!("Initialized.");
|
||||
info!("Initialized.");
|
||||
unsafe {
|
||||
EVENT_QUEUE.push(Event::smash_open());
|
||||
}
|
||||
|
@ -102,46 +98,43 @@ pub fn main() {
|
|||
|
||||
let ovl_path = "sd:/switch/.overlays/ovlTrainingModpack.ovl";
|
||||
if fs::metadata(ovl_path).is_ok() {
|
||||
log!("Removing ovlTrainingModpack.ovl...");
|
||||
fs::remove_file(ovl_path).unwrap();
|
||||
warn!("Removing ovlTrainingModpack.ovl...");
|
||||
fs::remove_file(ovl_path).expect(&format!("Could not remove {}", ovl_path));
|
||||
}
|
||||
|
||||
log!("Performing version check...");
|
||||
info!("Performing version check...");
|
||||
release::version_check();
|
||||
|
||||
let menu_conf_path = "sd:/TrainingModpack/training_modpack_menu.json";
|
||||
log!("Checking for previous menu in training_modpack_menu.json...");
|
||||
info!("Checking for previous menu in training_modpack_menu.json...");
|
||||
if fs::metadata(menu_conf_path).is_ok() {
|
||||
let menu_conf = fs::read_to_string(menu_conf_path).unwrap();
|
||||
let menu_conf = fs::read_to_string(menu_conf_path).expect(&format!("Could not remove {}", menu_conf_path));
|
||||
if let Ok(menu_conf_json) = serde_json::from_str::<MenuJsonStruct>(&menu_conf) {
|
||||
unsafe {
|
||||
MENU = menu_conf_json.menu;
|
||||
DEFAULTS_MENU = menu_conf_json.defaults_menu;
|
||||
log!("Previous menu found. Loading...");
|
||||
info!("Previous menu found. Loading...");
|
||||
}
|
||||
} else if menu_conf.starts_with("http://localhost") {
|
||||
log!("Previous menu found, with URL schema. Deleting...");
|
||||
fs::remove_file(menu_conf_path).expect("Could not delete menu conf file!");
|
||||
} else {
|
||||
log!("Previous menu found but is invalid. Deleting...");
|
||||
fs::remove_file(menu_conf_path).expect("Could not delete menu conf file!");
|
||||
warn!("Previous menu found but is invalid. Deleting...");
|
||||
fs::remove_file(menu_conf_path).expect(&format!("{} has invalid schema but could not be deleted!", menu_conf_path));
|
||||
}
|
||||
} else {
|
||||
log!("No previous menu file found.");
|
||||
info!("No previous menu file found.");
|
||||
}
|
||||
|
||||
let combo_path = "sd:/TrainingModpack/training_modpack.toml";
|
||||
log!("Checking for previous button combo settings in training_modpack.toml...");
|
||||
info!("Checking for previous button combo settings in training_modpack.toml...");
|
||||
if fs::metadata(combo_path).is_ok() {
|
||||
log!("Previous button combo settings found. Loading...");
|
||||
let combo_conf = fs::read_to_string(combo_path).unwrap();
|
||||
info!("Previous button combo settings found. Loading...");
|
||||
let combo_conf = fs::read_to_string(combo_path).expect(&format!("Could not read {}", combo_path));
|
||||
if button_config::validate_config(&combo_conf) {
|
||||
button_config::save_all_btn_config_from_toml(&combo_conf);
|
||||
} else {
|
||||
button_config::save_all_btn_config_from_defaults();
|
||||
}
|
||||
} else {
|
||||
log!("No previous button combo file found. Creating...");
|
||||
info!("No previous button combo file found. Creating...");
|
||||
fs::write(combo_path, button_config::DEFAULT_BTN_CONFIG)
|
||||
.expect("Failed to write button config conf file");
|
||||
button_config::save_all_btn_config_from_defaults();
|
||||
|
@ -166,7 +159,7 @@ pub fn main() {
|
|||
);
|
||||
|
||||
let url = format!("{host}{path}");
|
||||
minreq::post(url).with_json(&event).unwrap().send().ok();
|
||||
minreq::post(url).with_json(&event).expect("Failed to send info to firebase").send().ok();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
50
src/logging.rs
Normal file
50
src/logging.rs
Normal file
|
@ -0,0 +1,50 @@
|
|||
pub use log::{error, info, warn};
|
||||
use log::{Level, LevelFilter, Metadata, Record, SetLoggerError};
|
||||
use owo_colors::OwoColorize;
|
||||
|
||||
struct TrainingModpackLogger;
|
||||
|
||||
impl log::Log for TrainingModpackLogger {
|
||||
fn enabled(&self, metadata: &Metadata) -> bool {
|
||||
metadata.level() <= Level::Info
|
||||
}
|
||||
|
||||
fn log(&self, record: &Record) {
|
||||
if self.enabled(record.metadata()) {
|
||||
match record.level() {
|
||||
Level::Error => {
|
||||
println!(
|
||||
"[TrainingModpack] [{}] {}",
|
||||
record.level().red(),
|
||||
record.args()
|
||||
);
|
||||
}
|
||||
Level::Warn => {
|
||||
println!(
|
||||
"[TrainingModpack] [{}] {}",
|
||||
record.level().yellow(),
|
||||
record.args()
|
||||
);
|
||||
}
|
||||
Level::Info => {
|
||||
println!(
|
||||
"[TrainingModpack] [{}] {}",
|
||||
record.level().cyan(),
|
||||
record.args()
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
println!("[TrainingModpack] [{}] {}", record.level(), record.args());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&self) {}
|
||||
}
|
||||
|
||||
static LOGGER: TrainingModpackLogger = TrainingModpackLogger;
|
||||
|
||||
pub fn init_logger() -> Result<(), SetLoggerError> {
|
||||
log::set_logger(&LOGGER).map(|()| log::set_max_level(LevelFilter::Info))
|
||||
}
|
|
@ -3,6 +3,7 @@ use crate::common::{
|
|||
};
|
||||
use crate::hitbox_visualizer;
|
||||
use crate::training::character_specific::items;
|
||||
use crate::logging::*;
|
||||
use skyline::hooks::{getRegionAddress, InlineCtx, Region};
|
||||
use skyline::nn::hid::*;
|
||||
use skyline::nn::ro::LookupSymbol;
|
||||
|
@ -476,7 +477,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
pub fn training_mods() {
|
||||
println!("[Training Modpack] Applying training mods.");
|
||||
info!("Applying training mods.");
|
||||
|
||||
// Input Recording/Delay
|
||||
unsafe {
|
||||
|
|
Loading…
Reference in a new issue