fix packet errors
This commit is contained in:
parent
2479019443
commit
87b537ccc9
30
Cargo.lock
generated
30
Cargo.lock
generated
@ -211,6 +211,19 @@ dependencies = [
|
|||||||
"serde_bytes",
|
"serde_bytes",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastsnbt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51b48b5b742a5441eb6dac3dfe2c2bd048e91fd8e98abf266b4d9f89972aa8ec"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"itoa",
|
||||||
|
"nom",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fdeflate"
|
name = "fdeflate"
|
||||||
version = "0.3.4"
|
version = "0.3.4"
|
||||||
@ -333,6 +346,12 @@ version = "2.7.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minimal-lexical"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.7.4"
|
version = "0.7.4"
|
||||||
@ -356,6 +375,16 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "7.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"minimal-lexical",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-bigint"
|
name = "num-bigint"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
@ -506,6 +535,7 @@ dependencies = [
|
|||||||
"cfb8",
|
"cfb8",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"fastnbt",
|
"fastnbt",
|
||||||
|
"fastsnbt",
|
||||||
"flate2",
|
"flate2",
|
||||||
"image",
|
"image",
|
||||||
"log",
|
"log",
|
||||||
|
|||||||
@ -30,4 +30,6 @@ crossbeam-channel = "0.5.13"
|
|||||||
uuid = "1.10"
|
uuid = "1.10"
|
||||||
toml = "0.8.17"
|
toml = "0.8.17"
|
||||||
fastnbt = "2.5.0"
|
fastnbt = "2.5.0"
|
||||||
|
fastsnbt = "0.2"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
protocol::{
|
protocol::{
|
||||||
client::{
|
client::{
|
||||||
config::{CFinishConfig, CKnownPacks, CPluginMessage, CRegistryData, Entry},
|
config::{CFinishConfig, CKnownPacks, CRegistryData, Entry},
|
||||||
login::{CEncryptionRequest, CLoginSuccess},
|
login::{CEncryptionRequest, CLoginSuccess},
|
||||||
status::{CPingResponse, CStatusResponse},
|
status::{CPingResponse, CStatusResponse},
|
||||||
},
|
},
|
||||||
@ -83,10 +83,8 @@ impl ClientPacketProcessor for Client {
|
|||||||
let verify_token: [u8; 4] = rand::random();
|
let verify_token: [u8; 4] = rand::random();
|
||||||
let public_key_der = &server.public_key_der;
|
let public_key_der = &server.public_key_der;
|
||||||
let packet = CEncryptionRequest::new(
|
let packet = CEncryptionRequest::new(
|
||||||
"".into(),
|
"",
|
||||||
public_key_der.len() as i32,
|
|
||||||
public_key_der,
|
public_key_der,
|
||||||
verify_token.len() as i32,
|
|
||||||
&verify_token,
|
&verify_token,
|
||||||
false, // TODO
|
false, // TODO
|
||||||
);
|
);
|
||||||
@ -101,7 +99,7 @@ impl ClientPacketProcessor for Client {
|
|||||||
dbg!("encryption response");
|
dbg!("encryption response");
|
||||||
// should be impossible
|
// should be impossible
|
||||||
if self.uuid.is_none() || self.name.is_none() {
|
if self.uuid.is_none() || self.name.is_none() {
|
||||||
self.kick("UUID or Name is none".into());
|
self.kick("UUID or Name is none");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.enable_encryption(server, encryption_response.shared_secret)
|
self.enable_encryption(server, encryption_response.shared_secret)
|
||||||
@ -126,14 +124,11 @@ impl ClientPacketProcessor for Client {
|
|||||||
self.connection_state = ConnectionState::Config;
|
self.connection_state = ConnectionState::Config;
|
||||||
Server::send_brand(self);
|
Server::send_brand(self);
|
||||||
// known data packs
|
// known data packs
|
||||||
self.send_packet(CKnownPacks::new(
|
self.send_packet(CKnownPacks::new(&[KnownPack {
|
||||||
1,
|
namespace: "minecraft",
|
||||||
&[KnownPack {
|
id: "core",
|
||||||
namespace: "minecraft".to_string(),
|
version: "1.21",
|
||||||
id: "core".to_string(),
|
}]));
|
||||||
version: "1.21".to_string(),
|
|
||||||
}],
|
|
||||||
));
|
|
||||||
dbg!("login achnowlaged");
|
dbg!("login achnowlaged");
|
||||||
}
|
}
|
||||||
fn handle_client_information(
|
fn handle_client_information(
|
||||||
@ -155,11 +150,10 @@ 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) {
|
||||||
self.send_packet(CRegistryData::new(
|
self.send_packet(CRegistryData::new(
|
||||||
"0".into(),
|
"dimension_type",
|
||||||
1,
|
&[
|
||||||
vec![
|
|
||||||
Entry {
|
Entry {
|
||||||
entry_id: "minecraft:dimension_type".into(),
|
entry_id: "minecraft:dimension_type",
|
||||||
has_data: true,
|
has_data: true,
|
||||||
},
|
},
|
||||||
/* Entry {
|
/* Entry {
|
||||||
|
|||||||
@ -222,7 +222,7 @@ impl Client {
|
|||||||
Ok(self.closed)
|
Ok(self.closed)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kick(&mut self, reason: String) {
|
pub fn kick(&mut self, reason: &str) {
|
||||||
// Todo
|
// Todo
|
||||||
match self.connection_state {
|
match self.connection_state {
|
||||||
ConnectionState::Login => {
|
ConnectionState::Login => {
|
||||||
|
|||||||
@ -56,7 +56,7 @@ impl PacketDecoder {
|
|||||||
Ok(Some(RawPacket {
|
Ok(Some(RawPacket {
|
||||||
len: packet_len,
|
len: packet_len,
|
||||||
id: packet_id,
|
id: packet_id,
|
||||||
bytebuf: ByteBuffer::new(BytesMut::from(data)),
|
bytebuf: ByteBuffer::new(data),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use core::str;
|
use core::str;
|
||||||
use std::io::{self, Error, ErrorKind, Read, Write};
|
use std::io::{self, Error, ErrorKind};
|
||||||
|
|
||||||
use bytes::{Buf, BufMut, BytesMut};
|
use bytes::{Buf, BufMut, BytesMut};
|
||||||
|
|
||||||
@ -180,17 +180,17 @@ impl ByteBuffer {
|
|||||||
self.put_list(v, |p, &v| p.put_var_int(v))
|
self.put_list(v, |p, &v| p.put_var_int(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pub fn get_nbt(&mut self) -> Option<crab_nbt::NbtTag> {
|
/* pub fn get_nbt(&mut self) -> Option<fastnbt::value::Value> {
|
||||||
match crab_nbt::NbtTag::deserialize(self.buf()) {
|
match crab_nbt::NbtTag::deserialize(self.buf()) {
|
||||||
Ok(v) => Some(v),
|
Ok(v) => Some(v),
|
||||||
Err(err) => None,
|
Err(err) => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn put_nbt(&mut self, nbt: NbtTag) {
|
|
||||||
self.buffer.put_slice(&nbt.serialize());
|
|
||||||
} */
|
|
||||||
|
|
||||||
|
pub fn put_nbt(&mut self, nbt: N) {
|
||||||
|
self.buffer.put_slice(&nbt.serialize());
|
||||||
|
}
|
||||||
|
*/
|
||||||
pub fn buf(&mut self) -> &mut BytesMut {
|
pub fn buf(&mut self) -> &mut BytesMut {
|
||||||
&mut self.buffer
|
&mut self.buffer
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,25 +26,25 @@ impl<'a> ClientPacket for CPluginMessage<'a> {
|
|||||||
|
|
||||||
fn write(&self, bytebuf: &mut ByteBuffer) {
|
fn write(&self, bytebuf: &mut ByteBuffer) {
|
||||||
bytebuf.put_string(&self.channel);
|
bytebuf.put_string(&self.channel);
|
||||||
bytebuf.put_slice(&self.data);
|
bytebuf.put_slice(self.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CConfigDisconnect {
|
pub struct CConfigDisconnect<'a> {
|
||||||
reason: String,
|
reason: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CConfigDisconnect {
|
impl<'a> CConfigDisconnect<'a> {
|
||||||
pub fn new(reason: String) -> Self {
|
pub fn new(reason: &'a str) -> Self {
|
||||||
Self { reason }
|
Self { reason }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClientPacket for CConfigDisconnect {
|
impl<'a> ClientPacket for CConfigDisconnect<'a> {
|
||||||
const PACKET_ID: crate::protocol::VarInt = 0x02;
|
const PACKET_ID: crate::protocol::VarInt = 0x02;
|
||||||
|
|
||||||
fn write(&self, bytebuf: &mut ByteBuffer) {
|
fn write(&self, bytebuf: &mut ByteBuffer) {
|
||||||
bytebuf.put_string(&self.reason);
|
bytebuf.put_string(self.reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,13 +69,12 @@ impl ClientPacket for CFinishConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct CKnownPacks<'a> {
|
pub struct CKnownPacks<'a> {
|
||||||
count: VarInt,
|
known_packs: &'a [KnownPack<'a>],
|
||||||
known_packs: &'a [KnownPack],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CKnownPacks<'a> {
|
impl<'a> CKnownPacks<'a> {
|
||||||
pub fn new(count: VarInt, known_packs: &'a [KnownPack]) -> Self {
|
pub fn new(known_packs: &'a [KnownPack]) -> Self {
|
||||||
Self { count, known_packs }
|
Self { known_packs }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,47 +82,43 @@ impl<'a> ClientPacket for CKnownPacks<'a> {
|
|||||||
const PACKET_ID: VarInt = 0x0E;
|
const PACKET_ID: VarInt = 0x0E;
|
||||||
|
|
||||||
fn write(&self, bytebuf: &mut ByteBuffer) {
|
fn write(&self, bytebuf: &mut ByteBuffer) {
|
||||||
// bytebuf.write_var_int(self.count);
|
bytebuf.put_list::<KnownPack>(self.known_packs, |p, v| {
|
||||||
bytebuf.put_list::<KnownPack>(&self.known_packs, |p, v| {
|
p.put_string(v.namespace);
|
||||||
p.put_string(&v.namespace);
|
p.put_string(v.id);
|
||||||
p.put_string(&v.id);
|
p.put_string(v.version);
|
||||||
p.put_string(&v.version);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CRegistryData {
|
pub struct CRegistryData<'a> {
|
||||||
registry_id: String,
|
registry_id: &'a str,
|
||||||
entry_count: VarInt,
|
entries: &'a [Entry<'a>],
|
||||||
entries: Vec<Entry>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CRegistryData {
|
impl<'a> CRegistryData<'a> {
|
||||||
pub fn new(registry_id: String, entry_count: VarInt, entries: Vec<Entry>) -> Self {
|
pub fn new(registry_id: &'a str, entries: &'a [Entry]) -> Self {
|
||||||
Self {
|
Self {
|
||||||
registry_id,
|
registry_id,
|
||||||
entry_count,
|
|
||||||
entries,
|
entries,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Entry {
|
pub struct Entry<'a> {
|
||||||
pub entry_id: String,
|
pub entry_id: &'a str,
|
||||||
pub has_data: bool,
|
pub has_data: bool,
|
||||||
// data provided by registry::write_codec
|
// data provided by registry::write_codec
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClientPacket for CRegistryData {
|
impl<'a> ClientPacket for CRegistryData<'a> {
|
||||||
const PACKET_ID: VarInt = 0x07;
|
const PACKET_ID: VarInt = 0x07;
|
||||||
|
|
||||||
fn write(&self, bytebuf: &mut ByteBuffer) {
|
fn write(&self, bytebuf: &mut ByteBuffer) {
|
||||||
bytebuf.put_string(&self.registry_id);
|
bytebuf.put_string(self.registry_id);
|
||||||
bytebuf.put_var_int(self.entry_count);
|
bytebuf.put_list::<Entry>(self.entries, |p, v| {
|
||||||
bytebuf.put_list::<Entry>(&self.entries, |p, v| {
|
p.put_string(v.entry_id);
|
||||||
p.put_string(&v.entry_id);
|
|
||||||
p.put_bool(v.has_data);
|
p.put_bool(v.has_data);
|
||||||
registry::write_single_dimension(p, -64, 320);
|
registry::write_codec(p, -64, 384);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
use crate::protocol::{bytebuf::ByteBuffer, ClientPacket, VarInt};
|
use crate::protocol::{bytebuf::ByteBuffer, ClientPacket, VarInt};
|
||||||
|
|
||||||
pub struct CLoginDisconnect {
|
pub struct CLoginDisconnect<'a> {
|
||||||
reason: String,
|
reason: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CLoginDisconnect {
|
impl<'a> CLoginDisconnect<'a> {
|
||||||
pub fn new(reason: String) -> Self {
|
pub fn new(reason: &'a str) -> Self {
|
||||||
Self { reason }
|
Self { reason }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClientPacket for CLoginDisconnect {
|
impl<'a> ClientPacket for CLoginDisconnect<'a> {
|
||||||
const PACKET_ID: VarInt = 0x00;
|
const PACKET_ID: VarInt = 0x00;
|
||||||
|
|
||||||
fn write(&self, bytebuf: &mut ByteBuffer) {
|
fn write(&self, bytebuf: &mut ByteBuffer) {
|
||||||
@ -19,28 +19,22 @@ impl ClientPacket for CLoginDisconnect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct CEncryptionRequest<'a> {
|
pub struct CEncryptionRequest<'a> {
|
||||||
server_id: String, // 20
|
server_id: &'a str, // 20
|
||||||
public_key_length: VarInt,
|
|
||||||
public_key: &'a [u8],
|
public_key: &'a [u8],
|
||||||
verify_token_length: VarInt,
|
|
||||||
verify_token: &'a [u8],
|
verify_token: &'a [u8],
|
||||||
should_authenticate: bool,
|
should_authenticate: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CEncryptionRequest<'a> {
|
impl<'a> CEncryptionRequest<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
server_id: String,
|
server_id: &'a str,
|
||||||
public_key_length: VarInt,
|
|
||||||
public_key: &'a [u8],
|
public_key: &'a [u8],
|
||||||
verify_token_length: VarInt,
|
|
||||||
verify_token: &'a [u8],
|
verify_token: &'a [u8],
|
||||||
should_authenticate: bool,
|
should_authenticate: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
server_id,
|
server_id,
|
||||||
public_key_length,
|
|
||||||
public_key,
|
public_key,
|
||||||
verify_token_length,
|
|
||||||
verify_token,
|
verify_token,
|
||||||
should_authenticate,
|
should_authenticate,
|
||||||
}
|
}
|
||||||
@ -51,10 +45,10 @@ impl<'a> ClientPacket for CEncryptionRequest<'a> {
|
|||||||
const PACKET_ID: VarInt = 0x01;
|
const PACKET_ID: VarInt = 0x01;
|
||||||
|
|
||||||
fn write(&self, bytebuf: &mut ByteBuffer) {
|
fn write(&self, bytebuf: &mut ByteBuffer) {
|
||||||
bytebuf.put_string(self.server_id.as_str());
|
bytebuf.put_string(self.server_id);
|
||||||
bytebuf.put_var_int(self.public_key_length);
|
bytebuf.put_var_int(self.public_key.len() as VarInt);
|
||||||
bytebuf.put_slice(self.public_key);
|
bytebuf.put_slice(self.public_key);
|
||||||
bytebuf.put_var_int(self.verify_token_length);
|
bytebuf.put_var_int(self.verify_token.len() as VarInt);
|
||||||
bytebuf.put_slice(self.verify_token);
|
bytebuf.put_slice(self.verify_token);
|
||||||
bytebuf.put_bool(self.should_authenticate);
|
bytebuf.put_bool(self.should_authenticate);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -124,7 +124,7 @@ pub trait ClientPacket {
|
|||||||
fn write(&self, bytebuf: &mut ByteBuffer);
|
fn write(&self, bytebuf: &mut ByteBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize)]
|
||||||
pub struct StatusResponse {
|
pub struct StatusResponse {
|
||||||
pub version: Version,
|
pub version: Version,
|
||||||
pub players: Players,
|
pub players: Players,
|
||||||
@ -132,27 +132,27 @@ pub struct StatusResponse {
|
|||||||
pub favicon: String, // data:image/png;base64,<data>
|
pub favicon: String, // data:image/png;base64,<data>
|
||||||
// Players, favicon ...
|
// Players, favicon ...
|
||||||
}
|
}
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize)]
|
||||||
pub struct Version {
|
pub struct Version {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub protocol: u32,
|
pub protocol: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize)]
|
||||||
pub struct Players {
|
pub struct Players {
|
||||||
pub max: u32,
|
pub max: u32,
|
||||||
pub online: u32,
|
pub online: u32,
|
||||||
pub sample: Vec<Sample>,
|
pub sample: Vec<Sample>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize)]
|
||||||
pub struct Sample {
|
pub struct Sample {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub id: String, // uuid
|
pub id: String, // uuid
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct KnownPack {
|
pub struct KnownPack<'a> {
|
||||||
pub namespace: String,
|
pub namespace: &'a str,
|
||||||
pub id: String,
|
pub id: &'a str,
|
||||||
pub version: String,
|
pub version: &'a str,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use crate::protocol::VarInt;
|
use crate::protocol::VarInt;
|
||||||
|
|
||||||
use super::CodecItem;
|
use super::RegistryValue;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
@ -72,7 +72,7 @@ struct Music {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 1.20.6 default https://gist.github.com/WinX64/ab8c7a8df797c273b32d3a3b66522906
|
// 1.20.6 default https://gist.github.com/WinX64/ab8c7a8df797c273b32d3a3b66522906
|
||||||
pub(super) fn all() -> Vec<CodecItem<Biome>> {
|
pub(super) fn all() -> Vec<RegistryValue<Biome>> {
|
||||||
let biome = Biome {
|
let biome = Biome {
|
||||||
has_precipitation: false,
|
has_precipitation: false,
|
||||||
temperature: 1.0,
|
temperature: 1.0,
|
||||||
@ -99,7 +99,7 @@ pub(super) fn all() -> Vec<CodecItem<Biome>> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
vec![CodecItem {
|
vec![RegistryValue {
|
||||||
name: "minecraft:plains".into(),
|
name: "minecraft:plains".into(),
|
||||||
id: 0,
|
id: 0,
|
||||||
element: biome,
|
element: biome,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use super::CodecItem;
|
use super::RegistryValue;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
@ -13,8 +13,8 @@ struct Decoration {
|
|||||||
parameters: Vec<String>,
|
parameters: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn all() -> Vec<CodecItem<ChatType>> {
|
pub(super) fn all() -> Vec<RegistryValue<ChatType>> {
|
||||||
vec![CodecItem {
|
vec![RegistryValue {
|
||||||
name: "minecraft:chat".into(),
|
name: "minecraft:chat".into(),
|
||||||
id: 0,
|
id: 0,
|
||||||
element: ChatType {
|
element: ChatType {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use super::CodecItem;
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::RegistryValue;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct DamageType {
|
pub struct DamageType {
|
||||||
message_id: String,
|
message_id: String,
|
||||||
@ -60,10 +61,10 @@ const NAMES: &[&str] = &[
|
|||||||
"wither_skull",
|
"wither_skull",
|
||||||
];
|
];
|
||||||
|
|
||||||
pub(super) fn all() -> Vec<CodecItem<DamageType>> {
|
pub(super) fn all() -> Vec<RegistryValue<DamageType>> {
|
||||||
let mut items: Vec<_> = NAMES
|
let mut items: Vec<_> = NAMES
|
||||||
.iter()
|
.iter()
|
||||||
.map(|name| CodecItem {
|
.map(|name| RegistryValue {
|
||||||
name: (*name).into(),
|
name: (*name).into(),
|
||||||
id: 0,
|
id: 0,
|
||||||
element: DamageType {
|
element: DamageType {
|
||||||
|
|||||||
@ -1,48 +1,83 @@
|
|||||||
use serde::Serialize;
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Dimension {
|
pub struct Dimension {
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
pub ambient_light: f32,
|
||||||
fixed_time: Option<f64>,
|
|
||||||
has_skylight: bool,
|
|
||||||
has_ceiling: bool,
|
|
||||||
ultrawarm: bool,
|
|
||||||
natural: bool,
|
|
||||||
coordinate_scale: f64,
|
|
||||||
bed_works: bool,
|
bed_works: bool,
|
||||||
respawn_anchor_works: bool,
|
coordinate_scale: f64,
|
||||||
min_y: i32,
|
effects: DimensionEffects,
|
||||||
height: i32,
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
logical_height: i32,
|
fixed_time: Option<i32>,
|
||||||
infiniburn: String,
|
has_ceiling: bool,
|
||||||
effects: String,
|
|
||||||
ambient_light: f32,
|
|
||||||
piglin_safe: bool,
|
|
||||||
has_raids: bool,
|
has_raids: bool,
|
||||||
monster_spawn_light_level: i32,
|
has_skylight: bool,
|
||||||
|
height: i32,
|
||||||
|
infiniburn: String,
|
||||||
|
logical_height: i32,
|
||||||
|
min_y: i32,
|
||||||
monster_spawn_block_light_limit: i32,
|
monster_spawn_block_light_limit: i32,
|
||||||
|
monster_spawn_light_level: MonsterSpawnLightLevel,
|
||||||
|
natural: bool,
|
||||||
|
piglin_safe: bool,
|
||||||
|
respawn_anchor_works: bool,
|
||||||
|
ultrawarm: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn overworld(world_min_y: i32, world_height: u32) -> Dimension {
|
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default, Debug)]
|
||||||
Dimension {
|
pub enum DimensionEffects {
|
||||||
piglin_safe: false,
|
#[serde(rename = "minecraft:overworld")]
|
||||||
natural: true,
|
#[default]
|
||||||
ambient_light: 0.0,
|
Overworld,
|
||||||
fixed_time: Some(6000.0),
|
#[serde(rename = "minecraft:the_nether")]
|
||||||
infiniburn: "#minecraft:infiniburn_overworld".into(),
|
TheNether,
|
||||||
respawn_anchor_works: false,
|
#[serde(rename = "minecraft:the_end")]
|
||||||
has_skylight: true,
|
TheEnd,
|
||||||
bed_works: true,
|
}
|
||||||
effects: "minecraft:overworld".into(),
|
|
||||||
has_raids: false,
|
|
||||||
logical_height: 384,
|
|
||||||
coordinate_scale: 1.0,
|
|
||||||
ultrawarm: false,
|
|
||||||
has_ceiling: false,
|
|
||||||
min_y: world_min_y,
|
|
||||||
height: (world_height as i32 + 15) / 16 * 16,
|
|
||||||
|
|
||||||
monster_spawn_light_level: 7,
|
impl Default for Dimension {
|
||||||
monster_spawn_block_light_limit: 7,
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
ambient_light: 0.0,
|
||||||
|
bed_works: true,
|
||||||
|
coordinate_scale: 1.0,
|
||||||
|
effects: DimensionEffects::default(),
|
||||||
|
fixed_time: None,
|
||||||
|
has_ceiling: false,
|
||||||
|
has_raids: true,
|
||||||
|
has_skylight: true,
|
||||||
|
height: 384,
|
||||||
|
infiniburn: "#minecraft:infiniburn_overworld".into(),
|
||||||
|
logical_height: 384,
|
||||||
|
min_y: -64,
|
||||||
|
monster_spawn_block_light_limit: 0,
|
||||||
|
monster_spawn_light_level: MonsterSpawnLightLevel::Int(7),
|
||||||
|
natural: true,
|
||||||
|
piglin_safe: false,
|
||||||
|
respawn_anchor_works: false,
|
||||||
|
ultrawarm: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum MonsterSpawnLightLevel {
|
||||||
|
Int(i32),
|
||||||
|
Tagged(MonsterSpawnLightLevelTagged),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "type", content = "value")]
|
||||||
|
pub enum MonsterSpawnLightLevelTagged {
|
||||||
|
#[serde(rename = "minecraft:uniform")]
|
||||||
|
Uniform {
|
||||||
|
min_inclusive: i32,
|
||||||
|
max_inclusive: i32,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<i32> for MonsterSpawnLightLevel {
|
||||||
|
fn from(value: i32) -> Self {
|
||||||
|
Self::Int(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
use dimensions::Dimension;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use super::bytebuf::ByteBuffer;
|
use super::bytebuf::ByteBuffer;
|
||||||
@ -11,45 +12,55 @@ mod dimensions;
|
|||||||
struct LoginInfo {
|
struct LoginInfo {
|
||||||
#[serde(rename = "minecraft:dimension_type")]
|
#[serde(rename = "minecraft:dimension_type")]
|
||||||
dimensions: Codec<dimensions::Dimension>,
|
dimensions: Codec<dimensions::Dimension>,
|
||||||
#[serde(rename = "minecraft:worldgen/biome")]
|
/* #[serde(rename = "minecraft:worldgen/biome")]
|
||||||
biomes: Codec<biomes::Biome>,
|
biomes: Codec<biomes::Biome>,
|
||||||
#[serde(rename = "minecraft:chat_type")]
|
#[serde(rename = "minecraft:chat_type")]
|
||||||
chat: Codec<chat_type::ChatType>,
|
chat: Codec<chat_type::ChatType>,
|
||||||
#[serde(rename = "minecraft:damage_type")]
|
#[serde(rename = "minecraft:damage_type")]
|
||||||
damage: Codec<damage_type::DamageType>,
|
damage: Codec<damage_type::DamageType>, */
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
struct Codec<T> {
|
struct Codec<T> {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
ty: String,
|
ty: String,
|
||||||
value: Vec<CodecItem<T>>,
|
value: Vec<RegistryValue<T>>,
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
struct CodecItem<T> {
|
struct RegistryValue<T> {
|
||||||
name: String,
|
name: String,
|
||||||
id: i32,
|
id: i32,
|
||||||
element: T,
|
element: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_single_dimension(out: &mut ByteBuffer, world_min_y: i32, world_height: u32) {
|
pub fn write_single_dimension(out: &mut ByteBuffer, world_min_y: i32, world_height: u32) {
|
||||||
let dimension = dimensions::overworld(world_min_y, world_height);
|
let dimension = Dimension::default();
|
||||||
// out.put_nbt(nbt!(dimension))
|
let nbt = Codec {
|
||||||
|
ty: "minecraft:dimension_type".into(),
|
||||||
|
value: vec![RegistryValue {
|
||||||
|
name: "minecraft:overworld".into(),
|
||||||
|
id: 0,
|
||||||
|
element: dimension,
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
let val = &fastsnbt::to_string(&nbt).unwrap();
|
||||||
|
dbg!(val);
|
||||||
|
out.put_string(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_codec(out: &mut ByteBuffer, world_min_y: i32, world_height: u32) {
|
pub fn write_codec(out: &mut ByteBuffer, world_min_y: i32, world_height: u32) {
|
||||||
let dimension = dimensions::overworld(world_min_y, world_height);
|
let dimension = Dimension::default();
|
||||||
|
|
||||||
let info = LoginInfo {
|
let info = LoginInfo {
|
||||||
dimensions: Codec {
|
dimensions: Codec {
|
||||||
ty: "minecraft:dimension_type".into(),
|
ty: "minecraft:dimension_type".into(),
|
||||||
value: vec![CodecItem {
|
value: vec![RegistryValue {
|
||||||
name: "minecraft:overworld".into(),
|
name: "minecraft:overworld".into(),
|
||||||
id: 0,
|
id: 0,
|
||||||
element: dimension,
|
element: dimension,
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
biomes: Codec {
|
/* biomes: Codec {
|
||||||
ty: "minecraft:worldgen/biome".into(),
|
ty: "minecraft:worldgen/biome".into(),
|
||||||
value: biomes::all(),
|
value: biomes::all(),
|
||||||
},
|
},
|
||||||
@ -60,11 +71,13 @@ pub fn write_codec(out: &mut ByteBuffer, world_min_y: i32, world_height: u32) {
|
|||||||
damage: Codec {
|
damage: Codec {
|
||||||
ty: "minecraft:damage_type".into(),
|
ty: "minecraft:damage_type".into(),
|
||||||
value: damage_type::all(),
|
value: damage_type::all(),
|
||||||
},
|
}, */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let val = &fastsnbt::to_string(&info).unwrap();
|
||||||
|
dbg!(val);
|
||||||
// Dimension codec
|
// Dimension codec
|
||||||
// out.put_slice(&nbt::to_nbt("", &info).unwrap().serialize());
|
out.put_string(val);
|
||||||
// Current dimension type (key in dimension codec)
|
// Current dimension type (key in dimension codec)
|
||||||
out.put_string("minecraft:overworld");
|
out.put_string("minecraft:overworld");
|
||||||
// Current world
|
// Current world
|
||||||
|
|||||||
@ -16,10 +16,7 @@ use crate::{
|
|||||||
Entity, EntityId,
|
Entity, EntityId,
|
||||||
},
|
},
|
||||||
protocol::{
|
protocol::{
|
||||||
client::{
|
client::{config::CPluginMessage, play::CLogin},
|
||||||
config::{CFinishConfig, CKnownPacks, CPluginMessage, CRegistryData, Entry},
|
|
||||||
play::CLogin,
|
|
||||||
},
|
|
||||||
Players, Sample, StatusResponse, VarInt, VarInt32, Version,
|
Players, Sample, StatusResponse, VarInt, VarInt32, Version,
|
||||||
},
|
},
|
||||||
world::World,
|
world::World,
|
||||||
|
|||||||
@ -4,6 +4,12 @@ pub struct World {
|
|||||||
pub players: Vec<Player>,
|
pub players: Vec<Player>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for World {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl World {
|
impl World {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user