mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
Move ResourceLocation to pumpkin-util (#910)
* Rename Identifier to ResourceLocation * Run cargo fmt * Move ResourceLocation to pumpkin-util * Remove redundant as_string function * Run cargo fmt
This commit is contained in:
@@ -1,17 +1,16 @@
|
||||
use pumpkin_data::packet::clientbound::CONFIG_COOKIE_REQUEST;
|
||||
use pumpkin_macros::packet;
|
||||
|
||||
use crate::codec::identifier::Identifier;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
#[packet(CONFIG_COOKIE_REQUEST)]
|
||||
/// Requests a cookie that was previously stored.
|
||||
pub struct CCookieRequest<'a> {
|
||||
pub key: &'a Identifier,
|
||||
pub key: &'a ResourceLocation,
|
||||
}
|
||||
|
||||
impl<'a> CCookieRequest<'a> {
|
||||
pub fn new(key: &'a Identifier) -> Self {
|
||||
pub fn new(key: &'a ResourceLocation) -> Self {
|
||||
Self { key }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
use pumpkin_data::packet::clientbound::CONFIG_REGISTRY_DATA;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{codec::identifier::Identifier, ser::network_serialize_no_prefix};
|
||||
use crate::ser::network_serialize_no_prefix;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(CONFIG_REGISTRY_DATA)]
|
||||
pub struct CRegistryData<'a> {
|
||||
pub registry_id: &'a Identifier,
|
||||
pub registry_id: &'a ResourceLocation,
|
||||
pub entries: &'a [RegistryEntry],
|
||||
}
|
||||
|
||||
impl<'a> CRegistryData<'a> {
|
||||
pub fn new(registry_id: &'a Identifier, entries: &'a [RegistryEntry]) -> Self {
|
||||
pub fn new(registry_id: &'a ResourceLocation, entries: &'a [RegistryEntry]) -> Self {
|
||||
Self {
|
||||
registry_id,
|
||||
entries,
|
||||
@@ -22,7 +23,7 @@ impl<'a> CRegistryData<'a> {
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct RegistryEntry {
|
||||
pub entry_id: Identifier,
|
||||
pub entry_id: ResourceLocation,
|
||||
#[serde(serialize_with = "network_serialize_no_prefix")]
|
||||
pub data: Option<Box<[u8]>>,
|
||||
}
|
||||
@@ -33,7 +34,7 @@ impl RegistryEntry {
|
||||
let mut data_buf = Vec::new();
|
||||
pumpkin_nbt::serializer::to_bytes_unnamed(nbt, &mut data_buf).unwrap();
|
||||
RegistryEntry {
|
||||
entry_id: Identifier::vanilla(name),
|
||||
entry_id: ResourceLocation::vanilla(name),
|
||||
data: Some(data_buf.into_boxed_slice()),
|
||||
}
|
||||
}
|
||||
@@ -41,7 +42,7 @@ impl RegistryEntry {
|
||||
let mut data_buf = Vec::new();
|
||||
pumpkin_nbt::serializer::to_bytes_unnamed(nbt, &mut data_buf).unwrap();
|
||||
RegistryEntry {
|
||||
entry_id: Identifier::pumpkin(name),
|
||||
entry_id: ResourceLocation::pumpkin(name),
|
||||
data: Some(data_buf.into_boxed_slice()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
use crate::codec::identifier::Identifier;
|
||||
use pumpkin_data::packet::clientbound::CONFIG_STORE_COOKIE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
#[packet(CONFIG_STORE_COOKIE)]
|
||||
/// Stores some arbitrary data on the client, which persists between server transfers.
|
||||
/// The Notchian (vanilla) client only accepts cookies of up to 5 KiB in size.
|
||||
pub struct CStoreCookie<'a> {
|
||||
key: &'a Identifier,
|
||||
key: &'a ResourceLocation,
|
||||
payload: &'a [u8], // 5120,
|
||||
}
|
||||
|
||||
impl<'a> CStoreCookie<'a> {
|
||||
pub fn new(key: &'a Identifier, payload: &'a [u8]) -> Self {
|
||||
pub fn new(key: &'a ResourceLocation, payload: &'a [u8]) -> Self {
|
||||
Self { key, payload }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ use std::io::Write;
|
||||
|
||||
use crate::{
|
||||
ClientPacket,
|
||||
codec::identifier::Identifier,
|
||||
ser::{NetworkWriteExt, WritingError},
|
||||
};
|
||||
|
||||
@@ -13,6 +12,7 @@ use pumpkin_data::{
|
||||
tag::{RegistryKey, get_registry_key_tags},
|
||||
};
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
|
||||
#[packet(CONFIG_UPDATE_TAGS)]
|
||||
pub struct CUpdateTags<'a> {
|
||||
@@ -29,7 +29,9 @@ impl ClientPacket for CUpdateTags<'_> {
|
||||
fn write_packet_data(&self, write: impl Write) -> Result<(), WritingError> {
|
||||
let mut write = write;
|
||||
write.write_list(self.tags, |p, registry_key| {
|
||||
p.write_identifier(&Identifier::vanilla(registry_key.identifier_string()))?;
|
||||
p.write_resource_location(&ResourceLocation::vanilla(
|
||||
registry_key.identifier_string(),
|
||||
))?;
|
||||
|
||||
let values = get_registry_key_tags(registry_key);
|
||||
p.write_var_int(&values.len().try_into().map_err(|_| {
|
||||
@@ -37,7 +39,7 @@ impl ClientPacket for CUpdateTags<'_> {
|
||||
})?)?;
|
||||
|
||||
for (key, values) in values.iter() {
|
||||
// This is technically an `Identifier` but same thing
|
||||
// This is technically a `ResourceLocation` but same thing
|
||||
p.write_string_bounded(key, u16::MAX as usize)?;
|
||||
p.write_list(values, |p, string_id| {
|
||||
let id = match registry_key {
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
use pumpkin_data::packet::clientbound::LOGIN_COOKIE_REQUEST;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::codec::identifier::Identifier;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(LOGIN_COOKIE_REQUEST)]
|
||||
/// Requests a cookie that was previously stored.
|
||||
pub struct CLoginCookieRequest<'a> {
|
||||
key: &'a Identifier,
|
||||
key: &'a ResourceLocation,
|
||||
}
|
||||
|
||||
impl<'a> CLoginCookieRequest<'a> {
|
||||
pub fn new(key: &'a Identifier) -> Self {
|
||||
pub fn new(key: &'a ResourceLocation) -> Self {
|
||||
Self { key }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ impl ProtoNode<'_> {
|
||||
} => {
|
||||
// suggestion type
|
||||
let suggestion_type = &override_suggestion_type.expect("ProtoNode::FLAG_HAS_SUGGESTION_TYPE should only be set if override_suggestion_type is not `None`.");
|
||||
write.write_string(suggestion_type.identifier())?;
|
||||
write.write_string(suggestion_type.resource_location())?;
|
||||
}
|
||||
_ => unimplemented!(
|
||||
"`ProtoNode::FLAG_HAS_SUGGESTION_TYPE` is only implemented for `ProtoNodeType::Argument`"
|
||||
@@ -316,7 +316,7 @@ pub enum SuggestionProviders {
|
||||
}
|
||||
|
||||
impl SuggestionProviders {
|
||||
fn identifier(&self) -> &'static str {
|
||||
fn resource_location(&self) -> &'static str {
|
||||
match self {
|
||||
Self::AskServer => "minecraft:ask_server",
|
||||
Self::AllRecipes => "minecraft:all_recipes",
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_COOKIE_REQUEST;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::codec::identifier::Identifier;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_COOKIE_REQUEST)]
|
||||
/// Requests a cookie that was previously stored.
|
||||
pub struct CPlayCookieRequest<'a> {
|
||||
key: &'a Identifier,
|
||||
key: &'a ResourceLocation,
|
||||
}
|
||||
|
||||
impl<'a> CPlayCookieRequest<'a> {
|
||||
pub fn new(key: &'a Identifier) -> Self {
|
||||
pub fn new(key: &'a ResourceLocation) -> Self {
|
||||
Self { key }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_LOGIN;
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
use pumpkin_util::{math::position::BlockPos, resource_location::ResourceLocation};
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{VarInt, codec::identifier::Identifier};
|
||||
use crate::VarInt;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_LOGIN)]
|
||||
pub struct CLogin<'a> {
|
||||
entity_id: i32,
|
||||
is_hardcore: bool,
|
||||
dimension_names: &'a [Identifier],
|
||||
dimension_names: &'a [ResourceLocation],
|
||||
max_players: VarInt,
|
||||
view_distance: VarInt,
|
||||
simulated_distance: VarInt,
|
||||
@@ -20,14 +20,14 @@ pub struct CLogin<'a> {
|
||||
limited_crafting: bool,
|
||||
// Spawn info
|
||||
dimension_type: VarInt,
|
||||
dimension_name: Identifier,
|
||||
dimension_name: ResourceLocation,
|
||||
/// First 8 bytes of the SHA-256 hash of the world's seed. Used client side for biome noise
|
||||
hashed_seed: i64,
|
||||
game_mode: u8,
|
||||
previous_gamemode: i8,
|
||||
debug: bool,
|
||||
is_flat: bool,
|
||||
death_dimension_name: Option<(Identifier, BlockPos)>,
|
||||
death_dimension_name: Option<(ResourceLocation, BlockPos)>,
|
||||
portal_cooldown: VarInt,
|
||||
sealevel: VarInt,
|
||||
enforce_secure_chat: bool,
|
||||
@@ -38,7 +38,7 @@ impl<'a> CLogin<'a> {
|
||||
pub fn new(
|
||||
entity_id: i32,
|
||||
is_hardcore: bool,
|
||||
dimension_names: &'a [Identifier],
|
||||
dimension_names: &'a [ResourceLocation],
|
||||
max_players: VarInt,
|
||||
view_distance: VarInt,
|
||||
simulated_distance: VarInt,
|
||||
@@ -46,13 +46,13 @@ impl<'a> CLogin<'a> {
|
||||
enabled_respawn_screen: bool,
|
||||
limited_crafting: bool,
|
||||
dimension_type: VarInt,
|
||||
dimension_name: Identifier,
|
||||
dimension_name: ResourceLocation,
|
||||
hashed_seed: i64,
|
||||
game_mode: u8,
|
||||
previous_gamemode: i8,
|
||||
debug: bool,
|
||||
is_flat: bool,
|
||||
death_dimension_name: Option<(Identifier, BlockPos)>,
|
||||
death_dimension_name: Option<(ResourceLocation, BlockPos)>,
|
||||
portal_cooldown: VarInt,
|
||||
sealevel: VarInt,
|
||||
enforce_secure_chat: bool,
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_RESPAWN;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
use pumpkin_util::{math::position::BlockPos, resource_location::ResourceLocation};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{VarInt, codec::identifier::Identifier};
|
||||
use crate::VarInt;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[packet(PLAY_RESPAWN)]
|
||||
pub struct CRespawn {
|
||||
dimension_type: VarInt,
|
||||
dimension_name: Identifier,
|
||||
dimension_name: ResourceLocation,
|
||||
hashed_seed: i64,
|
||||
game_mode: u8,
|
||||
previous_gamemode: i8,
|
||||
debug: bool,
|
||||
is_flat: bool,
|
||||
death_dimension_name: Option<(Identifier, BlockPos)>,
|
||||
death_dimension_name: Option<(ResourceLocation, BlockPos)>,
|
||||
portal_cooldown: VarInt,
|
||||
sealevel: VarInt,
|
||||
data_kept: u8,
|
||||
@@ -25,13 +25,13 @@ impl CRespawn {
|
||||
#[expect(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
dimension_type: VarInt,
|
||||
dimension_name: Identifier,
|
||||
dimension_name: ResourceLocation,
|
||||
hashed_seed: i64,
|
||||
game_mode: u8,
|
||||
previous_gamemode: i8,
|
||||
debug: bool,
|
||||
is_flat: bool,
|
||||
death_dimension_name: Option<(Identifier, BlockPos)>,
|
||||
death_dimension_name: Option<(ResourceLocation, BlockPos)>,
|
||||
portal_cooldown: VarInt,
|
||||
sealevel: VarInt,
|
||||
data_kept: u8,
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
use std::io::Write;
|
||||
|
||||
use crate::ClientPacket;
|
||||
use crate::codec::var_int::VarInt;
|
||||
use crate::ser::{NetworkWriteExt, WritingError};
|
||||
use crate::{ClientPacket, codec::identifier::Identifier};
|
||||
use pumpkin_data::{packet::clientbound::PLAY_STOP_SOUND, sound::SoundCategory};
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
|
||||
#[packet(PLAY_STOP_SOUND)]
|
||||
pub struct CStopSound {
|
||||
sound_id: Option<Identifier>,
|
||||
sound_id: Option<ResourceLocation>,
|
||||
category: Option<SoundCategory>,
|
||||
}
|
||||
|
||||
impl CStopSound {
|
||||
pub fn new(sound_id: Option<Identifier>, category: Option<SoundCategory>) -> Self {
|
||||
pub fn new(sound_id: Option<ResourceLocation>, category: Option<SoundCategory>) -> Self {
|
||||
Self { sound_id, category }
|
||||
}
|
||||
}
|
||||
@@ -31,7 +32,7 @@ impl ClientPacket for CStopSound {
|
||||
(Some(category), Some(sound_id)) => {
|
||||
write.write_u8_be(CATEGORY_AND_SOUND)?;
|
||||
write.write_var_int(&VarInt(category as i32))?;
|
||||
write.write_identifier(sound_id)
|
||||
write.write_resource_location(sound_id)
|
||||
}
|
||||
(Some(category), None) => {
|
||||
write.write_u8_be(CATEGORY_ONLY)?;
|
||||
@@ -39,7 +40,7 @@ impl ClientPacket for CStopSound {
|
||||
}
|
||||
(None, Some(sound_id)) => {
|
||||
write.write_u8_be(SOUND_ONLY)?;
|
||||
write.write_identifier(sound_id)
|
||||
write.write_resource_location(sound_id)
|
||||
}
|
||||
(None, None) => write.write_u8_be(NO_CATEGORY_NO_SOUND),
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::codec::identifier::Identifier;
|
||||
use pumpkin_data::packet::clientbound::PLAY_STORE_COOKIE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use serde::Serialize;
|
||||
|
||||
/// Stores some arbitrary data on the client, which persists between server transfers.
|
||||
@@ -8,12 +8,12 @@ use serde::Serialize;
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_STORE_COOKIE)]
|
||||
pub struct CStoreCookie<'a> {
|
||||
key: &'a Identifier,
|
||||
key: &'a ResourceLocation,
|
||||
payload: &'a [u8], // 5120,
|
||||
}
|
||||
|
||||
impl<'a> CStoreCookie<'a> {
|
||||
pub fn new(key: &'a Identifier, payload: &'a [u8]) -> Self {
|
||||
pub fn new(key: &'a ResourceLocation, payload: &'a [u8]) -> Self {
|
||||
Self { key, payload }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
use std::{
|
||||
io::{Read, Write},
|
||||
num::NonZeroUsize,
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Visitor};
|
||||
|
||||
use crate::ser::{NetworkReadExt, NetworkWriteExt, ReadingError, WritingError};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Identifier {
|
||||
pub namespace: String,
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
impl Identifier {
|
||||
pub fn vanilla(path: &str) -> Self {
|
||||
Self {
|
||||
namespace: "minecraft".to_string(),
|
||||
path: path.to_string(),
|
||||
}
|
||||
}
|
||||
pub fn pumpkin(path: &str) -> Self {
|
||||
Self {
|
||||
namespace: "pumpkin".to_string(),
|
||||
path: path.to_string(),
|
||||
}
|
||||
}
|
||||
pub fn get(&self) -> String {
|
||||
format!("{}:{}", self.namespace, self.path)
|
||||
}
|
||||
}
|
||||
impl Identifier {
|
||||
/// The maximum number of bytes an `Identifier` is the same as for a normal `String`.
|
||||
const MAX_SIZE: NonZeroUsize = NonZeroUsize::new(i16::MAX as usize).unwrap();
|
||||
|
||||
pub fn encode(&self, write: &mut impl Write) -> Result<(), WritingError> {
|
||||
write.write_string_bounded(&self.to_string(), Self::MAX_SIZE.get())
|
||||
}
|
||||
|
||||
pub fn decode(read: &mut impl Read) -> Result<Self, ReadingError> {
|
||||
let identifier = read.get_string_bounded(Self::MAX_SIZE.get())?;
|
||||
match identifier.split_once(":") {
|
||||
Some((namespace, path)) => Ok(Identifier {
|
||||
namespace: namespace.to_string(),
|
||||
path: path.to_string(),
|
||||
}),
|
||||
None => Err(ReadingError::Incomplete("Identifier".to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Identifier {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Identifier {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct IdentifierVisitor;
|
||||
|
||||
impl Visitor<'_> for IdentifierVisitor {
|
||||
type Value = Identifier;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("a valid identifier (namespace:path)")
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
self.visit_str(&v)
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, identifier: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
match identifier.split_once(":") {
|
||||
Some((namespace, path)) => Ok(Identifier {
|
||||
namespace: namespace.to_string(),
|
||||
path: path.to_string(),
|
||||
}),
|
||||
None => Err(serde::de::Error::custom("identifier can't be split")),
|
||||
}
|
||||
}
|
||||
}
|
||||
deserializer.deserialize_str(IdentifierVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Identifier {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}:{}", self.namespace, self.path)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
pub mod bit_set;
|
||||
pub mod identifier;
|
||||
pub mod item_stack_seralizer;
|
||||
pub mod var_int;
|
||||
pub mod var_long;
|
||||
|
||||
@@ -5,8 +5,11 @@ use std::{
|
||||
|
||||
use aes::cipher::{BlockDecryptMut, BlockEncryptMut, BlockSizeUser, generic_array::GenericArray};
|
||||
use bytes::Bytes;
|
||||
use codec::{identifier::Identifier, var_int::VarInt};
|
||||
use pumpkin_util::text::{TextComponent, style::Style};
|
||||
use codec::var_int::VarInt;
|
||||
use pumpkin_util::{
|
||||
resource_location::ResourceLocation,
|
||||
text::{TextComponent, style::Style},
|
||||
};
|
||||
use ser::{NetworkWriteExt, ReadingError, WritingError, packet::Packet};
|
||||
use serde::{
|
||||
Deserialize, Serialize, Serializer,
|
||||
@@ -188,7 +191,7 @@ impl<T: Serialize> Serialize for IdOr<T> {
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq)]
|
||||
pub struct SoundEvent {
|
||||
pub sound_name: Identifier,
|
||||
pub sound_name: ResourceLocation,
|
||||
pub range: Option<f32>,
|
||||
}
|
||||
|
||||
@@ -516,10 +519,8 @@ impl Serialize for LinkType {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::{
|
||||
codec::identifier::Identifier,
|
||||
ser::{deserializer::Deserializer, serializer::Serializer},
|
||||
};
|
||||
use crate::ser::{deserializer::Deserializer, serializer::Serializer};
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{IdOr, SoundEvent};
|
||||
@@ -541,7 +542,7 @@ mod test {
|
||||
fn test_serde_id_or_value() {
|
||||
let mut buf = Vec::new();
|
||||
let event = SoundEvent {
|
||||
sound_name: Identifier::vanilla("test"),
|
||||
sound_name: ResourceLocation::vanilla("test"),
|
||||
range: Some(1.0),
|
||||
};
|
||||
|
||||
|
||||
@@ -3,11 +3,12 @@ use std::io::{Read, Write};
|
||||
|
||||
use crate::{
|
||||
FixedBitSet,
|
||||
codec::{bit_set::BitSet, identifier::Identifier, var_int::VarInt, var_long::VarLong},
|
||||
codec::{bit_set::BitSet, var_int::VarInt, var_long::VarLong},
|
||||
};
|
||||
|
||||
pub mod deserializer;
|
||||
use pumpkin_nbt::{serializer::WriteAdaptor, tag::NbtTag};
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use thiserror::Error;
|
||||
pub mod packet;
|
||||
pub mod serializer;
|
||||
@@ -67,7 +68,7 @@ pub trait NetworkReadExt {
|
||||
fn get_var_long(&mut self) -> Result<VarLong, ReadingError>;
|
||||
fn get_string_bounded(&mut self, bound: usize) -> Result<String, ReadingError>;
|
||||
fn get_string(&mut self) -> Result<String, ReadingError>;
|
||||
fn get_identifier(&mut self) -> Result<Identifier, ReadingError>;
|
||||
fn get_resource_location(&mut self) -> Result<ResourceLocation, ReadingError>;
|
||||
fn get_uuid(&mut self) -> Result<uuid::Uuid, ReadingError>;
|
||||
fn get_fixed_bitset(&mut self, bits: usize) -> Result<FixedBitSet, ReadingError>;
|
||||
|
||||
@@ -237,8 +238,15 @@ impl<R: Read> NetworkReadExt for R {
|
||||
self.get_string_bounded(i16::MAX as usize)
|
||||
}
|
||||
|
||||
fn get_identifier(&mut self) -> Result<Identifier, ReadingError> {
|
||||
Identifier::decode(self)
|
||||
fn get_resource_location(&mut self) -> Result<ResourceLocation, ReadingError> {
|
||||
let resource_location = self.get_string_bounded(ResourceLocation::MAX_SIZE.get())?;
|
||||
match resource_location.split_once(":") {
|
||||
Some((namespace, path)) => Ok(ResourceLocation {
|
||||
namespace: namespace.to_string(),
|
||||
path: path.to_string(),
|
||||
}),
|
||||
None => Err(ReadingError::Incomplete("ResourceLocation".to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_uuid(&mut self) -> Result<uuid::Uuid, ReadingError> {
|
||||
@@ -301,7 +309,7 @@ pub trait NetworkWriteExt {
|
||||
fn write_var_long(&mut self, data: &VarLong) -> Result<(), WritingError>;
|
||||
fn write_string_bounded(&mut self, data: &str, bound: usize) -> Result<(), WritingError>;
|
||||
fn write_string(&mut self, data: &str) -> Result<(), WritingError>;
|
||||
fn write_identifier(&mut self, data: &Identifier) -> Result<(), WritingError>;
|
||||
fn write_resource_location(&mut self, data: &ResourceLocation) -> Result<(), WritingError>;
|
||||
|
||||
fn write_uuid(&mut self, data: &uuid::Uuid) -> Result<(), WritingError> {
|
||||
let (first, second) = data.as_u64_pair();
|
||||
@@ -420,8 +428,8 @@ impl<W: Write> NetworkWriteExt for W {
|
||||
self.write_string_bounded(data, i16::MAX as usize)
|
||||
}
|
||||
|
||||
fn write_identifier(&mut self, data: &Identifier) -> Result<(), WritingError> {
|
||||
data.encode(self)
|
||||
fn write_resource_location(&mut self, data: &ResourceLocation) -> Result<(), WritingError> {
|
||||
self.write_string_bounded(&data.to_string(), ResourceLocation::MAX_SIZE.get())
|
||||
}
|
||||
|
||||
fn write_bitset(&mut self, data: &BitSet) -> Result<(), WritingError> {
|
||||
|
||||
@@ -2,10 +2,10 @@ use std::io::Read;
|
||||
|
||||
use pumpkin_data::packet::serverbound::CONFIG_COOKIE_RESPONSE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
|
||||
use crate::{
|
||||
ServerPacket,
|
||||
codec::identifier::Identifier,
|
||||
ser::{NetworkReadExt, ReadingError},
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ use crate::{
|
||||
/// Response to a `CCookieRequest` (configuration) from the server.
|
||||
/// The Notchian (vanilla) server only accepts responses of up to 5 KiB in size.
|
||||
pub struct SConfigCookieResponse {
|
||||
pub key: Identifier,
|
||||
pub key: ResourceLocation,
|
||||
pub has_payload: bool,
|
||||
pub payload: Option<Box<[u8]>>, // 5120,
|
||||
}
|
||||
@@ -24,7 +24,7 @@ impl ServerPacket for SConfigCookieResponse {
|
||||
fn read(read: impl Read) -> Result<Self, ReadingError> {
|
||||
let mut read = read;
|
||||
|
||||
let key = read.get_identifier()?;
|
||||
let key = read.get_resource_location()?;
|
||||
let has_payload = read.get_bool()?;
|
||||
|
||||
if !has_payload {
|
||||
|
||||
@@ -2,17 +2,17 @@ use std::io::Read;
|
||||
|
||||
use pumpkin_data::packet::serverbound::CONFIG_CUSTOM_PAYLOAD;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
|
||||
use crate::{
|
||||
ServerPacket,
|
||||
codec::identifier::Identifier,
|
||||
ser::{NetworkReadExt, ReadingError},
|
||||
};
|
||||
const MAX_PAYLOAD_SIZE: usize = 1048576;
|
||||
|
||||
#[packet(CONFIG_CUSTOM_PAYLOAD)]
|
||||
pub struct SPluginMessage {
|
||||
pub channel: Identifier,
|
||||
pub channel: ResourceLocation,
|
||||
pub data: Box<[u8]>,
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ impl ServerPacket for SPluginMessage {
|
||||
let mut read = read;
|
||||
|
||||
Ok(Self {
|
||||
channel: read.get_identifier()?,
|
||||
channel: read.get_resource_location()?,
|
||||
data: read.read_remaining_to_boxed_slice(MAX_PAYLOAD_SIZE)?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,17 +2,17 @@ use std::io::Read;
|
||||
|
||||
use crate::{
|
||||
ServerPacket,
|
||||
codec::identifier::Identifier,
|
||||
ser::{NetworkReadExt, ReadingError},
|
||||
};
|
||||
use pumpkin_data::packet::serverbound::LOGIN_COOKIE_RESPONSE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
|
||||
#[packet(LOGIN_COOKIE_RESPONSE)]
|
||||
/// Response to a `CCookieRequest` (login) from the server.
|
||||
/// The Notchian server only accepts responses of up to 5 kiB in size.
|
||||
pub struct SLoginCookieResponse {
|
||||
pub key: Identifier,
|
||||
pub key: ResourceLocation,
|
||||
pub payload: Option<Box<[u8]>>, // 5120,
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ impl ServerPacket for SLoginCookieResponse {
|
||||
fn read(read: impl Read) -> Result<Self, ReadingError> {
|
||||
let mut read = read;
|
||||
|
||||
let key = read.get_identifier()?;
|
||||
let key = read.get_resource_location()?;
|
||||
let has_payload = read.get_bool()?;
|
||||
|
||||
if !has_payload {
|
||||
|
||||
@@ -2,17 +2,17 @@ use std::io::Read;
|
||||
|
||||
use crate::{
|
||||
ServerPacket,
|
||||
codec::identifier::Identifier,
|
||||
ser::{NetworkReadExt, ReadingError},
|
||||
};
|
||||
use pumpkin_data::packet::serverbound::PLAY_COOKIE_RESPONSE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
|
||||
#[packet(PLAY_COOKIE_RESPONSE)]
|
||||
/// Response to a `CCookieRequest` (play) from the server.
|
||||
/// The Notchian (vanilla) server only accepts responses of up to 5 KiB in size.
|
||||
pub struct SCookieResponse {
|
||||
pub key: Identifier,
|
||||
pub key: ResourceLocation,
|
||||
pub payload: Option<Box<[u8]>>, // 5120,
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ impl ServerPacket for SCookieResponse {
|
||||
fn read(read: impl Read) -> Result<Self, ReadingError> {
|
||||
let mut read = read;
|
||||
|
||||
let key = read.get_identifier()?;
|
||||
let key = read.get_resource_location()?;
|
||||
let has_payload = read.get_bool()?;
|
||||
|
||||
if !has_payload {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use pumpkin_protocol::codec::identifier::Identifier;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct BannerPattern {
|
||||
asset_id: Identifier,
|
||||
asset_id: ResourceLocation,
|
||||
translation_key: String,
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ use instrument::Instrument;
|
||||
use jukebox_song::JukeboxSong;
|
||||
use paint::Painting;
|
||||
use pig::PigVariant;
|
||||
use pumpkin_protocol::{client::config::RegistryEntry, codec::identifier::Identifier};
|
||||
use pumpkin_protocol::client::config::RegistryEntry;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use trim_material::TrimMaterial;
|
||||
use trim_pattern::TrimPattern;
|
||||
@@ -45,7 +46,7 @@ pub static SYNCED_REGISTRIES: LazyLock<SyncedRegistry> = LazyLock::new(|| {
|
||||
});
|
||||
|
||||
pub struct Registry {
|
||||
pub registry_id: Identifier,
|
||||
pub registry_id: ResourceLocation,
|
||||
pub registry_entries: Vec<RegistryEntry>,
|
||||
}
|
||||
|
||||
@@ -72,32 +73,33 @@ pub struct SyncedRegistry {
|
||||
instrument: IndexMap<String, Instrument>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum DimensionType {
|
||||
Overworld,
|
||||
OverworldCaves,
|
||||
TheEnd,
|
||||
TheNether,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
struct DataPool<T> {
|
||||
data: T,
|
||||
weight: i32,
|
||||
}
|
||||
|
||||
impl DimensionType {
|
||||
pub fn name(&self) -> Identifier {
|
||||
// TODO: remove in favor of numerical registry ids for `minecraft:dimension_type`
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum VanillaDimensionType {
|
||||
Overworld,
|
||||
OverworldCaves,
|
||||
TheEnd,
|
||||
TheNether,
|
||||
}
|
||||
|
||||
impl VanillaDimensionType {
|
||||
pub fn resource_location(&self) -> ResourceLocation {
|
||||
match self {
|
||||
Self::Overworld => Identifier::vanilla("overworld"),
|
||||
Self::OverworldCaves => Identifier::vanilla("overworld_caves"),
|
||||
Self::TheEnd => Identifier::vanilla("the_end"),
|
||||
Self::TheNether => Identifier::vanilla("the_nether"),
|
||||
Self::Overworld => ResourceLocation::vanilla("overworld"),
|
||||
Self::OverworldCaves => ResourceLocation::vanilla("overworld_caves"),
|
||||
Self::TheEnd => ResourceLocation::vanilla("the_end"),
|
||||
Self::TheNether => ResourceLocation::vanilla("the_nether"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_name(name: &str) -> Option<Self> {
|
||||
match name {
|
||||
pub fn from_resource_location_string(resource_location: &str) -> Option<Self> {
|
||||
match resource_location {
|
||||
"minecraft:overworld" => Some(Self::Overworld),
|
||||
"minecraft:overworld_caves" => Some(Self::OverworldCaves),
|
||||
"minecraft:the_end" => Some(Self::TheEnd),
|
||||
@@ -115,7 +117,7 @@ impl Registry {
|
||||
.map(|(name, nbt)| RegistryEntry::from_nbt(name, nbt))
|
||||
.collect();
|
||||
let biome = Registry {
|
||||
registry_id: Identifier::vanilla("worldgen/biome"),
|
||||
registry_id: ResourceLocation::vanilla("worldgen/biome"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
@@ -143,7 +145,7 @@ impl Registry {
|
||||
));
|
||||
|
||||
let chat_type = Registry {
|
||||
registry_id: Identifier::vanilla("chat_type"),
|
||||
registry_id: ResourceLocation::vanilla("chat_type"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
@@ -153,7 +155,7 @@ impl Registry {
|
||||
.map(|(name, nbt)| RegistryEntry::from_nbt(name, nbt))
|
||||
.collect();
|
||||
let wolf_variant = Registry {
|
||||
registry_id: Identifier::vanilla("wolf_variant"),
|
||||
registry_id: ResourceLocation::vanilla("wolf_variant"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
@@ -163,7 +165,7 @@ impl Registry {
|
||||
.map(|(name, nbt)| RegistryEntry::from_nbt(name, nbt))
|
||||
.collect();
|
||||
let cat_variant = Registry {
|
||||
registry_id: Identifier::vanilla("cat_variant"),
|
||||
registry_id: ResourceLocation::vanilla("cat_variant"),
|
||||
registry_entries,
|
||||
};
|
||||
let registry_entries = SYNCED_REGISTRIES
|
||||
@@ -172,7 +174,7 @@ impl Registry {
|
||||
.map(|(name, nbt)| RegistryEntry::from_nbt(name, nbt))
|
||||
.collect();
|
||||
let chicken_variant = Registry {
|
||||
registry_id: Identifier::vanilla("chicken_variant"),
|
||||
registry_id: ResourceLocation::vanilla("chicken_variant"),
|
||||
registry_entries,
|
||||
};
|
||||
let registry_entries = SYNCED_REGISTRIES
|
||||
@@ -181,7 +183,7 @@ impl Registry {
|
||||
.map(|(name, nbt)| RegistryEntry::from_nbt(name, nbt))
|
||||
.collect();
|
||||
let cow_variant = Registry {
|
||||
registry_id: Identifier::vanilla("cow_variant"),
|
||||
registry_id: ResourceLocation::vanilla("cow_variant"),
|
||||
registry_entries,
|
||||
};
|
||||
let registry_entries = SYNCED_REGISTRIES
|
||||
@@ -190,7 +192,7 @@ impl Registry {
|
||||
.map(|(name, nbt)| RegistryEntry::from_nbt(name, nbt))
|
||||
.collect();
|
||||
let frog_variant = Registry {
|
||||
registry_id: Identifier::vanilla("frog_variant"),
|
||||
registry_id: ResourceLocation::vanilla("frog_variant"),
|
||||
registry_entries,
|
||||
};
|
||||
let registry_entries = SYNCED_REGISTRIES
|
||||
@@ -199,7 +201,7 @@ impl Registry {
|
||||
.map(|(name, nbt)| RegistryEntry::from_nbt(name, nbt))
|
||||
.collect();
|
||||
let pig_variant = Registry {
|
||||
registry_id: Identifier::vanilla("pig_variant"),
|
||||
registry_id: ResourceLocation::vanilla("pig_variant"),
|
||||
registry_entries,
|
||||
};
|
||||
let registry_entries = SYNCED_REGISTRIES
|
||||
@@ -208,7 +210,7 @@ impl Registry {
|
||||
.map(|(name, nbt)| RegistryEntry::from_nbt(name, nbt))
|
||||
.collect();
|
||||
let wolf_sound_variant = Registry {
|
||||
registry_id: Identifier::vanilla("wolf_sound_variant"),
|
||||
registry_id: ResourceLocation::vanilla("wolf_sound_variant"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
@@ -218,7 +220,7 @@ impl Registry {
|
||||
.map(|(name, nbt)| RegistryEntry::from_nbt(name, nbt))
|
||||
.collect();
|
||||
let painting_variant = Registry {
|
||||
registry_id: Identifier::vanilla("painting_variant"),
|
||||
registry_id: ResourceLocation::vanilla("painting_variant"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
@@ -228,7 +230,7 @@ impl Registry {
|
||||
.map(|(name, nbt)| RegistryEntry::from_nbt(name, nbt))
|
||||
.collect();
|
||||
let dimension_type = Registry {
|
||||
registry_id: Identifier::vanilla("dimension_type"),
|
||||
registry_id: ResourceLocation::vanilla("dimension_type"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
@@ -238,7 +240,7 @@ impl Registry {
|
||||
.map(|(name, nbt)| RegistryEntry::from_nbt(name, nbt))
|
||||
.collect();
|
||||
let damage_type = Registry {
|
||||
registry_id: Identifier::vanilla("damage_type"),
|
||||
registry_id: ResourceLocation::vanilla("damage_type"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
@@ -248,7 +250,7 @@ impl Registry {
|
||||
.map(|(name, nbt)| RegistryEntry::from_nbt(name, nbt))
|
||||
.collect();
|
||||
let banner_pattern = Registry {
|
||||
registry_id: Identifier::vanilla("banner_pattern"),
|
||||
registry_id: ResourceLocation::vanilla("banner_pattern"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
@@ -258,7 +260,7 @@ impl Registry {
|
||||
.map(|(name, nbt)| RegistryEntry::from_nbt(name, nbt))
|
||||
.collect();
|
||||
let jukebox_song = Registry {
|
||||
registry_id: Identifier::vanilla("jukebox_song"),
|
||||
registry_id: ResourceLocation::vanilla("jukebox_song"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use pumpkin_protocol::codec::identifier::Identifier;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Painting {
|
||||
asset_id: Identifier,
|
||||
asset_id: ResourceLocation,
|
||||
// #[serde(skip_serializing_if = "Option::is_none")]
|
||||
// title: Option<TextComponent<'static>>,
|
||||
// #[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use pumpkin_protocol::codec::identifier::Identifier;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct TrimPattern {
|
||||
asset_id: Identifier,
|
||||
asset_id: ResourceLocation,
|
||||
// description: TextComponent<'static>,
|
||||
decal: bool,
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ pub mod noise;
|
||||
pub mod permission;
|
||||
pub mod random;
|
||||
pub mod registry;
|
||||
pub mod resource_location;
|
||||
pub mod serde_enum_as_integer;
|
||||
pub mod text;
|
||||
pub mod translation;
|
||||
|
||||
81
pumpkin-util/src/resource_location.rs
Normal file
81
pumpkin-util/src/resource_location.rs
Normal file
@@ -0,0 +1,81 @@
|
||||
use std::num::NonZeroUsize;
|
||||
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Visitor};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct ResourceLocation {
|
||||
pub namespace: String,
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
impl ResourceLocation {
|
||||
/// The maximum number of bytes for a [`ResourceLocation`] is the same as for a normal [`String`].
|
||||
pub const MAX_SIZE: NonZeroUsize = NonZeroUsize::new(i16::MAX as usize).unwrap();
|
||||
|
||||
pub fn vanilla(path: &str) -> Self {
|
||||
Self {
|
||||
namespace: "minecraft".to_string(),
|
||||
path: path.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pumpkin(path: &str) -> Self {
|
||||
Self {
|
||||
namespace: "pumpkin".to_string(),
|
||||
path: path.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ResourceLocation {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}:{}", self.namespace, self.path)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for ResourceLocation {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for ResourceLocation {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct ResourceLocationVisitor;
|
||||
|
||||
impl Visitor<'_> for ResourceLocationVisitor {
|
||||
type Value = ResourceLocation;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("a valid resource location (namespace:path)")
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
self.visit_str(&v)
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, resource_location: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
match resource_location.split_once(":") {
|
||||
Some((namespace, path)) => Ok(ResourceLocation {
|
||||
namespace: namespace.to_string(),
|
||||
path: path.to_string(),
|
||||
}),
|
||||
None => Err(serde::de::Error::custom("resource location can't be split")),
|
||||
}
|
||||
}
|
||||
}
|
||||
deserializer.deserialize_str(ResourceLocationVisitor)
|
||||
}
|
||||
}
|
||||
@@ -296,8 +296,8 @@ impl TextComponent {
|
||||
|
||||
/// Allows you to change the font of the text.
|
||||
/// Default fonts: `minecraft:default`, `minecraft:uniform`, `minecraft:alt`, `minecraft:illageralt`
|
||||
pub fn font(mut self, identifier: String) -> Self {
|
||||
self.0.style.font = Some(identifier);
|
||||
pub fn font(mut self, resource_location: String) -> Self {
|
||||
self.0.style.font = Some(resource_location);
|
||||
self
|
||||
}
|
||||
|
||||
|
||||
@@ -106,8 +106,8 @@ impl Style {
|
||||
|
||||
/// Allows you to change the font of the text.
|
||||
/// Default fonts: `minecraft:default`, `minecraft:uniform`, `minecraft:alt`, `minecraft:illageralt`
|
||||
pub fn font(mut self, identifier: String) -> Self {
|
||||
self.font = Some(identifier);
|
||||
pub fn font(mut self, resource_location: String) -> Self {
|
||||
self.font = Some(resource_location);
|
||||
self
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ pub struct BarrelBlockEntity {
|
||||
|
||||
#[async_trait]
|
||||
impl BlockEntity for BarrelBlockEntity {
|
||||
fn identifier(&self) -> &'static str {
|
||||
fn resource_location(&self) -> &'static str {
|
||||
Self::ID
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ pub struct BedBlockEntity {
|
||||
|
||||
#[async_trait]
|
||||
impl BlockEntity for BedBlockEntity {
|
||||
fn identifier(&self) -> &'static str {
|
||||
fn resource_location(&self) -> &'static str {
|
||||
Self::ID
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ pub struct ChestBlockEntity {
|
||||
|
||||
#[async_trait]
|
||||
impl BlockEntity for ChestBlockEntity {
|
||||
fn identifier(&self) -> &'static str {
|
||||
fn resource_location(&self) -> &'static str {
|
||||
Self::ID
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ impl CommandBlockEntity {
|
||||
|
||||
#[async_trait]
|
||||
impl BlockEntity for CommandBlockEntity {
|
||||
fn identifier(&self) -> &'static str {
|
||||
fn resource_location(&self) -> &'static str {
|
||||
Self::ID
|
||||
}
|
||||
fn get_position(&self) -> BlockPos {
|
||||
|
||||
@@ -16,7 +16,7 @@ const OUTPUT_SIGNAL: &str = "OutputSignal";
|
||||
|
||||
#[async_trait]
|
||||
impl BlockEntity for ComparatorBlockEntity {
|
||||
fn identifier(&self) -> &'static str {
|
||||
fn resource_location(&self) -> &'static str {
|
||||
Self::ID
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ impl EndPortalBlockEntity {
|
||||
|
||||
#[async_trait]
|
||||
impl BlockEntity for EndPortalBlockEntity {
|
||||
fn identifier(&self) -> &'static str {
|
||||
fn resource_location(&self) -> &'static str {
|
||||
Self::ID
|
||||
}
|
||||
|
||||
|
||||
@@ -31,10 +31,10 @@ pub trait BlockEntity: Send + Sync {
|
||||
where
|
||||
Self: Sized;
|
||||
async fn tick(&self, _world: &Arc<dyn SimpleWorld>) {}
|
||||
fn identifier(&self) -> &'static str;
|
||||
fn resource_location(&self) -> &'static str;
|
||||
fn get_position(&self) -> BlockPos;
|
||||
async fn write_internal(&self, nbt: &mut NbtCompound) {
|
||||
nbt.put_string("id", self.identifier().to_string());
|
||||
nbt.put_string("id", self.resource_location().to_string());
|
||||
let position = self.get_position();
|
||||
nbt.put_int("x", position.0.x);
|
||||
nbt.put_int("y", position.0.y);
|
||||
@@ -45,7 +45,7 @@ pub trait BlockEntity: Send + Sync {
|
||||
pumpkin_data::block_properties::BLOCK_ENTITY_TYPES
|
||||
.iter()
|
||||
.position(|block_entity_name| {
|
||||
*block_entity_name == self.identifier().split(":").last().unwrap()
|
||||
*block_entity_name == self.resource_location().split(":").last().unwrap()
|
||||
})
|
||||
.unwrap() as u32
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ const SOURCE: &str = "source";
|
||||
|
||||
#[async_trait]
|
||||
impl BlockEntity for PistonBlockEntity {
|
||||
fn identifier(&self) -> &'static str {
|
||||
fn resource_location(&self) -> &'static str {
|
||||
Self::ID
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ impl Text {
|
||||
|
||||
#[async_trait]
|
||||
impl BlockEntity for SignBlockEntity {
|
||||
fn identifier(&self) -> &'static str {
|
||||
fn resource_location(&self) -> &'static str {
|
||||
Self::ID
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use pumpkin_data::tag::{RegistryKey, get_tag_values};
|
||||
use pumpkin_data::{Block, BlockDirection};
|
||||
use pumpkin_data::{BlockState, block_properties::BedPart};
|
||||
use pumpkin_protocol::server::play::SUseItemOn;
|
||||
use pumpkin_registry::DimensionType;
|
||||
use pumpkin_registry::VanillaDimensionType;
|
||||
use pumpkin_util::GameMode;
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
use pumpkin_util::text::TextComponent;
|
||||
@@ -159,7 +159,7 @@ impl PumpkinBlock for BedBlock {
|
||||
};
|
||||
|
||||
// Explode if not in the overworld
|
||||
if world.dimension_type != DimensionType::Overworld {
|
||||
if world.dimension_type != VanillaDimensionType::Overworld {
|
||||
world
|
||||
.break_block(&bed_head_pos, None, BlockFlags::SKIP_DROPS)
|
||||
.await;
|
||||
|
||||
@@ -64,7 +64,7 @@ impl PumpkinBlock for CommandBlock {
|
||||
if let Some((nbt, block_entity)) = world.get_block_entity(pos).await {
|
||||
let command_entity = CommandBlockEntity::from_nbt(&nbt, *pos);
|
||||
|
||||
if block_entity.identifier() != command_entity.identifier() {
|
||||
if block_entity.resource_location() != command_entity.resource_location() {
|
||||
return;
|
||||
}
|
||||
Self::update(
|
||||
@@ -82,7 +82,7 @@ impl PumpkinBlock for CommandBlock {
|
||||
if let Some((nbt, block_entity)) = world.get_block_entity(pos).await {
|
||||
let command_entity = CommandBlockEntity::from_nbt(&nbt, *pos);
|
||||
|
||||
if block_entity.identifier() != command_entity.identifier() {
|
||||
if block_entity.resource_location() != command_entity.resource_location() {
|
||||
return;
|
||||
}
|
||||
// TODO
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::world::World;
|
||||
use async_trait::async_trait;
|
||||
use pumpkin_data::{Block, BlockState};
|
||||
use pumpkin_macros::pumpkin_block;
|
||||
use pumpkin_registry::DimensionType;
|
||||
use pumpkin_registry::VanillaDimensionType;
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
use pumpkin_world::block::entities::end_portal::EndPortalBlockEntity;
|
||||
|
||||
@@ -25,12 +25,14 @@ impl PumpkinBlock for EndPortalBlock {
|
||||
_state: BlockState,
|
||||
server: &Server,
|
||||
) {
|
||||
let world = if world.dimension_type == DimensionType::TheEnd {
|
||||
let world = if world.dimension_type == VanillaDimensionType::TheEnd {
|
||||
server
|
||||
.get_world_from_dimension(DimensionType::Overworld)
|
||||
.get_world_from_dimension(VanillaDimensionType::Overworld)
|
||||
.await
|
||||
} else {
|
||||
server.get_world_from_dimension(DimensionType::TheEnd).await
|
||||
server
|
||||
.get_world_from_dimension(VanillaDimensionType::TheEnd)
|
||||
.await
|
||||
};
|
||||
entity.get_entity().try_use_portal(0, world, pos).await;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use pumpkin_data::block_properties::HorizontalAxis;
|
||||
use pumpkin_data::entity::EntityType;
|
||||
use pumpkin_registry::DimensionType;
|
||||
use pumpkin_registry::VanillaDimensionType;
|
||||
use pumpkin_world::world::BlockAccessor;
|
||||
use rand::Rng;
|
||||
use std::sync::Arc;
|
||||
@@ -51,7 +51,9 @@ impl PumpkinBlock for FireBlock {
|
||||
|
||||
let dimension = world.dimension_type;
|
||||
// First lets check if we are in OverWorld or Nether, its not possible to place an Nether portal in other dimensions in Vanilla
|
||||
if dimension == DimensionType::Overworld || dimension == DimensionType::TheNether {
|
||||
if dimension == VanillaDimensionType::Overworld
|
||||
|| dimension == VanillaDimensionType::TheNether
|
||||
{
|
||||
if let Some(portal) = NetherPortal::get_new_portal(world, pos, HorizontalAxis::X).await
|
||||
{
|
||||
portal.create(world).await;
|
||||
|
||||
@@ -10,7 +10,7 @@ use pumpkin_data::block_properties::{Axis, BlockProperties, NetherPortalLikeProp
|
||||
use pumpkin_data::entity::EntityType;
|
||||
use pumpkin_data::{Block, BlockDirection, BlockState};
|
||||
use pumpkin_macros::pumpkin_block;
|
||||
use pumpkin_registry::DimensionType;
|
||||
use pumpkin_registry::VanillaDimensionType;
|
||||
use pumpkin_util::GameMode;
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
use pumpkin_world::BlockStateId;
|
||||
@@ -70,13 +70,13 @@ impl PumpkinBlock for NetherPortalBlock {
|
||||
_state: BlockState,
|
||||
server: &Server,
|
||||
) {
|
||||
let target_world = if world.dimension_type == DimensionType::TheNether {
|
||||
let target_world = if world.dimension_type == VanillaDimensionType::TheNether {
|
||||
server
|
||||
.get_world_from_dimension(DimensionType::Overworld)
|
||||
.get_world_from_dimension(VanillaDimensionType::Overworld)
|
||||
.await
|
||||
} else {
|
||||
server
|
||||
.get_world_from_dimension(DimensionType::TheNether)
|
||||
.get_world_from_dimension(VanillaDimensionType::TheNether)
|
||||
.await
|
||||
};
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ use crate::command::{
|
||||
/// Command: playsound <sound> [<source>] [<targets>] [<pos>] [<volume>] [<pitch>] [<minVolume>]
|
||||
///
|
||||
/// Plays a sound at specified position for target players.
|
||||
/// - sound: The sound identifier to play
|
||||
/// - sound: The sound resource location to play
|
||||
/// - source: Sound category (master, music, record, etc.)
|
||||
/// - targets: Players who will hear the sound
|
||||
/// - pos: Position to play the sound from
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::command::{
|
||||
tree::{CommandTree, builder::argument},
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use pumpkin_protocol::codec::identifier::Identifier;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use pumpkin_util::text::TextComponent;
|
||||
|
||||
const NAMES: [&str; 1] = ["stopsound"];
|
||||
@@ -39,7 +39,7 @@ impl CommandExecutor for Executor {
|
||||
sound
|
||||
.as_ref()
|
||||
.cloned()
|
||||
.map(|s| Identifier::vanilla(s.to_name()))
|
||||
.map(|s| ResourceLocation::vanilla(s.to_name()))
|
||||
.ok(),
|
||||
category.as_ref().map(|s| **s).ok(),
|
||||
)
|
||||
|
||||
@@ -20,7 +20,7 @@ use pumpkin_protocol::{
|
||||
codec::var_int::VarInt,
|
||||
ser::serializer::Serializer,
|
||||
};
|
||||
use pumpkin_registry::DimensionType;
|
||||
use pumpkin_registry::VanillaDimensionType;
|
||||
use pumpkin_util::math::{
|
||||
boundingbox::{BoundingBox, EntityDimensions},
|
||||
get_section_cord,
|
||||
@@ -324,15 +324,16 @@ impl Entity {
|
||||
.store(self.default_portal_cooldown(), Ordering::Relaxed);
|
||||
let pos = self.pos.load();
|
||||
// TODO: this is bad
|
||||
let scale_factor_new =
|
||||
if portal_manager.portal_world.dimension_type == DimensionType::TheNether {
|
||||
8.0
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
let scale_factor_new = if portal_manager.portal_world.dimension_type
|
||||
== VanillaDimensionType::TheNether
|
||||
{
|
||||
8.0
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
// TODO: this is bad
|
||||
let scale_factor_current =
|
||||
if self.world.read().await.dimension_type == DimensionType::TheNether {
|
||||
if self.world.read().await.dimension_type == VanillaDimensionType::TheNether {
|
||||
8.0
|
||||
} else {
|
||||
1.0
|
||||
|
||||
@@ -44,7 +44,6 @@ use pumpkin_protocol::client::play::{
|
||||
CSubtitle, CSystemChatMessage, CTitleText, CUnloadChunk, CUpdateMobEffect, CUpdateTime,
|
||||
GameEvent, MetaDataType, Metadata, PlayerAction, PlayerInfoFlags, PreviousMessage,
|
||||
};
|
||||
use pumpkin_protocol::codec::identifier::Identifier;
|
||||
use pumpkin_protocol::codec::var_int::VarInt;
|
||||
use pumpkin_protocol::ser::packet::Packet;
|
||||
use pumpkin_protocol::server::play::{
|
||||
@@ -56,12 +55,13 @@ use pumpkin_protocol::server::play::{
|
||||
SSetCreativeSlot, SSetHeldItem, SSetPlayerGround, SSwingArm, SUpdateSign, SUseItem, SUseItemOn,
|
||||
};
|
||||
use pumpkin_protocol::{IdOr, RawPacket, ServerPacket};
|
||||
use pumpkin_registry::DimensionType;
|
||||
use pumpkin_registry::VanillaDimensionType;
|
||||
use pumpkin_util::GameMode;
|
||||
use pumpkin_util::math::{
|
||||
boundingbox::BoundingBox, experience, position::BlockPos, vector2::Vector2, vector3::Vector3,
|
||||
};
|
||||
use pumpkin_util::permission::PermissionLvl;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use pumpkin_util::text::TextComponent;
|
||||
use pumpkin_world::biome;
|
||||
use pumpkin_world::cylindrical_chunk_iterator::Cylindrical;
|
||||
@@ -512,7 +512,7 @@ impl Player {
|
||||
|
||||
pub async fn set_respawn_point(
|
||||
&self,
|
||||
dimension: DimensionType,
|
||||
dimension: VanillaDimensionType,
|
||||
block_pos: BlockPos,
|
||||
yaw: f32,
|
||||
) -> bool {
|
||||
@@ -544,12 +544,12 @@ impl Player {
|
||||
.get_block_and_block_state(&respawn_point.position)
|
||||
.await;
|
||||
|
||||
if respawn_point.dimension == DimensionType::Overworld
|
||||
if respawn_point.dimension == VanillaDimensionType::Overworld
|
||||
&& block.is_tagged_with("#minecraft:beds").unwrap()
|
||||
{
|
||||
// TODO: calculate respawn position
|
||||
Some((respawn_point.position.to_f64(), respawn_point.yaw))
|
||||
} else if respawn_point.dimension == DimensionType::TheNether
|
||||
} else if respawn_point.dimension == VanillaDimensionType::TheNether
|
||||
&& block == Block::RESPAWN_ANCHOR
|
||||
{
|
||||
// TODO: calculate respawn position
|
||||
@@ -679,9 +679,13 @@ impl Player {
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `sound_id`: An optional `Identifier` specifying the sound to stop. If `None`, all sounds in the specified category (if any) will be stopped.
|
||||
/// * `category`: An optional `SoundCategory` specifying the sound category to stop. If `None`, all sounds with the specified identifier (if any) will be stopped.
|
||||
pub async fn stop_sound(&self, sound_id: Option<Identifier>, category: Option<SoundCategory>) {
|
||||
/// * `sound_id`: An optional [`ResourceLocation`] specifying the sound to stop. If [`None`], all sounds in the specified category (if any) will be stopped.
|
||||
/// * `category`: An optional [`SoundCategory`] specifying the sound category to stop. If [`None`], all sounds with the specified resource location (if any) will be stopped.
|
||||
pub async fn stop_sound(
|
||||
&self,
|
||||
sound_id: Option<ResourceLocation>,
|
||||
category: Option<SoundCategory>,
|
||||
) {
|
||||
self.client
|
||||
.enqueue_packet(&CStopSound::new(sound_id, category))
|
||||
.await;
|
||||
@@ -1049,7 +1053,7 @@ impl Player {
|
||||
self.unload_watched_chunks(¤t_world).await;
|
||||
|
||||
let last_pos = self.living_entity.last_pos.load();
|
||||
let death_dimension = self.world().await.dimension_type.name();
|
||||
let death_dimension = self.world().await.dimension_type.resource_location();
|
||||
let death_location = BlockPos(Vector3::new(
|
||||
last_pos.x.round() as i32,
|
||||
last_pos.y.round() as i32,
|
||||
@@ -1058,7 +1062,7 @@ impl Player {
|
||||
self.client
|
||||
.send_packet_now(&CRespawn::new(
|
||||
(new_world.dimension_type as u8).into(),
|
||||
new_world.dimension_type.name(),
|
||||
new_world.dimension_type.resource_location(),
|
||||
biome::hash_seed(new_world.level.seed.0), // seed
|
||||
self.gamemode.load() as u8,
|
||||
self.gamemode.load() as i8,
|
||||
@@ -1867,7 +1871,14 @@ impl NBTStorage for Player {
|
||||
// Store food level, saturation, exhaustion, and tick timer
|
||||
self.hunger_manager.write_nbt(nbt).await;
|
||||
|
||||
nbt.put_string("Dimension", self.world().await.dimension_type.name().get());
|
||||
nbt.put_string(
|
||||
"Dimension",
|
||||
self.world()
|
||||
.await
|
||||
.dimension_type
|
||||
.resource_location()
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
async fn read_nbt(&mut self, nbt: &mut NbtCompound) {
|
||||
@@ -2282,7 +2293,7 @@ impl TryFrom<i32> for Hand {
|
||||
/// Represents the player's respawn point.
|
||||
#[derive(Copy, Debug, Clone, PartialEq)]
|
||||
pub struct RespawnPoint {
|
||||
pub dimension: DimensionType,
|
||||
pub dimension: VanillaDimensionType,
|
||||
pub position: BlockPos,
|
||||
pub yaw: f32,
|
||||
pub force: bool,
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::sync::Arc;
|
||||
use crate::entity::player::Player;
|
||||
use async_trait::async_trait;
|
||||
use pumpkin_data::{Block, BlockState, fluid::Fluid, item::Item};
|
||||
use pumpkin_registry::DimensionType;
|
||||
use pumpkin_registry::VanillaDimensionType;
|
||||
use pumpkin_util::{
|
||||
GameMode,
|
||||
math::{position::BlockPos, vector3::Vector3},
|
||||
@@ -211,7 +211,9 @@ impl PumpkinItem for FilledBucketItem {
|
||||
return;
|
||||
};
|
||||
|
||||
if item.id != Item::LAVA_BUCKET.id && world.dimension_type == DimensionType::TheNether {
|
||||
if item.id != Item::LAVA_BUCKET.id
|
||||
&& world.dimension_type == VanillaDimensionType::TheNether
|
||||
{
|
||||
return;
|
||||
}
|
||||
let (block, state) = world.get_block_and_block_state(&pos).await;
|
||||
|
||||
@@ -592,7 +592,7 @@ impl Player {
|
||||
if let Some((nbt, block_entity)) = self.world().await.get_block_entity(&pos).await {
|
||||
let command_entity = CommandBlockEntity::from_nbt(&nbt, pos);
|
||||
|
||||
if block_entity.identifier() != command_entity.identifier() {
|
||||
if block_entity.resource_location() != command_entity.resource_location() {
|
||||
log::warn!(
|
||||
"Client tried to change Command block but not Command block entity found"
|
||||
);
|
||||
|
||||
@@ -22,7 +22,7 @@ use pumpkin_protocol::client::login::CEncryptionRequest;
|
||||
use pumpkin_protocol::client::play::CChangeDifficulty;
|
||||
use pumpkin_protocol::client::play::CSetSelectedSlot;
|
||||
use pumpkin_protocol::{ClientPacket, client::config::CPluginMessage};
|
||||
use pumpkin_registry::{DimensionType, Registry};
|
||||
use pumpkin_registry::{Registry, VanillaDimensionType};
|
||||
use pumpkin_util::Difficulty;
|
||||
use pumpkin_util::math::vector2::Vector2;
|
||||
use pumpkin_util::text::TextComponent;
|
||||
@@ -70,7 +70,7 @@ pub struct Server {
|
||||
/// Manages multiple worlds within the server.
|
||||
pub worlds: RwLock<Vec<Arc<World>>>,
|
||||
/// All the dimensions that exist on the server.
|
||||
pub dimensions: Vec<DimensionType>,
|
||||
pub dimensions: Vec<VanillaDimensionType>,
|
||||
/// Caches game registries for efficient access.
|
||||
pub cached_registry: Vec<Registry>,
|
||||
/// Assigns unique IDs to containers.
|
||||
@@ -148,21 +148,21 @@ impl Server {
|
||||
let overworld = World::load(
|
||||
Dimension::Overworld.into_level(world_path.clone(), block_registry.clone(), seed),
|
||||
level_info.clone(),
|
||||
DimensionType::Overworld,
|
||||
VanillaDimensionType::Overworld,
|
||||
block_registry.clone(),
|
||||
);
|
||||
log::info!("Loading Nether: {seed}");
|
||||
let nether = World::load(
|
||||
Dimension::Nether.into_level(world_path.clone(), block_registry.clone(), seed),
|
||||
level_info.clone(),
|
||||
DimensionType::TheNether,
|
||||
VanillaDimensionType::TheNether,
|
||||
block_registry.clone(),
|
||||
);
|
||||
log::info!("Loading End: {seed}");
|
||||
let end = World::load(
|
||||
Dimension::End.into_level(world_path.clone(), block_registry.clone(), seed),
|
||||
level_info.clone(),
|
||||
DimensionType::TheEnd,
|
||||
VanillaDimensionType::TheEnd,
|
||||
block_registry.clone(),
|
||||
);
|
||||
|
||||
@@ -177,10 +177,10 @@ impl Server {
|
||||
container_id: 0.into(),
|
||||
worlds: RwLock::new(vec![Arc::new(overworld), Arc::new(nether), Arc::new(end)]),
|
||||
dimensions: vec![
|
||||
DimensionType::Overworld,
|
||||
DimensionType::OverworldCaves,
|
||||
DimensionType::TheNether,
|
||||
DimensionType::TheEnd,
|
||||
VanillaDimensionType::Overworld,
|
||||
VanillaDimensionType::OverworldCaves,
|
||||
VanillaDimensionType::TheNether,
|
||||
VanillaDimensionType::TheEnd,
|
||||
],
|
||||
command_dispatcher,
|
||||
block_registry,
|
||||
@@ -228,14 +228,14 @@ impl Server {
|
||||
self.tasks.spawn(task)
|
||||
}
|
||||
|
||||
pub async fn get_world_from_dimension(&self, dimension: DimensionType) -> Arc<World> {
|
||||
pub async fn get_world_from_dimension(&self, dimension: VanillaDimensionType) -> Arc<World> {
|
||||
// TODO: this is really bad
|
||||
let world_guard = self.worlds.read().await;
|
||||
let world = match dimension {
|
||||
DimensionType::Overworld => world_guard.first(),
|
||||
DimensionType::OverworldCaves => todo!(),
|
||||
DimensionType::TheEnd => world_guard.get(2),
|
||||
DimensionType::TheNether => world_guard.get(1),
|
||||
VanillaDimensionType::Overworld => world_guard.first(),
|
||||
VanillaDimensionType::OverworldCaves => todo!(),
|
||||
VanillaDimensionType::TheEnd => world_guard.get(2),
|
||||
VanillaDimensionType::TheNether => world_guard.get(1),
|
||||
};
|
||||
world.cloned().unwrap()
|
||||
}
|
||||
@@ -272,7 +272,9 @@ impl Server {
|
||||
|
||||
let (world, nbt) = if let Ok(Some(data)) = self.player_data_storage.load_data(&uuid) {
|
||||
if let Some(dimension_key) = data.get_string("Dimension") {
|
||||
if let Some(dimension) = DimensionType::from_name(dimension_key) {
|
||||
if let Some(dimension) =
|
||||
VanillaDimensionType::from_resource_location_string(dimension_key)
|
||||
{
|
||||
let world = self.get_world_from_dimension(dimension).await;
|
||||
(world, Some(data))
|
||||
} else {
|
||||
|
||||
@@ -44,7 +44,6 @@ use pumpkin_data::{BlockDirection, block_properties::get_block_outline_shapes};
|
||||
use pumpkin_inventory::equipment_slot::EquipmentSlot;
|
||||
use pumpkin_macros::send_cancellable;
|
||||
use pumpkin_nbt::{compound::NbtCompound, to_bytes_unnamed};
|
||||
use pumpkin_protocol::codec::identifier::Identifier;
|
||||
use pumpkin_protocol::ser::serializer::Serializer;
|
||||
use pumpkin_protocol::{
|
||||
ClientPacket, IdOr, SoundEvent,
|
||||
@@ -68,8 +67,9 @@ use pumpkin_protocol::{
|
||||
},
|
||||
codec::var_int::VarInt,
|
||||
};
|
||||
use pumpkin_registry::DimensionType;
|
||||
use pumpkin_registry::VanillaDimensionType;
|
||||
use pumpkin_util::math::{position::chunk_section_from_pos, vector2::Vector2};
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use pumpkin_util::text::{TextComponent, color::NamedColor};
|
||||
use pumpkin_util::{
|
||||
Difficulty,
|
||||
@@ -141,7 +141,7 @@ pub struct World {
|
||||
/// The world's time, including counting ticks for weather, time cycles, and statistics.
|
||||
pub level_time: Mutex<LevelTime>,
|
||||
/// The type of dimension the world is in.
|
||||
pub dimension_type: DimensionType,
|
||||
pub dimension_type: VanillaDimensionType,
|
||||
pub sea_level: i32,
|
||||
/// The world's weather, including rain and thunder levels.
|
||||
pub weather: Mutex<Weather>,
|
||||
@@ -157,17 +157,21 @@ impl World {
|
||||
pub fn load(
|
||||
level: Level,
|
||||
level_info: LevelData,
|
||||
dimension_type: DimensionType,
|
||||
dimension_type: VanillaDimensionType,
|
||||
block_registry: Arc<BlockRegistry>,
|
||||
) -> Self {
|
||||
// TODO
|
||||
let generation_settings = match dimension_type {
|
||||
DimensionType::Overworld => GENERATION_SETTINGS
|
||||
VanillaDimensionType::Overworld => GENERATION_SETTINGS
|
||||
.get(&GeneratorSetting::Overworld)
|
||||
.unwrap(),
|
||||
DimensionType::OverworldCaves => todo!(),
|
||||
DimensionType::TheEnd => GENERATION_SETTINGS.get(&GeneratorSetting::End).unwrap(),
|
||||
DimensionType::TheNether => GENERATION_SETTINGS.get(&GeneratorSetting::Nether).unwrap(),
|
||||
VanillaDimensionType::OverworldCaves => todo!(),
|
||||
VanillaDimensionType::TheEnd => {
|
||||
GENERATION_SETTINGS.get(&GeneratorSetting::End).unwrap()
|
||||
}
|
||||
VanillaDimensionType::TheNether => {
|
||||
GENERATION_SETTINGS.get(&GeneratorSetting::Nether).unwrap()
|
||||
}
|
||||
};
|
||||
|
||||
Self {
|
||||
@@ -521,12 +525,16 @@ impl World {
|
||||
pub async fn get_top_block(&self, position: Vector2<i32>) -> i32 {
|
||||
// TODO: this is bad
|
||||
let generation_settings = match self.dimension_type {
|
||||
DimensionType::Overworld => GENERATION_SETTINGS
|
||||
VanillaDimensionType::Overworld => GENERATION_SETTINGS
|
||||
.get(&GeneratorSetting::Overworld)
|
||||
.unwrap(),
|
||||
DimensionType::OverworldCaves => todo!(),
|
||||
DimensionType::TheEnd => GENERATION_SETTINGS.get(&GeneratorSetting::End).unwrap(),
|
||||
DimensionType::TheNether => GENERATION_SETTINGS.get(&GeneratorSetting::Nether).unwrap(),
|
||||
VanillaDimensionType::OverworldCaves => todo!(),
|
||||
VanillaDimensionType::TheEnd => {
|
||||
GENERATION_SETTINGS.get(&GeneratorSetting::End).unwrap()
|
||||
}
|
||||
VanillaDimensionType::TheNether => {
|
||||
GENERATION_SETTINGS.get(&GeneratorSetting::Nether).unwrap()
|
||||
}
|
||||
};
|
||||
for y in (i32::from(generation_settings.shape.min_y)
|
||||
..=i32::from(generation_settings.shape.height))
|
||||
@@ -549,8 +557,11 @@ impl World {
|
||||
player: Arc<Player>,
|
||||
server: &Server,
|
||||
) {
|
||||
let dimensions: Vec<Identifier> =
|
||||
server.dimensions.iter().map(DimensionType::name).collect();
|
||||
let dimensions: Vec<ResourceLocation> = server
|
||||
.dimensions
|
||||
.iter()
|
||||
.map(VanillaDimensionType::resource_location)
|
||||
.collect();
|
||||
|
||||
// This code follows the vanilla packet order
|
||||
let entity_id = player.entity_id();
|
||||
@@ -575,7 +586,7 @@ impl World {
|
||||
true,
|
||||
false,
|
||||
(self.dimension_type as u8).into(),
|
||||
self.dimension_type.name(),
|
||||
self.dimension_type.resource_location(),
|
||||
biome::hash_seed(self.level.seed.0), // seed
|
||||
gamemode as u8,
|
||||
player
|
||||
@@ -941,7 +952,7 @@ impl World {
|
||||
|
||||
pub async fn respawn_player(&self, player: &Arc<Player>, alive: bool) {
|
||||
let last_pos = player.living_entity.last_pos.load();
|
||||
let death_dimension = player.world().await.dimension_type.name();
|
||||
let death_dimension = player.world().await.dimension_type.resource_location();
|
||||
let death_location = BlockPos(Vector3::new(
|
||||
last_pos.x.round() as i32,
|
||||
last_pos.y.round() as i32,
|
||||
@@ -956,7 +967,7 @@ impl World {
|
||||
.client
|
||||
.enqueue_packet(&CRespawn::new(
|
||||
(self.dimension_type as u8).into(),
|
||||
self.dimension_type.name(),
|
||||
self.dimension_type.resource_location(),
|
||||
biome::hash_seed(self.level.seed.0), // seed
|
||||
player.gamemode.load() as u8,
|
||||
player.gamemode.load() as i8,
|
||||
|
||||
Reference in New Issue
Block a user