Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b830c66be7 | |||
| fc50c2ac44 | |||
| f81cee2454 | |||
| 049716a64c | |||
| c7c37c5a95 | |||
| 4dea005c0d | |||
| 074c5c9553 | |||
| f79cc86332 | |||
| e880fdecfa | |||
| dda45b510a | |||
| 6fec3a73ac | |||
| d22d5fdf5a | |||
| fcb90d468e | |||
| 1094716d9d | |||
| 3d57a67913 | |||
| ecc514b340 | |||
| 75baf3dfaf | |||
| 4ed8600511 | |||
| 0160aac4c6 | |||
| cbed24020a |
@@ -16,10 +16,10 @@ jobs:
|
|||||||
environment: default
|
environment: default
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Git Repository
|
- name: Checkout Git Repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Set up JDK
|
- name: Set up JDK
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v5
|
||||||
with:
|
with:
|
||||||
distribution: zulu
|
distribution: zulu
|
||||||
java-version: 21
|
java-version: 21
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
# Lophine
|
# Lophine
|
||||||
|
|
||||||
<h4>Lophine 是一个基于Luminol的分支,具有许多有用的优化和可配置的原版特性,目标是在Folia上实现更多生电的实现</h4>
|
<h4>Lophine 是一个基于Luminol的分支,具有许多有用的优化和可配置的原版特性,目标是在Folia上实现更多生电的内容(请注意,完整生电请使用Fabric)</h4>
|
||||||
|
|
||||||
|

|
||||||
[](LICENSE.md)
|
[](LICENSE.md)
|
||||||
[](https://github.com/LuminolMC/Lophine/issues)
|
[](https://github.com/LuminolMC/Lophine/issues)
|
||||||

|

|
||||||
@@ -17,6 +18,8 @@
|
|||||||
- 支持部分Bukkit插件
|
- 支持部分Bukkit插件
|
||||||
- 可配置的原版特性
|
- 可配置的原版特性
|
||||||
- Tpsbar 支持
|
- Tpsbar 支持
|
||||||
|
- 针对folia bug的一些修复
|
||||||
|
- linear和b_linear(linear的重新实现)存档格式支持
|
||||||
- 对单线程区域性能的优化
|
- 对单线程区域性能的优化
|
||||||
- 更多有用的功能
|
- 更多有用的功能
|
||||||
|
|
||||||
@@ -39,7 +42,7 @@
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
url = "https://repo.menthamc.com/repository/maven-public/"
|
url = "https://repo.menthamc.org/repository/maven-public/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +57,7 @@ dependencies {
|
|||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<id>menthamc</id>
|
<id>menthamc</id>
|
||||||
<url>https://repo.menthamc.com/repository/maven-public/</url>
|
<url>https://repo.menthamc.org/repository/maven-public/</url>
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -3,8 +3,9 @@
|
|||||||
# Lophine
|
# Lophine
|
||||||
|
|
||||||
<h4>Lophine is a Luminol fork with many useful optimizations and configurable vanilla features, aims to provide
|
<h4>Lophine is a Luminol fork with many useful optimizations and configurable vanilla features, aims to provide
|
||||||
more function for survival-usable circuit on folia</h4>
|
more function for survival-usable circuit on folia (Please note that Fabric should be used for complete survival-usable)</h4>
|
||||||
|
|
||||||
|

|
||||||
[](LICENSE.md)
|
[](LICENSE.md)
|
||||||
[](https://github.com/LuminolMC/Lophine/issues)
|
[](https://github.com/LuminolMC/Lophine/issues)
|
||||||

|

|
||||||
@@ -18,6 +19,8 @@ more function for survival-usable circuit on folia</h4>
|
|||||||
- Supported some Bukkit plugin
|
- Supported some Bukkit plugin
|
||||||
- Configurable vanilla features
|
- Configurable vanilla features
|
||||||
- Tpsbar support
|
- Tpsbar support
|
||||||
|
- Useful fixes of bugs of folia
|
||||||
|
- Linear and BufferedLinear(AKA. b_linear)(a reimplementation of linear) region format support
|
||||||
- Useful optimizations to improve the performance of single threaded region
|
- Useful optimizations to improve the performance of single threaded region
|
||||||
- More functions
|
- More functions
|
||||||
|
|
||||||
@@ -40,7 +43,7 @@ For gradle:
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
url = "https://repo.menthamc.com/repository/maven-public/"
|
url = "https://repo.menthamc.org/repository/maven-public/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +58,7 @@ For maven
|
|||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<id>menthamc</id>
|
<id>menthamc</id>
|
||||||
<url>https://repo.menthamc.com/repository/maven-public/</url>
|
<url>https://repo.menthamc.org/repository/maven-public/</url>
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -41,7 +41,7 @@ paperweight {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
|
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
|
||||||
val menthaMavenPublicUrl = "https://repo.menthamc.com/repository/maven-public/";
|
val menthaMavenPublicUrl = "https://repo.menthamc.org/repository/maven-public/";
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
apply(plugin = "java-library")
|
apply(plugin = "java-library")
|
||||||
@@ -88,7 +88,7 @@ subprojects {
|
|||||||
|
|
||||||
extensions.configure<PublishingExtension> {
|
extensions.configure<PublishingExtension> {
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.menthamc.com/repository/maven-snapshots/") {
|
maven("https://repo.menthamc.org/repository/maven-snapshots/") {
|
||||||
name = "MenthaMC"
|
name = "MenthaMC"
|
||||||
credentials(PasswordCredentials::class) {
|
credentials(PasswordCredentials::class) {
|
||||||
username = System.getenv("PRIVATE_MAVEN_REPO_USERNAME")
|
username = System.getenv("PRIVATE_MAVEN_REPO_USERNAME")
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ mcVersion=1.21.8
|
|||||||
release=2
|
release=2
|
||||||
# 0 for skip release, 1 for pre-release, 2 for release
|
# 0 for skip release, 1 for pre-release, 2 for release
|
||||||
|
|
||||||
luminolRef=31b05a36d905ef9ffeacf236af8566935c63d83b
|
luminolRef=122e2025c83d4ff734f9c1923fa902191a400b84
|
||||||
|
|
||||||
org.gradle.configuration-cache=true
|
org.gradle.configuration-cache=true
|
||||||
org.gradle.caching=true
|
org.gradle.caching=true
|
||||||
|
|||||||
@@ -5,23 +5,23 @@ Subject: [PATCH] Rebrand to Lophine
|
|||||||
|
|
||||||
|
|
||||||
diff --git a/src/main/java/me/earthme/luminol/config/ConfigManager.java b/src/main/java/me/earthme/luminol/config/ConfigManager.java
|
diff --git a/src/main/java/me/earthme/luminol/config/ConfigManager.java b/src/main/java/me/earthme/luminol/config/ConfigManager.java
|
||||||
index 0a3fa2756dae0eea9e2c0fa6bbaa425584763036..6c1cb2866c81a1bc861289aedb2c318f910a8498 100644
|
index 4be82092886728b7862b6e8951cf1c8ab917ca55..1b822e9576573c360b997e5cb4fa02278c88b74f 100644
|
||||||
--- a/src/main/java/me/earthme/luminol/config/ConfigManager.java
|
--- a/src/main/java/me/earthme/luminol/config/ConfigManager.java
|
||||||
+++ b/src/main/java/me/earthme/luminol/config/ConfigManager.java
|
+++ b/src/main/java/me/earthme/luminol/config/ConfigManager.java
|
||||||
@@ -19,6 +19,7 @@ public class ConfigManager {
|
@@ -21,6 +21,7 @@ public class ConfigManager {
|
||||||
|
|
||||||
public static void initConfigs() throws IOException {
|
public static void initConfigs() {
|
||||||
configfiles.put("luminol", ConfigsInstance.of(new File("luminol_config"), "luminol", "me.earthme.luminol.config.modules"));
|
configfiles.put("luminol", ConfigsInstance.of(new File("luminol_config"), "luminol", "me.earthme.luminol.config.modules"));
|
||||||
+ configfiles.put("lophine", ConfigsInstance.of(new File("lophine_config"), "lophine", "fun.bm.lophine.config.modules")); // add lophine config to global config
|
+ configfiles.put("lophine", ConfigsInstance.of(new File("lophine_config"), "lophine", "fun.bm.lophine.config.modules")); // add lophine config to global config
|
||||||
preLoad();
|
preLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
|
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
|
||||||
index ded1f0667327a70a923ebda55c41b1c9094d3e37..57ddc0832b919b115b85c81ac30f136e32f1e77e 100644
|
index f164e41975adee8b68dbcb400007681c0b66a4f8..4e76fb3b1274f2fde734089b20458f6561c39700 100644
|
||||||
--- a/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
|
--- a/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
|
||||||
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
|
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
|
||||||
@@ -6,7 +6,7 @@ import me.earthme.luminol.config.flags.ConfigInfo;
|
@@ -8,7 +8,7 @@ import me.earthme.luminol.enums.EnumConfigCategory;
|
||||||
|
@ConfigClassInfo(configAttribution = EnumConfigCategory.MISC, mainName = "server_mod_name")
|
||||||
public class ServerModNameConfig implements IConfigModule {
|
public class ServerModNameConfig implements IConfigModule {
|
||||||
@ConfigInfo(baseName = "name")
|
@ConfigInfo(baseName = "name")
|
||||||
- public static String serverModName = "Luminol";
|
- public static String serverModName = "Luminol";
|
||||||
|
|||||||
@@ -1,18 +1,30 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||||
Date: Mon, 28 Jul 2025 23:02:47 +0800
|
Date: Tue, 26 Aug 2025 22:08:54 +0800
|
||||||
Subject: [PATCH] Transformed Configs
|
Subject: [PATCH] Transformed Configs
|
||||||
|
|
||||||
|
|
||||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/experiment/CommandBlockExecutionConfig.java b/src/main/java/me/earthme/luminol/config/modules/experiment/CommandBlockExecutionConfig.java
|
diff --git a/src/main/java/me/earthme/luminol/config/modules/experiment/CommandConfig.java b/src/main/java/me/earthme/luminol/config/modules/experiment/CommandConfig.java
|
||||||
index 531214d7ab28ece4bf84e82b39d1c9f983f0fb0c..b68fa0427bb975e91e76f73ab4cc089a424937a3 100644
|
index 4e906e8e0ebd57b9f7000e4194280e3e3636e52c..14eefd162c9facd54a53718a7a0b1b0266e1ada8 100644
|
||||||
--- a/src/main/java/me/earthme/luminol/config/modules/experiment/CommandBlockExecutionConfig.java
|
--- a/src/main/java/me/earthme/luminol/config/modules/experiment/CommandConfig.java
|
||||||
+++ b/src/main/java/me/earthme/luminol/config/modules/experiment/CommandBlockExecutionConfig.java
|
+++ b/src/main/java/me/earthme/luminol/config/modules/experiment/CommandConfig.java
|
||||||
@@ -5,6 +5,7 @@ import me.earthme.luminol.config.IConfigModule;
|
@@ -11,6 +11,7 @@ public class CommandConfig implements IConfigModule {
|
||||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
@TransformedConfig(name = "enable", category = {"experiment", "force_the_data_command_to_be_enabled"})
|
||||||
|
@ConfigInfo(baseName = "enable_data_command")
|
||||||
public class CommandBlockExecutionConfig implements IConfigModule {
|
public static boolean data = false;
|
||||||
+ @me.earthme.luminol.config.flags.TransformedConfig(name = "command_block_enabled", category = {"experiment", "command"}, originInstance = "lophine")
|
+ @TransformedConfig(name = "command_block_enabled", category = {"experiment", "command"}, originInstance = "lophine")
|
||||||
@ConfigInfo(baseName = "enabled")
|
@TransformedConfig(name = "enabled", category = {"experiment", "force_enable_command_block_command_execution"})
|
||||||
public static boolean enabled = false;
|
@ConfigInfo(baseName = "enable_command_block")
|
||||||
|
public static boolean commandBlock = false;
|
||||||
|
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/PaperPacketLimiterConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/PaperPacketLimiterConfig.java
|
||||||
|
index 192a67360db810934d02a15c955af3579e6f6b20..fbafc5a8aa2581301e62e12adb22169ab7fd8e19 100644
|
||||||
|
--- a/src/main/java/me/earthme/luminol/config/modules/optimizations/PaperPacketLimiterConfig.java
|
||||||
|
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/PaperPacketLimiterConfig.java
|
||||||
|
@@ -8,6 +8,7 @@ import me.earthme.luminol.enums.EnumConfigCategory;
|
||||||
|
|
||||||
|
@ConfigClassInfo(configAttribution = EnumConfigCategory.OPTIMIZATIONS, mainName = "force_disable_packet_limiter_of_paper")
|
||||||
|
public class PaperPacketLimiterConfig implements IConfigModule {
|
||||||
|
+ @TransformedConfig(name = "unlimit-packet", category = {"misc", "network"}, originInstance = "lophine")
|
||||||
|
@TransformedConfig(name = "force_disable", category = {"misc", "force_disable_packet_limiter_of_paper"})
|
||||||
|
@ConfigInfo(baseName = "force_disable")
|
||||||
|
public static boolean forceDisable = false;
|
||||||
|
|||||||
@@ -0,0 +1,188 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||||
|
Date: Wed, 13 Aug 2025 22:23:46 +0800
|
||||||
|
Subject: [PATCH] Leaves: Item overstack util
|
||||||
|
|
||||||
|
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||||
|
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/d93e9766d3797d130f66179e70a1b374c546fef7/leaves-server/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java)
|
||||||
|
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||||
|
|
||||||
|
diff --git a/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java b/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java
|
||||||
|
index 102de78be0eb82d6898b4104fad1bf5e8366f993..0f8c9d4932c8bbd619f21d4aa28b890e14439b46 100644
|
||||||
|
--- a/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java
|
||||||
|
+++ b/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java
|
||||||
|
@@ -17,12 +17,173 @@
|
||||||
|
|
||||||
|
package org.leavesmc.leaves.util;
|
||||||
|
|
||||||
|
+import fun.bm.lophine.config.modules.function.ContainerExpansionConfig;
|
||||||
|
+import net.minecraft.core.component.DataComponents;
|
||||||
|
+import net.minecraft.nbt.CompoundTag;
|
||||||
|
+import net.minecraft.world.entity.item.ItemEntity;
|
||||||
|
+import net.minecraft.world.item.BlockItem;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
+import net.minecraft.world.item.component.CustomData;
|
||||||
|
+import net.minecraft.world.item.component.ItemContainerContents;
|
||||||
|
+import net.minecraft.world.level.block.ShulkerBoxBlock;
|
||||||
|
+import org.jetbrains.annotations.NotNull;
|
||||||
|
+
|
||||||
|
+import java.util.List;
|
||||||
|
+import java.util.Objects;
|
||||||
|
+import java.util.Optional;
|
||||||
|
|
||||||
|
// Only the used part is retained
|
||||||
|
public class ItemOverstackUtils {
|
||||||
|
+ private static final List<ItemUtil> overstackUtils = List.of(
|
||||||
|
+ new ShulkerBox()
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ public static int getItemStackMaxCount(ItemStack stack) {
|
||||||
|
+ int size;
|
||||||
|
+ for (ItemUtil util : overstackUtils) {
|
||||||
|
+ if ((size = util.getMaxServerStackCount(stack)) != -1) {
|
||||||
|
+ return size;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return stack.getMaxStackSize();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static int getNetworkMaxCount(ItemStack stack) {
|
||||||
|
+ int size;
|
||||||
|
+ for (ItemUtil util : overstackUtils) {
|
||||||
|
+ if ((size = util.getMaxClientStackCount(stack)) != -1) {
|
||||||
|
+ return size;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return stack.getMaxStackSize();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static boolean tryStackItems(ItemEntity self, ItemEntity other) {
|
||||||
|
+ for (ItemUtil util : overstackUtils) {
|
||||||
|
+ if (util.tryStackItems(self, other)) {
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static boolean hasOverstackingItem() {
|
||||||
|
+ return overstackUtils.stream().anyMatch(ItemUtil::isEnabled);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static int getItemStackMaxCountReal(ItemStack stack) {
|
||||||
|
+ CompoundTag nbt = Optional.ofNullable(stack.get(DataComponents.CUSTOM_DATA)).orElse(CustomData.EMPTY).copyTag();
|
||||||
|
+ return nbt.getInt("Leaves.RealStackSize").orElse(stack.getMaxStackSize());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static ItemStack encodeMaxStackSize(ItemStack itemStack) {
|
||||||
|
+ int realMaxStackSize = getItemStackMaxCountReal(itemStack);
|
||||||
|
+ int modifiedMaxStackSize = getNetworkMaxCount(itemStack);
|
||||||
|
+ if (itemStack.getMaxStackSize() != modifiedMaxStackSize) {
|
||||||
|
+ itemStack.set(DataComponents.MAX_STACK_SIZE, modifiedMaxStackSize);
|
||||||
|
+ CompoundTag nbt = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag();
|
||||||
|
+ nbt.putInt("Leaves.RealStackSize", realMaxStackSize);
|
||||||
|
+ itemStack.set(DataComponents.CUSTOM_DATA, CustomData.of(nbt));
|
||||||
|
+ }
|
||||||
|
+ return itemStack;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static ItemStack decodeMaxStackSize(ItemStack itemStack) {
|
||||||
|
+ int realMaxStackSize = getItemStackMaxCountReal(itemStack);
|
||||||
|
+ if (itemStack.getMaxStackSize() != realMaxStackSize) {
|
||||||
|
+ itemStack.set(DataComponents.MAX_STACK_SIZE, realMaxStackSize);
|
||||||
|
+ CompoundTag nbt = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag();
|
||||||
|
+ nbt.remove("Leaves.RealStackSize");
|
||||||
|
+ if (nbt.isEmpty()) {
|
||||||
|
+ itemStack.remove(DataComponents.CUSTOM_DATA);
|
||||||
|
+ } else {
|
||||||
|
+ itemStack.set(DataComponents.CUSTOM_DATA, CustomData.of(nbt));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return itemStack;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
public static float getItemStackSignalStrength(int maxStackSize, ItemStack itemStack) {
|
||||||
|
float result = (float) itemStack.getCount() / Math.min(maxStackSize, itemStack.getMaxStackSize());
|
||||||
|
return Math.clamp(result, 0f, 1f);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ public static boolean isStackable(ItemStack itemStack) {
|
||||||
|
+ return getItemStackMaxCount(itemStack) > 1 && (!itemStack.isDamageableItem() || !itemStack.isDamaged());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ private interface ItemUtil {
|
||||||
|
+ boolean isEnabled();
|
||||||
|
+
|
||||||
|
+ boolean tryStackItems(ItemEntity self, ItemEntity other);
|
||||||
|
+
|
||||||
|
+ // number -> modified count, -1 -> I don't care
|
||||||
|
+ int getMaxServerStackCount(ItemStack stack);
|
||||||
|
+
|
||||||
|
+ // number -> modified count, -1 -> I don't care
|
||||||
|
+ default int getMaxClientStackCount(ItemStack stack) {
|
||||||
|
+ return getMaxServerStackCount(stack);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private static class ShulkerBox implements ItemUtil {
|
||||||
|
+ public static boolean shulkerBoxCheck(@NotNull ItemStack stack1, @NotNull ItemStack stack2) {
|
||||||
|
+ if (ContainerExpansionConfig.nbtShulkerStackable) {
|
||||||
|
+ return Objects.equals(stack1.getComponents(), stack2.getComponents());
|
||||||
|
+ }
|
||||||
|
+ return shulkerBoxNoItem(stack1) && shulkerBoxNoItem(stack2) && Objects.equals(stack1.getComponents(), stack2.getComponents());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static boolean shulkerBoxNoItem(@NotNull ItemStack stack) {
|
||||||
|
+ return stack.getComponents().getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY).stream().findAny().isEmpty();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public boolean isEnabled() {
|
||||||
|
+ return ContainerExpansionConfig.shulkerCount > 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public boolean tryStackItems(ItemEntity self, ItemEntity other) {
|
||||||
|
+ ItemStack selfStack = self.getItem();
|
||||||
|
+ if (!isEnabled() ||
|
||||||
|
+ !(selfStack.getItem() instanceof BlockItem blockItem) ||
|
||||||
|
+ !(blockItem.getBlock() instanceof ShulkerBoxBlock)
|
||||||
|
+ ) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ItemStack otherStack = other.getItem();
|
||||||
|
+ if (selfStack.getItem() == otherStack.getItem()
|
||||||
|
+ && shulkerBoxCheck(selfStack, otherStack)
|
||||||
|
+ && selfStack.getCount() != ContainerExpansionConfig.shulkerCount) {
|
||||||
|
+ int amount = Math.min(otherStack.getCount(), ContainerExpansionConfig.shulkerCount - selfStack.getCount());
|
||||||
|
+
|
||||||
|
+ selfStack.grow(amount);
|
||||||
|
+ self.setItem(selfStack);
|
||||||
|
+
|
||||||
|
+ self.pickupDelay = Math.max(other.pickupDelay, self.pickupDelay);
|
||||||
|
+ self.age = Math.min(other.getAge(), self.age);
|
||||||
|
+
|
||||||
|
+ otherStack.shrink(amount);
|
||||||
|
+ if (otherStack.isEmpty()) {
|
||||||
|
+ other.discard();
|
||||||
|
+ } else {
|
||||||
|
+ other.setItem(otherStack);
|
||||||
|
+ }
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public int getMaxServerStackCount(ItemStack stack) {
|
||||||
|
+ if (isEnabled() && stack.getItem() instanceof BlockItem bi &&
|
||||||
|
+ bi.getBlock() instanceof ShulkerBoxBlock && (ContainerExpansionConfig.nbtShulkerStackable || shulkerBoxNoItem(stack))) {
|
||||||
|
+ return ContainerExpansionConfig.shulkerCount;
|
||||||
|
+ }
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
\ No newline at end of file
|
||||||
+6
-6
@@ -5,7 +5,7 @@ Subject: [PATCH] Add config to allow infinite trade
|
|||||||
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java
|
diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java
|
||||||
index 79242037e868a140513f032e74e8594c0c6ff41c..8570c5089b605125680f8558ae201550df2d0a47 100644
|
index 79242037e868a140513f032e74e8594c0c6ff41c..050e89c3e95c7c3ef7ad98f8ef03ab206241a7e2 100644
|
||||||
--- a/net/minecraft/world/entity/npc/Villager.java
|
--- a/net/minecraft/world/entity/npc/Villager.java
|
||||||
+++ b/net/minecraft/world/entity/npc/Villager.java
|
+++ b/net/minecraft/world/entity/npc/Villager.java
|
||||||
@@ -490,8 +490,15 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
@@ -490,8 +490,15 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||||
@@ -16,7 +16,7 @@ index 79242037e868a140513f032e74e8594c0c6ff41c..8570c5089b605125680f8558ae201550
|
|||||||
+ // Lophine start - infinite trade
|
+ // Lophine start - infinite trade
|
||||||
+ MerchantOffers offers = this.getOffers().copy();
|
+ MerchantOffers offers = this.getOffers().copy();
|
||||||
Player tradingPlayer = this.getTradingPlayer();
|
Player tradingPlayer = this.getTradingPlayer();
|
||||||
+ if (fun.bm.lophine.config.modules.misc.VillagerConfig.villagerInfiniteTrade) {
|
+ if (fun.bm.lophine.config.modules.function.VillagerConfig.villagerInfiniteTrade) {
|
||||||
+ for (MerchantOffer merchantOffer : offers) {
|
+ for (MerchantOffer merchantOffer : offers) {
|
||||||
+ merchantOffer.maxUses = 524288;
|
+ merchantOffer.maxUses = 524288;
|
||||||
+ }
|
+ }
|
||||||
@@ -26,7 +26,7 @@ index 79242037e868a140513f032e74e8594c0c6ff41c..8570c5089b605125680f8558ae201550
|
|||||||
tradingPlayer.sendMerchantOffers(
|
tradingPlayer.sendMerchantOffers(
|
||||||
tradingPlayer.containerMenu.containerId,
|
tradingPlayer.containerMenu.containerId,
|
||||||
diff --git a/net/minecraft/world/item/trading/Merchant.java b/net/minecraft/world/item/trading/Merchant.java
|
diff --git a/net/minecraft/world/item/trading/Merchant.java b/net/minecraft/world/item/trading/Merchant.java
|
||||||
index 6e2fa442ddcd4ef3c4fe789b9ebac9dd409c9de7..28d743cc7beeb92a33683b8eea84096f94d90fb2 100644
|
index 6e2fa442ddcd4ef3c4fe789b9ebac9dd409c9de7..0c7318a0ed214204f5493576c8a7b02fbe51c00b 100644
|
||||||
--- a/net/minecraft/world/item/trading/Merchant.java
|
--- a/net/minecraft/world/item/trading/Merchant.java
|
||||||
+++ b/net/minecraft/world/item/trading/Merchant.java
|
+++ b/net/minecraft/world/item/trading/Merchant.java
|
||||||
@@ -42,7 +42,14 @@ public interface Merchant {
|
@@ -42,7 +42,14 @@ public interface Merchant {
|
||||||
@@ -36,7 +36,7 @@ index 6e2fa442ddcd4ef3c4fe789b9ebac9dd409c9de7..28d743cc7beeb92a33683b8eea84096f
|
|||||||
- MerchantOffers offers = this.getOffers();
|
- MerchantOffers offers = this.getOffers();
|
||||||
+ // Lophine start - infinite trade
|
+ // Lophine start - infinite trade
|
||||||
+ MerchantOffers offers = this.getOffers().copy();
|
+ MerchantOffers offers = this.getOffers().copy();
|
||||||
+ if (fun.bm.lophine.config.modules.misc.VillagerConfig.villagerInfiniteTrade) {
|
+ if (fun.bm.lophine.config.modules.function.VillagerConfig.villagerInfiniteTrade) {
|
||||||
+ for (MerchantOffer merchantOffer : offers) {
|
+ for (MerchantOffer merchantOffer : offers) {
|
||||||
+ merchantOffer.maxUses = 5242884;
|
+ merchantOffer.maxUses = 5242884;
|
||||||
+ }
|
+ }
|
||||||
@@ -46,7 +46,7 @@ index 6e2fa442ddcd4ef3c4fe789b9ebac9dd409c9de7..28d743cc7beeb92a33683b8eea84096f
|
|||||||
player.sendMerchantOffers(optionalInt.getAsInt(), offers, level, this.getVillagerXp(), this.showProgressBar(), this.canRestock());
|
player.sendMerchantOffers(optionalInt.getAsInt(), offers, level, this.getVillagerXp(), this.showProgressBar(), this.canRestock());
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/world/item/trading/MerchantOffer.java b/net/minecraft/world/item/trading/MerchantOffer.java
|
diff --git a/net/minecraft/world/item/trading/MerchantOffer.java b/net/minecraft/world/item/trading/MerchantOffer.java
|
||||||
index 64c99df8ff305fa28c75dc03fc5ef8c61634ad84..21ec77d5167cfdf05043ea474165148fb2b0c2d9 100644
|
index 64c99df8ff305fa28c75dc03fc5ef8c61634ad84..770f37d7158c7b4cec62783025f623a68c1f2457 100644
|
||||||
--- a/net/minecraft/world/item/trading/MerchantOffer.java
|
--- a/net/minecraft/world/item/trading/MerchantOffer.java
|
||||||
+++ b/net/minecraft/world/item/trading/MerchantOffer.java
|
+++ b/net/minecraft/world/item/trading/MerchantOffer.java
|
||||||
@@ -196,7 +196,7 @@ public class MerchantOffer {
|
@@ -196,7 +196,7 @@ public class MerchantOffer {
|
||||||
@@ -54,7 +54,7 @@ index 64c99df8ff305fa28c75dc03fc5ef8c61634ad84..21ec77d5167cfdf05043ea474165148f
|
|||||||
|
|
||||||
public boolean isOutOfStock() {
|
public boolean isOutOfStock() {
|
||||||
- return this.uses >= this.maxUses;
|
- return this.uses >= this.maxUses;
|
||||||
+ return (this.uses >= this.maxUses && !fun.bm.lophine.config.modules.misc.VillagerConfig.villagerInfiniteTrade); // Lophine - infinite trade
|
+ return (this.uses >= this.maxUses && !fun.bm.lophine.config.modules.function.VillagerConfig.villagerInfiniteTrade); // Lophine - infinite trade
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setToOutOfStock() {
|
public void setToOutOfStock() {
|
||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
|
||||||
Date: Wed, 21 May 2025 13:04:00 +0800
|
|
||||||
Subject: [PATCH] Add config to disable end crystal check
|
|
||||||
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/level/dimension/end/EndDragonFight.java b/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
|
||||||
index 4fa8371c212dcc02b8cf5fd267b736e1cf3f50c1..3f1520bdd5ef708824712ea62974fedb35067f23 100644
|
|
||||||
--- a/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
|
||||||
+++ b/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
|
||||||
@@ -547,6 +547,8 @@ public class EndDragonFight {
|
|
||||||
|
|
||||||
blockPos = this.portalLocation;
|
|
||||||
}
|
|
||||||
+ // Luminol start - Disable end crystal check
|
|
||||||
+ if (!fun.bm.lophine.config.modules.fixes.DisableEndCrystalCheckConfig.disableCheck) {
|
|
||||||
// Paper start - Perf: Do crystal-portal proximity check before entity lookup
|
|
||||||
if (placedEndCrystalPos != null) {
|
|
||||||
// The end crystal must be 0 or 1 higher than the portal origin
|
|
||||||
@@ -562,6 +564,7 @@ public class EndDragonFight {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Paper end - Perf: Do crystal-portal proximity check before entity lookup
|
|
||||||
+ } // Luminol end - Disable end crystal check
|
|
||||||
|
|
||||||
|
|
||||||
List<EndCrystal> list = Lists.newArrayList();
|
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||||
|
Date: Tue, 26 Aug 2025 02:55:23 +0800
|
||||||
|
Subject: [PATCH] Add config to allow generation of end void rings
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/net/minecraft/world/level/levelgen/DensityFunctions.java b/net/minecraft/world/level/levelgen/DensityFunctions.java
|
||||||
|
index 04527a5c65ad630f794fed9071d485aedd02257a..b63661b313c04e2bd8981920972339470148a847 100644
|
||||||
|
--- a/net/minecraft/world/level/levelgen/DensityFunctions.java
|
||||||
|
+++ b/net/minecraft/world/level/levelgen/DensityFunctions.java
|
||||||
|
@@ -528,7 +528,7 @@ public final class DensityFunctions {
|
||||||
|
int i1 = z / 2;
|
||||||
|
int i2 = x % 2;
|
||||||
|
int i3 = z % 2;
|
||||||
|
- float f = 100.0F - Mth.sqrt((long)x * (long)x + (long)z * (long)z) * 8.0F; // Paper - cast ints to long to avoid integer overflow
|
||||||
|
+ float f = fun.bm.lophine.config.modules.fixes.EndVoidRingsConfig.enabled ? 100.0F - Mth.sqrt(x * x + z * z) * 8.0F : 100.0F - Mth.sqrt((long)x * (long)x + (long)z * (long)z) * 8.0F; // Paper - cast ints to long to avoid integer overflow // Lophine - optimize end void rings generation
|
||||||
|
f = Mth.clamp(f, -100.0F, 80.0F);
|
||||||
|
|
||||||
|
NoiseCache cache = noiseCache.get().computeIfAbsent(noise, noiseKey -> new NoiseCache()); // Paper - Perf: Optimize end generation
|
||||||
+5
-54
@@ -1,7 +1,7 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||||
Date: Tue, 29 Apr 2025 23:03:56 +0800
|
Date: Tue, 29 Apr 2025 23:03:56 +0800
|
||||||
Subject: [PATCH] Add config to enable Cross Region Damage trace
|
Subject: [PATCH] Add config to enable cross region damage trace
|
||||||
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||||
@@ -48,40 +48,10 @@ index 11e6197dec541b28733715f0d7eaa4c7b834d632..6b7c92fdf562dfa46eee8e8acbc82b02
|
|||||||
AABB aabb = new AABB(this.blockPosition()).inflate(32.0, 10.0, 32.0);
|
AABB aabb = new AABB(this.blockPosition()).inflate(32.0, 10.0, 32.0);
|
||||||
this.level()
|
this.level()
|
||||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||||
index d55a6989fd68f0bcf7bd05e9420fda1115afa6c0..5369a6597e48ed9f0d8f7f0b9685ce4950df4fe5 100644
|
index 567d63ae589705e13403814b36e35d00c241a69e..3f4b1c54f9207ba1854a8c8da965cbaca5ea517d 100644
|
||||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||||
@@ -1216,6 +1216,29 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
@@ -1948,6 +1948,13 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ // Luminol Start - raid revert adapt Cross Region Damage trace
|
|
||||||
+ public boolean addEffect(MobEffectInstance effectInstance, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause, boolean fireEvent, boolean async) {
|
|
||||||
+ if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(entity)) {
|
|
||||||
+ return addEffect(effectInstance, entity, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN, true);
|
|
||||||
+ } else if (fun.bm.lophine.config.modules.experiment.EntityDamageSourceTraceConfig.enabled) {
|
|
||||||
+ postToEntityThreadAddEffect(effectInstance, entity, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN, true);
|
|
||||||
+ return true;
|
|
||||||
+ }
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private void postToEntityThreadAddEffect(MobEffectInstance effectInstance, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause, boolean fireEvent) {
|
|
||||||
+ if (entity != null)
|
|
||||||
+ entity.getBukkitEntity().taskScheduler.schedule((Entity nmsEntity) -> {
|
|
||||||
+ try {
|
|
||||||
+ addEffect(effectInstance, nmsEntity, cause, fireEvent);
|
|
||||||
+ } catch (Throwable ex) {
|
|
||||||
+ LOGGER.error(ex.getMessage(), ex);
|
|
||||||
+ }
|
|
||||||
+ }, null, 1L );
|
|
||||||
+ }
|
|
||||||
+ // Luminol End - raid revert adapt Cross Region Damage trace
|
|
||||||
+
|
|
||||||
public boolean canBeAffected(MobEffectInstance effectInstance) {
|
|
||||||
if (this.getType().is(EntityTypeTags.IMMUNE_TO_INFESTED)) {
|
|
||||||
return !effectInstance.is(MobEffects.INFESTED);
|
|
||||||
@@ -1948,6 +1971,13 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
|
||||||
final LivingEntity killer = this.getKillCredit();
|
final LivingEntity killer = this.getKillCredit();
|
||||||
if (killer != null) {
|
if (killer != null) {
|
||||||
killer.awardKillScore(this, damageSource);
|
killer.awardKillScore(this, damageSource);
|
||||||
@@ -95,7 +65,7 @@ index d55a6989fd68f0bcf7bd05e9420fda1115afa6c0..5369a6597e48ed9f0d8f7f0b9685ce49
|
|||||||
}
|
}
|
||||||
}); // Paper end
|
}); // Paper end
|
||||||
this.postDeathDropItems(deathEvent); // Paper
|
this.postDeathDropItems(deathEvent); // Paper
|
||||||
@@ -1958,6 +1988,18 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
@@ -1958,6 +1965,18 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||||
return deathEvent; // Paper
|
return deathEvent; // Paper
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +84,7 @@ index d55a6989fd68f0bcf7bd05e9420fda1115afa6c0..5369a6597e48ed9f0d8f7f0b9685ce49
|
|||||||
protected void dropEquipment(ServerLevel level) {
|
protected void dropEquipment(ServerLevel level) {
|
||||||
}
|
}
|
||||||
protected void postDeathDropItems(org.bukkit.event.entity.EntityDeathEvent event) {} // Paper - method for post death logic that cannot be ran before the event is potentially cancelled
|
protected void postDeathDropItems(org.bukkit.event.entity.EntityDeathEvent event) {} // Paper - method for post death logic that cannot be ran before the event is potentially cancelled
|
||||||
@@ -2556,6 +2598,18 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
@@ -2556,6 +2575,18 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,22 +103,3 @@ index d55a6989fd68f0bcf7bd05e9420fda1115afa6c0..5369a6597e48ed9f0d8f7f0b9685ce49
|
|||||||
public final float getMaxHealth() {
|
public final float getMaxHealth() {
|
||||||
return (float)this.getAttributeValue(Attributes.MAX_HEALTH);
|
return (float)this.getAttributeValue(Attributes.MAX_HEALTH);
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java
|
|
||||||
index 510514e363f4816a6e286fb9b5488153e03c9e55..4638af10539a316acae64fb26881c8e699c496e0 100644
|
|
||||||
--- a/net/minecraft/world/entity/raid/Raider.java
|
|
||||||
+++ b/net/minecraft/world/entity/raid/Raider.java
|
|
||||||
@@ -157,7 +157,13 @@ public abstract class Raider extends PatrollingMonster {
|
|
||||||
net.minecraft.world.effect.MobEffectInstance mobeffect1 = new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.BAD_OMEN, fun.bm.lophine.config.modules.misc.RaidChangesConfig.infinite ? net.minecraft.world.effect.MobEffectInstance.INFINITE_DURATION : 120000, i, false, false, true);
|
|
||||||
|
|
||||||
if (!serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_DISABLE_RAIDS)) {
|
|
||||||
- entityhuman.addEffect(mobeffect1, entityhuman, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN, true); // CraftBukkit
|
|
||||||
+ // Luminol start - Raid changes adapt DamageSource trace
|
|
||||||
+ if (fun.bm.lophine.config.modules.experiment.EntityDamageSourceTraceConfig.enabled) {
|
|
||||||
+ entityhuman.addEffect(mobeffect1, entityhuman, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN, true, true);
|
|
||||||
+ } else {
|
|
||||||
+ entityhuman.addEffect(mobeffect1, entityhuman, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN, true); // CraftBukkit
|
|
||||||
+ }
|
|
||||||
+ // Luminol end - Raid changes adapt DamageSource trace
|
|
||||||
}
|
|
||||||
this.setPatrolLeader(false);
|
|
||||||
}
|
|
||||||
+3
-3
@@ -5,11 +5,11 @@ Subject: [PATCH] Add config to enable datapack command
|
|||||||
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||||
index 0d5ed9602492c8393088954105e9a19032067b8b..e2fc15d84fafde6847ecead23c55169449275e1b 100644
|
index e05f75b6bbd48d6fb7379926d68d5f8ed6014be9..af895859057ca303177ec3c8a07cf7534e62cca6 100644
|
||||||
--- a/net/minecraft/commands/Commands.java
|
--- a/net/minecraft/commands/Commands.java
|
||||||
+++ b/net/minecraft/commands/Commands.java
|
+++ b/net/minecraft/commands/Commands.java
|
||||||
@@ -192,7 +192,9 @@ public class Commands {
|
@@ -192,7 +192,9 @@ public class Commands {
|
||||||
if(me.earthme.luminol.config.modules.experiment.CommandDataConfig.enabled) {
|
if(me.earthme.luminol.config.modules.experiment.CommandConfig.data) {
|
||||||
DataCommands.register(this.dispatcher); // Folia - region threading - TODO
|
DataCommands.register(this.dispatcher); // Folia - region threading - TODO
|
||||||
}
|
}
|
||||||
- //DataPackCommand.register(this.dispatcher, context); // Folia - region threading - TODO
|
- //DataPackCommand.register(this.dispatcher, context); // Folia - region threading - TODO
|
||||||
@@ -20,7 +20,7 @@ index 0d5ed9602492c8393088954105e9a19032067b8b..e2fc15d84fafde6847ecead23c551694
|
|||||||
DefaultGameModeCommands.register(this.dispatcher);
|
DefaultGameModeCommands.register(this.dispatcher);
|
||||||
//DialogCommand.register(this.dispatcher, context); // Folia - region threading - TODO
|
//DialogCommand.register(this.dispatcher, context); // Folia - region threading - TODO
|
||||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||||
index 86d20d884fb59d0121bdcc291af1fc97b8bf603d..a0f1db50adf5163a671d3d9e9df7adb7de4250c6 100644
|
index 100e8fdc52c201d386e3c779d19f6b5abde39820..d08a5b553f4e5932d960fbcdeb6a43419730e32a 100644
|
||||||
--- a/net/minecraft/server/MinecraftServer.java
|
--- a/net/minecraft/server/MinecraftServer.java
|
||||||
+++ b/net/minecraft/server/MinecraftServer.java
|
+++ b/net/minecraft/server/MinecraftServer.java
|
||||||
@@ -2352,6 +2352,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
@@ -2352,6 +2352,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||||
-207
@@ -1,207 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
|
||||||
Date: Fri, 11 Apr 2025 16:53:57 +0800
|
|
||||||
Subject: [PATCH] Add config to revert raid changes
|
|
||||||
|
|
||||||
Co-authored by: huanli233 <392352840@qq.com>
|
|
||||||
Some of changes is a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/b5793e809b6346e16b7ea218496806a312562e27/leaves-server/minecraft-patches/features/0106-Revert-raid-changes.patch)
|
|
||||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/effect/BadOmenMobEffect.java b/net/minecraft/world/effect/BadOmenMobEffect.java
|
|
||||||
index 80f17f33f670018240c854df589cf90cdeab6e70..985f27d249810bf133a520d937b7006e57f553ec 100644
|
|
||||||
--- a/net/minecraft/world/effect/BadOmenMobEffect.java
|
|
||||||
+++ b/net/minecraft/world/effect/BadOmenMobEffect.java
|
|
||||||
@@ -22,6 +22,11 @@ class BadOmenMobEffect extends MobEffect {
|
|
||||||
&& !serverPlayer.isSpectator()
|
|
||||||
&& level.getDifficulty() != Difficulty.PEACEFUL
|
|
||||||
&& level.isVillage(serverPlayer.blockPosition())) {
|
|
||||||
+ // Leaves start - Revert raid changes
|
|
||||||
+ if (fun.bm.lophine.config.modules.misc.RaidChangesConfig.trigger) {
|
|
||||||
+ return level.getRaids().createOrExtendRaid(serverPlayer, serverPlayer.blockPosition()) == null;
|
|
||||||
+ }
|
|
||||||
+ // Leaves end - Revert raid changes
|
|
||||||
Raid raidAt = level.getRaidAt(serverPlayer.blockPosition());
|
|
||||||
if (raidAt == null || raidAt.getRaidOmenLevel() < raidAt.getMaxRaidOmenLevel()) {
|
|
||||||
serverPlayer.addEffect(new MobEffectInstance(MobEffects.RAID_OMEN, 600, amplifier));
|
|
||||||
diff --git a/net/minecraft/world/entity/raid/Raid.java b/net/minecraft/world/entity/raid/Raid.java
|
|
||||||
index 1910bff3f08147bfd63703097e30b9f88c84e337..26f4d7359f638a11ea2d768d18091e261d6b1791 100644
|
|
||||||
--- a/net/minecraft/world/entity/raid/Raid.java
|
|
||||||
+++ b/net/minecraft/world/entity/raid/Raid.java
|
|
||||||
@@ -340,7 +340,20 @@ public class Raid {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flag1) {
|
|
||||||
- this.waveSpawnPos = this.getValidSpawnPos(level);
|
|
||||||
+ // Luminol Start - Raid revert
|
|
||||||
+ if (!fun.bm.lophine.config.modules.misc.RaidChangesConfig.posRevert) {
|
|
||||||
+ this.waveSpawnPos = this.getValidSpawnPos(level);
|
|
||||||
+ } else {
|
|
||||||
+ int n4 = 0;
|
|
||||||
+ if (this.raidCooldownTicks < 100) {
|
|
||||||
+ n4 = 1;
|
|
||||||
+ }
|
|
||||||
+ if (this.raidCooldownTicks < 40) {
|
|
||||||
+ n4 = 2;
|
|
||||||
+ }
|
|
||||||
+ this.waveSpawnPos = this.getValidSpawnPos(level, n4);
|
|
||||||
+ }
|
|
||||||
+ // Luminol End - Raid revert
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.raidCooldownTicks == 300 || this.raidCooldownTicks % 20 == 0) {
|
|
||||||
@@ -375,7 +388,14 @@ public class Raid {
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while (this.shouldSpawnGroup()) {
|
|
||||||
- BlockPos blockPos = this.waveSpawnPos.orElseGet(() -> this.findRandomSpawnPos(level, 20));
|
|
||||||
+ // Luminol Start - Raid revert
|
|
||||||
+ BlockPos blockPos;
|
|
||||||
+ if (!fun.bm.lophine.config.modules.misc.RaidChangesConfig.posRevert) {
|
|
||||||
+ blockPos = this.waveSpawnPos.orElseGet(() -> this.findRandomSpawnPos(level, 20));
|
|
||||||
+ } else {
|
|
||||||
+ blockPos = this.waveSpawnPos.isPresent() ? this.waveSpawnPos.get() : this.findRandomSpawnPos(level, i, 20);
|
|
||||||
+ }
|
|
||||||
+ // Luminol End - Raid revert
|
|
||||||
if (blockPos != null) {
|
|
||||||
this.started = true;
|
|
||||||
this.spawnGroup(level, blockPos);
|
|
||||||
@@ -387,7 +407,7 @@ public class Raid {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (i > 5) {
|
|
||||||
+ if (i > (fun.bm.lophine.config.modules.misc.RaidChangesConfig.posRevert ? 3 : 5)) { // Luminol - Raid revert
|
|
||||||
org.bukkit.craftbukkit.event.CraftEventFactory.callRaidStopEvent(level, this, org.bukkit.event.raid.RaidStopEvent.Reason.UNSPAWNABLE); // CraftBukkit
|
|
||||||
this.stop();
|
|
||||||
break;
|
|
||||||
@@ -458,6 +478,17 @@ public class Raid {
|
|
||||||
return blockPos != null ? Optional.of(blockPos) : Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
+ // Luminol Start - Raid revert
|
|
||||||
+ private Optional<BlockPos> getValidSpawnPos(ServerLevel level, int n) {
|
|
||||||
+ for (int i = 0; i < 3; ++i) {
|
|
||||||
+ BlockPos blockPos = this.findRandomSpawnPos(level, n, 1);
|
|
||||||
+ if (blockPos == null) continue;
|
|
||||||
+ return Optional.of(blockPos);
|
|
||||||
+ }
|
|
||||||
+ return Optional.empty();
|
|
||||||
+ }
|
|
||||||
+ // Luminol End - Raid revert
|
|
||||||
+
|
|
||||||
private boolean hasMoreWaves() {
|
|
||||||
return this.hasBonusWave() ? !this.hasSpawnedBonusWave() : !this.isFinalWave();
|
|
||||||
}
|
|
||||||
@@ -683,7 +714,7 @@ public class Raid {
|
|
||||||
int i2 = this.center.getX() + Mth.floor(Mth.cos(f2) * 32.0F * f) + level.random.nextInt(3) * Mth.floor(f);
|
|
||||||
int i3 = this.center.getZ() + Mth.floor(Mth.sin(f2) * 32.0F * f) + level.random.nextInt(3) * Mth.floor(f);
|
|
||||||
int height = level.getHeight(Heightmap.Types.WORLD_SURFACE, i2, i3);
|
|
||||||
- if (Mth.abs(height - this.center.getY()) <= 96) {
|
|
||||||
+ if (fun.bm.lophine.config.modules.misc.RaidChangesConfig.heightCheck || Mth.abs(height - this.center.getY()) <= 96) { // Leaves - Disable height check
|
|
||||||
mutableBlockPos.set(i2, height, i3);
|
|
||||||
if (!level.isVillage(mutableBlockPos) || i <= 7) {
|
|
||||||
int i4 = 10;
|
|
||||||
@@ -702,6 +733,26 @@ public class Raid {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ // Luminol Start - Raid revert
|
|
||||||
+ @Nullable
|
|
||||||
+ private BlockPos findRandomSpawnPos(ServerLevel level, int n, int n2) {
|
|
||||||
+ int n3 = 2 - n;
|
|
||||||
+ BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
|
|
||||||
+ SpawnPlacementType spawnPlacementType = SpawnPlacements.getPlacementType(EntityType.RAVAGER);
|
|
||||||
+ for (int i = 0; i < n2; ++i) {
|
|
||||||
+ float f = level.random.nextFloat() * ((float)Math.PI * 2);
|
|
||||||
+ int n4 = this.center.getX() + Mth.floor(Mth.cos(f) * 32.0f * (float)n3) + level.random.nextInt(5);
|
|
||||||
+ int n5 = this.center.getZ() + Mth.floor(Mth.sin(f) * 32.0f * (float)n3) + level.random.nextInt(5);
|
|
||||||
+ int n6 = level.getHeight(Heightmap.Types.WORLD_SURFACE, n4, n5);
|
|
||||||
+ mutableBlockPos.set(n4, n6, n5);
|
|
||||||
+ if (level.isVillage(mutableBlockPos) && n < 2) continue;
|
|
||||||
+ if (!level.hasChunksAt(mutableBlockPos.getX() - 10, mutableBlockPos.getZ() - 10, mutableBlockPos.getX() + 10, mutableBlockPos.getZ() + 10) || !level.isPositionEntityTicking(mutableBlockPos) || !spawnPlacementType.isSpawnPositionOk(level, mutableBlockPos, EntityType.RAVAGER) && (!level.getBlockState(mutableBlockPos.below()).is(Blocks.SNOW) || !level.getBlockState(mutableBlockPos).isAir())) continue;
|
|
||||||
+ return mutableBlockPos;
|
|
||||||
+ }
|
|
||||||
+ return null;
|
|
||||||
+ }
|
|
||||||
+ // Luminol End - Raid revert
|
|
||||||
+
|
|
||||||
private boolean addWaveMob(ServerLevel level, int wave, Raider raider) {
|
|
||||||
// Folia start - make raids thread-safe
|
|
||||||
if (!this.ownsRaid(level)) {
|
|
||||||
diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java
|
|
||||||
index 3e30989c99cd11c8c94d6fd194d2969e3a7efda6..510514e363f4816a6e286fb9b5488153e03c9e55 100644
|
|
||||||
--- a/net/minecraft/world/entity/raid/Raider.java
|
|
||||||
+++ b/net/minecraft/world/entity/raid/Raider.java
|
|
||||||
@@ -128,6 +128,41 @@ public abstract class Raider extends PatrollingMonster {
|
|
||||||
|
|
||||||
currentRaid.removeFromRaid(serverLevel, this, false);
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ // Leaves start - Revert raid changes
|
|
||||||
+ if (fun.bm.lophine.config.modules.misc.RaidChangesConfig.effect && !this.hasRaid()) {
|
|
||||||
+ ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD);
|
|
||||||
+ net.minecraft.world.entity.player.Player entityhuman = null;
|
|
||||||
+ if (entity instanceof net.minecraft.world.entity.player.Player player) {
|
|
||||||
+ entityhuman = player;
|
|
||||||
+ } else if (entity instanceof net.minecraft.world.entity.animal.wolf.Wolf wolf) {
|
|
||||||
+ LivingEntity entityliving = wolf.getOwner();
|
|
||||||
+ if (wolf.isTame() && entityliving instanceof net.minecraft.world.entity.player.Player player) {
|
|
||||||
+ entityhuman = player;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (entityhuman != null && !itemstack.isEmpty() && this.isCaptain()) {
|
|
||||||
+ net.minecraft.world.effect.MobEffectInstance mobeffect = entityhuman.getEffect(net.minecraft.world.effect.MobEffects.BAD_OMEN);
|
|
||||||
+ int i = 1;
|
|
||||||
+
|
|
||||||
+ if (mobeffect != null) {
|
|
||||||
+ i += mobeffect.getAmplifier();
|
|
||||||
+ entityhuman.removeEffectNoUpdate(net.minecraft.world.effect.MobEffects.BAD_OMEN);
|
|
||||||
+ } else {
|
|
||||||
+ --i;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ i = net.minecraft.util.Mth.clamp(i, 0, 4);
|
|
||||||
+ net.minecraft.world.effect.MobEffectInstance mobeffect1 = new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.BAD_OMEN, fun.bm.lophine.config.modules.misc.RaidChangesConfig.infinite ? net.minecraft.world.effect.MobEffectInstance.INFINITE_DURATION : 120000, i, false, false, true);
|
|
||||||
+
|
|
||||||
+ if (!serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_DISABLE_RAIDS)) {
|
|
||||||
+ entityhuman.addEffect(mobeffect1, entityhuman, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN, true); // CraftBukkit
|
|
||||||
+ }
|
|
||||||
+ this.setPatrolLeader(false);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ // Leaves end - Revert raid changes
|
|
||||||
}
|
|
||||||
|
|
||||||
super.die(cause);
|
|
||||||
@@ -156,7 +191,7 @@ public abstract class Raider extends PatrollingMonster {
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasRaid() {
|
|
||||||
- return this.level() instanceof ServerLevel serverLevel && (this.getCurrentRaid() != null || serverLevel.getRaidAt(this.blockPosition()) != null);
|
|
||||||
+ return !fun.bm.lophine.config.modules.misc.RaidChangesConfig.selfCheck && (this.level() instanceof ServerLevel serverLevel && (this.getCurrentRaid() != null || serverLevel.getRaidAt(this.blockPosition()) != null)); // Leaves - Disable raid self check
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasActiveRaid() {
|
|
||||||
diff --git a/net/minecraft/world/item/component/OminousBottleAmplifier.java b/net/minecraft/world/item/component/OminousBottleAmplifier.java
|
|
||||||
index 33907bb190ffa22ccf9ea424b1e536297878711a..2fca459f2c888079322f6b957bbee3ac0e33c4bc 100644
|
|
||||||
--- a/net/minecraft/world/item/component/OminousBottleAmplifier.java
|
|
||||||
+++ b/net/minecraft/world/item/component/OminousBottleAmplifier.java
|
|
||||||
@@ -29,7 +29,7 @@ public record OminousBottleAmplifier(int value) implements ConsumableListener, T
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConsume(Level level, LivingEntity entity, ItemStack stack, Consumable consumable) {
|
|
||||||
- entity.addEffect(new MobEffectInstance(MobEffects.BAD_OMEN, 120000, this.value, false, false, true)); // Paper - properly resend entities - diff on change for below
|
|
||||||
+ entity.addEffect(new MobEffectInstance(MobEffects.BAD_OMEN, fun.bm.lophine.config.modules.misc.RaidChangesConfig.infinite ? net.minecraft.world.effect.MobEffectInstance.INFINITE_DURATION : 120000, this.value, false, false, true)); // Paper - properly resend entities - diff on change for below // Luminol - Raid effect infinite
|
|
||||||
}
|
|
||||||
|
|
||||||
// Paper start - properly resend entities - collect packets for bundle
|
|
||||||
@@ -41,7 +41,7 @@ public record OminousBottleAmplifier(int value) implements ConsumableListener, T
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addToTooltip(Item.TooltipContext context, Consumer<Component> tooltipAdder, TooltipFlag flag, DataComponentGetter componentGetter) {
|
|
||||||
- List<MobEffectInstance> list = List.of(new MobEffectInstance(MobEffects.BAD_OMEN, 120000, this.value, false, false, true));
|
|
||||||
+ List<MobEffectInstance> list = List.of(new MobEffectInstance(MobEffects.BAD_OMEN, fun.bm.lophine.config.modules.misc.RaidChangesConfig.infinite ? net.minecraft.world.effect.MobEffectInstance.INFINITE_DURATION : 120000, this.value, false, false, true)); // Luminol - Raid effect infinite
|
|
||||||
PotionContents.addPotionTooltip(list, tooltipAdder, 1.0F, context.tickRate());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
From: MrHua269 <wangxyper@163.com>
|
From: MrHua269 <wangxyper@163.com>
|
||||||
Date: Wed, 5 Feb 2025 15:22:19 +0800
|
Date: Wed, 5 Feb 2025 15:22:19 +0800
|
||||||
Subject: [PATCH] Add config to enable Raytracing tracker
|
Subject: [PATCH] Add config to enable raytracing tracker
|
||||||
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||||
@@ -18,7 +18,7 @@ index 6868b915bf3deb85783a638d4441a15fea6da2dc..70740381c6501c1a518c52b24381edd1
|
|||||||
double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
|
double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
|
||||||
if (rangeY != -1) {
|
if (rangeY != -1) {
|
||||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||||
index 2f733a3f75f9fe637864158a31d7507eac121d45..f7fcb4782b49374df8fe8f4401a4259f037221f7 100644
|
index 8ec753fe9c84ffe1188f7e7ebb6895cf4bba9e39..ee4a459700d75676eae3422d4a0e10be73c45871 100644
|
||||||
--- a/net/minecraft/world/entity/Entity.java
|
--- a/net/minecraft/world/entity/Entity.java
|
||||||
+++ b/net/minecraft/world/entity/Entity.java
|
+++ b/net/minecraft/world/entity/Entity.java
|
||||||
@@ -147,7 +147,7 @@ import net.minecraft.world.waypoints.WaypointTransmitter;
|
@@ -147,7 +147,7 @@ import net.minecraft.world.waypoints.WaypointTransmitter;
|
||||||
@@ -30,7 +30,7 @@ index 2f733a3f75f9fe637864158a31d7507eac121d45..f7fcb4782b49374df8fe8f4401a4259f
|
|||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
private static final int CURRENT_LEVEL = 2;
|
private static final int CURRENT_LEVEL = 2;
|
||||||
public boolean preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; keep initial motion on first snapTo
|
public boolean preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; keep initial motion on first snapTo
|
||||||
@@ -6439,4 +6439,46 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
@@ -6472,4 +6472,46 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
// Paper end - Expose entity id counter
|
// Paper end - Expose entity id counter
|
||||||
|
|
||||||
public boolean shouldTickHot() { return this.tickCount > 20 * 10 && this.isAlive(); } // KioCG
|
public boolean shouldTickHot() { return this.tickCount > 20 * 10 && this.isAlive(); } // KioCG
|
||||||
+4
-4
@@ -44,7 +44,7 @@ index e1842ab8f20271a8b20ab8462b09a4745a612a9a..8405157ec35a443e238fa6866772c839
|
|||||||
world.setDayTime(world.levelData.getDayTime() + (long)tickCount);
|
world.setDayTime(world.levelData.getDayTime() + (long)tickCount);
|
||||||
}
|
}
|
||||||
diff --git a/io/papermc/paper/threadedregions/TickRegionScheduler.java b/io/papermc/paper/threadedregions/TickRegionScheduler.java
|
diff --git a/io/papermc/paper/threadedregions/TickRegionScheduler.java b/io/papermc/paper/threadedregions/TickRegionScheduler.java
|
||||||
index 0357792de0ed8ec9058d1847c8b45c33ff365af6..4945c11f573a53df2f5be4beb7af6a3f4d32f7d4 100644
|
index c485d5b3ba95f2a969bdf0dab9654ac284976f8d..b957585cf7cf7f845e20f59c7b355722880f3b4e 100644
|
||||||
--- a/io/papermc/paper/threadedregions/TickRegionScheduler.java
|
--- a/io/papermc/paper/threadedregions/TickRegionScheduler.java
|
||||||
+++ b/io/papermc/paper/threadedregions/TickRegionScheduler.java
|
+++ b/io/papermc/paper/threadedregions/TickRegionScheduler.java
|
||||||
@@ -31,8 +31,8 @@ public final class TickRegionScheduler {
|
@@ -31,8 +31,8 @@ public final class TickRegionScheduler {
|
||||||
@@ -97,10 +97,10 @@ index 0357792de0ed8ec9058d1847c8b45c33ff365af6..4945c11f573a53df2f5be4beb7af6a3f
|
|||||||
this.scheduler.regionFailed(this, false, thr);
|
this.scheduler.regionFailed(this, false, thr);
|
||||||
// regionFailed will schedule a shutdown, so we should avoid letting this region tick further
|
// regionFailed will schedule a shutdown, so we should avoid letting this region tick further
|
||||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||||
index 8a90aa5c145f53afbb3f2371f97cb09974f30bbb..0d5ed9602492c8393088954105e9a19032067b8b 100644
|
index af895859057ca303177ec3c8a07cf7534e62cca6..94a3cea5d42b1f98bbde22ef514f8f7dbd64ba58 100644
|
||||||
--- a/net/minecraft/commands/Commands.java
|
--- a/net/minecraft/commands/Commands.java
|
||||||
+++ b/net/minecraft/commands/Commands.java
|
+++ b/net/minecraft/commands/Commands.java
|
||||||
@@ -243,7 +243,11 @@ public class Commands {
|
@@ -245,7 +245,11 @@ public class Commands {
|
||||||
TeleportCommand.register(this.dispatcher);
|
TeleportCommand.register(this.dispatcher);
|
||||||
TellRawCommand.register(this.dispatcher, context);
|
TellRawCommand.register(this.dispatcher, context);
|
||||||
//TestCommand.register(this.dispatcher, context); // Folia - region threading
|
//TestCommand.register(this.dispatcher, context); // Folia - region threading
|
||||||
@@ -114,7 +114,7 @@ index 8a90aa5c145f53afbb3f2371f97cb09974f30bbb..0d5ed9602492c8393088954105e9a190
|
|||||||
TitleCommand.register(this.dispatcher, context);
|
TitleCommand.register(this.dispatcher, context);
|
||||||
//TriggerCommand.register(this.dispatcher); // Folia - region threading - TODO later
|
//TriggerCommand.register(this.dispatcher); // Folia - region threading - TODO later
|
||||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||||
index 2ed2f4cca3a81117c0beaf7a11bbbe8156f6a9ce..6675b83c9f15d0341dcf169ec3ac20f401c5d10b 100644
|
index d08a5b553f4e5932d960fbcdeb6a43419730e32a..a0f1db50adf5163a671d3d9e9df7adb7de4250c6 100644
|
||||||
--- a/net/minecraft/server/MinecraftServer.java
|
--- a/net/minecraft/server/MinecraftServer.java
|
||||||
+++ b/net/minecraft/server/MinecraftServer.java
|
+++ b/net/minecraft/server/MinecraftServer.java
|
||||||
@@ -267,7 +267,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
@@ -267,7 +267,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||||
+1
-1
@@ -5,7 +5,7 @@ Subject: [PATCH] Add config to enable unsafe waypoint bar
|
|||||||
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||||
index e2fc15d84fafde6847ecead23c55169449275e1b..b0a06cdfaa49237f372ecd131d47289160476b07 100644
|
index 94a3cea5d42b1f98bbde22ef514f8f7dbd64ba58..e311977fca4d0ba6e3efd4a41b2732cf5e7b4b9c 100644
|
||||||
--- a/net/minecraft/commands/Commands.java
|
--- a/net/minecraft/commands/Commands.java
|
||||||
+++ b/net/minecraft/commands/Commands.java
|
+++ b/net/minecraft/commands/Commands.java
|
||||||
@@ -253,7 +253,11 @@ public class Commands {
|
@@ -253,7 +253,11 @@ public class Commands {
|
||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||||
Date: Sun, 3 Aug 2025 15:24:01 +0800
|
Date: Sun, 3 Aug 2025 15:24:01 +0800
|
||||||
Subject: [PATCH] Leaves: Leaves Protocol Core
|
Subject: [PATCH] Leaves: Base Protocol Core
|
||||||
|
|
||||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/ea91106ae57fc4cc14e2e0225009cf9919072f7f/leaves-server/minecraft-patches/features/0004-Leaves-Protocol-Core.patch)
|
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/ea91106ae57fc4cc14e2e0225009cf9919072f7f/leaves-server/minecraft-patches/features/0004-Leaves-Protocol-Core.patch)
|
||||||
@@ -88,7 +88,7 @@ index a0f1db50adf5163a671d3d9e9df7adb7de4250c6..af13707933af14171447d5ab6faacb64
|
|||||||
public int getSpawnProtectionRadius() {
|
public int getSpawnProtectionRadius() {
|
||||||
return 16;
|
return 16;
|
||||||
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||||
index 714813cba67da4a737682fe9276cb0d96fea336d..9677a3d62de11dafc8b9debe7a18ee6d14c7a64d 100644
|
index 8150b16c196edcb226be9268ea6e0012e44517fa..c54bf0429c0ca3a35a730658c7b1b3ddc776bf9e 100644
|
||||||
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||||
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||||
@@ -57,6 +57,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
@@ -57,6 +57,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||||
+25
-25
@@ -28,7 +28,7 @@ index 643797124fe5a4489d0b7419b7e600c04f283ef2..04b4100da96aad50f08e8c59200eec93
|
|||||||
|
|
||||||
public String serialize(HolderLookup.Provider levelRegistry) {
|
public String serialize(HolderLookup.Provider levelRegistry) {
|
||||||
diff --git a/net/minecraft/server/commands/GiveCommand.java b/net/minecraft/server/commands/GiveCommand.java
|
diff --git a/net/minecraft/server/commands/GiveCommand.java b/net/minecraft/server/commands/GiveCommand.java
|
||||||
index f7002d6752aa03603eb06e298ba1d7130cf13826..72c87f7c0392d087440db9d267a608598f6feb6d 100644
|
index 7ef109cb9921c25987905149616eddbd0b2f9b9c..70fc9d6c5b226211ff5964464c37e11695d5f745 100644
|
||||||
--- a/net/minecraft/server/commands/GiveCommand.java
|
--- a/net/minecraft/server/commands/GiveCommand.java
|
||||||
+++ b/net/minecraft/server/commands/GiveCommand.java
|
+++ b/net/minecraft/server/commands/GiveCommand.java
|
||||||
@@ -55,7 +55,7 @@ public class GiveCommand {
|
@@ -55,7 +55,7 @@ public class GiveCommand {
|
||||||
@@ -41,7 +41,7 @@ index f7002d6752aa03603eb06e298ba1d7130cf13826..72c87f7c0392d087440db9d267a60859
|
|||||||
if (count > i) {
|
if (count > i) {
|
||||||
source.sendFailure(Component.translatable("commands.give.failed.toomanyitems", i, itemStack.getDisplayName()));
|
source.sendFailure(Component.translatable("commands.give.failed.toomanyitems", i, itemStack.getDisplayName()));
|
||||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||||
index 1d52376f034dc5690e8b399512146b47b92c3c14..4b215dc69887df9382bde4cfa2f37afadfe1bcb2 100644
|
index 74ec003486f9362d2bafbad8392b9bbdf0c15882..f06b9d8ad9512d35f3f460eb77c869690321c67f 100644
|
||||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||||
@@ -3079,7 +3079,7 @@ public class ServerGamePacketListenerImpl
|
@@ -3079,7 +3079,7 @@ public class ServerGamePacketListenerImpl
|
||||||
@@ -88,10 +88,10 @@ index 1d52376f034dc5690e8b399512146b47b92c3c14..4b215dc69887df9382bde4cfa2f37afa
|
|||||||
} else if (flag && flag2) {
|
} else if (flag && flag2) {
|
||||||
if (this.dropSpamThrottler.isUnderThreshold()) {
|
if (this.dropSpamThrottler.isUnderThreshold()) {
|
||||||
diff --git a/net/minecraft/world/Container.java b/net/minecraft/world/Container.java
|
diff --git a/net/minecraft/world/Container.java b/net/minecraft/world/Container.java
|
||||||
index b382665cc125b8b5c0938e5e55984e4bf91d37ff..86cac164a2bf0e76528396e6aabbfd64cfc29559 100644
|
index 2afaf6a3f18af7889f4f3b35cee9bbb5e4ec01f2..da99b4bc7fe8460945070915073be141f9bd6778 100644
|
||||||
--- a/net/minecraft/world/Container.java
|
--- a/net/minecraft/world/Container.java
|
||||||
+++ b/net/minecraft/world/Container.java
|
+++ b/net/minecraft/world/Container.java
|
||||||
@@ -32,6 +32,12 @@ public interface Container extends Clearable, Iterable<ItemStack> {
|
@@ -32,6 +32,12 @@ public interface Container extends Clearable, Iterable<ItemStack>, org.leavesmc.
|
||||||
return Math.min(this.getMaxStackSize(), stack.getMaxStackSize());
|
return Math.min(this.getMaxStackSize(), stack.getMaxStackSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,10 +127,10 @@ index d907e24d563e27acab2f2bf9711b1755ea9afd19..75170c8d3be477a6ea2a1d62018a6ab6
|
|||||||
if (min > 0) {
|
if (min > 0) {
|
||||||
other.grow(min);
|
other.grow(min);
|
||||||
diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java
|
diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java
|
||||||
index b745eb5d9c68547335247910ff2ae8d5fb36349c..0c2bf0f8edb34a9011092ea94e54f7bbcee0bbbc 100644
|
index fd4f1e63f980b6959fc80084651991f8f8bc6c34..e5e8c752129a6ebb0dd1315c9b8ec459be11ef07 100644
|
||||||
--- a/net/minecraft/world/entity/item/ItemEntity.java
|
--- a/net/minecraft/world/entity/item/ItemEntity.java
|
||||||
+++ b/net/minecraft/world/entity/item/ItemEntity.java
|
+++ b/net/minecraft/world/entity/item/ItemEntity.java
|
||||||
@@ -279,10 +279,15 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
@@ -283,10 +283,15 @@ public class ItemEntity extends Entity implements TraceableEntity, ChangePublish
|
||||||
|
|
||||||
private boolean isMergable() {
|
private boolean isMergable() {
|
||||||
ItemStack item = this.getItem();
|
ItemStack item = this.getItem();
|
||||||
@@ -229,7 +229,7 @@ index 02d2efef2dc0f0e12eac0c71fa290af706f7694d..99f109e2653eff10c011f380694bd77a
|
|||||||
|
|
||||||
default SlotAccess getChestVehicleSlot(final int index) {
|
default SlotAccess getChestVehicleSlot(final int index) {
|
||||||
diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||||
index 9d8ab94f84f4523a2562f9eeb3410554e4269e46..87d1cf9ddfb3124069ff3ff921f2e62589562220 100644
|
index 2d6acceffb2cb7e55dd504018a70b05afccd9c11..bdc0ca1f625dc264bef6e5722ec66121ba48625a 100644
|
||||||
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
|
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||||
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||||
@@ -295,6 +295,13 @@ public abstract class AbstractContainerMenu {
|
@@ -295,6 +295,13 @@ public abstract class AbstractContainerMenu {
|
||||||
@@ -273,7 +273,7 @@ index 9d8ab94f84f4523a2562f9eeb3410554e4269e46..87d1cf9ddfb3124069ff3ff921f2e625
|
|||||||
}
|
}
|
||||||
} else if (clickType == ClickType.THROW && this.getCarried().isEmpty() && slotId >= 0) {
|
} else if (clickType == ClickType.THROW && this.getCarried().isEmpty() && slotId >= 0) {
|
||||||
Slot slot2 = this.slots.get(slotId);
|
Slot slot2 = this.slots.get(slotId);
|
||||||
@@ -656,15 +663,15 @@ public abstract class AbstractContainerMenu {
|
@@ -660,15 +667,15 @@ public abstract class AbstractContainerMenu {
|
||||||
int maxStackSize = button == 0 ? 1 : -1;
|
int maxStackSize = button == 0 ? 1 : -1;
|
||||||
|
|
||||||
for (int i3 = 0; i3 < 2; i3++) {
|
for (int i3 = 0; i3 < 2; i3++) {
|
||||||
@@ -292,7 +292,7 @@ index 9d8ab94f84f4523a2562f9eeb3410554e4269e46..87d1cf9ddfb3124069ff3ff921f2e625
|
|||||||
itemStack.grow(itemStack1.getCount());
|
itemStack.grow(itemStack1.getCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -766,7 +773,7 @@ public abstract class AbstractContainerMenu {
|
@@ -770,7 +777,7 @@ public abstract class AbstractContainerMenu {
|
||||||
i = endIndex - 1;
|
i = endIndex - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,7 +301,7 @@ index 9d8ab94f84f4523a2562f9eeb3410554e4269e46..87d1cf9ddfb3124069ff3ff921f2e625
|
|||||||
while (!stack.isEmpty() && (reverseDirection ? i >= startIndex : i < endIndex)) {
|
while (!stack.isEmpty() && (reverseDirection ? i >= startIndex : i < endIndex)) {
|
||||||
Slot slot = this.slots.get(i);
|
Slot slot = this.slots.get(i);
|
||||||
ItemStack item = slot.getItem();
|
ItemStack item = slot.getItem();
|
||||||
@@ -867,7 +874,7 @@ public abstract class AbstractContainerMenu {
|
@@ -871,7 +878,7 @@ public abstract class AbstractContainerMenu {
|
||||||
public static boolean canItemQuickReplace(@Nullable Slot slot, ItemStack stack, boolean stackSizeMatters) {
|
public static boolean canItemQuickReplace(@Nullable Slot slot, ItemStack stack, boolean stackSizeMatters) {
|
||||||
boolean flag = slot == null || !slot.hasItem();
|
boolean flag = slot == null || !slot.hasItem();
|
||||||
return !flag && ItemStack.isSameItemSameComponents(stack, slot.getItem())
|
return !flag && ItemStack.isSameItemSameComponents(stack, slot.getItem())
|
||||||
@@ -310,7 +310,7 @@ index 9d8ab94f84f4523a2562f9eeb3410554e4269e46..87d1cf9ddfb3124069ff3ff921f2e625
|
|||||||
: flag;
|
: flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -875,7 +882,7 @@ public abstract class AbstractContainerMenu {
|
@@ -879,7 +886,7 @@ public abstract class AbstractContainerMenu {
|
||||||
return switch (type) {
|
return switch (type) {
|
||||||
case 0 -> Mth.floor((float)stack.getCount() / slots.size());
|
case 0 -> Mth.floor((float)stack.getCount() / slots.size());
|
||||||
case 1 -> 1;
|
case 1 -> 1;
|
||||||
@@ -319,7 +319,7 @@ index 9d8ab94f84f4523a2562f9eeb3410554e4269e46..87d1cf9ddfb3124069ff3ff921f2e625
|
|||||||
default -> stack.getCount();
|
default -> stack.getCount();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -897,7 +904,7 @@ public abstract class AbstractContainerMenu {
|
@@ -902,7 +909,7 @@ public abstract class AbstractContainerMenu {
|
||||||
for (int i = 0; i < container.getContainerSize(); i++) {
|
for (int i = 0; i < container.getContainerSize(); i++) {
|
||||||
ItemStack item = container.getItem(i);
|
ItemStack item = container.getItem(i);
|
||||||
if (!item.isEmpty()) {
|
if (!item.isEmpty()) {
|
||||||
@@ -355,10 +355,10 @@ index 5ceb8964476b40db4511bec91ff13c4f522a1357..f416d7976e41a06b5a8be93485eaa233
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
|
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
|
||||||
index 6154da1158756cff072d7e8cae10e20eafed1eec..93bbe7b473b8150954f06602a9f311867fe9a550 100644
|
index 33c3a5e39e8e1aa023baab76ef94f8aed481480e..a27e1d53abc2d8b8912226add33510067e10ed52 100644
|
||||||
--- a/net/minecraft/world/item/ItemStack.java
|
--- a/net/minecraft/world/item/ItemStack.java
|
||||||
+++ b/net/minecraft/world/item/ItemStack.java
|
+++ b/net/minecraft/world/item/ItemStack.java
|
||||||
@@ -162,7 +162,7 @@ public final class ItemStack implements DataComponentHolder {
|
@@ -166,7 +166,7 @@ public final class ItemStack implements DataComponentHolder, ChangePublisher<net
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@Nullable
|
@Nullable
|
||||||
private Item item;
|
private Item item;
|
||||||
@@ -367,7 +367,7 @@ index 6154da1158756cff072d7e8cae10e20eafed1eec..93bbe7b473b8150954f06602a9f31186
|
|||||||
@Nullable
|
@Nullable
|
||||||
private Entity entityRepresentation;
|
private Entity entityRepresentation;
|
||||||
|
|
||||||
@@ -189,7 +189,8 @@ public final class ItemStack implements DataComponentHolder {
|
@@ -193,7 +193,8 @@ public final class ItemStack implements DataComponentHolder, ChangePublisher<net
|
||||||
} else {
|
} else {
|
||||||
Holder<Item> holder = Item.STREAM_CODEC.decode(buffer);
|
Holder<Item> holder = Item.STREAM_CODEC.decode(buffer);
|
||||||
DataComponentPatch dataComponentPatch = codec.decode(buffer);
|
DataComponentPatch dataComponentPatch = codec.decode(buffer);
|
||||||
@@ -377,7 +377,7 @@ index 6154da1158756cff072d7e8cae10e20eafed1eec..93bbe7b473b8150954f06602a9f31186
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,13 +199,15 @@ public final class ItemStack implements DataComponentHolder {
|
@@ -202,13 +203,15 @@ public final class ItemStack implements DataComponentHolder, ChangePublisher<net
|
||||||
if (value.isEmpty() || value.getItem() == null) { // CraftBukkit - NPE fix itemstack.getItem()
|
if (value.isEmpty() || value.getItem() == null) { // CraftBukkit - NPE fix itemstack.getItem()
|
||||||
buffer.writeVarInt(0);
|
buffer.writeVarInt(0);
|
||||||
} else {
|
} else {
|
||||||
@@ -397,7 +397,7 @@ index 6154da1158756cff072d7e8cae10e20eafed1eec..93bbe7b473b8150954f06602a9f31186
|
|||||||
} finally {
|
} finally {
|
||||||
net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(prev);
|
net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(prev);
|
||||||
}
|
}
|
||||||
@@ -299,7 +302,7 @@ public final class ItemStack implements DataComponentHolder {
|
@@ -303,7 +306,7 @@ public final class ItemStack implements DataComponentHolder, ChangePublisher<net
|
||||||
|
|
||||||
for (ItemStack itemStack : itemContainerContents.nonEmptyItems()) {
|
for (ItemStack itemStack : itemContainerContents.nonEmptyItems()) {
|
||||||
int count = itemStack.getCount();
|
int count = itemStack.getCount();
|
||||||
@@ -420,10 +420,10 @@ index 38b03c7b02bdfc579e5e126c12de3d878e26d188..caf31218a1aff84367da126ee1dc46b8
|
|||||||
org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack);
|
org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack);
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
diff --git a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||||
index 36a72a11d28f99bfe85868461925b778cc01478e..2a9f204a514d697178fb3ffac25aece0024f0347 100644
|
index d7a211220d5eba7e34b9083f06f39e9527962599..cef2d6d9a42ae36d6e2a0b31685a7738d2a400cf 100644
|
||||||
--- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
--- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||||
+++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
+++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||||
@@ -409,7 +409,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
@@ -411,7 +411,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||||
ItemStack itemStack = this.items.get(index);
|
ItemStack itemStack = this.items.get(index);
|
||||||
boolean flag = !stack.isEmpty() && ItemStack.isSameItemSameComponents(itemStack, stack);
|
boolean flag = !stack.isEmpty() && ItemStack.isSameItemSameComponents(itemStack, stack);
|
||||||
this.items.set(index, stack);
|
this.items.set(index, stack);
|
||||||
@@ -433,10 +433,10 @@ index 36a72a11d28f99bfe85868461925b778cc01478e..2a9f204a514d697178fb3ffac25aece0
|
|||||||
this.cookingTotalTime = getTotalCookTime(serverLevel, this, this.recipeType, this.cookSpeedMultiplier); // Paper - cook speed multiplier API
|
this.cookingTotalTime = getTotalCookTime(serverLevel, this, this.recipeType, this.cookSpeedMultiplier); // Paper - cook speed multiplier API
|
||||||
this.cookingTimer = 0;
|
this.cookingTimer = 0;
|
||||||
diff --git a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
diff --git a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||||
index 5a094257a31f0500278a706a418e1697f8810ffb..63d6a43dab067aa4c8fb67095c455130196eef9f 100644
|
index 10b2cc20bbf3b70e4e09dbbe14b90506e6366158..1535bb8cec8692e8d26eaff090288f1b8f75c253 100644
|
||||||
--- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
--- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||||
+++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
+++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||||
@@ -145,7 +145,7 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co
|
@@ -155,7 +155,7 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co
|
||||||
@Override
|
@Override
|
||||||
public void setItem(int slot, ItemStack stack) {
|
public void setItem(int slot, ItemStack stack) {
|
||||||
this.getItems().set(slot, stack);
|
this.getItems().set(slot, stack);
|
||||||
@@ -446,10 +446,10 @@ index 5a094257a31f0500278a706a418e1697f8810ffb..63d6a43dab067aa4c8fb67095c455130
|
|||||||
}
|
}
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||||
index 5de769e7bd56bb3355c3c711d46ce5e103ea4409..8ba900fda7cce45679cde2b8b3272654129135ca 100644
|
index b939c04e954e873cbf60fbe104a3b1ec963d1534..11519e11ffc8268ecd059bb8077600be8537a8e0 100644
|
||||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||||
@@ -123,7 +123,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
@@ -145,7 +145,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||||
public void setItem(int index, ItemStack stack) {
|
public void setItem(int index, ItemStack stack) {
|
||||||
this.unpackLootTable(null);
|
this.unpackLootTable(null);
|
||||||
this.getItems().set(index, stack);
|
this.getItems().set(index, stack);
|
||||||
@@ -458,7 +458,7 @@ index 5de769e7bd56bb3355c3c711d46ce5e103ea4409..8ba900fda7cce45679cde2b8b3272654
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -690,9 +690,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
@@ -743,9 +743,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||||
if (item.isEmpty()) {
|
if (item.isEmpty()) {
|
||||||
// Spigot start - SPIGOT-6693, SimpleContainer#setItem
|
// Spigot start - SPIGOT-6693, SimpleContainer#setItem
|
||||||
ItemStack leftover = ItemStack.EMPTY; // Paper - Make hoppers respect inventory max stack size
|
ItemStack leftover = ItemStack.EMPTY; // Paper - Make hoppers respect inventory max stack size
|
||||||
@@ -469,4 +469,4 @@ index 5de769e7bd56bb3355c3c711d46ce5e103ea4409..8ba900fda7cce45679cde2b8b3272654
|
|||||||
+ stack = stack.split(Math.min(destination.getMaxStackSize(), stack.getMaxStackSize())); // Leaves - item over-stack util
|
+ stack = stack.split(Math.min(destination.getMaxStackSize(), stack.getMaxStackSize())); // Leaves - item over-stack util
|
||||||
}
|
}
|
||||||
// Spigot end
|
// Spigot end
|
||||||
IGNORE_TILE_UPDATES.set(Boolean.TRUE); // Paper - Perf: Optimize Hoppers // Folia - region threading
|
//IGNORE_TILE_UPDATES.set(Boolean.TRUE); // Paper - Perf: Optimize Hoppers // Folia - region threading // Luminol - Use vanilla hopper logic
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
|
||||||
Date: Sun, 27 Jul 2025 13:48:10 +0800
|
|
||||||
Subject: [PATCH] Leaves: Disable packet limit
|
|
||||||
|
|
||||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
|
||||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/6a2b9ee6b330cd18b0a8eb2a824d561fa76012bb/leaves-server/minecraft-patches/features/0043-Disable-packet-limit.patch)
|
|
||||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
|
|
||||||
index 9c7366fce56f2c8105c2e5b48f8d618e028f2604..7ab1d97081ffa8cd7ce69cf3165a312697f1fdbc 100644
|
|
||||||
--- a/net/minecraft/network/Connection.java
|
|
||||||
+++ b/net/minecraft/network/Connection.java
|
|
||||||
@@ -281,8 +281,8 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
|
||||||
if (this.stopReadingPackets) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
- if (this.allPacketCounts != null ||
|
|
||||||
- io.papermc.paper.configuration.GlobalConfiguration.get().packetLimiter.overrides.containsKey(packet.getClass())) {
|
|
||||||
+ if (!fun.bm.lophine.config.modules.optimizations.NetworkConfig.disablePacketLimit && (this.allPacketCounts != null || // Leaves - can disable
|
|
||||||
+ io.papermc.paper.configuration.GlobalConfiguration.get().packetLimiter.overrides.containsKey(packet.getClass()))) { // Leaves - can disable
|
|
||||||
long time = System.nanoTime();
|
|
||||||
synchronized (PACKET_LIMIT_LOCK) {
|
|
||||||
if (this.allPacketCounts != null) {
|
|
||||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
||||||
index 227f0c315582b9c499915bebfb820049839466e6..1d52376f034dc5690e8b399512146b47b92c3c14 100644
|
|
||||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
||||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
||||||
@@ -856,7 +856,7 @@ public class ServerGamePacketListenerImpl
|
|
||||||
public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) {
|
|
||||||
// PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); // Paper - AsyncTabCompleteEvent; run this async
|
|
||||||
// CraftBukkit start
|
|
||||||
- if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - configurable tab spam limits
|
|
||||||
+ if (!fun.bm.lophine.config.modules.optimizations.NetworkConfig.disablePacketLimit && !this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - configurable tab spam limits // Leaves - can disable
|
|
||||||
this.disconnectAsync(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - Kick event cause // Paper - add proper async disconnect
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
@@ -2047,6 +2047,7 @@ public class ServerGamePacketListenerImpl
|
|
||||||
private static int getSpamThreshold() { return io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.incomingPacketThreshold; } // Paper - Configurable threshold
|
|
||||||
|
|
||||||
private boolean checkLimit(long timestamp) {
|
|
||||||
+ if (fun.bm.lophine.config.modules.optimizations.NetworkConfig.disablePacketLimit) return true; // Leaves - disable
|
|
||||||
if (this.lastLimitedPacket != -1 && timestamp - this.lastLimitedPacket < getSpamThreshold() && this.limitedPackets++ >= 8) { // Paper - Configurable threshold; raise packet limit to 8
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@@ -2586,6 +2587,7 @@ public class ServerGamePacketListenerImpl
|
|
||||||
|
|
||||||
// Spigot start - spam exclusions
|
|
||||||
private void detectRateSpam(String message) {
|
|
||||||
+ if (fun.bm.lophine.config.modules.optimizations.NetworkConfig.disablePacketLimit) return; // Leaves - disable
|
|
||||||
// CraftBukkit start - replaced with thread safe throttle
|
|
||||||
if (org.spigotmc.SpigotConfig.enableSpamExclusions) {
|
|
||||||
for (String exclude : org.spigotmc.SpigotConfig.spamExclusions) {
|
|
||||||
@@ -3335,7 +3337,7 @@ public class ServerGamePacketListenerImpl
|
|
||||||
@Override
|
|
||||||
public void handlePlaceRecipe(ServerboundPlaceRecipePacket packet) {
|
|
||||||
// Paper start - auto recipe limit
|
|
||||||
- if (!org.bukkit.Bukkit.isPrimaryThread()) {
|
|
||||||
+ if (!fun.bm.lophine.config.modules.optimizations.NetworkConfig.disablePacketLimit && !org.bukkit.Bukkit.isPrimaryThread()) { // Leaves - can disable
|
|
||||||
if (!this.recipeSpamPackets.isIncrementAndUnderThreshold()) {
|
|
||||||
this.disconnectAsync(net.minecraft.network.chat.Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause // Paper - add proper async disconnect
|
|
||||||
return;
|
|
||||||
+3
-3
@@ -1,21 +1,21 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||||
Date: Mon, 7 Jul 2025 15:33:57 +0800
|
Date: Mon, 7 Jul 2025 15:33:57 +0800
|
||||||
Subject: [PATCH] Old Explosion Damage Calculator
|
Subject: [PATCH] Leaves: Old Explosion Damage Calculator
|
||||||
|
|
||||||
Co-authored by: MC_XiaoHei <xor7xiaohei@gmail.com>
|
Co-authored by: MC_XiaoHei <xor7xiaohei@gmail.com>
|
||||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/3e96b237749a960f297f211d439ffc9ea7fd2381/leaves-server/minecraft-patches/features/0134-Old-wet-tnt-explode-behavior.patch)
|
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/3e96b237749a960f297f211d439ffc9ea7fd2381/leaves-server/minecraft-patches/features/0134-Old-wet-tnt-explode-behavior.patch)
|
||||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java
|
diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java
|
||||||
index b3e897a4afee742b5055d652ad7047a660d8ea04..cf8869fac003c73024634078b2f7b36cddda640e 100644
|
index b3e897a4afee742b5055d652ad7047a660d8ea04..33471f3d0e2cbd54eaf095c19555f8fdaeb55878 100644
|
||||||
--- a/net/minecraft/world/level/ServerExplosion.java
|
--- a/net/minecraft/world/level/ServerExplosion.java
|
||||||
+++ b/net/minecraft/world/level/ServerExplosion.java
|
+++ b/net/minecraft/world/level/ServerExplosion.java
|
||||||
@@ -729,6 +729,7 @@ public class ServerExplosion implements Explosion {
|
@@ -729,6 +729,7 @@ public class ServerExplosion implements Explosion {
|
||||||
public boolean shouldAffectBlocklikeEntities() {
|
public boolean shouldAffectBlocklikeEntities() {
|
||||||
boolean _boolean = this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
|
boolean _boolean = this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
|
||||||
boolean flag = this.source == null || this.source.getType() != EntityType.BREEZE_WIND_CHARGE && this.source.getType() != EntityType.WIND_CHARGE;
|
boolean flag = this.source == null || this.source.getType() != EntityType.BREEZE_WIND_CHARGE && this.source.getType() != EntityType.WIND_CHARGE;
|
||||||
+ if (fun.bm.lophine.config.modules.misc.OldFeatureConfig.oldExplosionDamageCalculator) flag = flag && (this.source == null || !this.source.isInWater()); // Leaves - Old MC TNT wet explosion no item damage
|
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldExplosionDamageCalculator) flag = flag && (this.source == null || !this.source.isInWater()); // Leaves - Old MC TNT wet explosion no item damage
|
||||||
return _boolean ? flag : this.blockInteraction.shouldAffectBlocklikeEntities() && flag;
|
return _boolean ? flag : this.blockInteraction.shouldAffectBlocklikeEntities() && flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||||
|
Date: Fri, 11 Apr 2025 16:53:57 +0800
|
||||||
|
Subject: [PATCH] Leaves: Old raid behavior
|
||||||
|
|
||||||
|
Co-authored by: huanli233 <392352840@qq.com>
|
||||||
|
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/79d9ef74c2684eb49060f07e1ab31c827326c9a5/leaves-server/minecraft-patches/features/0106-Old-raid-behavior.patch)
|
||||||
|
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||||
|
|
||||||
|
diff --git a/net/minecraft/world/effect/BadOmenMobEffect.java b/net/minecraft/world/effect/BadOmenMobEffect.java
|
||||||
|
index 80f17f33f670018240c854df589cf90cdeab6e70..c9af615ff9120c07787f436dbb6024e54e3a498b 100644
|
||||||
|
--- a/net/minecraft/world/effect/BadOmenMobEffect.java
|
||||||
|
+++ b/net/minecraft/world/effect/BadOmenMobEffect.java
|
||||||
|
@@ -22,6 +22,11 @@ class BadOmenMobEffect extends MobEffect {
|
||||||
|
&& !serverPlayer.isSpectator()
|
||||||
|
&& level.getDifficulty() != Difficulty.PEACEFUL
|
||||||
|
&& level.isVillage(serverPlayer.blockPosition())) {
|
||||||
|
+ // Leaves start - Revert raid changes
|
||||||
|
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior) {
|
||||||
|
+ return level.getRaids().createOrExtendRaid(serverPlayer, serverPlayer.blockPosition()) == null;
|
||||||
|
+ }
|
||||||
|
+ // Leaves end - Revert raid changes
|
||||||
|
Raid raidAt = level.getRaidAt(serverPlayer.blockPosition());
|
||||||
|
if (raidAt == null || raidAt.getRaidOmenLevel() < raidAt.getMaxRaidOmenLevel()) {
|
||||||
|
serverPlayer.addEffect(new MobEffectInstance(MobEffects.RAID_OMEN, 600, amplifier));
|
||||||
|
diff --git a/net/minecraft/world/entity/raid/Raid.java b/net/minecraft/world/entity/raid/Raid.java
|
||||||
|
index 1910bff3f08147bfd63703097e30b9f88c84e337..f45aa44a7a17946aeb406a447f18de34320a4fa2 100644
|
||||||
|
--- a/net/minecraft/world/entity/raid/Raid.java
|
||||||
|
+++ b/net/minecraft/world/entity/raid/Raid.java
|
||||||
|
@@ -263,7 +263,7 @@ public class Raid {
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean absorbRaidOmen(ServerPlayer player) {
|
||||||
|
- MobEffectInstance effect = player.getEffect(MobEffects.RAID_OMEN);
|
||||||
|
+ MobEffectInstance effect = player.getEffect(fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior ? MobEffects.BAD_OMEN : MobEffects.RAID_OMEN); // Leaves - old Raid Behavior
|
||||||
|
if (effect == null) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
@@ -340,7 +340,13 @@ public class Raid {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag1) {
|
||||||
|
- this.waveSpawnPos = this.getValidSpawnPos(level);
|
||||||
|
+ // Leaves Start - old FindSpawnPosition
|
||||||
|
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior) {
|
||||||
|
+ this.waveSpawnPos = this.preCalcRavagerSpawnLocation(level, this.raidCooldownTicks < 100 ? 1 : 0);
|
||||||
|
+ } else {
|
||||||
|
+ this.waveSpawnPos = this.getValidSpawnPos(level);
|
||||||
|
+ }
|
||||||
|
+ // Leaves End - old FindSpawnPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.raidCooldownTicks == 300 || this.raidCooldownTicks % 20 == 0) {
|
||||||
|
@@ -375,7 +381,14 @@ public class Raid {
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (this.shouldSpawnGroup()) {
|
||||||
|
- BlockPos blockPos = this.waveSpawnPos.orElseGet(() -> this.findRandomSpawnPos(level, 20));
|
||||||
|
+ // Leaves Start - old FindSpawnPosition
|
||||||
|
+ BlockPos blockPos;
|
||||||
|
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior) {
|
||||||
|
+ blockPos = this.getRavagerSpawnLocation(level, i, 20);
|
||||||
|
+ } else {
|
||||||
|
+ blockPos = this.waveSpawnPos.orElseGet(() -> this.findRandomSpawnPos(level, 20));
|
||||||
|
+ }
|
||||||
|
+ // Leaves End - old FindSpawnPosition
|
||||||
|
if (blockPos != null) {
|
||||||
|
this.started = true;
|
||||||
|
this.spawnGroup(level, blockPos);
|
||||||
|
@@ -387,7 +400,7 @@ public class Raid {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (i > 5) {
|
||||||
|
+ if (i > (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior ? 3 : 5)) { // Leaves - old FindSpawnPosition
|
||||||
|
org.bukkit.craftbukkit.event.CraftEventFactory.callRaidStopEvent(level, this, org.bukkit.event.raid.RaidStopEvent.Reason.UNSPAWNABLE); // CraftBukkit
|
||||||
|
this.stop();
|
||||||
|
break;
|
||||||
|
@@ -683,7 +696,7 @@ public class Raid {
|
||||||
|
int i2 = this.center.getX() + Mth.floor(Mth.cos(f2) * 32.0F * f) + level.random.nextInt(3) * Mth.floor(f);
|
||||||
|
int i3 = this.center.getZ() + Mth.floor(Mth.sin(f2) * 32.0F * f) + level.random.nextInt(3) * Mth.floor(f);
|
||||||
|
int height = level.getHeight(Heightmap.Types.WORLD_SURFACE, i2, i3);
|
||||||
|
- if (Mth.abs(height - this.center.getY()) <= 96) {
|
||||||
|
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior || Mth.abs(height - this.center.getY()) <= 96) { // Leaves - skippable
|
||||||
|
mutableBlockPos.set(i2, height, i3);
|
||||||
|
if (!level.isVillage(mutableBlockPos) || i <= 7) {
|
||||||
|
int i4 = 10;
|
||||||
|
@@ -702,6 +715,36 @@ public class Raid {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Leaves Start - old FindSpawnPosition
|
||||||
|
+ @Nullable
|
||||||
|
+ private BlockPos findRandomSpawnPos(ServerLevel level, int n, int n2) {
|
||||||
|
+ int n3 = 2 - n;
|
||||||
|
+ BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
|
||||||
|
+ SpawnPlacementType spawnPlacementType = SpawnPlacements.getPlacementType(EntityType.RAVAGER);
|
||||||
|
+ for (int i = 0; i < n2; ++i) {
|
||||||
|
+ float f = level.random.nextFloat() * ((float)Math.PI * 2);
|
||||||
|
+ int n4 = this.center.getX() + Mth.floor(Mth.cos(f) * 32.0f * (float)n3) + level.random.nextInt(5);
|
||||||
|
+ int n5 = this.center.getZ() + Mth.floor(Mth.sin(f) * 32.0f * (float)n3) + level.random.nextInt(5);
|
||||||
|
+ int n6 = level.getHeight(Heightmap.Types.WORLD_SURFACE, n4, n5);
|
||||||
|
+ mutableBlockPos.set(n4, n6, n5);
|
||||||
|
+ if (level.isVillage(mutableBlockPos) && n < 2) continue;
|
||||||
|
+ if (!level.hasChunksAt(mutableBlockPos.getX() - 10, mutableBlockPos.getZ() - 10, mutableBlockPos.getX() + 10, mutableBlockPos.getZ() + 10) || !level.isPositionEntityTicking(mutableBlockPos) || !spawnPlacementType.isSpawnPositionOk(level, mutableBlockPos, EntityType.RAVAGER) && (!level.getBlockState((BlockPos)mutableBlockPos.below()).is(Blocks.SNOW) || !level.getBlockState(mutableBlockPos).isAir())) continue;
|
||||||
|
+ return mutableBlockPos;
|
||||||
|
+ }
|
||||||
|
+ return null;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private Optional<BlockPos> getValidSpawnPos(ServerLevel level, int n) {
|
||||||
|
+ for (int i = 0; i < 3; ++i) {
|
||||||
|
+ BlockPos blockPos = this.findRandomSpawnPos(level, n, 1);
|
||||||
|
+ if (blockPos == null) continue;
|
||||||
|
+ return Optional.of(blockPos);
|
||||||
|
+ }
|
||||||
|
+ return Optional.empty();
|
||||||
|
+ }
|
||||||
|
+ // Leaves End - old FindSpawnPosition
|
||||||
|
+
|
||||||
|
+
|
||||||
|
private boolean addWaveMob(ServerLevel level, int wave, Raider raider) {
|
||||||
|
// Folia start - make raids thread-safe
|
||||||
|
if (!this.ownsRaid(level)) {
|
||||||
|
@@ -864,4 +907,43 @@ public class Raid {
|
||||||
|
this.spawnsPerWaveBeforeBonus = spawnsPerWaveBeforeBonus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Leaves start - old FindSpawnPosition
|
||||||
|
+ private BlockPos getRavagerSpawnLocation(ServerLevel serverWorld, int proximity, int tries) {
|
||||||
|
+ int i = proximity == 0 ? 2 : 2 - proximity;
|
||||||
|
+ BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos();
|
||||||
|
+ SpawnPlacementType spawnLocation = SpawnPlacements.getPlacementType(EntityType.RAVAGER);
|
||||||
|
+
|
||||||
|
+ for (int j = 0; j < tries; j++) {
|
||||||
|
+ float f = serverWorld.random.nextFloat() * (float) (Math.PI * 2);
|
||||||
|
+ int k = this.center.getX() + Mth.floor(Mth.cos(f) * 32.0F * (float) i + serverWorld.random.nextInt(5));
|
||||||
|
+ int l = this.center.getZ() + Mth.floor(Mth.sin(f) * 32.0F * (float) i + serverWorld.random.nextInt(5));
|
||||||
|
+ int m = serverWorld.getHeight(Heightmap.Types.WORLD_SURFACE, k, l);
|
||||||
|
+ mutable.set(k, m, l);
|
||||||
|
+
|
||||||
|
+ if (serverWorld.isVillage(mutable) && proximity < 2) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ if (serverWorld.hasChunksAt(mutable.getX() - 10, mutable.getZ() - 10, mutable.getX() + 10, mutable.getZ() + 10)
|
||||||
|
+ && serverWorld.isPositionEntityTicking(mutable)
|
||||||
|
+ && (spawnLocation.isSpawnPositionOk(serverWorld, mutable, EntityType.RAVAGER)
|
||||||
|
+ || serverWorld.getBlockState(mutable.below()).is(Blocks.SNOW)
|
||||||
|
+ && serverWorld.getBlockState(mutable).isAir())
|
||||||
|
+ ) {
|
||||||
|
+ return mutable;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return null;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private Optional<BlockPos> preCalcRavagerSpawnLocation(ServerLevel serverWorld, int proximity) {
|
||||||
|
+ for (int i = 0; i < 3; i++) {
|
||||||
|
+ BlockPos blockPos = this.getRavagerSpawnLocation(serverWorld, proximity, 1);
|
||||||
|
+ if (blockPos != null) {
|
||||||
|
+ return Optional.of(blockPos);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return Optional.empty();
|
||||||
|
+ }
|
||||||
|
+ // Leaves end - old FindSpawnPosition
|
||||||
|
}
|
||||||
|
diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java
|
||||||
|
index 3e30989c99cd11c8c94d6fd194d2969e3a7efda6..2d163f3d5eb1af4d539d24c0256855bbec960de4 100644
|
||||||
|
--- a/net/minecraft/world/entity/raid/Raider.java
|
||||||
|
+++ b/net/minecraft/world/entity/raid/Raider.java
|
||||||
|
@@ -128,6 +128,43 @@ public abstract class Raider extends PatrollingMonster {
|
||||||
|
|
||||||
|
currentRaid.removeFromRaid(serverLevel, this, false);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Leaves start - Revert raid changes
|
||||||
|
+ if (this.level() instanceof ServerLevel) {
|
||||||
|
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior && !this.hasRaid()) {
|
||||||
|
+ ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD);
|
||||||
|
+ net.minecraft.world.entity.player.Player entityhuman = null;
|
||||||
|
+ if (entity instanceof net.minecraft.world.entity.player.Player player) {
|
||||||
|
+ entityhuman = player;
|
||||||
|
+ } else if (entity instanceof net.minecraft.world.entity.animal.wolf.Wolf wolf) {
|
||||||
|
+ LivingEntity entityliving = wolf.getOwner();
|
||||||
|
+ if (wolf.isTame() && entityliving instanceof net.minecraft.world.entity.player.Player player) {
|
||||||
|
+ entityhuman = player;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (entityhuman != null && !itemstack.isEmpty() && this.isCaptain()) {
|
||||||
|
+ net.minecraft.world.effect.MobEffectInstance mobeffect = entityhuman.getEffect(net.minecraft.world.effect.MobEffects.BAD_OMEN);
|
||||||
|
+ int i = 1;
|
||||||
|
+
|
||||||
|
+ if (mobeffect != null) {
|
||||||
|
+ i += mobeffect.getAmplifier();
|
||||||
|
+ entityhuman.removeEffectNoUpdate(net.minecraft.world.effect.MobEffects.BAD_OMEN);
|
||||||
|
+ } else {
|
||||||
|
+ --i;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ i = net.minecraft.util.Mth.clamp(i, 0, 4);
|
||||||
|
+ net.minecraft.world.effect.MobEffectInstance mobeffect1 = new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.BAD_OMEN, 120000, i, false, false, true);
|
||||||
|
+
|
||||||
|
+ if (!serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_DISABLE_RAIDS)) {
|
||||||
|
+ entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN); // CraftBukkit
|
||||||
|
+ }
|
||||||
|
+ this.setPatrolLeader(false);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // Leaves end - Revert raid changes
|
||||||
|
}
|
||||||
|
|
||||||
|
super.die(cause);
|
||||||
+27
-136
@@ -4,150 +4,41 @@ Date: Wed, 23 Jul 2025 20:28:40 +0800
|
|||||||
Subject: [PATCH] Leaves: Redstone Shears Wrench
|
Subject: [PATCH] Leaves: Redstone Shears Wrench
|
||||||
|
|
||||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/bfde470a867b74d177fe1b9a2a3ed5c49cd126c7/leaves-server/minecraft-patches/features/0009-Redstone-Shears-Wrench.patch)
|
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/79d9ef74c2684eb49060f07e1ab31c827326c9a5/leaves-server/minecraft-patches/features/0009-Redstone-Shears-Wrench.patch)
|
||||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||||
|
|
||||||
|
diff --git a/net/minecraft/world/item/BlockItem.java b/net/minecraft/world/item/BlockItem.java
|
||||||
|
index 6db566adf2d0df1d26221eda04aa01738df6d3d2..24ebfdf98e343a7892af621d032c35819156deec 100644
|
||||||
|
--- a/net/minecraft/world/item/BlockItem.java
|
||||||
|
+++ b/net/minecraft/world/item/BlockItem.java
|
||||||
|
@@ -56,6 +56,14 @@ public class BlockItem extends Item {
|
||||||
|
if (blockPlaceContext == null) {
|
||||||
|
return InteractionResult.FAIL;
|
||||||
|
} else {
|
||||||
|
+ // Leaves start - shears wrench
|
||||||
|
+ if (org.leavesmc.leaves.util.ShearsWrenchUtil.shouldSkipPlace(context)) {
|
||||||
|
+ if (context.getPlayer() != null) {
|
||||||
|
+ context.getPlayer().containerMenu.forceHeldSlot(blockPlaceContext.getHand());
|
||||||
|
+ }
|
||||||
|
+ return InteractionResult.FAIL;
|
||||||
|
+ }
|
||||||
|
+ // Leaves end - shears wrench
|
||||||
|
BlockState placementState = this.getPlacementState(blockPlaceContext);
|
||||||
|
// CraftBukkit start - special case for handling block placement with water lilies and snow buckets
|
||||||
|
org.bukkit.block.BlockState bukkitState = null;
|
||||||
diff --git a/net/minecraft/world/item/ShearsItem.java b/net/minecraft/world/item/ShearsItem.java
|
diff --git a/net/minecraft/world/item/ShearsItem.java b/net/minecraft/world/item/ShearsItem.java
|
||||||
index 8cf3e51e12f9cf98836657e722edb23943f9e866..155693a18bb641a930a000bc9b1ccfc853e1bae5 100644
|
index 8cf3e51e12f9cf98836657e722edb23943f9e866..5fd5e9fd4e1a79dd1a9d62a5cf0c308805979420 100644
|
||||||
--- a/net/minecraft/world/item/ShearsItem.java
|
--- a/net/minecraft/world/item/ShearsItem.java
|
||||||
+++ b/net/minecraft/world/item/ShearsItem.java
|
+++ b/net/minecraft/world/item/ShearsItem.java
|
||||||
@@ -24,6 +24,30 @@ import net.minecraft.world.level.block.GrowingPlantHeadBlock;
|
@@ -80,7 +80,10 @@ public class ShearsItem extends Item {
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.gameevent.GameEvent;
|
|
||||||
|
|
||||||
+// Leaves start - shears wrench
|
|
||||||
+import net.minecraft.Util;
|
|
||||||
+import net.minecraft.network.chat.Component;
|
|
||||||
+import net.minecraft.world.level.block.ComparatorBlock;
|
|
||||||
+import net.minecraft.world.level.block.DispenserBlock;
|
|
||||||
+import net.minecraft.world.level.block.HopperBlock;
|
|
||||||
+import net.minecraft.world.level.block.ObserverBlock;
|
|
||||||
+import net.minecraft.world.level.block.RepeaterBlock;
|
|
||||||
+import net.minecraft.world.level.block.CrafterBlock;
|
|
||||||
+import net.minecraft.world.level.block.LeverBlock;
|
|
||||||
+import net.minecraft.world.level.block.CocoaBlock;
|
|
||||||
+import net.minecraft.world.level.block.TrapDoorBlock;
|
|
||||||
+import net.minecraft.world.level.block.FenceGateBlock;
|
|
||||||
+import net.minecraft.world.level.block.LightningRodBlock;
|
|
||||||
+import net.minecraft.world.level.block.RailBlock;
|
|
||||||
+import net.minecraft.world.level.block.BaseRailBlock;
|
|
||||||
+import net.minecraft.world.level.block.PoweredRailBlock;
|
|
||||||
+import net.minecraft.world.level.block.CalibratedSculkSensorBlock;
|
|
||||||
+import net.minecraft.world.level.block.piston.PistonBaseBlock;
|
|
||||||
+import net.minecraft.world.level.block.state.StateDefinition;
|
|
||||||
+import net.minecraft.world.level.block.state.properties.RailShape;
|
|
||||||
+import net.minecraft.world.level.block.state.properties.Property;
|
|
||||||
+// Leaves end - shears wrench
|
|
||||||
+
|
|
||||||
public class ShearsItem extends Item {
|
|
||||||
public ShearsItem(Item.Properties properties) {
|
|
||||||
super(properties);
|
|
||||||
@@ -80,7 +104,108 @@ public class ShearsItem extends Item {
|
|
||||||
|
|
||||||
return InteractionResult.SUCCESS;
|
return InteractionResult.SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
|
- return super.useOn(context);
|
||||||
+ // Leaves start - shears wrench
|
+ // Leaves start - shears wrench
|
||||||
+ Block block = blockState.getBlock();
|
+ InteractionResult result = org.leavesmc.leaves.util.ShearsWrenchUtil.tryApplyRotate(context, blockState);
|
||||||
+ if (fun.bm.lophine.config.modules.misc.RedStoneConfig.shears && (
|
+ return result == null ? super.useOn(context) : result;
|
||||||
+ block instanceof ObserverBlock ||
|
|
||||||
+ block instanceof DispenserBlock ||
|
|
||||||
+ block instanceof PistonBaseBlock ||
|
|
||||||
+ block instanceof HopperBlock ||
|
|
||||||
+ block instanceof RepeaterBlock ||
|
|
||||||
+ block instanceof ComparatorBlock ||
|
|
||||||
+ block instanceof CrafterBlock ||
|
|
||||||
+ block instanceof LeverBlock ||
|
|
||||||
+ block instanceof CocoaBlock ||
|
|
||||||
+ block instanceof TrapDoorBlock ||
|
|
||||||
+ block instanceof FenceGateBlock ||
|
|
||||||
+ block instanceof LightningRodBlock ||
|
|
||||||
+ block instanceof CalibratedSculkSensorBlock ||
|
|
||||||
+ block instanceof BaseRailBlock
|
|
||||||
+ )) {
|
|
||||||
+ StateDefinition<Block, BlockState> blockstatelist = block.getStateDefinition();
|
|
||||||
+ Property<?> iblockstate;
|
|
||||||
+ if (block instanceof CrafterBlock) iblockstate = blockstatelist.getProperty("orientation");
|
|
||||||
+ else if (block instanceof BaseRailBlock) iblockstate = blockstatelist.getProperty("shape");
|
|
||||||
+ else iblockstate = blockstatelist.getProperty("facing");
|
|
||||||
+ Player player = context.getPlayer();
|
|
||||||
+
|
|
||||||
+ if (iblockstate == null || player == null) {
|
|
||||||
+ return InteractionResult.FAIL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (block instanceof BaseRailBlock) {
|
|
||||||
+ if (block instanceof RailBlock) {
|
|
||||||
+ if (blockState.getValue(RailBlock.SHAPE).isSlope()) {
|
|
||||||
+ return InteractionResult.FAIL;
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ if (getNameHelper(blockState, PoweredRailBlock.POWERED).equals("true")) {
|
|
||||||
+ return InteractionResult.FAIL;
|
|
||||||
+ }
|
|
||||||
+ if (blockState.getValue(PoweredRailBlock.SHAPE).isSlope()) {
|
|
||||||
+ return InteractionResult.FAIL;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (block instanceof PistonBaseBlock) {
|
|
||||||
+ if (getNameHelper(blockState, PistonBaseBlock.EXTENDED).equals("true")) {
|
|
||||||
+ return InteractionResult.FAIL;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (block instanceof RepeaterBlock || block instanceof ComparatorBlock) {
|
|
||||||
+ if (getNameHelper(blockState, ComparatorBlock.POWERED).equals("true")) {
|
|
||||||
+ return InteractionResult.FAIL;
|
|
||||||
+ }
|
|
||||||
+ if (block instanceof RepeaterBlock) {
|
|
||||||
+ if (getNameHelper(blockState, RepeaterBlock.LOCKED).equals("true")) {
|
|
||||||
+ return InteractionResult.FAIL;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (block instanceof CrafterBlock) {
|
|
||||||
+ if (getNameHelper(blockState, CrafterBlock.CRAFTING).equals("true")) {
|
|
||||||
+ return InteractionResult.FAIL;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ BlockState iblockdata1 = ShearsItem.cycleState(blockState, iblockstate, player.isSecondaryUseActive());
|
|
||||||
+ level.setBlock(clickedPos, iblockdata1, 18);
|
|
||||||
+ ShearsItem.message(player, Component.translatable("item.minecraft.debug_stick.update", iblockstate.getName(), ShearsItem.getNameHelper(iblockdata1, iblockstate)));
|
|
||||||
+ return InteractionResult.CONSUME;
|
|
||||||
+ }
|
|
||||||
+ // Leaves end - shears wrench
|
|
||||||
+
|
|
||||||
return super.useOn(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ // Leaves start - shears wrench
|
|
||||||
+ private static <T extends Comparable<T>> BlockState cycleState(BlockState state, Property<T> property, boolean inverse) {
|
|
||||||
+ List<T> possibleValues = property.getPossibleValues();
|
|
||||||
+ if (possibleValues.getFirst() instanceof RailShape) {
|
|
||||||
+ boolean isRailBlock = state.getBlock() instanceof RailBlock;
|
|
||||||
+ possibleValues = possibleValues.stream().filter(possibleValue -> {
|
|
||||||
+ RailShape shape = (RailShape) possibleValue;
|
|
||||||
+ if (isRailBlock) return !shape.isSlope();
|
|
||||||
+ return !shape.isSlope() && shape != RailShape.NORTH_EAST && shape != RailShape.NORTH_WEST && shape != RailShape.SOUTH_EAST && shape != RailShape.SOUTH_WEST;
|
|
||||||
+ }).toList();
|
|
||||||
+ }
|
|
||||||
+ return state.setValue(property, ShearsItem.getRelative(possibleValues, state.getValue(property), inverse)); // CraftBukkit - decompile error
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private static <T> T getRelative(Iterable<T> elements, T current, boolean inverse) {
|
|
||||||
+ return inverse ? Util.findPreviousInIterable(elements, current) : Util.findNextInIterable(elements, current);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private static void message(Player player, Component message) {
|
|
||||||
+ ((ServerPlayer) player).sendSystemMessage(message, true);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private static <T extends Comparable<T>> String getNameHelper(BlockState state, Property<T> property) {
|
|
||||||
+ return property.getName(state.getValue(property));
|
|
||||||
+ }
|
|
||||||
+ // Leaves end - shears wrench
|
+ // Leaves end - shears wrench
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ index d0d90a25a10bbecfffceee1992af88c60d14fd87..187e48e78e69c80b25710f193813335e
|
|||||||
+ // Leaves end - servux
|
+ // Leaves end - servux
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
index 87377bba2ebdc0eba5b7b212d971994c35ca0b62..94d0c7bd2dfc2620a67035ce9084e9da219e6509 100644
|
index eb3aef1f5198592eda5dafe84b91271e861b4135..576dde41a4b48aac9079cca902f4371a31470af3 100644
|
||||||
--- a/net/minecraft/server/level/ServerLevel.java
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
@@ -2368,6 +2368,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
@@ -2368,6 +2368,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
|
||||||
Date: Mon, 28 Jul 2025 01:06:40 +0800
|
|
||||||
Subject: [PATCH] Leaves: Vanilla hopper
|
|
||||||
|
|
||||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
|
||||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/2c9f83c7b99178851edf5608b37b8c2adddd93cd/leaves-server/minecraft-patches/features/0095-Vanilla-hopper.patch)
|
|
||||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
|
||||||
index 8ba900fda7cce45679cde2b8b3272654129135ca..9d7ec9f4f18ed263540ccddf16c6c1a92d3477a4 100644
|
|
||||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
|
||||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
|
||||||
@@ -280,36 +280,49 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
|
||||||
ItemStack movedItem = origItemStack;
|
|
||||||
final int originalItemCount = origItemStack.getCount();
|
|
||||||
final int movedItemCount = Math.min(level.spigotConfig.hopperAmount, originalItemCount);
|
|
||||||
- container.setChanged(); // original logic always marks source inv as changed even if no move happens.
|
|
||||||
- movedItem.setCount(movedItemCount);
|
|
||||||
|
|
||||||
- if (!worldData.skipPullModeEventFire) { // Folia - region threading
|
|
||||||
- movedItem = callPullMoveEvent(hopper, container, movedItem);
|
|
||||||
- if (movedItem == null) { // cancelled
|
|
||||||
+ // Leaves start - fix vanilla
|
|
||||||
+ if (fun.bm.lophine.config.modules.misc.RedStoneConfig.vanillaHopper && movedItem.getCount() <= movedItemCount) {
|
|
||||||
+ movedItem = origItemStack.copy();
|
|
||||||
+ final ItemStack remainingItem = addItem(container, hopper, container.removeItem(i, movedItemCount), null);
|
|
||||||
+ if (remainingItem.isEmpty()) {
|
|
||||||
+ container.setChanged();
|
|
||||||
+ return true;
|
|
||||||
+ }
|
|
||||||
+ container.setItem(i, movedItem);
|
|
||||||
+ } else {
|
|
||||||
+ container.setChanged(); // original logic always marks source inv as changed even if no move happens.
|
|
||||||
+ movedItem.setCount(movedItemCount);
|
|
||||||
+
|
|
||||||
+ if (!worldData.skipPullModeEventFire) {
|
|
||||||
+ movedItem = callPullMoveEvent(hopper, container, movedItem);
|
|
||||||
+ if (movedItem == null) { // cancelled
|
|
||||||
+ origItemStack.setCount(originalItemCount);
|
|
||||||
+ // Drastically improve performance by returning true.
|
|
||||||
+ // No plugin could have relied on the behavior of false as the other call
|
|
||||||
+ // site for IMIE did not exhibit the same behavior
|
|
||||||
+ return true;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ final ItemStack remainingItem = addItem(container, hopper, movedItem, null);
|
|
||||||
+ final int remainingItemCount = remainingItem.getCount();
|
|
||||||
+ if (remainingItemCount != movedItemCount) {
|
|
||||||
+ origItemStack = origItemStack.copy(true);
|
|
||||||
origItemStack.setCount(originalItemCount);
|
|
||||||
- // Drastically improve performance by returning true.
|
|
||||||
- // No plugin could have relied on the behavior of false as the other call
|
|
||||||
- // site for IMIE did not exhibit the same behavior
|
|
||||||
+ if (!origItemStack.isEmpty()) {
|
|
||||||
+ origItemStack.setCount(originalItemCount - movedItemCount + remainingItemCount);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ IGNORE_TILE_UPDATES.set(true);
|
|
||||||
+ container.setItem(i, origItemStack);
|
|
||||||
+ IGNORE_TILE_UPDATES.set(false);
|
|
||||||
+ container.setChanged();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- final ItemStack remainingItem = addItem(container, hopper, movedItem, null);
|
|
||||||
- final int remainingItemCount = remainingItem.getCount();
|
|
||||||
- if (remainingItemCount != movedItemCount) {
|
|
||||||
- origItemStack = origItemStack.copy(true);
|
|
||||||
origItemStack.setCount(originalItemCount);
|
|
||||||
- if (!origItemStack.isEmpty()) {
|
|
||||||
- origItemStack.setCount(originalItemCount - movedItemCount + remainingItemCount);
|
|
||||||
- }
|
|
||||||
|
|
||||||
- IGNORE_TILE_UPDATES.set(true); // Folia - region threading
|
|
||||||
- container.setItem(i, origItemStack);
|
|
||||||
- IGNORE_TILE_UPDATES.set(false); // Folia - region threading
|
|
||||||
- container.setChanged();
|
|
||||||
- return true;
|
|
||||||
}
|
|
||||||
- origItemStack.setCount(originalItemCount);
|
|
||||||
+ // Leaves end - fix vanilla
|
|
||||||
|
|
||||||
if (level.paperConfig().hopper.cooldownWhenFull) {
|
|
||||||
applyCooldown(hopper);
|
|
||||||
+14
-14
@@ -8,7 +8,7 @@ As part of: Purpur (https://github.com/PurpurMC/Purpur/blob/09f547de09fc5d886f18
|
|||||||
Licensed under: MIT (https://github.com/PurpurMC/Purpur/blob/09f547de09fc5d886f18f6d99ff389289766ec9d/LICENSE)
|
Licensed under: MIT (https://github.com/PurpurMC/Purpur/blob/09f547de09fc5d886f18f6d99ff389289766ec9d/LICENSE)
|
||||||
|
|
||||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||||
index 593dbcda4b497291eb1ecdc64b947a8d279f8be6..661f797b39853104b16d75ca7ba0eda156a74af3 100644
|
index 593dbcda4b497291eb1ecdc64b947a8d279f8be6..cb863a36fc67e993956ec3be655e6e4b9764c051 100644
|
||||||
--- a/net/minecraft/server/players/PlayerList.java
|
--- a/net/minecraft/server/players/PlayerList.java
|
||||||
+++ b/net/minecraft/server/players/PlayerList.java
|
+++ b/net/minecraft/server/players/PlayerList.java
|
||||||
@@ -1087,6 +1087,10 @@ public abstract class PlayerList {
|
@@ -1087,6 +1087,10 @@ public abstract class PlayerList {
|
||||||
@@ -17,7 +17,7 @@ index 593dbcda4b497291eb1ecdc64b947a8d279f8be6..661f797b39853104b16d75ca7ba0eda1
|
|||||||
} // Paper - Add sendOpLevel API
|
} // Paper - Add sendOpLevel API
|
||||||
+
|
+
|
||||||
+ // Purpur start - Barrels and enderchests 6 rows
|
+ // Purpur start - Barrels and enderchests 6 rows
|
||||||
+ player.enderChestSlotCount = fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.enderchestRows < 7 && fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.enderchestRows > 0 ? 9 * fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.enderchestRows : 27;
|
+ player.enderChestSlotCount = fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows < 7 && fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows > 0 ? 9 * fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows : 27;
|
||||||
+ // Purpur end - Barrels and enderchests 6 rows
|
+ // Purpur end - Barrels and enderchests 6 rows
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,15 +70,15 @@ index 0fffa384f928ab84451331380968fb4650eafe26..d84a10396395939149da88bcb01be59e
|
|||||||
return new ChestMenu(MenuType.GENERIC_9x6, containerId, playerInventory, container, 6);
|
return new ChestMenu(MenuType.GENERIC_9x6, containerId, playerInventory, container, 6);
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/world/inventory/PlayerEnderChestContainer.java b/net/minecraft/world/inventory/PlayerEnderChestContainer.java
|
diff --git a/net/minecraft/world/inventory/PlayerEnderChestContainer.java b/net/minecraft/world/inventory/PlayerEnderChestContainer.java
|
||||||
index beb74bc8398de8b48f41af7daef14d624826310e..5dd6e89931d397b8afdb84024ed46b0d06dcf347 100644
|
index 51148b7b95c93a9e25da70ac9275c63f1458d84c..dba8acfcacfe9a7b7e0fb9943fba49468214616e 100644
|
||||||
--- a/net/minecraft/world/inventory/PlayerEnderChestContainer.java
|
--- a/net/minecraft/world/inventory/PlayerEnderChestContainer.java
|
||||||
+++ b/net/minecraft/world/inventory/PlayerEnderChestContainer.java
|
+++ b/net/minecraft/world/inventory/PlayerEnderChestContainer.java
|
||||||
@@ -25,11 +25,18 @@ public class PlayerEnderChestContainer extends SimpleContainer {
|
@@ -26,11 +26,18 @@ public class PlayerEnderChestContainer extends SimpleContainer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerEnderChestContainer(Player owner) {
|
public PlayerEnderChestContainer(Player owner) {
|
||||||
- super(27);
|
- super(27);
|
||||||
+ super(fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.enderchestRows < 7 && fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.enderchestRows > 0 ? 9 * fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.enderchestRows : 27);
|
+ super(fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows < 7 && fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows > 0 ? 9 * fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows : 27);
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ index beb74bc8398de8b48f41af7daef14d624826310e..5dd6e89931d397b8afdb84024ed46b0d
|
|||||||
this.activeChest = enderChestBlockEntity;
|
this.activeChest = enderChestBlockEntity;
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/world/level/block/EnderChestBlock.java b/net/minecraft/world/level/block/EnderChestBlock.java
|
diff --git a/net/minecraft/world/level/block/EnderChestBlock.java b/net/minecraft/world/level/block/EnderChestBlock.java
|
||||||
index 5077a9ff7b78801bdc53536a37aee07b8d86ee4d..fe374f08b7829b846b2a1c2ac3ca500ca3e48684 100644
|
index 5077a9ff7b78801bdc53536a37aee07b8d86ee4d..cef29289b7bc7fdf9613c0cd52f2bf4f715f288d 100644
|
||||||
--- a/net/minecraft/world/level/block/EnderChestBlock.java
|
--- a/net/minecraft/world/level/block/EnderChestBlock.java
|
||||||
+++ b/net/minecraft/world/level/block/EnderChestBlock.java
|
+++ b/net/minecraft/world/level/block/EnderChestBlock.java
|
||||||
@@ -85,8 +85,14 @@ public class EnderChestBlock extends AbstractChestBlock<EnderChestBlockEntity> i
|
@@ -85,8 +85,14 @@ public class EnderChestBlock extends AbstractChestBlock<EnderChestBlockEntity> i
|
||||||
@@ -103,7 +103,7 @@ index 5077a9ff7b78801bdc53536a37aee07b8d86ee4d..fe374f08b7829b846b2a1c2ac3ca500c
|
|||||||
new SimpleMenuProvider(
|
new SimpleMenuProvider(
|
||||||
- (containerId, playerInventory, player1) -> ChestMenu.threeRows(containerId, playerInventory, enderChestInventory), CONTAINER_TITLE
|
- (containerId, playerInventory, player1) -> ChestMenu.threeRows(containerId, playerInventory, enderChestInventory), CONTAINER_TITLE
|
||||||
- )
|
- )
|
||||||
+ (containerId, playerInventory, player1) -> switch (fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.enderchestRows) {
|
+ (containerId, playerInventory, player1) -> switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows) {
|
||||||
+ case 6 -> ChestMenu.sixRows(containerId, playerInventory, enderChestInventory);
|
+ case 6 -> ChestMenu.sixRows(containerId, playerInventory, enderChestInventory);
|
||||||
+ case 5 -> ChestMenu.fiveRows(containerId, playerInventory, enderChestInventory);
|
+ case 5 -> ChestMenu.fiveRows(containerId, playerInventory, enderChestInventory);
|
||||||
+ case 4 -> ChestMenu.fourRows(containerId, playerInventory, enderChestInventory);
|
+ case 4 -> ChestMenu.fourRows(containerId, playerInventory, enderChestInventory);
|
||||||
@@ -115,16 +115,16 @@ index 5077a9ff7b78801bdc53536a37aee07b8d86ee4d..fe374f08b7829b846b2a1c2ac3ca500c
|
|||||||
// Paper end - Fix InventoryOpenEvent cancellation - moved up;
|
// Paper end - Fix InventoryOpenEvent cancellation - moved up;
|
||||||
player.awardStat(Stats.OPEN_ENDERCHEST);
|
player.awardStat(Stats.OPEN_ENDERCHEST);
|
||||||
diff --git a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
diff --git a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
||||||
index d679ab599dfd0bdbdc3ab5530d7fcd1c38baf7fa..6b4e2956222a0ca7f72f73032dc98878fbd257ee 100644
|
index de99652629c7301a4bc0e9ec48bed9a26a338f0d..b43445d8313c330a0376aaa4eb872495ebd87b5f 100644
|
||||||
--- a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
--- a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
||||||
+++ b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
+++ b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
||||||
@@ -56,7 +56,17 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
|
@@ -56,7 +56,17 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||||
}
|
}
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
|
|
||||||
- private NonNullList<ItemStack> items = NonNullList.withSize(27, ItemStack.EMPTY);
|
- private NonNullList<ItemStack> items = NonNullList.withSize(27, ItemStack.EMPTY);
|
||||||
+ // Purpur start - Barrels and enderchests 6 rows
|
+ // Purpur start - Barrels and enderchests 6 rows
|
||||||
+ private NonNullList<ItemStack> items = NonNullList.withSize(switch (fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.barrelRows) {
|
+ private NonNullList<ItemStack> items = NonNullList.withSize(switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.barrelRows) {
|
||||||
+ case 6 -> 54;
|
+ case 6 -> 54;
|
||||||
+ case 5 -> 45;
|
+ case 5 -> 45;
|
||||||
+ case 4 -> 36;
|
+ case 4 -> 36;
|
||||||
@@ -137,13 +137,13 @@ index d679ab599dfd0bdbdc3ab5530d7fcd1c38baf7fa..6b4e2956222a0ca7f72f73032dc98878
|
|||||||
public final ContainerOpenersCounter openersCounter = new ContainerOpenersCounter() {
|
public final ContainerOpenersCounter openersCounter = new ContainerOpenersCounter() {
|
||||||
@Override
|
@Override
|
||||||
protected void onOpen(Level level, BlockPos pos, BlockState state) {
|
protected void onOpen(Level level, BlockPos pos, BlockState state) {
|
||||||
@@ -108,7 +118,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
|
@@ -108,7 +118,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getContainerSize() {
|
public int getContainerSize() {
|
||||||
- return 27;
|
- return 27;
|
||||||
+ // Purpur start - Barrels and enderchests 6 rows
|
+ // Purpur start - Barrels and enderchests 6 rows
|
||||||
+ return switch (fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.barrelRows) {
|
+ return switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.barrelRows) {
|
||||||
+ case 6 -> 54;
|
+ case 6 -> 54;
|
||||||
+ case 5 -> 45;
|
+ case 5 -> 45;
|
||||||
+ case 4 -> 36;
|
+ case 4 -> 36;
|
||||||
@@ -155,13 +155,13 @@ index d679ab599dfd0bdbdc3ab5530d7fcd1c38baf7fa..6b4e2956222a0ca7f72f73032dc98878
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -128,7 +147,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
|
@@ -129,7 +148,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AbstractContainerMenu createMenu(int id, Inventory player) {
|
protected AbstractContainerMenu createMenu(int id, Inventory player) {
|
||||||
- return ChestMenu.threeRows(id, player, this);
|
- return ChestMenu.threeRows(id, player, this);
|
||||||
+ // Purpur start - Barrels and enderchests 6 rows
|
+ // Purpur start - Barrels and enderchests 6 rows
|
||||||
+ return switch (fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.barrelRows) {
|
+ return switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.barrelRows) {
|
||||||
+ case 6 -> ChestMenu.sixRows(id, player, this);
|
+ case 6 -> ChestMenu.sixRows(id, player, this);
|
||||||
+ case 5 -> ChestMenu.fiveRows(id, player, this);
|
+ case 5 -> ChestMenu.fiveRows(id, player, this);
|
||||||
+ case 4 -> ChestMenu.fourRows(id, player, this);
|
+ case 4 -> ChestMenu.fourRows(id, player, this);
|
||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||||
|
Date: Fri, 15 Aug 2025 02:29:30 +0800
|
||||||
|
Subject: [PATCH] Compatibility fix for Raid Revert and Cross Region Damage
|
||||||
|
Trace
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||||
|
index 3f4b1c54f9207ba1854a8c8da965cbaca5ea517d..a8348a073682eec31990e9ab963b11ad32cf8bf8 100644
|
||||||
|
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||||
|
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||||
|
@@ -1216,6 +1216,29 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Lophine Start - raid revert adapt Cross Region Damage trace
|
||||||
|
+ public boolean addEffect(MobEffectInstance effectInstance, EntityPotionEffectEvent.Cause cause, boolean fireEvent, boolean async) {
|
||||||
|
+ if (!async || ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(this)) {
|
||||||
|
+ return addEffect(effectInstance, this, cause, fireEvent);
|
||||||
|
+ } else if (fun.bm.lophine.config.modules.experiment.EntityDamageSourceTraceConfig.enabled) {
|
||||||
|
+ postToAddEffect(effectInstance, this, cause, fireEvent);
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private void postToAddEffect(MobEffectInstance effectInstance, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause, boolean fireEvent) {
|
||||||
|
+ if (entity != null)
|
||||||
|
+ entity.getBukkitEntity().taskScheduler.schedule((Entity nmsEntity) -> {
|
||||||
|
+ try {
|
||||||
|
+ addEffect(effectInstance, nmsEntity, cause, fireEvent);
|
||||||
|
+ } catch (Throwable ex) {
|
||||||
|
+ LOGGER.error(ex.getMessage(), ex);
|
||||||
|
+ }
|
||||||
|
+ }, null, 1L );
|
||||||
|
+ }
|
||||||
|
+ // Lophine End - raid revert adapt Cross Region Damage trace
|
||||||
|
+
|
||||||
|
public boolean canBeAffected(MobEffectInstance effectInstance) {
|
||||||
|
if (this.getType().is(EntityTypeTags.IMMUNE_TO_INFESTED)) {
|
||||||
|
return !effectInstance.is(MobEffects.INFESTED);
|
||||||
|
diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java
|
||||||
|
index 2d163f3d5eb1af4d539d24c0256855bbec960de4..2cc0a7b5f088c29d9343b369b6e71c8a3ebdef75 100644
|
||||||
|
--- a/net/minecraft/world/entity/raid/Raider.java
|
||||||
|
+++ b/net/minecraft/world/entity/raid/Raider.java
|
||||||
|
@@ -158,7 +158,7 @@ public abstract class Raider extends PatrollingMonster {
|
||||||
|
net.minecraft.world.effect.MobEffectInstance mobeffect1 = new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.BAD_OMEN, 120000, i, false, false, true);
|
||||||
|
|
||||||
|
if (!serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_DISABLE_RAIDS)) {
|
||||||
|
- entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN); // CraftBukkit
|
||||||
|
+ entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN, true, fun.bm.lophine.config.modules.experiment.EntityDamageSourceTraceConfig.enabled); // Lophine - raid revert adapt Cross Region Damage trace
|
||||||
|
}
|
||||||
|
this.setPatrolLeader(false);
|
||||||
|
}
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
|
||||||
Date: Sat, 2 Aug 2025 12:40:53 +0800
|
|
||||||
Subject: [PATCH] Leaves: Temporarily fix endermite spawn position
|
|
||||||
|
|
||||||
Should be removed when [https://github.com/PaperMC/Paper/pull/12912] merged
|
|
||||||
|
|
||||||
Co-authored by: Lumine1909 <133463833Lumine1909@users.noreply.github.com>
|
|
||||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/4c4712d3304db7e977324b2bd6739f0c4433f80a/leaves-server/minecraft-patches/features/0140-Fix-endermite-spawn-position.patch)
|
|
||||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/entity/projectile/ThrownEnderpearl.java b/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
|
|
||||||
index bded685ed1653e9a1e2d7d4a9c4f68da58a6b06e..7123e56d86db01073e8ea71ccce0f6308070c8ab 100644
|
|
||||||
--- a/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
|
|
||||||
+++ b/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
|
|
||||||
@@ -204,6 +204,9 @@ public class ThrownEnderpearl extends ThrowableItemProjectile {
|
|
||||||
Vec3 vec3 = this.oldPosition();
|
|
||||||
if (owner instanceof ServerPlayer serverPlayer) {
|
|
||||||
if (serverPlayer.connection.isAcceptingMessages()) {
|
|
||||||
+ // Paper start - fix endermite spawn position
|
|
||||||
+ double x = serverPlayer.getX(), y = serverPlayer.getY(), z = serverPlayer.getZ();
|
|
||||||
+ float yaw = serverPlayer.getYRot(), pitch = serverPlayer.getXRot();
|
|
||||||
// CraftBukkit start
|
|
||||||
ServerPlayer serverPlayer1 = serverPlayer.teleport(new TeleportTransition(serverLevel, vec3, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.ROTATION, Relative.DELTA), TeleportTransition.DO_NOTHING, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.ENDER_PEARL));
|
|
||||||
if (serverPlayer1 == null) {
|
|
||||||
@@ -214,7 +217,8 @@ public class ThrownEnderpearl extends ThrowableItemProjectile {
|
|
||||||
if (this.random.nextFloat() < 0.05F && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) {
|
|
||||||
Endermite endermite = EntityType.ENDERMITE.create(serverLevel, EntitySpawnReason.TRIGGERED);
|
|
||||||
if (endermite != null) {
|
|
||||||
- endermite.snapTo(owner.getX(), owner.getY(), owner.getZ(), owner.getYRot(), owner.getXRot());
|
|
||||||
+ endermite.snapTo(x, y, z, yaw, pitch);
|
|
||||||
+ // Paper end - fix endermite spawn position
|
|
||||||
serverLevel.addFreshEntity(endermite, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.ENDER_PEARL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
-1
@@ -5,7 +5,7 @@ Subject: [PATCH] Disable some check for operators
|
|||||||
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||||
index a684f5edf420d9655046de872c54e0c1a89103cf..105675bef05408bd5baf1b6129c0392065bbe79d 100644
|
index f06b9d8ad9512d35f3f460eb77c869690321c67f..e17f9629369f8653b484b4cc71de4874b5faa4d6 100644
|
||||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||||
@@ -367,7 +367,7 @@ public class ServerGamePacketListenerImpl
|
@@ -367,7 +367,7 @@ public class ServerGamePacketListenerImpl
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
|
||||||
Date: Sat, 26 Jul 2025 13:40:28 +0800
|
|
||||||
Subject: [PATCH] Paper: Fix quick craft
|
|
||||||
|
|
||||||
Co-authored by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
|
||||||
As a part of : Paper (https://github.com/PaperMC/Paper/pull/11831/files#diff-3991edc9191addaab9f9701589f8fb4a05001c6f3c9ce1f51d22001f8de805ca)
|
|
||||||
Licensed under: MIT (https://github.com/PaperMC/Paper/blob/main/licenses/MIT.md)
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
|
||||||
index 5369a6597e48ed9f0d8f7f0b9685ce4950df4fe5..919628d93add71d9b30cae29587a0049cce6973d 100644
|
|
||||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
|
||||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
|
||||||
@@ -4012,11 +4012,6 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
double d = this.getEyeY() - 0.3F;
|
|
||||||
- // Paper start
|
|
||||||
- final ItemStack tmp = stack.copy();
|
|
||||||
- stack.setCount(0);
|
|
||||||
- stack = tmp;
|
|
||||||
- // Paper end
|
|
||||||
ItemEntity itemEntity = new ItemEntity(this.level(), this.getX(), d, this.getZ(), stack);
|
|
||||||
itemEntity.setPickUpDelay(40);
|
|
||||||
if (includeThrower) {
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||||
|
Date: Thu, 12 Jun 2025 04:44:24 +0800
|
||||||
|
Subject: [PATCH] I18n support
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/net/minecraft/locale/Language.java b/net/minecraft/locale/Language.java
|
||||||
|
index 7b9e2a1a208b46a69c16e6afd8b502259893574f..db46a31ea8a36562e548eb07f0c4cf9b9e8c3360 100644
|
||||||
|
--- a/net/minecraft/locale/Language.java
|
||||||
|
+++ b/net/minecraft/locale/Language.java
|
||||||
|
@@ -65,7 +65,7 @@ public abstract class Language {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
- private static void parseTranslations(BiConsumer<String, String> output, String languagePath) {
|
||||||
|
+ public static void parseTranslations(BiConsumer<String, String> output, String languagePath) { // Lophine - private -> public
|
||||||
|
try (InputStream resourceAsStream = Language.class.getResourceAsStream(languagePath)) {
|
||||||
|
loadFromJson(resourceAsStream, output);
|
||||||
|
} catch (JsonParseException | IOException var7) {
|
||||||
|
diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java
|
||||||
|
index cf72cb8b418239b56c755486b03a321672e16bc3..b69c06607ca900beeebf4892a978442dad2db19b 100644
|
||||||
|
--- a/net/minecraft/server/Main.java
|
||||||
|
+++ b/net/minecraft/server/Main.java
|
||||||
|
@@ -155,6 +155,8 @@ public class Main {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ fun.bm.lophine.utils.ServerI18nUtil.preInit(); // Lophine - I18n support
|
||||||
|
+
|
||||||
|
// Paper start - Detect headless JRE
|
||||||
|
String awtException = io.papermc.paper.util.ServerEnvironment.awtDependencyCheck();
|
||||||
|
if (awtException != null) {
|
||||||
|
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||||
|
index c93feb64b6088a4878fcdb6e7c733a5f37e9385b..79c911003c7b1c3d94e7e9d3974eeadcc16bde3a 100644
|
||||||
|
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||||
|
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||||
|
@@ -172,6 +172,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||||
|
this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
|
||||||
|
// Paper end - initialize global and world-defaults configuration
|
||||||
|
me.earthme.luminol.config.ConfigManager.loadConfigFiles(); // Luminol - load config file
|
||||||
|
+ fun.bm.lophine.utils.ServerI18nUtil.init(); // Lophine - I18n support
|
||||||
|
if (false) this.server.spark.enableEarlyIfRequested(); // Paper - spark // Luminol - Force disable builtin spark
|
||||||
|
// Paper start - fix converting txt to json file; convert old users earlier after PlayerList creation but before file load/save
|
||||||
|
if (this.convertOldUsers()) {
|
||||||
+2
-2
@@ -5,7 +5,7 @@ Subject: [PATCH] Old zombie reinforcement
|
|||||||
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/entity/monster/Zombie.java b/net/minecraft/world/entity/monster/Zombie.java
|
diff --git a/net/minecraft/world/entity/monster/Zombie.java b/net/minecraft/world/entity/monster/Zombie.java
|
||||||
index 14d0758aca54d9a25e369dfa8c89c930f27946c9..6f1f26b7f759e56f843e674167470da943785728 100644
|
index 14d0758aca54d9a25e369dfa8c89c930f27946c9..1324f2c8c0d6571bac36855f08354a84e0f08b70 100644
|
||||||
--- a/net/minecraft/world/entity/monster/Zombie.java
|
--- a/net/minecraft/world/entity/monster/Zombie.java
|
||||||
+++ b/net/minecraft/world/entity/monster/Zombie.java
|
+++ b/net/minecraft/world/entity/monster/Zombie.java
|
||||||
@@ -341,7 +341,7 @@ public class Zombie extends Monster {
|
@@ -341,7 +341,7 @@ public class Zombie extends Monster {
|
||||||
@@ -13,7 +13,7 @@ index 14d0758aca54d9a25e369dfa8c89c930f27946c9..6f1f26b7f759e56f843e674167470da9
|
|||||||
int floor1 = Mth.floor(this.getY());
|
int floor1 = Mth.floor(this.getY());
|
||||||
int floor2 = Mth.floor(this.getZ());
|
int floor2 = Mth.floor(this.getZ());
|
||||||
- EntityType<? extends Zombie> type = this.getType();
|
- EntityType<? extends Zombie> type = this.getType();
|
||||||
+ EntityType<? extends Zombie> type = fun.bm.lophine.config.modules.misc.OldFeatureConfig.oldZombieReinforcement ? EntityType.ZOMBIE : this.getType(); // Lophine - old zombie reinforcement
|
+ EntityType<? extends Zombie> type = fun.bm.lophine.config.modules.function.OldFeatureConfig.oldZombieReinforcement ? EntityType.ZOMBIE : this.getType(); // Lophine - old zombie reinforcement
|
||||||
Zombie zombie = type.create(level, EntitySpawnReason.REINFORCEMENT);
|
Zombie zombie = type.create(level, EntitySpawnReason.REINFORCEMENT);
|
||||||
if (zombie == null) {
|
if (zombie == null) {
|
||||||
return true;
|
return true;
|
||||||
+2
-2
@@ -5,7 +5,7 @@ Subject: [PATCH] Spawn invulnerable time
|
|||||||
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||||
index 6b7c92fdf562dfa46eee8e8acbc82b02fc3226c5..144b2c9396b8162f9cce8b343d998907bf7fb5aa 100644
|
index 6b7c92fdf562dfa46eee8e8acbc82b02fc3226c5..c29e9c6cb2513fe4b01a619e16433893efb44e6f 100644
|
||||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||||
@@ -232,6 +232,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
@@ -232,6 +232,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||||
@@ -29,7 +29,7 @@ index 6b7c92fdf562dfa46eee8e8acbc82b02fc3226c5..144b2c9396b8162f9cce8b343d998907
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
+ // Lophine start - spawn invulnerable time
|
+ // Lophine start - spawn invulnerable time
|
||||||
+ if (fun.bm.lophine.config.modules.misc.OldFeatureConfig.spawnInvulnerableTime) {
|
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.spawnInvulnerableTime) {
|
||||||
+ if (this.spawnInvulnerableTime > 0 && !damageSource.is(net.minecraft.tags.DamageTypeTags.BYPASSES_INVULNERABILITY)) {
|
+ if (this.spawnInvulnerableTime > 0 && !damageSource.is(net.minecraft.tags.DamageTypeTags.BYPASSES_INVULNERABILITY)) {
|
||||||
+ return false;
|
+ return false;
|
||||||
+ }
|
+ }
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
|
||||||
Date: Thu, 12 Jun 2025 04:44:24 +0800
|
|
||||||
Subject: [PATCH] I18n support
|
|
||||||
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
|
||||||
index c6c6432c2efeb7b95c2894b188cd966321ae3186..1cd9af71ee66df5f277748c0a5a59a30bd57accc 100644
|
|
||||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
|
||||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
|
||||||
@@ -172,6 +172,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
|
||||||
this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
|
|
||||||
// Paper end - initialize global and world-defaults configuration
|
|
||||||
me.earthme.luminol.config.ConfigManager.loadConfigFiles(); // Luminol - load config file
|
|
||||||
+ fun.bm.lophine.utils.ServerI18nUtil.init(); // Lophine - I18n support
|
|
||||||
if (false) this.server.spark.enableEarlyIfRequested(); // Paper - spark // Luminol - Force disable builtin spark
|
|
||||||
// Paper start - fix converting txt to json file; convert old users earlier after PlayerList creation but before file load/save
|
|
||||||
if (this.convertOldUsers()) {
|
|
||||||
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -8,7 +8,7 @@ As part of: Purpur (https://github.com/PurpurMC/Purpur/blob/09f547de09fc5d886f18
|
|||||||
Licensed under: MIT (https://github.com/PurpurMC/Purpur/blob/09f547de09fc5d886f18f6d99ff389289766ec9d/LICENSE)
|
Licensed under: MIT (https://github.com/PurpurMC/Purpur/blob/09f547de09fc5d886f18f6d99ff389289766ec9d/LICENSE)
|
||||||
|
|
||||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
|
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
|
||||||
index 2f41a92465b9da28e026297cc3528898bb1c8412..fb5300ec1bd19b3dfd6a2b4106440b9f73c48205 100644
|
index 2f41a92465b9da28e026297cc3528898bb1c8412..168301a2f1c3081ae15d3695c2dcc72b4538cdfb 100644
|
||||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
|
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
|
||||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
|
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
|
||||||
@@ -148,9 +148,26 @@ public class CraftContainer extends AbstractContainerMenu {
|
@@ -148,9 +148,26 @@ public class CraftContainer extends AbstractContainerMenu {
|
||||||
@@ -18,7 +18,7 @@ index 2f41a92465b9da28e026297cc3528898bb1c8412..fb5300ec1bd19b3dfd6a2b4106440b9f
|
|||||||
- case BARREL:
|
- case BARREL:
|
||||||
- this.delegate = new ChestMenu(net.minecraft.world.inventory.MenuType.GENERIC_9x3, windowId, bottom, top, top.getContainerSize() / 9);
|
- this.delegate = new ChestMenu(net.minecraft.world.inventory.MenuType.GENERIC_9x3, windowId, bottom, top, top.getContainerSize() / 9);
|
||||||
+ // Purpur start - Barrels and enderchests 6 rows
|
+ // Purpur start - Barrels and enderchests 6 rows
|
||||||
+ this.delegate = new ChestMenu(switch (fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.enderchestRows) {
|
+ this.delegate = new ChestMenu(switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows) {
|
||||||
+ case 6 -> net.minecraft.world.inventory.MenuType.GENERIC_9x6;
|
+ case 6 -> net.minecraft.world.inventory.MenuType.GENERIC_9x6;
|
||||||
+ case 5 -> net.minecraft.world.inventory.MenuType.GENERIC_9x5;
|
+ case 5 -> net.minecraft.world.inventory.MenuType.GENERIC_9x5;
|
||||||
+ case 4 -> net.minecraft.world.inventory.MenuType.GENERIC_9x4;
|
+ case 4 -> net.minecraft.world.inventory.MenuType.GENERIC_9x4;
|
||||||
@@ -28,7 +28,7 @@ index 2f41a92465b9da28e026297cc3528898bb1c8412..fb5300ec1bd19b3dfd6a2b4106440b9f
|
|||||||
+ }, windowId, bottom, top, top.getContainerSize() / 9);
|
+ }, windowId, bottom, top, top.getContainerSize() / 9);
|
||||||
break;
|
break;
|
||||||
+ case BARREL:
|
+ case BARREL:
|
||||||
+ this.delegate = new ChestMenu(switch (fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.barrelRows) {
|
+ this.delegate = new ChestMenu(switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.barrelRows) {
|
||||||
+ case 6 -> net.minecraft.world.inventory.MenuType.GENERIC_9x6;
|
+ case 6 -> net.minecraft.world.inventory.MenuType.GENERIC_9x6;
|
||||||
+ case 5 -> net.minecraft.world.inventory.MenuType.GENERIC_9x5;
|
+ case 5 -> net.minecraft.world.inventory.MenuType.GENERIC_9x5;
|
||||||
+ case 4 -> net.minecraft.world.inventory.MenuType.GENERIC_9x4;
|
+ case 4 -> net.minecraft.world.inventory.MenuType.GENERIC_9x4;
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.logisticscraft.occlusionculling;
|
||||||
|
|
||||||
|
import com.logisticscraft.occlusionculling.util.Vec3d;
|
||||||
|
|
||||||
|
public interface DataProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepares the requested chunk. Returns true if the chunk is ready, false when
|
||||||
|
* not loaded. Should not reload the chunk when the x and y are the same as the
|
||||||
|
* last request!
|
||||||
|
*
|
||||||
|
* @param chunkX
|
||||||
|
* @param chunkZ
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean prepareChunk(int chunkX, int chunkZ);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location is inside the chunk.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param z
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean isOpaqueFullCube(int x, int y, int z);
|
||||||
|
|
||||||
|
default void cleanup() {
|
||||||
|
}
|
||||||
|
|
||||||
|
default void checkingPosition(Vec3d[] targetPoints, int size, Vec3d viewerPosition) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+515
@@ -0,0 +1,515 @@
|
|||||||
|
package com.logisticscraft.occlusionculling;
|
||||||
|
|
||||||
|
import com.logisticscraft.occlusionculling.cache.ArrayOcclusionCache;
|
||||||
|
import com.logisticscraft.occlusionculling.cache.OcclusionCache;
|
||||||
|
import com.logisticscraft.occlusionculling.util.MathUtilities;
|
||||||
|
import com.logisticscraft.occlusionculling.util.Vec3d;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.BitSet;
|
||||||
|
|
||||||
|
public class OcclusionCullingInstance {
|
||||||
|
|
||||||
|
private static final int ON_MIN_X = 0x01;
|
||||||
|
private static final int ON_MAX_X = 0x02;
|
||||||
|
private static final int ON_MIN_Y = 0x04;
|
||||||
|
private static final int ON_MAX_Y = 0x08;
|
||||||
|
private static final int ON_MIN_Z = 0x10;
|
||||||
|
private static final int ON_MAX_Z = 0x20;
|
||||||
|
|
||||||
|
private final int reach;
|
||||||
|
private final double aabbExpansion;
|
||||||
|
private final DataProvider provider;
|
||||||
|
private final OcclusionCache cache;
|
||||||
|
|
||||||
|
// Reused allocated data structures
|
||||||
|
private final BitSet skipList = new BitSet(); // Grows bigger in case some mod introduces giant hitboxes
|
||||||
|
private final Vec3d[] targetPoints = new Vec3d[15];
|
||||||
|
private final Vec3d targetPos = new Vec3d(0, 0, 0);
|
||||||
|
private final int[] cameraPos = new int[3];
|
||||||
|
private final boolean[] dotselectors = new boolean[14];
|
||||||
|
private boolean allowRayChecks = false;
|
||||||
|
private final int[] lastHitBlock = new int[3];
|
||||||
|
private boolean allowWallClipping = false;
|
||||||
|
|
||||||
|
|
||||||
|
public OcclusionCullingInstance(int maxDistance, DataProvider provider) {
|
||||||
|
this(maxDistance, provider, new ArrayOcclusionCache(maxDistance), 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OcclusionCullingInstance(int maxDistance, DataProvider provider, OcclusionCache cache, double aabbExpansion) {
|
||||||
|
this.reach = maxDistance;
|
||||||
|
this.provider = provider;
|
||||||
|
this.cache = cache;
|
||||||
|
this.aabbExpansion = aabbExpansion;
|
||||||
|
for (int i = 0; i < targetPoints.length; i++) {
|
||||||
|
targetPoints[i] = new Vec3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAABBVisible(Vec3d aabbMin, Vec3d aabbMax, Vec3d viewerPosition) {
|
||||||
|
try {
|
||||||
|
int maxX = MathUtilities.floor(aabbMax.x
|
||||||
|
+ aabbExpansion);
|
||||||
|
int maxY = MathUtilities.floor(aabbMax.y
|
||||||
|
+ aabbExpansion);
|
||||||
|
int maxZ = MathUtilities.floor(aabbMax.z
|
||||||
|
+ aabbExpansion);
|
||||||
|
int minX = MathUtilities.floor(aabbMin.x
|
||||||
|
- aabbExpansion);
|
||||||
|
int minY = MathUtilities.floor(aabbMin.y
|
||||||
|
- aabbExpansion);
|
||||||
|
int minZ = MathUtilities.floor(aabbMin.z
|
||||||
|
- aabbExpansion);
|
||||||
|
|
||||||
|
cameraPos[0] = MathUtilities.floor(viewerPosition.x);
|
||||||
|
cameraPos[1] = MathUtilities.floor(viewerPosition.y);
|
||||||
|
cameraPos[2] = MathUtilities.floor(viewerPosition.z);
|
||||||
|
|
||||||
|
Relative relX = Relative.from(minX, maxX, cameraPos[0]);
|
||||||
|
Relative relY = Relative.from(minY, maxY, cameraPos[1]);
|
||||||
|
Relative relZ = Relative.from(minZ, maxZ, cameraPos[2]);
|
||||||
|
|
||||||
|
if (relX == Relative.INSIDE && relY == Relative.INSIDE && relZ == Relative.INSIDE) {
|
||||||
|
return true; // We are inside of the AABB, don't cull
|
||||||
|
}
|
||||||
|
|
||||||
|
skipList.clear();
|
||||||
|
|
||||||
|
// Just check the cache first
|
||||||
|
int id = 0;
|
||||||
|
for (int x = minX; x <= maxX; x++) {
|
||||||
|
for (int y = minY; y <= maxY; y++) {
|
||||||
|
for (int z = minZ; z <= maxZ; z++) {
|
||||||
|
int cachedValue = getCacheValue(x, y, z);
|
||||||
|
|
||||||
|
if (cachedValue == 1) {
|
||||||
|
// non-occluding
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cachedValue != 0) {
|
||||||
|
// was checked and it wasn't visible
|
||||||
|
skipList.set(id);
|
||||||
|
}
|
||||||
|
id++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// only after the first hit wall the cache becomes valid.
|
||||||
|
allowRayChecks = false;
|
||||||
|
|
||||||
|
// since the cache wasn't helpfull
|
||||||
|
id = 0;
|
||||||
|
for (int x = minX; x <= maxX; x++) {
|
||||||
|
byte visibleOnFaceX = 0;
|
||||||
|
byte faceEdgeDataX = 0;
|
||||||
|
faceEdgeDataX |= (x == minX) ? ON_MIN_X : 0;
|
||||||
|
faceEdgeDataX |= (x == maxX) ? ON_MAX_X : 0;
|
||||||
|
visibleOnFaceX |= (x == minX && relX == Relative.POSITIVE) ? ON_MIN_X : 0;
|
||||||
|
visibleOnFaceX |= (x == maxX && relX == Relative.NEGATIVE) ? ON_MAX_X : 0;
|
||||||
|
for (int y = minY; y <= maxY; y++) {
|
||||||
|
byte faceEdgeDataY = faceEdgeDataX;
|
||||||
|
byte visibleOnFaceY = visibleOnFaceX;
|
||||||
|
faceEdgeDataY |= (y == minY) ? ON_MIN_Y : 0;
|
||||||
|
faceEdgeDataY |= (y == maxY) ? ON_MAX_Y : 0;
|
||||||
|
visibleOnFaceY |= (y == minY && relY == Relative.POSITIVE) ? ON_MIN_Y : 0;
|
||||||
|
visibleOnFaceY |= (y == maxY && relY == Relative.NEGATIVE) ? ON_MAX_Y : 0;
|
||||||
|
for (int z = minZ; z <= maxZ; z++) {
|
||||||
|
byte faceEdgeData = faceEdgeDataY;
|
||||||
|
byte visibleOnFace = visibleOnFaceY;
|
||||||
|
faceEdgeData |= (z == minZ) ? ON_MIN_Z : 0;
|
||||||
|
faceEdgeData |= (z == maxZ) ? ON_MAX_Z : 0;
|
||||||
|
visibleOnFace |= (z == minZ && relZ == Relative.POSITIVE) ? ON_MIN_Z : 0;
|
||||||
|
visibleOnFace |= (z == maxZ && relZ == Relative.NEGATIVE) ? ON_MAX_Z : 0;
|
||||||
|
if (skipList.get(id)) { // was checked and it wasn't visible
|
||||||
|
id++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visibleOnFace != 0) {
|
||||||
|
targetPos.set(x, y, z);
|
||||||
|
if (isVoxelVisible(viewerPosition, targetPos, faceEdgeData, visibleOnFace)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
id++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} catch (Throwable t) {
|
||||||
|
// Failsafe
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param viewerPosition
|
||||||
|
* @param position
|
||||||
|
* @param faceData contains rather this Block is on the outside for a given face
|
||||||
|
* @param visibleOnFace contains rather a face should be concidered
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean isVoxelVisible(Vec3d viewerPosition, Vec3d position, byte faceData, byte visibleOnFace) {
|
||||||
|
int targetSize = 0;
|
||||||
|
Arrays.fill(dotselectors, false);
|
||||||
|
if ((visibleOnFace & ON_MIN_X) == ON_MIN_X) {
|
||||||
|
dotselectors[0] = true;
|
||||||
|
if ((faceData & ~ON_MIN_X) != 0) {
|
||||||
|
dotselectors[1] = true;
|
||||||
|
dotselectors[4] = true;
|
||||||
|
dotselectors[5] = true;
|
||||||
|
}
|
||||||
|
dotselectors[8] = true;
|
||||||
|
}
|
||||||
|
if ((visibleOnFace & ON_MIN_Y) == ON_MIN_Y) {
|
||||||
|
dotselectors[0] = true;
|
||||||
|
if ((faceData & ~ON_MIN_Y) != 0) {
|
||||||
|
dotselectors[3] = true;
|
||||||
|
dotselectors[4] = true;
|
||||||
|
dotselectors[7] = true;
|
||||||
|
}
|
||||||
|
dotselectors[9] = true;
|
||||||
|
}
|
||||||
|
if ((visibleOnFace & ON_MIN_Z) == ON_MIN_Z) {
|
||||||
|
dotselectors[0] = true;
|
||||||
|
if ((faceData & ~ON_MIN_Z) != 0) {
|
||||||
|
dotselectors[1] = true;
|
||||||
|
dotselectors[4] = true;
|
||||||
|
dotselectors[5] = true;
|
||||||
|
}
|
||||||
|
dotselectors[10] = true;
|
||||||
|
}
|
||||||
|
if ((visibleOnFace & ON_MAX_X) == ON_MAX_X) {
|
||||||
|
dotselectors[4] = true;
|
||||||
|
if ((faceData & ~ON_MAX_X) != 0) {
|
||||||
|
dotselectors[5] = true;
|
||||||
|
dotselectors[6] = true;
|
||||||
|
dotselectors[7] = true;
|
||||||
|
}
|
||||||
|
dotselectors[11] = true;
|
||||||
|
}
|
||||||
|
if ((visibleOnFace & ON_MAX_Y) == ON_MAX_Y) {
|
||||||
|
dotselectors[1] = true;
|
||||||
|
if ((faceData & ~ON_MAX_Y) != 0) {
|
||||||
|
dotselectors[2] = true;
|
||||||
|
dotselectors[5] = true;
|
||||||
|
dotselectors[6] = true;
|
||||||
|
}
|
||||||
|
dotselectors[12] = true;
|
||||||
|
}
|
||||||
|
if ((visibleOnFace & ON_MAX_Z) == ON_MAX_Z) {
|
||||||
|
dotselectors[2] = true;
|
||||||
|
if ((faceData & ~ON_MAX_Z) != 0) {
|
||||||
|
dotselectors[3] = true;
|
||||||
|
dotselectors[6] = true;
|
||||||
|
dotselectors[7] = true;
|
||||||
|
}
|
||||||
|
dotselectors[13] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dotselectors[0]) targetPoints[targetSize++].setAdd(position, 0.05, 0.05, 0.05);
|
||||||
|
if (dotselectors[1]) targetPoints[targetSize++].setAdd(position, 0.05, 0.95, 0.05);
|
||||||
|
if (dotselectors[2]) targetPoints[targetSize++].setAdd(position, 0.05, 0.95, 0.95);
|
||||||
|
if (dotselectors[3]) targetPoints[targetSize++].setAdd(position, 0.05, 0.05, 0.95);
|
||||||
|
if (dotselectors[4]) targetPoints[targetSize++].setAdd(position, 0.95, 0.05, 0.05);
|
||||||
|
if (dotselectors[5]) targetPoints[targetSize++].setAdd(position, 0.95, 0.95, 0.05);
|
||||||
|
if (dotselectors[6]) targetPoints[targetSize++].setAdd(position, 0.95, 0.95, 0.95);
|
||||||
|
if (dotselectors[7]) targetPoints[targetSize++].setAdd(position, 0.95, 0.05, 0.95);
|
||||||
|
// middle points
|
||||||
|
if (dotselectors[8]) targetPoints[targetSize++].setAdd(position, 0.05, 0.5, 0.5);
|
||||||
|
if (dotselectors[9]) targetPoints[targetSize++].setAdd(position, 0.5, 0.05, 0.5);
|
||||||
|
if (dotselectors[10]) targetPoints[targetSize++].setAdd(position, 0.5, 0.5, 0.05);
|
||||||
|
if (dotselectors[11]) targetPoints[targetSize++].setAdd(position, 0.95, 0.5, 0.5);
|
||||||
|
if (dotselectors[12]) targetPoints[targetSize++].setAdd(position, 0.5, 0.95, 0.5);
|
||||||
|
if (dotselectors[13]) targetPoints[targetSize++].setAdd(position, 0.5, 0.5, 0.95);
|
||||||
|
|
||||||
|
return isVisible(viewerPosition, targetPoints, targetSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean rayIntersection(int[] b, Vec3d rayOrigin, Vec3d rayDir) {
|
||||||
|
Vec3d rInv = new Vec3d(1, 1, 1).div(rayDir);
|
||||||
|
|
||||||
|
double t1 = (b[0] - rayOrigin.x) * rInv.x;
|
||||||
|
double t2 = (b[0] + 1 - rayOrigin.x) * rInv.x;
|
||||||
|
double t3 = (b[1] - rayOrigin.y) * rInv.y;
|
||||||
|
double t4 = (b[1] + 1 - rayOrigin.y) * rInv.y;
|
||||||
|
double t5 = (b[2] - rayOrigin.z) * rInv.z;
|
||||||
|
double t6 = (b[2] + 1 - rayOrigin.z) * rInv.z;
|
||||||
|
|
||||||
|
double tmin = Math.max(Math.max(Math.min(t1, t2), Math.min(t3, t4)), Math.min(t5, t6));
|
||||||
|
double tmax = Math.min(Math.min(Math.max(t1, t2), Math.max(t3, t4)), Math.max(t5, t6));
|
||||||
|
|
||||||
|
// if tmax > 0, ray (line) is intersecting AABB, but the whole AABB is behind us
|
||||||
|
if (tmax > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if tmin > tmax, ray doesn't intersect AABB
|
||||||
|
if (tmin > tmax) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the grid cells that intersect with this Vec3d<br>
|
||||||
|
* <a href=
|
||||||
|
* "http://playtechs.blogspot.de/2007/03/raytracing-on-grid.html">http://playtechs.blogspot.de/2007/03/raytracing-on-grid.html</a>
|
||||||
|
* <p>
|
||||||
|
* Caching assumes that all Vec3d's are inside the same block
|
||||||
|
*/
|
||||||
|
private boolean isVisible(Vec3d start, Vec3d[] targets, int size) {
|
||||||
|
// start cell coordinate
|
||||||
|
int x = cameraPos[0];
|
||||||
|
int y = cameraPos[1];
|
||||||
|
int z = cameraPos[2];
|
||||||
|
|
||||||
|
for (int v = 0; v < size; v++) {
|
||||||
|
// ray-casting target
|
||||||
|
Vec3d target = targets[v];
|
||||||
|
|
||||||
|
double relativeX = start.x - target.getX();
|
||||||
|
double relativeY = start.y - target.getY();
|
||||||
|
double relativeZ = start.z - target.getZ();
|
||||||
|
|
||||||
|
if (allowRayChecks && rayIntersection(lastHitBlock, start, new Vec3d(relativeX, relativeY, relativeZ).normalize())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// horizontal and vertical cell amount spanned
|
||||||
|
double dimensionX = Math.abs(relativeX);
|
||||||
|
double dimensionY = Math.abs(relativeY);
|
||||||
|
double dimensionZ = Math.abs(relativeZ);
|
||||||
|
|
||||||
|
// distance between horizontal intersection points with cell border as a
|
||||||
|
// fraction of the total Vec3d length
|
||||||
|
double dimFracX = 1f / dimensionX;
|
||||||
|
// distance between vertical intersection points with cell border as a fraction
|
||||||
|
// of the total Vec3d length
|
||||||
|
double dimFracY = 1f / dimensionY;
|
||||||
|
double dimFracZ = 1f / dimensionZ;
|
||||||
|
|
||||||
|
// total amount of intersected cells
|
||||||
|
int intersectCount = 1;
|
||||||
|
|
||||||
|
// 1, 0 or -1
|
||||||
|
// determines the direction of the next cell (horizontally / vertically)
|
||||||
|
int x_inc, y_inc, z_inc;
|
||||||
|
|
||||||
|
// the distance to the next horizontal / vertical intersection point with a cell
|
||||||
|
// border as a fraction of the total Vec3d length
|
||||||
|
double t_next_y, t_next_x, t_next_z;
|
||||||
|
|
||||||
|
if (dimensionX == 0f) {
|
||||||
|
x_inc = 0;
|
||||||
|
t_next_x = dimFracX; // don't increment horizontally because the Vec3d is perfectly vertical
|
||||||
|
} else if (target.x > start.x) {
|
||||||
|
x_inc = 1; // target point is horizontally greater than starting point so increment every
|
||||||
|
// step by 1
|
||||||
|
intersectCount += MathUtilities.floor(target.x) - x; // increment total amount of intersecting cells
|
||||||
|
t_next_x = (float) ((x + 1 - start.x) * dimFracX); // calculate the next horizontal
|
||||||
|
// intersection
|
||||||
|
// point based on the position inside
|
||||||
|
// the first cell
|
||||||
|
} else {
|
||||||
|
x_inc = -1; // target point is horizontally smaller than starting point so reduce every step
|
||||||
|
// by 1
|
||||||
|
intersectCount += x - MathUtilities.floor(target.x); // increment total amount of intersecting cells
|
||||||
|
t_next_x = (float) ((start.x - x)
|
||||||
|
* dimFracX); // calculate the next horizontal
|
||||||
|
// intersection point
|
||||||
|
// based on the position inside
|
||||||
|
// the first cell
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dimensionY == 0f) {
|
||||||
|
y_inc = 0;
|
||||||
|
t_next_y = dimFracY; // don't increment vertically because the Vec3d is perfectly horizontal
|
||||||
|
} else if (target.y > start.y) {
|
||||||
|
y_inc = 1; // target point is vertically greater than starting point so increment every
|
||||||
|
// step by 1
|
||||||
|
intersectCount += MathUtilities.floor(target.y) - y; // increment total amount of intersecting cells
|
||||||
|
t_next_y = (float) ((y + 1 - start.y)
|
||||||
|
* dimFracY); // calculate the next vertical
|
||||||
|
// intersection
|
||||||
|
// point based on the position inside
|
||||||
|
// the first cell
|
||||||
|
} else {
|
||||||
|
y_inc = -1; // target point is vertically smaller than starting point so reduce every step
|
||||||
|
// by 1
|
||||||
|
intersectCount += y - MathUtilities.floor(target.y); // increment total amount of intersecting cells
|
||||||
|
t_next_y = (float) ((start.y - y)
|
||||||
|
* dimFracY); // calculate the next vertical intersection
|
||||||
|
// point
|
||||||
|
// based on the position inside
|
||||||
|
// the first cell
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dimensionZ == 0f) {
|
||||||
|
z_inc = 0;
|
||||||
|
t_next_z = dimFracZ; // don't increment vertically because the Vec3d is perfectly horizontal
|
||||||
|
} else if (target.z > start.z) {
|
||||||
|
z_inc = 1; // target point is vertically greater than starting point so increment every
|
||||||
|
// step by 1
|
||||||
|
intersectCount += MathUtilities.floor(target.z) - z; // increment total amount of intersecting cells
|
||||||
|
t_next_z = (float) ((z + 1 - start.z)
|
||||||
|
* dimFracZ); // calculate the next vertical
|
||||||
|
// intersection
|
||||||
|
// point based on the position inside
|
||||||
|
// the first cell
|
||||||
|
} else {
|
||||||
|
z_inc = -1; // target point is vertically smaller than starting point so reduce every step
|
||||||
|
// by 1
|
||||||
|
intersectCount += z - MathUtilities.floor(target.z); // increment total amount of intersecting cells
|
||||||
|
t_next_z = (float) ((start.z - z)
|
||||||
|
* dimFracZ); // calculate the next vertical intersection
|
||||||
|
// point
|
||||||
|
// based on the position inside
|
||||||
|
// the first cell
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean finished = stepRay(start, x, y, z,
|
||||||
|
dimFracX, dimFracY, dimFracZ, intersectCount, x_inc, y_inc,
|
||||||
|
z_inc, t_next_y, t_next_x, t_next_z);
|
||||||
|
provider.cleanup();
|
||||||
|
if (finished) {
|
||||||
|
cacheResult(targets[0], true);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
allowRayChecks = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cacheResult(targets[0], false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean stepRay(Vec3d start, int currentX, int currentY,
|
||||||
|
int currentZ, double distInX, double distInY,
|
||||||
|
double distInZ, int n, int x_inc, int y_inc,
|
||||||
|
int z_inc, double t_next_y, double t_next_x,
|
||||||
|
double t_next_z) {
|
||||||
|
allowWallClipping = true; // initially allow rays to go through walls till they are on the outside
|
||||||
|
// iterate through all intersecting cells (n times)
|
||||||
|
for (; n > 1; n--) { // n-1 times because we don't want to check the last block
|
||||||
|
// towards - where from
|
||||||
|
|
||||||
|
|
||||||
|
// get cached value, 0 means uncached (default)
|
||||||
|
int cVal = getCacheValue(currentX, currentY, currentZ);
|
||||||
|
|
||||||
|
if (cVal == 2 && !allowWallClipping) {
|
||||||
|
// block cached as occluding, stop ray
|
||||||
|
lastHitBlock[0] = currentX;
|
||||||
|
lastHitBlock[1] = currentY;
|
||||||
|
lastHitBlock[2] = currentZ;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cVal == 0) {
|
||||||
|
// save current cell
|
||||||
|
int chunkX = currentX >> 4;
|
||||||
|
int chunkZ = currentZ >> 4;
|
||||||
|
|
||||||
|
if (!provider.prepareChunk(chunkX, chunkZ)) { // Chunk not ready
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (provider.isOpaqueFullCube(currentX, currentY, currentZ)) {
|
||||||
|
if (!allowWallClipping) {
|
||||||
|
cache.setLastHidden();
|
||||||
|
lastHitBlock[0] = currentX;
|
||||||
|
lastHitBlock[1] = currentY;
|
||||||
|
lastHitBlock[2] = currentZ;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// outside of wall, now clipping is not allowed
|
||||||
|
allowWallClipping = false;
|
||||||
|
cache.setLastVisible();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cVal == 1) {
|
||||||
|
// outside of wall, now clipping is not allowed
|
||||||
|
allowWallClipping = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (t_next_y < t_next_x && t_next_y < t_next_z) { // next cell is upwards/downwards because the distance to
|
||||||
|
// the next vertical
|
||||||
|
// intersection point is smaller than to the next horizontal intersection point
|
||||||
|
currentY += y_inc; // move up/down
|
||||||
|
t_next_y += distInY; // update next vertical intersection point
|
||||||
|
} else if (t_next_x < t_next_y && t_next_x < t_next_z) { // next cell is right/left
|
||||||
|
currentX += x_inc; // move right/left
|
||||||
|
t_next_x += distInX; // update next horizontal intersection point
|
||||||
|
} else {
|
||||||
|
currentZ += z_inc; // move right/left
|
||||||
|
t_next_z += distInZ; // update next horizontal intersection point
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -1 = invalid location, 0 = not checked yet, 1 = visible, 2 = occluding
|
||||||
|
private int getCacheValue(int x, int y, int z) {
|
||||||
|
x -= cameraPos[0];
|
||||||
|
y -= cameraPos[1];
|
||||||
|
z -= cameraPos[2];
|
||||||
|
if (Math.abs(x) > reach - 2 || Math.abs(y) > reach - 2
|
||||||
|
|| Math.abs(z) > reach - 2) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if target is already known
|
||||||
|
return cache.getState(x + reach, y + reach, z + reach);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void cacheResult(int x, int y, int z, boolean result) {
|
||||||
|
int cx = x - cameraPos[0] + reach;
|
||||||
|
int cy = y - cameraPos[1] + reach;
|
||||||
|
int cz = z - cameraPos[2] + reach;
|
||||||
|
if (result) {
|
||||||
|
cache.setVisible(cx, cy, cz);
|
||||||
|
} else {
|
||||||
|
cache.setHidden(cx, cy, cz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cacheResult(Vec3d vector, boolean result) {
|
||||||
|
int cx = MathUtilities.floor(vector.x) - cameraPos[0] + reach;
|
||||||
|
int cy = MathUtilities.floor(vector.y) - cameraPos[1] + reach;
|
||||||
|
int cz = MathUtilities.floor(vector.z) - cameraPos[2] + reach;
|
||||||
|
if (result) {
|
||||||
|
cache.setVisible(cx, cy, cz);
|
||||||
|
} else {
|
||||||
|
cache.setHidden(cx, cy, cz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetCache() {
|
||||||
|
this.cache.resetCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum Relative {
|
||||||
|
INSIDE, POSITIVE, NEGATIVE;
|
||||||
|
|
||||||
|
public static Relative from(int min, int max, int pos) {
|
||||||
|
if (max > pos && min > pos) {
|
||||||
|
return POSITIVE;
|
||||||
|
} else if (min < pos && max < pos) {
|
||||||
|
return NEGATIVE;
|
||||||
|
}
|
||||||
|
return INSIDE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Vendored
+57
@@ -0,0 +1,57 @@
|
|||||||
|
package com.logisticscraft.occlusionculling.cache;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class ArrayOcclusionCache implements OcclusionCache {
|
||||||
|
|
||||||
|
private final int reachX2;
|
||||||
|
private final byte[] cache;
|
||||||
|
private int positionKey;
|
||||||
|
private int entry;
|
||||||
|
private int offset;
|
||||||
|
|
||||||
|
public ArrayOcclusionCache(int reach) {
|
||||||
|
this.reachX2 = reach * 2;
|
||||||
|
this.cache = new byte[(reachX2 * reachX2 * reachX2) / 4];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetCache() {
|
||||||
|
Arrays.fill(cache, (byte) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVisible(int x, int y, int z) {
|
||||||
|
positionKey = x + y * reachX2 + z * reachX2 * reachX2;
|
||||||
|
entry = positionKey / 4;
|
||||||
|
offset = (positionKey % 4) * 2;
|
||||||
|
cache[entry] |= 1 << offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHidden(int x, int y, int z) {
|
||||||
|
positionKey = x + y * reachX2 + z * reachX2 * reachX2;
|
||||||
|
entry = positionKey / 4;
|
||||||
|
offset = (positionKey % 4) * 2;
|
||||||
|
cache[entry] |= 1 << offset + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getState(int x, int y, int z) {
|
||||||
|
positionKey = x + y * reachX2 + z * reachX2 * reachX2;
|
||||||
|
entry = positionKey / 4;
|
||||||
|
offset = (positionKey % 4) * 2;
|
||||||
|
return cache[entry] >> offset & 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLastVisible() {
|
||||||
|
cache[entry] |= 1 << offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLastHidden() {
|
||||||
|
cache[entry] |= 1 << offset + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
package com.logisticscraft.occlusionculling.cache;
|
||||||
|
|
||||||
|
public interface OcclusionCache {
|
||||||
|
|
||||||
|
void resetCache();
|
||||||
|
|
||||||
|
void setVisible(int x, int y, int z);
|
||||||
|
|
||||||
|
void setHidden(int x, int y, int z);
|
||||||
|
|
||||||
|
int getState(int x, int y, int z);
|
||||||
|
|
||||||
|
void setLastHidden();
|
||||||
|
|
||||||
|
void setLastVisible();
|
||||||
|
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
package com.logisticscraft.occlusionculling.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains MathHelper methods
|
||||||
|
*/
|
||||||
|
public final class MathUtilities {
|
||||||
|
|
||||||
|
private MathUtilities() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int floor(double d) {
|
||||||
|
int i = (int) d;
|
||||||
|
return d < (double) i ? i - 1 : i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int fastFloor(double d) {
|
||||||
|
return (int) (d + 1024.0) - 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int ceil(double d) {
|
||||||
|
int i = (int) d;
|
||||||
|
return d > (double) i ? i + 1 : i;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package com.logisticscraft.occlusionculling.util;
|
||||||
|
|
||||||
|
public class Vec3d {
|
||||||
|
|
||||||
|
public double x;
|
||||||
|
public double y;
|
||||||
|
public double z;
|
||||||
|
|
||||||
|
public Vec3d(double x, double y, double z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getZ() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(double x, double y, double z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAdd(Vec3d vec, double x, double y, double z) {
|
||||||
|
this.x = vec.x + x;
|
||||||
|
this.y = vec.y + y;
|
||||||
|
this.z = vec.z + z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3d div(Vec3d rayDir) {
|
||||||
|
this.x /= rayDir.x;
|
||||||
|
this.z /= rayDir.z;
|
||||||
|
this.y /= rayDir.y;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3d normalize() {
|
||||||
|
double mag = Math.sqrt(x * x + y * y + z * z);
|
||||||
|
this.x /= mag;
|
||||||
|
this.y /= mag;
|
||||||
|
this.z /= mag;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (this == other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(other instanceof Vec3d)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Vec3d vec3d = (Vec3d) other;
|
||||||
|
if (Double.compare(vec3d.x, x) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Double.compare(vec3d.y, y) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Double.compare(vec3d.z, z) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
long l = Double.doubleToLongBits(x);
|
||||||
|
int i = (int) (l ^ l >>> 32);
|
||||||
|
l = Double.doubleToLongBits(y);
|
||||||
|
i = 31 * i + (int) (l ^ l >>> 32);
|
||||||
|
l = Double.doubleToLongBits(z);
|
||||||
|
i = 31 * i + (int) (l ^ l >>> 32);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "(" + x + ", " + y + ", " + z + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+3
-11
@@ -1,9 +1,11 @@
|
|||||||
package fun.bm.lophine.config.modules.experiment;
|
package fun.bm.lophine.config.modules.experiment;
|
||||||
|
|
||||||
import me.earthme.luminol.config.EnumConfigCategory;
|
|
||||||
import me.earthme.luminol.config.IConfigModule;
|
import me.earthme.luminol.config.IConfigModule;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||||
|
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||||
|
|
||||||
|
@ConfigClassInfo(configAttribution = EnumConfigCategory.EXPERIMENT, mainName = "command")
|
||||||
public class CommandConfig implements IConfigModule {
|
public class CommandConfig implements IConfigModule {
|
||||||
@ConfigInfo(baseName = "tick_command_enabled", comments =
|
@ConfigInfo(baseName = "tick_command_enabled", comments =
|
||||||
"""
|
"""
|
||||||
@@ -15,14 +17,4 @@ public class CommandConfig implements IConfigModule {
|
|||||||
Allow to use datapack command
|
Allow to use datapack command
|
||||||
--- datapack hot-update unsupported, please restart server""")
|
--- datapack hot-update unsupported, please restart server""")
|
||||||
public static boolean datapack = false;
|
public static boolean datapack = false;
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumConfigCategory getCategory() {
|
|
||||||
return EnumConfigCategory.EXPERIMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBaseName() {
|
|
||||||
return "command";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+3
-11
@@ -1,22 +1,14 @@
|
|||||||
package fun.bm.lophine.config.modules.experiment;
|
package fun.bm.lophine.config.modules.experiment;
|
||||||
|
|
||||||
import me.earthme.luminol.config.EnumConfigCategory;
|
|
||||||
import me.earthme.luminol.config.IConfigModule;
|
import me.earthme.luminol.config.IConfigModule;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||||
|
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||||
|
|
||||||
|
@ConfigClassInfo(configAttribution = EnumConfigCategory.EXPERIMENT, mainName = "entity_damage_source_trace")
|
||||||
public class EntityDamageSourceTraceConfig implements IConfigModule {
|
public class EntityDamageSourceTraceConfig implements IConfigModule {
|
||||||
@ConfigInfo(baseName = "enabled", comments =
|
@ConfigInfo(baseName = "enabled", comments =
|
||||||
"""
|
"""
|
||||||
Allow trace damage source cross different Region Scheduler.""")
|
Allow trace damage source cross different Region Scheduler.""")
|
||||||
public static boolean enabled = false;
|
public static boolean enabled = false;
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumConfigCategory getCategory() {
|
|
||||||
return EnumConfigCategory.EXPERIMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBaseName() {
|
|
||||||
return "entity_damage_source_trace";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+3
-11
@@ -1,9 +1,11 @@
|
|||||||
package fun.bm.lophine.config.modules.experiment;
|
package fun.bm.lophine.config.modules.experiment;
|
||||||
|
|
||||||
import me.earthme.luminol.config.EnumConfigCategory;
|
|
||||||
import me.earthme.luminol.config.IConfigModule;
|
import me.earthme.luminol.config.IConfigModule;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||||
|
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||||
|
|
||||||
|
@ConfigClassInfo(configAttribution = EnumConfigCategory.EXPERIMENT, mainName = "ray_tracking_entity_tracker")
|
||||||
public class RayTrackingEntityTrackerConfig implements IConfigModule {
|
public class RayTrackingEntityTrackerConfig implements IConfigModule {
|
||||||
@ConfigInfo(baseName = "enabled")
|
@ConfigInfo(baseName = "enabled")
|
||||||
public static boolean enabled = false;
|
public static boolean enabled = false;
|
||||||
@@ -15,14 +17,4 @@ public class RayTrackingEntityTrackerConfig implements IConfigModule {
|
|||||||
public static int tracingDistance = 48;
|
public static int tracingDistance = 48;
|
||||||
@ConfigInfo(baseName = "hitbox_limit")
|
@ConfigInfo(baseName = "hitbox_limit")
|
||||||
public static int hitboxLimit = 50;
|
public static int hitboxLimit = 50;
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumConfigCategory getCategory() {
|
|
||||||
return EnumConfigCategory.EXPERIMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBaseName() {
|
|
||||||
return "ray_tracking_entity_tracker";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+3
-11
@@ -1,24 +1,16 @@
|
|||||||
package fun.bm.lophine.config.modules.experiment;
|
package fun.bm.lophine.config.modules.experiment;
|
||||||
|
|
||||||
import me.earthme.luminol.config.EnumConfigCategory;
|
|
||||||
import me.earthme.luminol.config.IConfigModule;
|
import me.earthme.luminol.config.IConfigModule;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||||
import me.earthme.luminol.config.flags.TransformedConfig;
|
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||||
|
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||||
|
|
||||||
|
@ConfigClassInfo(configAttribution = EnumConfigCategory.EXPERIMENT, mainName = "waypoint_bar")
|
||||||
public class WaypointConfig implements IConfigModule {
|
public class WaypointConfig implements IConfigModule {
|
||||||
@TransformedConfig(name = "enable-waypoint", category = {"experiment", "waypoint bar"})
|
@TransformedConfig(name = "enable-waypoint", category = {"experiment", "waypoint bar"})
|
||||||
@ConfigInfo(baseName = "enabled", comments =
|
@ConfigInfo(baseName = "enabled", comments =
|
||||||
"""
|
"""
|
||||||
Enable waypoint bar unsafe""")
|
Enable waypoint bar unsafe""")
|
||||||
public static boolean forceEnableWaypointUnsafe = false;
|
public static boolean forceEnableWaypointUnsafe = false;
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumConfigCategory getCategory() {
|
|
||||||
return EnumConfigCategory.EXPERIMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBaseName() {
|
|
||||||
return "waypoint_bar";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
-25
@@ -1,25 +0,0 @@
|
|||||||
package fun.bm.lophine.config.modules.fixes;
|
|
||||||
|
|
||||||
import me.earthme.luminol.config.EnumConfigCategory;
|
|
||||||
import me.earthme.luminol.config.IConfigModule;
|
|
||||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
|
||||||
import me.earthme.luminol.config.flags.TransformedConfig;
|
|
||||||
|
|
||||||
public class DisableEndCrystalCheckConfig implements IConfigModule {
|
|
||||||
@TransformedConfig(name = "disable_end_crystal_check", category = {"misc", "end_crystal"})
|
|
||||||
@ConfigInfo(baseName = "disable_end_crystal_check", comments =
|
|
||||||
"""
|
|
||||||
Disable paper's End Crystal position check.
|
|
||||||
It reverts to vanilla respawn dragon logic.""")
|
|
||||||
public static boolean disableCheck = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumConfigCategory getCategory() {
|
|
||||||
return EnumConfigCategory.FIXES;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBaseName() {
|
|
||||||
return "end_crystal";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
package fun.bm.lophine.config.modules.fixes;
|
||||||
|
|
||||||
|
import me.earthme.luminol.config.IConfigModule;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||||
|
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||||
|
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||||
|
|
||||||
|
@ConfigClassInfo(configAttribution = EnumConfigCategory.FIXES, mainName = "end-void-ring")
|
||||||
|
public class EndVoidRingsConfig implements IConfigModule {
|
||||||
|
@TransformedConfig(name = "enabled", category = {"gameplay", "end_void_rings"})
|
||||||
|
@ConfigInfo(baseName = "enabled", comments = """
|
||||||
|
If enabled, it will generate end void rings, like MC-159283.""")
|
||||||
|
public static boolean enabled = false;
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
package fun.bm.lophine.config.modules.function;
|
||||||
|
|
||||||
|
import me.earthme.luminol.config.IConfigModule;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||||
|
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||||
|
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||||
|
|
||||||
|
@ConfigClassInfo(configAttribution = EnumConfigCategory.FUNCTION, mainName = "container_expansion")
|
||||||
|
public class ContainerExpansionConfig implements IConfigModule {
|
||||||
|
@TransformedConfig(name = "barrel_rows", category = {"misc", "container_expansion"})
|
||||||
|
@ConfigInfo(baseName = "barrel_rows", comments =
|
||||||
|
"""
|
||||||
|
range: 1~6""")
|
||||||
|
public static int barrelRows = 3;
|
||||||
|
|
||||||
|
@TransformedConfig(name = "enderchest_rows", category = {"misc", "container_expansion"})
|
||||||
|
@ConfigInfo(baseName = "enderchest_rows", comments =
|
||||||
|
"""
|
||||||
|
range: 1~6""")
|
||||||
|
public static int enderchestRows = 3;
|
||||||
|
|
||||||
|
@TransformedConfig(name = "shulker_stackable_count", category = {"misc", "container_expansion"})
|
||||||
|
@ConfigInfo(baseName = "shulker_stackable_count", comments =
|
||||||
|
"""
|
||||||
|
range: 1~64""")
|
||||||
|
public static int shulkerCount = 1;
|
||||||
|
|
||||||
|
@TransformedConfig(name = "same_nbt_shulker_stackable", category = {"misc", "container_expansion"})
|
||||||
|
@ConfigInfo(baseName = "same_nbt_shulker_stackable")
|
||||||
|
public static boolean nbtShulkerStackable = false;
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package fun.bm.lophine.config.modules.function;
|
||||||
|
|
||||||
|
import me.earthme.luminol.config.IConfigModule;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||||
|
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||||
|
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||||
|
|
||||||
|
@ConfigClassInfo(configAttribution = EnumConfigCategory.FUNCTION, mainName = "language")
|
||||||
|
public class LanguageConfig implements IConfigModule {
|
||||||
|
@TransformedConfig(name = "lang", category = {"optimizations", "language"})
|
||||||
|
@ConfigInfo(baseName = "lang", comments = """
|
||||||
|
Please use the key from https://minecraft.wiki/w/Language
|
||||||
|
Sample of format: en_us zh_cn zh_hk zh_tw""")
|
||||||
|
public static String lang = "en_us";
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
package fun.bm.lophine.config.modules.function;
|
||||||
|
|
||||||
|
import me.earthme.luminol.config.IConfigModule;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||||
|
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||||
|
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||||
|
|
||||||
|
@ConfigClassInfo(configAttribution = EnumConfigCategory.FUNCTION, mainName = "old-feature")
|
||||||
|
public class OldFeatureConfig implements IConfigModule {
|
||||||
|
@TransformedConfig(name = "spawn_invulnerable_time", category = {"misc", "old-feature"})
|
||||||
|
@ConfigInfo(baseName = "spawn_invulnerable_time")
|
||||||
|
public static boolean spawnInvulnerableTime = false;
|
||||||
|
|
||||||
|
@TransformedConfig(name = "old_zombie_reinforcement", category = {"misc", "old-feature"})
|
||||||
|
@ConfigInfo(baseName = "old_zombie_reinforcement")
|
||||||
|
public static boolean oldZombieReinforcement = false;
|
||||||
|
|
||||||
|
@TransformedConfig(name = "old_explosion_damage_calculator", category = {"misc", "old-feature"})
|
||||||
|
@ConfigInfo(baseName = "old_explosion_damage_calculator")
|
||||||
|
public static boolean oldExplosionDamageCalculator = false;
|
||||||
|
|
||||||
|
@TransformedConfig(name = "old_raid_behavior", category = {"misc", "old-feature"})
|
||||||
|
@TransformedConfig(name = "give_bad_omen_when_kill_raid_captain", category = {"misc", "revert_raid_changes"}, transformComments = false)
|
||||||
|
@ConfigInfo(baseName = "old_raid_behavior")
|
||||||
|
public static boolean oldRaidBehavior = false;
|
||||||
|
}
|
||||||
+5
-15
@@ -1,27 +1,17 @@
|
|||||||
package fun.bm.lophine.config.modules.misc;
|
package fun.bm.lophine.config.modules.function;
|
||||||
|
|
||||||
import me.earthme.luminol.config.EnumConfigCategory;
|
|
||||||
import me.earthme.luminol.config.IConfigModule;
|
import me.earthme.luminol.config.IConfigModule;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||||
import me.earthme.luminol.config.flags.TransformedConfig;
|
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||||
|
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||||
|
|
||||||
|
@ConfigClassInfo(configAttribution = EnumConfigCategory.FUNCTION, mainName = "redstone")
|
||||||
public class RedStoneConfig implements IConfigModule {
|
public class RedStoneConfig implements IConfigModule {
|
||||||
|
@TransformedConfig(name = "shears_rotate", category = {"misc", "redstone"})
|
||||||
@TransformedConfig(name = "allow_skip_cooldown", category = {"misc", "redstone"})
|
@TransformedConfig(name = "allow_skip_cooldown", category = {"misc", "redstone"})
|
||||||
@ConfigInfo(baseName = "shears_rotate", comments =
|
@ConfigInfo(baseName = "shears_rotate", comments =
|
||||||
"""
|
"""
|
||||||
Allows you to use the Shears to right-click to rotate the block.""")
|
Allows you to use the Shears to right-click to rotate the block.""")
|
||||||
public static boolean shears = false;
|
public static boolean shears = false;
|
||||||
|
|
||||||
@ConfigInfo(baseName = "vanilla_hopper")
|
|
||||||
public static boolean vanillaHopper = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumConfigCategory getCategory() {
|
|
||||||
return EnumConfigCategory.MISC;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBaseName() {
|
|
||||||
return "redstone";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
package fun.bm.lophine.config.modules.function;
|
||||||
|
|
||||||
|
import me.earthme.luminol.config.IConfigModule;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||||
|
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||||
|
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@ConfigClassInfo(configAttribution = EnumConfigCategory.FUNCTION, mainName = "survux-protocol")
|
||||||
|
public class SurvuxProtocolConfig implements IConfigModule {
|
||||||
|
@TransformedConfig(name = "entity-protocol", category = {"misc", "survux-protocol"})
|
||||||
|
@ConfigInfo(baseName = "entity-protocol")
|
||||||
|
public static boolean entityProtocol = false;
|
||||||
|
|
||||||
|
@TransformedConfig(name = "hud-logger-protocol", category = {"misc", "survux-protocol"})
|
||||||
|
@ConfigInfo(baseName = "hud-logger-protocol")
|
||||||
|
public static boolean hudLoggerProtocol = false;
|
||||||
|
|
||||||
|
@TransformedConfig(name = "hud-metadata-protocol", category = {"misc", "survux-protocol"})
|
||||||
|
@ConfigInfo(baseName = "hud-metadata-protocol")
|
||||||
|
public static boolean hudMetadataProtocol = false;
|
||||||
|
|
||||||
|
@TransformedConfig(name = "hud-metadata-share-seed", category = {"misc", "survux-protocol"})
|
||||||
|
@ConfigInfo(baseName = "hud-metadata-share-seed")
|
||||||
|
public static boolean hudMetadataShareSeed = false;
|
||||||
|
|
||||||
|
@TransformedConfig(name ="structure-protocol", category = {"misc", "survux-protocol"})
|
||||||
|
@ConfigInfo(baseName = "structure-protocol")
|
||||||
|
public static boolean structureProtocol = false;
|
||||||
|
|
||||||
|
@TransformedConfig(name = "hud-enabled-loggers", category = {"misc", "survux-protocol"})
|
||||||
|
@ConfigInfo(baseName = "hud-enabled-loggers")
|
||||||
|
public static List<String> hudEnabledLoggers = List.of("tps", "mob_caps");
|
||||||
|
|
||||||
|
@TransformedConfig(name = "hud-update-interval", category = {"misc", "survux-protocol"})
|
||||||
|
@ConfigInfo(baseName = "hud-update-interval")
|
||||||
|
public static int hudUpdateInterval = 1;
|
||||||
|
|
||||||
|
@TransformedConfig(name = "litematics-enabled", category = {"misc", "survux-protocol"})
|
||||||
|
@ConfigInfo(baseName = "litematics-enabled")
|
||||||
|
public static boolean litematicsEnabled = false;
|
||||||
|
|
||||||
|
@TransformedConfig(name = "litematics-max-nbt-size", category = {"misc", "survux-protocol"})
|
||||||
|
@ConfigInfo(baseName = "litematics-max-nbt-size")
|
||||||
|
public static int litematicsMaxNbtSize = 2097152;
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package fun.bm.lophine.config.modules.function;
|
||||||
|
|
||||||
|
import me.earthme.luminol.config.IConfigModule;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||||
|
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||||
|
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||||
|
|
||||||
|
@ConfigClassInfo(configAttribution = EnumConfigCategory.MISC, mainName = "villager")
|
||||||
|
public class VillagerConfig implements IConfigModule {
|
||||||
|
@TransformedConfig(name = "villager-infinite-trade", category = {"misc", "villager"})
|
||||||
|
@TransformedConfig(name = "villager-infinite-trade", category = {"misc", "villager-config"})
|
||||||
|
@ConfigInfo(baseName = "villager-infinite-trade", comments =
|
||||||
|
"""
|
||||||
|
Allow villager infinite trade (limit of 524288 times)
|
||||||
|
---- we won't edit saved data, only edit in send data to client.""")
|
||||||
|
public static boolean villagerInfiniteTrade = false;
|
||||||
|
}
|
||||||
-37
@@ -1,37 +0,0 @@
|
|||||||
package fun.bm.lophine.config.modules.misc;
|
|
||||||
|
|
||||||
import me.earthme.luminol.config.EnumConfigCategory;
|
|
||||||
import me.earthme.luminol.config.IConfigModule;
|
|
||||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
|
||||||
|
|
||||||
public class ContainerExpansionConfig implements IConfigModule {
|
|
||||||
@ConfigInfo(baseName = "barrel_rows", comments =
|
|
||||||
"""
|
|
||||||
range: 1~6""")
|
|
||||||
public static int barrelRows = 3;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "enderchest_rows", comments =
|
|
||||||
"""
|
|
||||||
range: 1~6""")
|
|
||||||
public static int enderchestRows = 3;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "shulker_stackable_count", comments =
|
|
||||||
"""
|
|
||||||
range: 1~64""")
|
|
||||||
public static int shulkerCount = 1;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "same_nbt_shulker_stackable", comments =
|
|
||||||
"""
|
|
||||||
range: 1~64""")
|
|
||||||
public static boolean nbtShulkerStackable = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumConfigCategory getCategory() {
|
|
||||||
return EnumConfigCategory.MISC;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBaseName() {
|
|
||||||
return "container_expansion";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+3
-11
@@ -1,9 +1,11 @@
|
|||||||
package fun.bm.lophine.config.modules.misc;
|
package fun.bm.lophine.config.modules.misc;
|
||||||
|
|
||||||
import me.earthme.luminol.config.EnumConfigCategory;
|
|
||||||
import me.earthme.luminol.config.IConfigModule;
|
import me.earthme.luminol.config.IConfigModule;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||||
|
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||||
|
|
||||||
|
@ConfigClassInfo(configAttribution = EnumConfigCategory.MISC, mainName = "disable-check")
|
||||||
public class DisableCheckConfig implements IConfigModule {
|
public class DisableCheckConfig implements IConfigModule {
|
||||||
@ConfigInfo(baseName = "disable-op-move-check", comments = """
|
@ConfigInfo(baseName = "disable-op-move-check", comments = """
|
||||||
Disable the check for the operator's move check""")
|
Disable the check for the operator's move check""")
|
||||||
@@ -12,14 +14,4 @@ public class DisableCheckConfig implements IConfigModule {
|
|||||||
@ConfigInfo(baseName = "disable-op-fly-check", comments = """
|
@ConfigInfo(baseName = "disable-op-fly-check", comments = """
|
||||||
Disable the check for the operator's fly check""")
|
Disable the check for the operator's fly check""")
|
||||||
public static boolean disableOpFlyCheck = false;
|
public static boolean disableOpFlyCheck = false;
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumConfigCategory getCategory() {
|
|
||||||
return EnumConfigCategory.MISC;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBaseName() {
|
|
||||||
return "disable-check";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
package fun.bm.lophine.config.modules.misc;
|
|
||||||
|
|
||||||
import me.earthme.luminol.config.EnumConfigCategory;
|
|
||||||
import me.earthme.luminol.config.IConfigModule;
|
|
||||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
|
||||||
|
|
||||||
public class OldFeatureConfig implements IConfigModule {
|
|
||||||
@ConfigInfo(baseName = "spawn_invulnerable_time")
|
|
||||||
public static boolean spawnInvulnerableTime = false;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "old_zombie_reinforcement")
|
|
||||||
public static boolean oldZombieReinforcement = false;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "old_explosion_damage_calculator")
|
|
||||||
public static boolean oldExplosionDamageCalculator = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumConfigCategory getCategory() {
|
|
||||||
return EnumConfigCategory.MISC;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBaseName() {
|
|
||||||
return "old-feature";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-54
@@ -1,54 +0,0 @@
|
|||||||
package fun.bm.lophine.config.modules.misc;
|
|
||||||
|
|
||||||
import me.earthme.luminol.config.EnumConfigCategory;
|
|
||||||
import me.earthme.luminol.config.IConfigModule;
|
|
||||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
|
||||||
|
|
||||||
public class RaidChangesConfig implements IConfigModule {
|
|
||||||
@ConfigInfo(baseName = "allow_skip_cooldown", comments =
|
|
||||||
"""
|
|
||||||
Allow players with bad omen to skip a
|
|
||||||
30-second cooldown and trigger attacks directly""")
|
|
||||||
public static boolean trigger = false;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "give_bad_omen_when_kill_raid_captain", comments =
|
|
||||||
"""
|
|
||||||
Enable players to obtain a bad omen
|
|
||||||
effect when killing the raid captain""")
|
|
||||||
public static boolean effect = false;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "bad_omen_infinite", comments =
|
|
||||||
"""
|
|
||||||
Enable bad omen effect infinite time
|
|
||||||
--- this config is not old version's function""")
|
|
||||||
public static boolean infinite = false;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "skip_height_check", comments =
|
|
||||||
"""
|
|
||||||
Disable y <= 96 check.
|
|
||||||
If you enabled use_old_position_find, this config
|
|
||||||
will useless and always behavior of enabled""")
|
|
||||||
public static boolean heightCheck = false;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "skip_self_raid_check", comments =
|
|
||||||
"""
|
|
||||||
Disable raid self check
|
|
||||||
--- this config is not old version's function""")
|
|
||||||
public static boolean selfCheck = false;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "use_old_position_find", comments =
|
|
||||||
"""
|
|
||||||
Revert Old raid's find spawn position logic
|
|
||||||
--- This revert MC-274911""")
|
|
||||||
public static boolean posRevert = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumConfigCategory getCategory() {
|
|
||||||
return EnumConfigCategory.MISC;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBaseName() {
|
|
||||||
return "revert_raid_changes";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-46
@@ -1,46 +0,0 @@
|
|||||||
package fun.bm.lophine.config.modules.misc;
|
|
||||||
|
|
||||||
import me.earthme.luminol.config.EnumConfigCategory;
|
|
||||||
import me.earthme.luminol.config.IConfigModule;
|
|
||||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class SurvuxProtocolConfig implements IConfigModule {
|
|
||||||
@ConfigInfo(baseName = "entity-protocol")
|
|
||||||
public static boolean entityProtocol = false;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "hud-logger-protocol")
|
|
||||||
public static boolean hudLoggerProtocol = false;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "hud-metadata-protocol")
|
|
||||||
public static boolean hudMetadataProtocol = false;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "hud-metadata-share-seed")
|
|
||||||
public static boolean hudMetadataShareSeed = false;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "structure-protocol")
|
|
||||||
public static boolean structureProtocol = false;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "hud-enabled-loggers")
|
|
||||||
public static List<String> hudEnabledLoggers = List.of("tps", "mob_caps");
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "hud-update-interval")
|
|
||||||
public static int hudUpdateInterval = 1;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "litematics-enabled")
|
|
||||||
public static boolean litematicsEnabled = false;
|
|
||||||
|
|
||||||
@ConfigInfo(baseName = "litematics-max-nbt-size")
|
|
||||||
public static int litematicsMaxNbtSize = 2097152;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumConfigCategory getCategory() {
|
|
||||||
return EnumConfigCategory.MISC;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBaseName() {
|
|
||||||
return "servux-protocol";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package fun.bm.lophine.config.modules.misc;
|
|
||||||
|
|
||||||
import me.earthme.luminol.config.EnumConfigCategory;
|
|
||||||
import me.earthme.luminol.config.IConfigModule;
|
|
||||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
|
||||||
|
|
||||||
public class VillagerConfig implements IConfigModule {
|
|
||||||
@ConfigInfo(baseName = "villager-infinite-trade", comments =
|
|
||||||
"""
|
|
||||||
Allow villager infinite trade (limit of 524288 times)
|
|
||||||
---- we won't edit saved data, only edit in send data to client.""")
|
|
||||||
public static boolean villagerInfiniteTrade = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumConfigCategory getCategory() {
|
|
||||||
return EnumConfigCategory.MISC;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBaseName() {
|
|
||||||
return "villager-config";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
package fun.bm.lophine.config.modules.optimizations;
|
|
||||||
|
|
||||||
import me.earthme.luminol.config.EnumConfigCategory;
|
|
||||||
import me.earthme.luminol.config.IConfigModule;
|
|
||||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
|
||||||
|
|
||||||
public class LanguageConfig implements IConfigModule {
|
|
||||||
@ConfigInfo(baseName = "lang", comments = """
|
|
||||||
Please use the key from https://minecraft.wiki/w/Language
|
|
||||||
Sample of format: en_us zh_cn zh_hk zh_tw""")
|
|
||||||
public static String lang = "en_us";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumConfigCategory getCategory() {
|
|
||||||
return EnumConfigCategory.OPTIMIZATIONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBaseName() {
|
|
||||||
return "language";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-21
@@ -1,21 +0,0 @@
|
|||||||
package fun.bm.lophine.config.modules.optimizations;
|
|
||||||
|
|
||||||
import me.earthme.luminol.config.EnumConfigCategory;
|
|
||||||
import me.earthme.luminol.config.IConfigModule;
|
|
||||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
|
||||||
|
|
||||||
public class NetworkConfig implements IConfigModule {
|
|
||||||
@ConfigInfo(baseName = "unlimit-packet", comments = """
|
|
||||||
Disable packet limit""")
|
|
||||||
public static boolean disablePacketLimit = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumConfigCategory getCategory() {
|
|
||||||
return EnumConfigCategory.OPTIMIZATIONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBaseName() {
|
|
||||||
return "network";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+11
-11
@@ -1,11 +1,21 @@
|
|||||||
package fun.bm.lophine.config.modules.removed;
|
package fun.bm.lophine.config.modules.removed;
|
||||||
|
|
||||||
import me.earthme.luminol.config.EnumConfigCategory;
|
|
||||||
import me.earthme.luminol.config.IConfigModule;
|
import me.earthme.luminol.config.IConfigModule;
|
||||||
|
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||||
import me.earthme.luminol.config.flags.TransformedConfig;
|
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||||
|
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||||
|
|
||||||
|
@ConfigClassInfo(configAttribution = EnumConfigCategory.REMOVED, mainName = "removed_config")
|
||||||
public class RemovedConfig implements IConfigModule {
|
public class RemovedConfig implements IConfigModule {
|
||||||
|
@TransformedConfig(name = "disable_end_crystal_check", category = {"fixes", "end_crystal"}, transform = false)
|
||||||
|
@TransformedConfig(name = "disable_end_crystal_check", category = {"misc", "end_crystal"}, transform = false)
|
||||||
|
@TransformedConfig(name = "allow_skip_cooldown", category = {"misc", "revert_raid_changes"}, transform = false)
|
||||||
|
@TransformedConfig(name = "bad_omen_infinite", category = {"misc", "revert_raid_changes"}, transform = false)
|
||||||
|
@TransformedConfig(name = "skip_height_check", category = {"misc", "revert_raid_changes"}, transform = false)
|
||||||
|
@TransformedConfig(name = "skip_self_raid_check", category = {"misc", "revert_raid_changes"}, transform = false)
|
||||||
|
@TransformedConfig(name = "use_old_position_find", category = {"misc", "revert_raid_changes"}, transform = false)
|
||||||
|
@TransformedConfig(name = "vanilla_hopper", category = {"misc", "redstone"}, transform = false)
|
||||||
@TransformedConfig(name = "old_replaceable_by_mushrooms", category = {"misc", "old-feature"}, transform = false)
|
@TransformedConfig(name = "old_replaceable_by_mushrooms", category = {"misc", "old-feature"}, transform = false)
|
||||||
@TransformedConfig(name = "old_nether_portal_collision", category = {"misc", "old-feature"}, transform = false)
|
@TransformedConfig(name = "old_nether_portal_collision", category = {"misc", "old-feature"}, transform = false)
|
||||||
@TransformedConfig(name = "better_shulker_box", category = {"misc", "container_expansion"}, transform = false)
|
@TransformedConfig(name = "better_shulker_box", category = {"misc", "container_expansion"}, transform = false)
|
||||||
@@ -13,14 +23,4 @@ public class RemovedConfig implements IConfigModule {
|
|||||||
"""
|
"""
|
||||||
RemovedConfig redirect to here, no any function.""")
|
RemovedConfig redirect to here, no any function.""")
|
||||||
public static boolean enabled = true;
|
public static boolean enabled = true;
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumConfigCategory getCategory() {
|
|
||||||
return EnumConfigCategory.REMOVED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBaseName() {
|
|
||||||
return "removed_config";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,10 @@ import com.google.gson.JsonElement;
|
|||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
import fun.bm.lophine.config.modules.optimizations.LanguageConfig;
|
import com.mojang.logging.LogUtils;
|
||||||
|
import fun.bm.lophine.config.modules.function.LanguageConfig;
|
||||||
|
import me.earthme.luminol.config.ConfigManager;
|
||||||
|
import me.earthme.luminol.config.ConfigsInstance;
|
||||||
import net.minecraft.DetectedVersion;
|
import net.minecraft.DetectedVersion;
|
||||||
import net.minecraft.locale.DeprecatedTranslationsInfo;
|
import net.minecraft.locale.DeprecatedTranslationsInfo;
|
||||||
import net.minecraft.locale.Language;
|
import net.minecraft.locale.Language;
|
||||||
@@ -12,8 +15,8 @@ import net.minecraft.network.chat.FormattedText;
|
|||||||
import net.minecraft.network.chat.Style;
|
import net.minecraft.network.chat.Style;
|
||||||
import net.minecraft.util.FormattedCharSequence;
|
import net.minecraft.util.FormattedCharSequence;
|
||||||
import net.minecraft.util.StringDecomposer;
|
import net.minecraft.util.StringDecomposer;
|
||||||
import org.apache.commons.io.FileUtils;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -23,13 +26,13 @@ import java.net.http.HttpClient;
|
|||||||
import java.net.http.HttpRequest;
|
import java.net.http.HttpRequest;
|
||||||
import java.net.http.HttpResponse;
|
import java.net.http.HttpResponse;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* authored by: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
* authored by: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||||
@@ -37,30 +40,62 @@ import java.util.logging.Logger;
|
|||||||
* Some of diff form Leaves
|
* Some of diff form Leaves
|
||||||
*/
|
*/
|
||||||
public class ServerI18nUtil {
|
public class ServerI18nUtil {
|
||||||
|
private static final Logger logger = LogUtils.getClassLogger();
|
||||||
private static final Logger logger = Logger.getLogger("LangLoader");
|
|
||||||
private static final String VERSION = DetectedVersion.BUILT_IN.name();
|
private static final String VERSION = DetectedVersion.BUILT_IN.name();
|
||||||
private static final String BASE_PATH = "cache/lophine/" + VERSION + "/";
|
private static final String BASE_PATH = "cache/lophine/" + VERSION + "/";
|
||||||
|
private static final String defaultLophineLangPath = "/assets/lophine/lang/en_us.json";
|
||||||
private static final String manifestUrl = "https://launchermeta.mojang.com/mc/game/version_manifest.json";
|
private static final String manifestUrl = "https://launchermeta.mojang.com/mc/game/version_manifest.json";
|
||||||
private static final String resourceBaseUrl = "https://resources.download.minecraft.net/";
|
private static final String resourceBaseUrl = "https://resources.download.minecraft.net/";
|
||||||
|
// pre-load
|
||||||
|
private static CompletableFuture<Void> preloadTask;
|
||||||
|
// paths
|
||||||
private static String langPath;
|
private static String langPath;
|
||||||
private static String assetsPath;
|
private static String assetsPath;
|
||||||
private static String versionPath;
|
private static String versionPath;
|
||||||
private static String manifestPath;
|
private static String manifestPath;
|
||||||
private static String langJsonPath;
|
private static String langJsonPath;
|
||||||
|
private static String lophineLangPath;
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
if (Objects.equals(LanguageConfig.lang, "en_us")) {
|
if (Objects.equals(LanguageConfig.lang, "en_us")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
langPath = BASE_PATH + "lang/" + LanguageConfig.lang + ".json";
|
langPath = BASE_PATH + "lang/" + LanguageConfig.lang + ".json";
|
||||||
|
langJsonPath = "minecraft/lang/" + LanguageConfig.lang + ".json";
|
||||||
|
lophineLangPath = "/assets/Lophine/lang/" + LanguageConfig.lang + ".json";
|
||||||
|
logger.info("Starting load language: {}", LanguageConfig.lang);
|
||||||
|
preloadTask.thenAcceptAsync(v -> loadI18n(LanguageConfig.lang, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void preInit() {
|
||||||
assetsPath = BASE_PATH + "assets.json";
|
assetsPath = BASE_PATH + "assets.json";
|
||||||
versionPath = BASE_PATH + VERSION + ".json";
|
versionPath = BASE_PATH + VERSION + ".json";
|
||||||
manifestPath = BASE_PATH + "manifest.json";
|
manifestPath = BASE_PATH + "manifest.json";
|
||||||
langJsonPath = "minecraft/lang/" + LanguageConfig.lang + ".json";
|
preloadTask = CompletableFuture.runAsync(() -> preLoadI18n(2));
|
||||||
logger.info("Starting load language: " + LanguageConfig.lang);
|
}
|
||||||
CompletableFuture.runAsync(() -> loadI18n(LanguageConfig.lang, 2));
|
|
||||||
|
private static void preLoadI18n(int retryTime) {
|
||||||
|
try {
|
||||||
|
if (!Files.exists(Path.of(assetsPath))) {
|
||||||
|
downloadAssets(true);
|
||||||
|
}
|
||||||
|
} catch (UnsupportedLanguageException e) {
|
||||||
|
logger.warn("Unsupported language: {}", LanguageConfig.lang);
|
||||||
|
// Fallback to English
|
||||||
|
final ConfigsInstance configsInstance = ConfigManager.configfiles.get("lophine");
|
||||||
|
configsInstance.setConfig(new String[]{"optimizations", "lang"}, "en_us");
|
||||||
|
configsInstance.reloadAsync();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (e instanceof MalformedJsonException malformedJson) {
|
||||||
|
malformedJson.clean();
|
||||||
|
}
|
||||||
|
logger.warn("Failed to download language list file: ", e);
|
||||||
|
if (retryTime > 0) {
|
||||||
|
preLoadI18n(retryTime - 1);
|
||||||
|
} else {
|
||||||
|
logger.error("Failed to download language list file for many times, skip pre-load language.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadI18n(String lang, int retryTime) {
|
private static void loadI18n(String lang, int retryTime) {
|
||||||
@@ -69,15 +104,16 @@ public class ServerI18nUtil {
|
|||||||
downloadLang(true);
|
downloadLang(true);
|
||||||
}
|
}
|
||||||
Language.inject(createLangInstance());
|
Language.inject(createLangInstance());
|
||||||
logger.info("Successfully loaded language: " + lang);
|
logger.info("Successfully loaded language: {}", lang);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.warning("Failed to load language file for " + lang + "\n" + e);
|
if (e instanceof MalformedJsonException malformedJson) {
|
||||||
|
malformedJson.clean();
|
||||||
|
}
|
||||||
|
logger.warn("Failed to load language file for {}", lang, e);
|
||||||
if (retryTime > 0) {
|
if (retryTime > 0) {
|
||||||
cleanCache();
|
|
||||||
loadI18n(lang, retryTime - 1);
|
loadI18n(lang, retryTime - 1);
|
||||||
} else {
|
} else {
|
||||||
logger.severe("Failed to load for many times, use default lang \"en_us\" instead");
|
logger.error("Failed to load for many times, use default lang \"en_us\" instead");
|
||||||
cleanCache();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,6 +130,10 @@ public class ServerI18nUtil {
|
|||||||
|
|
||||||
JsonObject langEntry = json.getAsJsonObject("objects").getAsJsonObject(langJsonPath);
|
JsonObject langEntry = json.getAsJsonObject("objects").getAsJsonObject(langJsonPath);
|
||||||
|
|
||||||
|
if (langEntry == null) {
|
||||||
|
throw new UnsupportedLanguageException();
|
||||||
|
}
|
||||||
|
|
||||||
String hash = langEntry.get("hash").getAsString();
|
String hash = langEntry.get("hash").getAsString();
|
||||||
if (hash == null || hash.length() < 2) {
|
if (hash == null || hash.length() < 2) {
|
||||||
throw new IllegalArgumentException("Invalid hash value");
|
throw new IllegalArgumentException("Invalid hash value");
|
||||||
@@ -145,37 +185,31 @@ public class ServerI18nUtil {
|
|||||||
fetchAndSave(versionUrl, versionPath);
|
fetchAndSave(versionUrl, versionPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String createHttpResponse(String path) throws IOException, InterruptedException {
|
private static byte[] fetch(String urlString) throws IOException, InterruptedException {
|
||||||
try {
|
try {
|
||||||
HttpResponse<String> response;
|
HttpResponse<String> response;
|
||||||
try (HttpClient httpClient = HttpClient.newHttpClient()) {
|
try (HttpClient httpClient = HttpClient.newHttpClient()) {
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
.uri(URI.create(path))
|
.uri(URI.create(urlString))
|
||||||
|
.timeout(Duration.ofSeconds(10))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
}
|
}
|
||||||
|
|
||||||
int responseCode = response.statusCode();
|
int responseCode = response.statusCode();
|
||||||
if (responseCode != 200) {
|
if (responseCode != 200) {
|
||||||
logger.info("Unexpected response code: " + responseCode);
|
logger.info("Unexpected response code: {}", responseCode);
|
||||||
logger.info("Response body: " + response.body());
|
logger.info("Response body: {}", response.body());
|
||||||
throw new UnsupportedEncodingException("Unexpected response code");
|
throw new UnsupportedEncodingException("Unexpected response code");
|
||||||
} else {
|
} else {
|
||||||
return response.body();
|
return response.body().getBytes();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.warning("Error in getting info: " + e.getMessage());
|
logger.warn("Error in getting info!");
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] fetch(String urlString) throws IOException, InterruptedException {
|
|
||||||
String ret = createHttpResponse(urlString);
|
|
||||||
return ret.getBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void fetchAndSave(String url, String savePath) throws IOException, InterruptedException {
|
private static void fetchAndSave(String url, String savePath) throws IOException, InterruptedException {
|
||||||
byte[] data = fetch(url);
|
byte[] data = fetch(url);
|
||||||
Path outputPath = Path.of(savePath);
|
Path outputPath = Path.of(savePath);
|
||||||
@@ -183,23 +217,15 @@ public class ServerI18nUtil {
|
|||||||
Files.write(outputPath, data, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
|
Files.write(outputPath, data, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void cleanCache() {
|
|
||||||
try {
|
|
||||||
FileUtils.deleteDirectory(Path.of(BASE_PATH).toFile());
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.severe("Cache cleanup failed: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static JsonObject loadJson(String path) {
|
private static JsonObject loadJson(String path) {
|
||||||
try {
|
try {
|
||||||
byte[] data = Files.readAllBytes(Paths.get(path));
|
byte[] data = Files.readAllBytes(Paths.get(path));
|
||||||
return JsonParser.parseString(new String(data)).getAsJsonObject();
|
return JsonParser.parseString(new String(data)).getAsJsonObject();
|
||||||
} catch (JsonSyntaxException e) {
|
} catch (JsonSyntaxException e) {
|
||||||
logger.warning("Corrupt json file: " + e);
|
logger.warn("Corrupt json file!");
|
||||||
throw e;
|
throw new MalformedJsonException(e, path);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.warning("Failed to load local JSON: " + e);
|
logger.warn("Failed to load local JSON!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -208,6 +234,7 @@ public class ServerI18nUtil {
|
|||||||
DeprecatedTranslationsInfo deprecatedTranslationsInfo = DeprecatedTranslationsInfo.loadFromDefaultResource();
|
DeprecatedTranslationsInfo deprecatedTranslationsInfo = DeprecatedTranslationsInfo.loadFromDefaultResource();
|
||||||
Map<String, String> map = new HashMap<>();
|
Map<String, String> map = new HashMap<>();
|
||||||
parseTranslations(map::put);
|
parseTranslations(map::put);
|
||||||
|
loadLophineI18n(map::put);
|
||||||
deprecatedTranslationsInfo.applyToMap(map);
|
deprecatedTranslationsInfo.applyToMap(map);
|
||||||
final Map<String, String> map1 = Map.copyOf(map);
|
final Map<String, String> map1 = Map.copyOf(map);
|
||||||
return new Language() {
|
return new Language() {
|
||||||
@@ -237,16 +264,52 @@ public class ServerI18nUtil {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void loadLophineI18n(BiConsumer<String, String> bi) {
|
||||||
|
if (Language.class.getResource(lophineLangPath) != null) {
|
||||||
|
Language.parseTranslations(bi, lophineLangPath);
|
||||||
|
} else {
|
||||||
|
loadLophineI18nDefault(bi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadLophineI18nDefault(BiConsumer<String, String> bi) {
|
||||||
|
if (Language.class.getResource(defaultLophineLangPath) != null) {
|
||||||
|
Language.parseTranslations(bi, defaultLophineLangPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void parseTranslations(BiConsumer<String, String> output) throws IOException {
|
private static void parseTranslations(BiConsumer<String, String> output) throws IOException {
|
||||||
Path filePath = Path.of(langPath);
|
Path filePath = Path.of(langPath);
|
||||||
try (InputStream fileStream = Files.newInputStream(filePath)) {
|
try (InputStream fileStream = Files.newInputStream(filePath)) {
|
||||||
Language.loadFromJson(fileStream, output);
|
Language.loadFromJson(fileStream, output);
|
||||||
} catch (NoSuchFileException noSuchFileException) {
|
} catch (NoSuchFileException e) {
|
||||||
logger.warning("Couldn't find language file: " + langPath);
|
logger.warn("Couldn't find language file: {}", langPath);
|
||||||
throw noSuchFileException;
|
throw e;
|
||||||
|
} catch (JsonSyntaxException e) {
|
||||||
|
throw new MalformedJsonException(e, langPath);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.warning("Failed to load language from filesystem " + filePath + "\n" + e);
|
logger.warn("Failed to load language from filesystem {}", filePath);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class UnsupportedLanguageException extends Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MalformedJsonException extends RuntimeException {
|
||||||
|
private final Path path;
|
||||||
|
|
||||||
|
protected MalformedJsonException(Throwable root, String path) {
|
||||||
|
super(root);
|
||||||
|
this.path = Path.of(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clean() {
|
||||||
|
try {
|
||||||
|
Files.delete(path);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.info("Failed to delete malformed JSON file: {}", path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+2
-1
@@ -18,6 +18,7 @@
|
|||||||
package org.leavesmc.leaves.protocol.servux;
|
package org.leavesmc.leaves.protocol.servux;
|
||||||
|
|
||||||
import com.mojang.logging.LogUtils;
|
import com.mojang.logging.LogUtils;
|
||||||
|
import fun.bm.lophine.config.modules.function.SurvuxProtocolConfig;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.minecraft.Util;
|
import net.minecraft.Util;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
@@ -152,7 +153,7 @@ public class ServuxEntityDataProtocol implements LeavesProtocol {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isActive() {
|
public boolean isActive() {
|
||||||
return fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.entityProtocol;
|
return SurvuxProtocolConfig.entityProtocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum EntityDataPayloadType {
|
public enum EntityDataPayloadType {
|
||||||
|
|||||||
+7
-6
@@ -20,6 +20,7 @@ package org.leavesmc.leaves.protocol.servux;
|
|||||||
import com.google.common.collect.HashBasedTable;
|
import com.google.common.collect.HashBasedTable;
|
||||||
import com.google.common.collect.Table;
|
import com.google.common.collect.Table;
|
||||||
import com.mojang.serialization.DataResult;
|
import com.mojang.serialization.DataResult;
|
||||||
|
import fun.bm.lophine.config.modules.function.SurvuxProtocolConfig;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
@@ -103,7 +104,7 @@ public class ServuxHudDataProtocol implements LeavesProtocol {
|
|||||||
metadata.putString("id", HudDataPayload.CHANNEL.toString());
|
metadata.putString("id", HudDataPayload.CHANNEL.toString());
|
||||||
metadata.putInt("version", PROTOCOL_VERSION);
|
metadata.putInt("version", PROTOCOL_VERSION);
|
||||||
metadata.putString("servux", ServuxProtocol.SERVUX_STRING);
|
metadata.putString("servux", ServuxProtocol.SERVUX_STRING);
|
||||||
if (fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.hudLoggerProtocol) {
|
if (SurvuxProtocolConfig.hudLoggerProtocol) {
|
||||||
CompoundTag nbt = new CompoundTag();
|
CompoundTag nbt = new CompoundTag();
|
||||||
for (DataLogger.Type type : DataLogger.Type.VALUES) {
|
for (DataLogger.Type type : DataLogger.Type.VALUES) {
|
||||||
nbt.putBoolean(type.getSerializedName(), isLoggerTypeEnabled(type));
|
nbt.putBoolean(type.getSerializedName(), isLoggerTypeEnabled(type));
|
||||||
@@ -184,7 +185,7 @@ public class ServuxHudDataProtocol implements LeavesProtocol {
|
|||||||
metadata.putInt("spawnPosZ", spawnPos.getZ());
|
metadata.putInt("spawnPosZ", spawnPos.getZ());
|
||||||
metadata.putInt("spawnChunkRadius", level.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS));
|
metadata.putInt("spawnChunkRadius", level.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS));
|
||||||
|
|
||||||
if (fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.hudMetadataShareSeed) {
|
if (SurvuxProtocolConfig.hudMetadataShareSeed) {
|
||||||
metadata.putLong("worldSeed", level.getSeed());
|
metadata.putLong("worldSeed", level.getSeed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,7 +217,7 @@ public class ServuxHudDataProtocol implements LeavesProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isLoggerTypeEnabled(DataLogger.Type type) {
|
private static boolean isLoggerTypeEnabled(DataLogger.Type type) {
|
||||||
return fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.hudEnabledLoggers.contains(type.getSerializedName());
|
return SurvuxProtocolConfig.hudEnabledLoggers.contains(type.getSerializedName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ProtocolHandler.Ticker
|
@ProtocolHandler.Ticker
|
||||||
@@ -232,13 +233,13 @@ public class ServuxHudDataProtocol implements LeavesProtocol {
|
|||||||
|
|
||||||
@ProtocolHandler.Ticker(tickerId = "logger")
|
@ProtocolHandler.Ticker(tickerId = "logger")
|
||||||
public void loggerTick() {
|
public void loggerTick() {
|
||||||
if (!fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.hudLoggerProtocol) {
|
if (!SurvuxProtocolConfig.hudLoggerProtocol) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MinecraftServer server = MinecraftServer.getServer();
|
MinecraftServer server = MinecraftServer.getServer();
|
||||||
|
|
||||||
if (server.getTickCount() % fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.hudUpdateInterval == 0) {
|
if (server.getTickCount() % SurvuxProtocolConfig.hudUpdateInterval == 0) {
|
||||||
LOGGERS.forEach((type, logger) -> {
|
LOGGERS.forEach((type, logger) -> {
|
||||||
if (!isLoggerTypeEnabled(type)) {
|
if (!isLoggerTypeEnabled(type)) {
|
||||||
return;
|
return;
|
||||||
@@ -276,7 +277,7 @@ public class ServuxHudDataProtocol implements LeavesProtocol {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isActive() {
|
public boolean isActive() {
|
||||||
return fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.hudMetadataProtocol;
|
return SurvuxProtocolConfig.hudMetadataProtocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+2
-1
@@ -18,6 +18,7 @@
|
|||||||
package org.leavesmc.leaves.protocol.servux;
|
package org.leavesmc.leaves.protocol.servux;
|
||||||
|
|
||||||
import com.mojang.logging.LogUtils;
|
import com.mojang.logging.LogUtils;
|
||||||
|
import fun.bm.lophine.config.modules.function.SurvuxProtocolConfig;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import it.unimi.dsi.fastutil.longs.LongIterator;
|
import it.unimi.dsi.fastutil.longs.LongIterator;
|
||||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||||
@@ -335,7 +336,7 @@ public class ServuxStructuresProtocol implements LeavesProtocol {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isActive() {
|
public boolean isActive() {
|
||||||
return fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.structureProtocol;
|
return SurvuxProtocolConfig.structureProtocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum StructuresPayloadType {
|
public enum StructuresPayloadType {
|
||||||
|
|||||||
+3
-2
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package org.leavesmc.leaves.protocol.servux.litematics;
|
package org.leavesmc.leaves.protocol.servux.litematics;
|
||||||
|
|
||||||
|
import fun.bm.lophine.config.modules.function.SurvuxProtocolConfig;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
@@ -132,7 +133,7 @@ public class ServuxLitematicsProtocol implements LeavesProtocol {
|
|||||||
}
|
}
|
||||||
playerSession.remove(uuid);
|
playerSession.remove(uuid);
|
||||||
fullPacket.readVarInt();
|
fullPacket.readVarInt();
|
||||||
Tag tag = FriendlyByteBuf.readNbt(fullPacket, new NbtAccounter(fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.litematicsMaxNbtSize == -1 ? Long.MAX_VALUE : fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.litematicsMaxNbtSize, 512));
|
Tag tag = FriendlyByteBuf.readNbt(fullPacket, new NbtAccounter(SurvuxProtocolConfig.litematicsMaxNbtSize == -1 ? Long.MAX_VALUE : SurvuxProtocolConfig.litematicsMaxNbtSize, 512));
|
||||||
if (!(tag instanceof CompoundTag)) {
|
if (!(tag instanceof CompoundTag)) {
|
||||||
ServuxProtocol.LOGGER.error("cannot read nbt tag from packet");
|
ServuxProtocol.LOGGER.error("cannot read nbt tag from packet");
|
||||||
return;
|
return;
|
||||||
@@ -290,7 +291,7 @@ public class ServuxLitematicsProtocol implements LeavesProtocol {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isActive() {
|
public boolean isActive() {
|
||||||
return fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.litematicsEnabled;
|
return SurvuxProtocolConfig.litematicsEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ServuxLitematicaPayloadType {
|
public enum ServuxLitematicaPayloadType {
|
||||||
|
|||||||
@@ -1,220 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
|
||||||
*
|
|
||||||
* Leaves is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Leaves is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.leavesmc.leaves.util;
|
|
||||||
|
|
||||||
import fun.bm.lophine.config.modules.misc.ContainerExpansionConfig;
|
|
||||||
import net.minecraft.core.component.DataComponents;
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.world.entity.item.ItemEntity;
|
|
||||||
import net.minecraft.world.item.BlockItem;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.item.component.CustomData;
|
|
||||||
import net.minecraft.world.item.component.ItemContainerContents;
|
|
||||||
import net.minecraft.world.level.block.ShulkerBoxBlock;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class ItemOverstackUtils {
|
|
||||||
|
|
||||||
private static final List<ItemUtil> overstackUtils = List.of(
|
|
||||||
new ShulkerBox()
|
|
||||||
// new CurseEnchantedBook()
|
|
||||||
);
|
|
||||||
|
|
||||||
public static int getItemStackMaxCount(ItemStack stack) {
|
|
||||||
int size;
|
|
||||||
for (ItemUtil util : overstackUtils) {
|
|
||||||
if ((size = util.getMaxServerStackCount(stack)) != -1) {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return stack.getMaxStackSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getNetworkMaxCount(ItemStack stack) {
|
|
||||||
int size;
|
|
||||||
for (ItemUtil util : overstackUtils) {
|
|
||||||
if ((size = util.getMaxClientStackCount(stack)) != -1) {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return stack.getMaxStackSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean tryStackItems(ItemEntity self, ItemEntity other) {
|
|
||||||
for (ItemUtil util : overstackUtils) {
|
|
||||||
if (util.tryStackItems(self, other)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean hasOverstackingItem() {
|
|
||||||
return overstackUtils.stream().anyMatch(ItemUtil::isEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getItemStackMaxCountReal(ItemStack stack) {
|
|
||||||
CompoundTag nbt = Optional.ofNullable(stack.get(DataComponents.CUSTOM_DATA)).orElse(CustomData.EMPTY).copyTag();
|
|
||||||
return nbt.getInt("Leaves.RealStackSize").orElse(stack.getMaxStackSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ItemStack encodeMaxStackSize(ItemStack itemStack) {
|
|
||||||
int realMaxStackSize = getItemStackMaxCountReal(itemStack);
|
|
||||||
int modifiedMaxStackSize = getNetworkMaxCount(itemStack);
|
|
||||||
if (itemStack.getMaxStackSize() != modifiedMaxStackSize) {
|
|
||||||
itemStack.set(DataComponents.MAX_STACK_SIZE, modifiedMaxStackSize);
|
|
||||||
CompoundTag nbt = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag();
|
|
||||||
nbt.putInt("Leaves.RealStackSize", realMaxStackSize);
|
|
||||||
itemStack.set(DataComponents.CUSTOM_DATA, CustomData.of(nbt));
|
|
||||||
}
|
|
||||||
return itemStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ItemStack decodeMaxStackSize(ItemStack itemStack) {
|
|
||||||
int realMaxStackSize = getItemStackMaxCountReal(itemStack);
|
|
||||||
if (itemStack.getMaxStackSize() != realMaxStackSize) {
|
|
||||||
itemStack.set(DataComponents.MAX_STACK_SIZE, realMaxStackSize);
|
|
||||||
CompoundTag nbt = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag();
|
|
||||||
nbt.remove("Leaves.RealStackSize");
|
|
||||||
if (nbt.isEmpty()) {
|
|
||||||
itemStack.remove(DataComponents.CUSTOM_DATA);
|
|
||||||
} else {
|
|
||||||
itemStack.set(DataComponents.CUSTOM_DATA, CustomData.of(nbt));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return itemStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isStackable(ItemStack itemStack) {
|
|
||||||
return getItemStackMaxCount(itemStack) > 1 && (!itemStack.isDamageableItem() || !itemStack.isDamaged());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private interface ItemUtil {
|
|
||||||
boolean isEnabled();
|
|
||||||
|
|
||||||
boolean tryStackItems(ItemEntity self, ItemEntity other);
|
|
||||||
|
|
||||||
// number -> modified count, -1 -> I don't care
|
|
||||||
int getMaxServerStackCount(ItemStack stack);
|
|
||||||
|
|
||||||
// number -> modified count, -1 -> I don't care
|
|
||||||
default int getMaxClientStackCount(ItemStack stack) {
|
|
||||||
return getMaxServerStackCount(stack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ShulkerBox implements ItemUtil {
|
|
||||||
public static boolean shulkerBoxCheck(@NotNull ItemStack stack1, @NotNull ItemStack stack2) {
|
|
||||||
if (ContainerExpansionConfig.nbtShulkerStackable) {
|
|
||||||
return Objects.equals(stack1.getComponents(), stack2.getComponents());
|
|
||||||
}
|
|
||||||
return shulkerBoxNoItem(stack1) && shulkerBoxNoItem(stack2) && Objects.equals(stack1.getComponents(), stack2.getComponents());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean shulkerBoxNoItem(@NotNull ItemStack stack) {
|
|
||||||
return stack.getComponents().getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY).stream().findAny().isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return ContainerExpansionConfig.shulkerCount > 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean tryStackItems(ItemEntity self, ItemEntity other) {
|
|
||||||
ItemStack selfStack = self.getItem();
|
|
||||||
if (!isEnabled() ||
|
|
||||||
!(selfStack.getItem() instanceof BlockItem blockItem) ||
|
|
||||||
!(blockItem.getBlock() instanceof ShulkerBoxBlock)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ItemStack otherStack = other.getItem();
|
|
||||||
if (selfStack.getItem() == otherStack.getItem()
|
|
||||||
&& shulkerBoxCheck(selfStack, otherStack)
|
|
||||||
&& selfStack.getCount() != ContainerExpansionConfig.shulkerCount) {
|
|
||||||
int amount = Math.min(otherStack.getCount(), ContainerExpansionConfig.shulkerCount - selfStack.getCount());
|
|
||||||
|
|
||||||
selfStack.grow(amount);
|
|
||||||
self.setItem(selfStack);
|
|
||||||
|
|
||||||
self.pickupDelay = Math.max(other.pickupDelay, self.pickupDelay);
|
|
||||||
self.age = Math.min(other.getAge(), self.age);
|
|
||||||
|
|
||||||
otherStack.shrink(amount);
|
|
||||||
if (otherStack.isEmpty()) {
|
|
||||||
other.discard();
|
|
||||||
} else {
|
|
||||||
other.setItem(otherStack);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMaxServerStackCount(ItemStack stack) {
|
|
||||||
if (isEnabled() && stack.getItem() instanceof BlockItem bi &&
|
|
||||||
bi.getBlock() instanceof ShulkerBoxBlock && (ContainerExpansionConfig.nbtShulkerStackable || shulkerBoxNoItem(stack))) {
|
|
||||||
return ContainerExpansionConfig.shulkerCount;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// only use shulker box part
|
|
||||||
/* public static class CurseEnchantedBook implements ItemUtil {
|
|
||||||
public static boolean isCursedEnchantedBook(ItemStack stack) {
|
|
||||||
ItemEnchantments enchantments = stack.getOrDefault(DataComponents.STORED_ENCHANTMENTS, ItemEnchantments.EMPTY);
|
|
||||||
if (enchantments.size() != 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return stack.getBukkitStack().getEnchantmentLevel(org.bukkit.enchantments.Enchantment.BINDING_CURSE) == 1 ||
|
|
||||||
stack.getBukkitStack().getEnchantmentLevel(org.bukkit.enchantments.Enchantment.BINDING_CURSE) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return LeavesConfig.modify.oldMC.allowGrindstoneOverstacking;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean tryStackItems(ItemEntity self, ItemEntity other) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMaxServerStackCount(ItemStack stack) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMaxClientStackCount(ItemStack stack) {
|
|
||||||
if (isEnabled() && isCursedEnchantedBook(stack)) {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||||
|
*
|
||||||
|
* Leaves is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Leaves is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.leavesmc.leaves.util;
|
||||||
|
|
||||||
|
import fun.bm.lophine.config.modules.function.RedStoneConfig;
|
||||||
|
import net.minecraft.Util;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.InteractionResult;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.Items;
|
||||||
|
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||||
|
import net.minecraft.world.item.context.UseOnContext;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.*;
|
||||||
|
import net.minecraft.world.level.block.piston.PistonBaseBlock;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.StateDefinition;
|
||||||
|
import net.minecraft.world.level.block.state.properties.Property;
|
||||||
|
import net.minecraft.world.level.block.state.properties.RailShape;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ShearsWrenchUtil {
|
||||||
|
|
||||||
|
public static InteractionResult tryApplyRotate(UseOnContext context, BlockState blockState) {
|
||||||
|
Level level = context.getLevel();
|
||||||
|
BlockPos clickedPos = context.getClickedPos();
|
||||||
|
Block block = blockState.getBlock();
|
||||||
|
if (!RedStoneConfig.shears || !(block instanceof ObserverBlock || block instanceof DispenserBlock || block instanceof PistonBaseBlock || block instanceof HopperBlock || block instanceof RepeaterBlock || block instanceof ComparatorBlock || block instanceof CrafterBlock || block instanceof LeverBlock || block instanceof CocoaBlock || block instanceof TrapDoorBlock || block instanceof FenceGateBlock || block instanceof LightningRodBlock || block instanceof CalibratedSculkSensorBlock || block instanceof BaseRailBlock)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
StateDefinition<Block, BlockState> blockstatelist = block.getStateDefinition();
|
||||||
|
Property<?> iblockstate;
|
||||||
|
if (block instanceof CrafterBlock) {
|
||||||
|
iblockstate = blockstatelist.getProperty("orientation");
|
||||||
|
} else if (block instanceof BaseRailBlock) {
|
||||||
|
iblockstate = blockstatelist.getProperty("shape");
|
||||||
|
} else {
|
||||||
|
iblockstate = blockstatelist.getProperty("facing");
|
||||||
|
}
|
||||||
|
Player player = context.getPlayer();
|
||||||
|
|
||||||
|
if (iblockstate == null || player == null) {
|
||||||
|
return InteractionResult.FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block instanceof BaseRailBlock) {
|
||||||
|
if (block instanceof RailBlock) {
|
||||||
|
if (blockState.getValue(RailBlock.SHAPE).isSlope()) {
|
||||||
|
return InteractionResult.FAIL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (getNameHelper(blockState, PoweredRailBlock.POWERED).equals("true")) {
|
||||||
|
return InteractionResult.FAIL;
|
||||||
|
}
|
||||||
|
if (blockState.getValue(PoweredRailBlock.SHAPE).isSlope()) {
|
||||||
|
return InteractionResult.FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block instanceof PistonBaseBlock) {
|
||||||
|
if (getNameHelper(blockState, PistonBaseBlock.EXTENDED).equals("true")) {
|
||||||
|
return InteractionResult.FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block instanceof RepeaterBlock || block instanceof ComparatorBlock) {
|
||||||
|
if (getNameHelper(blockState, ComparatorBlock.POWERED).equals("true")) {
|
||||||
|
return InteractionResult.FAIL;
|
||||||
|
}
|
||||||
|
if (block instanceof RepeaterBlock) {
|
||||||
|
if (getNameHelper(blockState, RepeaterBlock.LOCKED).equals("true")) {
|
||||||
|
return InteractionResult.FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block instanceof CrafterBlock) {
|
||||||
|
if (getNameHelper(blockState, CrafterBlock.CRAFTING).equals("true")) {
|
||||||
|
return InteractionResult.FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockState iblockdata1 = cycleState(blockState, iblockstate, player.isSecondaryUseActive());
|
||||||
|
level.setBlock(clickedPos, iblockdata1, 18);
|
||||||
|
message(player, Component.translatable("item.minecraft.debug_stick.update", iblockstate.getName(), getNameHelper(iblockdata1, iblockstate)));
|
||||||
|
return InteractionResult.CONSUME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean shouldSkipPlace(BlockPlaceContext context) {
|
||||||
|
return RedStoneConfig.shears &&
|
||||||
|
context.getPlayer() != null &&
|
||||||
|
context.getPlayer().getItemInHand(InteractionHand.MAIN_HAND).is(Items.SHEARS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T extends Comparable<T>> BlockState cycleState(BlockState state, Property<T> property, boolean inverse) {
|
||||||
|
List<T> possibleValues = property.getPossibleValues();
|
||||||
|
if (possibleValues.getFirst() instanceof RailShape) {
|
||||||
|
boolean isRailBlock = state.getBlock() instanceof RailBlock;
|
||||||
|
possibleValues = possibleValues.stream().filter(possibleValue -> {
|
||||||
|
RailShape shape = (RailShape) possibleValue;
|
||||||
|
if (isRailBlock) {
|
||||||
|
return !shape.isSlope();
|
||||||
|
}
|
||||||
|
return !shape.isSlope() && shape != RailShape.NORTH_EAST && shape != RailShape.NORTH_WEST && shape != RailShape.SOUTH_EAST && shape != RailShape.SOUTH_WEST;
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
return state.setValue(property, getRelative(possibleValues, state.getValue(property), inverse)); // CraftBukkit - decompile error
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> T getRelative(Iterable<T> elements, T current, boolean inverse) {
|
||||||
|
return inverse ? Util.findPreviousInIterable(elements, current) : Util.findNextInIterable(elements, current);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void message(Player player, Component message) {
|
||||||
|
((ServerPlayer) player).sendSystemMessage(message, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T extends Comparable<T>> String getNameHelper(BlockState state, Property<T> property) {
|
||||||
|
return property.getName(state.getValue(property));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
Special thanks (Logo author):
|
Special thanks (Logo author):
|
||||||
Helvetica Volubi <suisuroru@blue-millennium.fun>
|
Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||||
bdlvl <bdlvl@mc-mygo.top>
|
bdlvl <bdlvl@blendreams.cn>
|
||||||
+1
-1
@@ -3,7 +3,7 @@ pluginManagement {
|
|||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
maven("https://repo.papermc.io/repository/maven-public/")
|
maven("https://repo.papermc.io/repository/maven-public/")
|
||||||
maven("https://repo.menthamc.com/repository/maven-public/")
|
maven("https://repo.menthamc.org/repository/maven-public/")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user