mirror of
https://github.com/LordMZTE/mcstat.git
synced 2024-05-06 22:41:10 +02:00
add timeout to mcstat
This commit is contained in:
parent
68096eb2d2
commit
e3387624e8
|
@ -17,6 +17,12 @@ args:
|
||||||
help: "the protocol version to use"
|
help: "the protocol version to use"
|
||||||
default_value: "751"
|
default_value: "751"
|
||||||
takes_value: true
|
takes_value: true
|
||||||
|
- timeout:
|
||||||
|
long: "timeout"
|
||||||
|
short: t
|
||||||
|
help: "the time before the server ping times out in milliseconds"
|
||||||
|
takes_value: true
|
||||||
|
default_value: "500"
|
||||||
|
|
||||||
# IMAGE ARGS
|
# IMAGE ARGS
|
||||||
# TODO due to a bug in clap, the image argument is always required because size has a default value
|
# TODO due to a bug in clap, the image argument is always required because size has a default value
|
||||||
|
|
80
src/main.rs
80
src/main.rs
|
@ -2,52 +2,81 @@
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate mcstat;
|
extern crate mcstat;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate anyhow;
|
||||||
|
|
||||||
use std::io::{Cursor, Write};
|
use std::io::{Cursor, Write};
|
||||||
|
use time::Duration;
|
||||||
|
use tokio::time;
|
||||||
|
|
||||||
use mcstat::{AsciiConfig, remove_formatting};
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use asciify::AsciiBuilder;
|
use asciify::AsciiBuilder;
|
||||||
use async_minecraft_ping::ConnectionConfig;
|
use async_minecraft_ping::{ConnectionConfig, StatusResponse};
|
||||||
use clap::App;
|
use clap::App;
|
||||||
use image::ImageFormat;
|
use image::ImageFormat;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use mcstat::{remove_formatting, AsciiConfig};
|
||||||
use termcolor::{Buffer, BufferWriter, ColorChoice, WriteColor};
|
use termcolor::{Buffer, BufferWriter, ColorChoice, WriteColor};
|
||||||
|
|
||||||
|
const ARGUMENT_FAIL_MESSAGE: &str = "failed to get value from args";
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
let yaml = load_yaml!("args.yml");
|
let yaml = load_yaml!("args.yml");
|
||||||
let matches = App::from_yaml(yaml).get_matches();
|
let matches = App::from_yaml(yaml).get_matches();
|
||||||
|
|
||||||
//region Network
|
//region Network
|
||||||
let config = ConnectionConfig::build(matches.value_of("ip").unwrap().to_owned())
|
let config = ConnectionConfig::build(
|
||||||
.with_port(
|
matches
|
||||||
matches
|
.value_of("ip")
|
||||||
.value_of("port")
|
.context(ARGUMENT_FAIL_MESSAGE)?
|
||||||
.unwrap()
|
.to_owned(),
|
||||||
.parse()
|
)
|
||||||
.ok()
|
.with_port(
|
||||||
.and_then(|p| if p > 0 && p < u16::MAX { Some(p) } else { None })
|
matches
|
||||||
.context("invalid port")?,
|
.value_of("port")
|
||||||
)
|
.context(ARGUMENT_FAIL_MESSAGE)?
|
||||||
.with_protocol_version(
|
.parse()
|
||||||
matches
|
.context("invalid port")
|
||||||
.value_of("protocol-version")
|
.and_then(|p| {
|
||||||
.unwrap()
|
if p > 0 && p < u16::MAX {
|
||||||
.parse()
|
Ok(p)
|
||||||
.context("invalid protocol version")?,
|
} else {
|
||||||
);
|
Err(anyhow!(ARGUMENT_FAIL_MESSAGE))
|
||||||
let mut connection = config.connect().await?;
|
}
|
||||||
let response = connection.status().await?;
|
})
|
||||||
|
.context("invalid port")?,
|
||||||
|
)
|
||||||
|
.with_protocol_version(
|
||||||
|
matches
|
||||||
|
.value_of("protocol-version")
|
||||||
|
.context(ARGUMENT_FAIL_MESSAGE)?
|
||||||
|
.parse()
|
||||||
|
.context("invalid protocol version")?,
|
||||||
|
);
|
||||||
|
|
||||||
|
//create timeout for server connection
|
||||||
|
let mut timeout = time::delay_for(Duration::from_millis(
|
||||||
|
matches
|
||||||
|
.value_of("timeout")
|
||||||
|
.context(ARGUMENT_FAIL_MESSAGE)?
|
||||||
|
.parse()
|
||||||
|
.context("timeout is invalid value")?,
|
||||||
|
));
|
||||||
|
|
||||||
|
let response = tokio::select! {
|
||||||
|
_ = &mut timeout => Err(anyhow!("Connection to server timed out")),
|
||||||
|
r = ping_server(config) => r,
|
||||||
|
}?;
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
//region Image
|
//region Image
|
||||||
let image_size: u32 = matches
|
let image_size: u32 = matches
|
||||||
.value_of("size")
|
.value_of("size")
|
||||||
.unwrap()
|
.context("failed to get value from args")?
|
||||||
.parse()
|
.parse()
|
||||||
.with_context(|| "image size must be number")?;
|
.context("image size must be number")?;
|
||||||
let mut image = None;
|
let mut image = None;
|
||||||
|
|
||||||
if let (Some(favicon), true) = (response.favicon, matches.is_present("image")) {
|
if let (Some(favicon), true) = (response.favicon, matches.is_present("image")) {
|
||||||
//The image parsing and asciifying is done while the table is printing
|
//The image parsing and asciifying is done while the table is printing
|
||||||
image = Some(tokio::spawn(get_image(
|
image = Some(tokio::spawn(get_image(
|
||||||
|
@ -112,3 +141,8 @@ async fn get_image(favicon: String, config: AsciiConfig) -> Result<Vec<u8>> {
|
||||||
buf.reset()?;
|
buf.reset()?;
|
||||||
Ok(buf.as_slice().to_vec())
|
Ok(buf.as_slice().to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn ping_server(server: ConnectionConfig) -> Result<StatusResponse> {
|
||||||
|
let mut con = server.connect().await?;
|
||||||
|
con.status().await
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue