Finally fix all registries
This commit is contained in:
parent
d444f68093
commit
2fd3585af7
@ -92,11 +92,11 @@ impl<'a> ClientPacket for CKnownPacks<'a> {
|
||||
|
||||
pub struct CRegistryData<'a> {
|
||||
registry_id: &'a str,
|
||||
entries: &'a [Entry<'a>],
|
||||
entries: &'a [RegistryEntry],
|
||||
}
|
||||
|
||||
impl<'a> CRegistryData<'a> {
|
||||
pub fn new(registry_id: &'a str, entries: &'a [Entry]) -> Self {
|
||||
pub fn new(registry_id: &'a str, entries: &'a [RegistryEntry]) -> Self {
|
||||
Self {
|
||||
registry_id,
|
||||
entries,
|
||||
@ -104,10 +104,9 @@ impl<'a> CRegistryData<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Entry<'a> {
|
||||
pub entry_id: &'a str,
|
||||
pub has_data: bool,
|
||||
pub data: &'a [u8],
|
||||
pub struct RegistryEntry {
|
||||
pub entry_id: String,
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl<'a> ClientPacket for CRegistryData<'a> {
|
||||
@ -115,10 +114,10 @@ impl<'a> ClientPacket for CRegistryData<'a> {
|
||||
|
||||
fn write(&self, bytebuf: &mut ByteBuffer) {
|
||||
bytebuf.put_string(self.registry_id);
|
||||
bytebuf.put_list::<Entry>(self.entries, |p, v| {
|
||||
p.put_string(v.entry_id);
|
||||
p.put_bool(v.has_data);
|
||||
p.put_slice(v.data);
|
||||
bytebuf.put_list::<RegistryEntry>(self.entries, |p, v| {
|
||||
p.put_string(&v.entry_id);
|
||||
p.put_bool(!v.data.is_empty());
|
||||
p.put_slice(&v.data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ pub struct CLogin {
|
||||
entity_id: i32,
|
||||
is_hardcore: bool,
|
||||
dimension_count: VarInt,
|
||||
dimension_names: Vec<String>,
|
||||
dimension_names: String,
|
||||
max_players: VarInt,
|
||||
view_distance: VarInt,
|
||||
simulated_distance: VarInt,
|
||||
@ -94,7 +94,7 @@ impl CLogin {
|
||||
entity_id: i32,
|
||||
is_hardcore: bool,
|
||||
dimension_count: VarInt,
|
||||
dimension_names: Vec<String>,
|
||||
dimension_names: String,
|
||||
max_players: VarInt,
|
||||
view_distance: VarInt,
|
||||
simulated_distance: VarInt,
|
||||
@ -148,7 +148,7 @@ impl ClientPacket for CLogin {
|
||||
bytebuf.put_i32(self.entity_id);
|
||||
bytebuf.put_bool(self.is_hardcore);
|
||||
bytebuf.put_var_int(self.dimension_count);
|
||||
bytebuf.put_string_array(self.dimension_names.as_slice());
|
||||
bytebuf.put_string(&self.dimension_names);
|
||||
bytebuf.put_var_int(self.max_players);
|
||||
bytebuf.put_var_int(self.view_distance);
|
||||
bytebuf.put_var_int(self.simulated_distance);
|
||||
|
||||
@ -1,10 +1,26 @@
|
||||
use super::RegistryValue;
|
||||
use pumpkin_protocol::VarInt;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct BiomeCodec {
|
||||
name: String,
|
||||
id: i32,
|
||||
element: Biome,
|
||||
}
|
||||
|
||||
impl Default for BiomeCodec {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "minecraft:plains".to_string(),
|
||||
id: 0,
|
||||
element: Biome::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct Biome {
|
||||
has_precipitation: bool,
|
||||
has_precipitation: i8,
|
||||
temperature: f32,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
temperature_modifier: Option<String>,
|
||||
@ -67,23 +83,24 @@ struct Music {
|
||||
sound: String,
|
||||
min_delay: i32,
|
||||
max_delay: i32,
|
||||
replace_current_music: bool,
|
||||
replace_current_music: i8,
|
||||
}
|
||||
|
||||
// 1.20.6 default https://gist.github.com/WinX64/ab8c7a8df797c273b32d3a3b66522906
|
||||
pub(super) fn all() -> Vec<RegistryValue<Biome>> {
|
||||
let biome = Biome {
|
||||
has_precipitation: false,
|
||||
impl Default for Biome {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
has_precipitation: 0,
|
||||
temperature: 1.0,
|
||||
temperature_modifier: None,
|
||||
downfall: 0.0,
|
||||
effects: BiomeEffects {
|
||||
fog_color: 0x7FA1FF,
|
||||
water_color: 0x7FA1FF,
|
||||
water_fog_color: 0x7FA1FF,
|
||||
sky_color: 0x7FA1FF,
|
||||
foliage_color: Some(0x7FA1FF),
|
||||
grass_color: Some(0x7FA1FF),
|
||||
fog_color: 12638463,
|
||||
water_color: 4159204,
|
||||
water_fog_color: 329011,
|
||||
sky_color: 7907327,
|
||||
foliage_color: None,
|
||||
grass_color: None,
|
||||
grass_color_modifier: None,
|
||||
particle: None,
|
||||
ambient_sound: None,
|
||||
@ -96,11 +113,6 @@ pub(super) fn all() -> Vec<RegistryValue<Biome>> {
|
||||
additions_sound: None,
|
||||
music: None,
|
||||
},
|
||||
};
|
||||
|
||||
vec![RegistryValue {
|
||||
name: "minecraft:plains".into(),
|
||||
id: 0,
|
||||
element: biome,
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
use super::RegistryValue;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
@ -13,19 +12,4 @@ struct Decoration {
|
||||
parameters: Vec<String>,
|
||||
}
|
||||
|
||||
pub(super) fn all() -> Vec<RegistryValue<ChatType>> {
|
||||
vec![RegistryValue {
|
||||
name: "minecraft:chat".into(),
|
||||
id: 0,
|
||||
element: ChatType {
|
||||
chat: Decoration {
|
||||
parameters: vec!["sender".into(), "content".into()],
|
||||
translation_key: "chat.type.text".into(),
|
||||
},
|
||||
narration: Decoration {
|
||||
parameters: vec!["sender".into(), "content".into()],
|
||||
translation_key: "chat.type.text.narrate".into(),
|
||||
},
|
||||
},
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
use serde::Serialize;
|
||||
|
||||
use super::RegistryValue;
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct DamageType {
|
||||
@ -61,23 +60,4 @@ const NAMES: &[&str] = &[
|
||||
"wither_skull",
|
||||
];
|
||||
|
||||
pub(super) fn all() -> Vec<RegistryValue<DamageType>> {
|
||||
let mut items: Vec<_> = NAMES
|
||||
.iter()
|
||||
.map(|name| RegistryValue {
|
||||
name: (*name).into(),
|
||||
id: 0,
|
||||
element: DamageType {
|
||||
exhaustion: 0.1,
|
||||
message_id: "inFire".into(),
|
||||
scaling: "when_caused_by_living_non_player".into(),
|
||||
effects: None,
|
||||
death_message_type: Some("default".into()),
|
||||
},
|
||||
})
|
||||
.collect();
|
||||
|
||||
items[1].element.effects = Some("burning".into());
|
||||
|
||||
items
|
||||
}
|
||||
|
||||
@ -49,13 +49,8 @@ impl Default for Dimension {
|
||||
infiniburn: "#minecraft:infiniburn_overworld".into(),
|
||||
logical_height: 384,
|
||||
min_y: -64,
|
||||
monster_spawn_block_light_limit: 0,
|
||||
monster_spawn_light_level: MonsterSpawnLightLevel::Tagged(
|
||||
MonsterSpawnLightLevelTagged::Uniform {
|
||||
min_inclusive: 7,
|
||||
max_inclusive: 0,
|
||||
},
|
||||
),
|
||||
monster_spawn_block_light_limit: 15,
|
||||
monster_spawn_light_level: MonsterSpawnLightLevel::Int(7),
|
||||
natural: 1,
|
||||
piglin_safe: 0,
|
||||
respawn_anchor_works: 0,
|
||||
|
||||
@ -1,121 +1,56 @@
|
||||
use biomes::Biome;
|
||||
use dimensions::Dimension;
|
||||
use fastnbt::SerOpts;
|
||||
use pumpkin_protocol::bytebuf::ByteBuffer;
|
||||
use serde::Serialize;
|
||||
use paint::Painting;
|
||||
use pumpkin_protocol::client::config::RegistryEntry;
|
||||
use wolf::WolfVariant;
|
||||
|
||||
mod biomes;
|
||||
mod chat_type;
|
||||
mod damage_type;
|
||||
mod dimensions;
|
||||
mod paint;
|
||||
mod wolf;
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
struct LoginInfo {
|
||||
#[serde(rename = "minecraft:dimension_type")]
|
||||
dimensions: Codec<dimensions::Dimension>,
|
||||
// #[serde(rename = "minecraft:wolf_variant")]
|
||||
// wolf: Codec<wolf::WolfVariant>,
|
||||
/* #[serde(rename = "minecraft:worldgen/biome")]
|
||||
biomes: Codec<biomes::Biome>,
|
||||
#[serde(rename = "minecraft:chat_type")]
|
||||
chat: Codec<chat_type::ChatType>,
|
||||
#[serde(rename = "minecraft:damage_type")]
|
||||
damage: Codec<damage_type::DamageType>, */
|
||||
pub struct Registry {
|
||||
pub registry_id: String,
|
||||
pub registry_entries: Vec<RegistryEntry>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct DimensionCodec {
|
||||
#[serde(rename = "minecraft:dimension_type")]
|
||||
dimensions: Codec<dimensions::Dimension>,
|
||||
}
|
||||
|
||||
impl DimensionCodec {
|
||||
pub fn parse() -> Vec<u8> {
|
||||
let dimension = Dimension::default();
|
||||
let codec = DimensionCodec {
|
||||
dimensions: Codec {
|
||||
ty: "minecraft:dimension_type".into(),
|
||||
value: vec![RegistryValue {
|
||||
name: "minecraft:overworld".into(),
|
||||
id: 0,
|
||||
element: dimension,
|
||||
impl Registry {
|
||||
pub fn get_static() -> Vec<Self> {
|
||||
let dimensions = Registry {
|
||||
registry_id: "minecraft:dimension_type".to_string(),
|
||||
registry_entries: vec![RegistryEntry {
|
||||
entry_id: "minecraft:overworld".to_string(),
|
||||
data: fastnbt::to_bytes_with_opts(&Dimension::default(), SerOpts::network_nbt())
|
||||
.unwrap(),
|
||||
}],
|
||||
},
|
||||
};
|
||||
fastnbt::to_bytes_with_opts(&codec, SerOpts::network_nbt()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct WolfCodec {
|
||||
#[serde(rename = "minecraft:wolf_variant")]
|
||||
wolf: Codec<wolf::WolfVariant>,
|
||||
}
|
||||
|
||||
impl WolfCodec {
|
||||
pub fn parse() -> Vec<u8> {
|
||||
let wolf = WolfVariant::default();
|
||||
let codec = WolfCodec {
|
||||
wolf: Codec {
|
||||
ty: "minecraft:wolf_variant".into(),
|
||||
value: vec![RegistryValue {
|
||||
name: "minecraft:wolf_variant".into(),
|
||||
id: 0,
|
||||
element: wolf,
|
||||
let biomes = Registry {
|
||||
registry_id: "minecraft:worldgen/biome".to_string(),
|
||||
registry_entries: vec![RegistryEntry {
|
||||
entry_id: "minecraft:snowy_taiga".to_string(),
|
||||
data: fastnbt::to_bytes_with_opts(&Biome::default(), SerOpts::network_nbt())
|
||||
.unwrap(),
|
||||
}],
|
||||
},
|
||||
};
|
||||
fastnbt::to_bytes_with_opts(&codec, SerOpts::network_nbt()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
struct Codec<T> {
|
||||
#[serde(rename = "type")]
|
||||
ty: String,
|
||||
value: Vec<RegistryValue<T>>,
|
||||
}
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
struct RegistryValue<T> {
|
||||
name: String,
|
||||
id: i32,
|
||||
element: T,
|
||||
}
|
||||
|
||||
pub fn write_codec(out: &mut ByteBuffer, world_min_y: i32, world_height: u32) -> Vec<u8> {
|
||||
let dimension = Dimension::default();
|
||||
let wolf = WolfVariant::default();
|
||||
|
||||
let info = LoginInfo {
|
||||
dimensions: Codec {
|
||||
ty: "minecraft:dimension_type".into(),
|
||||
value: vec![RegistryValue {
|
||||
name: "minecraft:overworld".into(),
|
||||
id: 0,
|
||||
element: dimension,
|
||||
let wolf_variants = Registry {
|
||||
registry_id: "minecraft:wolf_variant".to_string(),
|
||||
registry_entries: vec![RegistryEntry {
|
||||
entry_id: "minecraft:wolf_variant".to_string(),
|
||||
data: fastnbt::to_bytes_with_opts(&WolfVariant::default(), SerOpts::network_nbt())
|
||||
.unwrap(),
|
||||
}],
|
||||
},
|
||||
/* wolf: Codec {
|
||||
ty: "minecraft:wolf_variant".into(),
|
||||
value: vec![RegistryValue {
|
||||
name: "minecraft:wolf_variant".into(),
|
||||
id: 0,
|
||||
element: wolf,
|
||||
}],
|
||||
}, */ /* biomes: Codec {
|
||||
ty: "minecraft:worldgen/biome".into(),
|
||||
value: biomes::all(),
|
||||
},
|
||||
chat: Codec {
|
||||
ty: "minecraft:chat_type".into(),
|
||||
value: chat_type::all(),
|
||||
},
|
||||
damage: Codec {
|
||||
ty: "minecraft:damage_type".into(),
|
||||
value: damage_type::all(),
|
||||
}, */
|
||||
};
|
||||
|
||||
fastnbt::to_bytes_with_opts(&info, SerOpts::network_nbt()).unwrap()
|
||||
let paintings = Registry {
|
||||
registry_id: "minecraft:painting_variant".to_string(),
|
||||
registry_entries: vec![RegistryEntry {
|
||||
entry_id: "minecraft:painting_variant".to_string(),
|
||||
data: fastnbt::to_bytes_with_opts(&Painting::default(), SerOpts::network_nbt())
|
||||
.unwrap(),
|
||||
}],
|
||||
};
|
||||
vec![dimensions, biomes, wolf_variants, paintings]
|
||||
}
|
||||
}
|
||||
|
||||
18
pumpkin-registry/src/paint.rs
Normal file
18
pumpkin-registry/src/paint.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Painting {
|
||||
asset_id: String,
|
||||
height: i32,
|
||||
width: i32,
|
||||
}
|
||||
|
||||
impl Default for Painting {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
asset_id: "minecraft:backyard".into(),
|
||||
height: 2,
|
||||
width: 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
|
||||
use pumpkin_protocol::{
|
||||
client::{
|
||||
config::{CFinishConfig, CKnownPacks, CRegistryData, Entry},
|
||||
config::{CFinishConfig, CKnownPacks, CRegistryData},
|
||||
login::{CEncryptionRequest, CLoginSuccess},
|
||||
status::{CPingResponse, CStatusResponse},
|
||||
},
|
||||
@ -13,7 +12,7 @@ use pumpkin_protocol::{
|
||||
},
|
||||
ConnectionState, KnownPack,
|
||||
};
|
||||
use pumpkin_registry::{DimensionCodec, WolfCodec};
|
||||
use pumpkin_registry::Registry;
|
||||
|
||||
use crate::{
|
||||
entity::player::{ChatMode, Hand},
|
||||
@ -175,35 +174,13 @@ impl ClientPacketProcessor for Client {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_known_packs(&mut self, server: &mut Server, config_acknowledged: SKnownPacks) {
|
||||
fn handle_known_packs(&mut self, _server: &mut Server, _config_acknowledged: SKnownPacks) {
|
||||
for registry in Registry::get_static() {
|
||||
self.send_packet(CRegistryData::new(
|
||||
"dimension_type",
|
||||
&[
|
||||
Entry {
|
||||
entry_id: "minecraft:dimension_type",
|
||||
has_data: true,
|
||||
data: &DimensionCodec::parse(),
|
||||
},
|
||||
Entry {
|
||||
entry_id: "minecraft:wolf_variant",
|
||||
has_data: true,
|
||||
data: &WolfCodec::parse(),
|
||||
},
|
||||
/* Entry {
|
||||
entry_id: "minecraft:worldgen/biome".into(),
|
||||
has_data: true,
|
||||
},
|
||||
Entry {
|
||||
entry_id: "minecraft:chat_type".into(),
|
||||
has_data: true,
|
||||
},
|
||||
Entry {
|
||||
entry_id: "minecraft:damage_type".into(),
|
||||
has_data: true,
|
||||
}, */
|
||||
],
|
||||
))
|
||||
.unwrap_or_else(|e| self.kick(&e.to_string()));
|
||||
®istry.registry_id,
|
||||
®istry.registry_entries,
|
||||
)).unwrap_or_else(|e| self.kick(&e.to_string()));
|
||||
}
|
||||
|
||||
// We are done with configuring
|
||||
dbg!("finish config");
|
||||
|
||||
@ -190,8 +190,8 @@ impl Client {
|
||||
}
|
||||
|
||||
// Reads the connection until our buffer of len 4096 is full, then decode
|
||||
/// Returns `true` if the connection is closed.
|
||||
pub fn poll(&mut self, server: &mut Server, event: &Event) -> Result<bool, io::Error> {
|
||||
/// Close connection when an error occurs
|
||||
pub fn poll(&mut self, server: &mut Server, event: &Event) {
|
||||
if event.is_readable() {
|
||||
let mut received_data = vec![0; 4096];
|
||||
let mut bytes_read = 0;
|
||||
@ -201,7 +201,7 @@ impl Client {
|
||||
Ok(0) => {
|
||||
// Reading 0 bytes means the other side has closed the
|
||||
// connection or is done writing, then so are we.
|
||||
self.closed = true;
|
||||
self.close();
|
||||
break;
|
||||
}
|
||||
Ok(n) => {
|
||||
@ -215,7 +215,7 @@ impl Client {
|
||||
Err(ref err) if would_block(err) => break,
|
||||
Err(ref err) if interrupted(err) => continue,
|
||||
// Other errors we'll consider fatal.
|
||||
Err(err) => return Err(err),
|
||||
Err(_) => self.close(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,7 +234,6 @@ impl Client {
|
||||
self.dec.clear();
|
||||
}
|
||||
}
|
||||
Ok(self.closed)
|
||||
}
|
||||
|
||||
/// Kicks the Client with a reason depending on the connection state
|
||||
|
||||
@ -102,7 +102,7 @@ fn main() -> io::Result<()> {
|
||||
token => {
|
||||
// Maybe received an event for a TCP connection.
|
||||
let done = if let Some(client) = connections.get_mut(&token) {
|
||||
client.poll(&mut server, event).unwrap();
|
||||
client.poll(&mut server, event);
|
||||
client.closed
|
||||
} else {
|
||||
// Sporadic events happen, we can safely ignore them.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use std::{
|
||||
io::{self, Cursor},
|
||||
io::Cursor,
|
||||
sync::atomic::{AtomicI32, Ordering},
|
||||
};
|
||||
|
||||
@ -85,12 +85,7 @@ impl Server {
|
||||
}
|
||||
|
||||
// Returns Tokens to remove
|
||||
pub fn poll(
|
||||
&mut self,
|
||||
client: &mut Client,
|
||||
_poll: &Poll,
|
||||
event: &Event,
|
||||
) -> Result<bool, io::Error> {
|
||||
pub fn poll(&mut self, client: &mut Client, _poll: &Poll, event: &Event) {
|
||||
// todo, Poll players in every world
|
||||
client.poll(self, event)
|
||||
}
|
||||
@ -106,19 +101,19 @@ impl Server {
|
||||
.send_packet(CLogin::new(
|
||||
player.entity_id(),
|
||||
self.difficulty == Difficulty::Hard,
|
||||
1,
|
||||
vec!["minecraft:overworld".into()],
|
||||
0,
|
||||
"minecraft:overworld".into(),
|
||||
self.max_players as VarInt,
|
||||
8, // view distance todo
|
||||
8, // sim view dinstance todo
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
1,
|
||||
0,
|
||||
"minecraft:overworld".into(),
|
||||
0, // seed
|
||||
GameMode::Survival.to_byte() as u8,
|
||||
GameMode::Undefined.to_byte(),
|
||||
GameMode::Spectator.to_byte() as u8,
|
||||
GameMode::Spectator.to_byte(),
|
||||
false,
|
||||
false,
|
||||
false, // deth loc
|
||||
|
||||
Loading…
Reference in New Issue
Block a user