Minior Changes

This commit is contained in:
Snowiiii 2024-11-03 22:36:00 +01:00
parent 1842e8e6b1
commit 8db277f63e
17 changed files with 42 additions and 154 deletions

View File

@ -27,7 +27,7 @@ class Extractor : ModInitializer {
Recipes(), Recipes(),
Particles(), Particles(),
SyncedRegistries(), SyncedRegistries(),
Packet(), Packets(),
Screens(), Screens(),
Items(), Items(),
Blocks(), Blocks(),

View File

@ -12,7 +12,7 @@ import net.minecraft.network.state.*
import net.minecraft.server.MinecraftServer import net.minecraft.server.MinecraftServer
class Packet : Extractor.Extractor { class Packets : Extractor.Extractor {
override fun fileName(): String { override fun fileName(): String {
return "packets.json" return "packets.json"
} }

View File

@ -22,6 +22,7 @@ class Recipes : Extractor.Extractor {
recipeJson.addProperty("name", recipeRaw.id.value.toString()) recipeJson.addProperty("name", recipeRaw.id.value.toString())
val recipe: Recipe<*> = recipeRaw.value() val recipe: Recipe<*> = recipeRaw.value()
recipeJson.addProperty("category", recipe.group)
recipeJson.addProperty("group", recipe.group) recipeJson.addProperty("group", recipe.group)
recipeJson.addProperty("type", recipe.type.toString()) recipeJson.addProperty("type", recipe.type.toString())
val placementArray = JsonArray() val placementArray = JsonArray()

View File

@ -16,7 +16,7 @@ pub use open_container::OpenContainer;
/// https://wiki.vg/Inventory /// https://wiki.vg/Inventory
#[derive(Debug, ToPrimitive, FromPrimitive, Clone, Copy, Eq, PartialEq)] #[derive(Debug, ToPrimitive, FromPrimitive, Clone, Copy, Eq, PartialEq)]
#[repr(u16)] #[repr(u8)]
pub enum WindowType { pub enum WindowType {
// not used // not used
Generic9x1 = screen!("minecraft:generic_9x1"), Generic9x1 = screen!("minecraft:generic_9x1"),

View File

@ -7,9 +7,7 @@ mod packet;
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn client_packet(input: TokenStream, item: TokenStream) -> TokenStream { pub fn client_packet(input: TokenStream, item: TokenStream) -> TokenStream {
let ast: syn::DeriveInput = syn::parse(item.clone()).unwrap(); let ast: syn::DeriveInput = syn::parse(item.clone()).unwrap();
let name = &ast.ident; let name = &ast.ident;
let (impl_generics, ty_generics, _) = ast.generics.split_for_impl(); let (impl_generics, ty_generics, _) = ast.generics.split_for_impl();
let input: proc_macro2::TokenStream = packet::packet_clientbound(input); let input: proc_macro2::TokenStream = packet::packet_clientbound(input);
@ -28,9 +26,7 @@ pub fn client_packet(input: TokenStream, item: TokenStream) -> TokenStream {
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn server_packet(input: TokenStream, item: TokenStream) -> TokenStream { pub fn server_packet(input: TokenStream, item: TokenStream) -> TokenStream {
let ast: syn::DeriveInput = syn::parse(item.clone()).unwrap(); let ast: syn::DeriveInput = syn::parse(item.clone()).unwrap();
let name = &ast.ident; let name = &ast.ident;
let (impl_generics, ty_generics, _) = ast.generics.split_for_impl(); let (impl_generics, ty_generics, _) = ast.generics.split_for_impl();
let input: proc_macro2::TokenStream = packet::packet_serverbound(input); let input: proc_macro2::TokenStream = packet::packet_serverbound(input);

View File

@ -7,10 +7,10 @@ use serde::Deserialize;
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct Screen { pub struct Screen {
name: String, name: String,
id: u16, id: u8,
} }
static SCREENS: LazyLock<HashMap<String, u16>> = LazyLock::new(|| { static SCREENS: LazyLock<HashMap<String, u8>> = LazyLock::new(|| {
serde_json::from_str::<Vec<Screen>>(include_str!("../../assets/screens.json")) serde_json::from_str::<Vec<Screen>>(include_str!("../../assets/screens.json"))
.expect("Could not parse screens.json registry.") .expect("Could not parse screens.json registry.")
.into_iter() .into_iter()

View File

@ -1,80 +0,0 @@
### Pumpkin Protocol
Contains all Serverbound(Client->Server) and Clientbound(Server->Client) Packets.
### Features
- [x] ZLib Compression
- [x] AES/CFB8 Encryiption
Packets in the Pumpkin protocol are organized by functionality and state.
`server`: Contains definitions for serverbound packets.
`client`: Contains definitions for clientbound packets.
### 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 Packet
Adding a Packet is easy. First you have to dereive serde Serialize for Clientbound Packets or Deserialize for Serverbound packets.
```rust
#[derive(Serialize)]
```
Next you have set the packet id using the packet macro
```rust
#[packet(0x1D)]
```
Now you can create the Field. Please start the Packet name with "C" if its Clientbound and with "S" if its Serverbound.
Example:
```rust
pub struct CPlayDisconnect {
reason: TextComponent,
more fields...
}
```
Also don't forgot to impl a new function for Clientbound Packets so we can actaully send then by putting in the values :D
Example:
```rust
impl CPlayDisconnect {
pub fn new(reason: TextComponent) -> Self {
Self { reason }
}
}
```
At the End everything should come together,
Thats a Clientbound Packet
```rust
#[derive(Serialize)]
#[packet(0x1D)]
pub struct CPlayDisconnect {
reason: TextComponent,
}
impl CPlayDisconnect {
pub fn new(reason: TextComponent) -> Self {
Self { reason }
}
}
```
Thats a Serverbound packet
```rust
#[derive(Deserialize)]
#[packet(0x1D)]
pub struct CPlayDisconnect {
reason: TextComponent,
}
```
### Porting
You can compare difference in Protocol on wiki.vg https://wiki.vg/index.php?title=Protocol&action=history
Also change the `CURRENT_MC_PROTOCOL` in `src/lib.rs`

View File

@ -1,5 +0,0 @@
### 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.
Registry data usually send by the Clientbound Registry data Packet.
A list of Registry entries can be found at https://wiki.vg/Registry_Data

View File

@ -1,17 +0,0 @@
### Pumpkin World
Contains everything World related for example
- Loading Chunks (Anvil Format)
- Generating Chunks
- Loading Blocks/Items
### Porting
When updating your Minecraft server to a newer version, you typically need to replace the files in the assets directory to ensure compatibility with the new version's resources.
Thankfully, vanilla Minecraft provides a way to extract these updated assets directly from the server JAR file itself.
1. Download the latest Minecraft server JAR file for the version you want to upgrade to.
2. Run `java -DbundlerMainClass=net.minecraft.data.Main -jar <minecraft_server>.jar --reports`.
3. This command will create a new folder named `reports` in the same directory as the server JAR. This folder contains the updated "assets" directory for the new version.
4. Copy the assets folder from the reports folder and replace the existing assets directory within your server directory.
For details see https://wiki.vg/Data_Generators

View File

@ -3,11 +3,11 @@ use pumpkin_core::math::vector2::Vector2;
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct Cylindrical { pub struct Cylindrical {
pub center: Vector2<i32>, pub center: Vector2<i32>,
pub view_distance: i32, pub view_distance: u8,
} }
impl Cylindrical { impl Cylindrical {
pub fn new(center: Vector2<i32>, view_distance: i32) -> Self { pub fn new(center: Vector2<i32>, view_distance: u8) -> Self {
Self { Self {
center, center,
view_distance, view_distance,
@ -45,19 +45,19 @@ impl Cylindrical {
} }
fn left(&self) -> i32 { fn left(&self) -> i32 {
self.center.x - self.view_distance - 1 self.center.x - self.view_distance as i32 - 1
} }
fn bottom(&self) -> i32 { fn bottom(&self) -> i32 {
self.center.z - self.view_distance - 1 self.center.z - self.view_distance as i32 - 1
} }
fn right(&self) -> i32 { fn right(&self) -> i32 {
self.center.x + self.view_distance + 1 self.center.x + self.view_distance as i32 + 1
} }
fn top(&self) -> i32 { fn top(&self) -> i32 {
self.center.z + self.view_distance + 1 self.center.z + self.view_distance as i32 + 1
} }
fn is_within_distance(&self, x: i32, z: i32) -> bool { fn is_within_distance(&self, x: i32, z: i32) -> bool {

View File

@ -8,10 +8,10 @@ use pumpkin_protocol::{
status::CPingResponse, status::CPingResponse,
}, },
server::{ server::{
config::{SAcknowledgeFinishConfig, SClientInformationConfig, SKnownPacks, SPluginMessage}, config::{SClientInformationConfig, SKnownPacks, SPluginMessage},
handshake::SHandShake, handshake::SHandShake,
login::{SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart}, login::{SEncryptionResponse, SLoginPluginResponse, SLoginStart},
status::{SStatusPingRequest, SStatusRequest}, status::SStatusPingRequest,
}, },
ConnectionState, KnownPack, CURRENT_MC_PROTOCOL, ConnectionState, KnownPack, CURRENT_MC_PROTOCOL,
}; };
@ -55,14 +55,14 @@ impl Client {
} }
} }
pub async fn handle_status_request(&self, server: &Server, _status_request: SStatusRequest) { pub async fn handle_status_request(&self, server: &Server) {
log::debug!("Handling status request for id"); log::debug!("Handling status request");
let status = server.get_status(); let status = server.get_status();
self.send_packet(&status.lock().await.get_status()).await; self.send_packet(&status.lock().await.get_status()).await;
} }
pub async fn handle_ping_request(&self, ping_request: SStatusPingRequest) { pub async fn handle_ping_request(&self, ping_request: SStatusPingRequest) {
log::debug!("Handling ping request for id"); log::debug!("Handling ping request");
self.send_packet(&CPingResponse::new(ping_request.payload)) self.send_packet(&CPingResponse::new(ping_request.payload))
.await; .await;
self.close(); self.close();
@ -147,7 +147,7 @@ impl Client {
server: &Server, server: &Server,
encryption_response: SEncryptionResponse, encryption_response: SEncryptionResponse,
) { ) {
log::debug!("Handling encryption for id"); log::debug!("Handling encryption");
let shared_secret = server.decrypt(&encryption_response.shared_secret).unwrap(); let shared_secret = server.decrypt(&encryption_response.shared_secret).unwrap();
if let Err(error) = self.set_encryption(Some(&shared_secret)).await { if let Err(error) = self.set_encryption(Some(&shared_secret)).await {
@ -254,7 +254,7 @@ impl Client {
} }
pub async fn handle_plugin_response(&self, plugin_response: SLoginPluginResponse) { pub async fn handle_plugin_response(&self, plugin_response: SLoginPluginResponse) {
log::debug!("Handling plugin for id"); log::debug!("Handling plugin");
let velocity_config = &ADVANCED_CONFIG.proxy.velocity; let velocity_config = &ADVANCED_CONFIG.proxy.velocity;
if velocity_config.enabled { if velocity_config.enabled {
let mut address = self.address.lock().await; let mut address = self.address.lock().await;
@ -273,12 +273,8 @@ impl Client {
} }
} }
pub async fn handle_login_acknowledged( pub async fn handle_login_acknowledged(&self, server: &Server) {
&self, log::debug!("Handling login acknowledged");
server: &Server,
_login_acknowledged: SLoginAcknowledged,
) {
log::debug!("Handling login acknowledged for id");
self.connection_state.store(ConnectionState::Config); self.connection_state.store(ConnectionState::Config);
self.send_packet(&server.get_branding()).await; self.send_packet(&server.get_branding()).await;
@ -315,14 +311,14 @@ impl Client {
&self, &self,
client_information: SClientInformationConfig, client_information: SClientInformationConfig,
) { ) {
log::debug!("Handling client settings for id"); log::debug!("Handling client settings");
if let (Some(main_hand), Some(chat_mode)) = ( if let (Some(main_hand), Some(chat_mode)) = (
Hand::from_i32(client_information.main_hand.into()), Hand::from_i32(client_information.main_hand.into()),
ChatMode::from_i32(client_information.chat_mode.into()), ChatMode::from_i32(client_information.chat_mode.into()),
) { ) {
*self.config.lock().await = Some(PlayerConfig { *self.config.lock().await = Some(PlayerConfig {
locale: client_information.locale, locale: client_information.locale,
view_distance: client_information.view_distance, view_distance: client_information.view_distance as u8,
chat_mode, chat_mode,
chat_colors: client_information.chat_colors, chat_colors: client_information.chat_colors,
skin_parts: client_information.skin_parts, skin_parts: client_information.skin_parts,
@ -336,7 +332,7 @@ impl Client {
} }
pub async fn handle_plugin_message(&self, plugin_message: SPluginMessage) { pub async fn handle_plugin_message(&self, plugin_message: SPluginMessage) {
log::debug!("Handling plugin message for id"); log::debug!("Handling plugin message");
if plugin_message.channel.starts_with("minecraft:brand") if plugin_message.channel.starts_with("minecraft:brand")
|| plugin_message.channel.starts_with("MC|Brand") || plugin_message.channel.starts_with("MC|Brand")
{ {
@ -349,7 +345,7 @@ impl Client {
} }
pub async fn handle_known_packs(&self, server: &Server, _config_acknowledged: SKnownPacks) { pub async fn handle_known_packs(&self, server: &Server, _config_acknowledged: SKnownPacks) {
log::debug!("Handling known packs for id"); log::debug!("Handling known packs");
for registry in &server.cached_registry { for registry in &server.cached_registry {
self.send_packet(&CRegistryData::new( self.send_packet(&CRegistryData::new(
&registry.registry_id, &registry.registry_id,
@ -363,8 +359,8 @@ impl Client {
self.send_packet(&CFinishConfig::new()).await; self.send_packet(&CFinishConfig::new()).await;
} }
pub fn handle_config_acknowledged(&self, _config_acknowledged: &SAcknowledgeFinishConfig) { pub fn handle_config_acknowledged(&self) {
log::debug!("Handling config acknowledge for id"); log::debug!("Handling config acknowledge");
self.connection_state.store(ConnectionState::Play); self.connection_state.store(ConnectionState::Play);
self.make_player self.make_player
.store(true, std::sync::atomic::Ordering::Relaxed); .store(true, std::sync::atomic::Ordering::Relaxed);

View File

@ -134,6 +134,7 @@ impl Player {
} }
let click = Click::new( let click = Click::new(
// TODO: This is very bad
packet packet
.mode .mode
.0 .0

View File

@ -52,7 +52,7 @@ pub struct PlayerConfig {
/// The player's preferred language. /// The player's preferred language.
pub locale: String, // 16 pub locale: String, // 16
/// The maximum distance at which chunks are rendered. /// The maximum distance at which chunks are rendered.
pub view_distance: i8, pub view_distance: u8,
/// The player's chat mode settings /// The player's chat mode settings
pub chat_mode: ChatMode, pub chat_mode: ChatMode,
/// Whether chat colors are enabled. /// Whether chat colors are enabled.
@ -392,8 +392,7 @@ impl Client {
let bytebuf = &mut packet.bytebuf; let bytebuf = &mut packet.bytebuf;
match packet.id.0 { match packet.id.0 {
SStatusRequest::PACKET_ID => { SStatusRequest::PACKET_ID => {
self.handle_status_request(server, SStatusRequest::read(bytebuf)?) self.handle_status_request(server).await;
.await;
} }
SStatusPingRequest::PACKET_ID => { SStatusPingRequest::PACKET_ID => {
self.handle_ping_request(SStatusPingRequest::read(bytebuf)?) self.handle_ping_request(SStatusPingRequest::read(bytebuf)?)
@ -432,8 +431,7 @@ impl Client {
.await; .await;
} }
SLoginAcknowledged::PACKET_ID => { SLoginAcknowledged::PACKET_ID => {
self.handle_login_acknowledged(server, SLoginAcknowledged::read(bytebuf)?) self.handle_login_acknowledged(server).await;
.await;
} }
_ => { _ => {
log::error!( log::error!(
@ -463,7 +461,7 @@ impl Client {
.await; .await;
} }
SAcknowledgeFinishConfig::PACKET_ID => { SAcknowledgeFinishConfig::PACKET_ID => {
self.handle_config_acknowledged(&SAcknowledgeFinishConfig::read(bytebuf)?); self.handle_config_acknowledged();
} }
SKnownPacks::PACKET_ID => { SKnownPacks::PACKET_ID => {
self.handle_known_packs(server, SKnownPacks::read(bytebuf)?) self.handle_known_packs(server, SKnownPacks::read(bytebuf)?)

View File

@ -384,7 +384,8 @@ impl Player {
) { ) {
*self.config.lock().await = PlayerConfig { *self.config.lock().await = PlayerConfig {
locale: client_information.locale, locale: client_information.locale,
view_distance: client_information.view_distance, // A Negative view distance would be impossible and make no sense right ?, Mojang: Lets make is signed :D
view_distance: client_information.view_distance as u8,
chat_mode, chat_mode,
chat_colors: client_information.chat_colors, chat_colors: client_information.chat_colors,
skin_parts: client_information.skin_parts, skin_parts: client_information.skin_parts,
@ -398,7 +399,7 @@ impl Player {
} }
} }
pub async fn handle_interact(&self, _: &Server, interact: SInteract) { pub async fn handle_interact(&self, interact: SInteract) {
let sneaking = interact.sneaking; let sneaking = interact.sneaking;
let entity = &self.living_entity.entity; let entity = &self.living_entity.entity;
if entity.sneaking.load(std::sync::atomic::Ordering::Relaxed) != sneaking { if entity.sneaking.load(std::sync::atomic::Ordering::Relaxed) != sneaking {

View File

@ -223,7 +223,7 @@ impl Player {
world.remove_player(self).await; world.remove_player(self).await;
let watched = self.watched_section.load(); let watched = self.watched_section.load();
let view_distance = i32::from(get_view_distance(self).await); let view_distance = get_view_distance(self).await;
let cylindrical = Cylindrical::new(Vector2::new(watched.x, watched.z), view_distance); let cylindrical = Cylindrical::new(Vector2::new(watched.x, watched.z), view_distance);
// NOTE: This all must be synchronous to make sense! The chunks are handled asynhrously. // NOTE: This all must be synchronous to make sense! The chunks are handled asynhrously.
@ -676,8 +676,7 @@ impl Player {
.await; .await;
} }
SInteract::PACKET_ID => { SInteract::PACKET_ID => {
self.handle_interact(server, SInteract::read(bytebuf)?) self.handle_interact(SInteract::read(bytebuf)?).await;
.await;
} }
SKeepAlive::PACKET_ID => { SKeepAlive::PACKET_ID => {
self.handle_keep_alive(SKeepAlive::read(bytebuf)?).await; self.handle_keep_alive(SKeepAlive::read(bytebuf)?).await;

View File

@ -5,8 +5,6 @@
// REMOVE SOME WHEN RELEASE // REMOVE SOME WHEN RELEASE
#![expect(clippy::cargo_common_metadata)] #![expect(clippy::cargo_common_metadata)]
#![expect(clippy::multiple_crate_versions)] #![expect(clippy::multiple_crate_versions)]
#![expect(clippy::significant_drop_in_scrutinee)]
#![expect(clippy::significant_drop_tightening)]
#![expect(clippy::single_call_fn)] #![expect(clippy::single_call_fn)]
#![expect(clippy::cast_sign_loss)] #![expect(clippy::cast_sign_loss)]
#![expect(clippy::cast_possible_truncation)] #![expect(clippy::cast_possible_truncation)]

View File

@ -11,13 +11,13 @@ use crate::entity::player::Player;
use super::World; use super::World;
pub async fn get_view_distance(player: &Player) -> i8 { pub async fn get_view_distance(player: &Player) -> u8 {
player player
.config .config
.lock() .lock()
.await .await
.view_distance .view_distance
.clamp(2, BASIC_CONFIG.view_distance as i8) .clamp(2, BASIC_CONFIG.view_distance)
} }
pub async fn player_join(world: &World, player: Arc<Player>) { pub async fn player_join(world: &World, player: Arc<Player>) {
@ -36,7 +36,7 @@ pub async fn player_join(world: &World, player: Arc<Player>) {
chunk_z: chunk_pos.z.into(), chunk_z: chunk_pos.z.into(),
}) })
.await; .await;
let view_distance = i32::from(get_view_distance(&player).await); let view_distance = get_view_distance(&player).await;
log::debug!( log::debug!(
"Player {} ({}) joined with view distance: {}", "Player {} ({}) joined with view distance: {}",
player.gameprofile.name, player.gameprofile.name,
@ -70,7 +70,7 @@ pub async fn update_position(player: &Arc<Player>) {
}) })
.await; .await;
let view_distance = i32::from(get_view_distance(player).await); let view_distance = get_view_distance(player).await;
let old_cylindrical = Cylindrical::new( let old_cylindrical = Cylindrical::new(
Vector2::new(current_watched.x, current_watched.z), Vector2::new(current_watched.x, current_watched.z),
view_distance, view_distance,