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