mirror of
https://github.com/italicsjenga/valence.git
synced 2024-12-23 22:41:30 +11:00
parent
6de5de57a5
commit
5d3364d452
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "valence"
|
name = "valence"
|
||||||
version = "0.1.0+mc1.19.2"
|
version = "0.2.0+mc1.19.3"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "A framework for building Minecraft servers in Rust."
|
description = "A framework for building Minecraft servers in Rust."
|
||||||
repository = "https://github.com/rj00a/valence"
|
repository = "https://github.com/rj00a/valence"
|
||||||
|
|
|
@ -126,6 +126,7 @@ impl Config for Game {
|
||||||
client.game_mode(),
|
client.game_mode(),
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ struct Field {
|
||||||
enum Value {
|
enum Value {
|
||||||
Byte(u8),
|
Byte(u8),
|
||||||
Integer(i32),
|
Integer(i32),
|
||||||
|
Long(i64),
|
||||||
Float(f32),
|
Float(f32),
|
||||||
String(String),
|
String(String),
|
||||||
TextComponent(String),
|
TextComponent(String),
|
||||||
|
@ -85,27 +86,28 @@ impl Value {
|
||||||
match self {
|
match self {
|
||||||
Value::Byte(_) => 0,
|
Value::Byte(_) => 0,
|
||||||
Value::Integer(_) => 1,
|
Value::Integer(_) => 1,
|
||||||
Value::Float(_) => 2,
|
Value::Long(_) => 2,
|
||||||
Value::String(_) => 3,
|
Value::Float(_) => 3,
|
||||||
Value::TextComponent(_) => 4,
|
Value::String(_) => 4,
|
||||||
Value::OptionalTextComponent(_) => 5,
|
Value::TextComponent(_) => 5,
|
||||||
Value::ItemStack(_) => 6,
|
Value::OptionalTextComponent(_) => 6,
|
||||||
Value::Boolean(_) => 7,
|
Value::ItemStack(_) => 7,
|
||||||
Value::Rotation { .. } => 8,
|
Value::Boolean(_) => 8,
|
||||||
Value::BlockPos(_) => 9,
|
Value::Rotation { .. } => 9,
|
||||||
Value::OptionalBlockPos(_) => 10,
|
Value::BlockPos(_) => 10,
|
||||||
Value::Facing(_) => 11,
|
Value::OptionalBlockPos(_) => 11,
|
||||||
Value::OptionalUuid(_) => 12,
|
Value::Facing(_) => 12,
|
||||||
Value::OptionalBlockState(_) => 13,
|
Value::OptionalUuid(_) => 13,
|
||||||
Value::NbtCompound(_) => 14,
|
Value::OptionalBlockState(_) => 14,
|
||||||
Value::Particle(_) => 15,
|
Value::NbtCompound(_) => 15,
|
||||||
Value::VillagerData { .. } => 16,
|
Value::Particle(_) => 16,
|
||||||
Value::OptionalInt(_) => 17,
|
Value::VillagerData { .. } => 17,
|
||||||
Value::EntityPose(_) => 18,
|
Value::OptionalInt(_) => 18,
|
||||||
Value::CatVariant(_) => 19,
|
Value::EntityPose(_) => 19,
|
||||||
Value::FrogVariant(_) => 20,
|
Value::CatVariant(_) => 20,
|
||||||
Value::OptionalGlobalPos(_) => 21,
|
Value::FrogVariant(_) => 21,
|
||||||
Value::PaintingVariant(_) => 22,
|
Value::OptionalGlobalPos(_) => 22,
|
||||||
|
Value::PaintingVariant(_) => 23,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,6 +115,7 @@ impl Value {
|
||||||
match self {
|
match self {
|
||||||
Value::Byte(_) => quote!(u8),
|
Value::Byte(_) => quote!(u8),
|
||||||
Value::Integer(_) => quote!(i32),
|
Value::Integer(_) => quote!(i32),
|
||||||
|
Value::Long(_) => quote!(i64),
|
||||||
Value::Float(_) => quote!(f32),
|
Value::Float(_) => quote!(f32),
|
||||||
Value::String(_) => quote!(Box<str>),
|
Value::String(_) => quote!(Box<str>),
|
||||||
Value::TextComponent(_) => quote!(Text),
|
Value::TextComponent(_) => quote!(Text),
|
||||||
|
@ -161,6 +164,7 @@ impl Value {
|
||||||
match self {
|
match self {
|
||||||
Value::Byte(b) => quote!(#b),
|
Value::Byte(b) => quote!(#b),
|
||||||
Value::Integer(i) => quote!(#i),
|
Value::Integer(i) => quote!(#i),
|
||||||
|
Value::Long(l) => quote!(#l),
|
||||||
Value::Float(f) => quote!(#f),
|
Value::Float(f) => quote!(#f),
|
||||||
Value::String(s) => quote!(#s.to_owned().into_boxed_str()),
|
Value::String(s) => quote!(#s.to_owned().into_boxed_str()),
|
||||||
Value::TextComponent(_) => quote!(Text::default()), // TODO
|
Value::TextComponent(_) => quote!(Text::default()), // TODO
|
||||||
|
|
|
@ -176,6 +176,7 @@ impl Config for Game {
|
||||||
client.game_mode(),
|
client.game_mode(),
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,6 +123,7 @@ impl Config for Game {
|
||||||
client.game_mode(),
|
client.game_mode(),
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -155,6 +155,7 @@ impl Config for Game {
|
||||||
client.game_mode(),
|
client.game_mode(),
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,7 @@ impl Config for Game {
|
||||||
client.game_mode(),
|
client.game_mode(),
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,13 +170,15 @@ impl Config for Game {
|
||||||
let index = position.x as usize + position.z as usize * SIZE_X;
|
let index = position.x as usize + position.z as usize * SIZE_X;
|
||||||
|
|
||||||
if !server.state.board[index] {
|
if !server.state.board[index] {
|
||||||
client.play_sound(
|
// client.play_sound(
|
||||||
Ident::new("minecraft:block.note_block.banjo").unwrap(),
|
// Ident::new("minecraft:block.note_block.
|
||||||
SoundCategory::Block,
|
// banjo").unwrap(),
|
||||||
Vec3::new(position.x, position.y, position.z).as_(),
|
// SoundCategory::Block,
|
||||||
0.5f32,
|
// Vec3::new(position.x, position.y,
|
||||||
1f32,
|
// position.z).as_(),
|
||||||
);
|
// 0.5f32,
|
||||||
|
// 1f32,
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
server.state.board[index] = true;
|
server.state.board[index] = true;
|
||||||
|
@ -208,13 +211,13 @@ impl Config for Game {
|
||||||
let sneaking = data.get_pose() == Pose::Sneaking;
|
let sneaking = data.get_pose() == Pose::Sneaking;
|
||||||
if sneaking != server.state.paused {
|
if sneaking != server.state.paused {
|
||||||
server.state.paused = sneaking;
|
server.state.paused = sneaking;
|
||||||
client.play_sound(
|
// client.play_sound(
|
||||||
Ident::new("block.note_block.pling").unwrap(),
|
// Ident::new("block.note_block.pling").unwrap(),
|
||||||
SoundCategory::Block,
|
// SoundCategory::Block,
|
||||||
client.position(),
|
// client.position(),
|
||||||
0.5,
|
// 0.5,
|
||||||
if sneaking { 0.5 } else { 1.0 },
|
// if sneaking { 0.5 } else { 1.0 },
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,6 +146,7 @@ impl Config for Game {
|
||||||
client.game_mode(),
|
client.game_mode(),
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,6 +164,7 @@ impl Config for Game {
|
||||||
client.game_mode(),
|
client.game_mode(),
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
client.set_respawn_screen(true);
|
client.set_respawn_screen(true);
|
||||||
|
|
|
@ -247,6 +247,7 @@ impl Config for Game {
|
||||||
GameMode::Survival,
|
GameMode::Survival,
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
let (_, e) = server
|
let (_, e) = server
|
||||||
|
@ -360,6 +361,7 @@ impl Config for Game {
|
||||||
client.game_mode(),
|
client.game_mode(),
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,7 @@ impl Config for Game {
|
||||||
client.game_mode(),
|
client.game_mode(),
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,14 +211,17 @@ fn play_note(client: &mut Client<Game>, player: &mut Entity<Game>, clicked_slot:
|
||||||
let pitch = (clicked_slot - SLOT_MIN) as f32 * (PITCH_MAX - PITCH_MIN)
|
let pitch = (clicked_slot - SLOT_MIN) as f32 * (PITCH_MAX - PITCH_MIN)
|
||||||
/ (SLOT_MAX - SLOT_MIN) as f32
|
/ (SLOT_MAX - SLOT_MIN) as f32
|
||||||
+ PITCH_MIN;
|
+ PITCH_MIN;
|
||||||
client.send_message(format!("playing note with pitch: {}", pitch));
|
|
||||||
client.play_sound(
|
client.send_message(format!("playing note with pitch: {pitch}"));
|
||||||
Ident::new("block.note_block.harp").unwrap(),
|
|
||||||
SoundCategory::Block,
|
let _ = player;
|
||||||
player.position(),
|
// client.play_sound(
|
||||||
10.0,
|
// Ident::new("block.note_block.harp").unwrap(),
|
||||||
pitch,
|
// SoundCategory::Block,
|
||||||
);
|
// player.position(),
|
||||||
|
// 10.0,
|
||||||
|
// pitch,
|
||||||
|
// );
|
||||||
} else if clicked_slot == 44 {
|
} else if clicked_slot == 44 {
|
||||||
client.set_game_mode(match client.game_mode() {
|
client.set_game_mode(match client.game_mode() {
|
||||||
GameMode::Survival => GameMode::Creative,
|
GameMode::Survival => GameMode::Creative,
|
||||||
|
|
|
@ -14,7 +14,7 @@ pub fn main() -> ShutdownResult {
|
||||||
Game {
|
Game {
|
||||||
player_count: AtomicUsize::new(0),
|
player_count: AtomicUsize::new(0),
|
||||||
},
|
},
|
||||||
ServerState { player_list: None },
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,10 +22,6 @@ struct Game {
|
||||||
player_count: AtomicUsize,
|
player_count: AtomicUsize,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ServerState {
|
|
||||||
player_list: Option<PlayerListId>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct ChunkState {
|
struct ChunkState {
|
||||||
keep_loaded: bool,
|
keep_loaded: bool,
|
||||||
|
@ -57,7 +53,7 @@ const BLOCK_TYPES: [BlockState; 7] = [
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Config for Game {
|
impl Config for Game {
|
||||||
type ServerState = ServerState;
|
type ServerState = Option<PlayerListId>;
|
||||||
type ClientState = ClientState;
|
type ClientState = ClientState;
|
||||||
type EntityState = ();
|
type EntityState = ();
|
||||||
type WorldState = ();
|
type WorldState = ();
|
||||||
|
@ -81,7 +77,7 @@ impl Config for Game {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(&self, server: &mut Server<Self>) {
|
fn init(&self, server: &mut Server<Self>) {
|
||||||
server.state.player_list = Some(server.player_lists.insert(()).0);
|
server.state = Some(server.player_lists.insert(()).0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&self, server: &mut Server<Self>) {
|
fn update(&self, server: &mut Server<Self>) {
|
||||||
|
@ -125,11 +121,7 @@ impl Config for Game {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client.respawn(world_id);
|
if let Some(id) = &server.state {
|
||||||
client.set_flat(true);
|
|
||||||
client.set_player_list(server.state.player_list.clone());
|
|
||||||
|
|
||||||
if let Some(id) = &server.state.player_list {
|
|
||||||
server.player_lists[id].insert(
|
server.player_lists[id].insert(
|
||||||
client.uuid(),
|
client.uuid(),
|
||||||
client.username(),
|
client.username(),
|
||||||
|
@ -137,9 +129,14 @@ impl Config for Game {
|
||||||
client.game_mode(),
|
client.game_mode(),
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client.respawn(world_id);
|
||||||
|
client.set_flat(true);
|
||||||
|
client.set_player_list(server.state.clone());
|
||||||
|
|
||||||
client.send_message("Welcome to epic infinite parkour game!".italic());
|
client.send_message("Welcome to epic infinite parkour game!".italic());
|
||||||
client.set_game_mode(GameMode::Adventure);
|
client.set_game_mode(GameMode::Adventure);
|
||||||
reset(client, world);
|
reset(client, world);
|
||||||
|
@ -200,19 +197,21 @@ impl Config for Game {
|
||||||
client.combo = 0
|
client.combo = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
let pitch = 0.9 + ((client.combo as f32) - 1.0) * 0.05;
|
// let pitch = 0.9 + ((client.combo as f32) - 1.0) * 0.05;
|
||||||
|
|
||||||
for _ in 0..index {
|
for _ in 0..index {
|
||||||
generate_next_block(client, world, true)
|
generate_next_block(client, world, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
client.play_sound(
|
// TODO: add sounds again.
|
||||||
Ident::new("minecraft:block.note_block.bass").unwrap(),
|
// client.play_sound(
|
||||||
SoundCategory::Master,
|
// Ident::new("minecraft:block.note_block.bass").unwrap(),
|
||||||
client.position(),
|
// SoundCategory::Master,
|
||||||
1f32,
|
// client.position(),
|
||||||
pitch,
|
// 1f32,
|
||||||
);
|
// pitch,
|
||||||
|
// );
|
||||||
|
|
||||||
client.set_title(
|
client.set_title(
|
||||||
"",
|
"",
|
||||||
client.score.to_string().color(Color::LIGHT_PURPLE).bold(),
|
client.score.to_string().color(Color::LIGHT_PURPLE).bold(),
|
||||||
|
@ -239,10 +238,10 @@ impl Config for Game {
|
||||||
|
|
||||||
if client.is_disconnected() {
|
if client.is_disconnected() {
|
||||||
self.player_count.fetch_sub(1, Ordering::SeqCst);
|
self.player_count.fetch_sub(1, Ordering::SeqCst);
|
||||||
player.set_deleted(true);
|
if let Some(id) = &server.state {
|
||||||
if let Some(id) = &server.state.player_list {
|
|
||||||
server.player_lists[id].remove(client.uuid());
|
server.player_lists[id].remove(client.uuid());
|
||||||
}
|
}
|
||||||
|
player.set_deleted(true);
|
||||||
server.worlds.remove(world_id);
|
server.worlds.remove(world_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,6 +137,7 @@ impl Config for Game {
|
||||||
client.game_mode(),
|
client.game_mode(),
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,7 @@ impl Config for Game {
|
||||||
client.game_mode(),
|
client.game_mode(),
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
348563
extracted/blocks.json
348563
extracted/blocks.json
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -11,113 +11,114 @@
|
||||||
"boat": 8,
|
"boat": 8,
|
||||||
"chest_boat": 9,
|
"chest_boat": 9,
|
||||||
"cat": 10,
|
"cat": 10,
|
||||||
"cave_spider": 11,
|
"camel": 11,
|
||||||
"chicken": 12,
|
"cave_spider": 12,
|
||||||
"cod": 13,
|
"chicken": 13,
|
||||||
"cow": 14,
|
"cod": 14,
|
||||||
"creeper": 15,
|
"cow": 15,
|
||||||
"dolphin": 16,
|
"creeper": 16,
|
||||||
"donkey": 17,
|
"dolphin": 17,
|
||||||
"dragon_fireball": 18,
|
"donkey": 18,
|
||||||
"drowned": 19,
|
"dragon_fireball": 19,
|
||||||
"elder_guardian": 20,
|
"drowned": 20,
|
||||||
"end_crystal": 21,
|
"elder_guardian": 21,
|
||||||
"ender_dragon": 22,
|
"end_crystal": 22,
|
||||||
"enderman": 23,
|
"ender_dragon": 23,
|
||||||
"endermite": 24,
|
"enderman": 24,
|
||||||
"evoker": 25,
|
"endermite": 25,
|
||||||
"evoker_fangs": 26,
|
"evoker": 26,
|
||||||
"experience_orb": 27,
|
"evoker_fangs": 27,
|
||||||
"eye_of_ender": 28,
|
"experience_orb": 28,
|
||||||
"falling_block": 29,
|
"eye_of_ender": 29,
|
||||||
"firework_rocket": 30,
|
"falling_block": 30,
|
||||||
"fox": 31,
|
"firework_rocket": 31,
|
||||||
"frog": 32,
|
"fox": 32,
|
||||||
"ghast": 33,
|
"frog": 33,
|
||||||
"giant": 34,
|
"ghast": 34,
|
||||||
"glow_item_frame": 35,
|
"giant": 35,
|
||||||
"glow_squid": 36,
|
"glow_item_frame": 36,
|
||||||
"goat": 37,
|
"glow_squid": 37,
|
||||||
"guardian": 38,
|
"goat": 38,
|
||||||
"hoglin": 39,
|
"guardian": 39,
|
||||||
"horse": 40,
|
"hoglin": 40,
|
||||||
"husk": 41,
|
"horse": 41,
|
||||||
"illusioner": 42,
|
"husk": 42,
|
||||||
"iron_golem": 43,
|
"illusioner": 43,
|
||||||
"item": 44,
|
"iron_golem": 44,
|
||||||
"item_frame": 45,
|
"item": 45,
|
||||||
"fireball": 46,
|
"item_frame": 46,
|
||||||
"leash_knot": 47,
|
"fireball": 47,
|
||||||
"lightning_bolt": 48,
|
"leash_knot": 48,
|
||||||
"llama": 49,
|
"lightning_bolt": 49,
|
||||||
"llama_spit": 50,
|
"llama": 50,
|
||||||
"magma_cube": 51,
|
"llama_spit": 51,
|
||||||
"marker": 52,
|
"magma_cube": 52,
|
||||||
"minecart": 53,
|
"marker": 53,
|
||||||
"chest_minecart": 54,
|
"minecart": 54,
|
||||||
"command_block_minecart": 55,
|
"chest_minecart": 55,
|
||||||
"furnace_minecart": 56,
|
"command_block_minecart": 56,
|
||||||
"hopper_minecart": 57,
|
"furnace_minecart": 57,
|
||||||
"spawner_minecart": 58,
|
"hopper_minecart": 58,
|
||||||
"tnt_minecart": 59,
|
"spawner_minecart": 59,
|
||||||
"mule": 60,
|
"tnt_minecart": 60,
|
||||||
"mooshroom": 61,
|
"mule": 61,
|
||||||
"ocelot": 62,
|
"mooshroom": 62,
|
||||||
"painting": 63,
|
"ocelot": 63,
|
||||||
"panda": 64,
|
"painting": 64,
|
||||||
"parrot": 65,
|
"panda": 65,
|
||||||
"phantom": 66,
|
"parrot": 66,
|
||||||
"pig": 67,
|
"phantom": 67,
|
||||||
"piglin": 68,
|
"pig": 68,
|
||||||
"piglin_brute": 69,
|
"piglin": 69,
|
||||||
"pillager": 70,
|
"piglin_brute": 70,
|
||||||
"polar_bear": 71,
|
"pillager": 71,
|
||||||
"tnt": 72,
|
"polar_bear": 72,
|
||||||
"pufferfish": 73,
|
"tnt": 73,
|
||||||
"rabbit": 74,
|
"pufferfish": 74,
|
||||||
"ravager": 75,
|
"rabbit": 75,
|
||||||
"salmon": 76,
|
"ravager": 76,
|
||||||
"sheep": 77,
|
"salmon": 77,
|
||||||
"shulker": 78,
|
"sheep": 78,
|
||||||
"shulker_bullet": 79,
|
"shulker": 79,
|
||||||
"silverfish": 80,
|
"shulker_bullet": 80,
|
||||||
"skeleton": 81,
|
"silverfish": 81,
|
||||||
"skeleton_horse": 82,
|
"skeleton": 82,
|
||||||
"slime": 83,
|
"skeleton_horse": 83,
|
||||||
"small_fireball": 84,
|
"slime": 84,
|
||||||
"snow_golem": 85,
|
"small_fireball": 85,
|
||||||
"snowball": 86,
|
"snow_golem": 86,
|
||||||
"spectral_arrow": 87,
|
"snowball": 87,
|
||||||
"spider": 88,
|
"spectral_arrow": 88,
|
||||||
"squid": 89,
|
"spider": 89,
|
||||||
"stray": 90,
|
"squid": 90,
|
||||||
"strider": 91,
|
"stray": 91,
|
||||||
"tadpole": 92,
|
"strider": 92,
|
||||||
"egg": 93,
|
"tadpole": 93,
|
||||||
"ender_pearl": 94,
|
"egg": 94,
|
||||||
"experience_bottle": 95,
|
"ender_pearl": 95,
|
||||||
"potion": 96,
|
"experience_bottle": 96,
|
||||||
"trident": 97,
|
"potion": 97,
|
||||||
"trader_llama": 98,
|
"trident": 98,
|
||||||
"tropical_fish": 99,
|
"trader_llama": 99,
|
||||||
"turtle": 100,
|
"tropical_fish": 100,
|
||||||
"vex": 101,
|
"turtle": 101,
|
||||||
"villager": 102,
|
"vex": 102,
|
||||||
"vindicator": 103,
|
"villager": 103,
|
||||||
"wandering_trader": 104,
|
"vindicator": 104,
|
||||||
"warden": 105,
|
"wandering_trader": 105,
|
||||||
"witch": 106,
|
"warden": 106,
|
||||||
"wither": 107,
|
"witch": 107,
|
||||||
"wither_skeleton": 108,
|
"wither": 108,
|
||||||
"wither_skull": 109,
|
"wither_skeleton": 109,
|
||||||
"wolf": 110,
|
"wither_skull": 110,
|
||||||
"zoglin": 111,
|
"wolf": 111,
|
||||||
"zombie": 112,
|
"zoglin": 112,
|
||||||
"zombie_horse": 113,
|
"zombie": 113,
|
||||||
"zombie_villager": 114,
|
"zombie_horse": 114,
|
||||||
"zombified_piglin": 115,
|
"zombie_villager": 115,
|
||||||
"player": 116,
|
"zombified_piglin": 116,
|
||||||
"fishing_bobber": 117
|
"player": 117,
|
||||||
|
"fishing_bobber": 118
|
||||||
},
|
},
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"add_sprinting_particles_or_reset_spawner_minecart_spawn_delay": 1,
|
"add_sprinting_particles_or_reset_spawner_minecart_spawn_delay": 1,
|
||||||
|
@ -406,10 +407,11 @@
|
||||||
"dying": 7,
|
"dying": 7,
|
||||||
"croaking": 8,
|
"croaking": 8,
|
||||||
"using_tongue": 9,
|
"using_tongue": 9,
|
||||||
"roaring": 10,
|
"sitting": 10,
|
||||||
"sniffing": 11,
|
"roaring": 11,
|
||||||
"emerging": 12,
|
"sniffing": 12,
|
||||||
"digging": 13
|
"emerging": 13,
|
||||||
|
"digging": 14
|
||||||
},
|
},
|
||||||
"particle_types": {
|
"particle_types": {
|
||||||
"ambient_entity_effect": 0,
|
"ambient_entity_effect": 0,
|
||||||
|
|
2548
extracted/items.json
2548
extracted/items.json
File diff suppressed because it is too large
Load diff
|
@ -32,111 +32,111 @@
|
||||||
"id": 5
|
"id": 5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "RequestChatPreviewC2SPacket",
|
"name": "ClientStatusC2SPacket",
|
||||||
"id": 6
|
"id": 6
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ClientStatusC2SPacket",
|
"name": "ClientSettingsC2SPacket",
|
||||||
"id": 7
|
"id": 7
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ClientSettingsC2SPacket",
|
"name": "RequestCommandCompletionsC2SPacket",
|
||||||
"id": 8
|
"id": 8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "RequestCommandCompletionsC2SPacket",
|
"name": "ButtonClickC2SPacket",
|
||||||
"id": 9
|
"id": 9
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ButtonClickC2SPacket",
|
"name": "ClickSlotC2SPacket",
|
||||||
"id": 10
|
"id": 10
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ClickSlotC2SPacket",
|
"name": "CloseHandledScreenC2SPacket",
|
||||||
"id": 11
|
"id": 11
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "CloseHandledScreenC2SPacket",
|
"name": "CustomPayloadC2SPacket",
|
||||||
"id": 12
|
"id": 12
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "CustomPayloadC2SPacket",
|
"name": "BookUpdateC2SPacket",
|
||||||
"id": 13
|
"id": 13
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "BookUpdateC2SPacket",
|
"name": "QueryEntityNbtC2SPacket",
|
||||||
"id": 14
|
"id": 14
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "QueryEntityNbtC2SPacket",
|
"name": "PlayerInteractEntityC2SPacket",
|
||||||
"id": 15
|
"id": 15
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PlayerInteractEntityC2SPacket",
|
"name": "JigsawGeneratingC2SPacket",
|
||||||
"id": 16
|
"id": 16
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "JigsawGeneratingC2SPacket",
|
"name": "KeepAliveC2SPacket",
|
||||||
"id": 17
|
"id": 17
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "KeepAliveC2SPacket",
|
"name": "UpdateDifficultyLockC2SPacket",
|
||||||
"id": 18
|
"id": 18
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "UpdateDifficultyLockC2SPacket",
|
"name": "PositionAndOnGround",
|
||||||
"id": 19
|
"id": 19
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PositionAndOnGround",
|
"name": "Full",
|
||||||
"id": 20
|
"id": 20
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Full",
|
"name": "LookAndOnGround",
|
||||||
"id": 21
|
"id": 21
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "LookAndOnGround",
|
"name": "OnGroundOnly",
|
||||||
"id": 22
|
"id": 22
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "OnGroundOnly",
|
"name": "VehicleMoveC2SPacket",
|
||||||
"id": 23
|
"id": 23
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "VehicleMoveC2SPacket",
|
"name": "BoatPaddleStateC2SPacket",
|
||||||
"id": 24
|
"id": 24
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "BoatPaddleStateC2SPacket",
|
"name": "PickFromInventoryC2SPacket",
|
||||||
"id": 25
|
"id": 25
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PickFromInventoryC2SPacket",
|
"name": "CraftRequestC2SPacket",
|
||||||
"id": 26
|
"id": 26
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "CraftRequestC2SPacket",
|
"name": "UpdatePlayerAbilitiesC2SPacket",
|
||||||
"id": 27
|
"id": 27
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "UpdatePlayerAbilitiesC2SPacket",
|
"name": "PlayerActionC2SPacket",
|
||||||
"id": 28
|
"id": 28
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PlayerActionC2SPacket",
|
"name": "ClientCommandC2SPacket",
|
||||||
"id": 29
|
"id": 29
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ClientCommandC2SPacket",
|
"name": "PlayerInputC2SPacket",
|
||||||
"id": 30
|
"id": 30
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PlayerInputC2SPacket",
|
"name": "PlayPongC2SPacket",
|
||||||
"id": 31
|
"id": 31
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PlayPongC2SPacket",
|
"name": "PlayerSessionC2SPacket",
|
||||||
"id": 32
|
"id": 32
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -289,388 +289,384 @@
|
||||||
"id": 11
|
"id": 11
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ChatPreviewS2CPacket",
|
"name": "ClearTitleS2CPacket",
|
||||||
"id": 12
|
"id": 12
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ClearTitleS2CPacket",
|
"name": "CommandSuggestionsS2CPacket",
|
||||||
"id": 13
|
"id": 13
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "CommandSuggestionsS2CPacket",
|
"name": "CommandTreeS2CPacket",
|
||||||
"id": 14
|
"id": 14
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "CommandTreeS2CPacket",
|
"name": "CloseScreenS2CPacket",
|
||||||
"id": 15
|
"id": 15
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "CloseScreenS2CPacket",
|
"name": "InventoryS2CPacket",
|
||||||
"id": 16
|
"id": 16
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "InventoryS2CPacket",
|
"name": "ScreenHandlerPropertyUpdateS2CPacket",
|
||||||
"id": 17
|
"id": 17
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ScreenHandlerPropertyUpdateS2CPacket",
|
"name": "ScreenHandlerSlotUpdateS2CPacket",
|
||||||
"id": 18
|
"id": 18
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ScreenHandlerSlotUpdateS2CPacket",
|
"name": "CooldownUpdateS2CPacket",
|
||||||
"id": 19
|
"id": 19
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "CooldownUpdateS2CPacket",
|
"name": "ChatSuggestionsS2CPacket",
|
||||||
"id": 20
|
"id": 20
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ChatSuggestionsS2CPacket",
|
"name": "CustomPayloadS2CPacket",
|
||||||
"id": 21
|
"id": 21
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "CustomPayloadS2CPacket",
|
"name": "RemoveMessageS2CPacket",
|
||||||
"id": 22
|
"id": 22
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PlaySoundIdS2CPacket",
|
"name": "DisconnectS2CPacket",
|
||||||
"id": 23
|
"id": 23
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "HideMessageS2CPacket",
|
"name": "ProfilelessChatMessageS2CPacket",
|
||||||
"id": 24
|
"id": 24
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "DisconnectS2CPacket",
|
"name": "EntityStatusS2CPacket",
|
||||||
"id": 25
|
"id": 25
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "EntityStatusS2CPacket",
|
"name": "ExplosionS2CPacket",
|
||||||
"id": 26
|
"id": 26
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ExplosionS2CPacket",
|
"name": "UnloadChunkS2CPacket",
|
||||||
"id": 27
|
"id": 27
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "UnloadChunkS2CPacket",
|
"name": "GameStateChangeS2CPacket",
|
||||||
"id": 28
|
"id": 28
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "GameStateChangeS2CPacket",
|
"name": "OpenHorseScreenS2CPacket",
|
||||||
"id": 29
|
"id": 29
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "OpenHorseScreenS2CPacket",
|
"name": "WorldBorderInitializeS2CPacket",
|
||||||
"id": 30
|
"id": 30
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "WorldBorderInitializeS2CPacket",
|
"name": "KeepAliveS2CPacket",
|
||||||
"id": 31
|
"id": 31
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "KeepAliveS2CPacket",
|
"name": "ChunkDataS2CPacket",
|
||||||
"id": 32
|
"id": 32
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ChunkDataS2CPacket",
|
"name": "WorldEventS2CPacket",
|
||||||
"id": 33
|
"id": 33
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "WorldEventS2CPacket",
|
"name": "ParticleS2CPacket",
|
||||||
"id": 34
|
"id": 34
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ParticleS2CPacket",
|
"name": "LightUpdateS2CPacket",
|
||||||
"id": 35
|
"id": 35
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "LightUpdateS2CPacket",
|
"name": "GameJoinS2CPacket",
|
||||||
"id": 36
|
"id": 36
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "GameJoinS2CPacket",
|
"name": "MapUpdateS2CPacket",
|
||||||
"id": 37
|
"id": 37
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "MapUpdateS2CPacket",
|
"name": "SetTradeOffersS2CPacket",
|
||||||
"id": 38
|
"id": 38
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "SetTradeOffersS2CPacket",
|
"name": "MoveRelative",
|
||||||
"id": 39
|
"id": 39
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "MoveRelative",
|
"name": "RotateAndMoveRelative",
|
||||||
"id": 40
|
"id": 40
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "RotateAndMoveRelative",
|
"name": "Rotate",
|
||||||
"id": 41
|
"id": 41
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Rotate",
|
"name": "VehicleMoveS2CPacket",
|
||||||
"id": 42
|
"id": 42
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "VehicleMoveS2CPacket",
|
"name": "OpenWrittenBookS2CPacket",
|
||||||
"id": 43
|
"id": 43
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "OpenWrittenBookS2CPacket",
|
"name": "OpenScreenS2CPacket",
|
||||||
"id": 44
|
"id": 44
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "OpenScreenS2CPacket",
|
"name": "SignEditorOpenS2CPacket",
|
||||||
"id": 45
|
"id": 45
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "SignEditorOpenS2CPacket",
|
"name": "PlayPingS2CPacket",
|
||||||
"id": 46
|
"id": 46
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PlayPingS2CPacket",
|
"name": "CraftFailedResponseS2CPacket",
|
||||||
"id": 47
|
"id": 47
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "CraftFailedResponseS2CPacket",
|
"name": "PlayerAbilitiesS2CPacket",
|
||||||
"id": 48
|
"id": 48
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PlayerAbilitiesS2CPacket",
|
"name": "ChatMessageS2CPacket",
|
||||||
"id": 49
|
"id": 49
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "MessageHeaderS2CPacket",
|
"name": "EndCombatS2CPacket",
|
||||||
"id": 50
|
"id": 50
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ChatMessageS2CPacket",
|
"name": "EnterCombatS2CPacket",
|
||||||
"id": 51
|
"id": 51
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "EndCombatS2CPacket",
|
"name": "DeathMessageS2CPacket",
|
||||||
"id": 52
|
"id": 52
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "EnterCombatS2CPacket",
|
"name": "PlayerRemoveS2CPacket",
|
||||||
"id": 53
|
"id": 53
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "DeathMessageS2CPacket",
|
"name": "PlayerListS2CPacket",
|
||||||
"id": 54
|
"id": 54
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PlayerListS2CPacket",
|
"name": "LookAtS2CPacket",
|
||||||
"id": 55
|
"id": 55
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "LookAtS2CPacket",
|
"name": "PlayerPositionLookS2CPacket",
|
||||||
"id": 56
|
"id": 56
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PlayerPositionLookS2CPacket",
|
"name": "UnlockRecipesS2CPacket",
|
||||||
"id": 57
|
"id": 57
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "UnlockRecipesS2CPacket",
|
"name": "EntitiesDestroyS2CPacket",
|
||||||
"id": 58
|
"id": 58
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "EntitiesDestroyS2CPacket",
|
"name": "RemoveEntityStatusEffectS2CPacket",
|
||||||
"id": 59
|
"id": 59
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "RemoveEntityStatusEffectS2CPacket",
|
"name": "ResourcePackSendS2CPacket",
|
||||||
"id": 60
|
"id": 60
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ResourcePackSendS2CPacket",
|
"name": "PlayerRespawnS2CPacket",
|
||||||
"id": 61
|
"id": 61
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PlayerRespawnS2CPacket",
|
"name": "EntitySetHeadYawS2CPacket",
|
||||||
"id": 62
|
"id": 62
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "EntitySetHeadYawS2CPacket",
|
"name": "ChunkDeltaUpdateS2CPacket",
|
||||||
"id": 63
|
"id": 63
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ChunkDeltaUpdateS2CPacket",
|
"name": "SelectAdvancementTabS2CPacket",
|
||||||
"id": 64
|
"id": 64
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "SelectAdvancementTabS2CPacket",
|
"name": "ServerMetadataS2CPacket",
|
||||||
"id": 65
|
"id": 65
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ServerMetadataS2CPacket",
|
"name": "OverlayMessageS2CPacket",
|
||||||
"id": 66
|
"id": 66
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "OverlayMessageS2CPacket",
|
"name": "WorldBorderCenterChangedS2CPacket",
|
||||||
"id": 67
|
"id": 67
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "WorldBorderCenterChangedS2CPacket",
|
"name": "WorldBorderInterpolateSizeS2CPacket",
|
||||||
"id": 68
|
"id": 68
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "WorldBorderInterpolateSizeS2CPacket",
|
"name": "WorldBorderSizeChangedS2CPacket",
|
||||||
"id": 69
|
"id": 69
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "WorldBorderSizeChangedS2CPacket",
|
"name": "WorldBorderWarningTimeChangedS2CPacket",
|
||||||
"id": 70
|
"id": 70
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "WorldBorderWarningTimeChangedS2CPacket",
|
"name": "WorldBorderWarningBlocksChangedS2CPacket",
|
||||||
"id": 71
|
"id": 71
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "WorldBorderWarningBlocksChangedS2CPacket",
|
"name": "SetCameraEntityS2CPacket",
|
||||||
"id": 72
|
"id": 72
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "SetCameraEntityS2CPacket",
|
"name": "UpdateSelectedSlotS2CPacket",
|
||||||
"id": 73
|
"id": 73
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "UpdateSelectedSlotS2CPacket",
|
"name": "ChunkRenderDistanceCenterS2CPacket",
|
||||||
"id": 74
|
"id": 74
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ChunkRenderDistanceCenterS2CPacket",
|
"name": "ChunkLoadDistanceS2CPacket",
|
||||||
"id": 75
|
"id": 75
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ChunkLoadDistanceS2CPacket",
|
"name": "PlayerSpawnPositionS2CPacket",
|
||||||
"id": 76
|
"id": 76
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PlayerSpawnPositionS2CPacket",
|
"name": "ScoreboardDisplayS2CPacket",
|
||||||
"id": 77
|
"id": 77
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ChatPreviewStateChangeS2CPacket",
|
"name": "EntityTrackerUpdateS2CPacket",
|
||||||
"id": 78
|
"id": 78
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ScoreboardDisplayS2CPacket",
|
"name": "EntityAttachS2CPacket",
|
||||||
"id": 79
|
"id": 79
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "EntityTrackerUpdateS2CPacket",
|
"name": "EntityVelocityUpdateS2CPacket",
|
||||||
"id": 80
|
"id": 80
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "EntityAttachS2CPacket",
|
"name": "EntityEquipmentUpdateS2CPacket",
|
||||||
"id": 81
|
"id": 81
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "EntityVelocityUpdateS2CPacket",
|
"name": "ExperienceBarUpdateS2CPacket",
|
||||||
"id": 82
|
"id": 82
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "EntityEquipmentUpdateS2CPacket",
|
"name": "HealthUpdateS2CPacket",
|
||||||
"id": 83
|
"id": 83
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ExperienceBarUpdateS2CPacket",
|
"name": "ScoreboardObjectiveUpdateS2CPacket",
|
||||||
"id": 84
|
"id": 84
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "HealthUpdateS2CPacket",
|
"name": "EntityPassengersSetS2CPacket",
|
||||||
"id": 85
|
"id": 85
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ScoreboardObjectiveUpdateS2CPacket",
|
"name": "TeamS2CPacket",
|
||||||
"id": 86
|
"id": 86
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "EntityPassengersSetS2CPacket",
|
"name": "ScoreboardPlayerUpdateS2CPacket",
|
||||||
"id": 87
|
"id": 87
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "TeamS2CPacket",
|
"name": "SimulationDistanceS2CPacket",
|
||||||
"id": 88
|
"id": 88
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ScoreboardPlayerUpdateS2CPacket",
|
"name": "SubtitleS2CPacket",
|
||||||
"id": 89
|
"id": 89
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "SimulationDistanceS2CPacket",
|
"name": "WorldTimeUpdateS2CPacket",
|
||||||
"id": 90
|
"id": 90
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "SubtitleS2CPacket",
|
"name": "TitleS2CPacket",
|
||||||
"id": 91
|
"id": 91
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "WorldTimeUpdateS2CPacket",
|
"name": "TitleFadeS2CPacket",
|
||||||
"id": 92
|
"id": 92
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "TitleS2CPacket",
|
"name": "PlaySoundFromEntityS2CPacket",
|
||||||
"id": 93
|
"id": 93
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "TitleFadeS2CPacket",
|
"name": "PlaySoundS2CPacket",
|
||||||
"id": 94
|
"id": 94
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PlaySoundFromEntityS2CPacket",
|
"name": "StopSoundS2CPacket",
|
||||||
"id": 95
|
"id": 95
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PlaySoundS2CPacket",
|
"name": "GameMessageS2CPacket",
|
||||||
"id": 96
|
"id": 96
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "StopSoundS2CPacket",
|
"name": "PlayerListHeaderS2CPacket",
|
||||||
"id": 97
|
"id": 97
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "GameMessageS2CPacket",
|
"name": "NbtQueryResponseS2CPacket",
|
||||||
"id": 98
|
"id": 98
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PlayerListHeaderS2CPacket",
|
"name": "ItemPickupAnimationS2CPacket",
|
||||||
"id": 99
|
"id": 99
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "NbtQueryResponseS2CPacket",
|
"name": "EntityPositionS2CPacket",
|
||||||
"id": 100
|
"id": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ItemPickupAnimationS2CPacket",
|
"name": "AdvancementUpdateS2CPacket",
|
||||||
"id": 101
|
"id": 101
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "EntityPositionS2CPacket",
|
"name": "EntityAttributesS2CPacket",
|
||||||
"id": 102
|
"id": 102
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "AdvancementUpdateS2CPacket",
|
"name": "FeaturesS2CPacket",
|
||||||
"id": 103
|
"id": 103
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "EntityAttributesS2CPacket",
|
"name": "EntityStatusEffectS2CPacket",
|
||||||
"id": 104
|
"id": 104
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "EntityStatusEffectS2CPacket",
|
"name": "SynchronizeRecipesS2CPacket",
|
||||||
"id": 105
|
"id": 105
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "SynchronizeRecipesS2CPacket",
|
|
||||||
"id": 106
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "SynchronizeTagsS2CPacket",
|
"name": "SynchronizeTagsS2CPacket",
|
||||||
"id": 107
|
"id": 106
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"status": [
|
"status": [
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,9 +3,9 @@ org.gradle.jvmargs=-Xmx1G
|
||||||
|
|
||||||
# Fabric Properties
|
# Fabric Properties
|
||||||
# check these on https://fabricmc.net/develop
|
# check these on https://fabricmc.net/develop
|
||||||
minecraft_version=1.19.2
|
minecraft_version=1.19.3
|
||||||
yarn_mappings=1.19.2+build.8
|
yarn_mappings=1.19.3+build.3
|
||||||
loader_version=0.14.9
|
loader_version=0.14.11
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version = 1.0.0
|
mod_version = 1.0.0
|
||||||
|
@ -13,4 +13,4 @@ org.gradle.jvmargs=-Xmx1G
|
||||||
archives_base_name = valence-extractor
|
archives_base_name = valence-extractor
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
fabric_version=0.60.0+1.19.2
|
fabric_version=0.69.1+1.19.3
|
||||||
|
|
|
@ -27,7 +27,7 @@ public class DummyPlayerEntity extends PlayerEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private DummyPlayerEntity(World world, BlockPos pos, float yaw, GameProfile gameProfile, @Nullable PlayerPublicKey publicKey) {
|
private DummyPlayerEntity(World world, BlockPos pos, float yaw, GameProfile gameProfile, @Nullable PlayerPublicKey publicKey) {
|
||||||
super(world, pos, yaw, gameProfile, publicKey);
|
super(world, pos, yaw, gameProfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -7,6 +7,11 @@ import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.fluid.Fluid;
|
import net.minecraft.fluid.Fluid;
|
||||||
import net.minecraft.item.map.MapState;
|
import net.minecraft.item.map.MapState;
|
||||||
import net.minecraft.recipe.RecipeManager;
|
import net.minecraft.recipe.RecipeManager;
|
||||||
|
import net.minecraft.registry.DynamicRegistryManager;
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
import net.minecraft.registry.entry.RegistryEntry;
|
||||||
|
import net.minecraft.resource.featuretoggle.FeatureFlags;
|
||||||
|
import net.minecraft.resource.featuretoggle.FeatureSet;
|
||||||
import net.minecraft.scoreboard.Scoreboard;
|
import net.minecraft.scoreboard.Scoreboard;
|
||||||
import net.minecraft.sound.SoundCategory;
|
import net.minecraft.sound.SoundCategory;
|
||||||
import net.minecraft.sound.SoundEvent;
|
import net.minecraft.sound.SoundEvent;
|
||||||
|
@ -15,9 +20,6 @@ import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.math.random.Random;
|
import net.minecraft.util.math.random.Random;
|
||||||
import net.minecraft.util.profiler.Profiler;
|
import net.minecraft.util.profiler.Profiler;
|
||||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
|
||||||
import net.minecraft.util.registry.RegistryEntry;
|
|
||||||
import net.minecraft.util.registry.RegistryKey;
|
|
||||||
import net.minecraft.world.Difficulty;
|
import net.minecraft.world.Difficulty;
|
||||||
import net.minecraft.world.GameRules;
|
import net.minecraft.world.GameRules;
|
||||||
import net.minecraft.world.MutableWorldProperties;
|
import net.minecraft.world.MutableWorldProperties;
|
||||||
|
@ -63,13 +65,18 @@ public class DummyWorld extends World {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void playSound(@Nullable PlayerEntity except, double x, double y, double z, RegistryEntry<SoundEvent> sound, SoundCategory category, float volume, float pitch, long seed) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playSound(@Nullable PlayerEntity except, double x, double y, double z, SoundEvent sound, SoundCategory category, float volume, float pitch, long seed) {
|
public void playSound(@Nullable PlayerEntity except, double x, double y, double z, SoundEvent sound, SoundCategory category, float volume, float pitch, long seed) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playSoundFromEntity(@Nullable PlayerEntity except, Entity entity, SoundEvent sound, SoundCategory category, float volume, float pitch, long seed) {
|
public void playSoundFromEntity(@Nullable PlayerEntity except, Entity entity, RegistryEntry<SoundEvent> sound, SoundCategory category, float volume, float pitch, long seed) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,6 +157,11 @@ public class DummyWorld extends World {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureSet getEnabledFeatures() {
|
||||||
|
return FeatureSet.of(FeatureFlags.VANILLA, FeatureFlags.BUNDLE, FeatureFlags.UPDATE_1_20);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getBrightness(Direction direction, boolean shaded) {
|
public float getBrightness(Direction direction, boolean shaded) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -4,8 +4,8 @@ import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import net.minecraft.item.ItemPlacementContext;
|
import net.minecraft.item.ItemPlacementContext;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
import net.minecraft.world.EmptyBlockView;
|
import net.minecraft.world.EmptyBlockView;
|
||||||
import rs.valence.extractor.Main;
|
import rs.valence.extractor.Main;
|
||||||
|
|
||||||
|
@ -31,12 +31,12 @@ public class Blocks implements Main.Extractor {
|
||||||
|
|
||||||
var shapes = new LinkedHashMap<Shape, Integer>();
|
var shapes = new LinkedHashMap<Shape, Integer>();
|
||||||
|
|
||||||
for (var block : Registry.BLOCK) {
|
for (var block : Registries.BLOCK) {
|
||||||
var blockJson = new JsonObject();
|
var blockJson = new JsonObject();
|
||||||
blockJson.addProperty("id", Registry.BLOCK.getRawId(block));
|
blockJson.addProperty("id", Registries.BLOCK.getRawId(block));
|
||||||
blockJson.addProperty("name", Registry.BLOCK.getId(block).getPath());
|
blockJson.addProperty("name", Registries.BLOCK.getId(block).getPath());
|
||||||
blockJson.addProperty("translation_key", block.getTranslationKey());
|
blockJson.addProperty("translation_key", block.getTranslationKey());
|
||||||
blockJson.addProperty("item_id", Registry.ITEM.getRawId(block.asItem()));
|
blockJson.addProperty("item_id", Registries.ITEM.getRawId(block.asItem()));
|
||||||
|
|
||||||
var propsJson = new JsonArray();
|
var propsJson = new JsonArray();
|
||||||
for (var prop : block.getStateManager().getProperties()) {
|
for (var prop : block.getStateManager().getProperties()) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package rs.valence.extractor.extractors;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registries;
|
||||||
import rs.valence.extractor.Main;
|
import rs.valence.extractor.Main;
|
||||||
|
|
||||||
public class Enchants implements Main.Extractor {
|
public class Enchants implements Main.Extractor {
|
||||||
|
@ -19,11 +19,11 @@ public class Enchants implements Main.Extractor {
|
||||||
public JsonElement extract() {
|
public JsonElement extract() {
|
||||||
var enchantsJson = new JsonArray();
|
var enchantsJson = new JsonArray();
|
||||||
|
|
||||||
for (var enchant : Registry.ENCHANTMENT) {
|
for (var enchant : Registries.ENCHANTMENT) {
|
||||||
var enchantJson = new JsonObject();
|
var enchantJson = new JsonObject();
|
||||||
|
|
||||||
enchantJson.addProperty("id", Registry.ENCHANTMENT.getRawId(enchant));
|
enchantJson.addProperty("id", Registries.ENCHANTMENT.getRawId(enchant));
|
||||||
enchantJson.addProperty("name", Registry.ENCHANTMENT.getId(enchant).getPath());
|
enchantJson.addProperty("name", Registries.ENCHANTMENT.getId(enchant).getPath());
|
||||||
enchantJson.addProperty("translation_key", enchant.getTranslationKey());
|
enchantJson.addProperty("translation_key", enchant.getTranslationKey());
|
||||||
|
|
||||||
enchantJson.addProperty("min_level", enchant.getMinLevel());
|
enchantJson.addProperty("min_level", enchant.getMinLevel());
|
||||||
|
|
|
@ -11,12 +11,12 @@ import net.minecraft.entity.passive.CatVariant;
|
||||||
import net.minecraft.entity.passive.FrogVariant;
|
import net.minecraft.entity.passive.FrogVariant;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.particle.ParticleEffect;
|
import net.minecraft.particle.ParticleEffect;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
|
import net.minecraft.registry.entry.RegistryEntry;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.EulerAngle;
|
import net.minecraft.util.math.EulerAngle;
|
||||||
import net.minecraft.util.math.GlobalPos;
|
import net.minecraft.util.math.GlobalPos;
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
import net.minecraft.util.registry.RegistryEntry;
|
|
||||||
import net.minecraft.village.VillagerData;
|
import net.minecraft.village.VillagerData;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import rs.valence.extractor.ClassComparator;
|
import rs.valence.extractor.ClassComparator;
|
||||||
|
@ -150,6 +150,8 @@ public class Entities implements Main.Extractor {
|
||||||
return new Pair<>("byte", new JsonPrimitive((Byte) val));
|
return new Pair<>("byte", new JsonPrimitive((Byte) val));
|
||||||
} else if (handler == TrackedDataHandlerRegistry.INTEGER) {
|
} else if (handler == TrackedDataHandlerRegistry.INTEGER) {
|
||||||
return new Pair<>("integer", new JsonPrimitive((Integer) val));
|
return new Pair<>("integer", new JsonPrimitive((Integer) val));
|
||||||
|
} else if (handler == TrackedDataHandlerRegistry.LONG) {
|
||||||
|
return new Pair<>("long", new JsonPrimitive((Long) val));
|
||||||
} else if (handler == TrackedDataHandlerRegistry.FLOAT) {
|
} else if (handler == TrackedDataHandlerRegistry.FLOAT) {
|
||||||
return new Pair<>("float", new JsonPrimitive((Float) val));
|
return new Pair<>("float", new JsonPrimitive((Float) val));
|
||||||
} else if (handler == TrackedDataHandlerRegistry.STRING) {
|
} else if (handler == TrackedDataHandlerRegistry.STRING) {
|
||||||
|
@ -201,13 +203,13 @@ public class Entities implements Main.Extractor {
|
||||||
// TODO: base64 binary representation or SNBT?
|
// TODO: base64 binary representation or SNBT?
|
||||||
return new Pair<>("nbt_compound", new JsonPrimitive(val.toString()));
|
return new Pair<>("nbt_compound", new JsonPrimitive(val.toString()));
|
||||||
} else if (handler == TrackedDataHandlerRegistry.PARTICLE) {
|
} else if (handler == TrackedDataHandlerRegistry.PARTICLE) {
|
||||||
var id = Registry.PARTICLE_TYPE.getId(((ParticleEffect) val).getType());
|
var id = Registries.PARTICLE_TYPE.getId(((ParticleEffect) val).getType());
|
||||||
return new Pair<>("particle", new JsonPrimitive(id.getPath()));
|
return new Pair<>("particle", new JsonPrimitive(id.getPath()));
|
||||||
} else if (handler == TrackedDataHandlerRegistry.VILLAGER_DATA) {
|
} else if (handler == TrackedDataHandlerRegistry.VILLAGER_DATA) {
|
||||||
var vd = (VillagerData) val;
|
var vd = (VillagerData) val;
|
||||||
var json = new JsonObject();
|
var json = new JsonObject();
|
||||||
var type = Registry.VILLAGER_TYPE.getId(vd.getType()).getPath();
|
var type = Registries.VILLAGER_TYPE.getId(vd.getType()).getPath();
|
||||||
var profession = Registry.VILLAGER_PROFESSION.getId(vd.getProfession()).getPath();
|
var profession = Registries.VILLAGER_PROFESSION.getId(vd.getProfession()).getPath();
|
||||||
json.addProperty("type", type);
|
json.addProperty("type", type);
|
||||||
json.addProperty("profession", profession);
|
json.addProperty("profession", profession);
|
||||||
json.addProperty("level", vd.getLevel());
|
json.addProperty("level", vd.getLevel());
|
||||||
|
@ -218,9 +220,9 @@ public class Entities implements Main.Extractor {
|
||||||
} else if (handler == TrackedDataHandlerRegistry.ENTITY_POSE) {
|
} else if (handler == TrackedDataHandlerRegistry.ENTITY_POSE) {
|
||||||
return new Pair<>("entity_pose", new JsonPrimitive(((EntityPose) val).name().toLowerCase(Locale.ROOT)));
|
return new Pair<>("entity_pose", new JsonPrimitive(((EntityPose) val).name().toLowerCase(Locale.ROOT)));
|
||||||
} else if (handler == TrackedDataHandlerRegistry.CAT_VARIANT) {
|
} else if (handler == TrackedDataHandlerRegistry.CAT_VARIANT) {
|
||||||
return new Pair<>("cat_variant", new JsonPrimitive(Registry.CAT_VARIANT.getId((CatVariant) val).getPath()));
|
return new Pair<>("cat_variant", new JsonPrimitive(Registries.CAT_VARIANT.getId((CatVariant) val).getPath()));
|
||||||
} else if (handler == TrackedDataHandlerRegistry.FROG_VARIANT) {
|
} else if (handler == TrackedDataHandlerRegistry.FROG_VARIANT) {
|
||||||
return new Pair<>("frog_variant", new JsonPrimitive(Registry.FROG_VARIANT.getId((FrogVariant) val).getPath()));
|
return new Pair<>("frog_variant", new JsonPrimitive(Registries.FROG_VARIANT.getId((FrogVariant) val).getPath()));
|
||||||
} else if (handler == TrackedDataHandlerRegistry.OPTIONAL_GLOBAL_POS) {
|
} else if (handler == TrackedDataHandlerRegistry.OPTIONAL_GLOBAL_POS) {
|
||||||
return new Pair<>("optional_global_pos", ((Optional<?>) val).map(o -> {
|
return new Pair<>("optional_global_pos", ((Optional<?>) val).map(o -> {
|
||||||
var gp = (GlobalPos) o;
|
var gp = (GlobalPos) o;
|
||||||
|
@ -239,7 +241,7 @@ public class Entities implements Main.Extractor {
|
||||||
var variant = ((RegistryEntry<?>) val).getKey().map(k -> k.getValue().getPath()).orElse("");
|
var variant = ((RegistryEntry<?>) val).getKey().map(k -> k.getValue().getPath()).orElse("");
|
||||||
return new Pair<>("painting_variant", new JsonPrimitive(variant));
|
return new Pair<>("painting_variant", new JsonPrimitive(variant));
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unexpected tracked data type " + handler);
|
throw new IllegalArgumentException("Unexpected tracked data type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,6 +286,7 @@ public class Entities implements Main.Extractor {
|
||||||
// To obtain this, we create a dummy world to spawn the entities into and read the data tracker field from the base entity class.
|
// To obtain this, we create a dummy world to spawn the entities into and read the data tracker field from the base entity class.
|
||||||
// We also handle player entities specially since they cannot be spawned with EntityType#create.
|
// We also handle player entities specially since they cannot be spawned with EntityType#create.
|
||||||
final var entityInstance = entityType.equals(EntityType.PLAYER) ? DummyPlayerEntity.INSTANCE : entityType.create(DummyWorld.INSTANCE);
|
final var entityInstance = entityType.equals(EntityType.PLAYER) ? DummyPlayerEntity.INSTANCE : entityType.create(DummyWorld.INSTANCE);
|
||||||
|
|
||||||
final var dataTracker = (DataTracker) dataTrackerField.get(entityInstance);
|
final var dataTracker = (DataTracker) dataTrackerField.get(entityInstance);
|
||||||
|
|
||||||
while (entitiesMap.get(entityClass) == null) {
|
while (entitiesMap.get(entityClass) == null) {
|
||||||
|
@ -297,7 +300,7 @@ public class Entities implements Main.Extractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entityType != null) {
|
if (entityType != null) {
|
||||||
entityJson.addProperty("type", Registry.ENTITY_TYPE.getId(entityType).getPath());
|
entityJson.addProperty("type", Registries.ENTITY_TYPE.getId(entityType).getPath());
|
||||||
|
|
||||||
entityJson.add("translation_key", new JsonPrimitive(entityType.getTranslationKey()));
|
entityJson.add("translation_key", new JsonPrimitive(entityType.getTranslationKey()));
|
||||||
}
|
}
|
||||||
|
@ -332,6 +335,17 @@ public class Entities implements Main.Extractor {
|
||||||
}
|
}
|
||||||
entityJson.add("fields", fieldsJson);
|
entityJson.add("fields", fieldsJson);
|
||||||
|
|
||||||
|
var bb = entityInstance.getBoundingBox();
|
||||||
|
if (bb != null) {
|
||||||
|
var boundingBoxJson = new JsonObject();
|
||||||
|
|
||||||
|
boundingBoxJson.addProperty("size_x", bb.getXLength());
|
||||||
|
boundingBoxJson.addProperty("size_y", bb.getYLength());
|
||||||
|
boundingBoxJson.addProperty("size_z", bb.getZLength());
|
||||||
|
|
||||||
|
entityJson.add("default_bounding_box", boundingBoxJson);
|
||||||
|
}
|
||||||
|
|
||||||
entitiesMap.put(entityClass, entityJson);
|
entitiesMap.put(entityClass, entityJson);
|
||||||
|
|
||||||
if (!hasParent) {
|
if (!hasParent) {
|
||||||
|
|
|
@ -5,8 +5,8 @@ import com.google.gson.JsonObject;
|
||||||
import net.minecraft.entity.EntityPose;
|
import net.minecraft.entity.EntityPose;
|
||||||
import net.minecraft.entity.EntityStatuses;
|
import net.minecraft.entity.EntityStatuses;
|
||||||
import net.minecraft.network.packet.s2c.play.EntityAnimationS2CPacket;
|
import net.minecraft.network.packet.s2c.play.EntityAnimationS2CPacket;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
import rs.valence.extractor.Main;
|
import rs.valence.extractor.Main;
|
||||||
|
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
@ -23,8 +23,8 @@ public class EntityData implements Main.Extractor {
|
||||||
var dataJson = new JsonObject();
|
var dataJson = new JsonObject();
|
||||||
|
|
||||||
var typesJson = new JsonObject();
|
var typesJson = new JsonObject();
|
||||||
for (var type : Registry.ENTITY_TYPE) {
|
for (var type : Registries.ENTITY_TYPE) {
|
||||||
typesJson.addProperty(Registry.ENTITY_TYPE.getId(type).getPath(), Registry.ENTITY_TYPE.getRawId(type));
|
typesJson.addProperty(Registries.ENTITY_TYPE.getId(type).getPath(), Registries.ENTITY_TYPE.getRawId(type));
|
||||||
}
|
}
|
||||||
dataJson.add("types", typesJson);
|
dataJson.add("types", typesJson);
|
||||||
|
|
||||||
|
@ -50,36 +50,36 @@ public class EntityData implements Main.Extractor {
|
||||||
dataJson.add("animations", animationsJson);
|
dataJson.add("animations", animationsJson);
|
||||||
|
|
||||||
var villagerTypesJson = new JsonObject();
|
var villagerTypesJson = new JsonObject();
|
||||||
for (var type : Registry.VILLAGER_TYPE) {
|
for (var type : Registries.VILLAGER_TYPE) {
|
||||||
villagerTypesJson.addProperty(Registry.VILLAGER_TYPE.getId(type).getPath(), Registry.VILLAGER_TYPE.getRawId(type));
|
villagerTypesJson.addProperty(Registries.VILLAGER_TYPE.getId(type).getPath(), Registries.VILLAGER_TYPE.getRawId(type));
|
||||||
}
|
}
|
||||||
dataJson.add("villager_types", villagerTypesJson);
|
dataJson.add("villager_types", villagerTypesJson);
|
||||||
|
|
||||||
var villagerProfessionsJson = new JsonObject();
|
var villagerProfessionsJson = new JsonObject();
|
||||||
for (var profession : Registry.VILLAGER_PROFESSION) {
|
for (var profession : Registries.VILLAGER_PROFESSION) {
|
||||||
villagerProfessionsJson.addProperty(profession.id(), Registry.VILLAGER_PROFESSION.getRawId(profession));
|
villagerProfessionsJson.addProperty(profession.id(), Registries.VILLAGER_PROFESSION.getRawId(profession));
|
||||||
}
|
}
|
||||||
dataJson.add("villager_professions", villagerProfessionsJson);
|
dataJson.add("villager_professions", villagerProfessionsJson);
|
||||||
|
|
||||||
var catVariantsJson = new JsonObject();
|
var catVariantsJson = new JsonObject();
|
||||||
for (var variant : Registry.CAT_VARIANT) {
|
for (var variant : Registries.CAT_VARIANT) {
|
||||||
catVariantsJson.addProperty(Registry.CAT_VARIANT.getId(variant).getPath(), Registry.CAT_VARIANT.getRawId(variant));
|
catVariantsJson.addProperty(Registries.CAT_VARIANT.getId(variant).getPath(), Registries.CAT_VARIANT.getRawId(variant));
|
||||||
}
|
}
|
||||||
dataJson.add("cat_variants", catVariantsJson);
|
dataJson.add("cat_variants", catVariantsJson);
|
||||||
|
|
||||||
var frogVariantsJson = new JsonObject();
|
var frogVariantsJson = new JsonObject();
|
||||||
for (var variant : Registry.FROG_VARIANT) {
|
for (var variant : Registries.FROG_VARIANT) {
|
||||||
frogVariantsJson.addProperty(Registry.FROG_VARIANT.getId(variant).getPath(), Registry.FROG_VARIANT.getRawId(variant));
|
frogVariantsJson.addProperty(Registries.FROG_VARIANT.getId(variant).getPath(), Registries.FROG_VARIANT.getRawId(variant));
|
||||||
}
|
}
|
||||||
dataJson.add("frog_variants", frogVariantsJson);
|
dataJson.add("frog_variants", frogVariantsJson);
|
||||||
|
|
||||||
var paintingVariantsJson = new JsonObject();
|
var paintingVariantsJson = new JsonObject();
|
||||||
for (var variant : Registry.PAINTING_VARIANT) {
|
for (var variant : Registries.PAINTING_VARIANT) {
|
||||||
var variantJson = new JsonObject();
|
var variantJson = new JsonObject();
|
||||||
variantJson.addProperty("id", Registry.PAINTING_VARIANT.getRawId(variant));
|
variantJson.addProperty("id", Registries.PAINTING_VARIANT.getRawId(variant));
|
||||||
variantJson.addProperty("width", variant.getWidth());
|
variantJson.addProperty("width", variant.getWidth());
|
||||||
variantJson.addProperty("height", variant.getHeight());
|
variantJson.addProperty("height", variant.getHeight());
|
||||||
paintingVariantsJson.add(Registry.PAINTING_VARIANT.getId(variant).getPath(), variantJson);
|
paintingVariantsJson.add(Registries.PAINTING_VARIANT.getId(variant).getPath(), variantJson);
|
||||||
}
|
}
|
||||||
dataJson.add("painting_variants", paintingVariantsJson);
|
dataJson.add("painting_variants", paintingVariantsJson);
|
||||||
|
|
||||||
|
@ -97,8 +97,8 @@ public class EntityData implements Main.Extractor {
|
||||||
dataJson.add("poses", posesJson);
|
dataJson.add("poses", posesJson);
|
||||||
|
|
||||||
var particleTypesJson = new JsonObject();
|
var particleTypesJson = new JsonObject();
|
||||||
for (var type : Registry.PARTICLE_TYPE) {
|
for (var type : Registries.PARTICLE_TYPE) {
|
||||||
particleTypesJson.addProperty(Registry.PARTICLE_TYPE.getId(type).getPath(), Registry.PARTICLE_TYPE.getRawId(type));
|
particleTypesJson.addProperty(Registries.PARTICLE_TYPE.getId(type).getPath(), Registries.PARTICLE_TYPE.getRawId(type));
|
||||||
}
|
}
|
||||||
dataJson.add("particle_types", particleTypesJson);
|
dataJson.add("particle_types", particleTypesJson);
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ package rs.valence.extractor.extractors;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registries;
|
||||||
import rs.valence.extractor.Main;
|
import rs.valence.extractor.Main;
|
||||||
|
|
||||||
public class Items implements Main.Extractor {
|
public class Items implements Main.Extractor {
|
||||||
|
@ -19,10 +19,10 @@ public class Items implements Main.Extractor {
|
||||||
public JsonElement extract() throws Exception {
|
public JsonElement extract() throws Exception {
|
||||||
var itemsJson = new JsonArray();
|
var itemsJson = new JsonArray();
|
||||||
|
|
||||||
for (var item : Registry.ITEM) {
|
for (var item : Registries.ITEM) {
|
||||||
var itemJson = new JsonObject();
|
var itemJson = new JsonObject();
|
||||||
itemJson.addProperty("id", Registry.ITEM.getRawId(item));
|
itemJson.addProperty("id", Registries.ITEM.getRawId(item));
|
||||||
itemJson.addProperty("name", Registry.ITEM.getId(item).getPath());
|
itemJson.addProperty("name", Registries.ITEM.getId(item).getPath());
|
||||||
itemJson.addProperty("translation_key", item.getTranslationKey());
|
itemJson.addProperty("translation_key", item.getTranslationKey());
|
||||||
itemJson.addProperty("max_stack", item.getMaxCount());
|
itemJson.addProperty("max_stack", item.getMaxCount());
|
||||||
itemJson.addProperty("max_durability", item.getMaxDamage());
|
itemJson.addProperty("max_durability", item.getMaxDamage());
|
||||||
|
|
|
@ -14,17 +14,16 @@ use tokio::sync::OwnedSemaphorePermit;
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use valence_protocol::packets::s2c::play::{
|
use valence_protocol::packets::s2c::play::{
|
||||||
AcknowledgeBlockChange, ClearTitles, CloseContainerS2c, CombatDeath, CustomSoundEffect,
|
AcknowledgeBlockChange, ClearTitles, CloseContainerS2c, CombatDeath, DisconnectPlay,
|
||||||
DisconnectPlay, EntityAnimationS2c, EntityEvent, GameEvent, KeepAliveS2c, LoginPlayOwned,
|
EntityAnimationS2c, EntityEvent, GameEvent, KeepAliveS2c, LoginPlayOwned, OpenScreen,
|
||||||
OpenScreen, PluginMessageS2c, RemoveEntitiesEncode, ResourcePackS2c, RespawnOwned,
|
PluginMessageS2c, RemoveEntitiesEncode, ResourcePackS2c, RespawnOwned, SetActionBarText,
|
||||||
SetActionBarText, SetCenterChunk, SetContainerContentEncode, SetContainerSlotEncode,
|
SetCenterChunk, SetContainerContentEncode, SetContainerSlotEncode, SetDefaultSpawnPosition,
|
||||||
SetDefaultSpawnPosition, SetEntityMetadata, SetEntityVelocity, SetExperience, SetHealth,
|
SetEntityMetadata, SetEntityVelocity, SetExperience, SetHealth, SetRenderDistance,
|
||||||
SetRenderDistance, SetSubtitleText, SetTitleAnimationTimes, SetTitleText,
|
SetSubtitleText, SetTitleAnimationTimes, SetTitleText, SynchronizePlayerPosition,
|
||||||
SynchronizePlayerPosition, SystemChatMessage, UnloadChunk, UpdateAttributes, UpdateTime,
|
SystemChatMessage, UnloadChunk, UpdateAttributes, UpdateTime,
|
||||||
};
|
};
|
||||||
use valence_protocol::types::{
|
use valence_protocol::types::{
|
||||||
AttributeProperty, DisplayedSkinParts, GameMode, GameStateChangeReason, SoundCategory,
|
AttributeProperty, DisplayedSkinParts, GameMode, GameStateChangeReason, SyncPlayerPosLookFlags,
|
||||||
SyncPlayerPosLookFlags,
|
|
||||||
};
|
};
|
||||||
use valence_protocol::{
|
use valence_protocol::{
|
||||||
BlockPos, EncodePacket, Ident, ItemStack, RawBytes, Text, Username, VarInt,
|
BlockPos, EncodePacket, Ident, ItemStack, RawBytes, Text, Username, VarInt,
|
||||||
|
@ -576,25 +575,6 @@ impl<C: Config> Client<C> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Plays a sound to the client at a given position.
|
|
||||||
pub fn play_sound(
|
|
||||||
&mut self,
|
|
||||||
name: Ident<&str>,
|
|
||||||
category: SoundCategory,
|
|
||||||
pos: Vec3<f64>,
|
|
||||||
volume: f32,
|
|
||||||
pitch: f32,
|
|
||||||
) {
|
|
||||||
self.queue_packet(&CustomSoundEffect {
|
|
||||||
name,
|
|
||||||
category,
|
|
||||||
position: (pos.as_() * 8).into_array(),
|
|
||||||
volume,
|
|
||||||
pitch,
|
|
||||||
seed: rand::random(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the title this client sees.
|
/// Sets the title this client sees.
|
||||||
///
|
///
|
||||||
/// A title is a large piece of text displayed in the center of the screen
|
/// A title is a large piece of text displayed in the center of the screen
|
||||||
|
@ -1033,6 +1013,13 @@ impl<C: Config> Client<C> {
|
||||||
.map(|(id, pos)| (id.dimension_name(), pos)),
|
.map(|(id, pos)| (id.dimension_name(), pos)),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
/*
|
||||||
|
// TODO: enable all the features?
|
||||||
|
send.append_packet(&FeatureFlags {
|
||||||
|
features: vec![Ident::new("vanilla").unwrap()],
|
||||||
|
})?;
|
||||||
|
*/
|
||||||
|
|
||||||
if let Some(id) = &self.player_list {
|
if let Some(id) = &self.player_list {
|
||||||
player_lists[id].write_init_packets(&mut *send)?;
|
player_lists[id].write_init_packets(&mut *send)?;
|
||||||
}
|
}
|
||||||
|
@ -1378,6 +1365,15 @@ impl<C: Config> Client<C> {
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.bits.created_this_tick() {
|
||||||
|
// This closes the "downloading terrain" screen.
|
||||||
|
// Send this after the initial chunks are loaded.
|
||||||
|
send.append_packet(&SetDefaultSpawnPosition {
|
||||||
|
position: BlockPos::at(self.position.into_array()),
|
||||||
|
angle: self.yaw,
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
// Update the client's own player metadata.
|
// Update the client's own player metadata.
|
||||||
self.scratch.clear();
|
self.scratch.clear();
|
||||||
self.player_data.updated_tracked_data(&mut self.scratch);
|
self.player_data.updated_tracked_data(&mut self.scratch);
|
||||||
|
|
|
@ -188,6 +188,12 @@ pub enum ClientEvent {
|
||||||
Pong {
|
Pong {
|
||||||
id: i32,
|
id: i32,
|
||||||
},
|
},
|
||||||
|
PlayerSession {
|
||||||
|
session_id: Uuid,
|
||||||
|
expires_at: i64,
|
||||||
|
public_key_data: Box<[u8]>,
|
||||||
|
key_signature: Box<[u8]>,
|
||||||
|
},
|
||||||
ChangeRecipeBookSettings {
|
ChangeRecipeBookSettings {
|
||||||
book_id: RecipeBookId,
|
book_id: RecipeBookId,
|
||||||
book_open: bool,
|
book_open: bool,
|
||||||
|
@ -336,7 +342,6 @@ pub(super) fn next_event_fallible<C: Config>(
|
||||||
message: p.message.into(),
|
message: p.message.into(),
|
||||||
timestamp: p.timestamp,
|
timestamp: p.timestamp,
|
||||||
},
|
},
|
||||||
C2sPlayPacket::ChatPreviewC2s(_) => ClientEvent::ChatPreview,
|
|
||||||
C2sPlayPacket::ClientCommand(p) => match p {
|
C2sPlayPacket::ClientCommand(p) => match p {
|
||||||
ClientCommand::PerformRespawn => ClientEvent::PerformRespawn,
|
ClientCommand::PerformRespawn => ClientEvent::PerformRespawn,
|
||||||
ClientCommand::RequestStats => ClientEvent::RequestStats,
|
ClientCommand::RequestStats => ClientEvent::RequestStats,
|
||||||
|
@ -553,6 +558,12 @@ pub(super) fn next_event_fallible<C: Config>(
|
||||||
unmount: p.flags.unmount(),
|
unmount: p.flags.unmount(),
|
||||||
},
|
},
|
||||||
C2sPlayPacket::PongPlay(p) => ClientEvent::Pong { id: p.id },
|
C2sPlayPacket::PongPlay(p) => ClientEvent::Pong { id: p.id },
|
||||||
|
C2sPlayPacket::PlayerSession(p) => ClientEvent::PlayerSession {
|
||||||
|
session_id: p.session_id,
|
||||||
|
expires_at: p.expires_at,
|
||||||
|
public_key_data: p.public_key_data.into(),
|
||||||
|
key_signature: p.key_signature.into(),
|
||||||
|
},
|
||||||
C2sPlayPacket::ChangeRecipeBookSettings(p) => ClientEvent::ChangeRecipeBookSettings {
|
C2sPlayPacket::ChangeRecipeBookSettings(p) => ClientEvent::ChangeRecipeBookSettings {
|
||||||
book_id: p.book_id,
|
book_id: p.book_id,
|
||||||
book_open: p.book_open,
|
book_open: p.book_open,
|
||||||
|
|
|
@ -517,6 +517,7 @@ impl<C: Config> Entity<C> {
|
||||||
TrackedData::Bee(e) => baby(e.get_child(), [0.7, 0.6, 0.7]),
|
TrackedData::Bee(e) => baby(e.get_child(), [0.7, 0.6, 0.7]),
|
||||||
TrackedData::Blaze(_) => [0.6, 1.8, 0.6],
|
TrackedData::Blaze(_) => [0.6, 1.8, 0.6],
|
||||||
TrackedData::Boat(_) => [1.375, 0.5625, 1.375],
|
TrackedData::Boat(_) => [1.375, 0.5625, 1.375],
|
||||||
|
TrackedData::Camel(e) => baby(e.get_child(), [1.7, 2.375, 1.7]),
|
||||||
TrackedData::Cat(_) => [0.6, 0.7, 0.6],
|
TrackedData::Cat(_) => [0.6, 0.7, 0.6],
|
||||||
TrackedData::CaveSpider(_) => [0.7, 0.5, 0.7],
|
TrackedData::CaveSpider(_) => [0.7, 0.5, 0.7],
|
||||||
TrackedData::Chicken(e) => baby(e.get_child(), [0.4, 0.7, 0.4]),
|
TrackedData::Chicken(e) => baby(e.get_child(), [0.4, 0.7, 0.4]),
|
||||||
|
|
|
@ -4,10 +4,10 @@ use std::collections::hash_map::Entry;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::ops::{Deref, DerefMut, Index, IndexMut};
|
use std::ops::{Deref, DerefMut, Index, IndexMut};
|
||||||
|
|
||||||
use bitfield_struct::bitfield;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use valence_protocol::packets::s2c::play::{PlayerInfo, SetTabListHeaderAndFooter};
|
use valence_protocol::packets::s2c::play::{PlayerInfoRemove, SetTabListHeaderAndFooter};
|
||||||
use valence_protocol::types::{GameMode, PlayerInfoAddPlayer, SignedProperty};
|
use valence_protocol::player_list::{Actions, Entry as PacketEntry, PlayerInfoUpdate};
|
||||||
|
use valence_protocol::types::{GameMode, SignedProperty};
|
||||||
use valence_protocol::Text;
|
use valence_protocol::Text;
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
|
@ -76,7 +76,7 @@ impl<C: Config> PlayerLists<C> {
|
||||||
pub(crate) fn update_caches(&mut self, compression_threshold: Option<u32>) {
|
pub(crate) fn update_caches(&mut self, compression_threshold: Option<u32>) {
|
||||||
let mut scratch = vec![];
|
let mut scratch = vec![];
|
||||||
|
|
||||||
// Cache the update packets.
|
// Cache the update packets for each player list.
|
||||||
for pl in self.slab.iter_mut() {
|
for pl in self.slab.iter_mut() {
|
||||||
pl.cached_update_packets.clear();
|
pl.cached_update_packets.clear();
|
||||||
|
|
||||||
|
@ -88,90 +88,114 @@ impl<C: Config> PlayerLists<C> {
|
||||||
|
|
||||||
if !pl.removed.is_empty() {
|
if !pl.removed.is_empty() {
|
||||||
writer
|
writer
|
||||||
.write_packet(&PlayerInfo::RemovePlayer(
|
.write_packet(&PlayerInfoRemove(pl.removed.iter().cloned().collect()))
|
||||||
pl.removed.iter().cloned().collect(),
|
|
||||||
))
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut add_player = vec![];
|
|
||||||
let mut game_mode = vec![];
|
|
||||||
let mut ping = vec![];
|
|
||||||
let mut display_name = vec![];
|
|
||||||
|
|
||||||
for (&uuid, entry) in pl.entries.iter_mut() {
|
for (&uuid, entry) in pl.entries.iter_mut() {
|
||||||
if entry.bits.created_this_tick() {
|
if entry.created_this_tick {
|
||||||
let mut properties = vec![];
|
// Send packets to initialize this entry.
|
||||||
if let Some(textures) = &entry.textures {
|
|
||||||
properties.push(SignedProperty {
|
let mut actions = Actions::new().with_add_player(true);
|
||||||
|
|
||||||
|
// We don't need to send data for fields if they have the default values.
|
||||||
|
|
||||||
|
if entry.listed {
|
||||||
|
actions.set_update_listed(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Negative pings indicate absence.
|
||||||
|
if entry.ping >= 0 {
|
||||||
|
actions.set_update_latency(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if entry.game_mode != GameMode::default() {
|
||||||
|
actions.set_update_game_mode(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if entry.display_name.is_some() {
|
||||||
|
actions.set_update_display_name(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't forget to clear modified flags.
|
||||||
|
entry.old_listed = entry.listed;
|
||||||
|
entry.modified_ping = false;
|
||||||
|
entry.modified_game_mode = false;
|
||||||
|
entry.modified_display_name = false;
|
||||||
|
entry.created_this_tick = false;
|
||||||
|
|
||||||
|
let entries = vec![PacketEntry {
|
||||||
|
player_uuid: uuid,
|
||||||
|
username: &entry.username,
|
||||||
|
properties: entry
|
||||||
|
.textures
|
||||||
|
.as_ref()
|
||||||
|
.map(|textures| SignedProperty {
|
||||||
name: "textures",
|
name: "textures",
|
||||||
value: textures.payload(),
|
value: textures.payload(),
|
||||||
signature: Some(textures.signature()),
|
signature: Some(textures.signature()),
|
||||||
});
|
})
|
||||||
}
|
.into_iter()
|
||||||
|
.collect(),
|
||||||
add_player.push(PlayerInfoAddPlayer {
|
chat_data: None,
|
||||||
uuid,
|
listed: entry.listed,
|
||||||
username: &entry.username,
|
ping: entry.ping,
|
||||||
properties,
|
|
||||||
game_mode: entry.game_mode,
|
game_mode: entry.game_mode,
|
||||||
ping: entry.ping.into(),
|
|
||||||
display_name: entry.display_name.clone(),
|
display_name: entry.display_name.clone(),
|
||||||
sig_data: None,
|
}];
|
||||||
});
|
|
||||||
|
writer
|
||||||
|
.write_packet(&PlayerInfoUpdate { actions, entries })
|
||||||
|
.unwrap();
|
||||||
} else {
|
} else {
|
||||||
if entry.bits.modified_game_mode() {
|
let mut actions = Actions::new();
|
||||||
game_mode.push((uuid, entry.game_mode));
|
|
||||||
|
if entry.modified_ping {
|
||||||
|
entry.modified_ping = false;
|
||||||
|
actions.set_update_latency(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if entry.bits.modified_ping() {
|
if entry.modified_game_mode {
|
||||||
ping.push((uuid, entry.ping.into()));
|
entry.modified_game_mode = false;
|
||||||
|
actions.set_update_game_mode(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if entry.bits.modified_display_name() {
|
if entry.old_listed != entry.listed {
|
||||||
display_name.push((uuid, entry.display_name.clone()));
|
entry.old_listed = entry.listed;
|
||||||
}
|
actions.set_update_listed(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.bits = EntryBits::new();
|
if entry.modified_ping {
|
||||||
|
entry.modified_ping = false;
|
||||||
|
actions.set_update_latency(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !add_player.is_empty() {
|
if entry.modified_display_name {
|
||||||
|
entry.modified_display_name = false;
|
||||||
|
actions.set_update_display_name(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if u8::from(actions) != 0 {
|
||||||
writer
|
writer
|
||||||
.write_packet(&PlayerInfo::AddPlayer(add_player))
|
.write_packet(&PlayerInfoUpdate {
|
||||||
.unwrap();
|
actions,
|
||||||
}
|
entries: vec![PacketEntry {
|
||||||
|
player_uuid: uuid,
|
||||||
if !game_mode.is_empty() {
|
username: &entry.username,
|
||||||
writer
|
properties: vec![],
|
||||||
.write_packet(&PlayerInfo::UpdateGameMode(game_mode))
|
chat_data: None,
|
||||||
.unwrap();
|
listed: entry.listed,
|
||||||
}
|
ping: entry.ping,
|
||||||
|
game_mode: entry.game_mode,
|
||||||
if !ping.is_empty() {
|
display_name: entry.display_name.clone(),
|
||||||
writer
|
}],
|
||||||
.write_packet(&PlayerInfo::UpdateLatency(ping))
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
if !display_name.is_empty() {
|
|
||||||
writer
|
|
||||||
.write_packet(&PlayerInfo::UpdateDisplayName(display_name))
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
if pl.modified_header_or_footer {
|
|
||||||
pl.modified_header_or_footer = false;
|
|
||||||
|
|
||||||
writer
|
|
||||||
.write_packet(&SetTabListHeaderAndFooter {
|
|
||||||
header: pl.header.clone(),
|
|
||||||
footer: pl.footer.clone(),
|
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn clear_removed(&mut self) {
|
pub(crate) fn clear_removed(&mut self) {
|
||||||
for pl in self.slab.iter_mut() {
|
for pl in self.slab.iter_mut() {
|
||||||
|
@ -206,6 +230,7 @@ pub struct PlayerList<C: Config> {
|
||||||
pub state: C::PlayerListState,
|
pub state: C::PlayerListState,
|
||||||
cached_update_packets: Vec<u8>,
|
cached_update_packets: Vec<u8>,
|
||||||
entries: HashMap<Uuid, PlayerListEntry>,
|
entries: HashMap<Uuid, PlayerListEntry>,
|
||||||
|
/// Contains entries that need to be removed.
|
||||||
removed: HashSet<Uuid>,
|
removed: HashSet<Uuid>,
|
||||||
header: Text,
|
header: Text,
|
||||||
footer: Text,
|
footer: Text,
|
||||||
|
@ -231,6 +256,7 @@ impl<C: Config> PlayerList<C> {
|
||||||
///
|
///
|
||||||
/// If the given UUID conflicts with an existing entry, the entry is
|
/// If the given UUID conflicts with an existing entry, the entry is
|
||||||
/// overwritten and `false` is returned. Otherwise, `true` is returned.
|
/// overwritten and `false` is returned. Otherwise, `true` is returned.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn insert(
|
pub fn insert(
|
||||||
&mut self,
|
&mut self,
|
||||||
uuid: Uuid,
|
uuid: Uuid,
|
||||||
|
@ -239,6 +265,7 @@ impl<C: Config> PlayerList<C> {
|
||||||
game_mode: GameMode,
|
game_mode: GameMode,
|
||||||
ping: i32,
|
ping: i32,
|
||||||
display_name: Option<Text>,
|
display_name: Option<Text>,
|
||||||
|
listed: bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match self.entries.entry(uuid) {
|
match self.entries.entry(uuid) {
|
||||||
Entry::Occupied(mut oe) => {
|
Entry::Occupied(mut oe) => {
|
||||||
|
@ -246,7 +273,9 @@ impl<C: Config> PlayerList<C> {
|
||||||
let username = username.into();
|
let username = username.into();
|
||||||
|
|
||||||
if e.username() != username || e.textures != textures {
|
if e.username() != username || e.textures != textures {
|
||||||
if !e.bits.created_this_tick() {
|
// Entries created this tick haven't been initialized by clients yet, so there
|
||||||
|
// is nothing to remove.
|
||||||
|
if !e.created_this_tick {
|
||||||
self.removed.insert(*oe.key());
|
self.removed.insert(*oe.key());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,13 +285,20 @@ impl<C: Config> PlayerList<C> {
|
||||||
game_mode,
|
game_mode,
|
||||||
ping,
|
ping,
|
||||||
display_name,
|
display_name,
|
||||||
bits: EntryBits::new().with_created_this_tick(true),
|
old_listed: listed,
|
||||||
|
listed,
|
||||||
|
created_this_tick: true,
|
||||||
|
modified_game_mode: false,
|
||||||
|
modified_ping: false,
|
||||||
|
modified_display_name: false,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
e.set_game_mode(game_mode);
|
e.set_game_mode(game_mode);
|
||||||
e.set_ping(ping);
|
e.set_ping(ping);
|
||||||
e.set_display_name(display_name);
|
e.set_display_name(display_name);
|
||||||
|
e.set_listed(listed);
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
Entry::Vacant(ve) => {
|
Entry::Vacant(ve) => {
|
||||||
|
@ -272,8 +308,14 @@ impl<C: Config> PlayerList<C> {
|
||||||
game_mode,
|
game_mode,
|
||||||
ping,
|
ping,
|
||||||
display_name,
|
display_name,
|
||||||
bits: EntryBits::new().with_created_this_tick(true),
|
old_listed: listed,
|
||||||
|
listed,
|
||||||
|
created_this_tick: true,
|
||||||
|
modified_game_mode: false,
|
||||||
|
modified_ping: false,
|
||||||
|
modified_display_name: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,43 +405,50 @@ impl<C: Config> PlayerList<C> {
|
||||||
|
|
||||||
/// Writes the packets needed to completely initialize this player list.
|
/// Writes the packets needed to completely initialize this player list.
|
||||||
pub(crate) fn write_init_packets(&self, mut writer: impl WritePacket) -> anyhow::Result<()> {
|
pub(crate) fn write_init_packets(&self, mut writer: impl WritePacket) -> anyhow::Result<()> {
|
||||||
let add_player: Vec<_> = self
|
let actions = Actions::new()
|
||||||
|
.with_add_player(true)
|
||||||
|
.with_update_game_mode(true)
|
||||||
|
.with_update_listed(true)
|
||||||
|
.with_update_latency(true)
|
||||||
|
.with_update_display_name(true);
|
||||||
|
|
||||||
|
let entries: Vec<_> = self
|
||||||
.entries
|
.entries
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(&uuid, entry)| PlayerInfoAddPlayer {
|
.map(|(&uuid, entry)| {
|
||||||
uuid,
|
let properties = entry
|
||||||
username: &entry.username,
|
.textures
|
||||||
properties: {
|
.as_ref()
|
||||||
let mut properties = vec![];
|
.map(|textures| SignedProperty {
|
||||||
if let Some(textures) = &entry.textures {
|
|
||||||
properties.push(SignedProperty {
|
|
||||||
name: "textures",
|
name: "textures",
|
||||||
value: textures.payload(),
|
value: textures.payload(),
|
||||||
signature: Some(textures.signature()),
|
signature: Some(textures.signature()),
|
||||||
});
|
})
|
||||||
}
|
.into_iter()
|
||||||
properties
|
.collect();
|
||||||
},
|
|
||||||
|
PacketEntry {
|
||||||
|
player_uuid: uuid,
|
||||||
|
username: entry.username(),
|
||||||
|
properties,
|
||||||
|
chat_data: None,
|
||||||
|
listed: entry.listed,
|
||||||
|
ping: entry.ping,
|
||||||
game_mode: entry.game_mode,
|
game_mode: entry.game_mode,
|
||||||
ping: entry.ping.into(),
|
|
||||||
display_name: entry.display_name.clone(),
|
display_name: entry.display_name.clone(),
|
||||||
sig_data: None,
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if !add_player.is_empty() {
|
if !entries.is_empty() {
|
||||||
writer
|
writer.write_packet(&PlayerInfoUpdate { actions, entries })?;
|
||||||
.write_packet(&PlayerInfo::AddPlayer(add_player))
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.header.is_empty() || self.footer.is_empty() {
|
if !self.header.is_empty() || !self.footer.is_empty() {
|
||||||
writer
|
writer.write_packet(&SetTabListHeaderAndFooter {
|
||||||
.write_packet(&SetTabListHeaderAndFooter {
|
|
||||||
header: self.header.clone(),
|
header: self.header.clone(),
|
||||||
footer: self.footer.clone(),
|
footer: self.footer.clone(),
|
||||||
})
|
})?;
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -420,7 +469,7 @@ impl<C: Config> PlayerList<C> {
|
||||||
.chain(self.removed.iter().cloned())
|
.chain(self.removed.iter().cloned())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
writer.write_packet(&PlayerInfo::RemovePlayer(uuids))
|
writer.write_packet(&PlayerInfoRemove(uuids))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,17 +480,12 @@ pub struct PlayerListEntry {
|
||||||
game_mode: GameMode,
|
game_mode: GameMode,
|
||||||
ping: i32,
|
ping: i32,
|
||||||
display_name: Option<Text>,
|
display_name: Option<Text>,
|
||||||
bits: EntryBits,
|
old_listed: bool,
|
||||||
}
|
listed: bool,
|
||||||
|
|
||||||
#[bitfield(u8)]
|
|
||||||
struct EntryBits {
|
|
||||||
created_this_tick: bool,
|
created_this_tick: bool,
|
||||||
modified_game_mode: bool,
|
modified_game_mode: bool,
|
||||||
modified_ping: bool,
|
modified_ping: bool,
|
||||||
modified_display_name: bool,
|
modified_display_name: bool,
|
||||||
#[bits(4)]
|
|
||||||
_pad: u8,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PlayerListEntry {
|
impl PlayerListEntry {
|
||||||
|
@ -464,7 +508,8 @@ impl PlayerListEntry {
|
||||||
pub fn set_game_mode(&mut self, game_mode: GameMode) {
|
pub fn set_game_mode(&mut self, game_mode: GameMode) {
|
||||||
if self.game_mode != game_mode {
|
if self.game_mode != game_mode {
|
||||||
self.game_mode = game_mode;
|
self.game_mode = game_mode;
|
||||||
self.bits.set_modified_game_mode(true);
|
// TODO: replace modified_game_mode with old_game_mode
|
||||||
|
self.modified_game_mode = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,7 +522,7 @@ impl PlayerListEntry {
|
||||||
pub fn set_ping(&mut self, ping: i32) {
|
pub fn set_ping(&mut self, ping: i32) {
|
||||||
if self.ping != ping {
|
if self.ping != ping {
|
||||||
self.ping = ping;
|
self.ping = ping;
|
||||||
self.bits.set_modified_ping(true);
|
self.modified_ping = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,7 +536,17 @@ impl PlayerListEntry {
|
||||||
let display_name = display_name.into();
|
let display_name = display_name.into();
|
||||||
if self.display_name != display_name {
|
if self.display_name != display_name {
|
||||||
self.display_name = display_name;
|
self.display_name = display_name;
|
||||||
self.bits.set_modified_display_name(true);
|
self.modified_display_name = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If this entry is visible on the player list.
|
||||||
|
pub fn is_listed(&self) -> bool {
|
||||||
|
self.listed
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets if this entry is visible on the player list.
|
||||||
|
pub fn set_listed(&mut self, listed: bool) {
|
||||||
|
self.listed = listed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -693,7 +693,6 @@ async fn handle_login(
|
||||||
|
|
||||||
let LoginStart {
|
let LoginStart {
|
||||||
username,
|
username,
|
||||||
sig_data: _, // TODO
|
|
||||||
profile_id: _, // TODO
|
profile_id: _, // TODO
|
||||||
} = mngr.recv_packet().await?;
|
} = mngr.recv_packet().await?;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ use valence_protocol::packets::c2s::login::{EncryptionResponse, LoginPluginRespo
|
||||||
use valence_protocol::packets::s2c::login::{
|
use valence_protocol::packets::s2c::login::{
|
||||||
DisconnectLogin, EncryptionRequest, LoginPluginRequest,
|
DisconnectLogin, EncryptionRequest, LoginPluginRequest,
|
||||||
};
|
};
|
||||||
use valence_protocol::types::{MsgSigOrVerifyToken, SignedProperty, SignedPropertyOwned};
|
use valence_protocol::types::{SignedProperty, SignedPropertyOwned};
|
||||||
use valence_protocol::{translation_key, Decode, Ident, RawBytes, Text, Username, VarInt};
|
use valence_protocol::{translation_key, Decode, Ident, RawBytes, Text, Username, VarInt};
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
|
@ -31,13 +31,13 @@ use crate::server::{NewClientData, SharedServer};
|
||||||
/// [`ConnectionMode::Online`](crate::config::ConnectionMode).
|
/// [`ConnectionMode::Online`](crate::config::ConnectionMode).
|
||||||
pub(super) async fn online(
|
pub(super) async fn online(
|
||||||
server: &SharedServer<impl Config>,
|
server: &SharedServer<impl Config>,
|
||||||
ctrl: &mut InitialPacketManager<OwnedReadHalf, OwnedWriteHalf>,
|
mngr: &mut InitialPacketManager<OwnedReadHalf, OwnedWriteHalf>,
|
||||||
remote_addr: SocketAddr,
|
remote_addr: SocketAddr,
|
||||||
username: Username<String>,
|
username: Username<String>,
|
||||||
) -> anyhow::Result<NewClientData> {
|
) -> anyhow::Result<NewClientData> {
|
||||||
let my_verify_token: [u8; 16] = rand::random();
|
let my_verify_token: [u8; 16] = rand::random();
|
||||||
|
|
||||||
ctrl.send_packet(&EncryptionRequest {
|
mngr.send_packet(&EncryptionRequest {
|
||||||
server_id: "", // Always empty
|
server_id: "", // Always empty
|
||||||
public_key: &server.0.public_key_der,
|
public_key: &server.0.public_key_der,
|
||||||
verify_token: &my_verify_token,
|
verify_token: &my_verify_token,
|
||||||
|
@ -46,8 +46,8 @@ pub(super) async fn online(
|
||||||
|
|
||||||
let EncryptionResponse {
|
let EncryptionResponse {
|
||||||
shared_secret,
|
shared_secret,
|
||||||
sig_or_token,
|
verify_token: encrypted_verify_token,
|
||||||
} = ctrl.recv_packet().await?;
|
} = mngr.recv_packet().await?;
|
||||||
|
|
||||||
let shared_secret = server
|
let shared_secret = server
|
||||||
.0
|
.0
|
||||||
|
@ -55,8 +55,6 @@ pub(super) async fn online(
|
||||||
.decrypt(PaddingScheme::PKCS1v15Encrypt, shared_secret)
|
.decrypt(PaddingScheme::PKCS1v15Encrypt, shared_secret)
|
||||||
.context("failed to decrypt shared secret")?;
|
.context("failed to decrypt shared secret")?;
|
||||||
|
|
||||||
match sig_or_token {
|
|
||||||
MsgSigOrVerifyToken::VerifyToken(encrypted_verify_token) => {
|
|
||||||
let verify_token = server
|
let verify_token = server
|
||||||
.0
|
.0
|
||||||
.rsa_key
|
.rsa_key
|
||||||
|
@ -67,16 +65,13 @@ pub(super) async fn online(
|
||||||
my_verify_token.as_slice() == verify_token,
|
my_verify_token.as_slice() == verify_token,
|
||||||
"verify tokens do not match"
|
"verify tokens do not match"
|
||||||
);
|
);
|
||||||
}
|
|
||||||
MsgSigOrVerifyToken::MsgSig { .. } => {}
|
|
||||||
};
|
|
||||||
|
|
||||||
let crypt_key: [u8; 16] = shared_secret
|
let crypt_key: [u8; 16] = shared_secret
|
||||||
.as_slice()
|
.as_slice()
|
||||||
.try_into()
|
.try_into()
|
||||||
.context("shared secret has the wrong length")?;
|
.context("shared secret has the wrong length")?;
|
||||||
|
|
||||||
ctrl.enable_encryption(&crypt_key);
|
mngr.enable_encryption(&crypt_key);
|
||||||
|
|
||||||
let hash = Sha1::new()
|
let hash = Sha1::new()
|
||||||
.chain(&shared_secret)
|
.chain(&shared_secret)
|
||||||
|
@ -99,7 +94,7 @@ pub(super) async fn online(
|
||||||
translation_key::MULTIPLAYER_DISCONNECT_UNVERIFIED_USERNAME,
|
translation_key::MULTIPLAYER_DISCONNECT_UNVERIFIED_USERNAME,
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
ctrl.send_packet(&DisconnectLogin { reason }).await?;
|
mngr.send_packet(&DisconnectLogin { reason }).await?;
|
||||||
bail!("session server could not verify username");
|
bail!("session server could not verify username");
|
||||||
}
|
}
|
||||||
status => {
|
status => {
|
||||||
|
@ -131,8 +126,8 @@ pub(super) async fn online(
|
||||||
Ok(NewClientData {
|
Ok(NewClientData {
|
||||||
uuid,
|
uuid,
|
||||||
username,
|
username,
|
||||||
textures: Some(textures),
|
|
||||||
ip: remote_addr.ip(),
|
ip: remote_addr.ip(),
|
||||||
|
textures: Some(textures),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,17 +192,17 @@ fn auth_digest(bytes: &[u8]) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) async fn velocity(
|
pub(super) async fn velocity(
|
||||||
ctrl: &mut InitialPacketManager<OwnedReadHalf, OwnedWriteHalf>,
|
mngr: &mut InitialPacketManager<OwnedReadHalf, OwnedWriteHalf>,
|
||||||
username: Username<String>,
|
username: Username<String>,
|
||||||
velocity_secret: &str,
|
velocity_secret: &str,
|
||||||
) -> anyhow::Result<NewClientData> {
|
) -> anyhow::Result<NewClientData> {
|
||||||
const VELOCITY_MIN_SUPPORTED_VERSION: u8 = 1;
|
const VELOCITY_MIN_SUPPORTED_VERSION: u8 = 1;
|
||||||
const VELOCITY_MODERN_FORWARDING_WITH_KEY_V2: i32 = 3;
|
const VELOCITY_MODERN_FORWARDING_WITH_KEY_V2: i32 = 3;
|
||||||
|
|
||||||
let message_id = 0;
|
let message_id: i32 = 0; // TODO: make this random?
|
||||||
|
|
||||||
// Send Player Info Request into the Plugin Channel
|
// Send Player Info Request into the Plugin Channel
|
||||||
ctrl.send_packet(&LoginPluginRequest {
|
mngr.send_packet(&LoginPluginRequest {
|
||||||
message_id: VarInt(message_id),
|
message_id: VarInt(message_id),
|
||||||
channel: Ident::new("velocity:player_info").unwrap(),
|
channel: Ident::new("velocity:player_info").unwrap(),
|
||||||
data: RawBytes(&[VELOCITY_MIN_SUPPORTED_VERSION]),
|
data: RawBytes(&[VELOCITY_MIN_SUPPORTED_VERSION]),
|
||||||
|
@ -215,7 +210,7 @@ pub(super) async fn velocity(
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Get Response
|
// Get Response
|
||||||
let plugin_response: LoginPluginResponse = ctrl.recv_packet().await?;
|
let plugin_response: LoginPluginResponse = mngr.recv_packet().await?;
|
||||||
|
|
||||||
ensure!(
|
ensure!(
|
||||||
plugin_response.message_id.0 == message_id,
|
plugin_response.message_id.0 == message_id,
|
||||||
|
@ -290,7 +285,7 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn auth_digest_correct() {
|
fn auth_digest_usernames() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
auth_digest(&Sha1::digest("Notch")),
|
auth_digest(&Sha1::digest("Notch")),
|
||||||
"4ed1f46bbe04bc756bcb17c0c7ce3e4632f06a48"
|
"4ed1f46bbe04bc756bcb17c0c7ce3e4632f06a48"
|
||||||
|
|
|
@ -15,7 +15,7 @@ byteorder = "1.4.3"
|
||||||
flate2 = "1.0.25"
|
flate2 = "1.0.25"
|
||||||
thiserror = "1.0.37"
|
thiserror = "1.0.37"
|
||||||
num-integer = "0.1.45" # TODO: remove when div_ceil is stabilized.
|
num-integer = "0.1.45" # TODO: remove when div_ceil is stabilized.
|
||||||
valence = { version = "0.1.0", path = "..", optional = true }
|
valence = { version = "0.2.0", path = "..", optional = true }
|
||||||
valence_nbt = { version = "0.5.0", path = "../valence_nbt" }
|
valence_nbt = { version = "0.5.0", path = "../valence_nbt" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
@ -23,7 +23,7 @@ anyhow = "1.0.68"
|
||||||
criterion = "0.4.0"
|
criterion = "0.4.0"
|
||||||
fs_extra = "1.2.0"
|
fs_extra = "1.2.0"
|
||||||
tempfile = "3.3.0"
|
tempfile = "3.3.0"
|
||||||
valence = { version = "0.1.0", path = ".." }
|
valence = { version = "0.2.0", path = ".." }
|
||||||
valence_anvil = { version = "0.1.0", path = ".", features = ["valence"] }
|
valence_anvil = { version = "0.1.0", path = ".", features = ["valence"] }
|
||||||
zip = "0.6.3"
|
zip = "0.6.3"
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,7 @@ impl Config for Game {
|
||||||
client.game_mode(),
|
client.game_mode(),
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,12 @@ impl Decode<'_> for u64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Encode for i64 {
|
||||||
|
fn encode(&self, mut w: impl Write) -> Result<()> {
|
||||||
|
Ok(w.write_i64::<BigEndian>(*self)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Decode<'_> for i64 {
|
impl Decode<'_> for i64 {
|
||||||
fn decode(r: &mut &[u8]) -> Result<Self> {
|
fn decode(r: &mut &[u8]) -> Result<Self> {
|
||||||
Ok(r.read_i64::<BigEndian>()?)
|
Ok(r.read_i64::<BigEndian>()?)
|
||||||
|
@ -165,12 +171,6 @@ impl Decode<'_> for i128 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encode for i64 {
|
|
||||||
fn encode(&self, mut w: impl Write) -> Result<()> {
|
|
||||||
Ok(w.write_i64::<BigEndian>(*self)?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encode for f32 {
|
impl Encode for f32 {
|
||||||
fn encode(&self, mut w: impl Write) -> Result<()> {
|
fn encode(&self, mut w: impl Write) -> Result<()> {
|
||||||
ensure!(
|
ensure!(
|
||||||
|
|
|
@ -90,11 +90,11 @@ pub use var_long::VarLong;
|
||||||
pub use {uuid, valence_nbt as nbt};
|
pub use {uuid, valence_nbt as nbt};
|
||||||
|
|
||||||
/// The Minecraft protocol version this library currently targets.
|
/// The Minecraft protocol version this library currently targets.
|
||||||
pub const PROTOCOL_VERSION: i32 = 760;
|
pub const PROTOCOL_VERSION: i32 = 761;
|
||||||
|
|
||||||
/// The stringified name of the Minecraft version this library currently
|
/// The stringified name of the Minecraft version this library currently
|
||||||
/// targets.
|
/// targets.
|
||||||
pub const MINECRAFT_VERSION: &str = "1.19.2";
|
pub const MINECRAFT_VERSION: &str = "1.19.3";
|
||||||
|
|
||||||
mod array;
|
mod array;
|
||||||
pub mod block;
|
pub mod block;
|
||||||
|
@ -109,6 +109,7 @@ mod impls;
|
||||||
mod inventory;
|
mod inventory;
|
||||||
mod item;
|
mod item;
|
||||||
pub mod packets;
|
pub mod packets;
|
||||||
|
pub mod player_list;
|
||||||
mod raw_bytes;
|
mod raw_bytes;
|
||||||
pub mod text;
|
pub mod text;
|
||||||
pub mod translation_key;
|
pub mod translation_key;
|
||||||
|
|
|
@ -62,7 +62,7 @@ macro_rules! packet_enum {
|
||||||
<$packet as crate::DecodePacket>::PACKET_ID =>
|
<$packet as crate::DecodePacket>::PACKET_ID =>
|
||||||
Self::$packet($packet::decode(r)?),
|
Self::$packet($packet::decode(r)?),
|
||||||
)*
|
)*
|
||||||
id => anyhow::bail!("unknown packet id {}", id),
|
id => anyhow::bail!("unknown packet ID {:#02x} while decoding {}", id, stringify!($enum_name)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ macro_rules! packet_enum {
|
||||||
<$packet as crate::DecodePacket>::PACKET_ID =>
|
<$packet as crate::DecodePacket>::PACKET_ID =>
|
||||||
Self::$packet($packet::decode(r)?),
|
Self::$packet($packet::decode(r)?),
|
||||||
)*
|
)*
|
||||||
id => anyhow::bail!("unknown packet id {}", id),
|
id => anyhow::bail!("unknown packet ID {:#02x} while decoding {}", id, stringify!($enum_name)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,9 @@ use crate::raw_bytes::RawBytes;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
Action, ChatMode, ClickContainerMode, CommandArgumentSignature, CommandBlockFlags,
|
Action, ChatMode, ClickContainerMode, CommandArgumentSignature, CommandBlockFlags,
|
||||||
CommandBlockMode, Difficulty, DiggingStatus, DisplayedSkinParts, EntityInteraction, Hand,
|
CommandBlockMode, Difficulty, DiggingStatus, DisplayedSkinParts, EntityInteraction, Hand,
|
||||||
HandshakeNextState, MainHand, MessageAcknowledgment, MsgSigOrVerifyToken, PlayerInputFlags,
|
HandshakeNextState, MainHand, MessageAcknowledgment, PlayerInputFlags, RecipeBookId,
|
||||||
PublicKeyData, RecipeBookId, StructureBlockAction, StructureBlockFlags, StructureBlockMirror,
|
StructureBlockAction, StructureBlockFlags, StructureBlockMirror, StructureBlockMode,
|
||||||
StructureBlockMode, StructureBlockRotation,
|
StructureBlockRotation,
|
||||||
};
|
};
|
||||||
use crate::username::Username;
|
use crate::username::Username;
|
||||||
use crate::var_int::VarInt;
|
use crate::var_int::VarInt;
|
||||||
|
@ -75,7 +75,6 @@ pub mod login {
|
||||||
#[packet_id = 0x00]
|
#[packet_id = 0x00]
|
||||||
pub struct LoginStart<'a> {
|
pub struct LoginStart<'a> {
|
||||||
pub username: Username<&'a str>,
|
pub username: Username<&'a str>,
|
||||||
pub sig_data: Option<PublicKeyData<'a>>,
|
|
||||||
pub profile_id: Option<Uuid>,
|
pub profile_id: Option<Uuid>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +82,7 @@ pub mod login {
|
||||||
#[packet_id = 0x01]
|
#[packet_id = 0x01]
|
||||||
pub struct EncryptionResponse<'a> {
|
pub struct EncryptionResponse<'a> {
|
||||||
pub shared_secret: &'a [u8],
|
pub shared_secret: &'a [u8],
|
||||||
pub sig_or_token: MsgSigOrVerifyToken<'a>,
|
pub verify_token: &'a [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
|
@ -151,19 +150,13 @@ pub mod play {
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x06]
|
#[packet_id = 0x06]
|
||||||
pub struct ChatPreviewC2s {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
|
||||||
#[packet_id = 0x07]
|
|
||||||
pub enum ClientCommand {
|
pub enum ClientCommand {
|
||||||
PerformRespawn,
|
PerformRespawn,
|
||||||
RequestStats,
|
RequestStats,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x08]
|
#[packet_id = 0x07]
|
||||||
pub struct ClientInformation<'a> {
|
pub struct ClientInformation<'a> {
|
||||||
pub locale: &'a str,
|
pub locale: &'a str,
|
||||||
pub view_distance: u8,
|
pub view_distance: u8,
|
||||||
|
@ -176,21 +169,21 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x09]
|
#[packet_id = 0x08]
|
||||||
pub struct CommandSuggestionsRequest<'a> {
|
pub struct CommandSuggestionsRequest<'a> {
|
||||||
pub transaction_id: VarInt,
|
pub transaction_id: VarInt,
|
||||||
pub text: &'a str,
|
pub text: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x0a]
|
#[packet_id = 0x09]
|
||||||
pub struct ClickContainerButton {
|
pub struct ClickContainerButton {
|
||||||
pub window_id: i8,
|
pub window_id: i8,
|
||||||
pub button_id: i8,
|
pub button_id: i8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x0b]
|
#[packet_id = 0x0a]
|
||||||
pub struct ClickContainer {
|
pub struct ClickContainer {
|
||||||
pub window_id: u8,
|
pub window_id: u8,
|
||||||
pub state_id: VarInt,
|
pub state_id: VarInt,
|
||||||
|
@ -202,20 +195,20 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x0c]
|
#[packet_id = 0x0b]
|
||||||
pub struct CloseContainerC2s {
|
pub struct CloseContainerC2s {
|
||||||
pub window_id: i8,
|
pub window_id: i8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x0d]
|
#[packet_id = 0x0c]
|
||||||
pub struct PluginMessageC2s<'a> {
|
pub struct PluginMessageC2s<'a> {
|
||||||
pub channel: Ident<&'a str>,
|
pub channel: Ident<&'a str>,
|
||||||
pub data: RawBytes<'a>,
|
pub data: RawBytes<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x0e]
|
#[packet_id = 0x0d]
|
||||||
pub struct EditBook<'a> {
|
pub struct EditBook<'a> {
|
||||||
pub slot: VarInt,
|
pub slot: VarInt,
|
||||||
pub entries: Vec<&'a str>,
|
pub entries: Vec<&'a str>,
|
||||||
|
@ -223,14 +216,14 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x0f]
|
#[packet_id = 0x0e]
|
||||||
pub struct QueryEntityTag {
|
pub struct QueryEntityTag {
|
||||||
pub transaction_id: VarInt,
|
pub transaction_id: VarInt,
|
||||||
pub entity_id: VarInt,
|
pub entity_id: VarInt,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x10]
|
#[packet_id = 0x0f]
|
||||||
pub struct Interact {
|
pub struct Interact {
|
||||||
pub entity_id: VarInt,
|
pub entity_id: VarInt,
|
||||||
pub interact: EntityInteraction,
|
pub interact: EntityInteraction,
|
||||||
|
@ -238,7 +231,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x11]
|
#[packet_id = 0x10]
|
||||||
pub struct JigsawGenerate {
|
pub struct JigsawGenerate {
|
||||||
pub position: BlockPos,
|
pub position: BlockPos,
|
||||||
pub levels: VarInt,
|
pub levels: VarInt,
|
||||||
|
@ -246,24 +239,24 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x12]
|
#[packet_id = 0x11]
|
||||||
pub struct KeepAliveC2s {
|
pub struct KeepAliveC2s {
|
||||||
pub id: u64,
|
pub id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x13]
|
#[packet_id = 0x12]
|
||||||
pub struct LockDifficulty(pub bool);
|
pub struct LockDifficulty(pub bool);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x14]
|
#[packet_id = 0x13]
|
||||||
pub struct SetPlayerPosition {
|
pub struct SetPlayerPosition {
|
||||||
pub position: [f64; 3],
|
pub position: [f64; 3],
|
||||||
pub on_ground: bool,
|
pub on_ground: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x15]
|
#[packet_id = 0x14]
|
||||||
pub struct SetPlayerPositionAndRotation {
|
pub struct SetPlayerPositionAndRotation {
|
||||||
pub position: [f64; 3],
|
pub position: [f64; 3],
|
||||||
pub yaw: f32,
|
pub yaw: f32,
|
||||||
|
@ -272,7 +265,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x16]
|
#[packet_id = 0x15]
|
||||||
pub struct SetPlayerRotation {
|
pub struct SetPlayerRotation {
|
||||||
pub yaw: f32,
|
pub yaw: f32,
|
||||||
pub pitch: f32,
|
pub pitch: f32,
|
||||||
|
@ -280,11 +273,11 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x17]
|
#[packet_id = 0x16]
|
||||||
pub struct SetPlayerOnGround(pub bool);
|
pub struct SetPlayerOnGround(pub bool);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x18]
|
#[packet_id = 0x17]
|
||||||
pub struct MoveVehicleC2s {
|
pub struct MoveVehicleC2s {
|
||||||
pub position: [f64; 3],
|
pub position: [f64; 3],
|
||||||
pub yaw: f32,
|
pub yaw: f32,
|
||||||
|
@ -292,20 +285,20 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x19]
|
#[packet_id = 0x18]
|
||||||
pub struct PaddleBoat {
|
pub struct PaddleBoat {
|
||||||
pub left_paddle_turning: bool,
|
pub left_paddle_turning: bool,
|
||||||
pub right_paddle_turning: bool,
|
pub right_paddle_turning: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x1a]
|
#[packet_id = 0x19]
|
||||||
pub struct PickItem {
|
pub struct PickItem {
|
||||||
pub slot_to_use: VarInt,
|
pub slot_to_use: VarInt,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x1b]
|
#[packet_id = 0x1a]
|
||||||
pub struct PlaceRecipe<'a> {
|
pub struct PlaceRecipe<'a> {
|
||||||
pub window_id: i8,
|
pub window_id: i8,
|
||||||
pub recipe: Ident<&'a str>,
|
pub recipe: Ident<&'a str>,
|
||||||
|
@ -313,7 +306,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x1c]
|
#[packet_id = 0x1b]
|
||||||
pub enum PlayerAbilitiesC2s {
|
pub enum PlayerAbilitiesC2s {
|
||||||
#[tag = 0b00]
|
#[tag = 0b00]
|
||||||
StopFlying,
|
StopFlying,
|
||||||
|
@ -322,7 +315,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x1d]
|
#[packet_id = 0x1c]
|
||||||
pub struct PlayerAction {
|
pub struct PlayerAction {
|
||||||
pub status: DiggingStatus,
|
pub status: DiggingStatus,
|
||||||
pub position: BlockPos,
|
pub position: BlockPos,
|
||||||
|
@ -331,7 +324,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x1e]
|
#[packet_id = 0x1d]
|
||||||
pub struct PlayerCommand {
|
pub struct PlayerCommand {
|
||||||
pub entity_id: VarInt,
|
pub entity_id: VarInt,
|
||||||
pub action_id: Action,
|
pub action_id: Action,
|
||||||
|
@ -339,7 +332,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x1f]
|
#[packet_id = 0x1e]
|
||||||
pub struct PlayerInput {
|
pub struct PlayerInput {
|
||||||
pub sideways: f32,
|
pub sideways: f32,
|
||||||
pub forward: f32,
|
pub forward: f32,
|
||||||
|
@ -347,11 +340,21 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x20]
|
#[packet_id = 0x1f]
|
||||||
pub struct PongPlay {
|
pub struct PongPlay {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
|
#[packet_id = 0x20]
|
||||||
|
pub struct PlayerSession<'a> {
|
||||||
|
pub session_id: Uuid,
|
||||||
|
// Public key
|
||||||
|
pub expires_at: i64,
|
||||||
|
pub public_key_data: &'a [u8],
|
||||||
|
pub key_signature: &'a [u8],
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x21]
|
#[packet_id = 0x21]
|
||||||
pub struct ChangeRecipeBookSettings {
|
pub struct ChangeRecipeBookSettings {
|
||||||
|
@ -503,7 +506,6 @@ pub mod play {
|
||||||
MessageAcknowledgmentC2s<'a>,
|
MessageAcknowledgmentC2s<'a>,
|
||||||
ChatCommand<'a>,
|
ChatCommand<'a>,
|
||||||
ChatMessage<'a>,
|
ChatMessage<'a>,
|
||||||
ChatPreviewC2s,
|
|
||||||
ClientCommand,
|
ClientCommand,
|
||||||
ClientInformation<'a>,
|
ClientInformation<'a>,
|
||||||
CommandSuggestionsRequest<'a>,
|
CommandSuggestionsRequest<'a>,
|
||||||
|
@ -530,6 +532,7 @@ pub mod play {
|
||||||
PlayerCommand,
|
PlayerCommand,
|
||||||
PlayerInput,
|
PlayerInput,
|
||||||
PongPlay,
|
PongPlay,
|
||||||
|
PlayerSession<'a>,
|
||||||
ChangeRecipeBookSettings,
|
ChangeRecipeBookSettings,
|
||||||
SetSeenRecipe<'a>,
|
SetSeenRecipe<'a>,
|
||||||
RenameItem<'a>,
|
RenameItem<'a>,
|
||||||
|
|
|
@ -9,8 +9,8 @@ use crate::item::ItemStack;
|
||||||
use crate::raw_bytes::RawBytes;
|
use crate::raw_bytes::RawBytes;
|
||||||
use crate::text::Text;
|
use crate::text::Text;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
AttributeProperty, BossBarAction, ChunkDataBlockEntity, DeathLocation, Difficulty, GameMode,
|
AttributeProperty, BossBarAction, ChunkDataBlockEntity, Difficulty, GameMode,
|
||||||
GameStateChangeReason, PlayerInfoAddPlayer, SignedProperty, SoundCategory,
|
GameStateChangeReason, GlobalPos, PlayerAbilitiesFlags, SignedProperty, SoundCategory,
|
||||||
SyncPlayerPosLookFlags,
|
SyncPlayerPosLookFlags,
|
||||||
};
|
};
|
||||||
use crate::username::Username;
|
use crate::username::Username;
|
||||||
|
@ -95,6 +95,7 @@ pub mod login {
|
||||||
|
|
||||||
pub mod play {
|
pub mod play {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
pub use crate::player_list::PlayerInfoUpdate;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x00]
|
#[packet_id = 0x00]
|
||||||
|
@ -181,20 +182,20 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x0d]
|
#[packet_id = 0x0c]
|
||||||
pub struct ClearTitles {
|
pub struct ClearTitles {
|
||||||
pub reset: bool,
|
pub reset: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x10]
|
#[packet_id = 0x0f]
|
||||||
pub struct CloseContainerS2c {
|
pub struct CloseContainerS2c {
|
||||||
/// Ignored by notchian clients.
|
/// Ignored by notchian clients.
|
||||||
pub window_id: u8,
|
pub window_id: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x11]
|
#[packet_id = 0x10]
|
||||||
pub struct SetContainerContent {
|
pub struct SetContainerContent {
|
||||||
pub window_id: u8,
|
pub window_id: u8,
|
||||||
pub state_id: VarInt,
|
pub state_id: VarInt,
|
||||||
|
@ -203,7 +204,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket)]
|
||||||
#[packet_id = 0x11]
|
#[packet_id = 0x10]
|
||||||
pub struct SetContainerContentEncode<'a> {
|
pub struct SetContainerContentEncode<'a> {
|
||||||
pub window_id: u8,
|
pub window_id: u8,
|
||||||
pub state_id: VarInt,
|
pub state_id: VarInt,
|
||||||
|
@ -212,7 +213,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x12]
|
#[packet_id = 0x11]
|
||||||
pub struct SetContainerProperty {
|
pub struct SetContainerProperty {
|
||||||
pub window_id: u8,
|
pub window_id: u8,
|
||||||
pub property: i16,
|
pub property: i16,
|
||||||
|
@ -220,7 +221,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x13]
|
#[packet_id = 0x12]
|
||||||
pub struct SetContainerSlot {
|
pub struct SetContainerSlot {
|
||||||
pub window_id: i8,
|
pub window_id: i8,
|
||||||
pub state_id: VarInt,
|
pub state_id: VarInt,
|
||||||
|
@ -229,7 +230,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket)]
|
||||||
#[packet_id = 0x13]
|
#[packet_id = 0x12]
|
||||||
pub struct SetContainerSlotEncode<'a> {
|
pub struct SetContainerSlotEncode<'a> {
|
||||||
pub window_id: i8,
|
pub window_id: i8,
|
||||||
pub state_id: VarInt,
|
pub state_id: VarInt,
|
||||||
|
@ -238,59 +239,48 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x14]
|
#[packet_id = 0x13]
|
||||||
pub struct SetCooldown {
|
pub struct SetCooldown {
|
||||||
pub item_id: VarInt,
|
pub item_id: VarInt,
|
||||||
pub cooldown_ticks: VarInt,
|
pub cooldown_ticks: VarInt,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x16]
|
#[packet_id = 0x15]
|
||||||
pub struct PluginMessageS2c<'a> {
|
pub struct PluginMessageS2c<'a> {
|
||||||
pub channel: Ident<&'a str>,
|
pub channel: Ident<&'a str>,
|
||||||
pub data: RawBytes<'a>,
|
pub data: RawBytes<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
|
||||||
#[packet_id = 0x17]
|
|
||||||
pub struct CustomSoundEffect<'a> {
|
|
||||||
pub name: Ident<&'a str>,
|
|
||||||
pub category: SoundCategory,
|
|
||||||
pub position: [i32; 3],
|
|
||||||
pub volume: f32,
|
|
||||||
pub pitch: f32,
|
|
||||||
pub seed: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x19]
|
#[packet_id = 0x17]
|
||||||
pub struct DisconnectPlay {
|
pub struct DisconnectPlay {
|
||||||
pub reason: Text,
|
pub reason: Text,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x1a]
|
#[packet_id = 0x19]
|
||||||
pub struct EntityEvent {
|
pub struct EntityEvent {
|
||||||
pub entity_id: i32,
|
pub entity_id: i32,
|
||||||
pub entity_status: u8,
|
pub entity_status: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x1c]
|
#[packet_id = 0x1b]
|
||||||
pub struct UnloadChunk {
|
pub struct UnloadChunk {
|
||||||
pub chunk_x: i32,
|
pub chunk_x: i32,
|
||||||
pub chunk_z: i32,
|
pub chunk_z: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x1d]
|
#[packet_id = 0x1c]
|
||||||
pub struct GameEvent {
|
pub struct GameEvent {
|
||||||
pub reason: GameStateChangeReason,
|
pub reason: GameStateChangeReason,
|
||||||
pub value: f32,
|
pub value: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x1f]
|
#[packet_id = 0x1e]
|
||||||
pub struct WorldBorderInitialize {
|
pub struct WorldBorderInitialize {
|
||||||
pub x: f64,
|
pub x: f64,
|
||||||
pub z: f64,
|
pub z: f64,
|
||||||
|
@ -303,13 +293,13 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x20]
|
#[packet_id = 0x1f]
|
||||||
pub struct KeepAliveS2c {
|
pub struct KeepAliveS2c {
|
||||||
pub id: u64,
|
pub id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x21]
|
#[packet_id = 0x20]
|
||||||
pub struct ChunkDataAndUpdateLight<'a> {
|
pub struct ChunkDataAndUpdateLight<'a> {
|
||||||
pub chunk_x: i32,
|
pub chunk_x: i32,
|
||||||
pub chunk_z: i32,
|
pub chunk_z: i32,
|
||||||
|
@ -326,7 +316,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket)]
|
||||||
#[packet_id = 0x21]
|
#[packet_id = 0x20]
|
||||||
pub struct ChunkDataAndUpdateLightEncode<'a> {
|
pub struct ChunkDataAndUpdateLightEncode<'a> {
|
||||||
pub chunk_x: i32,
|
pub chunk_x: i32,
|
||||||
pub chunk_z: i32,
|
pub chunk_z: i32,
|
||||||
|
@ -343,7 +333,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x23]
|
#[packet_id = 0x22]
|
||||||
pub struct ParticleS2c<'a> {
|
pub struct ParticleS2c<'a> {
|
||||||
pub particle_id: VarInt,
|
pub particle_id: VarInt,
|
||||||
pub long_distance: bool,
|
pub long_distance: bool,
|
||||||
|
@ -355,7 +345,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x25]
|
#[packet_id = 0x24]
|
||||||
pub struct LoginPlay<'a> {
|
pub struct LoginPlay<'a> {
|
||||||
pub entity_id: i32,
|
pub entity_id: i32,
|
||||||
pub is_hardcore: bool,
|
pub is_hardcore: bool,
|
||||||
|
@ -374,12 +364,12 @@ pub mod play {
|
||||||
pub enable_respawn_screen: bool,
|
pub enable_respawn_screen: bool,
|
||||||
pub is_debug: bool,
|
pub is_debug: bool,
|
||||||
pub is_flat: bool,
|
pub is_flat: bool,
|
||||||
pub last_death_location: Option<DeathLocation<'a>>,
|
pub last_death_location: Option<GlobalPos<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove this.
|
// TODO: remove this.
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x25]
|
#[packet_id = 0x24]
|
||||||
pub struct LoginPlayOwned {
|
pub struct LoginPlayOwned {
|
||||||
pub entity_id: i32,
|
pub entity_id: i32,
|
||||||
pub is_hardcore: bool,
|
pub is_hardcore: bool,
|
||||||
|
@ -401,7 +391,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x28]
|
#[packet_id = 0x27]
|
||||||
pub struct UpdateEntityPosition {
|
pub struct UpdateEntityPosition {
|
||||||
pub entity_id: VarInt,
|
pub entity_id: VarInt,
|
||||||
pub delta: [i16; 3],
|
pub delta: [i16; 3],
|
||||||
|
@ -409,7 +399,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x29]
|
#[packet_id = 0x28]
|
||||||
pub struct UpdateEntityPositionAndRotation {
|
pub struct UpdateEntityPositionAndRotation {
|
||||||
pub entity_id: VarInt,
|
pub entity_id: VarInt,
|
||||||
pub delta: [i16; 3],
|
pub delta: [i16; 3],
|
||||||
|
@ -419,7 +409,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x2a]
|
#[packet_id = 0x29]
|
||||||
pub struct UpdateEntityRotation {
|
pub struct UpdateEntityRotation {
|
||||||
pub entity_id: VarInt,
|
pub entity_id: VarInt,
|
||||||
pub yaw: ByteAngle,
|
pub yaw: ByteAngle,
|
||||||
|
@ -428,7 +418,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x2d]
|
#[packet_id = 0x2c]
|
||||||
pub struct OpenScreen {
|
pub struct OpenScreen {
|
||||||
pub window_id: VarInt,
|
pub window_id: VarInt,
|
||||||
pub window_type: VarInt,
|
pub window_type: VarInt,
|
||||||
|
@ -436,14 +426,22 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x33]
|
#[packet_id = 0x30]
|
||||||
|
pub struct PlayerAbilitiesS2c {
|
||||||
|
pub flags: PlayerAbilitiesFlags,
|
||||||
|
pub flying_speed: f32,
|
||||||
|
pub fov_modifier: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
|
#[packet_id = 0x31]
|
||||||
pub struct PlayerChatMessage<'a> {
|
pub struct PlayerChatMessage<'a> {
|
||||||
// TODO: A _lot_ of fields
|
// TODO: A bunch of crap.
|
||||||
pub data: RawBytes<'a>,
|
pub data: RawBytes<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x36]
|
#[packet_id = 0x34]
|
||||||
pub struct CombatDeath {
|
pub struct CombatDeath {
|
||||||
pub player_id: VarInt,
|
pub player_id: VarInt,
|
||||||
/// Killer's entity ID, -1 if no killer
|
/// Killer's entity ID, -1 if no killer
|
||||||
|
@ -452,17 +450,11 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x37]
|
#[packet_id = 0x35]
|
||||||
pub enum PlayerInfo<'a> {
|
pub struct PlayerInfoRemove(pub Vec<Uuid>);
|
||||||
AddPlayer(Vec<PlayerInfoAddPlayer<'a>>),
|
|
||||||
UpdateGameMode(Vec<(Uuid, GameMode)>),
|
|
||||||
UpdateLatency(Vec<(Uuid, VarInt)>),
|
|
||||||
UpdateDisplayName(Vec<(Uuid, Option<Text>)>),
|
|
||||||
RemovePlayer(Vec<Uuid>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x39]
|
#[packet_id = 0x38]
|
||||||
pub struct SynchronizePlayerPosition {
|
pub struct SynchronizePlayerPosition {
|
||||||
pub position: [f64; 3],
|
pub position: [f64; 3],
|
||||||
pub yaw: f32,
|
pub yaw: f32,
|
||||||
|
@ -473,19 +465,19 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x3b]
|
#[packet_id = 0x3a]
|
||||||
pub struct RemoveEntities {
|
pub struct RemoveEntities {
|
||||||
pub entity_ids: Vec<VarInt>,
|
pub entity_ids: Vec<VarInt>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Debug, Encode, EncodePacket)]
|
#[derive(Copy, Clone, PartialEq, Debug, Encode, EncodePacket)]
|
||||||
#[packet_id = 0x3b]
|
#[packet_id = 0x3a]
|
||||||
pub struct RemoveEntitiesEncode<'a> {
|
pub struct RemoveEntitiesEncode<'a> {
|
||||||
pub entity_ids: &'a [VarInt],
|
pub entity_ids: &'a [VarInt],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x3d]
|
#[packet_id = 0x3c]
|
||||||
pub struct ResourcePackS2c<'a> {
|
pub struct ResourcePackS2c<'a> {
|
||||||
pub url: &'a str,
|
pub url: &'a str,
|
||||||
pub hash: &'a str,
|
pub hash: &'a str,
|
||||||
|
@ -494,7 +486,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x3e]
|
#[packet_id = 0x3d]
|
||||||
pub struct Respawn<'a> {
|
pub struct Respawn<'a> {
|
||||||
pub dimension_type_name: Ident<&'a str>,
|
pub dimension_type_name: Ident<&'a str>,
|
||||||
pub dimension_name: Ident<&'a str>,
|
pub dimension_name: Ident<&'a str>,
|
||||||
|
@ -504,12 +496,12 @@ pub mod play {
|
||||||
pub is_debug: bool,
|
pub is_debug: bool,
|
||||||
pub is_flat: bool,
|
pub is_flat: bool,
|
||||||
pub copy_metadata: bool,
|
pub copy_metadata: bool,
|
||||||
pub last_death_location: Option<DeathLocation<'a>>,
|
pub last_death_location: Option<GlobalPos<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove
|
// TODO: remove
|
||||||
#[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x3e]
|
#[packet_id = 0x3d]
|
||||||
pub struct RespawnOwned {
|
pub struct RespawnOwned {
|
||||||
pub dimension_type_name: Ident<String>,
|
pub dimension_type_name: Ident<String>,
|
||||||
pub dimension_name: Ident<String>,
|
pub dimension_name: Ident<String>,
|
||||||
|
@ -523,14 +515,14 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x3f]
|
#[packet_id = 0x3e]
|
||||||
pub struct SetHeadRotation {
|
pub struct SetHeadRotation {
|
||||||
pub entity_id: VarInt,
|
pub entity_id: VarInt,
|
||||||
pub head_yaw: ByteAngle,
|
pub head_yaw: ByteAngle,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x40]
|
#[packet_id = 0x3f]
|
||||||
pub struct UpdateSectionBlocks {
|
pub struct UpdateSectionBlocks {
|
||||||
pub chunk_section_position: i64,
|
pub chunk_section_position: i64,
|
||||||
pub invert_trust_edges: bool,
|
pub invert_trust_edges: bool,
|
||||||
|
@ -538,7 +530,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket)]
|
||||||
#[packet_id = 0x40]
|
#[packet_id = 0x3f]
|
||||||
pub struct UpdateSectionBlocksEncode<'a> {
|
pub struct UpdateSectionBlocksEncode<'a> {
|
||||||
pub chunk_section_position: i64,
|
pub chunk_section_position: i64,
|
||||||
pub invert_trust_edges: bool,
|
pub invert_trust_edges: bool,
|
||||||
|
@ -546,49 +538,49 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x43]
|
#[packet_id = 0x42]
|
||||||
pub struct SetActionBarText(pub Text);
|
pub struct SetActionBarText(pub Text);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x4a]
|
#[packet_id = 0x49]
|
||||||
pub struct SetHeldItemS2c {
|
pub struct SetHeldItemS2c {
|
||||||
pub slot: u8,
|
pub slot: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x4b]
|
#[packet_id = 0x4a]
|
||||||
pub struct SetCenterChunk {
|
pub struct SetCenterChunk {
|
||||||
pub chunk_x: VarInt,
|
pub chunk_x: VarInt,
|
||||||
pub chunk_z: VarInt,
|
pub chunk_z: VarInt,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x4c]
|
#[packet_id = 0x4b]
|
||||||
pub struct SetRenderDistance(pub VarInt);
|
pub struct SetRenderDistance(pub VarInt);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x4d]
|
#[packet_id = 0x4c]
|
||||||
pub struct SetDefaultSpawnPosition {
|
pub struct SetDefaultSpawnPosition {
|
||||||
pub position: BlockPos,
|
pub position: BlockPos,
|
||||||
pub angle: f32,
|
pub angle: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x50]
|
#[packet_id = 0x4e]
|
||||||
pub struct SetEntityMetadata<'a> {
|
pub struct SetEntityMetadata<'a> {
|
||||||
pub entity_id: VarInt,
|
pub entity_id: VarInt,
|
||||||
pub metadata: RawBytes<'a>,
|
pub metadata: RawBytes<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x52]
|
#[packet_id = 0x50]
|
||||||
pub struct SetEntityVelocity {
|
pub struct SetEntityVelocity {
|
||||||
pub entity_id: VarInt,
|
pub entity_id: VarInt,
|
||||||
pub velocity: [i16; 3],
|
pub velocity: [i16; 3],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x54]
|
#[packet_id = 0x52]
|
||||||
pub struct SetExperience {
|
pub struct SetExperience {
|
||||||
pub bar: f32,
|
pub bar: f32,
|
||||||
pub level: VarInt,
|
pub level: VarInt,
|
||||||
|
@ -596,7 +588,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x55]
|
#[packet_id = 0x53]
|
||||||
pub struct SetHealth {
|
pub struct SetHealth {
|
||||||
pub health: f32,
|
pub health: f32,
|
||||||
pub food: VarInt,
|
pub food: VarInt,
|
||||||
|
@ -604,11 +596,11 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x5b]
|
#[packet_id = 0x59]
|
||||||
pub struct SetSubtitleText(pub Text);
|
pub struct SetSubtitleText(pub Text);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x5c]
|
#[packet_id = 0x5a]
|
||||||
pub struct UpdateTime {
|
pub struct UpdateTime {
|
||||||
/// The age of the world in 1/20ths of a second.
|
/// The age of the world in 1/20ths of a second.
|
||||||
pub world_age: i64,
|
pub world_age: i64,
|
||||||
|
@ -619,11 +611,11 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x5d]
|
#[packet_id = 0x5b]
|
||||||
pub struct SetTitleText(pub Text);
|
pub struct SetTitleText(pub Text);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x5e]
|
#[packet_id = 0x5c]
|
||||||
pub struct SetTitleAnimationTimes {
|
pub struct SetTitleAnimationTimes {
|
||||||
/// Ticks to spend fading in.
|
/// Ticks to spend fading in.
|
||||||
pub fade_in: i32,
|
pub fade_in: i32,
|
||||||
|
@ -634,7 +626,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x5f]
|
#[packet_id = 0x5d]
|
||||||
pub struct EntitySoundEffect {
|
pub struct EntitySoundEffect {
|
||||||
pub id: VarInt,
|
pub id: VarInt,
|
||||||
pub category: SoundCategory,
|
pub category: SoundCategory,
|
||||||
|
@ -644,7 +636,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x60]
|
#[packet_id = 0x5e]
|
||||||
pub struct SoundEffect {
|
pub struct SoundEffect {
|
||||||
pub id: VarInt,
|
pub id: VarInt,
|
||||||
pub category: SoundCategory,
|
pub category: SoundCategory,
|
||||||
|
@ -655,7 +647,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x62]
|
#[packet_id = 0x60]
|
||||||
pub struct SystemChatMessage {
|
pub struct SystemChatMessage {
|
||||||
pub chat: Text,
|
pub chat: Text,
|
||||||
/// Index into the chat type registry.
|
/// Index into the chat type registry.
|
||||||
|
@ -663,14 +655,14 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x63]
|
#[packet_id = 0x61]
|
||||||
pub struct SetTabListHeaderAndFooter {
|
pub struct SetTabListHeaderAndFooter {
|
||||||
pub header: Text,
|
pub header: Text,
|
||||||
pub footer: Text,
|
pub footer: Text,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x66]
|
#[packet_id = 0x64]
|
||||||
pub struct TeleportEntity {
|
pub struct TeleportEntity {
|
||||||
pub entity_id: VarInt,
|
pub entity_id: VarInt,
|
||||||
pub position: [f64; 3],
|
pub position: [f64; 3],
|
||||||
|
@ -680,12 +672,18 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
#[packet_id = 0x68]
|
#[packet_id = 0x66]
|
||||||
pub struct UpdateAttributes<'a> {
|
pub struct UpdateAttributes<'a> {
|
||||||
pub entity_id: VarInt,
|
pub entity_id: VarInt,
|
||||||
pub properties: Vec<AttributeProperty<'a>>,
|
pub properties: Vec<AttributeProperty<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
|
||||||
|
#[packet_id = 0x67]
|
||||||
|
pub struct FeatureFlags<'a> {
|
||||||
|
pub features: Vec<Ident<&'a str>>,
|
||||||
|
}
|
||||||
|
|
||||||
packet_enum! {
|
packet_enum! {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
S2cPlayPacket<'a> {
|
S2cPlayPacket<'a> {
|
||||||
|
@ -706,7 +704,6 @@ pub mod play {
|
||||||
SetContainerSlot,
|
SetContainerSlot,
|
||||||
SetCooldown,
|
SetCooldown,
|
||||||
PluginMessageS2c<'a>,
|
PluginMessageS2c<'a>,
|
||||||
CustomSoundEffect<'a>,
|
|
||||||
DisconnectPlay,
|
DisconnectPlay,
|
||||||
EntityEvent,
|
EntityEvent,
|
||||||
UnloadChunk,
|
UnloadChunk,
|
||||||
|
@ -720,9 +717,11 @@ pub mod play {
|
||||||
UpdateEntityPositionAndRotation,
|
UpdateEntityPositionAndRotation,
|
||||||
UpdateEntityRotation,
|
UpdateEntityRotation,
|
||||||
OpenScreen,
|
OpenScreen,
|
||||||
|
PlayerAbilitiesS2c,
|
||||||
PlayerChatMessage<'a>,
|
PlayerChatMessage<'a>,
|
||||||
CombatDeath,
|
CombatDeath,
|
||||||
PlayerInfo<'a>,
|
PlayerInfoRemove,
|
||||||
|
PlayerInfoUpdate<'a>,
|
||||||
SynchronizePlayerPosition,
|
SynchronizePlayerPosition,
|
||||||
RemoveEntities,
|
RemoveEntities,
|
||||||
ResourcePackS2c<'a>,
|
ResourcePackS2c<'a>,
|
||||||
|
@ -748,6 +747,7 @@ pub mod play {
|
||||||
SetTabListHeaderAndFooter,
|
SetTabListHeaderAndFooter,
|
||||||
TeleportEntity,
|
TeleportEntity,
|
||||||
UpdateAttributes<'a>,
|
UpdateAttributes<'a>,
|
||||||
|
FeatureFlags<'a>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
126
valence_protocol/src/player_list.rs
Normal file
126
valence_protocol/src/player_list.rs
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
use bitfield_struct::bitfield;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use crate::types::{GameMode, SignedProperty};
|
||||||
|
use crate::{Decode, DecodePacket, Encode, EncodePacket, Text, VarInt};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, EncodePacket, DecodePacket)]
|
||||||
|
#[packet_id = 0x36]
|
||||||
|
pub struct PlayerInfoUpdate<'a> {
|
||||||
|
pub actions: Actions,
|
||||||
|
pub entries: Vec<Entry<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bitfield(u8)]
|
||||||
|
pub struct Actions {
|
||||||
|
pub add_player: bool,
|
||||||
|
pub initialize_chat: bool,
|
||||||
|
pub update_game_mode: bool,
|
||||||
|
pub update_listed: bool,
|
||||||
|
pub update_latency: bool,
|
||||||
|
pub update_display_name: bool,
|
||||||
|
#[bits(2)]
|
||||||
|
_pad: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Default, Debug)]
|
||||||
|
pub struct Entry<'a> {
|
||||||
|
pub player_uuid: Uuid,
|
||||||
|
pub username: &'a str,
|
||||||
|
pub properties: Vec<SignedProperty<'a>>,
|
||||||
|
pub chat_data: Option<ChatData<'a>>,
|
||||||
|
pub listed: bool,
|
||||||
|
pub ping: i32,
|
||||||
|
pub game_mode: GameMode,
|
||||||
|
pub display_name: Option<Text>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Debug, Encode, Decode)]
|
||||||
|
pub struct ChatData<'a> {
|
||||||
|
pub session_id: Uuid,
|
||||||
|
/// Unix timestamp in milliseconds.
|
||||||
|
pub key_expiry_time: i64,
|
||||||
|
pub public_key: &'a [u8],
|
||||||
|
pub public_key_signature: &'a [u8],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Encode for PlayerInfoUpdate<'a> {
|
||||||
|
fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
|
||||||
|
self.actions.0.encode(&mut w)?;
|
||||||
|
|
||||||
|
// Write number of entries.
|
||||||
|
VarInt(self.entries.len() as i32).encode(&mut w)?;
|
||||||
|
|
||||||
|
for entry in &self.entries {
|
||||||
|
entry.player_uuid.encode(&mut w)?;
|
||||||
|
|
||||||
|
if self.actions.add_player() {
|
||||||
|
entry.username.encode(&mut w)?;
|
||||||
|
entry.properties.encode(&mut w)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.actions.initialize_chat() {
|
||||||
|
entry.chat_data.encode(&mut w)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.actions.update_game_mode() {
|
||||||
|
entry.game_mode.encode(&mut w)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.actions.update_listed() {
|
||||||
|
entry.listed.encode(&mut w)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.actions.update_latency() {
|
||||||
|
VarInt(entry.ping).encode(&mut w)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.actions.update_display_name() {
|
||||||
|
entry.display_name.encode(&mut w)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Decode<'a> for PlayerInfoUpdate<'a> {
|
||||||
|
fn decode(r: &mut &'a [u8]) -> anyhow::Result<Self> {
|
||||||
|
let actions = Actions(u8::decode(r)?);
|
||||||
|
|
||||||
|
let mut entries = vec![];
|
||||||
|
|
||||||
|
for _ in 0..VarInt::decode(r)?.0 {
|
||||||
|
let mut entry = Entry {
|
||||||
|
player_uuid: Uuid::decode(r)?,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
if actions.add_player() {
|
||||||
|
entry.username = Decode::decode(r)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if actions.initialize_chat() {
|
||||||
|
entry.chat_data = Decode::decode(r)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if actions.update_game_mode() {
|
||||||
|
entry.game_mode = Decode::decode(r)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if actions.update_latency() {
|
||||||
|
entry.ping = VarInt::decode(r)?.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if actions.update_display_name() {
|
||||||
|
entry.display_name = Decode::decode(r)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
entries.push(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self { actions, entries })
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,12 +22,6 @@ pub struct PublicKeyData<'a> {
|
||||||
pub signature: &'a [u8],
|
pub signature: &'a [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, Decode)]
|
|
||||||
pub enum MsgSigOrVerifyToken<'a> {
|
|
||||||
MsgSig { salt: u64, sig: &'a [u8] },
|
|
||||||
VerifyToken(&'a [u8]),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, Decode)]
|
#[derive(Clone, Debug, Encode, Decode)]
|
||||||
pub struct MessageAcknowledgment<'a> {
|
pub struct MessageAcknowledgment<'a> {
|
||||||
pub last_seen: Vec<MessageAcknowledgmentEntry<'a>>,
|
pub last_seen: Vec<MessageAcknowledgmentEntry<'a>>,
|
||||||
|
@ -271,8 +265,9 @@ pub struct ChunkDataBlockEntity {
|
||||||
pub data: Compound,
|
pub data: Compound,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, Default, Encode, Decode)]
|
||||||
pub enum GameMode {
|
pub enum GameMode {
|
||||||
|
#[default]
|
||||||
Survival,
|
Survival,
|
||||||
Creative,
|
Creative,
|
||||||
Adventure,
|
Adventure,
|
||||||
|
@ -280,7 +275,7 @@ pub enum GameMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)]
|
||||||
pub struct DeathLocation<'a> {
|
pub struct GlobalPos<'a> {
|
||||||
pub dimension_name: Ident<&'a str>,
|
pub dimension_name: Ident<&'a str>,
|
||||||
pub position: BlockPos,
|
pub position: BlockPos,
|
||||||
}
|
}
|
||||||
|
@ -299,17 +294,6 @@ pub struct AttributeModifier {
|
||||||
pub operation: u8,
|
pub operation: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Encode, Decode)]
|
|
||||||
pub struct PlayerInfoAddPlayer<'a> {
|
|
||||||
pub uuid: Uuid,
|
|
||||||
pub username: &'a str,
|
|
||||||
pub properties: Vec<SignedProperty<'a>>,
|
|
||||||
pub game_mode: GameMode,
|
|
||||||
pub ping: VarInt,
|
|
||||||
pub display_name: Option<Text>,
|
|
||||||
pub sig_data: Option<PublicKeyData<'a>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bitfield(u8)]
|
#[bitfield(u8)]
|
||||||
#[derive(PartialEq, Eq, Encode, Decode)]
|
#[derive(PartialEq, Eq, Encode, Decode)]
|
||||||
pub struct DisplayedSkinParts {
|
pub struct DisplayedSkinParts {
|
||||||
|
@ -363,3 +347,14 @@ pub struct SyncPlayerPosLookFlags {
|
||||||
#[bits(3)]
|
#[bits(3)]
|
||||||
_pad: u8,
|
_pad: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[bitfield(u8)]
|
||||||
|
#[derive(PartialEq, Eq, Encode, Decode)]
|
||||||
|
pub struct PlayerAbilitiesFlags {
|
||||||
|
pub invulnerable: bool,
|
||||||
|
pub flying: bool,
|
||||||
|
pub allow_flying: bool,
|
||||||
|
pub instant_break: bool,
|
||||||
|
#[bits(4)]
|
||||||
|
_pad: u8,
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue