Add pumpkin-world

also refactor player
This commit is contained in:
Snowiiii 2024-08-04 00:29:20 +02:00
parent 31aa333410
commit ae69bbc7f1
20 changed files with 342 additions and 268 deletions

219
Cargo.lock generated
View File

@ -37,6 +37,12 @@ version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]]
name = "bit_field"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
@ -63,9 +69,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.7.0" version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fca2be1d5c43812bae364ee3f30b3afcb7877cf59f4aeb94c66f313a41d2fac9" checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
[[package]] [[package]]
name = "cesu8" name = "cesu8"
@ -98,6 +104,12 @@ dependencies = [
"inout", "inout",
] ]
[[package]]
name = "color_quant"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]] [[package]]
name = "colored" name = "colored"
version = "2.1.0" version = "2.1.0"
@ -193,6 +205,37 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "fastanvil"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "619fbd9bb48f9e54a7ff88cdd0f7048b8ea519448518c690057f9d03d3e81ebf"
dependencies = [
"bit_field",
"byteorder",
"fastnbt 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2",
"image 0.23.14",
"log",
"num_enum",
"once_cell",
"serde",
"serde_json",
"tar",
]
[[package]]
name = "fastnbt"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d4a73a95dc65551ccd98e1ecd1adb5d1ba5361146963b31f481ca42fc0520a3"
dependencies = [
"byteorder",
"cesu8",
"serde",
"serde_bytes",
]
[[package]] [[package]]
name = "fastnbt" name = "fastnbt"
version = "2.5.0" version = "2.5.0"
@ -227,10 +270,22 @@ dependencies = [
] ]
[[package]] [[package]]
name = "flate2" name = "filetime"
version = "1.0.30" version = "0.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"windows-sys 0.52.0",
]
[[package]]
name = "flate2"
version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920"
dependencies = [ dependencies = [
"crc32fast", "crc32fast",
"miniz_oxide", "miniz_oxide",
@ -269,6 +324,20 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]]
name = "image"
version = "0.23.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1"
dependencies = [
"bytemuck",
"byteorder",
"color_quant",
"num-iter",
"num-rational",
"num-traits",
]
[[package]] [[package]]
name = "image" name = "image"
version = "0.25.2" version = "0.25.2"
@ -431,6 +500,17 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "num-rational"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.19" version = "0.2.19"
@ -441,6 +521,27 @@ dependencies = [
"libm", "libm",
] ]
[[package]]
name = "num_enum"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9"
dependencies = [
"num_enum_derive",
]
[[package]]
name = "num_enum_derive"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799"
dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "num_threads" name = "num_threads"
version = "0.1.7" version = "0.1.7"
@ -450,6 +551,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]] [[package]]
name = "pem-rfc7468" name = "pem-rfc7468"
version = "0.7.0" version = "0.7.0"
@ -501,13 +608,23 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.18" version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dee4364d9f3b902ef14fab8a1ddffb783a1cb6b4bba3bfc1fa3922732c7de97f" checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
dependencies = [ dependencies = [
"zerocopy", "zerocopy",
] ]
[[package]]
name = "proc-macro-crate"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
dependencies = [
"once_cell",
"toml_edit 0.19.15",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.86" version = "1.0.86"
@ -524,11 +641,12 @@ dependencies = [
"base64", "base64",
"crossbeam-channel", "crossbeam-channel",
"flate2", "flate2",
"image", "image 0.25.2",
"log", "log",
"mio", "mio",
"pumpkin-protocol", "pumpkin-protocol",
"pumpkin-registry", "pumpkin-registry",
"pumpkin-world",
"rand", "rand",
"rsa", "rsa",
"rsa-der", "rsa-der",
@ -558,11 +676,20 @@ dependencies = [
name = "pumpkin-registry" name = "pumpkin-registry"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"fastnbt", "fastnbt 2.5.0 (git+https://github.com/owengage/fastnbt.git)",
"fastsnbt", "fastsnbt",
"pumpkin-protocol", "pumpkin-protocol",
"serde", "serde",
"serde_json", ]
[[package]]
name = "pumpkin-world"
version = "0.1.0"
dependencies = [
"fastanvil",
"fastnbt 2.5.0 (git+https://github.com/owengage/fastnbt.git)",
"fastsnbt",
"pumpkin-protocol",
] ]
[[package]] [[package]]
@ -604,6 +731,15 @@ dependencies = [
"getrandom", "getrandom",
] ]
[[package]]
name = "redox_syscall"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
dependencies = [
"bitflags",
]
[[package]] [[package]]
name = "rsa" name = "rsa"
version = "0.9.6" version = "0.9.6"
@ -665,14 +801,14 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.72",
] ]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.121" version = "1.0.122"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da"
dependencies = [ dependencies = [
"itoa", "itoa",
"memchr", "memchr",
@ -757,6 +893,17 @@ version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.72" version = "2.0.72"
@ -768,6 +915,16 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "tar"
version = "0.4.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909"
dependencies = [
"filetime",
"libc",
]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.63" version = "1.0.63"
@ -785,7 +942,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -830,7 +987,7 @@ dependencies = [
"serde", "serde",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
"toml_edit", "toml_edit 0.22.20",
] ]
[[package]] [[package]]
@ -842,6 +999,17 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "toml_edit"
version = "0.19.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
dependencies = [
"indexmap",
"toml_datetime",
"winnow 0.5.40",
]
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.22.20" version = "0.22.20"
@ -852,7 +1020,7 @@ dependencies = [
"serde", "serde",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
"winnow", "winnow 0.6.18",
] ]
[[package]] [[package]]
@ -1024,6 +1192,15 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.5.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.6.18" version = "0.6.18"
@ -1035,9 +1212,9 @@ dependencies = [
[[package]] [[package]]
name = "zerocopy" name = "zerocopy"
version = "0.6.6" version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"zerocopy-derive", "zerocopy-derive",
@ -1045,13 +1222,13 @@ dependencies = [
[[package]] [[package]]
name = "zerocopy-derive" name = "zerocopy-derive"
version = "0.6.6" version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.72",
] ]
[[package]] [[package]]

View File

@ -1,6 +1,6 @@
[workspace] [workspace]
resolver = "2" resolver = "2"
members = [ "pumpkin-protocol/", "pumpkin-registry/", "pumpkin/"] members = [ "pumpkin-protocol/", "pumpkin-registry/", "pumpkin-world", "pumpkin/"]
[workspace.package] [workspace.package]
version = "0.1.0" version = "0.1.0"

View File

@ -92,7 +92,7 @@ impl<'a> ClientPacket for CKnownPacks<'a> {
pub struct CRegistryData<'a> { pub struct CRegistryData<'a> {
registry_id: &'a str, registry_id: &'a str,
entries: &'a [RegistryEntry], entries: &'a [RegistryEntry<'a>],
} }
impl<'a> CRegistryData<'a> { impl<'a> CRegistryData<'a> {
@ -104,8 +104,8 @@ impl<'a> CRegistryData<'a> {
} }
} }
pub struct RegistryEntry { pub struct RegistryEntry<'a> {
pub entry_id: String, pub entry_id: &'a str,
pub data: Vec<u8>, pub data: Vec<u8>,
} }

View File

@ -312,9 +312,9 @@ pub struct BlockEntity {
} }
pub struct SkyLight { pub struct SkyLight {
array: Vec<u8>, pub array: Vec<u8>,
} }
pub struct BlockLight { pub struct BlockLight {
array: Vec<u8>, pub array: Vec<u8>,
} }

View File

@ -1,7 +1,7 @@
use crate::{ServerPacket, VarInt}; use crate::{ServerPacket, VarInt};
pub struct SConfirmTeleport { pub struct SConfirmTeleport {
teleport_id: VarInt, pub teleport_id: VarInt,
} }
impl ServerPacket for SConfirmTeleport { impl ServerPacket for SConfirmTeleport {

View File

@ -10,4 +10,3 @@ fastnbt = { git = "https://github.com/owengage/fastnbt.git" }
fastsnbt = "0.2" fastsnbt = "0.2"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

View File

@ -63,7 +63,7 @@ const NAMES: &[&str] = &[
"wither_skull", "wither_skull",
]; ];
pub(super) fn entires() -> Vec<RegistryEntry> { pub(super) fn entires() -> Vec<RegistryEntry<'static>> {
let items: Vec<_> = NAMES let items: Vec<_> = NAMES
.iter() .iter()
.map(|name| RegistryEntry { .map(|name| RegistryEntry {

View File

@ -14,7 +14,7 @@ mod wolf;
pub struct Registry { pub struct Registry {
pub registry_id: String, pub registry_id: String,
pub registry_entries: Vec<RegistryEntry>, pub registry_entries: Vec<RegistryEntry<'static>>,
} }
impl Registry { impl Registry {
@ -22,7 +22,7 @@ impl Registry {
let dimensions = Registry { let dimensions = Registry {
registry_id: "minecraft:dimension_type".to_string(), registry_id: "minecraft:dimension_type".to_string(),
registry_entries: vec![RegistryEntry { registry_entries: vec![RegistryEntry {
entry_id: "minecraft:overworld".to_string(), entry_id: "minecraft:overworld",
data: fastnbt::to_bytes_with_opts(&Dimension::default(), SerOpts::network_nbt()) data: fastnbt::to_bytes_with_opts(&Dimension::default(), SerOpts::network_nbt())
.unwrap(), .unwrap(),
}], }],
@ -31,12 +31,12 @@ impl Registry {
registry_id: "minecraft:worldgen/biome".to_string(), registry_id: "minecraft:worldgen/biome".to_string(),
registry_entries: vec![ registry_entries: vec![
RegistryEntry { RegistryEntry {
entry_id: "minecraft:snowy_taiga".to_string(), entry_id: "minecraft:snowy_taiga",
data: fastnbt::to_bytes_with_opts(&Biome::default(), SerOpts::network_nbt()) data: fastnbt::to_bytes_with_opts(&Biome::default(), SerOpts::network_nbt())
.unwrap(), .unwrap(),
}, },
RegistryEntry { RegistryEntry {
entry_id: "minecraft:plains".to_string(), entry_id: "minecraft:plains",
data: fastnbt::to_bytes_with_opts(&Biome::default(), SerOpts::network_nbt()) data: fastnbt::to_bytes_with_opts(&Biome::default(), SerOpts::network_nbt())
.unwrap(), .unwrap(),
}, },
@ -45,7 +45,7 @@ impl Registry {
let wolf_variants = Registry { let wolf_variants = Registry {
registry_id: "minecraft:wolf_variant".to_string(), registry_id: "minecraft:wolf_variant".to_string(),
registry_entries: vec![RegistryEntry { registry_entries: vec![RegistryEntry {
entry_id: "minecraft:wolf_variant".to_string(), entry_id: "minecraft:wolf_variant",
data: fastnbt::to_bytes_with_opts(&WolfVariant::default(), SerOpts::network_nbt()) data: fastnbt::to_bytes_with_opts(&WolfVariant::default(), SerOpts::network_nbt())
.unwrap(), .unwrap(),
}], }],
@ -57,7 +57,7 @@ impl Registry {
let paintings = Registry { let paintings = Registry {
registry_id: "minecraft:painting_variant".to_string(), registry_id: "minecraft:painting_variant".to_string(),
registry_entries: vec![RegistryEntry { registry_entries: vec![RegistryEntry {
entry_id: "minecraft:painting_variant".to_string(), entry_id: "minecraft:painting_variant",
data: fastnbt::to_bytes_with_opts(&Painting::default(), SerOpts::network_nbt()) data: fastnbt::to_bytes_with_opts(&Painting::default(), SerOpts::network_nbt())
.unwrap(), .unwrap(),
}], }],

10
pumpkin-world/Cargo.toml Normal file
View File

@ -0,0 +1,10 @@
[package]
name = "pumpkin-world"
version.workspace = true
edition.workspace = true
[dependencies]
pumpkin-protocol = { path = "../pumpkin-protocol"}
fastanvil = "0.31"
fastnbt = { git = "https://github.com/owengage/fastnbt.git" }
fastsnbt = "0.2"

View File

@ -0,0 +1,20 @@
use fastnbt::{nbt, SerOpts};
pub const BLOCKS_AND_BIOMES: [u8; 2000] = [0x80; 2000];
pub const SKY_LIGHT_ARRAYS: [FixedArray<u8, 2048>; 26] = [FixedArray([0xff; 2048]); 26];
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[repr(transparent)]
pub struct FixedArray<T, const N: usize>(pub [T; N]);
pub struct TestChunk {
pub heightmap: Vec<u8>,
}
impl TestChunk {
pub fn new() -> Self {
let bytes = fastnbt::to_bytes(&nbt!({"MOTION_BLOCKING": [L; 123, 256]})).unwrap();
Self { heightmap: bytes }
}
}

26
pumpkin-world/src/lib.rs Normal file
View File

@ -0,0 +1,26 @@
use std::{fs::File, path::Path};
use fastanvil::{complete, Chunk, Region};
pub mod chunk;
pub struct World {
pub region: Region<File>,
}
impl World {
pub fn load<P: AsRef<Path>>(path: P) -> Self {
let file = std::fs::File::open(path).unwrap();
let region = Region::from_stream(file).unwrap();
Self { region }
}
/* pub fn load_chunk(&mut self, x: usize, y: usize) -> Chunk {
let data = self.region.read_chunk(x, y).unwrap().unwrap();
let complete_chunk = complete::Chunk::from_bytes(&data).unwrap();
}
*/
}

View File

@ -4,6 +4,7 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
pumpkin-world = { path = "../pumpkin-world"}
pumpkin-protocol = { path = "../pumpkin-protocol"} pumpkin-protocol = { path = "../pumpkin-protocol"}
pumpkin-registry = { path = "../pumpkin-registry"} pumpkin-registry = { path = "../pumpkin-registry"}

View File

@ -10,6 +10,7 @@ use crate::{
}; };
use mio::{event::Event, net::TcpStream, Token}; use mio::{event::Event, net::TcpStream, Token};
use player_packet::PlayerPacketProcessor;
use pumpkin_protocol::{ use pumpkin_protocol::{
client::{config::CConfigDisconnect, login::CLoginDisconnect}, client::{config::CConfigDisconnect, login::CLoginDisconnect},
packet_decoder::PacketDecoder, packet_decoder::PacketDecoder,
@ -18,6 +19,7 @@ use pumpkin_protocol::{
config::{SAcknowledgeFinishConfig, SClientInformation, SKnownPacks, SPluginMessage}, config::{SAcknowledgeFinishConfig, SClientInformation, SKnownPacks, SPluginMessage},
handshake::SHandShake, handshake::SHandShake,
login::{SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart}, login::{SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart},
play::SConfirmTeleport,
status::{SPingRequest, SStatusRequest}, status::{SPingRequest, SStatusRequest},
}, },
ClientPacket, ConnectionState, PacketError, RawPacket, ServerPacket, ClientPacket, ConnectionState, PacketError, RawPacket, ServerPacket,
@ -186,8 +188,8 @@ impl Client {
), ),
}, },
pumpkin_protocol::ConnectionState::Play => { pumpkin_protocol::ConnectionState::Play => {
if let Some(player) = &mut self.player { if self.player.is_some() {
player.handle_packet(server, packet); self.handle_play_packet(server, packet);
} else { } else {
// should be impossible // should be impossible
self.kick("no player in play state?") self.kick("no player in play state?")
@ -197,6 +199,16 @@ impl Client {
} }
} }
pub fn handle_play_packet(&mut self, server: &mut Server, packet: &mut RawPacket) {
let bytebuf = &mut packet.bytebuf;
match packet.id {
SConfirmTeleport::PACKET_ID => {
self.handle_confirm_teleport(server, SConfirmTeleport::read(bytebuf))
}
_ => log::error!("Failed to handle player packet id {}", packet.id),
}
}
// Reads the connection until our buffer of len 4096 is full, then decode // Reads the connection until our buffer of len 4096 is full, then decode
/// Close connection when an error occurs /// Close connection when an error occurs
pub fn poll(&mut self, server: &mut Server, event: &Event) { pub fn poll(&mut self, server: &mut Server, event: &Event) {

View File

@ -2,12 +2,28 @@ use pumpkin_protocol::server::play::SConfirmTeleport;
use crate::{entity::player::Player, server::Server}; use crate::{entity::player::Player, server::Server};
use super::Client;
// implement player packets // implement player packets
pub trait PlayerPacketProcessor { pub trait PlayerPacketProcessor {
fn handle_confirm_teleport(&mut self, server: &mut Server, confirm_teleport: SConfirmTeleport); fn handle_confirm_teleport(&mut self, server: &mut Server, confirm_teleport: SConfirmTeleport);
} }
impl PlayerPacketProcessor for Player { impl PlayerPacketProcessor for Client {
fn handle_confirm_teleport(&mut self, server: &mut Server, confirm_teleport: SConfirmTeleport) { fn handle_confirm_teleport(
&mut self,
_server: &mut Server,
confirm_teleport: SConfirmTeleport,
) {
let player = self.player.as_mut().unwrap();
if let Some(id) = player.awaiting_teleport {
if id == confirm_teleport.teleport_id {
} else {
log::warn!("Teleport id does not match, Weird but okay");
}
player.awaiting_teleport = None;
} else {
self.kick("Send Teleport confirm, but we did not teleport")
}
} }
} }

View File

@ -62,13 +62,10 @@ impl AdvancedConfiguration {
pub fn load<P: AsRef<Path>>(path: P) -> AdvancedConfiguration { pub fn load<P: AsRef<Path>>(path: P) -> AdvancedConfiguration {
if path.as_ref().exists() { if path.as_ref().exists() {
let toml = std::fs::read_to_string(path).expect("Couldn't read configuration"); let toml = std::fs::read_to_string(path).expect("Couldn't read configuration");
let configuration: AdvancedConfiguration = toml::from_str(toml.as_str()).expect("Couldn't parse")
toml::from_str(toml.as_str()).expect("Couldn't parse");
configuration
} else { } else {
let config = AdvancedConfiguration::default(); let config = AdvancedConfiguration::default();
let toml = toml::to_string(&config).expect("Couldn't create toml!"); let toml = toml::to_string(&config).expect("Couldn't create toml!");
std::fs::write(path, toml).expect("Couldn't save configuration"); std::fs::write(path, toml).expect("Couldn't save configuration");
config config
} }
@ -79,13 +76,10 @@ impl BasicConfiguration {
pub fn load<P: AsRef<Path>>(path: P) -> BasicConfiguration { pub fn load<P: AsRef<Path>>(path: P) -> BasicConfiguration {
if path.as_ref().exists() { if path.as_ref().exists() {
let toml = std::fs::read_to_string(path).expect("Couldn't read configuration"); let toml = std::fs::read_to_string(path).expect("Couldn't read configuration");
let configuration: BasicConfiguration = toml::from_str(toml.as_str()).expect("Couldn't parse")
toml::from_str(toml.as_str()).expect("Couldn't parse");
configuration
} else { } else {
let config = BasicConfiguration::default(); let config = BasicConfiguration::default();
let toml = toml::to_string(&config).expect("Couldn't create toml!"); let toml = toml::to_string(&config).expect("Couldn't create toml!");
std::fs::write(path, toml).expect("Couldn't save configuration"); std::fs::write(path, toml).expect("Couldn't save configuration");
config config
} }

View File

@ -1,31 +1,25 @@
use pumpkin_protocol::{server::play::SConfirmTeleport, RawPacket, ServerPacket, VarInt}; use pumpkin_protocol::VarInt;
use crate::{client::player_packet::PlayerPacketProcessor, server::Server};
use super::{Entity, EntityId}; use super::{Entity, EntityId};
pub struct Player { pub struct Player {
pub entity: Entity, pub entity: Entity,
// Current awaiting teleport id, None if did not teleport
pub awaiting_teleport: Option<VarInt>,
} }
impl Player { impl Player {
pub fn new(entity: Entity) -> Self { pub fn new(entity: Entity) -> Self {
Self { entity } Self {
entity,
awaiting_teleport: None,
}
} }
pub fn entity_id(&self) -> EntityId { pub fn entity_id(&self) -> EntityId {
self.entity.entity_id self.entity.entity_id
} }
pub fn handle_packet(&mut self, server: &mut Server, packet: &mut RawPacket) {
let bytebuf = &mut packet.bytebuf;
match packet.id {
SConfirmTeleport::PACKET_ID => {
self.handle_confirm_teleport(server, SConfirmTeleport::read(bytebuf))
}
_ => log::error!("Failed to handle Player packet, id {}", packet.id),
}
}
} }
pub enum Hand { pub enum Hand {

View File

@ -14,7 +14,6 @@ pub mod configuration;
pub mod entity; pub mod entity;
pub mod server; pub mod server;
pub mod util; pub mod util;
pub mod world;
#[cfg(not(target_os = "wasi"))] #[cfg(not(target_os = "wasi"))]
fn main() -> io::Result<()> { fn main() -> io::Result<()> {

View File

@ -1,174 +0,0 @@
use crate::{
entity::player::GameMode,
protocol::{bytebuf::ByteBuffer, ClientPacket, VarInt},
};
pub struct SetHeldItem {
slot: i8,
}
impl SetHeldItem {
pub fn new(slot: i8) -> Self {
Self { slot }
}
}
impl ClientPacket for SetHeldItem {
const PACKET_ID: VarInt = 0x53;
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i8(self.slot);
}
}
pub struct CPlayerAbilities {
flags: i8,
flying_speed: f32,
field_of_view: f32,
}
impl CPlayerAbilities {
pub fn new(flags: i8, flying_speed: f32, field_of_view: f32) -> Self {
Self {
flags,
flying_speed,
field_of_view,
}
}
}
impl ClientPacket for CPlayerAbilities {
const PACKET_ID: VarInt = 0x38;
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i8(self.flags);
bytebuf.put_f32(self.flying_speed);
bytebuf.put_f32(self.field_of_view);
}
}
pub struct CChangeDifficulty {
difficulty: u8,
locked: bool,
}
impl CChangeDifficulty {
pub fn new(difficulty: u8, locked: bool) -> Self {
Self { difficulty, locked }
}
}
impl ClientPacket for CChangeDifficulty {
const PACKET_ID: VarInt = 0x0B;
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_u8(self.difficulty);
bytebuf.put_bool(self.locked);
}
}
pub struct CLogin {
entity_id: i32,
is_hardcore: bool,
dimension_count: VarInt,
dimension_names: Vec<String>,
max_players: VarInt,
view_distance: VarInt,
simulated_distance: VarInt,
reduced_debug_info: bool,
enabled_respawn_screen: bool,
limited_crafting: bool,
dimension_type: VarInt,
dimension_name: String,
hashed_seed: i64,
game_mode: GameMode,
previous_gamemode: GameMode,
debug: bool,
is_flat: bool,
has_death_loc: bool,
death_dimension_name: Option<String>,
death_loc: Option<String>, // POSITION NOT STRING
portal_cooldown: VarInt,
enforce_secure_chat: bool,
}
impl CLogin {
#[allow(clippy::too_many_arguments)]
pub fn new(
entity_id: i32,
is_hardcore: bool,
dimension_count: VarInt,
dimension_names: Vec<String>,
max_players: VarInt,
view_distance: VarInt,
simulated_distance: VarInt,
reduced_debug_info: bool,
enabled_respawn_screen: bool,
limited_crafting: bool,
dimension_type: VarInt,
dimension_name: String,
hashed_seed: i64,
game_mode: GameMode,
previous_gamemode: GameMode,
debug: bool,
is_flat: bool,
has_death_loc: bool,
death_dimension_name: Option<String>,
death_loc: Option<String>,
portal_cooldown: VarInt,
enforce_secure_chat: bool,
) -> Self {
Self {
entity_id,
is_hardcore,
dimension_count,
dimension_names,
max_players,
view_distance,
simulated_distance,
reduced_debug_info,
enabled_respawn_screen,
limited_crafting,
dimension_type,
dimension_name,
hashed_seed,
game_mode,
previous_gamemode,
debug,
is_flat,
has_death_loc,
death_dimension_name,
death_loc,
portal_cooldown,
enforce_secure_chat,
}
}
}
impl ClientPacket for CLogin {
const PACKET_ID: VarInt = 0x2B;
fn write(&self, bytebuf: &mut ByteBuffer) {
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_var_int(self.max_players);
bytebuf.put_var_int(self.view_distance);
bytebuf.put_var_int(self.simulated_distance);
bytebuf.put_bool(self.reduced_debug_info);
bytebuf.put_bool(self.enabled_respawn_screen);
bytebuf.put_bool(self.limited_crafting);
bytebuf.put_var_int(self.dimension_type);
bytebuf.put_string(&self.dimension_name);
bytebuf.put_i64(self.hashed_seed);
bytebuf.put_u8(self.game_mode.to_byte() as u8);
bytebuf.put_i8(self.previous_gamemode.to_byte());
bytebuf.put_bool(self.debug);
bytebuf.put_bool(self.is_flat);
bytebuf.put_bool(self.has_death_loc);
bytebuf.put_option(&self.death_dimension_name, |buf, v| buf.put_string(v));
bytebuf.put_option(&self.death_loc, |buf, v| buf.put_string(v));
bytebuf.put_var_int(self.portal_cooldown);
bytebuf.put_bool(self.enforce_secure_chat);
}
}

View File

@ -1,5 +1,6 @@
use std::{ use std::{
io::Cursor, io::Cursor,
rc::Rc,
sync::atomic::{AtomicI32, Ordering}, sync::atomic::{AtomicI32, Ordering},
}; };
@ -8,9 +9,13 @@ use mio::{event::Event, Poll};
use pumpkin_protocol::{ use pumpkin_protocol::{
client::{ client::{
config::CPluginMessage, config::CPluginMessage,
play::{CGameEvent, CLogin, CSyncPlayerPostion}, play::{CChunkDataUpdateLight, CGameEvent, CLogin, CSyncPlayerPostion, SkyLight},
}, },
PacketError, Players, Sample, StatusResponse, VarInt, VarInt32, Version, BitSet, PacketError, Players, Sample, StatusResponse, VarInt, VarInt32, Version,
};
use pumpkin_world::{
chunk::{TestChunk, SKY_LIGHT_ARRAYS},
World,
}; };
use rsa::{rand_core::OsRng, traits::PublicKeyParts, RsaPrivateKey, RsaPublicKey}; use rsa::{rand_core::OsRng, traits::PublicKeyParts, RsaPrivateKey, RsaPublicKey};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -22,7 +27,6 @@ use crate::{
player::{GameMode, Player}, player::{GameMode, Player},
Entity, EntityId, Entity, EntityId,
}, },
world::World,
}; };
pub struct Server { pub struct Server {
@ -37,8 +41,7 @@ pub struct Server {
/// the maximum amount of players that can join the Server /// the maximum amount of players that can join the Server
pub max_players: u32, pub max_players: u32,
pub world: World, // pub world: World,
pub status_response: StatusResponse, pub status_response: StatusResponse,
// We cache the json response here so we don't parse it every time someone makes a Status request. // We cache the json response here so we don't parse it every time someone makes a Status request.
// Keep in mind that we must parse this again, when the StatusResponse changes which usally happen when a player joins or leaves // Keep in mind that we must parse this again, when the StatusResponse changes which usally happen when a player joins or leaves
@ -72,7 +75,7 @@ impl Server {
Self { Self {
// 0 is invalid // 0 is invalid
entity_id: 2.into(), entity_id: 2.into(),
world: World::new(), // world: World::load(""),
online_mode: config.0.online_mode, online_mode: config.0.online_mode,
encryption: config.1.encryption, encryption: config.1.encryption,
compression_threshold: None, // 256 compression_threshold: None, // 256
@ -96,11 +99,9 @@ impl Server {
// todo: do this in a world // todo: do this in a world
pub fn spawn_player(&mut self, client: &mut Client) { pub fn spawn_player(&mut self, client: &mut Client) {
dbg!("spawning player"); dbg!("spawning player");
let player = Player { let player = Player::new(Entity {
entity: Entity {
entity_id: self.new_entity_id(), entity_id: self.new_entity_id(),
}, });
};
client client
.send_packet(CLogin::new( .send_packet(CLogin::new(
@ -137,11 +138,29 @@ impl Server {
.send_packet(CGameEvent::new(13, 0.0)) .send_packet(CGameEvent::new(13, 0.0))
.unwrap_or_else(|e| client.kick(&e.to_string())); .unwrap_or_else(|e| client.kick(&e.to_string()));
Server::spawn_test_chunk(client);
client.player = Some(player); client.player = Some(player);
} }
// todo: do this in a world // todo: do this in a world
fn spawn_test_chunk(client: &Client) {} fn spawn_test_chunk(client: &mut Client) {
let test_chunk = TestChunk::new();
client
.send_packet(CChunkDataUpdateLight::new(
10,
10,
test_chunk.heightmap,
Vec::new(),
Vec::new(),
BitSet(0, Vec::new()),
BitSet(0, Vec::new()),
BitSet(0, Vec::new()),
Vec::new(),
Vec::new(),
))
.unwrap_or_else(|e| client.kick(&e.to_string()))
}
// move to world // move to world
pub fn new_entity_id(&self) -> EntityId { pub fn new_entity_id(&self) -> EntityId {

View File

@ -1,19 +0,0 @@
use crate::entity::player::Player;
pub struct World {
pub players: Vec<Player>,
}
impl Default for World {
fn default() -> Self {
Self::new()
}
}
impl World {
pub fn new() -> Self {
Self {
players: Vec::new(),
}
}
}