valence_server/
client_command.rs
1use bevy_app::prelude::*;
2use bevy_ecs::prelude::*;
3use valence_entity::entity::Flags;
4use valence_entity::{entity, Pose};
5pub use valence_protocol::packets::play::client_command_c2s::ClientCommand;
6use valence_protocol::packets::play::ClientCommandC2s;
7
8use crate::event_loop::{EventLoopPreUpdate, PacketEvent};
9
10pub struct ClientCommandPlugin;
11
12impl Plugin for ClientCommandPlugin {
13 fn build(&self, app: &mut App) {
14 app.add_event::<SprintEvent>()
15 .add_event::<SneakEvent>()
16 .add_event::<JumpWithHorseEvent>()
17 .add_event::<LeaveBedEvent>()
18 .add_systems(EventLoopPreUpdate, handle_client_command);
19 }
20}
21
22#[derive(Event, Copy, Clone, PartialEq, Eq, Debug)]
23pub struct SprintEvent {
24 pub client: Entity,
25 pub state: SprintState,
26}
27
28#[derive(Copy, Clone, PartialEq, Eq, Debug)]
29pub enum SprintState {
30 Start,
31 Stop,
32}
33
34#[derive(Event, Copy, Clone, PartialEq, Eq, Debug)]
35pub struct SneakEvent {
36 pub client: Entity,
37 pub state: SneakState,
38}
39
40#[derive(Copy, Clone, PartialEq, Eq, Debug)]
41pub enum SneakState {
42 Start,
43 Stop,
44}
45
46#[derive(Event, Copy, Clone, PartialEq, Eq, Debug)]
47pub struct JumpWithHorseEvent {
48 pub client: Entity,
49 pub state: JumpWithHorseState,
50}
51
52#[derive(Copy, Clone, PartialEq, Eq, Debug)]
53pub enum JumpWithHorseState {
54 Start {
55 power: u8,
57 },
58 Stop,
59}
60
61#[derive(Event, Copy, Clone, PartialEq, Eq, Debug)]
62pub struct LeaveBedEvent {
63 pub client: Entity,
64}
65
66fn handle_client_command(
67 mut packets: EventReader<PacketEvent>,
68 mut clients: Query<(&mut entity::Pose, &mut Flags)>,
69 mut sprinting_events: EventWriter<SprintEvent>,
70 mut sneaking_events: EventWriter<SneakEvent>,
71 mut jump_with_horse_events: EventWriter<JumpWithHorseEvent>,
72 mut leave_bed_events: EventWriter<LeaveBedEvent>,
73) {
74 for packet in packets.read() {
75 if let Some(pkt) = packet.decode::<ClientCommandC2s>() {
76 match pkt.action {
77 ClientCommand::StartSneaking => {
78 if let Ok((mut pose, mut flags)) = clients.get_mut(packet.client) {
79 pose.0 = Pose::Sneaking;
80 flags.set_sneaking(true);
81 }
82
83 sneaking_events.send(SneakEvent {
84 client: packet.client,
85 state: SneakState::Start,
86 });
87 }
88 ClientCommand::StopSneaking => {
89 if let Ok((mut pose, mut flags)) = clients.get_mut(packet.client) {
90 pose.0 = Pose::Standing;
91 flags.set_sneaking(false);
92 }
93
94 sneaking_events.send(SneakEvent {
95 client: packet.client,
96 state: SneakState::Stop,
97 });
98 }
99 ClientCommand::LeaveBed => {
100 leave_bed_events.send(LeaveBedEvent {
101 client: packet.client,
102 });
103 }
104 ClientCommand::StartSprinting => {
105 if let Ok((_, mut flags)) = clients.get_mut(packet.client) {
106 flags.set_sprinting(true);
107 }
108
109 sprinting_events.send(SprintEvent {
110 client: packet.client,
111 state: SprintState::Start,
112 });
113 }
114 ClientCommand::StopSprinting => {
115 if let Ok((_, mut flags)) = clients.get_mut(packet.client) {
116 flags.set_sprinting(false);
117 }
118
119 sprinting_events.send(SprintEvent {
120 client: packet.client,
121 state: SprintState::Stop,
122 });
123 }
124 ClientCommand::StartJumpWithHorse => {
125 jump_with_horse_events.send(JumpWithHorseEvent {
126 client: packet.client,
127 state: JumpWithHorseState::Start {
128 power: pkt.jump_boost.0 as u8,
129 },
130 });
131 }
132 ClientCommand::StopJumpWithHorse => {
133 jump_with_horse_events.send(JumpWithHorseEvent {
134 client: packet.client,
135 state: JumpWithHorseState::Stop,
136 });
137 }
138 ClientCommand::OpenHorseInventory => {} ClientCommand::StartFlyingWithElytra => {
140 if let Ok((mut pose, _)) = clients.get_mut(packet.client) {
141 pose.0 = Pose::FallFlying;
142 }
143
144 }
146 }
147 }
148 }
149}