Skip to content

Commit 6c6c6d4

Browse files
committed
tproom command
1 parent 08fef56 commit 6c6c6d4

File tree

3 files changed

+56
-10
lines changed

3 files changed

+56
-10
lines changed

server/src/commands/command.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::commands::string_reader::StringReader;
22
use crate::{Player, PlayerExtension};
33
use std::collections::HashMap;
44

5-
pub type CommandFunction<P> = fn(&mut StringReader, &mut Player<P>) -> anyhow::Result<()>;
5+
pub type CommandFunction<P> = Box<dyn for<'a> Fn(&'a mut StringReader<'a>, &mut Player<P>) -> anyhow::Result<()>>;
66

77
pub struct Command<P: PlayerExtension> {
88
pub literal: &'static str,
@@ -43,18 +43,17 @@ impl<P: PlayerExtension> CommandDispatcher<P> {
4343

4444
#[macro_export]
4545
macro_rules! command {
46-
// Syntax: literal, |first: Type, rest: Type,...| { body }
4746
($lit:expr, | $first:ident : $first_ty:ty $(, $rest:ident : $ty:ty )* | $body:block) => {{
4847
server::commands::command::Command {
4948
literal: concat!("/", $lit),
50-
callback: |reader: &mut StringReader, $first: $first_ty| -> anyhow::Result<()> {
49+
callback: Box::new(|reader: &mut server::commands::string_reader::StringReader<'_>, $first: $first_ty| -> anyhow::Result<()> {
5150
use server::commands::command_parse::CommandParse;
5251
$(
5352
let mut $rest: $ty = CommandParse::parse(reader)?;
5453
)*
5554
$body
5655
Ok(())
57-
}
56+
})
5857
}
5958
}};
6059
}
Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,36 @@
11
use crate::commands::string_reader::StringReader;
2+
use anyhow::bail;
23
use std::str::FromStr;
34

4-
pub trait CommandParse: Sized {
5-
fn parse(reader: &mut StringReader) -> anyhow::Result<Self>;
5+
pub trait CommandParse<'a>: Sized {
6+
fn parse(reader: &'a mut StringReader<'a>) -> anyhow::Result<Self>;
67
}
78

8-
impl CommandParse for i32 {
9-
fn parse(reader: &mut StringReader) -> anyhow::Result<Self> {
9+
impl<'a> CommandParse<'a> for i32 {
10+
fn parse(reader: &'a mut StringReader<'a>) -> anyhow::Result<Self> {
1011
let str = reader.read_word();
1112
let int = Self::from_str(str)?;
1213
Ok(int)
1314
}
1415
}
16+
17+
impl<'a> CommandParse<'a> for &'a str {
18+
fn parse(reader: &'a mut StringReader<'a>) -> anyhow::Result<Self> {
19+
let s = reader.read_word();
20+
if s.is_empty() {
21+
bail!("empty string")
22+
}
23+
Ok(s)
24+
}
25+
}
26+
27+
pub struct GreedyString<'a> {
28+
pub str: &'a str
29+
}
30+
31+
impl<'a> CommandParse<'a> for GreedyString<'a> {
32+
fn parse(reader: &'a mut StringReader<'a>) -> anyhow::Result<Self> {
33+
reader.skip_whitespace();
34+
Ok(GreedyString { str: reader.remaining() })
35+
}
36+
}

src/dungeon/dungeon.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,17 @@ use anyhow::bail;
99
use glam::{ivec3, DVec3, IVec2};
1010
use server::block::block_parameter::Axis;
1111
use server::block::rotatable::Rotate;
12+
use server::commands::command_parse::GreedyString;
1213
use server::constants::Gamemode;
1314
use server::inventory::menu::OpenContainer;
1415
use server::network::binary::var_int::VarInt;
15-
use server::network::protocol::play::clientbound::{Chat, EntityProperties, PlayerAbilities};
16+
use server::network::protocol::play::clientbound::{Chat, EntityProperties, PlayerAbilities, PositionLook, Relative};
1617
use server::player::attribute::{Attribute, AttributeMap, AttributeModifier};
1718
use server::player::sidebar::Sidebar;
1819
use server::types::aabb::AABB;
1920
use server::types::chat_component::ChatComponent;
2021
use server::utils::hasher::deterministic_hasher::DeterministicHashMap;
21-
use server::{ClientId, GameProfile, Player, World, WorldExtension};
22+
use server::{command, ClientId, GameProfile, Player, World, WorldExtension};
2223
use std::cell::{Cell, RefCell};
2324
use std::collections::HashMap;
2425
use std::rc::Rc;
@@ -202,6 +203,30 @@ impl WorldExtension for Dungeon {
202203
player.inventory.set_slot(43, Some(DungeonItem::AspectOfTheVoid));
203204
player.inventory.set_slot(44, Some(DungeonItem::SkyblockMenu));
204205
player.sync_inventory();
206+
207+
let cmd = command!("tproom", |player: &mut Player<DungeonPlayer>, room_name: GreedyString| {
208+
let name = room_name.str;
209+
for room_rc in player.world().rooms.iter() {
210+
let room = room_rc.borrow();
211+
if room.data.name.to_lowercase().contains(name) {
212+
for neighbour in room.neighbours() {
213+
let door = neighbour.door.borrow();
214+
player.write_packet(&PositionLook {
215+
x: door.x as f64 + 0.5,
216+
y: 69.0,
217+
z: door.z as f64 + 0.5,
218+
yaw: 0.0,
219+
pitch: 0.0,
220+
flags: Relative::Yaw | Relative::Pitch,
221+
});
222+
}
223+
return Ok(());
224+
}
225+
}
226+
player.send_message(format!("no room with name containing {name}").as_str())
227+
});
228+
player.command_dispatcher_mut().register_command(cmd);
229+
205230
player.flush_packets()
206231
}
207232

0 commit comments

Comments
 (0)