Extend status collector
Information about the currently loaded/ticked chunks have been added.
This commit is contained in:
parent
461d66a3d9
commit
4d60e14d43
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -613,7 +613,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "glados"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
dependencies = [
|
||||
"dotenv",
|
||||
"influx_db_client",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "glados"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ lazy_static! {
|
|||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct Args {
|
||||
#[structopt(long, env = "DATA_COLLECTOR_ENABLE", takes_value = false)]
|
||||
#[structopt(long, env = "DATA_COLLECTOR_ENABLE", takes_value = false, requires_all = &["influx-host", "influx-db", "influx-user", "influx-password"])]
|
||||
pub enable_data_collector: bool,
|
||||
|
||||
#[structopt(long = "token",
|
||||
|
|
|
@ -24,6 +24,8 @@ pub enum Error {
|
|||
RconListCmd(#[source] nom::Err<nom::error::Error<String>>),
|
||||
#[error("Parsing results of `whois` command: {_0}")]
|
||||
RconWhoIsCmd(#[source] nom::Err<nom::error::Error<String>>),
|
||||
#[error("Parsing results of `paper chunkinfo` command: {_0}")]
|
||||
RconWorldInfoCmd(#[source] nom::Err<nom::error::Error<String>>),
|
||||
#[error("Parsing member filter of `~filter` command: {_0}")]
|
||||
ParseMemberFilter(#[source] nom::Err<nom::error::Error<String>>),
|
||||
#[error("Unknown role {_0:?} in filter")]
|
||||
|
|
|
@ -3,6 +3,7 @@ use serenity::client::Context;
|
|||
|
||||
use std::collections::HashMap;
|
||||
|
||||
mod world_info;
|
||||
mod player_info;
|
||||
mod tps;
|
||||
|
||||
|
@ -14,6 +15,7 @@ use crate::{
|
|||
};
|
||||
|
||||
use self::{
|
||||
world_info::{WorldInfo, WorldInfoCmd},
|
||||
player_info::{ListCmd, PlayerInfo},
|
||||
tps::{Tps, TpsCmd},
|
||||
};
|
||||
|
@ -23,6 +25,7 @@ pub struct Status {
|
|||
pub amount_online: u32,
|
||||
/// List of players associated with their online status.
|
||||
pub players: HashMap<MinecraftPlayer, bool>,
|
||||
pub world_info: WorldInfo,
|
||||
}
|
||||
|
||||
impl Status {
|
||||
|
@ -45,11 +48,13 @@ impl Status {
|
|||
for (_ign, uuid) in online_players {
|
||||
players.insert(MinecraftPlayer::from_uuid(ctx, uuid).await?, true);
|
||||
}
|
||||
let world_info = RconHandle::cmd(&WorldInfoCmd, ctx).await?;
|
||||
|
||||
Ok(Status {
|
||||
tps,
|
||||
amount_online,
|
||||
players,
|
||||
world_info,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -58,7 +63,84 @@ impl Status {
|
|||
let status = Point::new("status")
|
||||
.add_field("tps", self.tps.min1)
|
||||
// Safe, since we started with u32
|
||||
.add_field("player_count", self.amount_online as i64);
|
||||
.add_field("player_count", self.amount_online as i64)
|
||||
.add_field(
|
||||
"world_total_chunks",
|
||||
self.world_info.overworld.total_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"world_inactive_chunks",
|
||||
self.world_info.overworld.inactive_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"world_border_chunks",
|
||||
self.world_info.overworld.border_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"world_ticking_chunks",
|
||||
self.world_info.overworld.ticking_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"world_entity_chunks",
|
||||
self.world_info.overworld.entity_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"nether_total_chunks",
|
||||
self.world_info.nether.total_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"nether_inactive_chunks",
|
||||
self.world_info.nether.inactive_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"nether_border_chunks",
|
||||
self.world_info.nether.border_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"nether_ticking_chunks",
|
||||
self.world_info.nether.ticking_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"nether_entity_chunks",
|
||||
self.world_info.nether.entity_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"the_end_total_chunks",
|
||||
self.world_info.the_end.total_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"the_end_inactive_chunks",
|
||||
self.world_info.the_end.inactive_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"the_end_border_chunks",
|
||||
self.world_info.the_end.border_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"the_end_ticking_chunks",
|
||||
self.world_info.the_end.ticking_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"the_end_entity_chunks",
|
||||
self.world_info.the_end.entity_chunks as i64,
|
||||
)
|
||||
.add_field("all_total_chunks", self.world_info.all.total_chunks as i64)
|
||||
.add_field(
|
||||
"all_inactive_chunks",
|
||||
self.world_info.all.inactive_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"all_border_chunks",
|
||||
self.world_info.all.border_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"all_ticking_chunks",
|
||||
self.world_info.all.ticking_chunks as i64,
|
||||
)
|
||||
.add_field(
|
||||
"all_entity_chunks",
|
||||
self.world_info.all.entity_chunks as i64,
|
||||
);
|
||||
points.push(status);
|
||||
let mut activity = Point::new("activity");
|
||||
for (player, is_online) in &self.players {
|
||||
|
|
118
src/tracking/status/world_info.rs
Normal file
118
src/tracking/status/world_info.rs
Normal file
|
@ -0,0 +1,118 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use nom::{
|
||||
bytes::complete::tag,
|
||||
character::complete::char,
|
||||
combinator::{map, opt, recognize},
|
||||
sequence::{pair, preceded, tuple},
|
||||
IResult, Parser,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
error::{Error, Result},
|
||||
rcon::RconCommand,
|
||||
};
|
||||
|
||||
pub struct WorldInfoCmd;
|
||||
|
||||
pub struct WorldInfo {
|
||||
pub overworld: WorldInfoPart<Overworld>,
|
||||
pub nether: WorldInfoPart<Nether>,
|
||||
pub the_end: WorldInfoPart<TheEnd>,
|
||||
pub all: WorldInfoPart<AllWorlds>,
|
||||
}
|
||||
|
||||
pub trait World {
|
||||
const NAME: &'static str;
|
||||
}
|
||||
|
||||
macro_rules! world {
|
||||
($ident:ident: $name:literal) => {
|
||||
pub struct $ident;
|
||||
impl World for $ident {
|
||||
const NAME: &'static str = $name;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
world!(Overworld: "world");
|
||||
world!(Nether: "world_nether");
|
||||
world!(TheEnd: "world_the_end");
|
||||
world!(AllWorlds: "all listed worlds");
|
||||
|
||||
pub struct WorldInfoPart<W: World> {
|
||||
pub total_chunks: u32,
|
||||
pub inactive_chunks: u32,
|
||||
pub border_chunks: u32,
|
||||
pub ticking_chunks: u32,
|
||||
pub entity_chunks: u32,
|
||||
_world: PhantomData<W>,
|
||||
}
|
||||
|
||||
impl RconCommand for WorldInfoCmd {
|
||||
type Output = WorldInfo;
|
||||
|
||||
fn as_string(&self) -> String {
|
||||
String::from("paper chunkinfo")
|
||||
}
|
||||
|
||||
fn parse(&self, raw: String) -> Result<Self::Output> {
|
||||
parse_chunkinfo_result(&raw)
|
||||
.map(|(_, world_info)| world_info)
|
||||
.map_err(|why| Error::RconWorldInfoCmd(why.to_owned()))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_chunkinfo_result(inp: &str) -> IResult<&str, WorldInfo> {
|
||||
let world = WorldInfoPart::<Overworld>::parse;
|
||||
let world_nether = WorldInfoPart::<Nether>::parse;
|
||||
let world_the_end = WorldInfoPart::<TheEnd>::parse;
|
||||
let all_worlds = WorldInfoPart::<AllWorlds>::parse;
|
||||
map(
|
||||
tuple((world, world_nether, world_the_end, all_worlds)),
|
||||
|(overworld, nether, the_end, all)| WorldInfo {
|
||||
overworld,
|
||||
nether,
|
||||
the_end,
|
||||
all,
|
||||
},
|
||||
)(inp)
|
||||
}
|
||||
|
||||
impl<W: World> WorldInfoPart<W> {
|
||||
pub fn parse(inp: &str) -> IResult<&str, Self> {
|
||||
preceded(Self::parse_headline, Self::parse_info)(inp)
|
||||
}
|
||||
|
||||
fn parse_headline(inp: &str) -> IResult<&str, &str> {
|
||||
recognize(tuple((tag("§9Chunks in §a"), tag(W::NAME), tag("§3:\n"))))(inp)
|
||||
}
|
||||
|
||||
fn parse_info<'i>(inp: &'i str) -> IResult<&'i str, Self> {
|
||||
let total = Self::parse_entry("Total");
|
||||
let inactive = Self::parse_entry("Inactive");
|
||||
let border = Self::parse_entry("Border");
|
||||
let ticking = Self::parse_entry("Ticking");
|
||||
let entity = Self::parse_entry("Entity");
|
||||
map(
|
||||
tuple((total, inactive, border, ticking, entity, char('\n'))),
|
||||
|(total, inactive, border, ticking, entity, _)| Self {
|
||||
total_chunks: total,
|
||||
inactive_chunks: inactive,
|
||||
border_chunks: border,
|
||||
ticking_chunks: ticking,
|
||||
entity_chunks: entity,
|
||||
_world: PhantomData,
|
||||
},
|
||||
)(inp)
|
||||
}
|
||||
|
||||
fn parse_entry<'i, E>(key: &'static str) -> impl Parser<&'i str, u32, E>
|
||||
where
|
||||
E: nom::error::ParseError<&'i str>,
|
||||
{
|
||||
use nom::character::complete::u32;
|
||||
let key = preceded(pair(tag("§9"), opt(char(' '))), tag(key));
|
||||
map(tuple((key, tag(": §3"), u32)), |(_, _, num)| num)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue