mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
removed some clones
fix: https://github.com/Pumpkin-MC/Pumpkin/issues/1226
This commit is contained in:
155
Cargo.lock
generated
155
Cargo.lock
generated
@@ -2,15 +2,6 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.25.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.1"
|
||||
@@ -134,9 +125,9 @@ checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
|
||||
|
||||
[[package]]
|
||||
name = "async-compression"
|
||||
version = "0.4.34"
|
||||
version = "0.4.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e86f6d3dc9dc4352edeea6b8e499e13e3f5dc3b964d7ca5fd411415a3498473"
|
||||
checksum = "07a926debf178f2d355197f9caddb08e54a9329d44748034bba349c5848cb519"
|
||||
dependencies = [
|
||||
"compression-codecs",
|
||||
"compression-core",
|
||||
@@ -211,21 +202,6 @@ dependencies = [
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base16ct"
|
||||
version = "0.2.0"
|
||||
@@ -252,9 +228,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.8.0"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba"
|
||||
checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
@@ -306,9 +282,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.48"
|
||||
version = "1.2.49"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c481bdbf0ed3b892f6f806287d72acd515b352a4ec27a208489b8c1bc839633a"
|
||||
checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"shlex",
|
||||
@@ -425,9 +401,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "compression-codecs"
|
||||
version = "0.4.33"
|
||||
version = "0.4.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "302266479cb963552d11bd042013a58ef1adc56768016c8b82b4199488f2d4ad"
|
||||
checksum = "34a3cbbb8b6eca96f3a5c4bf6938d5b27ced3675d69f95bb51948722870bc323"
|
||||
dependencies = [
|
||||
"compression-core",
|
||||
"flate2",
|
||||
@@ -576,9 +552,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "criterion"
|
||||
version = "0.8.0"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0dfe5e9e71bdcf4e4954f7d14da74d1cdb92a3a07686452d1509652684b1aab"
|
||||
checksum = "4d883447757bb0ee46f233e9dc22eb84d93a9508c9b868687b274fc431d886bf"
|
||||
dependencies = [
|
||||
"alloca",
|
||||
"anes",
|
||||
@@ -600,9 +576,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "criterion-plot"
|
||||
version = "0.8.0"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5de36c2bee19fba779808f92bf5d9b0fa5a40095c277aba10c458a12b35d21d6"
|
||||
checksum = "ed943f81ea2faa8dcecbbfa50164acf95d555afec96a27871663b300e387b2e4"
|
||||
dependencies = [
|
||||
"cast",
|
||||
"itertools 0.13.0",
|
||||
@@ -832,22 +808,6 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dhat"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98cd11d84628e233de0ce467de10b8633f4ddaecafadefc86e13b84b8739b827"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"lazy_static",
|
||||
"mintex",
|
||||
"parking_lot",
|
||||
"rustc-hash 1.1.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thousands",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
@@ -1008,9 +968,9 @@ checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.7"
|
||||
version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2152dbcb980c05735e2a651d96011320a949eb31a0c8b38b72645ce97dec676"
|
||||
checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
@@ -1160,12 +1120,6 @@ dependencies = [
|
||||
"wasip2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.32.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7"
|
||||
|
||||
[[package]]
|
||||
name = "group"
|
||||
version = "0.13.0"
|
||||
@@ -1666,15 +1620,6 @@ version = "0.11.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08ab2867e3eeeca90e844d1940eab391c9dc5228783db2ed999acbc0a9ed375a"
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9"
|
||||
dependencies = [
|
||||
"regex-automata",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matchit"
|
||||
version = "0.8.4"
|
||||
@@ -1725,12 +1670,6 @@ dependencies = [
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mintex"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c505b3e17ed6b70a7ed2e67fbb2c560ee327353556120d6e72f5232b6880d536"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.1.1"
|
||||
@@ -1817,15 +1756,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.37.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
@@ -2171,13 +2101,13 @@ dependencies = [
|
||||
"bytes",
|
||||
"console-subscriber",
|
||||
"crossbeam",
|
||||
"dhat",
|
||||
"flate2",
|
||||
"futures",
|
||||
"hmac 0.13.0-rc.3",
|
||||
"libloading",
|
||||
"log",
|
||||
"num-bigint",
|
||||
"pkcs8 0.11.0-rc.8",
|
||||
"pumpkin-config",
|
||||
"pumpkin-data",
|
||||
"pumpkin-inventory",
|
||||
@@ -2188,10 +2118,8 @@ dependencies = [
|
||||
"pumpkin-util",
|
||||
"pumpkin-world",
|
||||
"rand",
|
||||
"rayon",
|
||||
"rsa",
|
||||
"rsa-der",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustc-hash",
|
||||
"rustyline-async",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -2265,7 +2193,6 @@ dependencies = [
|
||||
name = "pumpkin-macros"
|
||||
version = "0.1.0-dev+1.21.10"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2367,8 +2294,7 @@ dependencies = [
|
||||
"pumpkin-nbt",
|
||||
"pumpkin-util",
|
||||
"rand",
|
||||
"rayon",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustc-hash",
|
||||
"ruzstd",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -2526,27 +2452,6 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rsa-der"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a19473b2de3164677ff38e4309c42448ba8d0fe5ad5fa722e7d278f991859aa6"
|
||||
dependencies = [
|
||||
"simple_asn1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
@@ -2858,18 +2763,6 @@ version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||
|
||||
[[package]]
|
||||
name = "simple_asn1"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"thiserror",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simplelog"
|
||||
version = "0.12.2"
|
||||
@@ -2896,9 +2789,9 @@ checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
|
||||
|
||||
[[package]]
|
||||
name = "slotmap"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "811fec94324ff439b2d5e4a1cf88cc5b6c09d92358715d600b2fe91c0489b5cb"
|
||||
checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
@@ -3054,12 +2947,6 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thousands"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820"
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.9"
|
||||
@@ -3323,12 +3210,8 @@ version = "0.3.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e"
|
||||
dependencies = [
|
||||
"matchers",
|
||||
"once_cell",
|
||||
"regex-automata",
|
||||
"sharded-slab",
|
||||
"thread_local",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
|
||||
@@ -284,7 +284,7 @@ impl ToTokens for ItemComponents {
|
||||
.clone()
|
||||
.map(|list| {
|
||||
let vec: Vec<_> = list
|
||||
.get_values()
|
||||
.into_vec()
|
||||
.iter()
|
||||
.map(|reg| {
|
||||
match reg {
|
||||
|
||||
@@ -1025,7 +1025,7 @@ pub trait ScreenHandlerListener: Send + Sync {
|
||||
_slot: u8,
|
||||
_stack: ItemStack,
|
||||
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
fn on_property_update<'a>(
|
||||
&'a self,
|
||||
@@ -1033,7 +1033,7 @@ pub trait ScreenHandlerListener: Send + Sync {
|
||||
_property: u8,
|
||||
_value: i32,
|
||||
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ pub trait Slot: Send + Sync + Debug {
|
||||
_stack: ItemStack,
|
||||
_stack_prev: ItemStack,
|
||||
) -> BoxFuture<'_, ()> {
|
||||
Box::pin(async move {}) // Default implementation
|
||||
Box::pin(async {}) // Default implementation
|
||||
}
|
||||
|
||||
/// Callback for when an item is taken from the slot.
|
||||
@@ -57,7 +57,7 @@ pub trait Slot: Send + Sync + Debug {
|
||||
|
||||
// Used for plugins
|
||||
fn on_click(&self, _player: &dyn InventoryPlayer) -> BoxFuture<'_, ()> {
|
||||
Box::pin(async move {}) // Default implementation
|
||||
Box::pin(async {}) // Default implementation
|
||||
}
|
||||
|
||||
fn can_insert<'a>(&'a self, _stack: &'a ItemStack) -> BoxFuture<'a, bool> {
|
||||
|
||||
@@ -9,7 +9,6 @@ proc-macro = true
|
||||
[dependencies]
|
||||
proc-macro-error2.workspace = true
|
||||
|
||||
heck = "0.5"
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn.workspace = true
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
use heck::{ToPascalCase, ToSnakeCase};
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro_error2::{abort, abort_call_site, proc_macro_error};
|
||||
use quote::quote;
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{self, Attribute, Type};
|
||||
use syn::{
|
||||
Block, Expr, Field, Fields, ItemStruct, Stmt,
|
||||
parse::{Nothing, Parser},
|
||||
parse_macro_input,
|
||||
};
|
||||
use syn::{self, Attribute, DeriveInput, LitStr, Type, parse_quote};
|
||||
use syn::{Block, Expr, Field, Fields, ItemStruct, Stmt, parse_macro_input};
|
||||
|
||||
#[proc_macro_derive(Event)]
|
||||
pub fn event(item: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(item as ItemStruct);
|
||||
let name = &input.ident;
|
||||
let ast = parse_macro_input!(item as DeriveInput);
|
||||
let name = &ast.ident;
|
||||
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
|
||||
|
||||
quote! {
|
||||
impl crate::plugin::Payload for #name {
|
||||
impl #impl_generics crate::plugin::Payload for #name #ty_generics #where_clause {
|
||||
fn get_name_static() -> &'static str {
|
||||
stringify!(#name)
|
||||
}
|
||||
@@ -38,26 +34,36 @@ pub fn event(item: TokenStream) -> TokenStream {
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn cancellable(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
pub fn cancellable(_args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let mut item_struct = parse_macro_input!(input as ItemStruct);
|
||||
let name = item_struct.ident.clone();
|
||||
let _ = parse_macro_input!(args as Nothing);
|
||||
let name = &item_struct.ident;
|
||||
let (impl_generics, ty_generics, where_clause) = item_struct.generics.split_for_impl();
|
||||
|
||||
if let Fields::Named(ref mut fields) = item_struct.fields {
|
||||
fields.named.push(
|
||||
Field::parse_named
|
||||
.parse2(quote! {
|
||||
/// A boolean indicating cancel state of the event.
|
||||
pub cancelled: bool
|
||||
})
|
||||
.unwrap(),
|
||||
);
|
||||
match &mut item_struct.fields {
|
||||
Fields::Named(fields) => {
|
||||
if fields
|
||||
.named
|
||||
.iter()
|
||||
.any(|f| f.ident.as_ref().map(|i| i == "cancelled").unwrap_or(false))
|
||||
{
|
||||
abort!(fields.span(), "Struct already has a `cancelled` field");
|
||||
}
|
||||
|
||||
let field: Field = parse_quote! {
|
||||
pub cancelled: bool
|
||||
};
|
||||
fields.named.push(field);
|
||||
}
|
||||
_ => abort!(
|
||||
item_struct.span(),
|
||||
"#[cancellable] can only be used on structs with named fields"
|
||||
),
|
||||
}
|
||||
|
||||
quote! {
|
||||
#item_struct
|
||||
|
||||
impl crate::plugin::Cancellable for #name {
|
||||
impl #impl_generics crate::plugin::Cancellable for #name #ty_generics #where_clause {
|
||||
fn cancelled(&self) -> bool {
|
||||
self.cancelled
|
||||
}
|
||||
@@ -73,115 +79,116 @@ pub fn cancellable(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
#[proc_macro_error]
|
||||
#[proc_macro]
|
||||
pub fn send_cancellable(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as Block);
|
||||
let block = parse_macro_input!(input as Block);
|
||||
|
||||
let mut event = None;
|
||||
let mut event_expr = None;
|
||||
let mut after_block = None;
|
||||
let mut cancelled_block = None;
|
||||
|
||||
for stmt in input.stmts {
|
||||
if let Stmt::Expr(expr, _) = stmt {
|
||||
if event.is_none() {
|
||||
event = Some(expr);
|
||||
} else if let Expr::Block(b) = expr
|
||||
&& let Some(ref label) = b.label
|
||||
{
|
||||
if label.name.ident == "after" {
|
||||
after_block = Some(b);
|
||||
} else if label.name.ident == "cancelled" {
|
||||
cancelled_block = Some(b);
|
||||
for stmt in block.stmts {
|
||||
match stmt {
|
||||
Stmt::Expr(expr, _) => {
|
||||
// Check if it is a labeled block first
|
||||
let mut is_special_block = false;
|
||||
if let Expr::Block(ref b) = expr
|
||||
&& let Some(ref label) = b.label
|
||||
{
|
||||
let label_name = label.name.ident.to_string();
|
||||
if label_name == "after" {
|
||||
after_block = Some(b.clone()); // Clone strictly necessary here as we split AST
|
||||
is_special_block = true;
|
||||
} else if label_name == "cancelled" {
|
||||
cancelled_block = Some(b.clone());
|
||||
is_special_block = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If it wasn't a special block, it must be the event expression
|
||||
if !is_special_block {
|
||||
if event_expr.is_some() {
|
||||
abort!(
|
||||
expr.span(),
|
||||
"Multiple event expressions found. Only one event expression allowed."
|
||||
);
|
||||
}
|
||||
event_expr = Some(expr);
|
||||
}
|
||||
}
|
||||
// Abort on other statements (like `let x = ...`) if strictness is desired
|
||||
_ => abort!(
|
||||
stmt.span(),
|
||||
"Only event expressions and labeled blocks allowed in `send_cancellable!`"
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(event) = event {
|
||||
if let Some(after_block) = after_block {
|
||||
if let Some(cancelled_block) = cancelled_block {
|
||||
quote! {
|
||||
let event = crate::PLUGIN_MANAGER
|
||||
.fire(#event)
|
||||
.await;
|
||||
let event = match event_expr {
|
||||
Some(e) => e,
|
||||
None => abort_call_site!("Event expression must be specified"),
|
||||
};
|
||||
|
||||
if !event.cancelled {
|
||||
#after_block
|
||||
} else {
|
||||
#cancelled_block
|
||||
}
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
quote! {
|
||||
let event = crate::PLUGIN_MANAGER
|
||||
.fire(#event)
|
||||
.await;
|
||||
// Construct the if/else logic
|
||||
let logic = match (after_block, cancelled_block) {
|
||||
(Some(after), Some(cancelled)) => quote! {
|
||||
if !event.cancelled { #after } else { #cancelled }
|
||||
},
|
||||
(Some(after), None) => quote! {
|
||||
if !event.cancelled { #after }
|
||||
},
|
||||
(None, Some(cancelled)) => quote! {
|
||||
if event.cancelled { #cancelled }
|
||||
},
|
||||
(None, None) => quote! {},
|
||||
};
|
||||
|
||||
if !event.cancelled {
|
||||
#after_block
|
||||
}
|
||||
}
|
||||
.into()
|
||||
}
|
||||
} else if let Some(cancelled_block) = cancelled_block {
|
||||
quote! {
|
||||
let event = crate::PLUGIN_MANAGER
|
||||
.fire(#event)
|
||||
.await;
|
||||
|
||||
if event.cancelled {
|
||||
#cancelled_block
|
||||
}
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
quote! {
|
||||
let event = crate::PLUGIN_MANAGER
|
||||
.fire(#event)
|
||||
.await;
|
||||
}
|
||||
.into()
|
||||
}
|
||||
} else {
|
||||
abort_call_site!("Event must be specified");
|
||||
quote! {
|
||||
let event = crate::PLUGIN_MANAGER.fire(#event).await;
|
||||
#logic
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn packet(input: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let ast: syn::DeriveInput = syn::parse(item.clone()).unwrap();
|
||||
pub fn packet(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let packet_id_expr = parse_macro_input!(args as Expr);
|
||||
let ast = parse_macro_input!(item as DeriveInput);
|
||||
|
||||
let name = &ast.ident;
|
||||
let (impl_generics, ty_generics, _) = ast.generics.split_for_impl();
|
||||
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
|
||||
|
||||
let input: proc_macro2::TokenStream = input.into();
|
||||
let item: proc_macro2::TokenStream = item.into();
|
||||
quote! {
|
||||
#ast
|
||||
impl #impl_generics crate::packet::Packet for #name #ty_generics #where_clause {
|
||||
const PACKET_ID: i32 = #packet_id_expr;
|
||||
}
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
let code = quote! {
|
||||
#item
|
||||
impl #impl_generics crate::packet::Packet for #name #ty_generics {
|
||||
const PACKET_ID: i32 = #input;
|
||||
#[proc_macro_attribute]
|
||||
pub fn pumpkin_block(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let arg_lit = parse_macro_input!(args as LitStr);
|
||||
let arg_value = arg_lit.value();
|
||||
|
||||
let (namespace, id) = match arg_value.split_once(':') {
|
||||
Some(pair) => pair,
|
||||
None => {
|
||||
return syn::Error::new(
|
||||
arg_lit.span(),
|
||||
"Expected format \"namespace:id\" (e.g. \"minecraft:stone\")",
|
||||
)
|
||||
.to_compile_error()
|
||||
.into();
|
||||
}
|
||||
};
|
||||
|
||||
code.into()
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn pumpkin_block(input: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let ast: syn::DeriveInput = syn::parse(item.clone()).unwrap();
|
||||
let ast = parse_macro_input!(item as DeriveInput);
|
||||
let name = &ast.ident;
|
||||
let (impl_generics, ty_generics, _) = ast.generics.split_for_impl();
|
||||
|
||||
let input_string = input.to_string();
|
||||
let packet_name = input_string.trim_matches('"');
|
||||
let (namespace, id) = packet_name
|
||||
.split_once(":")
|
||||
.unwrap_or_else(|| abort!(packet_name, "A namespace is required!"));
|
||||
|
||||
let item: proc_macro2::TokenStream = item.into();
|
||||
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
|
||||
|
||||
let code = quote! {
|
||||
#item
|
||||
impl #impl_generics crate::block::BlockMetadata for #name #ty_generics {
|
||||
#ast
|
||||
impl #impl_generics crate::block::BlockMetadata for #name #ty_generics #where_clause {
|
||||
fn namespace(&self) -> &'static str {
|
||||
#namespace
|
||||
}
|
||||
@@ -195,182 +202,183 @@ pub fn pumpkin_block(input: TokenStream, item: TokenStream) -> TokenStream {
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn pumpkin_block_from_tag(input: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let ast: syn::DeriveInput = syn::parse(item.clone()).unwrap();
|
||||
pub fn pumpkin_block_from_tag(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let arg_lit = parse_macro_input!(args as LitStr);
|
||||
let ast = parse_macro_input!(item as DeriveInput);
|
||||
|
||||
let name = &ast.ident;
|
||||
let (impl_generics, ty_generics, _) = ast.generics.split_for_impl();
|
||||
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
|
||||
|
||||
let input_string = input.to_string();
|
||||
let packet_name = input_string.trim_matches('"');
|
||||
let packet_name_split: Vec<&str> = packet_name.split(":").collect();
|
||||
let full_tag = arg_lit.value();
|
||||
|
||||
let namespace = packet_name_split[0];
|
||||
// Efficient splitting
|
||||
let namespace = match full_tag.split_once(':') {
|
||||
Some((ns, _)) => ns,
|
||||
None => abort!(arg_lit.span(), "Expected format 'namespace:path'"),
|
||||
};
|
||||
|
||||
let item: proc_macro2::TokenStream = item.into();
|
||||
|
||||
let code = quote! {
|
||||
#item
|
||||
impl #impl_generics crate::block::BlockMetadata for #name #ty_generics {
|
||||
quote! {
|
||||
#ast
|
||||
impl #impl_generics crate::block::BlockMetadata for #name #ty_generics #where_clause {
|
||||
fn namespace(&self) -> &'static str {
|
||||
#namespace
|
||||
}
|
||||
fn ids(&self) -> &'static [&'static str] {
|
||||
get_tag_values(RegistryKey::Block, #packet_name).unwrap()
|
||||
get_tag_values(RegistryKey::Block, #arg_lit).unwrap()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
code.into()
|
||||
}
|
||||
|
||||
#[proc_macro_error]
|
||||
#[proc_macro_attribute]
|
||||
pub fn block_property(input: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let ast: syn::DeriveInput = syn::parse(item.clone()).unwrap();
|
||||
let name = &ast.ident;
|
||||
let (impl_generics, ty_generics, _) = ast.generics.split_for_impl();
|
||||
|
||||
let input_string = input.to_string();
|
||||
let input_parts: Vec<&str> = input_string.split("[").collect();
|
||||
let property_name = input_parts[0].trim_ascii().trim_matches(&['"', ','][..]);
|
||||
let mut property_values: Vec<&str> = Vec::new();
|
||||
if input_parts.len() > 1 {
|
||||
property_values = input_parts[1]
|
||||
.trim_matches(']')
|
||||
.split(", ")
|
||||
.map(|p| p.trim_ascii().trim_matches(&['"', ','][..]))
|
||||
.collect::<Vec<&str>>();
|
||||
}
|
||||
|
||||
let item: proc_macro2::TokenStream = item.into();
|
||||
|
||||
let (variants, is_enum): (Vec<proc_macro2::Ident>, bool) = match ast.data {
|
||||
syn::Data::Enum(enum_item) => (
|
||||
enum_item.variants.into_iter().map(|v| v.ident).collect(),
|
||||
true,
|
||||
),
|
||||
syn::Data::Struct(s) => {
|
||||
let fields = match s.fields {
|
||||
Fields::Named(f) => abort!(f.span(), "Block properties can't have named fields"),
|
||||
Fields::Unnamed(fields) => fields.unnamed,
|
||||
Fields::Unit => abort!(s.fields.span(), "Block properties must have fields"),
|
||||
};
|
||||
if fields.len() != 1 {
|
||||
abort!(
|
||||
fields.span(),
|
||||
"Block properties `struct`s must have exactly one field"
|
||||
);
|
||||
}
|
||||
let field = fields.first().unwrap();
|
||||
let ty = &field.ty;
|
||||
let struct_type = match field.ty {
|
||||
syn::Type::Path(ref type_path) => {
|
||||
type_path.path.segments.first().unwrap().ident.to_string()
|
||||
}
|
||||
ref other => abort!(
|
||||
other.span(),
|
||||
"Block properties can only have primitive types"
|
||||
),
|
||||
};
|
||||
match struct_type.as_str() {
|
||||
"bool" => (
|
||||
vec![
|
||||
proc_macro2::Ident::new("true", proc_macro2::Span::call_site()),
|
||||
proc_macro2::Ident::new("false", proc_macro2::Span::call_site()),
|
||||
],
|
||||
false,
|
||||
),
|
||||
other => abort!(
|
||||
ty.span(),
|
||||
format!("`{other}` is not supported (why not implement it yourself?)")
|
||||
),
|
||||
}
|
||||
}
|
||||
_ => abort_call_site!("Block properties can only be `enum`s or `struct`s"),
|
||||
};
|
||||
|
||||
let values = variants.iter().enumerate().map(|(i, v)| match is_enum {
|
||||
true => {
|
||||
let mut value = v.to_string().to_snake_case();
|
||||
if !property_values.is_empty() && i < property_values.len() {
|
||||
value = property_values[i].to_string();
|
||||
}
|
||||
quote! {
|
||||
Self::#v => #value.to_string(),
|
||||
}
|
||||
}
|
||||
false => {
|
||||
let value = v.to_string();
|
||||
quote! {
|
||||
Self(#v) => #value.to_string(),
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let from_values = variants.iter().enumerate().map(|(i, v)| match is_enum {
|
||||
true => {
|
||||
let mut value = v.to_string().to_snake_case();
|
||||
if !property_values.is_empty() && i < property_values.len() {
|
||||
value = property_values[i].to_string();
|
||||
}
|
||||
quote! {
|
||||
#value => Self::#v,
|
||||
}
|
||||
}
|
||||
false => {
|
||||
let value = v.to_string();
|
||||
quote! {
|
||||
#value => Self(#v),
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let extra_fns = variants.iter().map(|v| {
|
||||
let title = proc_macro2::Ident::new(
|
||||
&v.to_string().to_pascal_case(),
|
||||
proc_macro2::Span::call_site(),
|
||||
);
|
||||
quote! {
|
||||
pub fn #title() -> Self {
|
||||
Self(#v)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let extra = if is_enum {
|
||||
quote! {}
|
||||
} else {
|
||||
quote! {
|
||||
impl #name {
|
||||
#(#extra_fns)*
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let code = quote! {
|
||||
#item
|
||||
impl #impl_generics pumpkin_world::block::properties::BlockPropertyMetadata for #name #ty_generics {
|
||||
fn name(&self) -> &'static str {
|
||||
#property_name
|
||||
}
|
||||
fn value(&self) -> String {
|
||||
match self {
|
||||
#(#values)*
|
||||
}
|
||||
}
|
||||
fn from_value(value: String) -> Self {
|
||||
match value.as_str() {
|
||||
#(#from_values)*
|
||||
_ => panic!("Invalid value for block property"),
|
||||
}
|
||||
}
|
||||
}
|
||||
#extra
|
||||
};
|
||||
|
||||
code.into()
|
||||
.into()
|
||||
}
|
||||
|
||||
// #[proc_macro_error]
|
||||
// #[proc_macro_attribute]
|
||||
// pub fn block_property(input: TokenStream, item: TokenStream) -> TokenStream {
|
||||
// let ast: syn::DeriveInput = syn::parse(item.clone()).unwrap();
|
||||
// let name = &ast.ident;
|
||||
// let (impl_generics, ty_generics, _) = ast.generics.split_for_impl();
|
||||
|
||||
// let input_string = input.to_string();
|
||||
// let input_parts: Vec<&str> = input_string.split("[").collect();
|
||||
// let property_name = input_parts[0].trim_ascii().trim_matches(&['"', ','][..]);
|
||||
// let mut property_values: Vec<&str> = Vec::new();
|
||||
// if input_parts.len() > 1 {
|
||||
// property_values = input_parts[1]
|
||||
// .trim_matches(']')
|
||||
// .split(", ")
|
||||
// .map(|p| p.trim_ascii().trim_matches(&['"', ','][..]))
|
||||
// .collect::<Vec<&str>>();
|
||||
// }
|
||||
|
||||
// let item: proc_macro2::TokenStream = item.into();
|
||||
|
||||
// let (variants, is_enum): (Vec<proc_macro2::Ident>, bool) = match ast.data {
|
||||
// syn::Data::Enum(enum_item) => (
|
||||
// enum_item.variants.into_iter().map(|v| v.ident).collect(),
|
||||
// true,
|
||||
// ),
|
||||
// syn::Data::Struct(s) => {
|
||||
// let fields = match s.fields {
|
||||
// Fields::Named(f) => abort!(f.span(), "Block properties can't have named fields"),
|
||||
// Fields::Unnamed(fields) => fields.unnamed,
|
||||
// Fields::Unit => abort!(s.fields.span(), "Block properties must have fields"),
|
||||
// };
|
||||
// if fields.len() != 1 {
|
||||
// abort!(
|
||||
// fields.span(),
|
||||
// "Block properties `struct`s must have exactly one field"
|
||||
// );
|
||||
// }
|
||||
// let field = fields.first().unwrap();
|
||||
// let ty = &field.ty;
|
||||
// let struct_type = match field.ty {
|
||||
// syn::Type::Path(ref type_path) => {
|
||||
// type_path.path.segments.first().unwrap().ident.to_string()
|
||||
// }
|
||||
// ref other => abort!(
|
||||
// other.span(),
|
||||
// "Block properties can only have primitive types"
|
||||
// ),
|
||||
// };
|
||||
// match struct_type.as_str() {
|
||||
// "bool" => (
|
||||
// vec![
|
||||
// proc_macro2::Ident::new("true", proc_macro2::Span::call_site()),
|
||||
// proc_macro2::Ident::new("false", proc_macro2::Span::call_site()),
|
||||
// ],
|
||||
// false,
|
||||
// ),
|
||||
// other => abort!(
|
||||
// ty.span(),
|
||||
// format!("`{other}` is not supported (why not implement it yourself?)")
|
||||
// ),
|
||||
// }
|
||||
// }
|
||||
// _ => abort_call_site!("Block properties can only be `enum`s or `struct`s"),
|
||||
// };
|
||||
|
||||
// let values = variants.iter().enumerate().map(|(i, v)| match is_enum {
|
||||
// true => {
|
||||
// let mut value = v.to_string().to_snake_case();
|
||||
// if !property_values.is_empty() && i < property_values.len() {
|
||||
// value = property_values[i].to_string();
|
||||
// }
|
||||
// quote! {
|
||||
// Self::#v => #value.to_string(),
|
||||
// }
|
||||
// }
|
||||
// false => {
|
||||
// let value = v.to_string();
|
||||
// quote! {
|
||||
// Self(#v) => #value.to_string(),
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
// let from_values = variants.iter().enumerate().map(|(i, v)| match is_enum {
|
||||
// true => {
|
||||
// let mut value = v.to_string().to_snake_case();
|
||||
// if !property_values.is_empty() && i < property_values.len() {
|
||||
// value = property_values[i].to_string();
|
||||
// }
|
||||
// quote! {
|
||||
// #value => Self::#v,
|
||||
// }
|
||||
// }
|
||||
// false => {
|
||||
// let value = v.to_string();
|
||||
// quote! {
|
||||
// #value => Self(#v),
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
// let extra_fns = variants.iter().map(|v| {
|
||||
// let title = proc_macro2::Ident::new(
|
||||
// &v.to_string().to_pascal_case(),
|
||||
// proc_macro2::Span::call_site(),
|
||||
// );
|
||||
// quote! {
|
||||
// pub fn #title() -> Self {
|
||||
// Self(#v)
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
// let extra = if is_enum {
|
||||
// quote! {}
|
||||
// } else {
|
||||
// quote! {
|
||||
// impl #name {
|
||||
// #(#extra_fns)*
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
// let code = quote! {
|
||||
// #item
|
||||
// impl #impl_generics pumpkin_world::block::properties::BlockPropertyMetadata for #name #ty_generics {
|
||||
// fn name(&self) -> &'static str {
|
||||
// #property_name
|
||||
// }
|
||||
// fn value(&self) -> String {
|
||||
// match self {
|
||||
// #(#values)*
|
||||
// }
|
||||
// }
|
||||
// fn from_value(value: String) -> Self {
|
||||
// match value.as_str() {
|
||||
// #(#from_values)*
|
||||
// _ => panic!("Invalid value for block property"),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// #extra
|
||||
// };
|
||||
|
||||
// code.into()
|
||||
// }
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[proc_macro_derive(PacketWrite, attributes(serial))]
|
||||
pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
||||
|
||||
@@ -27,11 +27,11 @@ aes = "0.8"
|
||||
cfb8 = "0.8"
|
||||
|
||||
# compression
|
||||
async-compression = { version = "0.4.34", features = ["tokio", "zlib"] }
|
||||
async-compression = { version = "0.4.35", features = ["tokio", "zlib"] }
|
||||
|
||||
take_mut = "0.2.2"
|
||||
bitflags = "2.10.0"
|
||||
|
||||
[dev-dependencies]
|
||||
# Validate correctness
|
||||
flate2 = "1.1.7"
|
||||
flate2 = "1.1.5"
|
||||
|
||||
@@ -45,11 +45,10 @@ pub enum RegistryEntryList {
|
||||
}
|
||||
|
||||
impl RegistryEntryList {
|
||||
#[allow(dead_code)]
|
||||
pub fn get_values(&self) -> Vec<TagType> {
|
||||
pub fn into_vec(self) -> Vec<TagType> {
|
||||
match self {
|
||||
RegistryEntryList::Single(s) => vec![s.clone()],
|
||||
RegistryEntryList::Many(s) => s.clone(),
|
||||
RegistryEntryList::Single(s) => vec![s],
|
||||
RegistryEntryList::Many(s) => s,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ tokio = { workspace = true, features = [
|
||||
"io-util",
|
||||
"time",
|
||||
] }
|
||||
rayon.workspace = true
|
||||
uuid.workspace = true
|
||||
thiserror.workspace = true
|
||||
serde.workspace = true
|
||||
|
||||
@@ -29,7 +29,7 @@ impl BlockEntity for BedBlockEntity {
|
||||
&'a self,
|
||||
_nbt: &'a mut NbtCompound,
|
||||
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
|
||||
@@ -48,7 +48,7 @@ impl BlockEntity for CommandBlockEntity {
|
||||
&'a self,
|
||||
_nbt: &'a mut NbtCompound,
|
||||
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
fn is_dirty(&self) -> bool {
|
||||
|
||||
@@ -36,7 +36,7 @@ impl BlockEntity for EndPortalBlockEntity {
|
||||
&'a self,
|
||||
_nbt: &'a mut NbtCompound,
|
||||
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
|
||||
@@ -43,7 +43,7 @@ impl BlockEntity for EnderChestBlockEntity {
|
||||
&'a self,
|
||||
_nbt: &'a mut NbtCompound,
|
||||
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
fn tick<'a>(
|
||||
|
||||
@@ -51,7 +51,7 @@ pub trait BlockEntity: Send + Sync {
|
||||
&'a self,
|
||||
_world: Arc<dyn SimpleWorld>,
|
||||
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
fn resource_location(&self) -> &'static str;
|
||||
fn get_position(&self) -> BlockPos;
|
||||
|
||||
@@ -271,7 +271,7 @@ impl SignBlockEntity {
|
||||
Text::default()
|
||||
},
|
||||
back_text: if !is_front {
|
||||
Text::new(messages.clone())
|
||||
Text::new(messages)
|
||||
} else {
|
||||
Text::default()
|
||||
},
|
||||
|
||||
@@ -307,9 +307,9 @@ impl AnvilChunkData {
|
||||
.decompress_data(&self.compressed_data)
|
||||
.map_err(ChunkReadingError::Compression)?;
|
||||
|
||||
S::from_bytes(decompress_bytes.into(), pos)
|
||||
S::from_bytes(&decompress_bytes.into(), pos)
|
||||
} else {
|
||||
S::from_bytes(self.compressed_data.clone(), pos)
|
||||
S::from_bytes(&self.compressed_data, pos)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,7 +521,7 @@ pub trait SingleChunkDataSerializer: Send + Sync + Sized + Dirtiable {
|
||||
fn to_bytes(
|
||||
&self,
|
||||
) -> Pin<Box<dyn Future<Output = Result<Bytes, ChunkSerializingError>> + Send + '_>>;
|
||||
fn from_bytes(bytes: Bytes, pos: Vector2<i32>) -> Result<Self, ChunkReadingError>;
|
||||
fn from_bytes(bytes: &Bytes, pos: Vector2<i32>) -> Result<Self, ChunkReadingError>;
|
||||
fn position(&self) -> &Vector2<i32>;
|
||||
}
|
||||
|
||||
@@ -540,7 +540,7 @@ impl<S: SingleChunkDataSerializer> ChunkSerializer for AnvilChunkFile<S> {
|
||||
format!("./r.{region_x}.{region_z}.mca")
|
||||
}
|
||||
|
||||
async fn write(&self, path: PathBuf) -> Result<(), std::io::Error> {
|
||||
async fn write(&self, path: &PathBuf) -> Result<(), std::io::Error> {
|
||||
let mut write_action = self.write_action.lock().await;
|
||||
match &*write_action {
|
||||
WriteAction::Pass => {
|
||||
@@ -550,9 +550,9 @@ impl<S: SingleChunkDataSerializer> ChunkSerializer for AnvilChunkFile<S> {
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
WriteAction::All => self.write_all(&path).await,
|
||||
WriteAction::All => self.write_all(path).await,
|
||||
WriteAction::Parts(parts) => {
|
||||
self.write_indices(&path, Vec::from_iter(parts.iter().cloned()).as_slice())
|
||||
self.write_indices(path, Vec::from_iter(parts.iter().cloned()).as_slice())
|
||||
.await
|
||||
}
|
||||
}?;
|
||||
|
||||
@@ -178,7 +178,7 @@ impl<S: SingleChunkDataSerializer> ChunkSerializer for LinearFile<S> {
|
||||
format!("./r.{region_x}.{region_z}.linear")
|
||||
}
|
||||
|
||||
async fn write(&self, path: PathBuf) -> Result<(), std::io::Error> {
|
||||
async fn write(&self, path: &PathBuf) -> Result<(), std::io::Error> {
|
||||
let temp_path = path.with_extension("tmp");
|
||||
log::trace!("Writing tmp file to disk: {}", temp_path.display());
|
||||
|
||||
@@ -358,7 +358,7 @@ impl<S: SingleChunkDataSerializer> ChunkSerializer for LinearFile<S> {
|
||||
let linear_chunk_data = &self.chunks_data[index];
|
||||
|
||||
let result = if let Some(data) = linear_chunk_data {
|
||||
match S::from_bytes(data.clone(), chunk) {
|
||||
match S::from_bytes(data, chunk) {
|
||||
Ok(chunk) => LoadedData::Loaded(chunk),
|
||||
Err(err) => LoadedData::Error((chunk, err)),
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ pub mod linear;
|
||||
|
||||
impl SingleChunkDataSerializer for ChunkData {
|
||||
#[inline]
|
||||
fn from_bytes(bytes: Bytes, pos: Vector2<i32>) -> Result<Self, ChunkReadingError> {
|
||||
Self::internal_from_bytes(&bytes, pos).map_err(ChunkReadingError::ParsingError)
|
||||
fn from_bytes(bytes: &Bytes, pos: Vector2<i32>) -> Result<Self, ChunkReadingError> {
|
||||
Self::internal_from_bytes(bytes, pos).map_err(ChunkReadingError::ParsingError)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -116,46 +116,49 @@ impl ChunkData {
|
||||
position.x, position.y, chunk_data.x_pos, chunk_data.z_pos,
|
||||
)));
|
||||
}
|
||||
|
||||
let light_engine = ChunkLight {
|
||||
block_light: chunk_data
|
||||
.sections
|
||||
.iter()
|
||||
.map(|x| {
|
||||
x.block_light
|
||||
.clone()
|
||||
.map(LightContainer::new)
|
||||
.unwrap_or_default()
|
||||
})
|
||||
.collect(),
|
||||
sky_light: chunk_data
|
||||
.sections
|
||||
.iter()
|
||||
.map(|x| {
|
||||
x.sky_light
|
||||
.clone()
|
||||
.map(LightContainer::new)
|
||||
.unwrap_or_default()
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let sub_chunks = chunk_data
|
||||
let (block_lights, sky_lights, sub_chunks) = chunk_data
|
||||
.sections
|
||||
.into_iter()
|
||||
.map(|section| SubChunk {
|
||||
block_states: section
|
||||
.block_states
|
||||
.map(BlockPalette::from_disk_nbt)
|
||||
.unwrap_or_default(),
|
||||
biomes: section
|
||||
.biomes
|
||||
.map(BiomePalette::from_disk_nbt)
|
||||
.unwrap_or_default(),
|
||||
.map(|section| {
|
||||
let block_light = section
|
||||
.block_light
|
||||
.map(LightContainer::new)
|
||||
.unwrap_or_default();
|
||||
let sky_light = section
|
||||
.sky_light
|
||||
.map(LightContainer::new)
|
||||
.unwrap_or_default();
|
||||
|
||||
let sub_chunk = SubChunk {
|
||||
block_states: section
|
||||
.block_states
|
||||
.map(BlockPalette::from_disk_nbt)
|
||||
.unwrap_or_default(),
|
||||
biomes: section
|
||||
.biomes
|
||||
.map(BiomePalette::from_disk_nbt)
|
||||
.unwrap_or_default(),
|
||||
};
|
||||
|
||||
(block_light, sky_light, sub_chunk)
|
||||
})
|
||||
.collect();
|
||||
.fold(
|
||||
(Vec::new(), Vec::new(), Vec::new()),
|
||||
|(mut bl, mut sl, mut sc), (block_l, sky_l, sub_c)| {
|
||||
bl.push(block_l);
|
||||
sl.push(sky_l);
|
||||
sc.push(sub_c);
|
||||
(bl, sl, sc)
|
||||
},
|
||||
);
|
||||
|
||||
// 2. Assemble the final structs using the collected vectors.
|
||||
let light_engine = ChunkLight {
|
||||
block_light: block_lights.into_boxed_slice(),
|
||||
sky_light: sky_lights.into_boxed_slice(),
|
||||
};
|
||||
let min_y = section_coords::section_to_block(chunk_data.min_y_section);
|
||||
let section = ChunkSections::new(sub_chunks, min_y);
|
||||
let section = ChunkSections::new(sub_chunks.into_boxed_slice(), min_y);
|
||||
|
||||
Ok(ChunkData {
|
||||
section,
|
||||
@@ -249,8 +252,8 @@ impl Dirtiable for ChunkEntityData {
|
||||
|
||||
impl SingleChunkDataSerializer for ChunkEntityData {
|
||||
#[inline]
|
||||
fn from_bytes(bytes: Bytes, pos: Vector2<i32>) -> Result<Self, ChunkReadingError> {
|
||||
Self::internal_from_bytes(&bytes, pos).map_err(ChunkReadingError::ParsingError)
|
||||
fn from_bytes(bytes: &Bytes, pos: Vector2<i32>) -> Result<Self, ChunkReadingError> {
|
||||
Self::internal_from_bytes(bytes, pos).map_err(ChunkReadingError::ParsingError)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
@@ -365,7 +365,7 @@ where
|
||||
|
||||
log::debug!("Writing file for {}", path.display());
|
||||
serializer
|
||||
.write(path.clone())
|
||||
.write(&path)
|
||||
.await
|
||||
.map_err(|err| ChunkWritingError::IoError(err.kind()))?;
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ pub trait ChunkSerializer: Send + Sync + Default {
|
||||
/// Serialize the data to bytes.
|
||||
fn write(
|
||||
&self,
|
||||
backend: Self::WriteBackend,
|
||||
backend: &Self::WriteBackend,
|
||||
) -> impl Future<Output = Result<(), std::io::Error>> + Send;
|
||||
|
||||
/// Create a new instance from bytes
|
||||
|
||||
@@ -49,7 +49,7 @@ pub enum FluidLevelSampler {
|
||||
}
|
||||
|
||||
impl FluidLevelSamplerImpl for FluidLevelSampler {
|
||||
fn get_fluid_level(&self, x: i32, y: i32, z: i32) -> FluidLevel {
|
||||
fn get_fluid_level(&self, x: i32, y: i32, z: i32) -> &FluidLevel {
|
||||
match self {
|
||||
FluidLevelSampler::Static(sampler) => sampler.get_fluid_level(x, y, z),
|
||||
FluidLevelSampler::Chunk(sampler) => sampler.get_fluid_level(x, y, z),
|
||||
@@ -58,24 +58,25 @@ impl FluidLevelSamplerImpl for FluidLevelSampler {
|
||||
}
|
||||
|
||||
pub struct StaticFluidLevelSampler {
|
||||
y: i32,
|
||||
block: &'static Block,
|
||||
fluid_level: FluidLevel,
|
||||
}
|
||||
|
||||
impl StaticFluidLevelSampler {
|
||||
pub fn new(y: i32, block: &'static Block) -> Self {
|
||||
Self { y, block }
|
||||
Self {
|
||||
fluid_level: FluidLevel::new(y, block),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FluidLevelSamplerImpl for StaticFluidLevelSampler {
|
||||
fn get_fluid_level(&self, _x: i32, _y: i32, _z: i32) -> FluidLevel {
|
||||
FluidLevel::new(self.y, self.block)
|
||||
fn get_fluid_level(&self, _x: i32, _y: i32, _z: i32) -> &FluidLevel {
|
||||
&self.fluid_level
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FluidLevelSamplerImpl {
|
||||
fn get_fluid_level(&self, x: i32, y: i32, z: i32) -> FluidLevel;
|
||||
fn get_fluid_level(&self, x: i32, y: i32, z: i32) -> &FluidLevel;
|
||||
}
|
||||
|
||||
#[enum_dispatch(AquiferSamplerImpl)]
|
||||
@@ -103,8 +104,7 @@ macro_rules! local_y {
|
||||
}
|
||||
|
||||
pub struct WorldAquiferSampler {
|
||||
random_deriver: RandomDeriver,
|
||||
fluid_level: FluidLevelSampler,
|
||||
fluid_level_sampler: FluidLevelSampler,
|
||||
start_x: i32,
|
||||
start_y: i8,
|
||||
start_z: i32,
|
||||
@@ -134,7 +134,7 @@ impl WorldAquiferSampler {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
chunk_pos: Vector2<i32>,
|
||||
random_deriver: RandomDeriver,
|
||||
random_deriver: &RandomDeriver,
|
||||
minimum_y: i8,
|
||||
height: u16,
|
||||
fluid_level: FluidLevelSampler,
|
||||
@@ -176,8 +176,7 @@ impl WorldAquiferSampler {
|
||||
}
|
||||
|
||||
Self {
|
||||
random_deriver,
|
||||
fluid_level,
|
||||
fluid_level_sampler: fluid_level,
|
||||
start_x,
|
||||
start_y,
|
||||
start_z,
|
||||
@@ -230,13 +229,12 @@ impl WorldAquiferSampler {
|
||||
}
|
||||
|
||||
fn calculate_density(
|
||||
&mut self,
|
||||
barrier_sample: &mut Option<f64>,
|
||||
pos: &impl NoisePos,
|
||||
router: &mut ChunkNoiseRouter,
|
||||
sample_options: &ChunkNoiseFunctionSampleOptions,
|
||||
level_1: FluidLevel,
|
||||
level_2: FluidLevel,
|
||||
level_1: &FluidLevel,
|
||||
level_2: &FluidLevel,
|
||||
) -> f64 {
|
||||
let y = pos.y();
|
||||
let block_state1 = level_1.get_block(y);
|
||||
@@ -280,7 +278,7 @@ impl WorldAquiferSampler {
|
||||
router: &mut ChunkNoiseRouter,
|
||||
height_estimator: &mut SurfaceHeightEstimateSampler,
|
||||
sample_options: &ChunkNoiseFunctionSampleOptions,
|
||||
) -> FluidLevel {
|
||||
) -> &FluidLevel {
|
||||
let x = block_pos::unpack_x(packed_pos);
|
||||
let y = block_pos::unpack_y(packed_pos);
|
||||
let z = block_pos::unpack_z(packed_pos);
|
||||
@@ -290,18 +288,26 @@ impl WorldAquiferSampler {
|
||||
let local_z = local_xz!(z);
|
||||
|
||||
let index = self.packed_position_index(local_x, local_y, local_z);
|
||||
if let Some(level) = &self.levels[index] {
|
||||
level.clone()
|
||||
} else {
|
||||
let fluid_level =
|
||||
self.get_fluid_level(x, y, z, router, height_estimator, sample_options);
|
||||
self.levels[index] = Some(fluid_level.clone());
|
||||
fluid_level
|
||||
}
|
||||
let entry = self
|
||||
.levels
|
||||
.get_mut(index)
|
||||
.expect("Index calculated by packed_position_index is out of bounds for self.levels");
|
||||
let fluid_level = &self.fluid_level_sampler;
|
||||
entry.get_or_insert_with(|| {
|
||||
Self::get_fluid_level(
|
||||
fluid_level,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
router,
|
||||
height_estimator,
|
||||
sample_options,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn get_fluid_level(
|
||||
&mut self,
|
||||
fluid_level_sampler: &FluidLevelSampler,
|
||||
block_x: i32,
|
||||
block_y: i32,
|
||||
block_z: i32,
|
||||
@@ -309,7 +315,7 @@ impl WorldAquiferSampler {
|
||||
height_estimator: &mut SurfaceHeightEstimateSampler,
|
||||
sample_options: &ChunkNoiseFunctionSampleOptions,
|
||||
) -> FluidLevel {
|
||||
let fluid_level = self.fluid_level.get_fluid_level(block_x, block_y, block_z);
|
||||
let fluid_level = fluid_level_sampler.get_fluid_level(block_x, block_y, block_z);
|
||||
let j = block_y + 12;
|
||||
let k = block_y - 12;
|
||||
let mut bl = false;
|
||||
@@ -324,19 +330,19 @@ impl WorldAquiferSampler {
|
||||
let bl2 = offset.x == 0 && offset.y == 0;
|
||||
|
||||
if bl2 && k > o {
|
||||
return fluid_level;
|
||||
return fluid_level.clone();
|
||||
}
|
||||
|
||||
let bl3 = j > o;
|
||||
if bl3 || bl2 {
|
||||
let fluid_level = self.fluid_level.get_fluid_level(x, o, z);
|
||||
let fluid_level = fluid_level_sampler.get_fluid_level(x, o, z);
|
||||
if !fluid_level.get_block(o).default_state.is_air() {
|
||||
if bl2 {
|
||||
bl = true;
|
||||
}
|
||||
|
||||
if bl3 {
|
||||
return fluid_level;
|
||||
return fluid_level.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -344,11 +350,11 @@ impl WorldAquiferSampler {
|
||||
min_surface_estimate = min_surface_estimate.min(n);
|
||||
}
|
||||
|
||||
let p = self.get_fluid_block_y(
|
||||
let p = Self::get_fluid_block_y(
|
||||
block_x,
|
||||
block_y,
|
||||
block_z,
|
||||
fluid_level.clone(),
|
||||
fluid_level,
|
||||
min_surface_estimate,
|
||||
bl,
|
||||
router,
|
||||
@@ -356,7 +362,7 @@ impl WorldAquiferSampler {
|
||||
);
|
||||
FluidLevel::new(
|
||||
p,
|
||||
self.get_fluid_block_state(
|
||||
WorldAquiferSampler::get_fluid_block_state(
|
||||
block_x,
|
||||
block_y,
|
||||
block_z,
|
||||
@@ -370,11 +376,10 @@ impl WorldAquiferSampler {
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn get_fluid_block_y(
|
||||
&mut self,
|
||||
block_x: i32,
|
||||
block_y: i32,
|
||||
block_z: i32,
|
||||
default_level: FluidLevel,
|
||||
default_level: &FluidLevel,
|
||||
surface_height_estimate: i32,
|
||||
map_y: bool,
|
||||
router: &mut ChunkNoiseRouter,
|
||||
@@ -407,7 +412,7 @@ impl WorldAquiferSampler {
|
||||
if e > 0f64 {
|
||||
default_level.max_y
|
||||
} else if d > 0f64 {
|
||||
self.get_noise_based_fluid_level(
|
||||
Self::get_noise_based_fluid_level(
|
||||
block_x,
|
||||
block_y,
|
||||
block_z,
|
||||
@@ -421,7 +426,6 @@ impl WorldAquiferSampler {
|
||||
}
|
||||
|
||||
fn get_noise_based_fluid_level(
|
||||
&mut self,
|
||||
block_x: i32,
|
||||
block_y: i32,
|
||||
block_z: i32,
|
||||
@@ -446,11 +450,10 @@ impl WorldAquiferSampler {
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn get_fluid_block_state(
|
||||
&mut self,
|
||||
block_x: i32,
|
||||
block_y: i32,
|
||||
block_z: i32,
|
||||
default_level: FluidLevel,
|
||||
default_level: &FluidLevel,
|
||||
level: i32,
|
||||
router: &mut ChunkNoiseRouter,
|
||||
sample_options: &ChunkNoiseFunctionSampleOptions,
|
||||
@@ -486,7 +489,7 @@ impl WorldAquiferSampler {
|
||||
let sample_z = pos.z();
|
||||
|
||||
let fluid_level = self
|
||||
.fluid_level
|
||||
.fluid_level_sampler
|
||||
.get_fluid_level(sample_x, sample_y, sample_z);
|
||||
if fluid_level.get_block(sample_y) == &LAVA_BLOCK {
|
||||
Some(LAVA_BLOCK.default_state)
|
||||
@@ -521,13 +524,14 @@ impl WorldAquiferSampler {
|
||||
random_positions_and_hypot[0] = (packed_random, hypot_squared);
|
||||
}
|
||||
}
|
||||
|
||||
let fluid_level2 = self.get_water_level(
|
||||
random_positions_and_hypot[0].0,
|
||||
router,
|
||||
height_estimator,
|
||||
sample_options,
|
||||
);
|
||||
let fluid_level2 = self
|
||||
.get_water_level(
|
||||
random_positions_and_hypot[0].0,
|
||||
router,
|
||||
height_estimator,
|
||||
sample_options,
|
||||
)
|
||||
.clone();
|
||||
let d = Self::max_distance(
|
||||
random_positions_and_hypot[0].1,
|
||||
random_positions_and_hypot[1].1,
|
||||
@@ -540,7 +544,7 @@ impl WorldAquiferSampler {
|
||||
Some(block_state.default_state)
|
||||
} else if block_state == &WATER_BLOCK
|
||||
&& self
|
||||
.fluid_level
|
||||
.fluid_level_sampler
|
||||
.get_fluid_level(sample_x, sample_y - 1, sample_z)
|
||||
.get_block(sample_y - 1)
|
||||
== &LAVA_BLOCK
|
||||
@@ -548,19 +552,21 @@ impl WorldAquiferSampler {
|
||||
Some(block_state.default_state)
|
||||
} else {
|
||||
let mut barrier_sample = None;
|
||||
let fluid_level3 = self.get_water_level(
|
||||
random_positions_and_hypot[1].0,
|
||||
router,
|
||||
height_estimator,
|
||||
sample_options,
|
||||
);
|
||||
let e = d * self.calculate_density(
|
||||
let fluid_level3 = self
|
||||
.get_water_level(
|
||||
random_positions_and_hypot[1].0,
|
||||
router,
|
||||
height_estimator,
|
||||
sample_options,
|
||||
)
|
||||
.clone();
|
||||
let e = d * Self::calculate_density(
|
||||
&mut barrier_sample,
|
||||
pos,
|
||||
router,
|
||||
sample_options,
|
||||
fluid_level2.clone(),
|
||||
fluid_level3.clone(),
|
||||
&fluid_level2,
|
||||
&fluid_level3,
|
||||
);
|
||||
|
||||
if density + e > 0f64 {
|
||||
@@ -579,13 +585,13 @@ impl WorldAquiferSampler {
|
||||
if f > 0f64 {
|
||||
let g = d
|
||||
* f
|
||||
* self.calculate_density(
|
||||
* Self::calculate_density(
|
||||
&mut barrier_sample,
|
||||
pos,
|
||||
router,
|
||||
sample_options,
|
||||
fluid_level2,
|
||||
fluid_level4.clone(),
|
||||
&fluid_level2,
|
||||
fluid_level4,
|
||||
);
|
||||
if density + g > 0f64 {
|
||||
return None;
|
||||
@@ -599,12 +605,12 @@ impl WorldAquiferSampler {
|
||||
if g > 0f64 {
|
||||
let h = d
|
||||
* g
|
||||
* self.calculate_density(
|
||||
* Self::calculate_density(
|
||||
&mut barrier_sample,
|
||||
pos,
|
||||
router,
|
||||
sample_options,
|
||||
fluid_level3,
|
||||
&fluid_level3,
|
||||
fluid_level4,
|
||||
);
|
||||
if density + h > 0f64 {
|
||||
@@ -794,7 +800,7 @@ mod random_positions_and_hypot {
|
||||
|
||||
#[test]
|
||||
fn test_get_fluid_block_state() {
|
||||
let (mut aquifer, mut router, _, options) = create_aquifer(&PROTO_ROUTER);
|
||||
let (_, mut router, _, options) = create_aquifer(&PROTO_ROUTER);
|
||||
let level = FluidLevel::new(0, &WATER_BLOCK);
|
||||
|
||||
let values = [
|
||||
@@ -927,7 +933,15 @@ mod random_positions_and_hypot {
|
||||
|
||||
for ((x, y, z), result) in values {
|
||||
assert_eq!(
|
||||
aquifer.get_fluid_block_state(x, y, z, level.clone(), -10, &mut router, &options),
|
||||
WorldAquiferSampler::get_fluid_block_state(
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
&level,
|
||||
-10,
|
||||
&mut router,
|
||||
&options
|
||||
),
|
||||
&result
|
||||
);
|
||||
}
|
||||
@@ -935,7 +949,7 @@ mod random_positions_and_hypot {
|
||||
|
||||
#[test]
|
||||
fn test_get_noise_based_fluid_level() {
|
||||
let (mut aquifer, mut router, _, options) = create_aquifer(&PROTO_ROUTER);
|
||||
let (_, mut router, _, options) = create_aquifer(&PROTO_ROUTER);
|
||||
|
||||
let values = [
|
||||
((-100, -100, -100), -103),
|
||||
@@ -1067,7 +1081,14 @@ mod random_positions_and_hypot {
|
||||
|
||||
for ((x, y, z), result) in values {
|
||||
assert_eq!(
|
||||
aquifer.get_noise_based_fluid_level(x, y, z, 200, &mut router, &options),
|
||||
WorldAquiferSampler::get_noise_based_fluid_level(
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
200,
|
||||
&mut router,
|
||||
&options
|
||||
),
|
||||
result
|
||||
);
|
||||
}
|
||||
@@ -1075,7 +1096,7 @@ mod random_positions_and_hypot {
|
||||
|
||||
#[test]
|
||||
fn test_get_fluid_block_y() {
|
||||
let (mut aquifer, mut router, _, env) = create_aquifer(&PROTO_ROUTER);
|
||||
let (_, mut router, _, env) = create_aquifer(&PROTO_ROUTER);
|
||||
let level = FluidLevel::new(0, &WATER_BLOCK);
|
||||
let values = [
|
||||
((-100, -100, -100), -32512),
|
||||
@@ -1207,7 +1228,16 @@ mod random_positions_and_hypot {
|
||||
|
||||
for ((x, y, z), result) in values {
|
||||
assert_eq!(
|
||||
aquifer.get_fluid_block_y(x, y, z, level.clone(), 80, true, &mut router, &env),
|
||||
WorldAquiferSampler::get_fluid_block_y(
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
&level,
|
||||
80,
|
||||
true,
|
||||
&mut router,
|
||||
&env
|
||||
),
|
||||
result
|
||||
);
|
||||
}
|
||||
@@ -1342,7 +1372,16 @@ mod random_positions_and_hypot {
|
||||
|
||||
for ((x, y, z), result) in values {
|
||||
assert_eq!(
|
||||
aquifer.get_fluid_block_y(x, y, z, level.clone(), 80, false, &mut router, &env),
|
||||
WorldAquiferSampler::get_fluid_block_y(
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
&level,
|
||||
80,
|
||||
false,
|
||||
&mut router,
|
||||
&env
|
||||
),
|
||||
result
|
||||
);
|
||||
}
|
||||
@@ -1350,7 +1389,7 @@ mod random_positions_and_hypot {
|
||||
|
||||
#[test]
|
||||
fn test_get_fluid_level() {
|
||||
let (mut aquifer, mut router, mut height_estimator, env) = create_aquifer(&PROTO_ROUTER);
|
||||
let (aquifer, mut router, mut height_estimator, env) = create_aquifer(&PROTO_ROUTER);
|
||||
let values = [
|
||||
((-100, -100, -100), (-32512, LAVA_BLOCK)),
|
||||
((-100, -100, -50), (-32512, LAVA_BLOCK)),
|
||||
@@ -1479,8 +1518,17 @@ mod random_positions_and_hypot {
|
||||
((100, 100, 100), (63, WATER_BLOCK)),
|
||||
];
|
||||
|
||||
let fluid_level_sampler = &aquifer.fluid_level_sampler;
|
||||
for ((x, y, z), (y1, state)) in values {
|
||||
let level = aquifer.get_fluid_level(x, y, z, &mut router, &mut height_estimator, &env);
|
||||
let level = WorldAquiferSampler::get_fluid_level(
|
||||
fluid_level_sampler,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
&mut router,
|
||||
&mut height_estimator,
|
||||
&env,
|
||||
);
|
||||
assert_eq!(level.max_y, y1);
|
||||
assert_eq!(level.block, &state);
|
||||
}
|
||||
@@ -1488,7 +1536,7 @@ mod random_positions_and_hypot {
|
||||
|
||||
#[test]
|
||||
fn test_calculate_density() {
|
||||
let (mut aquifer, mut router, _, env) = create_aquifer(&PROTO_ROUTER);
|
||||
let (_, mut router, _, env) = create_aquifer(&PROTO_ROUTER);
|
||||
|
||||
let values = [
|
||||
((-100, -100, -100, 0, 0), 0.0),
|
||||
@@ -1625,7 +1673,14 @@ mod random_positions_and_hypot {
|
||||
let mut sample = None;
|
||||
|
||||
assert_eq!(
|
||||
aquifer.calculate_density(&mut sample, &pos, &mut router, &env, level1, level2),
|
||||
WorldAquiferSampler::calculate_density(
|
||||
&mut sample,
|
||||
&pos,
|
||||
&mut router,
|
||||
&env,
|
||||
&level1,
|
||||
&level2
|
||||
),
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
@@ -106,7 +106,11 @@ impl DualNoiseBlockStateProvider {
|
||||
&BlockPos(pos.0.add(&Vector3::new(i * 54545, 0, i * 34234))),
|
||||
&sampler,
|
||||
);
|
||||
list.push(self.base.get_state_by_value(&self.base.states, value));
|
||||
list.push(
|
||||
self.base
|
||||
.get_state_by_value(&self.base.states, value)
|
||||
.clone(),
|
||||
);
|
||||
}
|
||||
let value = self.base.base.get_noise(pos);
|
||||
self.base.get_state_by_value(&list, value).get_state()
|
||||
@@ -184,9 +188,13 @@ impl NoiseBlockStateProvider {
|
||||
self.get_state_by_value(&self.states, value).get_state()
|
||||
}
|
||||
|
||||
fn get_state_by_value(&self, states: &[BlockStateCodec], value: f64) -> BlockStateCodec {
|
||||
fn get_state_by_value<'a>(
|
||||
&self,
|
||||
states: &'a [BlockStateCodec],
|
||||
value: f64,
|
||||
) -> &'a BlockStateCodec {
|
||||
let val = ((1.0 + value) / 2.0).clamp(0.0, 0.9999);
|
||||
states[(val * states.len() as f64) as usize].clone()
|
||||
&states[(val * states.len() as f64) as usize]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -210,7 +210,7 @@ impl<'a> ChunkNoiseGenerator<'a> {
|
||||
let section_z = section_coords::block_to_section(start_block_z);
|
||||
AquiferSampler::Aquifer(WorldAquiferSampler::new(
|
||||
Vector2::new(section_x, section_z),
|
||||
random_config.aquifer_random_deriver.clone(),
|
||||
&random_config.aquifer_random_deriver,
|
||||
generation_shape.min_y,
|
||||
generation_shape.height,
|
||||
level_sampler,
|
||||
|
||||
@@ -21,6 +21,15 @@ enum BlockWrapper {
|
||||
Multi(Vec<String>),
|
||||
}
|
||||
|
||||
impl BlockWrapper {
|
||||
fn contains(&self, name: &str) -> bool {
|
||||
match self {
|
||||
Self::Single(s) => s == name,
|
||||
Self::Multi(h) => h.contains(&name.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SpringFeatureFeature {
|
||||
pub fn generate<T: GenerationCache>(
|
||||
&self,
|
||||
@@ -29,91 +38,80 @@ impl SpringFeatureFeature {
|
||||
_random: &mut RandomGenerator,
|
||||
pos: BlockPos,
|
||||
) -> bool {
|
||||
// i don't think this is the most efficient way, but it works
|
||||
let valid_blocks = match self.valid_blocks.clone() {
|
||||
BlockWrapper::Single(item) => vec![item],
|
||||
BlockWrapper::Multi(items) => items,
|
||||
};
|
||||
let valid_blocks = &self.valid_blocks;
|
||||
|
||||
if !valid_blocks.contains(
|
||||
&GenerationCache::get_block_state(chunk, &pos.up().0)
|
||||
GenerationCache::get_block_state(chunk, &pos.up().0)
|
||||
.to_block()
|
||||
.name
|
||||
.to_string(),
|
||||
.name,
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if self.requires_block_below
|
||||
&& !valid_blocks.contains(
|
||||
&GenerationCache::get_block_state(
|
||||
GenerationCache::get_block_state(
|
||||
chunk,
|
||||
&pos.offset(BlockDirection::Down.to_offset()).0,
|
||||
)
|
||||
.to_block()
|
||||
.name
|
||||
.to_string(),
|
||||
.name,
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
let state = GenerationCache::get_block_state(chunk, &pos.0);
|
||||
if !state.to_state().is_air() && !valid_blocks.contains(&state.to_block().name.to_string())
|
||||
{
|
||||
if !state.to_state().is_air() && !valid_blocks.contains(state.to_block().name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let mut valid = 0;
|
||||
if valid_blocks.contains(
|
||||
&GenerationCache::get_block_state(
|
||||
GenerationCache::get_block_state(
|
||||
chunk,
|
||||
&pos.offset(BlockDirection::West.to_offset()).0,
|
||||
)
|
||||
.to_block()
|
||||
.name
|
||||
.to_string(),
|
||||
.name,
|
||||
) {
|
||||
valid += 1;
|
||||
}
|
||||
if valid_blocks.contains(
|
||||
&GenerationCache::get_block_state(
|
||||
GenerationCache::get_block_state(
|
||||
chunk,
|
||||
&pos.offset(BlockDirection::East.to_offset()).0,
|
||||
)
|
||||
.to_block()
|
||||
.name
|
||||
.to_string(),
|
||||
.name,
|
||||
) {
|
||||
valid += 1;
|
||||
}
|
||||
if valid_blocks.contains(
|
||||
&GenerationCache::get_block_state(
|
||||
GenerationCache::get_block_state(
|
||||
chunk,
|
||||
&pos.offset(BlockDirection::North.to_offset()).0,
|
||||
)
|
||||
.to_block()
|
||||
.name
|
||||
.to_string(),
|
||||
.name,
|
||||
) {
|
||||
valid += 1;
|
||||
}
|
||||
if valid_blocks.contains(
|
||||
&GenerationCache::get_block_state(
|
||||
GenerationCache::get_block_state(
|
||||
chunk,
|
||||
&pos.offset(BlockDirection::South.to_offset()).0,
|
||||
)
|
||||
.to_block()
|
||||
.name
|
||||
.to_string(),
|
||||
.name,
|
||||
) {
|
||||
valid += 1;
|
||||
}
|
||||
if valid_blocks.contains(
|
||||
&GenerationCache::get_block_state(
|
||||
GenerationCache::get_block_state(
|
||||
chunk,
|
||||
&pos.offset(BlockDirection::Down.to_offset()).0,
|
||||
)
|
||||
.to_block()
|
||||
.name
|
||||
.to_string(),
|
||||
.name,
|
||||
) {
|
||||
valid += 1;
|
||||
}
|
||||
|
||||
@@ -82,11 +82,11 @@ impl StandardChunkFluidLevelSampler {
|
||||
}
|
||||
|
||||
impl FluidLevelSamplerImpl for StandardChunkFluidLevelSampler {
|
||||
fn get_fluid_level(&self, _x: i32, y: i32, _z: i32) -> FluidLevel {
|
||||
fn get_fluid_level(&self, _x: i32, y: i32, _z: i32) -> &FluidLevel {
|
||||
if y < self.bottom_y {
|
||||
self.bottom_fluid.clone()
|
||||
&self.bottom_fluid
|
||||
} else {
|
||||
self.top_fluid.clone()
|
||||
&self.top_fluid
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -842,7 +842,7 @@ impl Level {
|
||||
.await;
|
||||
let mut chunk = chunk.write().await;
|
||||
chunk.block_ticks.schedule_tick(
|
||||
ScheduledTick {
|
||||
&ScheduledTick {
|
||||
delay,
|
||||
position: block_pos,
|
||||
priority,
|
||||
@@ -865,7 +865,7 @@ impl Level {
|
||||
.await;
|
||||
let mut chunk = chunk.write().await;
|
||||
chunk.fluid_ticks.schedule_tick(
|
||||
ScheduledTick {
|
||||
&ScheduledTick {
|
||||
delay,
|
||||
position: block_pos,
|
||||
priority,
|
||||
|
||||
@@ -24,7 +24,7 @@ impl<'a, T: std::hash::Hash + Eq> ChunkTickScheduler<&'a T> {
|
||||
res
|
||||
}
|
||||
|
||||
pub fn schedule_tick(&mut self, tick: ScheduledTick<&'a T>, sub_tick_order: u64) {
|
||||
pub fn schedule_tick(&mut self, tick: &ScheduledTick<&'a T>, sub_tick_order: u64) {
|
||||
if self.queued_ticks.insert((tick.position, tick.value)) {
|
||||
let index = (self.offset + tick.delay as usize) % MAX_TICK_DELAY;
|
||||
self.tick_queue[index].push(OrderedTick {
|
||||
@@ -57,7 +57,7 @@ impl<'a, T: std::hash::Hash + Eq> ChunkTickScheduler<&'a T> {
|
||||
pub fn from_vec(ticks: &[ScheduledTick<&'a T>]) -> Self {
|
||||
let mut scheduler = Self::default();
|
||||
for tick in ticks {
|
||||
scheduler.schedule_tick(tick.clone(), 0);
|
||||
scheduler.schedule_tick(tick, 0);
|
||||
}
|
||||
scheduler
|
||||
}
|
||||
|
||||
@@ -112,9 +112,7 @@ impl WorldInfoWriter for AnvilLevelInfo {
|
||||
.expect("Time went backwards");
|
||||
let mut level_data = info.clone();
|
||||
level_data.last_played = since_the_epoch.as_millis() as i64;
|
||||
let level = LevelDat {
|
||||
data: level_data.clone(),
|
||||
};
|
||||
let level = LevelDat { data: level_data };
|
||||
|
||||
// open file
|
||||
let path = level_folder.join(LEVEL_DAT_FILE_NAME);
|
||||
|
||||
@@ -41,7 +41,6 @@ tokio = { workspace = true, features = [
|
||||
"io-util",
|
||||
"time",
|
||||
] }
|
||||
rayon.workspace = true
|
||||
thiserror.workspace = true
|
||||
futures.workspace = true
|
||||
|
||||
@@ -60,13 +59,14 @@ rustyline-async = "0.4.7"
|
||||
|
||||
# encryption
|
||||
rsa = { version = "=0.10.0-rc.10", features = ["sha1"] }
|
||||
rsa-der = "0.3"
|
||||
pkcs8 = "=0.11.0-rc.8"
|
||||
|
||||
# authentication
|
||||
ureq = { version = "3.1.4", features = [
|
||||
"json",
|
||||
] }
|
||||
|
||||
|
||||
sha1 = "=0.11.0-rc.3"
|
||||
|
||||
# velocity en
|
||||
@@ -79,7 +79,7 @@ base64 = "0.22.1"
|
||||
simplelog = { version = "0.12.2", features = ["ansi_term"] }
|
||||
|
||||
# Remove time in favor of chrono?
|
||||
time = "0.3"
|
||||
time = { version = "0.3", features = ["parsing", "macros"] }
|
||||
|
||||
# plugins
|
||||
libloading = "0.9"
|
||||
@@ -88,18 +88,12 @@ rustc-hash = "2.1.1"
|
||||
# Task handling
|
||||
tokio-util = { version = "0.7.17", features = ["rt"] }
|
||||
|
||||
# Memory profiling
|
||||
dhat = { version = "0.3.3", optional = true }
|
||||
|
||||
flate2 = "1.1.7"
|
||||
console-subscriber = { version = "0.5.0", optional = true }
|
||||
flate2 = "1.1.5"
|
||||
console-subscriber = { version = "0.5.0", default-features= false, optional = true }
|
||||
signature = "2.2.0"
|
||||
[dev-dependencies]
|
||||
tempfile.workspace = true
|
||||
|
||||
[features]
|
||||
#https://nnethercote.github.io/dh_view/dh_view.html
|
||||
#https://valgrind.org/docs/manual/dh-manual.html
|
||||
dhat-heap = ["dep:dhat"]
|
||||
console-subscriber = ["dep:console-subscriber"]
|
||||
tokio_taskdump = ["pumpkin-world/tokio_taskdump"]
|
||||
|
||||
@@ -52,7 +52,7 @@ pub trait BlockBehaviour: Send + Sync {
|
||||
}
|
||||
|
||||
fn on_entity_collision<'a>(&'a self, _args: OnEntityCollisionArgs<'a>) -> BlockFuture<'a, ()> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
fn should_drop_items_on_explosion(&self) -> bool {
|
||||
@@ -60,7 +60,7 @@ pub trait BlockBehaviour: Send + Sync {
|
||||
}
|
||||
|
||||
fn explode<'a>(&'a self, _args: ExplodeArgs<'a>) -> BlockFuture<'a, ()> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
/// Handles the block event, which is an event specific to a block with an integer ID and data.
|
||||
@@ -79,7 +79,7 @@ pub trait BlockBehaviour: Send + Sync {
|
||||
}
|
||||
|
||||
fn random_tick<'a>(&'a self, _args: RandomTickArgs<'a>) -> BlockFuture<'a, ()> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
fn can_place_at<'a>(&'a self, _args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
|
||||
@@ -92,24 +92,24 @@ pub trait BlockBehaviour: Send + Sync {
|
||||
|
||||
/// onBlockAdded in source code
|
||||
fn placed<'a>(&'a self, _args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
fn player_placed<'a>(&'a self, _args: PlayerPlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
fn broken<'a>(&'a self, _args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
fn on_neighbor_update<'a>(&'a self, _args: OnNeighborUpdateArgs<'a>) -> BlockFuture<'a, ()> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
/// Called if a block state is replaced or it replaces another state
|
||||
fn prepare<'a>(&'a self, _args: PrepareArgs<'a>) -> BlockFuture<'a, ()> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
fn get_state_for_neighbor_update<'a>(
|
||||
@@ -120,11 +120,11 @@ pub trait BlockBehaviour: Send + Sync {
|
||||
}
|
||||
|
||||
fn on_scheduled_tick<'a>(&'a self, _args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
fn on_state_replaced<'a>(&'a self, _args: OnStateReplacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
// --- Redstone/Comparator Methods ---
|
||||
|
||||
@@ -56,9 +56,6 @@ mod weather;
|
||||
mod whitelist;
|
||||
mod worldborder;
|
||||
|
||||
#[cfg(feature = "dhat-heap")]
|
||||
mod profile;
|
||||
|
||||
#[must_use]
|
||||
pub async fn default_dispatcher(basic_config: &BasicConfiguration) -> CommandDispatcher {
|
||||
let mut dispatcher = CommandDispatcher::default();
|
||||
@@ -144,9 +141,6 @@ pub async fn default_dispatcher(basic_config: &BasicConfiguration) -> CommandDis
|
||||
// Four
|
||||
dispatcher.register(stop::init_command_tree(), "minecraft:command.stop");
|
||||
|
||||
#[cfg(feature = "dhat-heap")]
|
||||
dispatcher.register(profile::init_command_tree(), "pumpkin:command.profile");
|
||||
|
||||
dispatcher
|
||||
}
|
||||
|
||||
@@ -510,13 +504,4 @@ fn register_level_4_permissions(registry: &mut PermissionRegistry) {
|
||||
PermissionDefault::Op(PermissionLvl::Four),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
#[cfg(feature = "dhat-heap")]
|
||||
registry
|
||||
.register_permission(Permission::new(
|
||||
"pumpkin:command.profile",
|
||||
"Controls heap profiling",
|
||||
PermissionDefault::Op(PermissionLvl::Four),
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
use pumpkin_util::text::TextComponent;
|
||||
use pumpkin_util::text::color::NamedColor;
|
||||
|
||||
use crate::command::CommandResult;
|
||||
|
||||
use crate::command::args::ConsumedArgs;
|
||||
use crate::command::tree::CommandTree;
|
||||
use crate::command::{CommandExecutor, CommandSender};
|
||||
use crate::{HEAP_PROFILER, stop_server};
|
||||
|
||||
const NAMES: [&str; 1] = ["mem_profile"];
|
||||
|
||||
const DESCRIPTION: &str = "Stop the server and dump a memory profile.";
|
||||
|
||||
struct Executor;
|
||||
|
||||
impl CommandExecutor for Executor {
|
||||
fn execute<'a>(
|
||||
&'a self,
|
||||
sender: &'a CommandSender,
|
||||
_server: &'a crate::server::Server,
|
||||
_args: &'a ConsumedArgs<'a>,
|
||||
) -> CommandResult<'a> {
|
||||
Box::pin(async move {
|
||||
sender
|
||||
.send_message(
|
||||
TextComponent::translate("commands.stop.stopping", [])
|
||||
.color_named(NamedColor::Red),
|
||||
)
|
||||
.await;
|
||||
|
||||
let mut profiler = HEAP_PROFILER.lock().await;
|
||||
let p = profiler.take().unwrap();
|
||||
drop(p);
|
||||
|
||||
stop_server();
|
||||
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_command_tree() -> CommandTree {
|
||||
CommandTree::new(NAMES, DESCRIPTION).execute(Executor)
|
||||
}
|
||||
@@ -67,9 +67,8 @@ impl BannedIpEntry {
|
||||
}
|
||||
|
||||
mod format {
|
||||
use simplelog::FormatItem;
|
||||
|
||||
const DATE_FORMAT: &[FormatItem<'static>] = time::macros::format_description!(
|
||||
const DATE_FORMAT: &[time::format_description::FormatItem<'static>] = time::macros::format_description!(
|
||||
"[year]-[month]-[day] [hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]"
|
||||
);
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ pub trait ItemBehaviour: Send + Sync {
|
||||
_item: &'a Item,
|
||||
_player: &'a Player,
|
||||
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
fn use_on_block<'a>(
|
||||
@@ -37,7 +37,7 @@ pub trait ItemBehaviour: Send + Sync {
|
||||
_block: &'a Block,
|
||||
_server: &'a Server,
|
||||
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
fn use_on_entity<'a>(
|
||||
@@ -46,7 +46,7 @@ pub trait ItemBehaviour: Send + Sync {
|
||||
_player: &'a Player,
|
||||
_entity: Arc<dyn EntityBase>,
|
||||
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
||||
fn can_mine(&self, _player: &Player) -> bool {
|
||||
|
||||
@@ -42,10 +42,6 @@ pub mod plugin;
|
||||
pub mod server;
|
||||
pub mod world;
|
||||
|
||||
#[cfg(feature = "dhat-heap")]
|
||||
pub static HEAP_PROFILER: LazyLock<Mutex<Option<dhat::Profiler>>> =
|
||||
LazyLock::new(|| Mutex::new(None));
|
||||
|
||||
pub static PLUGIN_MANAGER: LazyLock<Arc<PluginManager>> =
|
||||
LazyLock::new(|| Arc::new(PluginManager::new()));
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ use tokio::signal::ctrl_c;
|
||||
use tokio::signal::unix::{SignalKind, signal};
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
use pumpkin::{LOGGER_IMPL, PumpkinServer, SHOULD_STOP, STOP_INTERRUPT, init_log, stop_server};
|
||||
use pumpkin::{PumpkinServer, SHOULD_STOP, STOP_INTERRUPT, init_log, stop_server};
|
||||
|
||||
use pumpkin_config::{AdvancedConfiguration, BasicConfiguration, LoadConfiguration};
|
||||
use pumpkin_util::{
|
||||
@@ -74,13 +74,6 @@ pub mod plugin;
|
||||
pub mod server;
|
||||
pub mod world;
|
||||
|
||||
#[cfg(feature = "dhat-heap")]
|
||||
#[global_allocator]
|
||||
static ALLOC: dhat::Alloc = dhat::Alloc;
|
||||
|
||||
#[cfg(feature = "dhat-heap")]
|
||||
use pumpkin::HEAP_PROFILER;
|
||||
|
||||
pub static PLUGIN_MANAGER: LazyLock<Arc<PluginManager>> =
|
||||
LazyLock::new(|| Arc::new(PluginManager::new()));
|
||||
|
||||
@@ -102,13 +95,6 @@ const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
async fn main() {
|
||||
#[cfg(feature = "console-subscriber")]
|
||||
console_subscriber::init();
|
||||
#[cfg(feature = "dhat-heap")]
|
||||
{
|
||||
let profiler = dhat::Profiler::new_heap();
|
||||
let mut static_loc = HEAP_PROFILER.lock().await;
|
||||
*static_loc = Some(profiler);
|
||||
};
|
||||
|
||||
let time = Instant::now();
|
||||
|
||||
let exec_dir = std::env::current_dir().unwrap();
|
||||
@@ -123,10 +109,6 @@ async fn main() {
|
||||
|
||||
let default_panic = std::panic::take_hook();
|
||||
std::panic::set_hook(Box::new(move |info| {
|
||||
if let Some((wrapper, _)) = LOGGER_IMPL.wait() {
|
||||
// Drop readline to reset terminal state
|
||||
let _ = wrapper.take_readline();
|
||||
}
|
||||
default_panic(info);
|
||||
// TODO: Gracefully exit?
|
||||
// We need to abide by the panic rules here.
|
||||
|
||||
@@ -19,7 +19,6 @@ use pumpkin_util::{Hand, ProfileAction, text::TextComponent};
|
||||
use serde::Deserialize;
|
||||
use sha1::Digest;
|
||||
use sha2::Sha256;
|
||||
use simplelog::FormatItem;
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
use thiserror::Error;
|
||||
@@ -180,7 +179,7 @@ pub async fn can_not_join(
|
||||
address: &SocketAddr,
|
||||
server: &Server,
|
||||
) -> Option<TextComponent> {
|
||||
const FORMAT_DESCRIPTION: &[FormatItem<'_>] = time::macros::format_description!(
|
||||
const FORMAT_DESCRIPTION: &[time::format_description::FormatItem<'static>] = time::macros::format_description!(
|
||||
"[year]-[month]-[day] at [hour]:[minute]:[second] [offset_hour sign:mandatory]:[offset_minute]"
|
||||
);
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ pub trait DynEventHandler: Send + Sync {
|
||||
///
|
||||
/// # Returns
|
||||
/// The priority of the event handler.
|
||||
fn get_priority(&self) -> EventPriority;
|
||||
fn get_priority(&self) -> &EventPriority;
|
||||
}
|
||||
|
||||
/// A trait for handling specific events.
|
||||
@@ -72,7 +72,7 @@ pub trait EventHandler<E: Payload>: Send + Sync {
|
||||
/// # Arguments
|
||||
/// - `event`: A mutable reference to the event to handle.
|
||||
fn handle_blocking(&self, _server: &Arc<Server>, _event: &mut E) -> BoxFuture<'_, ()> {
|
||||
Box::pin(async move {})
|
||||
Box::pin(async {})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,8 +129,8 @@ where
|
||||
}
|
||||
|
||||
/// Retrieves the priority of the handler.
|
||||
fn get_priority(&self) -> EventPriority {
|
||||
self.priority.clone()
|
||||
fn get_priority(&self) -> &EventPriority {
|
||||
&self.priority
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use num_bigint::BigInt;
|
||||
use pkcs8::EncodePublicKey;
|
||||
use pumpkin_protocol::java::client::login::CEncryptionRequest;
|
||||
use rsa::{Pkcs1v15Encrypt, RsaPrivateKey, traits::PublicKeyParts as _};
|
||||
use rsa::{Pkcs1v15Encrypt, RsaPrivateKey};
|
||||
use sha1::Sha1;
|
||||
use sha2::Digest;
|
||||
|
||||
@@ -17,11 +18,15 @@ impl KeyStore {
|
||||
log::debug!("Creating encryption keys...");
|
||||
let private_key = Self::generate_private_key();
|
||||
|
||||
let public_key_der = rsa_der::public_key_to_der(
|
||||
&private_key.n().to_be_bytes(),
|
||||
&private_key.e().to_be_bytes(),
|
||||
)
|
||||
.into_boxed_slice();
|
||||
let public_key = private_key.to_public_key();
|
||||
|
||||
let public_key_der = public_key
|
||||
.to_public_key_der()
|
||||
.expect("Failed to encode public key to SPKI DER")
|
||||
.as_bytes()
|
||||
.to_vec()
|
||||
.into_boxed_slice();
|
||||
|
||||
Self {
|
||||
private_key,
|
||||
public_key_der,
|
||||
|
||||
Reference in New Issue
Block a user