Skip to content

Commit 266bba6

Browse files
committed
feat(player): accept item use events
1 parent b8078fc commit 266bba6

File tree

4 files changed

+150
-3
lines changed

4 files changed

+150
-3
lines changed

src/net/player.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use crate::{
3939
ConfirmTeleportS, GameEvent, GameEventC, Gamemode, KeepAliveC, LoginPlayC,
4040
PlayerInfoUpdateC, PlayerStatus, SetBorderCenterC, SetBorderSizeC, SetCenterChunkC,
4141
SetPlayerPositionAndRotationS, SetPlayerPositionS, SetTickingStateC, StepTicksC,
42-
SynchronisePositionC,
42+
SynchronisePositionC, UseItemOnS,
4343
},
4444
},
4545
Frame, Packet, PacketState,
@@ -506,6 +506,11 @@ impl SharedPlayer {
506506
self.check_teleports(Some(packet)).await?;
507507
}
508508

509+
UseItemOnS::ID => {
510+
let packet: UseItemOnS = frame.decode()?;
511+
debug!("{:?}", packet);
512+
}
513+
509514
id => {
510515
debug!(
511516
"Got packet with id {id} from player {}, ignoring",

src/protocol/datatypes/position.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
*/
1919

2020
use bitfield_struct::bitfield;
21-
use byteorder::{BigEndian, WriteBytesExt};
21+
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
2222
use color_eyre::eyre::Result;
2323
use thiserror::Error;
2424

25-
use crate::protocol::Encode;
25+
use crate::protocol::{Decode, Encode};
2626

2727
#[derive(Debug)]
2828
pub struct Position {
@@ -70,13 +70,38 @@ impl TryFrom<&Position> for PackedPosition {
7070
}
7171
}
7272

73+
impl From<PackedPosition> for Position {
74+
fn from(value: PackedPosition) -> Self {
75+
Self {
76+
x: value.x(),
77+
y: value.y(),
78+
z: value.z(),
79+
}
80+
}
81+
}
82+
7383
impl Encode for Position {
7484
fn encode(&self, w: impl std::io::Write) -> Result<()> {
7585
let encoded: PackedPosition = self.try_into()?;
7686
encoded.encode(w)
7787
}
7888
}
7989

90+
impl Decode<'_> for Position {
91+
fn decode(r: &mut &'_ [u8]) -> Result<Self>
92+
where
93+
Self: Sized,
94+
{
95+
let bytes = r.read_i64::<BigEndian>()?;
96+
97+
Ok(Self {
98+
x: (bytes >> 38) as i32,
99+
y: (bytes << 52 >> 52) as i32,
100+
z: (bytes << 26 >> 38) as i32,
101+
})
102+
}
103+
}
104+
80105
impl Encode for PackedPosition {
81106
fn encode(&self, mut w: impl std::io::Write) -> Result<()> {
82107
Ok(w.write_u64::<BigEndian>(self.0)?)

src/protocol/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ pub mod packets {
4747

4848
pub mod play {
4949
mod game_event;
50+
mod interactions;
5051
mod keepalive;
5152
mod login;
5253
mod position;
@@ -56,6 +57,7 @@ pub mod packets {
5657
mod world;
5758

5859
pub use game_event::*;
60+
pub use interactions::*;
5961
pub use keepalive::*;
6062
pub use login::*;
6163
pub use position::*;
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright (c) 2024 Andrew Brower.
3+
* This file is part of Crawlspace.
4+
*
5+
* Crawlspace is free software: you can redistribute it and/or
6+
* modify it under the terms of the GNU Affero General Public
7+
* License as published by the Free Software Foundation, either
8+
* version 3 of the License, or (at your option) any later version.
9+
*
10+
* Crawlspace is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Affero General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Affero General Public
16+
* License along with Crawlspace. If not, see
17+
* <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
use byteorder::{BigEndian, ReadBytesExt};
21+
22+
use crate::protocol::{
23+
datatypes::{Position, VarInt},
24+
Decode, Packet,
25+
};
26+
27+
#[derive(Debug)]
28+
pub struct UseItemOnS {
29+
pub hand: Hand,
30+
pub location: Position,
31+
pub face: Face,
32+
pub cursor_x: f32,
33+
pub cursor_y: f32,
34+
pub cursor_z: f32,
35+
pub inside_block: bool,
36+
pub sequence: VarInt,
37+
}
38+
39+
#[derive(Debug)]
40+
pub enum Hand {
41+
Main,
42+
Off,
43+
}
44+
45+
#[derive(thiserror::Error, Debug)]
46+
pub enum HandParseError {
47+
#[error("Got unexpected hand index {0}")]
48+
Unexpected(i32),
49+
}
50+
51+
impl TryFrom<VarInt> for Hand {
52+
type Error = HandParseError;
53+
54+
fn try_from(value: VarInt) -> Result<Self, Self::Error> {
55+
match value.0 {
56+
0 => Ok(Hand::Main),
57+
1 => Ok(Hand::Off),
58+
i => Err(HandParseError::Unexpected(i)),
59+
}
60+
}
61+
}
62+
63+
#[derive(Debug)]
64+
pub enum Face {
65+
Bottom,
66+
Top,
67+
North,
68+
South,
69+
East,
70+
West,
71+
}
72+
73+
#[derive(thiserror::Error, Debug)]
74+
pub enum FaceParseError {
75+
#[error("Got unexpected face index {0}")]
76+
Unexpected(i32),
77+
}
78+
79+
impl TryFrom<VarInt> for Face {
80+
type Error = FaceParseError;
81+
82+
fn try_from(value: VarInt) -> Result<Self, Self::Error> {
83+
match value.0 {
84+
0 => Ok(Face::Bottom),
85+
1 => Ok(Face::Top),
86+
2 => Ok(Face::North),
87+
3 => Ok(Face::South),
88+
4 => Ok(Face::East),
89+
5 => Ok(Face::West),
90+
i => Err(FaceParseError::Unexpected(i)),
91+
}
92+
}
93+
}
94+
95+
impl Packet for UseItemOnS {
96+
const ID: i32 = 0x38;
97+
}
98+
99+
impl Decode<'_> for UseItemOnS {
100+
fn decode(r: &mut &'_ [u8]) -> color_eyre::eyre::Result<Self>
101+
where
102+
Self: Sized,
103+
{
104+
Ok(Self {
105+
hand: VarInt::decode(r)?.try_into()?,
106+
location: Position::decode(r)?,
107+
face: VarInt::decode(r)?.try_into()?,
108+
cursor_x: r.read_f32::<BigEndian>()?,
109+
cursor_y: r.read_f32::<BigEndian>()?,
110+
cursor_z: r.read_f32::<BigEndian>()?,
111+
inside_block: r.read_u8()? == 1,
112+
sequence: VarInt::decode(r)?,
113+
})
114+
}
115+
}

0 commit comments

Comments
 (0)