Skip to main content

steel_core/command/builtins/
version.rs

1//! Vanilla server-version reporting command.
2
3use steel_registry::packets::CURRENT_MC_PROTOCOL;
4use steel_utils::{Identifier, translations, version};
5use text_components::TextComponent;
6
7use super::super::{
8    brigadier::{CommandNodeBuilder, CommandSyntaxError},
9    execution::{CommandSource, SteelCommandContext, SteelCommandRuntime, literal},
10    registration::CommandRegistration,
11};
12use crate::GIT_HASH_SHORT;
13
14pub(super) fn registration() -> CommandRegistration<CommandSource> {
15    CommandRegistration::new(Identifier::vanilla_static("version"), |_| command())
16}
17
18fn command() -> CommandNodeBuilder<CommandSource, SteelCommandRuntime> {
19    literal("version").executes(send_version)
20}
21
22/// Reports the targeted Minecraft version details.
23#[expect(
24    clippy::unnecessary_wraps,
25    reason = "Command executors use a shared fallible callback signature."
26)]
27fn send_version(context: &SteelCommandContext<CommandSource>) -> Result<i32, CommandSyntaxError> {
28    let source = context.source();
29    source.send_system_message(&TextComponent::from(&translations::COMMANDS_VERSION_HEADER));
30    source.send_system_message(
31        &translations::COMMANDS_VERSION_ID
32            .message([version::VERSION_ID])
33            .component(),
34    );
35    source.send_system_message(
36        &translations::COMMANDS_VERSION_NAME
37            .message([version::VERSION_NAME])
38            .component(),
39    );
40    source.send_system_message(
41        &translations::COMMANDS_VERSION_DATA
42            .message([version::DATA_VERSION.to_string()])
43            .component(),
44    );
45    source.send_system_message(
46        &translations::COMMANDS_VERSION_SERIES
47            .message([version::DATA_VERSION_SERIES])
48            .component(),
49    );
50    source.send_system_message(
51        &translations::COMMANDS_VERSION_PROTOCOL
52            .message([
53                CURRENT_MC_PROTOCOL.to_string(),
54                format!("0x{CURRENT_MC_PROTOCOL:x}"),
55            ])
56            .component(),
57    );
58    source.send_system_message(
59        &translations::COMMANDS_VERSION_BUILD_TIME
60            .message([version::BUILD_TIME])
61            .component(),
62    );
63    source.send_system_message(
64        &translations::COMMANDS_VERSION_PACK_RESOURCE
65            .message([version::RESOURCE_PACK_VERSION])
66            .component(),
67    );
68    source.send_system_message(
69        &translations::COMMANDS_VERSION_PACK_DATA
70            .message([version::DATA_PACK_VERSION])
71            .component(),
72    );
73    let stable = if version::STABLE {
74        &translations::COMMANDS_VERSION_STABLE_YES
75    } else {
76        &translations::COMMANDS_VERSION_STABLE_NO
77    };
78    source.send_system_message(&TextComponent::from(stable));
79    source.send_system_message(&TextComponent::plain(format!(
80        "steel_commit = {GIT_HASH_SHORT}"
81    )));
82    Ok(1)
83}
84
85#[cfg(test)]
86mod tests {
87    use steel_registry::init_vanilla_registry;
88
89    use super::super::create_dispatcher;
90
91    #[test]
92    fn version_is_a_bare_executable_literal() {
93        init_vanilla_registry();
94        let Ok(dispatcher) = create_dispatcher() else {
95            panic!("built-in commands should register");
96        };
97        let Some(version) = dispatcher.children(dispatcher.root()).and_then(|children| {
98            children.iter().copied().find(|child| {
99                dispatcher
100                    .node(*child)
101                    .is_some_and(|node| node.name() == "version")
102            })
103        }) else {
104            panic!("version root should exist");
105        };
106        let Some(node) = dispatcher.node(version) else {
107            panic!("version root node should exist");
108        };
109        assert!(node.is_executable());
110        assert!(node.argument_type().is_none());
111    }
112}