Skip to content

Commit f2f52f3

Browse files
committed
add query command
1 parent 8b6aac3 commit f2f52f3

File tree

5 files changed

+205
-2
lines changed

5 files changed

+205
-2
lines changed

Cargo.lock

Lines changed: 12 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "mcvcli"
33
description = "A command line interface for managing Minecraft servers."
4-
version = "2.3.7"
4+
version = "2.4.0"
55
edition = "2024"
66
license = "MIT"
77
homepage = "https://github.com/mcjars/mcvcli"
@@ -38,3 +38,4 @@ rand = "0.9.0"
3838
ipipe = "0.11.7"
3939
xz2 = "0.1.7"
4040
atoi = "2.0.0"
41+
msp = "0.1.2"

src/commands/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub mod java;
77
pub mod lookup;
88
pub mod mods;
99
pub mod profile;
10+
pub mod query;
1011
pub mod start;
1112
pub mod status;
1213
pub mod stop;

src/commands/query.rs

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
use clap::ArgMatches;
2+
use colored::Colorize;
3+
4+
pub async fn query(matches: &ArgMatches) -> i32 {
5+
let mut address = matches
6+
.get_one::<String>("address")
7+
.expect("required")
8+
.to_string();
9+
let use_query = matches.get_one::<bool>("query").expect("required");
10+
11+
if !address.contains(':') {
12+
address.push_str(":25565");
13+
}
14+
15+
println!(
16+
"{} {}{}",
17+
"querying server".bright_black(),
18+
address.bright_cyan(),
19+
"...".bright_black()
20+
);
21+
22+
let (host, port) = match address.split_once(':') {
23+
Some((host, port)) => (host.to_string(), port.parse::<u16>().unwrap_or(25565)),
24+
None => (address.clone(), 25565),
25+
};
26+
27+
let server = msp::Conf::create_with_port(&host, port);
28+
29+
if *use_query {
30+
let status = match server.query_full() {
31+
Ok(status) => status,
32+
Err(e) => {
33+
println!("{}: {}", "Error".red(), e);
34+
return 1;
35+
}
36+
};
37+
38+
println!("{:?}", status);
39+
} else {
40+
match server.get_server_status() {
41+
Ok(status) => {
42+
println!(
43+
"{} {}{} {}",
44+
"querying server".bright_black(),
45+
address.bright_cyan(),
46+
"...".bright_black(),
47+
"DONE".green().bold()
48+
);
49+
println!();
50+
51+
println!("{}", address.bright_cyan().underline());
52+
println!(
53+
" {} {}",
54+
"version:".bright_black(),
55+
status.version.name.cyan()
56+
);
57+
println!(
58+
" {} {}",
59+
"protocol:".bright_black(),
60+
status.version.protocol.to_string().cyan()
61+
);
62+
63+
println!(" {}", "players:".bright_black());
64+
println!(
65+
" {} {}",
66+
"online:".bright_black(),
67+
status.players.online.to_string().cyan()
68+
);
69+
println!(
70+
" {} {}",
71+
"max:".bright_black(),
72+
status.players.max.to_string().cyan()
73+
);
74+
println!(" {}", "sample:".bright_black());
75+
for player in status.players.sample {
76+
println!(" {}", player.name.cyan());
77+
}
78+
79+
println!(" {}", "motd:".bright_black());
80+
for line in status.description.text.lines() {
81+
println!(" {}", line.cyan());
82+
}
83+
}
84+
Err(_) => {
85+
let status = match server.get_netty_server_status() {
86+
Ok(status) => status,
87+
Err(_) => match server.get_legacy_server_status() {
88+
Ok(status) => status,
89+
Err(_) => {
90+
let status = match server.get_beta_legacy_server_status() {
91+
Ok(status) => status,
92+
Err(e) => {
93+
println!("{}: {}", "Error".red(), e);
94+
return 1;
95+
}
96+
};
97+
98+
println!(
99+
"{} {}{} {}",
100+
"querying server".bright_black(),
101+
address.bright_cyan(),
102+
"...".bright_black(),
103+
"DONE".green().bold()
104+
);
105+
println!();
106+
107+
println!("{}", address.bright_cyan().underline());
108+
println!(" {}", "players:".bright_black());
109+
println!(
110+
" {} {}",
111+
"online:".bright_black(),
112+
status.online_players.to_string().cyan()
113+
);
114+
println!(
115+
" {} {}",
116+
"max:".bright_black(),
117+
status.max_players.to_string().cyan()
118+
);
119+
120+
return 0;
121+
}
122+
},
123+
};
124+
125+
println!(
126+
"{} {}{} {}",
127+
"querying server".bright_black(),
128+
address.bright_cyan(),
129+
"...".bright_black(),
130+
"DONE".green().bold()
131+
);
132+
println!();
133+
134+
println!("{}", address.bright_cyan().underline());
135+
println!(
136+
" {} {}",
137+
"version:".bright_black(),
138+
status.server_version.cyan()
139+
);
140+
println!(
141+
" {} {}",
142+
"protocol:".bright_black(),
143+
status.protocol_version.to_string().cyan()
144+
);
145+
146+
println!(" {}", "players:".bright_black());
147+
println!(
148+
" {} {}",
149+
"online:".bright_black(),
150+
status.online_players.to_string().cyan()
151+
);
152+
println!(
153+
" {} {}",
154+
"max:".bright_black(),
155+
status.max_players.to_string().cyan()
156+
);
157+
158+
println!(" {}", "motd:".bright_black());
159+
for line in status.motd.lines() {
160+
println!(" {}", line.cyan());
161+
}
162+
}
163+
};
164+
}
165+
166+
0
167+
}

src/main.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,26 @@ fn cli() -> Command {
251251
)
252252
.arg_required_else_help(true),
253253
)
254+
.subcommand(
255+
Command::new("query")
256+
.about("Queries the Minecraft server for information")
257+
.arg(
258+
Arg::new("address")
259+
.help("The address of the Minecraft server to query (e.g., `example.com:25565`)")
260+
.num_args(1)
261+
.required(true),
262+
)
263+
.arg(
264+
Arg::new("query")
265+
.long("query")
266+
.short('q')
267+
.help("Use the query protocol to get more information (requires server to have query enabled)")
268+
.num_args(0)
269+
.default_value("false")
270+
.value_parser(clap::value_parser!(bool))
271+
.required(false),
272+
)
273+
)
254274
.subcommand(
255275
Command::new("version")
256276
.about("Gets the installed version of the Minecraft server")
@@ -477,6 +497,9 @@ async fn main() {
477497
Some(("lookup", sub_matches)) => {
478498
std::process::exit(commands::lookup::lookup(sub_matches).await)
479499
}
500+
Some(("query", sub_matches)) => {
501+
std::process::exit(commands::query::query(sub_matches).await)
502+
}
480503
Some(("version", sub_matches)) => {
481504
std::process::exit(commands::version::version(sub_matches).await)
482505
}

0 commit comments

Comments
 (0)