Skip to content

Commit

Permalink
Consistent registry values and player changes (#324)
Browse files Browse the repository at this point in the history
* Made registry values consistent

* Port to own nbt crate

---------

Co-authored-by: Snowiiii <[email protected]>
  • Loading branch information
Alvsch and Snowiiii authored Nov 23, 2024
1 parent 402f395 commit c3c4aff
Show file tree
Hide file tree
Showing 8 changed files with 194 additions and 139 deletions.
2 changes: 2 additions & 0 deletions pumpkin-registry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ pumpkin-protocol = { path = "../pumpkin-protocol" }
pumpkin-nbt = { path = "../pumpkin-nbt" }
pumpkin-core = { path = "../pumpkin-core" }

indexmap = { version = "2.6.0", features = ["serde"] }

serde.workspace = true
serde_json.workspace = true

Expand Down
47 changes: 34 additions & 13 deletions pumpkin-registry/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::{collections::HashMap, sync::LazyLock};
use std::sync::LazyLock;

use banner_pattern::BannerPattern;
use biome::Biome;
use chat_type::ChatType;
use damage_type::DamageType;
use dimension::Dimension;
use enchantment::Enchantment;
use indexmap::IndexMap;
use instrument::Instrument;
use jukebox_song::JukeboxSong;
use paint::Painting;
Expand Down Expand Up @@ -47,29 +48,49 @@ pub struct Registry {
#[derive(Serialize, Deserialize)]
pub struct SyncedRegistry {
#[serde(rename = "minecraft:worldgen/biome")]
biome: HashMap<String, Biome>,
biome: IndexMap<String, Biome>,
#[serde(rename = "minecraft:chat_type")]
chat_type: HashMap<String, ChatType>,
chat_type: IndexMap<String, ChatType>,
#[serde(rename = "minecraft:trim_pattern")]
trim_pattern: HashMap<String, TrimPattern>,
trim_pattern: IndexMap<String, TrimPattern>,
#[serde(rename = "minecraft:trim_material")]
trim_material: HashMap<String, TrimMaterial>,
trim_material: IndexMap<String, TrimMaterial>,
#[serde(rename = "minecraft:wolf_variant")]
wolf_variant: HashMap<String, WolfVariant>,
wolf_variant: IndexMap<String, WolfVariant>,
#[serde(rename = "minecraft:painting_variant")]
painting_variant: HashMap<String, Painting>,
painting_variant: IndexMap<String, Painting>,
#[serde(rename = "minecraft:dimension_type")]
dimension_type: HashMap<String, Dimension>,
dimension_type: IndexMap<String, Dimension>,
#[serde(rename = "minecraft:damage_type")]
damage_type: HashMap<String, DamageType>,
damage_type: IndexMap<String, DamageType>,
#[serde(rename = "minecraft:banner_pattern")]
banner_pattern: HashMap<String, BannerPattern>,
banner_pattern: IndexMap<String, BannerPattern>,
#[serde(rename = "minecraft:enchantment")]
enchantment: HashMap<String, Enchantment>,
enchantment: IndexMap<String, Enchantment>,
#[serde(rename = "minecraft:jukebox_song")]
jukebox_song: HashMap<String, JukeboxSong>,
jukebox_song: IndexMap<String, JukeboxSong>,
#[serde(rename = "minecraft:instrument")]
instrument: HashMap<String, Instrument>,
instrument: IndexMap<String, Instrument>,
}

#[derive(Debug, Clone, Copy)]
#[repr(u8)]
pub enum DimensionType {
Overworld,
OverworldCaves,
TheEnd,
TheNether,
}

impl DimensionType {
pub fn name(&self) -> &str {
match self {
Self::Overworld => "minecraft:overworld",
Self::OverworldCaves => "minecraft:overworld_caves",
Self::TheEnd => "minecraft:the_end",
Self::TheNether => "minecraft:the_nether",
}
}
}

impl Registry {
Expand Down
4 changes: 2 additions & 2 deletions pumpkin/src/client/player_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ impl Player {
Hand::Off => Animation::SwingOffhand,
};
let id = self.entity_id();
let world = &self.living_entity.entity.world;
let world = self.world();
world
.broadcast_packet_except(
&[self.gameprofile.id],
Expand Down Expand Up @@ -449,7 +449,7 @@ impl Player {
if self.living_entity.health.load() > 0.0 {
return;
}
self.respawn(false).await;
self.world().respawn_player(self, false).await;
// TODO: hardcore set spectator
}
1 => {
Expand Down
8 changes: 4 additions & 4 deletions pumpkin/src/entity/living.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ impl LivingEntity {
.await;
}

pub async fn damage(&self, amount: f32) {
// TODO add damage_type enum
pub async fn damage(&self, amount: f32, damage_type: u8) {
self.entity
.world
.broadcast_packet_all(&CDamageEvent::new(
self.entity.entity_id.into(),
// TODO add damage_type id
0.into(),
damage_type.into(),
None,
None,
None,
Expand Down Expand Up @@ -130,7 +130,7 @@ impl LivingEntity {
return;
}

self.damage(damage).await;
self.damage(damage, 10).await; // Fall
} else if y_diff < 0.0 {
self.fall_distance.store(0.0);
} else {
Expand Down
122 changes: 15 additions & 107 deletions pumpkin/src/entity/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@ use pumpkin_core::{
use pumpkin_entity::{entity_type::EntityType, EntityId};
use pumpkin_inventory::player::PlayerInventory;
use pumpkin_macros::sound;
use pumpkin_protocol::client::play::{CSetEntityMetadata, Metadata};
use pumpkin_protocol::server::play::{SClickContainer, SKeepAlive};
use pumpkin_protocol::{
bytebuf::packet_id::Packet,
client::play::{
CCombatDeath, CEntityStatus, CGameEvent, CHurtAnimation, CKeepAlive, CPlayDisconnect,
CPlayerAbilities, CPlayerInfoUpdate, CRespawn, CSetHealth, CSpawnEntity,
CSyncPlayerPosition, CSystemChatMessage, GameEvent, PlayerAction,
CPlayerAbilities, CPlayerInfoUpdate, CSetHealth, CSyncPlayerPosition, CSystemChatMessage,
GameEvent, PlayerAction,
},
server::play::{
SChatCommand, SChatMessage, SClientCommand, SClientInformationPlay, SClientTickEnd,
Expand All @@ -53,7 +52,7 @@ use crate::{
Client, PlayerConfig,
},
server::Server,
world::{player_chunker, World},
world::World,
};
use crate::{error::PumpkinError, world::player_chunker::get_view_distance};

Expand Down Expand Up @@ -225,7 +224,7 @@ impl Player {
/// Removes the Player out of the current World
#[allow(unused_variables)]
pub async fn remove(&self) {
let world = &self.living_entity.entity.world;
let world = self.world();
// Abort pending chunks here too because we might clean up before chunk tasks are done
self.abort_chunks("closed");

Expand Down Expand Up @@ -343,14 +342,14 @@ impl Player {
"Removed player id {} ({}) ({} chunks remain cached)",
self.gameprofile.name,
self.client.id,
self.living_entity.entity.world.get_cached_chunk_len()
self.world().get_cached_chunk_len()
);

//self.living_entity.entity.world.level.list_cached();
//self.world().level.list_cached();
}

pub async fn attack(&self, victim: &Arc<Self>) {
let world = &self.living_entity.entity.world;
let world = self.world();
let victim_entity = &victim.living_entity.entity;
let attacker_entity = &self.living_entity.entity;
let config = &ADVANCED_CONFIG.pvp;
Expand Down Expand Up @@ -392,7 +391,10 @@ impl Player {
damage *= 1.5;
}

victim.living_entity.damage(damage).await;
victim
.living_entity
.damage(damage, 34) // PlayerAttack
.await;

let mut knockback_strength = 1.0;
match attack_type {
Expand Down Expand Up @@ -473,6 +475,10 @@ impl Player {
self.living_entity.entity.entity_id
}

pub const fn world(&self) -> &Arc<World> {
&self.living_entity.entity.world
}

/// Updates the current abilities the Player has
pub async fn send_abilties_update(&self) {
let mut b = 0i8;
Expand Down Expand Up @@ -520,104 +526,6 @@ impl Player {
self.permission_lvl
}

pub async fn respawn(self: &Arc<Self>, alive: bool) {
let last_pos = self.living_entity.last_pos.load();
let death_location = WorldPosition(Vector3::new(
last_pos.x.round() as i32,
last_pos.y.round() as i32,
last_pos.z.round() as i32,
));

let data_kept = u8::from(alive);

self.client
.send_packet(&CRespawn::new(
0.into(),
"minecraft:overworld",
0, // seed
self.gamemode.load() as u8,
self.gamemode.load() as i8,
false,
false,
Some(("minecraft:overworld", death_location)),
0.into(),
0.into(),
data_kept,
))
.await;

log::debug!("Sending player abilities to {}", self.gameprofile.name);
self.send_abilties_update().await;

self.send_permission_lvl_update().await;

let world = &self.living_entity.entity.world;

// teleport
let x = 10.0;
let z = 10.0;
let top = world.get_top_block(Vector2::new(x as i32, z as i32)).await;
let position = Vector3::new(x, f64::from(top + 1), z);
let yaw = 10.0;
let pitch = 10.0;

log::debug!("Sending player teleport to {}", self.gameprofile.name);
self.teleport(position, yaw, pitch).await;

self.living_entity.last_pos.store(position);

// TODO: difficulty, exp bar, status effect

let world = &self.living_entity.entity.world;
world
.worldborder
.lock()
.await
.init_client(&self.client)
.await;

// TODO: world spawn (compass stuff)

self.client
.send_packet(&CGameEvent::new(GameEvent::StartWaitingChunks, 0.0))
.await;

let entity = &self.living_entity.entity;
let entity_id = entity.entity_id;

let skin_parts = self.config.lock().await.skin_parts;
let entity_metadata_packet =
CSetEntityMetadata::new(entity_id.into(), Metadata::new(17, VarInt(0), &skin_parts));

world
.broadcast_packet_except(
&[self.gameprofile.id],
// TODO: add velo
&CSpawnEntity::new(
entity.entity_id.into(),
self.gameprofile.id,
(EntityType::Player as i32).into(),
position.x,
position.y,
position.z,
pitch,
yaw,
yaw,
0.into(),
0.0,
0.0,
0.0,
),
)
.await;

player_chunker::player_join(world, self.clone()).await;
world.broadcast_packet_all(&entity_metadata_packet).await;
// update commands

self.set_health(20.0, 20, 20.0).await;
}

/// yaw and pitch in degrees
pub async fn teleport(&self, position: Vector3<f64>, yaw: f32, pitch: f32) {
// this is the ultra special magic code used to create the teleport id
Expand Down
2 changes: 1 addition & 1 deletion pumpkin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ async fn main() -> io::Result<()> {
{
let (player, world) = server.add_player(client).await;
world
.spawn_player(&BASIC_CONFIG, player.clone(), &server.command_dispatcher)
.spawn_player(&BASIC_CONFIG, player.clone(), &server)
.await;

// poll Player
Expand Down
21 changes: 16 additions & 5 deletions pumpkin/src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use pumpkin_inventory::drag_handler::DragHandler;
use pumpkin_inventory::{Container, OpenContainer};
use pumpkin_protocol::client::login::CEncryptionRequest;
use pumpkin_protocol::{client::config::CPluginMessage, ClientPacket};
use pumpkin_registry::Registry;
use pumpkin_registry::{DimensionType, Registry};
use pumpkin_world::dimension::Dimension;
use rand::prelude::SliceRandom;
use std::collections::HashMap;
Expand Down Expand Up @@ -46,6 +46,8 @@ pub struct Server {
pub command_dispatcher: Arc<CommandDispatcher<'static>>,
/// Manages multiple worlds within the server.
pub worlds: Vec<Arc<World>>,
// All the dimensions that exists on the server,
pub dimensions: Vec<DimensionType>,
/// Caches game registries for efficient access.
pub cached_registry: Vec<Registry>,
/// Tracks open containers used for item interactions.
Expand Down Expand Up @@ -77,17 +79,26 @@ impl Server {
// First register default command, after that plugins can put in their own
let command_dispatcher = default_dispatcher();

let world = World::load(Dimension::OverWorld.into_level(
// TODO: load form config
"./world".parse().unwrap(),
));
let world = World::load(
Dimension::OverWorld.into_level(
// TODO: load form config
"./world".parse().unwrap(),
),
DimensionType::Overworld,
);
Self {
cached_registry: Registry::get_synced(),
open_containers: RwLock::new(HashMap::new()),
drag_handler: DragHandler::new(),
// 0 is invalid
entity_id: 2.into(),
worlds: vec![Arc::new(world)],
dimensions: vec![
DimensionType::Overworld,
DimensionType::OverworldCaves,
DimensionType::TheNether,
DimensionType::TheEnd,
],
command_dispatcher,
auth_client,
key_store: KeyStore::new(),
Expand Down
Loading

0 comments on commit c3c4aff

Please sign in to comment.