reorganize into different crates
Should help to get a more clear view and simplify things
This commit is contained in:
parent
5a1d333f02
commit
fd9344a512
32
Cargo.lock
generated
32
Cargo.lock
generated
@ -521,17 +521,14 @@ dependencies = [
|
||||
name = "pumpkin"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"base64",
|
||||
"bytes",
|
||||
"cfb8",
|
||||
"crossbeam-channel",
|
||||
"fastnbt",
|
||||
"fastsnbt",
|
||||
"flate2",
|
||||
"image",
|
||||
"log",
|
||||
"mio",
|
||||
"pumpkin-protocol",
|
||||
"pumpkin-registry",
|
||||
"rand",
|
||||
"rsa",
|
||||
"rsa-der",
|
||||
@ -543,6 +540,31 @@ dependencies = [
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pumpkin-protocol"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"bytes",
|
||||
"cfb8",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pumpkin-registry"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"fastnbt",
|
||||
"fastsnbt",
|
||||
"pumpkin-protocol",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"pumpkin/"]
|
||||
members = [ "pumpkin-protocol/", "pumpkin-registry/", "pumpkin/"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.1.0"
|
||||
|
||||
20
pumpkin-protocol/Cargo.toml
Normal file
20
pumpkin-protocol/Cargo.toml
Normal file
@ -0,0 +1,20 @@
|
||||
[package]
|
||||
name = "pumpkin-protocol"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
bytes = "1.7"
|
||||
|
||||
uuid = "1.10"
|
||||
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
# to parse strings to json responses
|
||||
serde_json = "1.0"
|
||||
|
||||
thiserror = "1.0.63"
|
||||
log = "0.4"
|
||||
|
||||
# encryption
|
||||
aes = "0.8.4"
|
||||
cfb8 = "0.8.1"
|
||||
32
pumpkin-protocol/README.md
Normal file
32
pumpkin-protocol/README.md
Normal file
@ -0,0 +1,32 @@
|
||||
### Pumpkin Protocol
|
||||
Contains all Serverbound(Client->Server) and Clientbound(Server->Client) Packets.
|
||||
The packets are sorted by their folder architecture you find:
|
||||
|
||||
Serverbound Packets under:
|
||||
`server`
|
||||
Clientbound Packets under:
|
||||
`client`
|
||||
Than they both have folders for packets for all their diffrent states:
|
||||
|
||||
### States:
|
||||
**Handshake**: Always the first packet being send from the Client. This begins also determins the next state, usally to indicate if the player thans perform a Status Request, Join the Server or wants to be transfered.
|
||||
|
||||
**Status**: Indicates the Client wants to see a Status response (MOTD).
|
||||
|
||||
**Login**: The Login sequence. Indicates the Client wants to join to the Server
|
||||
|
||||
**Config**: A sequence of Configuration packets beining mostly send from the Server to the Client. (Features, Resource Pack, Server Links...)
|
||||
|
||||
**Play**: The final state which indicate the Player is now ready to Join in also used to handle all other Gameplay packets.
|
||||
|
||||
### How to add a Packet ?
|
||||
You can find all Minecraft Java packets at https://wiki.vg/Protocol. There you also can see in which [State](State) they are.
|
||||
You also can see all the information the Packets has which we can either Write or Read depending if its Serverbound or Clientbound
|
||||
#### Adding a Serverbound Packet
|
||||
Serverbound Packets do use the trait `ServerPacket` which has an packet id (use hex) and can read incoming Client packets.
|
||||
https://wiki.vg/Protocol gives you the Packet structure which you can than read. Feel free to orientate on already existing Packets.
|
||||
Please use a name structure like `SPacketName` for the struct, The 'S' representing its Serverbound
|
||||
#### Adding a Clientbound Packet
|
||||
Clientbound Packets do use the trait `ClientPacket` which has an packet id (use hex) and can write outgoining Server packets.
|
||||
https://wiki.vg/Protocol gives you the Packet structure which you can than write. Feel free to orientate on already existing Packets.
|
||||
Please use a name structure like `CPacketName` for the struct, The 'C' representing its Clientbound
|
||||
@ -3,7 +3,7 @@ use std::io::{self, Error, ErrorKind};
|
||||
|
||||
use bytes::{Buf, BufMut, BytesMut};
|
||||
|
||||
use crate::protocol::{VarInt, VarLong};
|
||||
use crate::{VarInt, VarLong};
|
||||
|
||||
const SEGMENT_BITS: u8 = 0x7F;
|
||||
const CONTINUE_BIT: u8 = 0x80;
|
||||
@ -1,11 +1,11 @@
|
||||
use crate::protocol::{bytebuf::ByteBuffer, ClientPacket, KnownPack, VarInt};
|
||||
use crate::{bytebuf::ByteBuffer, ClientPacket, KnownPack, VarInt};
|
||||
|
||||
pub struct CCookieRequest {
|
||||
// TODO
|
||||
}
|
||||
|
||||
impl ClientPacket for CCookieRequest {
|
||||
const PACKET_ID: crate::protocol::VarInt = 0x00;
|
||||
const PACKET_ID: VarInt = 0x00;
|
||||
|
||||
fn write(&self, bytebuf: &mut ByteBuffer) {}
|
||||
}
|
||||
@ -41,7 +41,7 @@ impl<'a> CConfigDisconnect<'a> {
|
||||
}
|
||||
|
||||
impl<'a> ClientPacket for CConfigDisconnect<'a> {
|
||||
const PACKET_ID: crate::protocol::VarInt = 0x02;
|
||||
const PACKET_ID: VarInt = 0x02;
|
||||
|
||||
fn write(&self, bytebuf: &mut ByteBuffer) {
|
||||
bytebuf.put_string(self.reason);
|
||||
@ -63,7 +63,7 @@ impl CFinishConfig {
|
||||
}
|
||||
|
||||
impl ClientPacket for CFinishConfig {
|
||||
const PACKET_ID: crate::protocol::VarInt = 0x03;
|
||||
const PACKET_ID: VarInt = 0x03;
|
||||
|
||||
fn write(&self, _bytebuf: &mut ByteBuffer) {}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::protocol::{bytebuf::ByteBuffer, ClientPacket, VarInt};
|
||||
use crate::{bytebuf::ByteBuffer, ClientPacket, VarInt};
|
||||
|
||||
pub struct CLoginDisconnect<'a> {
|
||||
reason: &'a str,
|
||||
@ -1,7 +1,4 @@
|
||||
use crate::{
|
||||
entity::player::GameMode,
|
||||
protocol::{bytebuf::ByteBuffer, ClientPacket, VarInt},
|
||||
};
|
||||
use crate::{bytebuf::ByteBuffer, ClientPacket, VarInt};
|
||||
|
||||
pub struct SetHeldItem {
|
||||
slot: i8,
|
||||
@ -80,8 +77,8 @@ pub struct CLogin {
|
||||
dimension_type: VarInt,
|
||||
dimension_name: String,
|
||||
hashed_seed: i64,
|
||||
game_mode: GameMode,
|
||||
previous_gamemode: GameMode,
|
||||
game_mode: u8,
|
||||
previous_gamemode: i8,
|
||||
debug: bool,
|
||||
is_flat: bool,
|
||||
has_death_loc: bool,
|
||||
@ -107,8 +104,8 @@ impl CLogin {
|
||||
dimension_type: VarInt,
|
||||
dimension_name: String,
|
||||
hashed_seed: i64,
|
||||
game_mode: GameMode,
|
||||
previous_gamemode: GameMode,
|
||||
game_mode: u8,
|
||||
previous_gamemode: i8,
|
||||
debug: bool,
|
||||
is_flat: bool,
|
||||
has_death_loc: bool,
|
||||
@ -161,8 +158,8 @@ impl ClientPacket for CLogin {
|
||||
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_u8(self.game_mode);
|
||||
bytebuf.put_i8(self.previous_gamemode);
|
||||
bytebuf.put_bool(self.debug);
|
||||
bytebuf.put_bool(self.is_flat);
|
||||
bytebuf.put_bool(self.has_death_loc);
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::protocol::{bytebuf::ByteBuffer, ClientPacket, VarInt};
|
||||
use crate::{bytebuf::ByteBuffer, ClientPacket, VarInt};
|
||||
|
||||
pub struct CPingResponse {
|
||||
payload: i64, // must responde with the same as in `SPingRequest`
|
||||
@ -6,12 +6,16 @@ use serde::Serialize;
|
||||
use thiserror::Error;
|
||||
|
||||
pub mod bytebuf;
|
||||
pub mod registry;
|
||||
|
||||
pub mod client;
|
||||
pub mod server;
|
||||
|
||||
pub mod packet_decoder;
|
||||
pub mod packet_encoder;
|
||||
|
||||
pub const MAX_PACKET_SIZE: i32 = 2097152;
|
||||
|
||||
pub type VarInt = i32;
|
||||
pub type VarLong = i64;
|
||||
|
||||
pub struct VarInt32(pub i32);
|
||||
|
||||
@ -87,7 +91,23 @@ pub enum VarIntDecodeError {
|
||||
TooLarge,
|
||||
}
|
||||
|
||||
pub type VarLong = i64;
|
||||
#[derive(Error, Debug)]
|
||||
pub enum PacketError {
|
||||
#[error("failed to decode packet ID")]
|
||||
DecodeID,
|
||||
#[error("failed to encode packet ID")]
|
||||
EncodeID,
|
||||
#[error("failed to write encoded packet")]
|
||||
EncodeFailedWrite,
|
||||
#[error("failed to write encoded packet to connection")]
|
||||
ConnectionWrite,
|
||||
#[error("packet exceeds maximum length")]
|
||||
TooLong,
|
||||
#[error("packet length is out of bounds")]
|
||||
OutOfBounds,
|
||||
#[error("malformed packet length VarInt")]
|
||||
MailformedLength,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ConnectionState {
|
||||
@ -125,6 +145,12 @@ pub trait ClientPacket {
|
||||
fn write(&self, bytebuf: &mut ByteBuffer);
|
||||
}
|
||||
|
||||
pub trait ServerPacket {
|
||||
const PACKET_ID: VarInt;
|
||||
|
||||
fn read(bytebuf: &mut ByteBuffer) -> Self;
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct StatusResponse {
|
||||
pub version: Version,
|
||||
@ -2,8 +2,7 @@ use aes::cipher::{generic_array::GenericArray, BlockDecryptMut, BlockSizeUser, K
|
||||
use bytes::{Buf, BytesMut};
|
||||
|
||||
use crate::{
|
||||
client::{PacketError, MAX_PACKET_SIZE},
|
||||
protocol::{bytebuf::ByteBuffer, RawPacket, VarInt32, VarIntDecodeError},
|
||||
bytebuf::ByteBuffer, PacketError, RawPacket, VarInt32, VarIntDecodeError, MAX_PACKET_SIZE,
|
||||
};
|
||||
|
||||
type Cipher = cfb8::Decryptor<aes::Aes128>;
|
||||
@ -4,12 +4,10 @@ use aes::cipher::{generic_array::GenericArray, BlockEncryptMut, BlockSizeUser, K
|
||||
use bytes::{BufMut, BytesMut};
|
||||
|
||||
use crate::{
|
||||
client::MAX_PACKET_SIZE,
|
||||
protocol::{bytebuf::ByteBuffer, ClientPacket, VarInt32},
|
||||
bytebuf::ByteBuffer, ClientPacket, PacketError, VarInt32,
|
||||
MAX_PACKET_SIZE,
|
||||
};
|
||||
|
||||
use super::PacketError;
|
||||
|
||||
type Cipher = cfb8::Encryptor<aes::Aes128>;
|
||||
|
||||
// Encoder: Server -> Client
|
||||
@ -1,30 +1,27 @@
|
||||
use crate::{
|
||||
entity::player::{ChatMode, Hand},
|
||||
protocol::{bytebuf::ByteBuffer, VarInt},
|
||||
};
|
||||
use crate::{bytebuf::ByteBuffer, ServerPacket, VarInt};
|
||||
|
||||
pub struct SClientInformation {
|
||||
pub locale: String, // 16
|
||||
pub view_distance: i8,
|
||||
pub chat_mode: ChatMode, // Varint
|
||||
pub chat_mode: VarInt, // Varint
|
||||
pub chat_colors: bool,
|
||||
pub skin_parts: u8,
|
||||
pub main_hand: Hand,
|
||||
pub main_hand: VarInt,
|
||||
pub text_filtering: bool,
|
||||
pub server_listing: bool,
|
||||
}
|
||||
|
||||
impl SClientInformation {
|
||||
pub const PACKET_ID: VarInt = 0x00;
|
||||
impl ServerPacket for SClientInformation {
|
||||
const PACKET_ID: VarInt = 0x00;
|
||||
|
||||
pub fn read(bytebuf: &mut ByteBuffer) -> Self {
|
||||
fn read(bytebuf: &mut ByteBuffer) -> Self {
|
||||
Self {
|
||||
locale: bytebuf.get_string_len(16).unwrap(),
|
||||
view_distance: bytebuf.get_i8(),
|
||||
chat_mode: ChatMode::from_varint(bytebuf.get_var_int()),
|
||||
chat_mode: bytebuf.get_var_int(),
|
||||
chat_colors: bytebuf.get_bool(),
|
||||
skin_parts: bytebuf.get_u8(),
|
||||
main_hand: Hand::from_varint(bytebuf.get_var_int()),
|
||||
main_hand: bytebuf.get_var_int(),
|
||||
text_filtering: bytebuf.get_bool(),
|
||||
server_listing: bytebuf.get_bool(),
|
||||
}
|
||||
@ -33,10 +30,10 @@ impl SClientInformation {
|
||||
|
||||
pub struct SAcknowledgeFinishConfig {}
|
||||
|
||||
impl SAcknowledgeFinishConfig {
|
||||
pub const PACKET_ID: VarInt = 0x03;
|
||||
impl ServerPacket for SAcknowledgeFinishConfig {
|
||||
const PACKET_ID: VarInt = 0x03;
|
||||
|
||||
pub fn read(_bytebuf: &mut ByteBuffer) -> Self {
|
||||
fn read(_bytebuf: &mut ByteBuffer) -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
@ -46,10 +43,10 @@ pub struct SKnownPacks {
|
||||
// known_packs: &'a [KnownPack]
|
||||
}
|
||||
|
||||
impl SKnownPacks {
|
||||
pub const PACKET_ID: VarInt = 0x07;
|
||||
impl ServerPacket for SKnownPacks {
|
||||
const PACKET_ID: VarInt = 0x07;
|
||||
|
||||
pub fn read(bytebuf: &mut ByteBuffer) -> Self {
|
||||
fn read(bytebuf: &mut ByteBuffer) -> Self {
|
||||
Self {
|
||||
known_pack_count: bytebuf.get_var_int(),
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::protocol::{bytebuf::ByteBuffer, ConnectionState, VarInt};
|
||||
use crate::{bytebuf::ByteBuffer, ConnectionState, ServerPacket, VarInt};
|
||||
|
||||
pub struct SHandShake {
|
||||
pub protocol_version: VarInt,
|
||||
@ -7,10 +7,10 @@ pub struct SHandShake {
|
||||
pub next_state: ConnectionState,
|
||||
}
|
||||
|
||||
impl SHandShake {
|
||||
pub const PACKET_ID: VarInt = 0x00;
|
||||
impl ServerPacket for SHandShake {
|
||||
const PACKET_ID: VarInt = 0x00;
|
||||
|
||||
pub fn read(bytebuf: &mut ByteBuffer) -> Self {
|
||||
fn read(bytebuf: &mut ByteBuffer) -> Self {
|
||||
Self {
|
||||
protocol_version: bytebuf.get_var_int(),
|
||||
server_address: bytebuf.get_string_len(255).unwrap(),
|
||||
@ -1,14 +1,14 @@
|
||||
use crate::protocol::{bytebuf::ByteBuffer, VarInt};
|
||||
use crate::{bytebuf::ByteBuffer, ServerPacket, VarInt};
|
||||
|
||||
pub struct SLoginStart {
|
||||
pub name: String, // 16
|
||||
pub uuid: uuid::Uuid,
|
||||
}
|
||||
|
||||
impl SLoginStart {
|
||||
pub const PACKET_ID: VarInt = 0x00;
|
||||
impl ServerPacket for SLoginStart {
|
||||
const PACKET_ID: VarInt = 0x00;
|
||||
|
||||
pub fn read(bytebuf: &mut ByteBuffer) -> Self {
|
||||
fn read(bytebuf: &mut ByteBuffer) -> Self {
|
||||
Self {
|
||||
name: bytebuf.get_string_len(16).unwrap(),
|
||||
uuid: bytebuf.get_uuid(),
|
||||
@ -23,10 +23,10 @@ pub struct SEncryptionResponse {
|
||||
pub verify_token: Vec<u8>,
|
||||
}
|
||||
|
||||
impl SEncryptionResponse {
|
||||
pub const PACKET_ID: VarInt = 0x01;
|
||||
impl ServerPacket for SEncryptionResponse {
|
||||
const PACKET_ID: VarInt = 0x01;
|
||||
|
||||
pub fn read(bytebuf: &mut ByteBuffer) -> Self {
|
||||
fn read(bytebuf: &mut ByteBuffer) -> Self {
|
||||
let shared_secret_length = bytebuf.get_var_int();
|
||||
let shared_secret = bytebuf.copy_to_bytes(shared_secret_length as usize);
|
||||
let verify_token_length = bytebuf.get_var_int();
|
||||
@ -46,10 +46,10 @@ pub struct SLoginPluginResponse<'a> {
|
||||
data: Option<&'a [u8]>,
|
||||
}
|
||||
|
||||
impl<'a> SLoginPluginResponse<'a> {
|
||||
pub const PACKET_ID: VarInt = 0x02;
|
||||
impl<'a> ServerPacket for SLoginPluginResponse<'a> {
|
||||
const PACKET_ID: VarInt = 0x02;
|
||||
|
||||
pub fn read(bytebuf: &mut ByteBuffer) -> Self {
|
||||
fn read(bytebuf: &mut ByteBuffer) -> Self {
|
||||
Self {
|
||||
message_id: bytebuf.get_var_int(),
|
||||
successful: bytebuf.get_bool(),
|
||||
@ -63,10 +63,10 @@ pub struct SLoginAcknowledged {
|
||||
// empty
|
||||
}
|
||||
|
||||
impl SLoginAcknowledged {
|
||||
pub const PACKET_ID: VarInt = 0x03;
|
||||
impl ServerPacket for SLoginAcknowledged {
|
||||
const PACKET_ID: VarInt = 0x03;
|
||||
|
||||
pub fn read(_bytebuf: &mut ByteBuffer) -> Self {
|
||||
fn read(_bytebuf: &mut ByteBuffer) -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
27
pumpkin-protocol/src/server/status/mod.rs
Normal file
27
pumpkin-protocol/src/server/status/mod.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use crate::{bytebuf::ByteBuffer, ServerPacket, VarInt};
|
||||
|
||||
pub struct SStatusRequest {
|
||||
// empty
|
||||
}
|
||||
|
||||
impl ServerPacket for SStatusRequest {
|
||||
const PACKET_ID: VarInt = 0x00;
|
||||
|
||||
fn read(_bytebuf: &mut ByteBuffer) -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SPingRequest {
|
||||
pub payload: i64,
|
||||
}
|
||||
|
||||
impl ServerPacket for SPingRequest {
|
||||
const PACKET_ID: VarInt = 0x01;
|
||||
|
||||
fn read(bytebuf: &mut ByteBuffer) -> Self {
|
||||
Self {
|
||||
payload: bytebuf.get_i64(),
|
||||
}
|
||||
}
|
||||
}
|
||||
13
pumpkin-registry/Cargo.toml
Normal file
13
pumpkin-registry/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "pumpkin-registry"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
pumpkin-protocol = { path = "../pumpkin-protocol"}
|
||||
# nbt
|
||||
fastnbt = { git = "https://github.com/owengage/fastnbt.git" }
|
||||
fastsnbt = "0.2"
|
||||
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
5
pumpkin-registry/README.md
Normal file
5
pumpkin-registry/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
### Pumpkin Registry
|
||||
Here you find all the registry data we have.
|
||||
Registries are repositories of data that contain entries pertaining to certain aspects of the game, such as the world, the player, among others.
|
||||
Registery data usally send by the Clientbound Registery data Packet.
|
||||
A list of Registry entries can be found at https://wiki.vg/Registry_Data
|
||||
@ -1,6 +1,5 @@
|
||||
use crate::protocol::VarInt;
|
||||
|
||||
use super::RegistryValue;
|
||||
use pumpkin_protocol::VarInt;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
@ -1,10 +1,9 @@
|
||||
use dimensions::Dimension;
|
||||
use fastnbt::SerOpts;
|
||||
use pumpkin_protocol::bytebuf::ByteBuffer;
|
||||
use serde::Serialize;
|
||||
use wolf::WolfVariant;
|
||||
|
||||
use super::bytebuf::ByteBuffer;
|
||||
|
||||
mod biomes;
|
||||
mod chat_type;
|
||||
mod damage_type;
|
||||
@ -4,32 +4,36 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
pumpkin-protocol = { path = "../pumpkin-protocol"}
|
||||
pumpkin-registry = { path = "../pumpkin-registry"}
|
||||
|
||||
# config
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
||||
rand = "0.8.5"
|
||||
|
||||
# encryption
|
||||
rsa = "0.9.6"
|
||||
rsa-der = "0.3.0"
|
||||
|
||||
aes = "0.8.4"
|
||||
cfb8 = "0.8.1"
|
||||
flate2 = "1.0.30"
|
||||
bytes = "1.7"
|
||||
|
||||
thiserror = "1.0.63"
|
||||
|
||||
# icon loading
|
||||
base64 = "0.22.1"
|
||||
image = { version = "0.25", default-features = false, features = ["png"]}
|
||||
|
||||
simple_logger = "5.0.0"
|
||||
log = "0.4"
|
||||
|
||||
# networking
|
||||
mio = { version = "1.0.1", features = ["os-poll", "net"]}
|
||||
crossbeam-channel = "0.5.13"
|
||||
|
||||
uuid = "1.10"
|
||||
toml = "0.8.17"
|
||||
fastnbt = { git = "https://github.com/owengage/fastnbt.git" }
|
||||
fastsnbt = "0.2"
|
||||
toml = "0.8.19"
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,19 +1,21 @@
|
||||
use crate::{
|
||||
protocol::{
|
||||
client::{
|
||||
config::{CFinishConfig, CKnownPacks, CRegistryData, Entry},
|
||||
login::{CEncryptionRequest, CLoginSuccess},
|
||||
status::{CPingResponse, CStatusResponse},
|
||||
},
|
||||
registry::{DimensionCodec, WolfCodec},
|
||||
server::{
|
||||
config::{SAcknowledgeFinishConfig, SClientInformation, SKnownPacks},
|
||||
handshake::SHandShake,
|
||||
login::{SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart},
|
||||
status::{SPingRequest, SStatusRequest},
|
||||
},
|
||||
ConnectionState, KnownPack,
|
||||
use pumpkin_protocol::{
|
||||
client::{
|
||||
config::{CFinishConfig, CKnownPacks, CRegistryData, Entry},
|
||||
login::{CEncryptionRequest, CLoginSuccess},
|
||||
status::{CPingResponse, CStatusResponse},
|
||||
},
|
||||
server::{
|
||||
config::{SAcknowledgeFinishConfig, SClientInformation, SKnownPacks},
|
||||
handshake::SHandShake,
|
||||
login::{SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart},
|
||||
status::{SPingRequest, SStatusRequest},
|
||||
},
|
||||
ConnectionState, KnownPack,
|
||||
};
|
||||
use pumpkin_registry::{DimensionCodec, WolfCodec};
|
||||
|
||||
use crate::{
|
||||
entity::player::{ChatMode, Hand},
|
||||
server::Server,
|
||||
};
|
||||
|
||||
@ -150,10 +152,10 @@ impl ClientPacketProcessor for Client {
|
||||
self.config = Some(PlayerConfig {
|
||||
locale: client_information.locale,
|
||||
view_distance: client_information.view_distance,
|
||||
chat_mode: client_information.chat_mode,
|
||||
chat_mode: ChatMode::from_varint(client_information.chat_mode),
|
||||
chat_colors: client_information.chat_colors,
|
||||
skin_parts: client_information.skin_parts,
|
||||
main_hand: client_information.main_hand,
|
||||
main_hand: Hand::from_varint(client_information.main_hand),
|
||||
text_filtering: client_information.text_filtering,
|
||||
server_listing: client_information.server_listing,
|
||||
});
|
||||
|
||||
@ -6,23 +6,23 @@ use std::{
|
||||
|
||||
use crate::{
|
||||
entity::player::{ChatMode, Hand, Player},
|
||||
protocol::{
|
||||
client::{config::CConfigDisconnect, login::CLoginDisconnect},
|
||||
server::{
|
||||
config::{SAcknowledgeFinishConfig, SClientInformation, SKnownPacks},
|
||||
handshake::SHandShake,
|
||||
login::{SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart},
|
||||
status::{SPingRequest, SStatusRequest},
|
||||
},
|
||||
ClientPacket, RawPacket,
|
||||
},
|
||||
server::Server,
|
||||
};
|
||||
|
||||
use crate::protocol::ConnectionState;
|
||||
use mio::{event::Event, net::TcpStream, Token};
|
||||
use packet_decoder::PacketDecoder;
|
||||
use packet_encoder::PacketEncoder;
|
||||
use pumpkin_protocol::{
|
||||
client::{config::CConfigDisconnect, login::CLoginDisconnect},
|
||||
packet_decoder::PacketDecoder,
|
||||
packet_encoder::PacketEncoder,
|
||||
server::{
|
||||
config::{SAcknowledgeFinishConfig, SClientInformation, SKnownPacks},
|
||||
handshake::SHandShake,
|
||||
login::{SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart},
|
||||
status::{SPingRequest, SStatusRequest},
|
||||
},
|
||||
ClientPacket, ConnectionState, PacketError, RawPacket, ServerPacket,
|
||||
};
|
||||
|
||||
use rsa::Pkcs1v15Encrypt;
|
||||
use std::io::Read;
|
||||
use thiserror::Error;
|
||||
@ -30,13 +30,8 @@ use thiserror::Error;
|
||||
mod client_packet;
|
||||
mod player_packet;
|
||||
|
||||
mod packet_decoder;
|
||||
mod packet_encoder;
|
||||
|
||||
use client_packet::ClientPacketProcessor;
|
||||
|
||||
pub const MAX_PACKET_SIZE: i32 = 2097152;
|
||||
|
||||
pub struct PlayerConfig {
|
||||
locale: String, // 16
|
||||
view_distance: i8,
|
||||
@ -133,14 +128,14 @@ impl Client {
|
||||
dbg!("Handling packet");
|
||||
let bytebuf = &mut packet.bytebuf;
|
||||
match self.connection_state {
|
||||
crate::protocol::ConnectionState::HandShake => match packet.id {
|
||||
pumpkin_protocol::ConnectionState::HandShake => match packet.id {
|
||||
SHandShake::PACKET_ID => self.handle_handshake(server, SHandShake::read(bytebuf)),
|
||||
_ => log::error!(
|
||||
"Failed to handle packet id {} while in Handshake state",
|
||||
packet.id
|
||||
),
|
||||
},
|
||||
crate::protocol::ConnectionState::Status => match packet.id {
|
||||
pumpkin_protocol::ConnectionState::Status => match packet.id {
|
||||
SStatusRequest::PACKET_ID => {
|
||||
self.handle_status_request(server, SStatusRequest::read(bytebuf))
|
||||
}
|
||||
@ -152,7 +147,7 @@ impl Client {
|
||||
packet.id
|
||||
),
|
||||
},
|
||||
crate::protocol::ConnectionState::Login => match packet.id {
|
||||
pumpkin_protocol::ConnectionState::Login => match packet.id {
|
||||
SLoginStart::PACKET_ID => {
|
||||
self.handle_login_start(server, SLoginStart::read(bytebuf))
|
||||
}
|
||||
@ -170,7 +165,7 @@ impl Client {
|
||||
packet.id
|
||||
),
|
||||
},
|
||||
crate::protocol::ConnectionState::Config => match packet.id {
|
||||
pumpkin_protocol::ConnectionState::Config => match packet.id {
|
||||
SClientInformation::PACKET_ID => {
|
||||
self.handle_client_information(server, SClientInformation::read(bytebuf))
|
||||
}
|
||||
@ -270,24 +265,6 @@ pub enum EncryptionError {
|
||||
SharedWrongLength,
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum PacketError {
|
||||
#[error("failed to decode packet ID")]
|
||||
DecodeID,
|
||||
#[error("failed to encode packet ID")]
|
||||
EncodeID,
|
||||
#[error("failed to write encoded packet")]
|
||||
EncodeFailedWrite,
|
||||
#[error("failed to write encoded packet to connection")]
|
||||
ConnectionWrite,
|
||||
#[error("packet exceeds maximum length")]
|
||||
TooLong,
|
||||
#[error("packet length is out of bounds")]
|
||||
OutOfBounds,
|
||||
#[error("malformed packet length VarInt")]
|
||||
MailformedLength,
|
||||
}
|
||||
|
||||
fn would_block(err: &io::Error) -> bool {
|
||||
err.kind() == io::ErrorKind::WouldBlock
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::protocol::VarInt;
|
||||
use pumpkin_protocol::VarInt;
|
||||
|
||||
use super::{Entity, EntityId};
|
||||
|
||||
|
||||
@ -12,7 +12,6 @@ const SERVER: Token = Token(0);
|
||||
pub mod client;
|
||||
pub mod configuration;
|
||||
pub mod entity;
|
||||
pub mod protocol;
|
||||
pub mod server;
|
||||
pub mod util;
|
||||
pub mod world;
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
use crate::protocol::{bytebuf::ByteBuffer, VarInt};
|
||||
|
||||
pub struct SStatusRequest {
|
||||
// empty
|
||||
}
|
||||
|
||||
impl SStatusRequest {
|
||||
pub const PACKET_ID: VarInt = 0x00;
|
||||
|
||||
pub fn read(_bytebuf: &mut ByteBuffer) -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SPingRequest {
|
||||
pub payload: i64,
|
||||
}
|
||||
|
||||
impl SPingRequest {
|
||||
pub const PACKET_ID: VarInt = 0x01;
|
||||
|
||||
pub fn read(bytebuf: &mut ByteBuffer) -> Self {
|
||||
Self {
|
||||
payload: bytebuf.get_i64(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,20 +5,20 @@ use std::{
|
||||
|
||||
use base64::{engine::general_purpose, Engine};
|
||||
use mio::{event::Event, Poll};
|
||||
use pumpkin_protocol::{
|
||||
client::{config::CPluginMessage, play::CLogin},
|
||||
PacketError, Players, Sample, StatusResponse, VarInt, VarInt32, Version,
|
||||
};
|
||||
use rsa::{rand_core::OsRng, traits::PublicKeyParts, RsaPrivateKey, RsaPublicKey};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
client::{Client, PacketError},
|
||||
client::Client,
|
||||
configuration::{AdvancedConfiguration, BasicConfiguration},
|
||||
entity::{
|
||||
player::{GameMode, Player},
|
||||
Entity, EntityId,
|
||||
},
|
||||
protocol::{
|
||||
client::{config::CPluginMessage, play::CLogin},
|
||||
Players, Sample, StatusResponse, VarInt, VarInt32, Version,
|
||||
},
|
||||
world::World,
|
||||
};
|
||||
|
||||
@ -117,8 +117,8 @@ impl Server {
|
||||
1,
|
||||
"minecraft:overworld".into(),
|
||||
0, // seed
|
||||
GameMode::Survival,
|
||||
GameMode::Undefined,
|
||||
GameMode::Survival.to_byte() as u8,
|
||||
GameMode::Undefined.to_byte(),
|
||||
false,
|
||||
false,
|
||||
false, // deth loc
|
||||
|
||||
Loading…
Reference in New Issue
Block a user