mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-10-31 04:17:44 +00:00
Fix rust 1.89 warns
This commit is contained in:
@@ -60,7 +60,7 @@ representative at an online or offline event.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
lilalexmed@proton.me.
|
||||
<lilalexmed@proton.me>.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
@@ -116,7 +116,7 @@ the community.
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
<https://www.contributor-covenant.org/version/2/0/code_of_conduct.html>.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
@@ -124,5 +124,5 @@ enforcement ladder](https://github.com/mozilla/diversity).
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
<https://www.contributor-covenant.org/faq>. Translations are available at
|
||||
<https://www.contributor-covenant.org/translations>.
|
||||
|
||||
@@ -47,10 +47,10 @@ Note: Pumpkin's clippy settings are relatively strict, this can be may frustrati
|
||||
- **No Clippy Warnings:** Address all warnings reported by the Clippy linter. You can check for warnings using `cargo clippy --all-targets`.
|
||||
- **Passing Unit Tests:** All existing unit tests must pass successfully. You can run the tests with `cargo test`.
|
||||
|
||||
**Best Practice**
|
||||
#### Best Practice
|
||||
|
||||
- **Writing Unit Tests:** When adding new features or modifying existing code, consider adding unit tests to prevent regressions in the future. Refer to the Rust documentation for guidance on writing tests: https://doc.rust-lang.org/book/ch11-01-writing-tests.html
|
||||
- **Benchmarking:** If your changes might impact performance, consider adding benchmarks to track performance regressions or improvements. We use the Criterion library for benchmarking. Refer to their Quick Start guide for more information: https://github.com/bheisler/criterion.rs#quickstart
|
||||
- **Writing Unit Tests:** When adding new features or modifying existing code, consider adding unit tests to prevent regressions in the future. Refer to the Rust documentation for guidance on writing tests: <https://doc.rust-lang.org/book/ch11-01-writing-tests.html>
|
||||
- **Benchmarking:** If your changes might impact performance, consider adding benchmarks to track performance regressions or improvements. We use the Criterion library for benchmarking. Refer to their Quick Start guide for more information: <https://github.com/bheisler/criterion.rs#quickstart>
|
||||
- **Clear and Concise Commit Messages:** Use clear and concise commit messages that describe the changes you've made.
|
||||
- **Code Style:** Adhere to consistent coding style throughout your contributions.
|
||||
- **Documentation:** If your changes introduce new functionality, consider updating the relevant documentation.
|
||||
|
||||
47
Cargo.lock
generated
47
Cargo.lock
generated
@@ -419,7 +419,7 @@ version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -647,9 +647,9 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-bigint"
|
||||
version = "0.7.0-pre.7"
|
||||
version = "0.7.0-rc.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85ff38607b7ebe30e4715eeb0a0427ff42e3b6b47b2df55a775e767ef2658ccd"
|
||||
checksum = "737a2363b81de8cc95d8780d84aecb4b3c6f41e4473759da6636072b5514c875"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"rand_core 0.9.3",
|
||||
@@ -866,7 +866,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1379,9 +1379,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "io-uring"
|
||||
version = "0.7.8"
|
||||
version = "0.7.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
|
||||
checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
@@ -2362,9 +2362,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rsa"
|
||||
version = "0.10.0-rc.3"
|
||||
version = "0.10.0-rc.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e8cb237ca3624409eda7d73de0d423815c9d91175ed5a62a8dd6549d2408cc2"
|
||||
checksum = "b311b61ea276fd51ccb77f6995c5f70084db933bab9655ba51fe5d831ea25b39"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"crypto-bigint",
|
||||
@@ -2391,9 +2391,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.25"
|
||||
version = "0.1.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"
|
||||
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
@@ -2417,7 +2417,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2648,18 +2648,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.5"
|
||||
version = "1.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410"
|
||||
checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signature"
|
||||
version = "3.0.0-rc.1"
|
||||
version = "3.0.0-rc.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8852cecbd17ba45978bbbe43061ebe36a2ae376058c5c172e09f72888f8f7de"
|
||||
checksum = "4835c3b5ecb10171941a4998a95a3a76ecac1c5ae8e6954f2ad030acd1c7e8ab"
|
||||
dependencies = [
|
||||
"digest 0.11.0-rc.0",
|
||||
"rand_core 0.9.3",
|
||||
@@ -2804,7 +2804,7 @@ dependencies = [
|
||||
"fastrand",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2916,9 +2916,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.47.0"
|
||||
version = "1.47.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43864ed400b6043a4757a25c7a64a8efde741aed79a056a2fb348a406701bb35"
|
||||
checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
@@ -2958,15 +2958,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.15"
|
||||
version = "0.7.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df"
|
||||
checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"hashbrown 0.15.4",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
@@ -3255,9 +3254,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.17.0"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d"
|
||||
checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be"
|
||||
dependencies = [
|
||||
"getrandom 0.3.3",
|
||||
"js-sys",
|
||||
@@ -3410,7 +3409,7 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -51,7 +51,7 @@ futures = { version = "0.3", default-features = false, features = ["executor"] }
|
||||
rayon = "1.10"
|
||||
crossbeam = "0.8"
|
||||
|
||||
uuid = { version = "1.17", features = ["serde", "v3", "v4"] }
|
||||
uuid = { version = "1.18", features = ["serde", "v3", "v4"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
||||
|
||||
@@ -7,13 +7,12 @@
|
||||
[](https://opensource.org/licenses/MIT)
|
||||

|
||||
|
||||
|
||||
</div>
|
||||
|
||||
[Pumpkin](https://pumpkinmc.org/) is a Minecraft server built entirely in Rust, offering a fast, efficient,
|
||||
and customizable experience. It prioritizes performance and player enjoyment while adhering to the core mechanics of the game.
|
||||
<div align="center">
|
||||
|
||||
|
||||

|
||||
|
||||
</div>
|
||||
@@ -49,7 +48,7 @@ and customizable experience. It prioritizes performance and player enjoyment whi
|
||||
- [x] World Loading
|
||||
- [x] World Time
|
||||
- [x] World Borders
|
||||
- [x] World Saving
|
||||
- [x] World Saving
|
||||
- [x] Lighting
|
||||
- [x] Entity Spawning
|
||||
- [x] Item drops (W.I.P)
|
||||
@@ -74,7 +73,7 @@ and customizable experience. It prioritizes performance and player enjoyment whi
|
||||
- [x] Experience
|
||||
- [x] Hunger
|
||||
- [X] Off Hand
|
||||
- [ ] Advancements
|
||||
- [ ] Advancements
|
||||
- [ ] Eating
|
||||
- Entities
|
||||
- [x] Non-Living (Minecart, Eggs...) (W.I.P)
|
||||
@@ -113,7 +112,7 @@ Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
|
||||
## Docs
|
||||
|
||||
Pumpkin's documentation can be found at https://pumpkinmc.org/
|
||||
Pumpkin's documentation can be found at <https://pumpkinmc.org/>
|
||||
|
||||
## Communication
|
||||
|
||||
|
||||
@@ -83,13 +83,13 @@ pub fn send_cancellable(input: TokenStream) -> TokenStream {
|
||||
if let Stmt::Expr(expr, _) = stmt {
|
||||
if event.is_none() {
|
||||
event = Some(expr);
|
||||
} else if let Expr::Block(b) = expr {
|
||||
if 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);
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,23 +119,21 @@ gen_from!(i16);
|
||||
gen_from!(u16);
|
||||
gen_from!(u32);
|
||||
|
||||
macro_rules! gen_try_from {
|
||||
macro_rules! gen_from {
|
||||
($ty: ty) => {
|
||||
impl TryFrom<$ty> for VarUInt {
|
||||
type Error = <i32 as TryFrom<$ty>>::Error;
|
||||
|
||||
fn try_from(value: $ty) -> Result<Self, Self::Error> {
|
||||
Ok(VarUInt(value as u32))
|
||||
impl From<$ty> for VarUInt {
|
||||
fn from(value: $ty) -> Self {
|
||||
VarUInt(value as u32)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
gen_try_from!(i32);
|
||||
gen_try_from!(i64);
|
||||
gen_try_from!(u64);
|
||||
gen_try_from!(isize);
|
||||
gen_try_from!(usize);
|
||||
gen_from!(i32);
|
||||
gen_from!(i64);
|
||||
gen_from!(u64);
|
||||
gen_from!(isize);
|
||||
gen_from!(usize);
|
||||
|
||||
impl Serialize for VarUInt {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
|
||||
@@ -339,12 +339,11 @@ impl<'de> serde::Deserialize<'de> for Vector3<i32> {
|
||||
self,
|
||||
mut seq: A,
|
||||
) -> Result<Self::Value, A::Error> {
|
||||
if let Some(x) = seq.next_element::<i32>()? {
|
||||
if let Some(y) = seq.next_element::<i32>()? {
|
||||
if let Some(z) = seq.next_element::<i32>()? {
|
||||
return Ok(Vector3::new(x, y, z));
|
||||
}
|
||||
}
|
||||
if let Some(x) = seq.next_element::<i32>()?
|
||||
&& let Some(y) = seq.next_element::<i32>()?
|
||||
&& let Some(z) = seq.next_element::<i32>()?
|
||||
{
|
||||
return Ok(Vector3::new(x, y, z));
|
||||
}
|
||||
Err(serde::de::Error::custom("Failed to read Vector<i32>"))
|
||||
}
|
||||
@@ -369,12 +368,11 @@ impl<'de> serde::Deserialize<'de> for Vector3<f32> {
|
||||
self,
|
||||
mut seq: A,
|
||||
) -> Result<Self::Value, A::Error> {
|
||||
if let Some(x) = seq.next_element::<f32>()? {
|
||||
if let Some(y) = seq.next_element::<f32>()? {
|
||||
if let Some(z) = seq.next_element::<f32>()? {
|
||||
return Ok(Vector3::new(x, y, z));
|
||||
}
|
||||
}
|
||||
if let Some(x) = seq.next_element::<f32>()?
|
||||
&& let Some(y) = seq.next_element::<f32>()?
|
||||
&& let Some(z) = seq.next_element::<f32>()?
|
||||
{
|
||||
return Ok(Vector3::new(x, y, z));
|
||||
}
|
||||
Err(serde::de::Error::custom("Failed to read Vector<f32>"))
|
||||
}
|
||||
@@ -399,12 +397,11 @@ impl<'de> serde::Deserialize<'de> for Vector3<f64> {
|
||||
self,
|
||||
mut seq: A,
|
||||
) -> Result<Self::Value, A::Error> {
|
||||
if let Some(x) = seq.next_element::<f64>()? {
|
||||
if let Some(y) = seq.next_element::<f64>()? {
|
||||
if let Some(z) = seq.next_element::<f64>()? {
|
||||
return Ok(Vector3::new(x, y, z));
|
||||
}
|
||||
}
|
||||
if let Some(x) = seq.next_element::<f64>()?
|
||||
&& let Some(y) = seq.next_element::<f64>()?
|
||||
&& let Some(z) = seq.next_element::<f64>()?
|
||||
{
|
||||
return Ok(Vector3::new(x, y, z));
|
||||
}
|
||||
Err(serde::de::Error::custom("Failed to read Vector<f64>"))
|
||||
}
|
||||
|
||||
@@ -197,10 +197,10 @@ impl PermissionManager {
|
||||
|
||||
// Check for inherited permissions from parent nodes
|
||||
for (node, value) in attachment.get_permissions() {
|
||||
if let Some(permission) = reg.get_permission(node) {
|
||||
if permission.children.contains_key(permission_node) {
|
||||
return *value && *permission.children.get(permission_node).unwrap();
|
||||
}
|
||||
if let Some(permission) = reg.get_permission(node)
|
||||
&& permission.children.contains_key(permission_node)
|
||||
{
|
||||
return *value && *permission.children.get(permission_node).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ derive-getters = "0.5.0"
|
||||
thread_local = "1.1.9"
|
||||
lru = "0.16.0"
|
||||
|
||||
tokio-util = { version = "0.7.15", features = ["rt"] }
|
||||
tokio-util = { version = "0.7.16", features = ["rt"] }
|
||||
rand = "0.9.2"
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -70,7 +70,7 @@ impl DropperBlockEntity {
|
||||
dirty: AtomicBool::new(false),
|
||||
}
|
||||
}
|
||||
pub async fn get_random_slot(&self) -> Option<MutexGuard<ItemStack>> {
|
||||
pub async fn get_random_slot(&self) -> Option<MutexGuard<'_, ItemStack>> {
|
||||
// this.unpackLootTable(null);
|
||||
let mut ret = None;
|
||||
let mut j = 1;
|
||||
|
||||
@@ -85,14 +85,12 @@ impl FurnaceBlockEntity {
|
||||
|
||||
if let Some(recipe_output_item) =
|
||||
Item::from_registry_key(recipe.result.id.strip_prefix("minecraft:").unwrap())
|
||||
&& !is_top_items_empty
|
||||
&& recipe_output_item.id == side_item_stack.item.id
|
||||
&& side_item_stack.item_count < max_count
|
||||
&& side_item_stack.item_count < side_item_stack.get_max_stack_size()
|
||||
{
|
||||
if !is_top_items_empty
|
||||
&& recipe_output_item.id == side_item_stack.item.id
|
||||
&& side_item_stack.item_count < max_count
|
||||
&& side_item_stack.item_count < side_item_stack.get_max_stack_size()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
@@ -163,24 +163,24 @@ impl HopperBlockEntity {
|
||||
async fn suck_in_items(&self, world: &Arc<dyn SimpleWorld>) -> bool {
|
||||
// TODO getEntityContainer
|
||||
let pos_up = &self.position.up();
|
||||
if let Some(entity) = world.get_block_entity(pos_up).await {
|
||||
if let Some(container) = entity.get_inventory() {
|
||||
// TODO check WorldlyContainer
|
||||
for i in 0..container.size() {
|
||||
let bind = container.get_stack(i).await;
|
||||
let mut item = bind.lock().await;
|
||||
if !item.is_empty() && container.can_transfer_to(self, i, &item) {
|
||||
//TODO WorldlyContainer
|
||||
let backup = item.clone();
|
||||
let one_item = item.split(1);
|
||||
if Self::add_one_item(container.as_ref(), self, one_item).await {
|
||||
return true;
|
||||
}
|
||||
*item = backup;
|
||||
if let Some(entity) = world.get_block_entity(pos_up).await
|
||||
&& let Some(container) = entity.get_inventory()
|
||||
{
|
||||
// TODO check WorldlyContainer
|
||||
for i in 0..container.size() {
|
||||
let bind = container.get_stack(i).await;
|
||||
let mut item = bind.lock().await;
|
||||
if !item.is_empty() && container.can_transfer_to(self, i, &item) {
|
||||
//TODO WorldlyContainer
|
||||
let backup = item.clone();
|
||||
let one_item = item.split(1);
|
||||
if Self::add_one_item(container.as_ref(), self, one_item).await {
|
||||
return true;
|
||||
}
|
||||
*item = backup;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
let (block, state) = world.get_block_and_state(pos_up).await;
|
||||
if !(state.is_solid()
|
||||
@@ -200,32 +200,31 @@ impl HopperBlockEntity {
|
||||
if let Some(entity) = world
|
||||
.get_block_entity(&self.position.offset(to_offset(&self.facing)))
|
||||
.await
|
||||
&& let Some(container) = entity.get_inventory()
|
||||
{
|
||||
if let Some(container) = entity.get_inventory() {
|
||||
// TODO check WorldlyContainer
|
||||
let mut is_full = true;
|
||||
for i in 0..container.size() {
|
||||
let bind = container.get_stack(i).await;
|
||||
let item = bind.lock().await;
|
||||
if item.item_count < item.get_max_stack_size() {
|
||||
is_full = false;
|
||||
break;
|
||||
}
|
||||
// TODO check WorldlyContainer
|
||||
let mut is_full = true;
|
||||
for i in 0..container.size() {
|
||||
let bind = container.get_stack(i).await;
|
||||
let item = bind.lock().await;
|
||||
if item.item_count < item.get_max_stack_size() {
|
||||
is_full = false;
|
||||
break;
|
||||
}
|
||||
if is_full {
|
||||
return false;
|
||||
}
|
||||
for i in &self.items {
|
||||
let mut item = i.lock().await;
|
||||
if !item.is_empty() {
|
||||
//TODO WorldlyContainer
|
||||
let backup = item.clone();
|
||||
let one_item = item.split(1);
|
||||
if Self::add_one_item(self, container.as_ref(), one_item).await {
|
||||
return true;
|
||||
}
|
||||
*item = backup;
|
||||
}
|
||||
if is_full {
|
||||
return false;
|
||||
}
|
||||
for i in &self.items {
|
||||
let mut item = i.lock().await;
|
||||
if !item.is_empty() {
|
||||
//TODO WorldlyContainer
|
||||
let backup = item.clone();
|
||||
let one_item = item.split(1);
|
||||
if Self::add_one_item(self, container.as_ref(), one_item).await {
|
||||
return true;
|
||||
}
|
||||
*item = backup;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -247,37 +246,34 @@ impl HopperBlockEntity {
|
||||
success = true;
|
||||
}
|
||||
if success {
|
||||
if to_empty {
|
||||
if let Some(hopper) = to.as_any().downcast_ref::<HopperBlockEntity>() {
|
||||
if hopper
|
||||
if to_empty
|
||||
&& let Some(hopper) = to.as_any().downcast_ref::<HopperBlockEntity>()
|
||||
&& hopper
|
||||
.cooldown_time
|
||||
.load(std::sync::atomic::Ordering::Relaxed)
|
||||
<= 8
|
||||
{
|
||||
if let Some(from_hopper) = from.as_any().downcast_ref::<HopperBlockEntity>()
|
||||
{
|
||||
if from_hopper
|
||||
.cooldown_time
|
||||
.load(std::sync::atomic::Ordering::Relaxed)
|
||||
<= 8
|
||||
>= hopper
|
||||
.cooldown_time
|
||||
.load(std::sync::atomic::Ordering::Relaxed)
|
||||
{
|
||||
if let Some(from_hopper) =
|
||||
from.as_any().downcast_ref::<HopperBlockEntity>()
|
||||
{
|
||||
if from_hopper
|
||||
.cooldown_time
|
||||
.load(std::sync::atomic::Ordering::Relaxed)
|
||||
>= hopper
|
||||
.cooldown_time
|
||||
.load(std::sync::atomic::Ordering::Relaxed)
|
||||
{
|
||||
hopper
|
||||
.cooldown_time
|
||||
.store(7, std::sync::atomic::Ordering::Relaxed);
|
||||
} else {
|
||||
hopper
|
||||
.cooldown_time
|
||||
.store(8, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
} else {
|
||||
hopper
|
||||
.cooldown_time
|
||||
.store(8, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
hopper
|
||||
.cooldown_time
|
||||
.store(7, std::sync::atomic::Ordering::Relaxed);
|
||||
} else {
|
||||
hopper
|
||||
.cooldown_time
|
||||
.store(8, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
} else {
|
||||
hopper
|
||||
.cooldown_time
|
||||
.store(8, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
to.mark_dirty();
|
||||
|
||||
@@ -28,10 +28,10 @@ impl PlayerDataStorage {
|
||||
/// Creates a new `PlayerDataStorage` with the specified data path and cache expiration time.
|
||||
pub fn new(data_path: impl Into<PathBuf>) -> Self {
|
||||
let path = data_path.into();
|
||||
if !path.exists() {
|
||||
if let Err(e) = create_dir_all(&path) {
|
||||
log::error!("Failed to create player data directory at {path:?}: {e}");
|
||||
}
|
||||
if !path.exists()
|
||||
&& let Err(e) = create_dir_all(&path)
|
||||
{
|
||||
log::error!("Failed to create player data directory at {path:?}: {e}");
|
||||
}
|
||||
|
||||
Self {
|
||||
@@ -126,11 +126,11 @@ impl PlayerDataStorage {
|
||||
let path = self.get_player_data_path(uuid);
|
||||
|
||||
// Ensure parent directory exists
|
||||
if let Some(parent) = path.parent() {
|
||||
if let Err(e) = create_dir_all(parent) {
|
||||
log::error!("Failed to create player data directory for {uuid}: {e}");
|
||||
return Err(PlayerDataError::Io(e));
|
||||
}
|
||||
if let Some(parent) = path.parent()
|
||||
&& let Err(e) = create_dir_all(parent)
|
||||
{
|
||||
log::error!("Failed to create player data directory for {uuid}: {e}");
|
||||
return Err(PlayerDataError::Io(e));
|
||||
}
|
||||
|
||||
// Create the file and write directly with GZip compression
|
||||
|
||||
@@ -63,15 +63,15 @@ pub trait Inventory: Send + Sync + Debug + Clearable {
|
||||
) {
|
||||
if let Some(inventory_list) = nbt.get_list("Items") {
|
||||
for tag in inventory_list {
|
||||
if let Some(item_compound) = tag.extract_compound() {
|
||||
if let Some(slot_byte) = item_compound.get_byte("Slot") {
|
||||
let slot = slot_byte as usize;
|
||||
if slot < stacks.len() {
|
||||
if let Some(item_stack) = ItemStack::read_item_stack(item_compound) {
|
||||
// This won't error cause it's only called on initialization
|
||||
*stacks[slot].try_lock().unwrap() = item_stack;
|
||||
}
|
||||
}
|
||||
if let Some(item_compound) = tag.extract_compound()
|
||||
&& let Some(slot_byte) = item_compound.get_byte("Slot")
|
||||
{
|
||||
let slot = slot_byte as usize;
|
||||
if slot < stacks.len()
|
||||
&& let Some(item_stack) = ItemStack::read_item_stack(item_compound)
|
||||
{
|
||||
// This won't error cause it's only called on initialization
|
||||
*stacks[slot].try_lock().unwrap() = item_stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ num-bigint = "0.4"
|
||||
rustyline-async = "0.4.7"
|
||||
|
||||
# encryption
|
||||
rsa = { version = "=0.10.0-rc.3", features = ["sha1"] }
|
||||
rsa = { version = "=0.10.0-rc.4", features = ["sha1"] }
|
||||
rsa-der = "0.3"
|
||||
|
||||
# authentication
|
||||
@@ -77,7 +77,7 @@ libloading = "0.8"
|
||||
rustc-hash = "2.1.1"
|
||||
|
||||
# Task handling
|
||||
tokio-util = { version = "0.7.15", features = ["rt"] }
|
||||
tokio-util = { version = "0.7.16", features = ["rt"] }
|
||||
|
||||
# Memory profiling
|
||||
dhat = { version = "0.3.3", optional = true }
|
||||
|
||||
@@ -27,14 +27,14 @@ pub struct CandleBlock;
|
||||
#[async_trait]
|
||||
impl BlockBehaviour for CandleBlock {
|
||||
async fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
||||
if args.player.get_entity().pose.load() != EntityPose::Crouching {
|
||||
if let BlockIsReplacing::Itself(state_id) = args.replacing {
|
||||
let mut properties = CandleLikeProperties::from_state_id(state_id, args.block);
|
||||
if properties.candles.to_index() < 3 {
|
||||
properties.candles = Integer1To4::from_index(properties.candles.to_index() + 1);
|
||||
}
|
||||
return properties.to_state_id(args.block);
|
||||
if args.player.get_entity().pose.load() != EntityPose::Crouching
|
||||
&& let BlockIsReplacing::Itself(state_id) = args.replacing
|
||||
{
|
||||
let mut properties = CandleLikeProperties::from_state_id(state_id, args.block);
|
||||
if properties.candles.to_index() < 3 {
|
||||
properties.candles = Integer1To4::from_index(properties.candles.to_index() + 1);
|
||||
}
|
||||
return properties.to_state_id(args.block);
|
||||
}
|
||||
|
||||
let mut properties = CandleLikeProperties::default(args.block);
|
||||
|
||||
@@ -48,22 +48,21 @@ impl BlockBehaviour for ChiseledBookshelfBlock {
|
||||
|
||||
if let Some(slot) = Self::get_slot_for_hit(args.hit, properties.facing) {
|
||||
if Self::is_slot_used(properties, slot) {
|
||||
if let Some(block_entity) = args.world.get_block_entity(args.position).await {
|
||||
if let Some(block_entity) = block_entity
|
||||
if let Some(block_entity) = args.world.get_block_entity(args.position).await
|
||||
&& let Some(block_entity) = block_entity
|
||||
.as_any()
|
||||
.downcast_ref::<ChiseledBookshelfBlockEntity>()
|
||||
{
|
||||
Self::try_remove_book(
|
||||
args.world,
|
||||
args.player,
|
||||
args.position,
|
||||
block_entity,
|
||||
properties,
|
||||
slot,
|
||||
)
|
||||
.await;
|
||||
return BlockActionResult::Success;
|
||||
}
|
||||
{
|
||||
Self::try_remove_book(
|
||||
args.world,
|
||||
args.player,
|
||||
args.position,
|
||||
block_entity,
|
||||
properties,
|
||||
slot,
|
||||
)
|
||||
.await;
|
||||
return BlockActionResult::Success;
|
||||
}
|
||||
} else {
|
||||
return BlockActionResult::Consume;
|
||||
@@ -88,23 +87,22 @@ impl BlockBehaviour for ChiseledBookshelfBlock {
|
||||
if let Some(slot) = Self::get_slot_for_hit(args.hit, properties.facing) {
|
||||
if Self::is_slot_used(properties, slot) {
|
||||
return BlockActionResult::PassToDefaultBlockAction;
|
||||
} else if let Some(block_entity) = args.world.get_block_entity(args.position).await {
|
||||
if let Some(block_entity) = block_entity
|
||||
} else if let Some(block_entity) = args.world.get_block_entity(args.position).await
|
||||
&& let Some(block_entity) = block_entity
|
||||
.as_any()
|
||||
.downcast_ref::<ChiseledBookshelfBlockEntity>()
|
||||
{
|
||||
Self::try_add_book(
|
||||
args.world,
|
||||
args.player,
|
||||
args.position,
|
||||
block_entity,
|
||||
properties,
|
||||
slot,
|
||||
args.item_stack,
|
||||
)
|
||||
.await;
|
||||
return BlockActionResult::Success;
|
||||
}
|
||||
{
|
||||
Self::try_add_book(
|
||||
args.world,
|
||||
args.player,
|
||||
args.position,
|
||||
block_entity,
|
||||
properties,
|
||||
slot,
|
||||
args.item_stack,
|
||||
)
|
||||
.await;
|
||||
return BlockActionResult::Success;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,13 +115,12 @@ impl BlockBehaviour for ChiseledBookshelfBlock {
|
||||
}
|
||||
|
||||
async fn get_comparator_output(&self, args: GetComparatorOutputArgs<'_>) -> Option<u8> {
|
||||
if let Some(block_entity) = args.world.get_block_entity(args.position).await {
|
||||
if let Some(block_entity) = block_entity
|
||||
if let Some(block_entity) = args.world.get_block_entity(args.position).await
|
||||
&& let Some(block_entity) = block_entity
|
||||
.as_any()
|
||||
.downcast_ref::<ChiseledBookshelfBlockEntity>()
|
||||
{
|
||||
return Some((block_entity.last_interacted_slot.load(Ordering::Relaxed) + 1) as u8);
|
||||
}
|
||||
{
|
||||
return Some((block_entity.last_interacted_slot.load(Ordering::Relaxed) + 1) as u8);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
@@ -74,19 +74,19 @@ impl BlockBehaviour for CommandBlock {
|
||||
}
|
||||
|
||||
async fn on_scheduled_tick(&self, args: OnScheduledTickArgs<'_>) {
|
||||
if let Some(block_entity) = args.world.get_block_entity(args.position).await {
|
||||
if block_entity.resource_location() != CommandBlockEntity::ID {
|
||||
return;
|
||||
}
|
||||
// TODO
|
||||
if let Some(block_entity) = args.world.get_block_entity(args.position).await
|
||||
&& block_entity.resource_location() != CommandBlockEntity::ID
|
||||
{
|
||||
return;
|
||||
}
|
||||
// TODO
|
||||
}
|
||||
|
||||
async fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
|
||||
if let Some(player) = args.player {
|
||||
if player.gamemode.load() == GameMode::Creative {
|
||||
return true;
|
||||
}
|
||||
if let Some(player) = args.player
|
||||
&& player.gamemode.load() == GameMode::Creative
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
|
||||
@@ -50,24 +50,16 @@ impl BlockBehaviour for ComposterBlock {
|
||||
self.clear_composter(args.world, args.position, state_id, args.block)
|
||||
.await;
|
||||
}
|
||||
if level < 7 {
|
||||
if let Some(chance) =
|
||||
if level < 7
|
||||
&& let Some(chance) =
|
||||
get_composter_increase_chance_from_item_id(args.item_stack.lock().await.item.id)
|
||||
{
|
||||
if level == 0 || rand::rng().random_bool(f64::from(chance)) {
|
||||
self.update_level_composter(
|
||||
args.world,
|
||||
args.position,
|
||||
state_id,
|
||||
args.block,
|
||||
level + 1,
|
||||
)
|
||||
.await;
|
||||
args.world
|
||||
.sync_world_event(WorldEvent::ComposterUsed, *args.position, 1)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
&& (level == 0 || rand::rng().random_bool(f64::from(chance)))
|
||||
{
|
||||
self.update_level_composter(args.world, args.position, state_id, args.block, level + 1)
|
||||
.await;
|
||||
args.world
|
||||
.sync_world_event(WorldEvent::ComposterUsed, *args.position, 1)
|
||||
.await;
|
||||
}
|
||||
BlockActionResult::Consume
|
||||
}
|
||||
|
||||
@@ -175,15 +175,13 @@ impl BlockBehaviour for FireBlock {
|
||||
|
||||
let dimension = args.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 == VanillaDimensionType::Overworld
|
||||
|| dimension == VanillaDimensionType::TheNether
|
||||
{
|
||||
if let Some(portal) =
|
||||
if (dimension == VanillaDimensionType::Overworld
|
||||
|| dimension == VanillaDimensionType::TheNether)
|
||||
&& let Some(portal) =
|
||||
NetherPortal::get_new_portal(args.world, args.position, HorizontalAxis::X).await
|
||||
{
|
||||
portal.create(args.world).await;
|
||||
return;
|
||||
}
|
||||
{
|
||||
portal.create(args.world).await;
|
||||
return;
|
||||
}
|
||||
|
||||
args.world
|
||||
|
||||
@@ -61,13 +61,13 @@ impl BlockBehaviour for FurnaceBlock {
|
||||
&self,
|
||||
args: crate::block::NormalUseArgs<'_>,
|
||||
) -> crate::block::registry::BlockActionResult {
|
||||
if let Some(block_entity) = args.world.get_block_entity(args.position).await {
|
||||
if let Some(inventory) = block_entity.clone().get_inventory() {
|
||||
let furnace_screen_factory = FurnaceScreenFactory::new(inventory, block_entity);
|
||||
args.player
|
||||
.open_handled_screen(&furnace_screen_factory)
|
||||
.await;
|
||||
}
|
||||
if let Some(block_entity) = args.world.get_block_entity(args.position).await
|
||||
&& let Some(inventory) = block_entity.clone().get_inventory()
|
||||
{
|
||||
let furnace_screen_factory = FurnaceScreenFactory::new(inventory, block_entity);
|
||||
args.player
|
||||
.open_handled_screen(&furnace_screen_factory)
|
||||
.await;
|
||||
}
|
||||
crate::block::registry::BlockActionResult::Consume
|
||||
}
|
||||
|
||||
@@ -52,12 +52,12 @@ type HopperLikeProperties = pumpkin_data::block_properties::HopperLikeProperties
|
||||
#[async_trait]
|
||||
impl BlockBehaviour for HopperBlock {
|
||||
async fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||
if let Some(block_entity) = args.world.get_block_entity(args.position).await {
|
||||
if let Some(inventory) = block_entity.get_inventory() {
|
||||
args.player
|
||||
.open_handled_screen(&HopperBlockScreenFactory(inventory))
|
||||
.await;
|
||||
}
|
||||
if let Some(block_entity) = args.world.get_block_entity(args.position).await
|
||||
&& let Some(inventory) = block_entity.get_inventory()
|
||||
{
|
||||
args.player
|
||||
.open_handled_screen(&HopperBlockScreenFactory(inventory))
|
||||
.await;
|
||||
}
|
||||
|
||||
BlockActionResult::Success
|
||||
|
||||
@@ -200,13 +200,13 @@ impl BlockBehaviour for PistonBlock {
|
||||
let pos = pos.offset_dir(dir.to_offset(), 2);
|
||||
let (block, state) = world.get_block_and_state(&pos).await;
|
||||
let mut bl2 = false;
|
||||
if block == &Block::MOVING_PISTON {
|
||||
if let Some(entity) = world.get_block_entity(&pos).await {
|
||||
let piston = entity.as_any().downcast_ref::<PistonBlockEntity>().unwrap();
|
||||
if piston.facing == dir && piston.extending {
|
||||
piston.finish(world.clone()).await;
|
||||
bl2 = true;
|
||||
}
|
||||
if block == &Block::MOVING_PISTON
|
||||
&& let Some(entity) = world.get_block_entity(&pos).await
|
||||
{
|
||||
let piston = entity.as_any().downcast_ref::<PistonBlockEntity>().unwrap();
|
||||
if piston.facing == dir && piston.extending {
|
||||
piston.finish(world.clone()).await;
|
||||
bl2 = true;
|
||||
}
|
||||
}
|
||||
if !bl2 {
|
||||
@@ -295,15 +295,15 @@ async fn try_move(world: &Arc<World>, block: &Block, block_pos: &BlockPos) {
|
||||
|
||||
if new_block == &Block::MOVING_PISTON {
|
||||
let new_props = MovingPistonLikeProperties::from_state_id(new_state, new_block);
|
||||
if new_props.facing == props.facing {
|
||||
if let Some(entity) = world.get_block_entity(&new_pos).await {
|
||||
let piston = entity.as_any().downcast_ref::<PistonBlockEntity>().unwrap();
|
||||
if piston.extending && piston.current_progress.load() < 0.5
|
||||
// TODO: more stuff...
|
||||
{
|
||||
// Piston reduced too quickly, if its a stick piston no blocks will be dragged
|
||||
r#type = 2;
|
||||
}
|
||||
if new_props.facing == props.facing
|
||||
&& let Some(entity) = world.get_block_entity(&new_pos).await
|
||||
{
|
||||
let piston = entity.as_any().downcast_ref::<PistonBlockEntity>().unwrap();
|
||||
if piston.extending && piston.current_progress.load() < 0.5
|
||||
// TODO: more stuff...
|
||||
{
|
||||
// Piston reduced too quickly, if its a stick piston no blocks will be dragged
|
||||
r#type = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,18 +107,18 @@ impl BlockBehaviour for SeaPickleBlock {
|
||||
}
|
||||
|
||||
async fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
||||
if args.player.get_entity().pose.load() != EntityPose::Crouching {
|
||||
if let BlockIsReplacing::Itself(state_id) = args.replacing {
|
||||
let mut sea_pickle_prop = SeaPickleProperties::from_state_id(state_id, args.block);
|
||||
if sea_pickle_prop.pickles != Integer1To4::L4 {
|
||||
sea_pickle_prop.pickles = match sea_pickle_prop.pickles {
|
||||
Integer1To4::L1 => Integer1To4::L2,
|
||||
Integer1To4::L2 => Integer1To4::L3,
|
||||
_ => Integer1To4::L4,
|
||||
};
|
||||
}
|
||||
return sea_pickle_prop.to_state_id(args.block);
|
||||
if args.player.get_entity().pose.load() != EntityPose::Crouching
|
||||
&& let BlockIsReplacing::Itself(state_id) = args.replacing
|
||||
{
|
||||
let mut sea_pickle_prop = SeaPickleProperties::from_state_id(state_id, args.block);
|
||||
if sea_pickle_prop.pickles != Integer1To4::L4 {
|
||||
sea_pickle_prop.pickles = match sea_pickle_prop.pickles {
|
||||
Integer1To4::L1 => Integer1To4::L2,
|
||||
Integer1To4::L2 => Integer1To4::L3,
|
||||
_ => Integer1To4::L4,
|
||||
};
|
||||
}
|
||||
return sea_pickle_prop.to_state_id(args.block);
|
||||
}
|
||||
|
||||
let mut sea_pickle_prop = SeaPickleProperties::default(args.block);
|
||||
|
||||
@@ -136,14 +136,14 @@ impl RedstoneGateBlockProperties for ComparatorLikeProperties {
|
||||
#[async_trait]
|
||||
impl RedstoneGateBlock<ComparatorLikeProperties> for ComparatorBlock {
|
||||
async fn get_output_level(&self, world: &World, pos: BlockPos) -> u8 {
|
||||
if let Some(blockentity) = world.get_block_entity(&pos).await {
|
||||
if blockentity.resource_location() == ComparatorBlockEntity::ID {
|
||||
let comparator = blockentity
|
||||
.as_any()
|
||||
.downcast_ref::<ComparatorBlockEntity>()
|
||||
.unwrap();
|
||||
return comparator.output_signal.load(Ordering::Relaxed);
|
||||
}
|
||||
if let Some(blockentity) = world.get_block_entity(&pos).await
|
||||
&& blockentity.resource_location() == ComparatorBlockEntity::ID
|
||||
{
|
||||
let comparator = blockentity
|
||||
.as_any()
|
||||
.downcast_ref::<ComparatorBlockEntity>()
|
||||
.unwrap();
|
||||
return comparator.output_signal.load(Ordering::Relaxed);
|
||||
}
|
||||
0
|
||||
}
|
||||
@@ -219,8 +219,8 @@ impl RedstoneGateBlock<ComparatorLikeProperties> for ComparatorBlock {
|
||||
let source_pos = pos.offset(facing.to_offset());
|
||||
let (source_block, source_state) = world.get_block_and_state(&source_pos).await;
|
||||
|
||||
if let Some(pumpkin_block) = world.block_registry.get_pumpkin_block(source_block) {
|
||||
if let Some(level) = pumpkin_block
|
||||
if let Some(pumpkin_block) = world.block_registry.get_pumpkin_block(source_block)
|
||||
&& let Some(level) = pumpkin_block
|
||||
.get_comparator_output(GetComparatorOutputArgs {
|
||||
world,
|
||||
block: source_block,
|
||||
@@ -228,9 +228,8 @@ impl RedstoneGateBlock<ComparatorLikeProperties> for ComparatorBlock {
|
||||
position: &source_pos,
|
||||
})
|
||||
.await
|
||||
{
|
||||
return level;
|
||||
}
|
||||
{
|
||||
return level;
|
||||
}
|
||||
|
||||
if redstone_level < 15 && source_state.is_solid() {
|
||||
@@ -322,11 +321,11 @@ impl ComparatorBlock {
|
||||
entity.get_entity().entity_type == &EntityType::ITEM_FRAME
|
||||
&& entity.get_entity().get_horizontal_facing() == facing
|
||||
});
|
||||
if let Some(_itemframe) = itemframes.next() {
|
||||
if itemframes.next().is_none() {
|
||||
// TODO itemframe.getComparatorPower()
|
||||
return Some(1);
|
||||
}
|
||||
if let Some(_itemframe) = itemframes.next()
|
||||
&& itemframes.next().is_none()
|
||||
{
|
||||
// TODO itemframe.getComparatorPower()
|
||||
return Some(1);
|
||||
}
|
||||
None
|
||||
}
|
||||
@@ -334,17 +333,17 @@ impl ComparatorBlock {
|
||||
async fn update(&self, world: &Arc<World>, pos: BlockPos, state: &BlockState, block: &Block) {
|
||||
let future_level = i32::from(self.calculate_output_signal(world, pos, state, block).await);
|
||||
let mut now_level = 0;
|
||||
if let Some(blockentity) = world.get_block_entity(&pos).await {
|
||||
if blockentity.resource_location() == ComparatorBlockEntity::ID {
|
||||
let comparator = blockentity
|
||||
.as_any()
|
||||
.downcast_ref::<ComparatorBlockEntity>()
|
||||
.unwrap();
|
||||
now_level = i32::from(comparator.output_signal.load(Ordering::Relaxed));
|
||||
comparator
|
||||
.output_signal
|
||||
.store(future_level as u8, Ordering::Relaxed);
|
||||
}
|
||||
if let Some(blockentity) = world.get_block_entity(&pos).await
|
||||
&& blockentity.resource_location() == ComparatorBlockEntity::ID
|
||||
{
|
||||
let comparator = blockentity
|
||||
.as_any()
|
||||
.downcast_ref::<ComparatorBlockEntity>()
|
||||
.unwrap();
|
||||
now_level = i32::from(comparator.output_signal.load(Ordering::Relaxed));
|
||||
comparator
|
||||
.output_signal
|
||||
.store(future_level as u8, Ordering::Relaxed);
|
||||
}
|
||||
let mut props = ComparatorLikeProperties::from_state_id(state.id, block);
|
||||
if now_level != future_level || props.mode == ComparatorMode::Compare {
|
||||
|
||||
@@ -84,12 +84,12 @@ const fn to_data3d(facing: Facing) -> i32 {
|
||||
#[async_trait]
|
||||
impl BlockBehaviour for DropperBlock {
|
||||
async fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||
if let Some(block_entity) = args.world.get_block_entity(args.position).await {
|
||||
if let Some(inventory) = block_entity.get_inventory() {
|
||||
args.player
|
||||
.open_handled_screen(&DropperScreenFactory(inventory))
|
||||
.await;
|
||||
}
|
||||
if let Some(block_entity) = args.world.get_block_entity(args.position).await
|
||||
&& let Some(inventory) = block_entity.get_inventory()
|
||||
{
|
||||
args.player
|
||||
.open_handled_screen(&DropperScreenFactory(inventory))
|
||||
.await;
|
||||
}
|
||||
BlockActionResult::Success
|
||||
}
|
||||
@@ -157,32 +157,30 @@ impl BlockBehaviour for DropperBlock {
|
||||
.offset(props.facing.to_block_direction().to_offset()),
|
||||
)
|
||||
.await
|
||||
&& let Some(container) = entity.get_inventory()
|
||||
{
|
||||
if let Some(container) = entity.get_inventory() {
|
||||
// TODO check WorldlyContainer
|
||||
let mut is_full = true;
|
||||
for i in 0..container.size() {
|
||||
let bind = container.get_stack(i).await;
|
||||
let item = bind.lock().await;
|
||||
if item.item_count < item.get_max_stack_size() {
|
||||
is_full = false;
|
||||
break;
|
||||
}
|
||||
// TODO check WorldlyContainer
|
||||
let mut is_full = true;
|
||||
for i in 0..container.size() {
|
||||
let bind = container.get_stack(i).await;
|
||||
let item = bind.lock().await;
|
||||
if item.item_count < item.get_max_stack_size() {
|
||||
is_full = false;
|
||||
break;
|
||||
}
|
||||
if is_full {
|
||||
return;
|
||||
}
|
||||
//TODO WorldlyContainer
|
||||
let backup = item.clone();
|
||||
let one_item = item.split(1);
|
||||
if HopperBlockEntity::add_one_item(dropper, container.as_ref(), one_item)
|
||||
.await
|
||||
{
|
||||
return;
|
||||
}
|
||||
*item = backup;
|
||||
}
|
||||
if is_full {
|
||||
return;
|
||||
}
|
||||
//TODO WorldlyContainer
|
||||
let backup = item.clone();
|
||||
let one_item = item.split(1);
|
||||
if HopperBlockEntity::add_one_item(dropper, container.as_ref(), one_item).await
|
||||
{
|
||||
return;
|
||||
}
|
||||
*item = backup;
|
||||
return;
|
||||
}
|
||||
let drop_item = item.split(1);
|
||||
let facing = to_normal(props.facing);
|
||||
|
||||
@@ -29,10 +29,10 @@ pub(super) async fn rail_placement_is_valid(world: &World, block: &Block, pos: &
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(direction) = rail_leaning_direction {
|
||||
if !can_place_rail_at(world, &pos.offset(direction.to_offset()).up()).await {
|
||||
return false;
|
||||
}
|
||||
if let Some(direction) = rail_leaning_direction
|
||||
&& !can_place_rail_at(world, &pos.offset(direction.to_offset()).up()).await
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
|
||||
@@ -108,28 +108,24 @@ async fn compute_stair_shape(
|
||||
|
||||
if let Some(other_stair_props) =
|
||||
get_stair_properties_if_exists(world, &block_pos.offset(facing.to_offset())).await
|
||||
&& other_stair_props.half == half
|
||||
{
|
||||
if other_stair_props.half == half {
|
||||
if !left_locked && other_stair_props.facing == facing.rotate_clockwise() {
|
||||
return StairShape::OuterRight;
|
||||
} else if !right_locked && other_stair_props.facing == facing.rotate_counter_clockwise()
|
||||
{
|
||||
return StairShape::OuterLeft;
|
||||
}
|
||||
if !left_locked && other_stair_props.facing == facing.rotate_clockwise() {
|
||||
return StairShape::OuterRight;
|
||||
} else if !right_locked && other_stair_props.facing == facing.rotate_counter_clockwise() {
|
||||
return StairShape::OuterLeft;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(other_stair_props) =
|
||||
get_stair_properties_if_exists(world, &block_pos.offset(facing.opposite().to_offset()))
|
||||
.await
|
||||
&& other_stair_props.half == half
|
||||
{
|
||||
if other_stair_props.half == half {
|
||||
if !right_locked && other_stair_props.facing == facing.rotate_clockwise() {
|
||||
return StairShape::InnerRight;
|
||||
} else if !left_locked && other_stair_props.facing == facing.rotate_counter_clockwise()
|
||||
{
|
||||
return StairShape::InnerLeft;
|
||||
}
|
||||
if !right_locked && other_stair_props.facing == facing.rotate_clockwise() {
|
||||
return StairShape::InnerRight;
|
||||
} else if !left_locked && other_stair_props.facing == facing.rotate_counter_clockwise() {
|
||||
return StairShape::InnerLeft;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -91,14 +91,13 @@ pub trait FlowingFluid {
|
||||
|
||||
let state_id = world.get_block_state_id(pos).await;
|
||||
// Check if the block has waterlogged property and if it's true
|
||||
if let Some(properties) = block.properties(state_id) {
|
||||
if properties
|
||||
if let Some(properties) = block.properties(state_id)
|
||||
&& properties
|
||||
.to_props()
|
||||
.iter()
|
||||
.any(|(key, value)| key == "waterlogged" && value == "true")
|
||||
{
|
||||
return Some(state_id);
|
||||
}
|
||||
{
|
||||
return Some(state_id);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
@@ -313,14 +313,12 @@ pub async fn drop_loot(
|
||||
}
|
||||
}
|
||||
|
||||
if experience {
|
||||
if let Some(experience) = &block.experience {
|
||||
let mut random = RandomGenerator::Xoroshiro(Xoroshiro::from_seed(get_seed()));
|
||||
let amount = experience.experience.get(&mut random);
|
||||
// TODO: Silk touch gives no exp
|
||||
if amount > 0 {
|
||||
ExperienceOrbEntity::spawn(world, pos.to_f64(), amount as u32).await;
|
||||
}
|
||||
if experience && let Some(experience) = &block.experience {
|
||||
let mut random = RandomGenerator::Xoroshiro(Xoroshiro::from_seed(get_seed()));
|
||||
let amount = experience.experience.get(&mut random);
|
||||
// TODO: Silk touch gives no exp
|
||||
if amount > 0 {
|
||||
ExperienceOrbEntity::spawn(world, pos.to_f64(), amount as u32).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ use super::{
|
||||
pub struct BlockArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for BlockArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::BlockState
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ pub enum BlockPredicate {
|
||||
}
|
||||
|
||||
impl GetClientSideArgParser for BlockPredicateArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::BlockPredicate
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, Sugg
|
||||
pub struct BoolArgConsumer;
|
||||
|
||||
impl GetClientSideArgParser for BoolArgConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::Bool
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, Sugg
|
||||
pub struct BossbarColorArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for BossbarColorArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
// Not sure if this is right...
|
||||
ArgumentType::ResourceLocation
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, Sugg
|
||||
pub struct BossbarStyleArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for BossbarStyleArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
// Not sure if this is right...
|
||||
ArgumentType::ResourceLocation
|
||||
}
|
||||
|
||||
@@ -34,22 +34,22 @@ where
|
||||
) -> Option<Arg<'a>> {
|
||||
let x = args.pop()?.parse::<T>().ok()?;
|
||||
|
||||
if let Some(max) = self.max_inclusive {
|
||||
if x > max {
|
||||
return Some(Arg::Num(Err(NotInBounds::UpperBound(
|
||||
x.to_number(),
|
||||
max.to_number(),
|
||||
))));
|
||||
}
|
||||
if let Some(max) = self.max_inclusive
|
||||
&& x > max
|
||||
{
|
||||
return Some(Arg::Num(Err(NotInBounds::UpperBound(
|
||||
x.to_number(),
|
||||
max.to_number(),
|
||||
))));
|
||||
}
|
||||
|
||||
if let Some(min) = self.min_inclusive {
|
||||
if x < min {
|
||||
return Some(Arg::Num(Err(NotInBounds::LowerBound(
|
||||
x.to_number(),
|
||||
min.to_number(),
|
||||
))));
|
||||
}
|
||||
if let Some(min) = self.min_inclusive
|
||||
&& x < min
|
||||
{
|
||||
return Some(Arg::Num(Err(NotInBounds::LowerBound(
|
||||
x.to_number(),
|
||||
min.to_number(),
|
||||
))));
|
||||
}
|
||||
|
||||
Some(Arg::Num(Ok(x.to_number())))
|
||||
@@ -198,7 +198,7 @@ impl ToFromNumber for f64 {
|
||||
}
|
||||
|
||||
impl GetClientSideArgParser for BoundedNumArgumentConsumer<f64> {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::Double {
|
||||
min: self.min_inclusive,
|
||||
max: self.max_inclusive,
|
||||
@@ -226,7 +226,7 @@ impl ToFromNumber for f32 {
|
||||
}
|
||||
|
||||
impl GetClientSideArgParser for BoundedNumArgumentConsumer<f32> {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::Float {
|
||||
min: self.min_inclusive,
|
||||
max: self.max_inclusive,
|
||||
@@ -254,7 +254,7 @@ impl ToFromNumber for i32 {
|
||||
}
|
||||
|
||||
impl GetClientSideArgParser for BoundedNumArgumentConsumer<i32> {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::Integer {
|
||||
min: self.min_inclusive,
|
||||
max: self.max_inclusive,
|
||||
@@ -282,7 +282,7 @@ impl ToFromNumber for i64 {
|
||||
}
|
||||
|
||||
impl GetClientSideArgParser for BoundedNumArgumentConsumer<i64> {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::Long {
|
||||
min: self.min_inclusive,
|
||||
max: self.max_inclusive,
|
||||
|
||||
@@ -18,7 +18,7 @@ use super::{Arg, ArgumentConsumer, DefaultNameArgConsumer, FindArg, GetClientSid
|
||||
pub struct CommandTreeArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for CommandTreeArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::String(StringProtoArgBehavior::SingleWord)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ use super::{Arg, ArgumentConsumer, DefaultNameArgConsumer, FindArg, GetClientSid
|
||||
pub struct DifficultyArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for DifficultyArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::String(
|
||||
pumpkin_protocol::java::client::play::StringProtoArgBehavior::SingleWord,
|
||||
)
|
||||
|
||||
@@ -227,9 +227,9 @@ impl FromStr for TargetSelector {
|
||||
}
|
||||
Ok(selector)
|
||||
} else if let Ok(uuid) = Uuid::parse_str(arg) {
|
||||
return Ok(Self::new(EntitySelectorType::Uuid(uuid)));
|
||||
Ok(Self::new(EntitySelectorType::Uuid(uuid)))
|
||||
} else {
|
||||
return Ok(Self::new(EntitySelectorType::NamedPlayer(arg.to_string())));
|
||||
Ok(Self::new(EntitySelectorType::NamedPlayer(arg.to_string())))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -240,7 +240,7 @@ impl FromStr for TargetSelector {
|
||||
pub struct EntitiesArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for EntitiesArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
// todo: investigate why this does not accept target selectors
|
||||
ArgumentType::Entity { flags: 0 }
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ use super::{Arg, DefaultNameArgConsumer, FindArg, GetClientSideArgParser};
|
||||
pub struct EntityArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for EntityArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
// todo: investigate why this does not accept target selectors
|
||||
ArgumentType::Entity {
|
||||
flags: ArgumentType::ENTITY_FLAG_ONLY_SINGLE,
|
||||
|
||||
@@ -14,7 +14,7 @@ use super::{Arg, ArgumentConsumer, DefaultNameArgConsumer, FindArg, GetClientSid
|
||||
pub struct GamemodeArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for GamemodeArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::Gamemode
|
||||
}
|
||||
|
||||
@@ -33,10 +33,10 @@ impl ArgumentConsumer for GamemodeArgumentConsumer {
|
||||
) -> Option<Arg<'a>> {
|
||||
let s = args.pop()?;
|
||||
|
||||
if let Ok(id) = s.parse::<i8>() {
|
||||
if let Ok(gamemode) = GameMode::try_from(id) {
|
||||
return Some(Arg::GameMode(gamemode));
|
||||
}
|
||||
if let Ok(id) = s.parse::<i8>()
|
||||
&& let Ok(gamemode) = GameMode::try_from(id)
|
||||
{
|
||||
return Some(Arg::GameMode(gamemode));
|
||||
}
|
||||
|
||||
GameMode::from_str(s).map_or_else(|_| None, |gamemode| Some(Arg::GameMode(gamemode)))
|
||||
|
||||
@@ -17,7 +17,7 @@ use super::{
|
||||
pub struct MsgArgConsumer;
|
||||
|
||||
impl GetClientSideArgParser for MsgArgConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::String(StringProtoArgBehavior::GreedyPhrase)
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ pub trait ArgumentConsumer: Sync + GetClientSideArgParser {
|
||||
|
||||
pub trait GetClientSideArgParser {
|
||||
/// Return the parser the client should use while typing a command in chat.
|
||||
fn get_client_side_parser(&self) -> ArgumentType;
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_>;
|
||||
/// Usually this should return None. This can be used to force suggestions to be processed on serverside.
|
||||
fn get_client_side_suggestion_type_override(&self) -> Option<SuggestionProviders>;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ use super::{Arg, DefaultNameArgConsumer, FindArg, GetClientSideArgParser};
|
||||
pub struct PlayersArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for PlayersArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
// todo: investigate why this does not accept target selectors
|
||||
ArgumentType::Entity {
|
||||
flags: ArgumentType::ENTITY_FLAG_PLAYERS_ONLY,
|
||||
|
||||
@@ -18,7 +18,7 @@ use super::{Arg, DefaultNameArgConsumer, FindArg, GetClientSideArgParser};
|
||||
pub struct Position2DArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for Position2DArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::Vec2
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ use super::{Arg, DefaultNameArgConsumer, FindArg, GetClientSideArgParser};
|
||||
pub struct Position3DArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for Position3DArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::Vec3
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ use super::{Arg, DefaultNameArgConsumer, FindArg, GetClientSideArgParser};
|
||||
pub struct BlockPosArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for BlockPosArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::BlockPos
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ use crate::server::Server;
|
||||
pub struct DamageTypeArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for DamageTypeArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::Resource {
|
||||
identifier: "damage_type",
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ use crate::server::Server;
|
||||
pub struct EffectTypeArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for EffectTypeArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::Resource {
|
||||
identifier: "mob_effect",
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ use crate::server::Server;
|
||||
pub struct EnchantmentArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for EnchantmentArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::Resource {
|
||||
identifier: "enchantment",
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ use crate::server::Server;
|
||||
pub struct ItemArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for ItemArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::Resource { identifier: "item" }
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ use crate::server::Server;
|
||||
pub struct ParticleArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for ParticleArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::Resource {
|
||||
identifier: "particle_type",
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ pub struct ResourceLocationArgumentConsumer {
|
||||
}
|
||||
|
||||
impl GetClientSideArgParser for ResourceLocationArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::ResourceLocation
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ use super::{Arg, DefaultNameArgConsumer, FindArg, GetClientSideArgParser};
|
||||
pub struct RotationArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for RotationArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::Rotation
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ use super::{
|
||||
pub struct SimpleArgConsumer;
|
||||
|
||||
impl GetClientSideArgParser for SimpleArgConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::String(StringProtoArgBehavior::SingleWord)
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ use super::{
|
||||
pub struct SoundArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for SoundArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::ResourceLocation
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, Sugg
|
||||
pub struct SoundCategoryArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for SoundCategoryArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
// ResourceLocation is used for enumerated string values
|
||||
ArgumentType::ResourceLocation
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ use super::{
|
||||
pub struct SummonableEntitiesArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for SummonableEntitiesArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::ResourceLocation
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ use pumpkin_util::text::TextComponent;
|
||||
pub struct TextComponentArgConsumer;
|
||||
|
||||
impl GetClientSideArgParser for TextComponentArgConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::Component
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::server::Server;
|
||||
pub struct TimeArgumentConsumer;
|
||||
|
||||
impl GetClientSideArgParser for TimeArgumentConsumer {
|
||||
fn get_client_side_parser(&self) -> ArgumentType {
|
||||
fn get_client_side_parser(&self) -> ArgumentType<'_> {
|
||||
ArgumentType::Time { min: 0 }
|
||||
}
|
||||
|
||||
|
||||
@@ -86,10 +86,10 @@ impl CommandExecutor for Executor {
|
||||
for y in start_y..=end_y {
|
||||
for z in start_z..=end_z {
|
||||
let block_position = BlockPos(Vector3::new(x, y, z));
|
||||
if let Some(filter) = &option_filter {
|
||||
if not_in_filter(filter, world.get_block(&block_position).await) {
|
||||
continue;
|
||||
}
|
||||
if let Some(filter) = &option_filter
|
||||
&& not_in_filter(filter, world.get_block(&block_position).await)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
world
|
||||
.break_block(
|
||||
@@ -116,10 +116,10 @@ impl CommandExecutor for Executor {
|
||||
for y in start_y..=end_y {
|
||||
for z in start_z..=end_z {
|
||||
let block_position = BlockPos(Vector3::new(x, y, z));
|
||||
if let Some(filter) = &option_filter {
|
||||
if not_in_filter(filter, world.get_block(&block_position).await) {
|
||||
continue;
|
||||
}
|
||||
if let Some(filter) = &option_filter
|
||||
&& not_in_filter(filter, world.get_block(&block_position).await)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
world
|
||||
.set_block_state(
|
||||
@@ -141,11 +141,10 @@ impl CommandExecutor for Executor {
|
||||
let block_position = BlockPos(Vector3::new(x, y, z));
|
||||
let old_state = world.get_block_state(&block_position).await;
|
||||
if old_state.is_air() {
|
||||
if let Some(filter) = &option_filter {
|
||||
if not_in_filter(filter, world.get_block(&block_position).await)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if let Some(filter) = &option_filter
|
||||
&& not_in_filter(filter, world.get_block(&block_position).await)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
world
|
||||
.set_block_state(
|
||||
@@ -172,10 +171,10 @@ impl CommandExecutor for Executor {
|
||||
|| y == end_y
|
||||
|| z == start_z
|
||||
|| z == end_z;
|
||||
if let Some(filter) = &option_filter {
|
||||
if not_in_filter(filter, world.get_block(&block_position).await) {
|
||||
continue;
|
||||
}
|
||||
if let Some(filter) = &option_filter
|
||||
&& not_in_filter(filter, world.get_block(&block_position).await)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if is_edge {
|
||||
world
|
||||
@@ -210,10 +209,10 @@ impl CommandExecutor for Executor {
|
||||
if !is_edge {
|
||||
continue;
|
||||
}
|
||||
if let Some(filter) = &option_filter {
|
||||
if not_in_filter(filter, world.get_block(&block_position).await) {
|
||||
continue;
|
||||
}
|
||||
if let Some(filter) = &option_filter
|
||||
&& not_in_filter(filter, world.get_block(&block_position).await)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
world
|
||||
.set_block_state(
|
||||
@@ -233,10 +232,10 @@ impl CommandExecutor for Executor {
|
||||
for y in start_y..=end_y {
|
||||
for z in start_z..=end_z {
|
||||
let block_position = BlockPos(Vector3::new(x, y, z));
|
||||
if let Some(filter) = &option_filter {
|
||||
if not_in_filter(filter, world.get_block(&block_position).await) {
|
||||
continue;
|
||||
}
|
||||
if let Some(filter) = &option_filter
|
||||
&& not_in_filter(filter, world.get_block(&block_position).await)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
world
|
||||
.set_block_state(
|
||||
|
||||
@@ -428,10 +428,10 @@ impl CommandDispatcher {
|
||||
for (key, value) in &self.commands {
|
||||
if key == name {
|
||||
to_remove.push(key.clone());
|
||||
} else if let Command::Alias(target) = value {
|
||||
if target == name {
|
||||
to_remove.push(key.clone());
|
||||
}
|
||||
} else if let Command::Alias(target) = value
|
||||
&& target == name
|
||||
{
|
||||
to_remove.push(key.clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -141,12 +141,12 @@ impl Goal for LookAtEntityGoal {
|
||||
|
||||
async fn tick(&self, mob: &dyn Mob) {
|
||||
let mob = mob.get_mob_entity();
|
||||
if let Some(target) = self.target.lock().await.as_ref() {
|
||||
if target.get_entity().is_alive() {
|
||||
let target_pos = target.get_entity().pos.load();
|
||||
mob.living_entity.entity.look_at(target_pos).await;
|
||||
self.look_time.fetch_sub(1, Relaxed);
|
||||
}
|
||||
if let Some(target) = self.target.lock().await.as_ref()
|
||||
&& target.get_entity().is_alive()
|
||||
{
|
||||
let target_pos = target.get_entity().pos.load();
|
||||
mob.living_entity.entity.look_at(target_pos).await;
|
||||
self.look_time.fetch_sub(1, Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -702,12 +702,14 @@ impl LivingEntity {
|
||||
) -> TextComponent {
|
||||
match damage_type.death_message_type {
|
||||
DeathMessageType::Default => {
|
||||
if cause.is_some() && source.is_some() {
|
||||
if let Some(cause) = cause
|
||||
&& source.is_some()
|
||||
{
|
||||
TextComponent::translate(
|
||||
format!("death.attack.{}.player", damage_type.message_id),
|
||||
[
|
||||
dyn_self.get_display_name().await,
|
||||
cause.unwrap().get_display_name().await,
|
||||
cause.get_display_name().await,
|
||||
],
|
||||
)
|
||||
} else {
|
||||
|
||||
@@ -990,13 +990,11 @@ impl Entity {
|
||||
|
||||
let in_lava = in_fluid[1];
|
||||
|
||||
if in_lava {
|
||||
if let Some(living) = caller.get_living_entity() {
|
||||
let halved_fall = living.fall_distance.load() / 2.0;
|
||||
if in_lava && let Some(living) = caller.get_living_entity() {
|
||||
let halved_fall = living.fall_distance.load() / 2.0;
|
||||
|
||||
if halved_fall != 0.0 {
|
||||
living.fall_distance.store(halved_fall);
|
||||
}
|
||||
if halved_fall != 0.0 {
|
||||
living.fall_distance.store(halved_fall);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -541,10 +541,11 @@ impl Player {
|
||||
block_pos: BlockPos,
|
||||
yaw: f32,
|
||||
) -> bool {
|
||||
if let Some(respawn_point) = self.respawn_point.load() {
|
||||
if dimension == respawn_point.dimension && block_pos == respawn_point.position {
|
||||
return false;
|
||||
}
|
||||
if let Some(respawn_point) = self.respawn_point.load()
|
||||
&& dimension == respawn_point.dimension
|
||||
&& block_pos == respawn_point.position
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
self.respawn_point.store(Some(RespawnPoint {
|
||||
@@ -802,10 +803,10 @@ impl Player {
|
||||
}
|
||||
|
||||
self.tick_counter.fetch_add(1, Ordering::Relaxed);
|
||||
if let Some(sleeping_since) = self.sleeping_since.load() {
|
||||
if sleeping_since < 101 {
|
||||
self.sleeping_since.store(Some(sleeping_since + 1));
|
||||
}
|
||||
if let Some(sleeping_since) = self.sleeping_since.load()
|
||||
&& sleeping_since < 101
|
||||
{
|
||||
self.sleeping_since.store(Some(sleeping_since + 1));
|
||||
}
|
||||
|
||||
if self.mining.load(Ordering::Relaxed) {
|
||||
@@ -2006,46 +2007,46 @@ impl NBTStorage for PlayerInventory {
|
||||
// Process inventory list
|
||||
if let Some(inventory_list) = nbt.get_list("Inventory") {
|
||||
for tag in inventory_list {
|
||||
if let Some(item_compound) = tag.extract_compound() {
|
||||
if let Some(slot_byte) = item_compound.get_byte("Slot") {
|
||||
let slot = slot_byte as usize;
|
||||
if let Some(item_stack) = ItemStack::read_item_stack(item_compound) {
|
||||
self.set_stack(slot, item_stack).await;
|
||||
}
|
||||
if let Some(item_compound) = tag.extract_compound()
|
||||
&& let Some(slot_byte) = item_compound.get_byte("Slot")
|
||||
{
|
||||
let slot = slot_byte as usize;
|
||||
if let Some(item_stack) = ItemStack::read_item_stack(item_compound) {
|
||||
self.set_stack(slot, item_stack).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(equipment) = nbt.get_compound("equipment") {
|
||||
if let Some(offhand) = equipment.get_compound("offhand") {
|
||||
if let Some(item_stack) = ItemStack::read_item_stack(offhand) {
|
||||
self.set_stack(40, item_stack).await;
|
||||
}
|
||||
if let Some(offhand) = equipment.get_compound("offhand")
|
||||
&& let Some(item_stack) = ItemStack::read_item_stack(offhand)
|
||||
{
|
||||
self.set_stack(40, item_stack).await;
|
||||
}
|
||||
|
||||
if let Some(head) = equipment.get_compound("head") {
|
||||
if let Some(item_stack) = ItemStack::read_item_stack(head) {
|
||||
self.set_stack(39, item_stack).await;
|
||||
}
|
||||
if let Some(head) = equipment.get_compound("head")
|
||||
&& let Some(item_stack) = ItemStack::read_item_stack(head)
|
||||
{
|
||||
self.set_stack(39, item_stack).await;
|
||||
}
|
||||
|
||||
if let Some(chest) = equipment.get_compound("chest") {
|
||||
if let Some(item_stack) = ItemStack::read_item_stack(chest) {
|
||||
self.set_stack(38, item_stack).await;
|
||||
}
|
||||
if let Some(chest) = equipment.get_compound("chest")
|
||||
&& let Some(item_stack) = ItemStack::read_item_stack(chest)
|
||||
{
|
||||
self.set_stack(38, item_stack).await;
|
||||
}
|
||||
|
||||
if let Some(legs) = equipment.get_compound("legs") {
|
||||
if let Some(item_stack) = ItemStack::read_item_stack(legs) {
|
||||
self.set_stack(37, item_stack).await;
|
||||
}
|
||||
if let Some(legs) = equipment.get_compound("legs")
|
||||
&& let Some(item_stack) = ItemStack::read_item_stack(legs)
|
||||
{
|
||||
self.set_stack(37, item_stack).await;
|
||||
}
|
||||
|
||||
if let Some(feet) = equipment.get_compound("feet") {
|
||||
if let Some(item_stack) = ItemStack::read_item_stack(feet) {
|
||||
self.set_stack(36, item_stack).await;
|
||||
}
|
||||
if let Some(feet) = equipment.get_compound("feet")
|
||||
&& let Some(item_stack) = ItemStack::read_item_stack(feet)
|
||||
{
|
||||
self.set_stack(36, item_stack).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ use crate::world::World;
|
||||
|
||||
pub struct EmptyBucketItem;
|
||||
pub struct FilledBucketItem;
|
||||
pub struct MilkBucketItem;
|
||||
|
||||
impl ItemMetadata for EmptyBucketItem {
|
||||
fn ids() -> Box<[u16]> {
|
||||
@@ -47,11 +46,11 @@ impl ItemMetadata for FilledBucketItem {
|
||||
}
|
||||
}
|
||||
|
||||
impl ItemMetadata for MilkBucketItem {
|
||||
fn ids() -> Box<[u16]> {
|
||||
[Item::MILK_BUCKET.id].into()
|
||||
}
|
||||
}
|
||||
// impl ItemMetadata for MilkBucketItem {
|
||||
// fn ids() -> Box<[u16]> {
|
||||
// [Item::MILK_BUCKET.id].into()
|
||||
// }
|
||||
// }
|
||||
|
||||
fn get_start_and_end_pos(player: &Player) -> (Vector3<f64>, Vector3<f64>) {
|
||||
let start_pos = player.eye_position();
|
||||
|
||||
@@ -35,11 +35,11 @@ impl ItemBehaviour for HoneyCombItem {
|
||||
// First we try to strip the block. by getting his equivalent and applying it the axis.
|
||||
let replacement_block = get_waxed_equivalent(block);
|
||||
// If there is a strip equivalent.
|
||||
if replacement_block.is_some() {
|
||||
if let Some(replacement_block) = replacement_block {
|
||||
// get block state of the old log.
|
||||
// get the log properties
|
||||
// create new properties for the new log.
|
||||
let new_block = &Block::from_id(replacement_block.unwrap());
|
||||
let new_block = &Block::from_id(replacement_block);
|
||||
|
||||
let new_state_id = if block.is_tagged_with_by_tag(&tag::Block::MINECRAFT_DOORS)
|
||||
&& block.is_tagged_with_by_tag(&tag::Block::MINECRAFT_DOORS)
|
||||
|
||||
@@ -175,18 +175,18 @@ impl PumpkinServer {
|
||||
|
||||
let mut ticker = Ticker::new();
|
||||
|
||||
if advanced_config().commands.use_console {
|
||||
if let Some((wrapper, _)) = &*LOGGER_IMPL {
|
||||
if let Some(rl) = wrapper.take_readline() {
|
||||
setup_console(rl, server.clone());
|
||||
} else {
|
||||
if advanced_config().commands.use_tty {
|
||||
log::warn!(
|
||||
"The input is not a TTY; falling back to simple logger and ignoring `use_tty` setting"
|
||||
);
|
||||
}
|
||||
setup_stdin_console(server.clone()).await;
|
||||
if advanced_config().commands.use_console
|
||||
&& let Some((wrapper, _)) = &*LOGGER_IMPL
|
||||
{
|
||||
if let Some(rl) = wrapper.take_readline() {
|
||||
setup_console(rl, server.clone());
|
||||
} else {
|
||||
if advanced_config().commands.use_tty {
|
||||
log::warn!(
|
||||
"The input is not a TTY; falling back to simple logger and ignoring `use_tty` setting"
|
||||
);
|
||||
}
|
||||
setup_stdin_console(server.clone()).await;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,10 +311,10 @@ impl PumpkinServer {
|
||||
log::info!("Completed save!");
|
||||
|
||||
// Explicitly drop the line reader to return the terminal to the original state.
|
||||
if let Some((wrapper, _)) = &*LOGGER_IMPL {
|
||||
if let Some(rl) = wrapper.take_readline() {
|
||||
let _ = rl;
|
||||
}
|
||||
if let Some((wrapper, _)) = &*LOGGER_IMPL
|
||||
&& let Some(rl) = wrapper.take_readline()
|
||||
{
|
||||
let _ = rl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -213,19 +213,19 @@ impl ReadlineLogWrapper {
|
||||
impl Log for ReadlineLogWrapper {
|
||||
fn log(&self, record: &log::Record) {
|
||||
self.internal.log(record);
|
||||
if let Ok(mut lock) = self.readline.lock() {
|
||||
if let Some(rl) = lock.as_mut() {
|
||||
let _ = rl.flush();
|
||||
}
|
||||
if let Ok(mut lock) = self.readline.lock()
|
||||
&& let Some(rl) = lock.as_mut()
|
||||
{
|
||||
let _ = rl.flush();
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&self) {
|
||||
self.internal.flush();
|
||||
if let Ok(mut lock) = self.readline.lock() {
|
||||
if let Some(rl) = lock.as_mut() {
|
||||
let _ = rl.flush();
|
||||
}
|
||||
if let Ok(mut lock) = self.readline.lock()
|
||||
&& let Some(rl) = lock.as_mut()
|
||||
{
|
||||
let _ = rl.flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ impl BedrockClient {
|
||||
&CConnectionRequestAccepted::new(
|
||||
self.address,
|
||||
0,
|
||||
[SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 19132)); 10],
|
||||
[SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 19132)); 10],
|
||||
packet.time,
|
||||
UNIX_EPOCH.elapsed().unwrap().as_millis() as u64,
|
||||
),
|
||||
|
||||
@@ -170,13 +170,13 @@ impl BedrockClient {
|
||||
|
||||
pub async fn process_packet(self: &Arc<Self>, server: &Server, packet: Cursor<Vec<u8>>) {
|
||||
let packet = self.get_packet_payload(packet).await;
|
||||
if let Some(packet) = packet {
|
||||
if let Err(error) = self.handle_packet_payload(server, packet).await {
|
||||
let _text = format!("Error while reading incoming packet {error}");
|
||||
log::error!("Failed to read incoming packet with : {error}");
|
||||
self.kick(DisconnectReason::BadPacket, error.to_string())
|
||||
.await;
|
||||
}
|
||||
if let Some(packet) = packet
|
||||
&& let Err(error) = self.handle_packet_payload(server, packet).await
|
||||
{
|
||||
let _text = format!("Error while reading incoming packet {error}");
|
||||
log::error!("Failed to read incoming packet with : {error}");
|
||||
self.kick(DisconnectReason::BadPacket, error.to_string())
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -756,10 +756,10 @@ impl JavaClient {
|
||||
gameprofile.id,
|
||||
err
|
||||
);
|
||||
if err.is_kick() {
|
||||
if let Some(reason) = err.client_kick_reason() {
|
||||
self.kick(TextComponent::text(reason)).await;
|
||||
}
|
||||
if err.is_kick()
|
||||
&& let Some(reason) = err.client_kick_reason()
|
||||
{
|
||||
self.kick(TextComponent::text(reason)).await;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -879,10 +879,10 @@ impl JavaClient {
|
||||
player.gameprofile.id,
|
||||
err
|
||||
);
|
||||
if err.is_kick() {
|
||||
if let Some(reason) = err.client_kick_reason() {
|
||||
self.kick(TextComponent::text(reason)).await;
|
||||
}
|
||||
if err.is_kick()
|
||||
&& let Some(reason) = err.client_kick_reason()
|
||||
{
|
||||
self.kick(TextComponent::text(reason)).await;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -108,75 +108,74 @@ async fn handle_packet(
|
||||
}
|
||||
}
|
||||
PacketType::Status => {
|
||||
if let Ok(packet) = SStatusRequest::decode(&mut raw_packet).await {
|
||||
if clients
|
||||
if let Ok(packet) = SStatusRequest::decode(&mut raw_packet).await
|
||||
&& clients
|
||||
.read()
|
||||
.await
|
||||
.get(&packet.challenge_token)
|
||||
.is_some_and(|token_bound_ip: &SocketAddr| token_bound_ip == &addr)
|
||||
{
|
||||
if packet.is_full_request {
|
||||
// Get 4 players
|
||||
let mut players: Vec<CString> = Vec::new();
|
||||
for world in server.worlds.read().await.iter() {
|
||||
let mut world_players = world
|
||||
.players
|
||||
.read()
|
||||
.await
|
||||
// Although there is no documented limit, we will limit to 4 players
|
||||
.values()
|
||||
.take(4 - players.len())
|
||||
.map(|player| {
|
||||
CString::new(player.gameprofile.name.as_str()).unwrap()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
players.append(&mut world_players); // Append players from this world
|
||||
|
||||
if players.len() >= 4 {
|
||||
break; // Stop if we've collected 4 players
|
||||
}
|
||||
}
|
||||
|
||||
let plugins = PLUGIN_MANAGER
|
||||
.active_plugins()
|
||||
{
|
||||
if packet.is_full_request {
|
||||
// Get 4 players
|
||||
let mut players: Vec<CString> = Vec::new();
|
||||
for world in server.worlds.read().await.iter() {
|
||||
let mut world_players = world
|
||||
.players
|
||||
.read()
|
||||
.await
|
||||
.into_iter()
|
||||
.map(|meta| meta.name.to_string())
|
||||
.reduce(|acc, name| format!("{acc}, {name}"))
|
||||
.unwrap_or_default();
|
||||
// Although there is no documented limit, we will limit to 4 players
|
||||
.values()
|
||||
.take(4 - players.len())
|
||||
.map(|player| {
|
||||
CString::new(player.gameprofile.name.as_str()).unwrap()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let response = CFullStatus {
|
||||
session_id: packet.session_id,
|
||||
hostname: CString::new(BASIC_CONFIG.motd.as_str())?,
|
||||
version: CString::new(CURRENT_MC_VERSION)?,
|
||||
plugins: CString::new(plugins)?,
|
||||
map: CString::new("world")?, // TODO: Get actual world name
|
||||
num_players: server.get_player_count().await,
|
||||
max_players: BASIC_CONFIG.max_players as usize,
|
||||
host_port: bound_addr.port(),
|
||||
host_ip: CString::new(bound_addr.ip().to_string())?,
|
||||
players,
|
||||
};
|
||||
players.append(&mut world_players); // Append players from this world
|
||||
|
||||
let _ = socket
|
||||
.send_to(response.encode().await.as_slice(), addr)
|
||||
.await;
|
||||
} else {
|
||||
let response = CBasicStatus {
|
||||
session_id: packet.session_id,
|
||||
motd: CString::new(BASIC_CONFIG.motd.as_str())?,
|
||||
map: CString::new("world")?,
|
||||
num_players: server.get_player_count().await,
|
||||
max_players: BASIC_CONFIG.max_players as usize,
|
||||
host_port: bound_addr.port(),
|
||||
host_ip: CString::new(bound_addr.ip().to_string())?,
|
||||
};
|
||||
|
||||
let _ = socket
|
||||
.send_to(response.encode().await.as_slice(), addr)
|
||||
.await;
|
||||
if players.len() >= 4 {
|
||||
break; // Stop if we've collected 4 players
|
||||
}
|
||||
}
|
||||
|
||||
let plugins = PLUGIN_MANAGER
|
||||
.active_plugins()
|
||||
.await
|
||||
.into_iter()
|
||||
.map(|meta| meta.name.to_string())
|
||||
.reduce(|acc, name| format!("{acc}, {name}"))
|
||||
.unwrap_or_default();
|
||||
|
||||
let response = CFullStatus {
|
||||
session_id: packet.session_id,
|
||||
hostname: CString::new(BASIC_CONFIG.motd.as_str())?,
|
||||
version: CString::new(CURRENT_MC_VERSION)?,
|
||||
plugins: CString::new(plugins)?,
|
||||
map: CString::new("world")?, // TODO: Get actual world name
|
||||
num_players: server.get_player_count().await,
|
||||
max_players: BASIC_CONFIG.max_players as usize,
|
||||
host_port: bound_addr.port(),
|
||||
host_ip: CString::new(bound_addr.ip().to_string())?,
|
||||
players,
|
||||
};
|
||||
|
||||
let _ = socket
|
||||
.send_to(response.encode().await.as_slice(), addr)
|
||||
.await;
|
||||
} else {
|
||||
let response = CBasicStatus {
|
||||
session_id: packet.session_id,
|
||||
motd: CString::new(BASIC_CONFIG.motd.as_str())?,
|
||||
map: CString::new("world")?,
|
||||
num_players: server.get_player_count().await,
|
||||
max_players: BASIC_CONFIG.max_players as usize,
|
||||
host_port: bound_addr.port(),
|
||||
host_ip: CString::new(bound_addr.ip().to_string())?,
|
||||
};
|
||||
|
||||
let _ = socket
|
||||
.send_to(response.encode().await.as_slice(), addr)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ impl CachedBranding {
|
||||
cached_server_brand,
|
||||
}
|
||||
}
|
||||
pub fn get_branding(&self) -> CPluginMessage {
|
||||
pub fn get_branding(&self) -> CPluginMessage<'_> {
|
||||
CPluginMessage::new("minecraft:brand", &self.cached_server_brand)
|
||||
}
|
||||
const BRAND: &str = "Pumpkin";
|
||||
|
||||
@@ -62,10 +62,10 @@ impl Ticker {
|
||||
Duration::from_nanos(manager.nanoseconds_per_tick() as u64)
|
||||
};
|
||||
|
||||
if let Some(sleep_time) = tick_interval.checked_sub(elapsed) {
|
||||
if !sleep_time.is_zero() {
|
||||
sleep(sleep_time).await;
|
||||
}
|
||||
if let Some(sleep_time) = tick_interval.checked_sub(elapsed)
|
||||
&& !sleep_time.is_zero()
|
||||
{
|
||||
sleep(sleep_time).await;
|
||||
}
|
||||
|
||||
self.last_tick = Instant::now();
|
||||
|
||||
@@ -108,7 +108,7 @@ impl CustomBossbars {
|
||||
&mut self,
|
||||
server: &Server,
|
||||
resource_location: String,
|
||||
) -> Result<(), BossbarUpdateError> {
|
||||
) -> Result<(), BossbarUpdateError<'_>> {
|
||||
let bossbar = self.custom_bossbars.get_cloned(&resource_location);
|
||||
if let Some(bossbar) = bossbar {
|
||||
self.custom_bossbars.remove(&resource_location);
|
||||
@@ -144,7 +144,7 @@ impl CustomBossbars {
|
||||
resource_location: String,
|
||||
max_value: u32,
|
||||
value: u32,
|
||||
) -> Result<(), BossbarUpdateError> {
|
||||
) -> Result<(), BossbarUpdateError<'_>> {
|
||||
let bossbar = self.custom_bossbars.get_mut(&resource_location);
|
||||
if let Some(bossbar) = bossbar {
|
||||
if bossbar.value == value && bossbar.max == max_value {
|
||||
@@ -193,7 +193,7 @@ impl CustomBossbars {
|
||||
server: &Server,
|
||||
resource_location: String,
|
||||
new_visibility: bool,
|
||||
) -> Result<(), BossbarUpdateError> {
|
||||
) -> Result<(), BossbarUpdateError<'_>> {
|
||||
let bossbar = self.custom_bossbars.get_mut(&resource_location);
|
||||
if let Some(bossbar) = bossbar {
|
||||
if bossbar.visible == new_visibility && new_visibility {
|
||||
@@ -232,7 +232,7 @@ impl CustomBossbars {
|
||||
server: &Server,
|
||||
resource_location: &str,
|
||||
new_title: TextComponent,
|
||||
) -> Result<(), BossbarUpdateError> {
|
||||
) -> Result<(), BossbarUpdateError<'_>> {
|
||||
let bossbar = self.custom_bossbars.get_mut(resource_location);
|
||||
if let Some(bossbar) = bossbar {
|
||||
if bossbar.bossbar_data.title == new_title {
|
||||
@@ -271,7 +271,7 @@ impl CustomBossbars {
|
||||
server: &Server,
|
||||
resource_location: String,
|
||||
new_color: BossbarColor,
|
||||
) -> Result<(), BossbarUpdateError> {
|
||||
) -> Result<(), BossbarUpdateError<'_>> {
|
||||
let bossbar = self.custom_bossbars.get_mut(&resource_location);
|
||||
if let Some(bossbar) = bossbar {
|
||||
if bossbar.bossbar_data.color == new_color {
|
||||
@@ -311,7 +311,7 @@ impl CustomBossbars {
|
||||
server: &Server,
|
||||
resource_location: String,
|
||||
new_division: BossbarDivisions,
|
||||
) -> Result<(), BossbarUpdateError> {
|
||||
) -> Result<(), BossbarUpdateError<'_>> {
|
||||
let bossbar = self.custom_bossbars.get_mut(&resource_location);
|
||||
if let Some(bossbar) = bossbar {
|
||||
if bossbar.bossbar_data.division == new_division {
|
||||
@@ -351,7 +351,7 @@ impl CustomBossbars {
|
||||
server: &Server,
|
||||
resource_location: String,
|
||||
new_players: Vec<Uuid>,
|
||||
) -> Result<(), BossbarUpdateError> {
|
||||
) -> Result<(), BossbarUpdateError<'_>> {
|
||||
let bossbar = self.custom_bossbars.get_mut(&resource_location);
|
||||
if let Some(bossbar) = bossbar {
|
||||
// Get the difference between the old and new player list and remove bossbars from old players.
|
||||
|
||||
@@ -53,20 +53,20 @@ trait LootPoolEntryExt {
|
||||
|
||||
impl LootPoolEntryExt for LootPoolEntry {
|
||||
fn get_loot(&self, params: &LootContextParameters) -> Option<Vec<ItemStack>> {
|
||||
if let Some(conditions) = self.conditions {
|
||||
if !conditions.iter().all(|cond| cond.is_fulfilled(params)) {
|
||||
return None;
|
||||
}
|
||||
if let Some(conditions) = self.conditions
|
||||
&& !conditions.iter().all(|cond| cond.is_fulfilled(params))
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut stacks = self.content.get_stacks(params);
|
||||
|
||||
if let Some(functions) = self.functions {
|
||||
for function in functions {
|
||||
if let Some(conditions) = function.conditions {
|
||||
if !conditions.iter().all(|cond| cond.is_fulfilled(params)) {
|
||||
continue;
|
||||
}
|
||||
if let Some(conditions) = function.conditions
|
||||
&& !conditions.iter().all(|cond| cond.is_fulfilled(params))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
match &function.content {
|
||||
|
||||
@@ -3061,10 +3061,10 @@ impl World {
|
||||
let mut block = BlockPos::floored(from.x, from.y, from.z);
|
||||
|
||||
let (collision, direction) = self.ray_outline_check(&block, from, to).await;
|
||||
if let Some(dir) = direction {
|
||||
if collision {
|
||||
return Some((block, dir));
|
||||
}
|
||||
if let Some(dir) = direction
|
||||
&& collision
|
||||
{
|
||||
return Some((block, dir));
|
||||
}
|
||||
|
||||
let difference = to.sub(&from);
|
||||
|
||||
@@ -16,10 +16,10 @@ impl EndPortal {
|
||||
|
||||
pub async fn get_new_portal(world: &Arc<World>, pos: BlockPos) {
|
||||
let mid_pos = Self::get_mid_pos(world, pos);
|
||||
if let Some(mid_pos) = mid_pos.await {
|
||||
if Self::is_valid_portal(world, mid_pos).await {
|
||||
Self::create_portal(world, mid_pos).await;
|
||||
}
|
||||
if let Some(mid_pos) = mid_pos.await
|
||||
&& Self::is_valid_portal(world, mid_pos).await
|
||||
{
|
||||
Self::create_portal(world, mid_pos).await;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,20 +71,22 @@ impl NetherPortal {
|
||||
first_axis: HorizontalAxis,
|
||||
) -> Option<Self> {
|
||||
// We check both axis here X and Z
|
||||
if let Some(portal) = Self::get_on_axis(world, pos, first_axis).await {
|
||||
if portal.is_valid() && portal.found_portal_blocks == 0 {
|
||||
return Some(portal);
|
||||
}
|
||||
if let Some(portal) = Self::get_on_axis(world, pos, first_axis).await
|
||||
&& portal.is_valid()
|
||||
&& portal.found_portal_blocks == 0
|
||||
{
|
||||
return Some(portal);
|
||||
}
|
||||
let next_axis = if first_axis == HorizontalAxis::X {
|
||||
HorizontalAxis::Z
|
||||
} else {
|
||||
HorizontalAxis::X
|
||||
};
|
||||
if let Some(portal) = Self::get_on_axis(world, pos, next_axis).await {
|
||||
if portal.is_valid() && portal.found_portal_blocks == 0 {
|
||||
return Some(portal);
|
||||
}
|
||||
if let Some(portal) = Self::get_on_axis(world, pos, next_axis).await
|
||||
&& portal.is_valid()
|
||||
&& portal.found_portal_blocks == 0
|
||||
{
|
||||
return Some(portal);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user