mirror of
https://github.com/LordMZTE/mcstat.git
synced 2024-04-29 20:34:22 +02:00
add debug logging
This commit is contained in:
parent
af22c22406
commit
d97383f31f
|
@ -9,8 +9,10 @@ edition = "2018"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64 = "0.13.0"
|
base64 = "0.13.0"
|
||||||
crossterm = "0.21.0"
|
crossterm = "0.21.0"
|
||||||
|
env_logger = "0.9.0"
|
||||||
image = "0.23.14"
|
image = "0.23.14"
|
||||||
itertools = "0.10.1"
|
itertools = "0.10.1"
|
||||||
|
log = "0.4.14"
|
||||||
miette = { version = "3.2.0", features = ["fancy"] }
|
miette = { version = "3.2.0", features = ["fancy"] }
|
||||||
serde_json = "1.0.68"
|
serde_json = "1.0.68"
|
||||||
smart-default = "0.6.0"
|
smart-default = "0.6.0"
|
||||||
|
|
|
@ -8,6 +8,7 @@ use crossterm::{
|
||||||
};
|
};
|
||||||
use image::{DynamicImage, ImageFormat};
|
use image::{DynamicImage, ImageFormat};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use log::info;
|
||||||
use miette::{bail, miette, IntoDiagnostic, WrapErr};
|
use miette::{bail, miette, IntoDiagnostic, WrapErr};
|
||||||
use std::{
|
use std::{
|
||||||
io::{self, Cursor, Write},
|
io::{self, Cursor, Write},
|
||||||
|
@ -35,9 +36,11 @@ macro_rules! none_if_empty {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn resolve_address(addr_and_port: &str) -> miette::Result<(String, u16)> {
|
pub async fn resolve_address(addr_and_port: &str) -> miette::Result<(String, u16)> {
|
||||||
|
info!("Resolving address");
|
||||||
let addr;
|
let addr;
|
||||||
let port;
|
let port;
|
||||||
if let Some((addr_, port_)) = addr_and_port.split_once(':') {
|
if let Some((addr_, port_)) = addr_and_port.split_once(':') {
|
||||||
|
info!("Address has explicit port");
|
||||||
addr = addr_;
|
addr = addr_;
|
||||||
port = Some(
|
port = Some(
|
||||||
port_
|
port_
|
||||||
|
@ -46,6 +49,7 @@ pub async fn resolve_address(addr_and_port: &str) -> miette::Result<(String, u16
|
||||||
.wrap_err("User provided port is invalid")?,
|
.wrap_err("User provided port is invalid")?,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
info!("Address has no explicit port");
|
||||||
addr = addr_and_port;
|
addr = addr_and_port;
|
||||||
port = None;
|
port = None;
|
||||||
}
|
}
|
||||||
|
@ -53,10 +57,12 @@ pub async fn resolve_address(addr_and_port: &str) -> miette::Result<(String, u16
|
||||||
if let Some(port) = port {
|
if let Some(port) = port {
|
||||||
Ok((addr.to_string(), port))
|
Ok((addr.to_string(), port))
|
||||||
} else if addr.parse::<IpAddr>().is_ok() {
|
} else if addr.parse::<IpAddr>().is_ok() {
|
||||||
|
info!("Got IP address without explicit port, assuming 25565");
|
||||||
// if we only have an IP and no port, there is no domain to lookup so we can
|
// if we only have an IP and no port, there is no domain to lookup so we can
|
||||||
// only default to port 25565.
|
// only default to port 25565.
|
||||||
Ok((addr.to_string(), 25565))
|
Ok((addr.to_string(), 25565))
|
||||||
} else {
|
} else {
|
||||||
|
info!("Sending SRV request");
|
||||||
let dns = TokioAsyncResolver::tokio_from_system_conf()
|
let dns = TokioAsyncResolver::tokio_from_system_conf()
|
||||||
.into_diagnostic()
|
.into_diagnostic()
|
||||||
.wrap_err("Failed to create DNS resolver")?;
|
.wrap_err("Failed to create DNS resolver")?;
|
||||||
|
@ -64,6 +70,7 @@ pub async fn resolve_address(addr_and_port: &str) -> miette::Result<(String, u16
|
||||||
let lookup = dns.srv_lookup(format!("_minecraft._tcp.{}.", addr)).await;
|
let lookup = dns.srv_lookup(format!("_minecraft._tcp.{}.", addr)).await;
|
||||||
|
|
||||||
if let Ok(lookup) = lookup {
|
if let Ok(lookup) = lookup {
|
||||||
|
info!("Found SRV record");
|
||||||
let srv = lookup
|
let srv = lookup
|
||||||
.iter()
|
.iter()
|
||||||
.next()
|
.next()
|
||||||
|
@ -76,6 +83,7 @@ pub async fn resolve_address(addr_and_port: &str) -> miette::Result<(String, u16
|
||||||
|
|
||||||
Ok((addr.to_string(), port))
|
Ok((addr.to_string(), port))
|
||||||
} else {
|
} else {
|
||||||
|
info!("No SRV record found. Defaulting to 25565");
|
||||||
// if there is no SRV record, we have to default to port 25565
|
// if there is no SRV record, we have to default to port 25565
|
||||||
Ok((addr.to_string(), 25565))
|
Ok((addr.to_string(), 25565))
|
||||||
}
|
}
|
||||||
|
@ -187,6 +195,7 @@ pub fn get_table<'a>(
|
||||||
|
|
||||||
/// parses a base64 formatted image
|
/// parses a base64 formatted image
|
||||||
pub fn parse_base64_image(data: String) -> miette::Result<DynamicImage> {
|
pub fn parse_base64_image(data: String) -> miette::Result<DynamicImage> {
|
||||||
|
info!("Parsing base64 image");
|
||||||
let (header, data) = data
|
let (header, data) = data
|
||||||
.split_once(',')
|
.split_once(',')
|
||||||
.ok_or_else(|| miette!("Couldn't parse base64 image due to missing format header."))?;
|
.ok_or_else(|| miette!("Couldn't parse base64 image due to missing format header."))?;
|
||||||
|
|
48
src/main.rs
48
src/main.rs
|
@ -1,6 +1,7 @@
|
||||||
use async_minecraft_ping::{ConnectionConfig, ServerDescription, StatusResponse};
|
use async_minecraft_ping::{ConnectionConfig, ServerDescription, StatusResponse};
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use log::info;
|
||||||
use miette::{IntoDiagnostic, WrapErr};
|
use miette::{IntoDiagnostic, WrapErr};
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use time::{Duration, Instant};
|
use time::{Duration, Instant};
|
||||||
|
@ -82,27 +83,35 @@ impl Opt {
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> miette::Result<()> {
|
async fn main() -> miette::Result<()> {
|
||||||
|
env_logger::try_init()
|
||||||
|
.into_diagnostic()
|
||||||
|
.wrap_err("Failed to init logger")?;
|
||||||
|
|
||||||
let opt = Opt::from_args();
|
let opt = Opt::from_args();
|
||||||
|
|
||||||
let (addr, port) = resolve_address(&opt.ip)
|
let (addr, port) = resolve_address(&opt.ip)
|
||||||
.await
|
.await
|
||||||
.wrap_err("Error resolving address")?;
|
.wrap_err("Error resolving address")?;
|
||||||
|
|
||||||
|
info!("Using address '{}:{}'", &addr, &port);
|
||||||
|
|
||||||
let config = ConnectionConfig::build(addr)
|
let config = ConnectionConfig::build(addr)
|
||||||
.with_port(port)
|
.with_port(port)
|
||||||
.with_protocol_version(opt.protocol_version);
|
.with_protocol_version(opt.protocol_version);
|
||||||
|
|
||||||
// create timeout for server connection
|
// create timeout for server connection
|
||||||
let (raw_response, ping) = time::timeout(Duration::from_millis(opt.timeout), async {
|
let (raw_response, ping) = time::timeout(Duration::from_millis(opt.timeout), async {
|
||||||
|
info!("Connecting to server");
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
let mut con = config.connect().await.into_diagnostic()?;
|
let mut con = config.connect().await.into_diagnostic()?;
|
||||||
// we end the timer here, because at this point, we've sent ONE request to the
|
// we end the timer here, because at this point, we've sent ONE request to the
|
||||||
// server, and we don't want to send 2, since then we get double the
|
// server, and we don't want to send 2, since then we get double the
|
||||||
// ping. the connect function may have some processing which may take
|
// ping. the connect function may have some processing which may take
|
||||||
// some time, but it shouldn't make an impact at this code runs at rust
|
// some time, but it shouldn't make an impact since this code runs at rust
|
||||||
// speed.
|
// speed.
|
||||||
let end_time = Instant::now();
|
let end_time = Instant::now();
|
||||||
|
|
||||||
|
info!("Requesting status");
|
||||||
let status = con.status_raw().await.into_diagnostic()?;
|
let status = con.status_raw().await.into_diagnostic()?;
|
||||||
Result::<_, miette::Error>::Ok((status, end_time - start_time))
|
Result::<_, miette::Error>::Ok((status, end_time - start_time))
|
||||||
})
|
})
|
||||||
|
@ -115,10 +124,9 @@ async fn main() -> miette::Result<()> {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info!("Parsing status");
|
||||||
let response = serde_json::from_str::<StatusResponse>(&raw_response).into_diagnostic()?;
|
let response = serde_json::from_str::<StatusResponse>(&raw_response).into_diagnostic()?;
|
||||||
// endregion
|
|
||||||
|
|
||||||
// region printing
|
|
||||||
// if the server has mods, and the user hasn't used the -m argument, notify
|
// if the server has mods, and the user hasn't used the -m argument, notify
|
||||||
// that.
|
// that.
|
||||||
if let (false, Some(_)) = (opt.mods, response.forge_mod_info()) {
|
if let (false, Some(_)) = (opt.mods, response.forge_mod_info()) {
|
||||||
|
@ -139,43 +147,9 @@ async fn main() -> miette::Result<()> {
|
||||||
let decoded = parse_base64_image(img)?;
|
let decoded = parse_base64_image(img)?;
|
||||||
viuer::print(&decoded, &opt.get_viuer_conf()).into_diagnostic()?;
|
viuer::print(&decoded, &opt.get_viuer_conf()).into_diagnostic()?;
|
||||||
}
|
}
|
||||||
// endregion
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns the asciifyed image from base64
|
|
||||||
// returns Err if the base64 image is invalid
|
|
||||||
// async fn asciify_base64_image(favicon: String, config: AsciiConfig) ->
|
|
||||||
// Result<String> { let image = parse_base64_image(favicon)?;
|
|
||||||
//
|
|
||||||
// let builder = config.apply(AsciiBuilder::new_from_image(image));
|
|
||||||
//
|
|
||||||
// let mut buf = if config.colored {
|
|
||||||
// this does not write to stdout but just gets the correct color
|
|
||||||
// information for stdout
|
|
||||||
// let mut buf = BufferWriter::stdout(ColorChoice::Always).buffer();
|
|
||||||
// builder.to_stream_colored(&mut buf);
|
|
||||||
// buf
|
|
||||||
// } else {
|
|
||||||
// let mut buf = Buffer::no_color();
|
|
||||||
// builder.to_stream(&mut buf);
|
|
||||||
// buf
|
|
||||||
// };
|
|
||||||
// reset color
|
|
||||||
// buf.reset()?;
|
|
||||||
//
|
|
||||||
// let bytes = buf.as_slice().to_vec();
|
|
||||||
//
|
|
||||||
// only check utf8 format in debug mode
|
|
||||||
// #[cfg(debug_assertions)]
|
|
||||||
// let out = String::from_utf8(bytes).expect("asciifyed image is invalid utf8");
|
|
||||||
// bytes should always be valid utf8
|
|
||||||
// #[cfg(not(debug_assertions))]
|
|
||||||
// let out = unsafe { String::from_utf8_unchecked(bytes) };
|
|
||||||
//
|
|
||||||
// Ok(out)
|
|
||||||
// }
|
|
||||||
|
|
||||||
fn format_table(
|
fn format_table(
|
||||||
response: &StatusResponse,
|
response: &StatusResponse,
|
||||||
ping: u128,
|
ping: u128,
|
||||||
|
|
Loading…
Reference in a new issue