Skip to main content

steel_core/command/builtins/
transfer.rs

1use std::sync::Arc;
2
3use steel_protocol::packets::common::CTransfer;
4use steel_utils::{Identifier, translations};
5use text_components::TextComponent;
6
7use crate::{
8    command::{
9        brigadier::{ArgumentType, CommandContext, CommandNodeBuilder, CommandSyntaxError},
10        execution::{CommandSource, SteelArgumentType, SteelCommandRuntime, argument, literal},
11        registration::CommandRegistration,
12    },
13    entity::Entity,
14    player::Player,
15};
16
17pub(super) fn registration() -> CommandRegistration<CommandSource> {
18    CommandRegistration::new(Identifier::vanilla_static("transfer"), |_| command())
19}
20
21fn command() -> CommandNodeBuilder<CommandSource, SteelCommandRuntime> {
22    literal("transfer").then(
23        argument("hostname", ArgumentType::string())
24            .executes(|c| {
25                transfer(
26                    c.source(),
27                    c.string("hostname")?,
28                    25565,
29                    &[player_executor(c)?],
30                )
31            })
32            .then(
33                argument("port", ArgumentType::integer(1, 65535))
34                    .executes(|c| {
35                        transfer(
36                            c.source(),
37                            c.string("hostname")?,
38                            c.integer("port")?,
39                            &[player_executor(c)?],
40                        )
41                    })
42                    .then(
43                        argument("players", SteelArgumentType::players()).executes(|c| {
44                            transfer(
45                                c.source(),
46                                c.string("hostname")?,
47                                c.integer("port")?,
48                                &c.players("players")?,
49                            )
50                        }),
51                    ),
52            ),
53    )
54}
55
56fn transfer(
57    source: &CommandSource,
58    hostname: &str,
59    port: i32,
60    players: &[Arc<Player>],
61) -> Result<i32, CommandSyntaxError> {
62    if players.is_empty() {
63        return Err(CommandSyntaxError::dynamic(
64            translations::COMMANDS_TRANSFER_ERROR_NO_PLAYERS.msg(),
65        ));
66    }
67
68    for p in players {
69        p.send_packet(CTransfer::new(hostname, port));
70    }
71
72    if players.len() == 1 {
73        source.send_success(
74            &TextComponent::translated(translations::COMMANDS_TRANSFER_SUCCESS_SINGLE.message([
75                players[0].display_name(),
76                TextComponent::from(hostname.to_string()),
77                TextComponent::from(port.to_string()),
78            ])),
79            true,
80        );
81    } else {
82        source.send_success(
83            &TextComponent::translated(translations::COMMANDS_TRANSFER_SUCCESS_MULTIPLE.message([
84                TextComponent::from(players.len().to_string()),
85                TextComponent::from(hostname.to_string()),
86                TextComponent::from(port.to_string()),
87            ])),
88            true,
89        );
90    }
91
92    Ok(players.len() as i32)
93}
94
95fn player_executor(
96    c: &CommandContext<CommandSource, SteelCommandRuntime>,
97) -> Result<Arc<Player>, CommandSyntaxError> {
98    c.source()
99        .player()
100        .ok_or(CommandSyntaxError::dynamic(
101            translations::PERMISSIONS_REQUIRES_PLAYER.msg(),
102        ))
103        .cloned()
104}