Player list support

This commit is contained in:
August 2026-05-06 15:09:36 -04:00
parent c56f4c7772
commit a493259f7f
Signed by: shibedrill
SSH Key Fingerprint: SHA256:M0m3JW1s38BgO2t0fG146Yxd9OJ2IOqkvCAsuRHQ6Pw
5 changed files with 540 additions and 1428 deletions

1920
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -4,13 +4,8 @@ version = "0.6.1"
edition = "2021"
[dependencies]
anyhow = "1.0.93"
dotenvy = "0.15.7"
log = "0.4.22"
poise = "0.6.1"
pretty_env_logger = "0.5.0"
reqwest = {version = "0.12.9", features = ["json"]}
anyhow = "1.0.102"
reqwest = {version = "0.13.3", features = ["json"]}
serde = {version = "1.0.215", features = ["derive", "serde_derive"]}
serde_json = {version = "1.0.132", features = []}
tokio = {version = "1.41.1", features = ["full"]}
url = "2.5.3"

View File

@ -2,7 +2,7 @@ use reqwest::{header::HeaderValue, Client};
use serde::Deserialize;
use url::Url;
use crate::types::{ServerInfo, ServerOnlineResponse, ServerResponse};
use crate::types::{PlayerList, ServerInfo, ServerOnlineResponse, ServerResponse};
#[derive(Deserialize, Debug)]
struct ApiResponse {
@ -12,10 +12,18 @@ struct ApiResponse {
motd: Option<Motd>,
}
#[derive(Deserialize, Debug, Clone, Copy)]
#[derive(Deserialize, Debug, Clone)]
struct ApiResponsePlayers {
online: u64,
max: u64,
list: Option<Vec<ApiResponsePlayerEntry>>,
}
#[derive(Deserialize, Debug, Clone)]
struct ApiResponsePlayerEntry {
name: String,
#[allow(dead_code)]
uuid: String,
}
#[derive(Deserialize, Debug)]
@ -35,6 +43,7 @@ pub struct OnlineResponse {
players_online: u64,
player_limit: u64,
version: String,
players: Vec<String>,
}
impl ServerOnlineResponse for OnlineResponse {
@ -59,6 +68,12 @@ impl ServerOnlineResponse for OnlineResponse {
}
}
impl PlayerList for OnlineResponse {
fn players(&self) -> &Vec<String> {
&self.players
}
}
pub struct Server {
#[allow(dead_code)]
token: String,
@ -100,14 +115,21 @@ impl ServerInfo for Server {
match json.online {
true => {
let players = json.players.unwrap();
let motd = json.motd.as_ref().unwrap();
self::ServerResponse::Online(OnlineResponse {
searchable_name: self.addr.host().unwrap().to_string(),
reported_name: motd.clean.first().unwrap().into(),
clean_name: motd.clean.first().unwrap().into(),
players_online: json.players.unwrap().online,
player_limit: json.players.unwrap().max,
players_online: players.online,
player_limit: players.max,
version: json.version.unwrap(),
players: players
.list
.unwrap_or(Vec::<ApiResponsePlayerEntry>::new())
.iter()
.map(|e| e.name.clone())
.collect(),
})
}
false => ServerResponse::Offline,

View File

@ -3,7 +3,7 @@ mod types;
use crate::{
handlers::minecraft,
types::{ServerInfo, ServerOnlineResponse, ServerResponse},
types::{PlayerList, ServerInfo, ServerOnlineResponse, ServerResponse},
};
#[tokio::main]
@ -24,7 +24,8 @@ async fn main() {
online_info.version(),
online_info.players_online(),
online_info.player_limit()
)
);
println!("Players online: {}", online_info.players().join(", "));
}
}
}

View File

@ -15,6 +15,10 @@ pub trait ServerOnlineResponse {
fn readable_name(&self) -> &String;
}
pub trait PlayerList {
fn players(&self) -> &Vec<String>;
}
#[allow(dead_code)]
pub trait ServerInfo {
fn new(token: String, addr: Url) -> Self;