Skip to content

Commit b4ae457

Browse files
committed
hotbar syncing
1 parent 80cf746 commit b4ae457

9 files changed

Lines changed: 89 additions & 9 deletions

File tree

build.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ fn main() {
77
load_packets();
88
load_blocks();
99
load_items();
10+
load_item_to_block();
1011
}
1112

1213
fn load_packets() {
@@ -126,4 +127,48 @@ fn load_items() {
126127

127128
let out_path = Path::new(&env::var("OUT_DIR").unwrap()).join("items.rs");
128129
fs::write(out_path, out).unwrap();
130+
}
131+
132+
fn load_item_to_block() {
133+
let manifest = env::var("CARGO_MANIFEST_DIR").unwrap();
134+
let blocks_json_path = Path::new(&manifest).join("src/assets/blocks.json");
135+
let items_json_path = Path::new(&manifest).join("src/assets/items.json");
136+
137+
let block_bytes = fs::read(&blocks_json_path).expect("Failed to read blocks.json");
138+
let item_bytes = fs::read(&items_json_path).expect("Failed to read items.json");
139+
140+
let blocks: HashMap<String, serde_json::Value> =
141+
serde_json::from_slice(&block_bytes).expect("Failed to parse blocks.json");
142+
let items: HashMap<String, serde_json::Value> =
143+
serde_json::from_slice(&item_bytes).expect("Failed to parse items.json");
144+
145+
let mut out = String::new();
146+
out.push_str("pub fn item_to_block(item_id: i32) -> Option<u16> {\n");
147+
out.push_str(" match item_id {\n");
148+
149+
for (ik, iv) in items["entries"].as_object().unwrap() {
150+
if let Some(block) = blocks.get(ik) {
151+
let default_state = block["states"]
152+
.as_array()
153+
.unwrap()
154+
.iter()
155+
.find(|state| state["default"].as_bool().unwrap_or(false))
156+
.expect("Block is missing a default state");
157+
158+
out.push_str(
159+
&format!(
160+
" {} => Some({}),\n",
161+
iv["protocol_id"].as_u64().unwrap(),
162+
default_state["id"].as_u64().unwrap()
163+
)
164+
);
165+
}
166+
}
167+
168+
out.push_str(" _ => None,\n");
169+
out.push_str(" }\n");
170+
out.push_str("}\n");
171+
172+
let out_path = Path::new(&env::var("OUT_DIR").unwrap()).join("item_to_block.rs");
173+
fs::write(out_path, out).unwrap();
129174
}

src/net/packet.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub enum ClientPacket {
2323
ChatCommand(std::io::Cursor<Vec<u8>>), // 0x06 in play
2424
ChatMessage(std::io::Cursor<Vec<u8>>), // 0x08 in play
2525
PlayerAction(std::io::Cursor<Vec<u8>>), // 0x28 in play
26+
SetCarriedItem(std::io::Cursor<Vec<u8>>), // 0x34 in play
2627
UseItemOn(std::io::Cursor<Vec<u8>>), // 0x3F in play
2728
SetPlayerPositionAndRotation(std::io::Cursor<Vec<u8>>), // 0x1E in play
2829
PlayerInput(std::io::Cursor<Vec<u8>>), // 0x2A in play
@@ -159,6 +160,10 @@ pub async fn read_packet<R: AsyncReadExt + Unpin>(stream: &mut R, state: &Protoc
159160
play::serverbound::MOVE_PLAYER_ROT => {
160161
Ok(Some(ClientPacket::SetPlayerRotation(cursor)))
161162
},
163+
164+
play::serverbound::SET_CARRIED_ITEM => {
165+
Ok(Some(ClientPacket::SetCarriedItem(cursor)))
166+
},
162167

163168
_ => Ok(None)
164169
}

src/net/packets/serverbound/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ pub mod chat_message;
1010
pub mod set_player_position_and_rotation;
1111
pub mod player_input;
1212
pub mod set_player_rotation;
13-
pub mod chat_command;
13+
pub mod chat_command;
14+
pub mod set_carried_item;

src/net/packets/serverbound/player_input.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use tokio::io::AsyncReadExt;
22
use crate::types::player::Player;
33

4-
pub async fn read_player_input
5-
<R: AsyncReadExt + Unpin>(
4+
pub async fn read_player_input<R: AsyncReadExt + Unpin>(
65
stream: &mut R, player: &mut Player
76
) -> anyhow::Result<()> {
87
let flags = stream.read_u8().await?;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use tokio::io::AsyncReadExt;
2+
use crate::types::player::Player;
3+
4+
pub async fn read_set_carried_item<R: AsyncReadExt + Unpin>(
5+
stream: &mut R, player: &mut Player
6+
) -> anyhow::Result<()> {
7+
let slot = stream.read_i16().await?;
8+
player.current_slot = slot;
9+
10+
Ok(())
11+
}

src/net/packets/serverbound/use_item_on.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use tokio::io::AsyncReadExt;
22

33
use crate::{net::codec::{read_position, read_var}, types::player::Player, world::get_region};
44

5-
pub async fn read_use_item_on<R: AsyncReadExt + Unpin>(stream: &mut R, _player: &mut Player) -> anyhow::Result<()> {
5+
pub async fn read_use_item_on<R: AsyncReadExt + Unpin>(stream: &mut R, player: &mut Player) -> anyhow::Result<()> {
66
let _hand = read_var(stream).await?;
77
let (x, y, z) = read_position(stream).await?;
88

@@ -28,8 +28,15 @@ pub async fn read_use_item_on<R: AsyncReadExt + Unpin>(stream: &mut R, _player:
2828
_ => {}
2929
}
3030

31-
// todo: replace stone placeholder
32-
let block_id = crate::types::blocks::STONE;
31+
let block_id = if let Some(Some(item_stack)) = player.inventory.get(player.current_slot as usize + 36) {
32+
if let Some(block_id) = crate::types::items::item_to_block(item_stack.item_id) {
33+
block_id
34+
} else {
35+
return Ok(());
36+
}
37+
} else {
38+
return Ok(());
39+
};
3340

3441
let chunk_pos = (bx.div_euclid(16), bz.div_euclid(16));
3542
let region_pos = (chunk_pos.0.div_euclid(32), chunk_pos.1.div_euclid(32));
@@ -41,7 +48,7 @@ pub async fn read_use_item_on<R: AsyncReadExt + Unpin>(stream: &mut R, _player:
4148

4249
if let Some(chunk) = region_lock.chunks.iter_mut().find(|chunk| chunk.x == chunk_pos.0 && chunk.z == chunk_pos.1) {
4350
if let Some(section) = chunk.sections.iter_mut().find(|section| section.y == section_y) {
44-
section.set_block((bx & 15) as u8, (by & 15) as u8, (bz & 15) as u8, block_id);
51+
section.set_block((bx & 15) as u8, (by & 15) as u8, (bz & 15) as u8, block_id as u16);
4552
}
4653
}
4754

src/server/state/play.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ use crate::{
3535
set_player_position_and_rotation::read_set_player_position_and_rotation,
3636
set_player_rotation::read_set_player_rotation,
3737
use_item_on::read_use_item_on,
38-
chat_command::read_chat_command
38+
chat_command::read_chat_command,
39+
set_carried_item::read_set_carried_item
3940
}
4041
}
4142
},
@@ -384,6 +385,13 @@ pub async fn play(socket: EncryptedStream<TcpStream>, player: Player) -> anyhow:
384385
read_set_player_rotation(&mut cursor, &mut player).await?;
385386
}
386387

388+
ClientPacket::SetCarriedItem(mut cursor) => {
389+
let players_locked = PLAYERS.read().await;
390+
let mut player = players_locked.get(&uuid).unwrap().lock().await;
391+
392+
read_set_carried_item(&mut cursor, &mut player).await?;
393+
}
394+
387395
_ => { }
388396
}
389397
},

src/types/items.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ pub use items::*;
33
#[allow(unused)]
44
mod items {
55
include!(concat!(env!("OUT_DIR"), "/items.rs"));
6-
}
6+
}
7+
8+
include!(concat!(env!("OUT_DIR"), "/item_to_block.rs"));

src/types/player.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub struct Player {
3131
pub uuid: String,
3232
pub username: String,
3333
pub inventory: [Option<ItemStack>; 45],
34+
pub current_slot: i16,
3435

3536
pub shared_secret: Option<Vec<u8>>,
3637
pub textures: Option<String>,
@@ -64,6 +65,7 @@ impl Player {
6465
uuid,
6566
username: username.clone(),
6667
inventory: [None; 45],
68+
current_slot: 0,
6769

6870
shared_secret: None,
6971
textures: None,

0 commit comments

Comments
 (0)