mirror of
https://github.com/BX-Team/DivineMC.git
synced 2026-01-06 15:41:52 +00:00
move some patches
This commit is contained in:
@@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: tr7zw <tr7zw@live.de>
|
||||
Date: Sat, 25 Jul 2020 17:16:18 +0200
|
||||
Subject: [PATCH] Global Eula file
|
||||
|
||||
Original code by YatopiaMC, licensed under MIT
|
||||
You can find the original code on https://github.com/YatopiaMC/Yatopia
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/Eula.java b/src/main/java/net/minecraft/server/Eula.java
|
||||
index 30599028f6263fbf61ab95d68573073426db19db..9e169c96fa1bc9dea9efb27cb996b4dd5d2a4c0c 100644
|
||||
--- a/src/main/java/net/minecraft/server/Eula.java
|
||||
+++ b/src/main/java/net/minecraft/server/Eula.java
|
||||
@@ -16,12 +16,26 @@ public class Eula {
|
||||
|
||||
public Eula(Path eulaFile) {
|
||||
this.file = eulaFile;
|
||||
- this.agreed = SharedConstants.IS_RUNNING_IN_IDE || this.readFile();
|
||||
+ this.agreed = SharedConstants.IS_RUNNING_IN_IDE || globalEula() || this.readFile(eulaFile);
|
||||
}
|
||||
|
||||
- private boolean readFile() {
|
||||
+ // Yatopia start - global eula file
|
||||
+ private boolean globalEula() {
|
||||
+ java.io.File globalEula = new java.io.File(System.getProperty("user.home"), "eula.txt");
|
||||
+
|
||||
+ if (globalEula.exists()) {
|
||||
+ System.out.println("Loaded global eula file from " + globalEula.getAbsolutePath());
|
||||
+ return readFile(globalEula.toPath());
|
||||
+ } else {
|
||||
+ System.out.println("No global eula file found at " + globalEula.getAbsolutePath());
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Yatopia end
|
||||
+
|
||||
+ private boolean readFile(java.nio.file.Path path) {
|
||||
try {
|
||||
- InputStream inputStream = Files.newInputStream(this.file);
|
||||
+ InputStream inputStream = Files.newInputStream(path);
|
||||
|
||||
boolean var3;
|
||||
try {
|
||||
@@ -1,708 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Gardling <titaniumtown@gmail.com>
|
||||
Date: Tue, 9 Nov 2021 16:53:39 -0500
|
||||
Subject: [PATCH] Reduce constants allocations
|
||||
|
||||
This patch includes code from the lithium project under the GNU Lesser General Public License v3.0: https://github.com/CaffeineMC/lithium-fabric/ but also original code created by your's truly
|
||||
|
||||
Original code by Titaniumtown, licensed under GNU General Public License v3.0
|
||||
You can find the original code on https://gitlab.com/Titaniumtown/JettPack
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java b/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java
|
||||
index 0133ea6feb1ab88f021f66855669f58367e7420b..5f4ad69862b24b568b9e907563289624d196d6ea 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java
|
||||
@@ -17,9 +17,9 @@ public final class EntityList implements Iterable<Entity> {
|
||||
this.entityToIndex.defaultReturnValue(Integer.MIN_VALUE);
|
||||
}
|
||||
|
||||
- protected static final Entity[] EMPTY_LIST = new Entity[0];
|
||||
+ //protected static final Entity[] EMPTY_LIST = new Entity[0]; // JettPack
|
||||
|
||||
- protected Entity[] entities = EMPTY_LIST;
|
||||
+ protected Entity[] entities = me.titaniumtown.Constants.EMPTY_entity_arr; // JettPack
|
||||
protected int count;
|
||||
|
||||
public int size() {
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java b/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java
|
||||
index 277cfd9d1e8fff5d9b5e534b75c3c5162d58b0b7..093170c13b3980791373fb240c9ec6c5adfc1519 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java
|
||||
@@ -20,9 +20,9 @@ public final class IBlockDataList {
|
||||
this.map.defaultReturnValue(Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
- private static final long[] EMPTY_LIST = new long[0];
|
||||
+ //private static final long[] EMPTY_LIST = new long[0]; // JettPack
|
||||
|
||||
- private long[] byIndex = EMPTY_LIST;
|
||||
+ private long[] byIndex = me.titaniumtown.Constants.EMPTY_long_arr; // JettPack
|
||||
private int size;
|
||||
|
||||
public static int getLocationKey(final int x, final int y, final int z) {
|
||||
diff --git a/src/main/java/io/papermc/paper/command/subcommands/VersionCommand.java b/src/main/java/io/papermc/paper/command/subcommands/VersionCommand.java
|
||||
index ae60bd96b5284d54676d8e7e4dd5d170b526ec1e..2344ea858eda8e54c2eb3ccbdad464ed5934650c 100644
|
||||
--- a/src/main/java/io/papermc/paper/command/subcommands/VersionCommand.java
|
||||
+++ b/src/main/java/io/papermc/paper/command/subcommands/VersionCommand.java
|
||||
@@ -14,7 +14,7 @@ public final class VersionCommand implements PaperSubcommand {
|
||||
public boolean execute(final CommandSender sender, final String subCommand, final String[] args) {
|
||||
final @Nullable Command ver = MinecraftServer.getServer().server.getCommandMap().getCommand("version");
|
||||
if (ver != null) {
|
||||
- ver.execute(sender, "paper", new String[0]);
|
||||
+ ver.execute(sender, "paper", me.titaniumtown.Constants.EMPTY_string_arr); // JettPack
|
||||
}
|
||||
return true;
|
||||
}
|
||||
diff --git a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
|
||||
index f597d65d56964297eeeed6c7e77703764178fee0..209c4f0b25470bff7278c0a8dcd30576900b9933 100644
|
||||
--- a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
|
||||
+++ b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
|
||||
@@ -81,7 +81,7 @@ public final class ChunkEntitySlices {
|
||||
}
|
||||
}
|
||||
|
||||
- return ret.toArray(new org.bukkit.entity.Entity[0]);
|
||||
+ return ret.toArray(me.titaniumtown.Constants.EMPTY_bukkit_entity_arr); // JettPack
|
||||
}
|
||||
|
||||
public CompoundTag save() {
|
||||
@@ -298,7 +298,7 @@ public final class ChunkEntitySlices {
|
||||
|
||||
protected static final class BasicEntityList<E extends Entity> {
|
||||
|
||||
- protected static final Entity[] EMPTY = new Entity[0];
|
||||
+ //protected static final Entity[] EMPTY = new Entity[0]; // JettPack
|
||||
protected static final int DEFAULT_CAPACITY = 4;
|
||||
|
||||
protected E[] storage;
|
||||
@@ -309,7 +309,7 @@ public final class ChunkEntitySlices {
|
||||
}
|
||||
|
||||
public BasicEntityList(final int cap) {
|
||||
- this.storage = (E[])(cap <= 0 ? EMPTY : new Entity[cap]);
|
||||
+ this.storage = (E[])(cap <= 0 ? me.titaniumtown.Constants.EMPTY_entity_arr : new Entity[cap]); // JettPack
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
@@ -321,7 +321,7 @@ public final class ChunkEntitySlices {
|
||||
}
|
||||
|
||||
private void resize() {
|
||||
- if (this.storage == EMPTY) {
|
||||
+ if (this.storage == me.titaniumtown.Constants.EMPTY_entity_arr) { // JettPack
|
||||
this.storage = (E[])new Entity[DEFAULT_CAPACITY];
|
||||
} else {
|
||||
this.storage = Arrays.copyOf(this.storage, this.storage.length * 2);
|
||||
diff --git a/src/main/java/me/titaniumtown/Constants.java b/src/main/java/me/titaniumtown/Constants.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..60bf30759a26c04c0f79ba739426aab1de955243
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/titaniumtown/Constants.java
|
||||
@@ -0,0 +1,16 @@
|
||||
+package me.titaniumtown;
|
||||
+
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+
|
||||
+public final class Constants {
|
||||
+ private Constants() {}
|
||||
+
|
||||
+ public static final Object[] EMPTY_object_arr = new Object[0];
|
||||
+ public static final int[] EMPTY_int_arr = new int[0];
|
||||
+ public static final int[] ZERO_int_arr = new int[]{0};
|
||||
+ public static final byte[] EMPTY_byte_arr = new byte[0];
|
||||
+ public static final String[] EMPTY_string_arr = new String[0];
|
||||
+ public static final long[] EMPTY_long_arr = new long[0];
|
||||
+ public static final org.bukkit.entity.Entity[] EMPTY_bukkit_entity_arr = new org.bukkit.entity.Entity[0];
|
||||
+ public static final net.minecraft.world.entity.Entity[] EMPTY_entity_arr = new net.minecraft.world.entity.Entity[0];
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/net/minecraft/advancements/RequirementsStrategy.java b/src/main/java/net/minecraft/advancements/RequirementsStrategy.java
|
||||
index 57d504d15794b1640ff7186f563d6ca5c2453d8c..97ca3c80af66884e74595a051224d54b9a8bde21 100644
|
||||
--- a/src/main/java/net/minecraft/advancements/RequirementsStrategy.java
|
||||
+++ b/src/main/java/net/minecraft/advancements/RequirementsStrategy.java
|
||||
@@ -14,7 +14,7 @@ public interface RequirementsStrategy {
|
||||
return strings;
|
||||
};
|
||||
RequirementsStrategy OR = (collection) -> {
|
||||
- return new String[][]{collection.toArray(new String[0])};
|
||||
+ return new String[][]{collection.toArray(me.titaniumtown.Constants.EMPTY_string_arr)}; // JettPack
|
||||
};
|
||||
|
||||
String[][] createRequirements(Collection<String> criteriaNames);
|
||||
diff --git a/src/main/java/net/minecraft/nbt/ByteArrayTag.java b/src/main/java/net/minecraft/nbt/ByteArrayTag.java
|
||||
index 3dd8a189c26f41759c59c3b9d0e5282038989a9f..147beddf8ef369cdae4b1ed2dcd0d7b2fd865315 100644
|
||||
--- a/src/main/java/net/minecraft/nbt/ByteArrayTag.java
|
||||
+++ b/src/main/java/net/minecraft/nbt/ByteArrayTag.java
|
||||
@@ -170,7 +170,7 @@ public class ByteArrayTag extends CollectionTag<ByteTag> {
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
- this.data = new byte[0];
|
||||
+ this.data = me.titaniumtown.Constants.EMPTY_byte_arr; // JettPack
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/nbt/CompoundTag.java b/src/main/java/net/minecraft/nbt/CompoundTag.java
|
||||
index 912fd5135e89348bdd3c0a8b6c07860ebc106df3..beecf9d1effea5cd12d1f826cc8071cd83b5a4d5 100644
|
||||
--- a/src/main/java/net/minecraft/nbt/CompoundTag.java
|
||||
+++ b/src/main/java/net/minecraft/nbt/CompoundTag.java
|
||||
@@ -364,7 +364,7 @@ public class CompoundTag implements Tag {
|
||||
throw new ReportedException(this.createReport(key, ByteArrayTag.TYPE, var3));
|
||||
}
|
||||
|
||||
- return new byte[0];
|
||||
+ return me.titaniumtown.Constants.EMPTY_byte_arr; // JettPack
|
||||
}
|
||||
|
||||
public int[] getIntArray(String key) {
|
||||
@@ -376,7 +376,7 @@ public class CompoundTag implements Tag {
|
||||
throw new ReportedException(this.createReport(key, IntArrayTag.TYPE, var3));
|
||||
}
|
||||
|
||||
- return new int[0];
|
||||
+ return me.titaniumtown.Constants.EMPTY_int_arr; // JettPack
|
||||
}
|
||||
|
||||
public long[] getLongArray(String key) {
|
||||
@@ -388,7 +388,7 @@ public class CompoundTag implements Tag {
|
||||
throw new ReportedException(this.createReport(key, LongArrayTag.TYPE, var3));
|
||||
}
|
||||
|
||||
- return new long[0];
|
||||
+ return me.titaniumtown.Constants.EMPTY_long_arr; // JettPack
|
||||
}
|
||||
|
||||
public CompoundTag getCompound(String key) {
|
||||
diff --git a/src/main/java/net/minecraft/nbt/IntArrayTag.java b/src/main/java/net/minecraft/nbt/IntArrayTag.java
|
||||
index a14b01cee7a8d7022c4fa7264d349a76be143ba5..44f441d6c102fa5bd50071cae991a8a6ba0ec713 100644
|
||||
--- a/src/main/java/net/minecraft/nbt/IntArrayTag.java
|
||||
+++ b/src/main/java/net/minecraft/nbt/IntArrayTag.java
|
||||
@@ -184,7 +184,7 @@ public class IntArrayTag extends CollectionTag<IntTag> {
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
- this.data = new int[0];
|
||||
+ this.data = me.titaniumtown.Constants.EMPTY_int_arr; // JettPack
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/nbt/ListTag.java b/src/main/java/net/minecraft/nbt/ListTag.java
|
||||
index 6a5e33d9821221be73f9c16afc17c9130248a231..29b7bde3ef3c5817910ccd5248e791f9e2948af7 100644
|
||||
--- a/src/main/java/net/minecraft/nbt/ListTag.java
|
||||
+++ b/src/main/java/net/minecraft/nbt/ListTag.java
|
||||
@@ -218,7 +218,7 @@ public class ListTag extends CollectionTag<Tag> {
|
||||
}
|
||||
}
|
||||
|
||||
- return new int[0];
|
||||
+ return me.titaniumtown.Constants.EMPTY_int_arr; // JettPack
|
||||
}
|
||||
|
||||
public long[] getLongArray(int index) {
|
||||
@@ -229,7 +229,7 @@ public class ListTag extends CollectionTag<Tag> {
|
||||
}
|
||||
}
|
||||
|
||||
- return new long[0];
|
||||
+ return me.titaniumtown.Constants.EMPTY_long_arr; // JettPack
|
||||
}
|
||||
|
||||
public double getDouble(int index) {
|
||||
diff --git a/src/main/java/net/minecraft/nbt/LongArrayTag.java b/src/main/java/net/minecraft/nbt/LongArrayTag.java
|
||||
index a39baec88dc9c73f1b592881ed96d11ab64ad785..710bb5579e23258c38a767f99d751576524f88f0 100644
|
||||
--- a/src/main/java/net/minecraft/nbt/LongArrayTag.java
|
||||
+++ b/src/main/java/net/minecraft/nbt/LongArrayTag.java
|
||||
@@ -188,7 +188,7 @@ public class LongArrayTag extends CollectionTag<LongTag> {
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
- this.data = new long[0];
|
||||
+ this.data = me.titaniumtown.Constants.EMPTY_long_arr; // JettPack
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/network/CipherBase.java b/src/main/java/net/minecraft/network/CipherBase.java
|
||||
index a2920b8a9eff77d9c5d1d7f70ad3abdacba8f0fa..f7f19e360d712211625ff28e92f83949197c93b0 100644
|
||||
--- a/src/main/java/net/minecraft/network/CipherBase.java
|
||||
+++ b/src/main/java/net/minecraft/network/CipherBase.java
|
||||
@@ -7,8 +7,8 @@ import javax.crypto.ShortBufferException;
|
||||
|
||||
public class CipherBase {
|
||||
private final Cipher cipher;
|
||||
- private byte[] heapIn = new byte[0];
|
||||
- private byte[] heapOut = new byte[0];
|
||||
+ private byte[] heapIn = me.titaniumtown.Constants.EMPTY_byte_arr; // JettPack
|
||||
+ private byte[] heapOut = me.titaniumtown.Constants.EMPTY_byte_arr; // JettPack
|
||||
|
||||
protected CipherBase(Cipher cipher) {
|
||||
this.cipher = cipher;
|
||||
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
|
||||
index cd386a13d8c0909d4ac971a5df751cd23e609b1b..5344f1f81797344130bd48f16689161af8261882 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -311,7 +311,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
}
|
||||
|
||||
public void setListener(PacketListener listener) {
|
||||
- Validate.notNull(listener, "packetListener", new Object[0]);
|
||||
+ Validate.notNull(listener, "packetListener", me.titaniumtown.Constants.EMPTY_object_arr); // JettPack
|
||||
this.packetListener = listener;
|
||||
}
|
||||
// Paper start
|
||||
diff --git a/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java b/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java
|
||||
index 02fb51f7f699992caf13d088c75b8275ec5267bb..11cb4ac19ddc09889117690ffec5191534a8adee 100644
|
||||
--- a/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java
|
||||
+++ b/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java
|
||||
@@ -20,7 +20,7 @@ import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
||||
public class TranslatableContents implements ComponentContents {
|
||||
- private static final Object[] NO_ARGS = new Object[0];
|
||||
+ private static final Object[] NO_ARGS = me.titaniumtown.Constants.EMPTY_object_arr; // JettPack
|
||||
private static final FormattedText TEXT_PERCENT = FormattedText.of("%");
|
||||
private static final FormattedText TEXT_NULL = FormattedText.of("null");
|
||||
private final String key;
|
||||
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
|
||||
index 5962f7a2b185d7d54a0f9e341a4fdf6e6f1c1ec5..0b677d128cbd108bb58d74d3cfe6015551e94143 100644
|
||||
--- a/src/main/java/net/minecraft/server/Main.java
|
||||
+++ b/src/main/java/net/minecraft/server/Main.java
|
||||
@@ -85,7 +85,7 @@ public class Main {
|
||||
OptionSpec<Void> optionspec6 = optionparser.accepts("safeMode", "Loads level with vanilla datapack only");
|
||||
OptionSpec<Void> optionspec7 = optionparser.accepts("help").forHelp();
|
||||
OptionSpec<String> optionspec8 = optionparser.accepts("singleplayer").withRequiredArg();
|
||||
- OptionSpec<String> optionspec9 = optionparser.accepts("universe").withRequiredArg().defaultsTo(".", new String[0]);
|
||||
+ OptionSpec<String> optionspec9 = optionparser.accepts("universe").withRequiredArg().defaultsTo(".", me.titaniumtown.Constants.EMPTY_string_arr); // JettPack
|
||||
OptionSpec<String> optionspec10 = optionparser.accepts("world").withRequiredArg();
|
||||
OptionSpec<Integer> optionspec11 = optionparser.accepts("port").withRequiredArg().ofType(Integer.class).defaultsTo(-1, new Integer[0]);
|
||||
OptionSpec<String> optionspec12 = optionparser.accepts("serverId").withRequiredArg();
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 6b4dbf0e1b5ddcf2bd33a917e4ee3654be511147..409ac6cef5085ffe6bd187031af3f3ad63cc71ea 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1354,8 +1354,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
try {
|
||||
BufferedImage bufferedimage = ImageIO.read(file);
|
||||
|
||||
- Validate.validState(bufferedimage.getWidth() == 64, "Must be 64 pixels wide", new Object[0]);
|
||||
- Validate.validState(bufferedimage.getHeight() == 64, "Must be 64 pixels high", new Object[0]);
|
||||
+ Validate.validState(bufferedimage.getWidth() == 64, "Must be 64 pixels wide", me.titaniumtown.Constants.EMPTY_object_arr); // JettPack
|
||||
+ Validate.validState(bufferedimage.getHeight() == 64, "Must be 64 pixels high", me.titaniumtown.Constants.EMPTY_object_arr); // JettPack
|
||||
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
|
||||
|
||||
ImageIO.write(bufferedimage, "PNG", bytearrayoutputstream);
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
index 1eb912ad97f9663bf6bd336ad739f2552b0a5c9b..9901ffe9de585a73e9ef32c700b1e8702f8786d3 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -303,7 +303,7 @@ public class ServerEntity {
|
||||
|
||||
if (this.entity instanceof LivingEntity) {
|
||||
List<Pair<EquipmentSlot, ItemStack>> list = Lists.newArrayList();
|
||||
- EquipmentSlot[] aenumitemslot = EquipmentSlot.values();
|
||||
+ EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // JettPack
|
||||
int i = aenumitemslot.length;
|
||||
|
||||
for (int j = 0; j < i; ++j) {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index e802ee2b2dc458f52dbce9746fc9891eebb6dcc1..f4280eb9f77568e4f3af6f264fc60901e667a936 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -909,7 +909,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
BlockPos blockposition2 = blockposition.set(j + randomX, randomY, k + randomZ);
|
||||
BlockState iblockdata = com.destroystokyo.paper.util.maplist.IBlockDataList.getBlockDataFromRaw(raw);
|
||||
|
||||
- iblockdata.randomTick(this, blockposition2, this.randomTickRandom);
|
||||
+ iblockdata.randomTick(this, blockposition2.immutable(), this.randomTickRandom); // JettPack
|
||||
// We drop the fluid tick since LAVA is ALREADY TICKED by the above method (See LiquidBlock).
|
||||
// TODO CHECK ON UPDATE
|
||||
}
|
||||
@@ -1164,7 +1164,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
|
||||
public static List<Entity> getCurrentlyTickingEntities() {
|
||||
Entity ticking = currentlyTickingEntity.get();
|
||||
- List<Entity> ret = java.util.Arrays.asList(ticking == null ? new Entity[0] : new Entity[] { ticking });
|
||||
+ List<Entity> ret = java.util.Arrays.asList(ticking == null ? me.titaniumtown.Constants.EMPTY_entity_arr : new Entity[] { ticking }); // JettPack
|
||||
|
||||
return ret;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 4e615e5d5b8d79f6eaac2136be03961415fd093e..633fe61c98c1fc181f38b4195651c3ed6fc1db42 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -410,7 +410,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
if (this.keepAlivePending) {
|
||||
if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected
|
||||
ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getScoreboardName()); // more info
|
||||
- this.disconnect(Component.translatable("disconnect.timeout", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause
|
||||
+ this.disconnect(Component.translatable("disconnect.timeout", me.titaniumtown.Constants.EMPTY_object_arr), org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause // JettPack
|
||||
}
|
||||
} else {
|
||||
if (elapsedTime >= 15000L) { // 15 seconds
|
||||
@@ -876,13 +876,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
// PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel()); // Paper - run this async
|
||||
// CraftBukkit start
|
||||
if (this.chatSpamTickCount.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamLimit && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { // Paper start - split and make configurable
|
||||
- server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause
|
||||
+ server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", me.titaniumtown.Constants.EMPTY_object_arr), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause // JettPack
|
||||
return;
|
||||
}
|
||||
// Paper start
|
||||
String str = packet.getCommand(); int index = -1;
|
||||
if (str.length() > 64 && ((index = str.indexOf(' ')) == -1 || index >= 64)) {
|
||||
- server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause
|
||||
+ server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", me.titaniumtown.Constants.EMPTY_object_arr), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause // JettPack
|
||||
return;
|
||||
}
|
||||
// Paper end
|
||||
@@ -3398,7 +3398,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
// Paper start
|
||||
if (!org.bukkit.Bukkit.isPrimaryThread()) {
|
||||
if (recipeSpamPackets.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamLimit) {
|
||||
- server.scheduleOnMain(() -> this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause
|
||||
+ server.scheduleOnMain(() -> this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam", me.titaniumtown.Constants.EMPTY_object_arr), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause // JettPack
|
||||
return;
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index ea9b56fd6ae1d5577da5bd3e0c38abfeec8f3646..f1105edce8484cac39d8fb33a42c9ed8d44fe5c0 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -269,8 +269,8 @@ public class ServerLoginPacketListenerImpl implements TickablePacketListener, Se
|
||||
|
||||
@Override
|
||||
public void handleHello(ServerboundHelloPacket packet) {
|
||||
- Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet", new Object[0]);
|
||||
- Validate.validState(ServerLoginPacketListenerImpl.isValidUsername(packet.name()), "Invalid characters in username", new Object[0]);
|
||||
+ Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet", me.titaniumtown.Constants.EMPTY_object_arr); // JettPack
|
||||
+ Validate.validState(ServerLoginPacketListenerImpl.isValidUsername(packet.name()), "Invalid characters in username", me.titaniumtown.Constants.EMPTY_object_arr); // JettPack
|
||||
// Paper start - validate usernames
|
||||
if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.performUsernameValidation) {
|
||||
if (!this.iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation && !validateUsername(packet.name())) {
|
||||
@@ -330,7 +330,7 @@ public class ServerLoginPacketListenerImpl implements TickablePacketListener, Se
|
||||
|
||||
@Override
|
||||
public void handleKey(ServerboundKeyPacket packet) {
|
||||
- Validate.validState(this.state == ServerLoginPacketListenerImpl.State.KEY, "Unexpected key packet", new Object[0]);
|
||||
+ Validate.validState(this.state == ServerLoginPacketListenerImpl.State.KEY, "Unexpected key packet", me.titaniumtown.Constants.EMPTY_object_arr); // JettPack
|
||||
|
||||
final String s;
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 06eda955f96b5fe2d08ed0d39229c7a6ebb88931..3fc95b7d7b41e078e1d219e29ada27aeab1320bf 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -741,7 +741,7 @@ public abstract class PlayerList {
|
||||
while (iterator.hasNext()) {
|
||||
entityplayer = (ServerPlayer) iterator.next();
|
||||
this.save(entityplayer); // CraftBukkit - Force the player's inventory to be saved
|
||||
- entityplayer.connection.disconnect(Component.translatable("multiplayer.disconnect.duplicate_login", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.DUPLICATE_LOGIN); // Paper - kick event cause
|
||||
+ entityplayer.connection.disconnect(Component.translatable("multiplayer.disconnect.duplicate_login", me.titaniumtown.Constants.EMPTY_object_arr), org.bukkit.event.player.PlayerKickEvent.Cause.DUPLICATE_LOGIN); // Paper - kick event cause // JettPack
|
||||
}
|
||||
|
||||
// Instead of kicking then returning, we need to store the kick reason
|
||||
diff --git a/src/main/java/net/minecraft/server/players/StoredUserList.java b/src/main/java/net/minecraft/server/players/StoredUserList.java
|
||||
index 4fd709a550bf8da1e996894a1ca6b91206c31e9e..63c0fe30ff035b6b5c1b4b35d3ad6c649d94e421 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/StoredUserList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/StoredUserList.java
|
||||
@@ -95,7 +95,7 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
|
||||
}
|
||||
|
||||
public String[] getUserList() {
|
||||
- return (String[]) this.map.keySet().toArray(new String[0]);
|
||||
+ return (String[]) this.map.keySet().toArray(me.titaniumtown.Constants.EMPTY_string_arr); // JettPack
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
||||
diff --git a/src/main/java/net/minecraft/util/MemoryReserve.java b/src/main/java/net/minecraft/util/MemoryReserve.java
|
||||
index 0ee04fe6ff6a4d09754f326526ae04fe7226bab2..58217ddb1d63f3bb628cc40e5cc0959657a17938 100644
|
||||
--- a/src/main/java/net/minecraft/util/MemoryReserve.java
|
||||
+++ b/src/main/java/net/minecraft/util/MemoryReserve.java
|
||||
@@ -11,6 +11,6 @@ public class MemoryReserve {
|
||||
}
|
||||
|
||||
public static void release() {
|
||||
- reserve = new byte[0];
|
||||
+ reserve = me.titaniumtown.Constants.EMPTY_byte_arr; // JettPack
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/util/ZeroBitStorage.java b/src/main/java/net/minecraft/util/ZeroBitStorage.java
|
||||
index 5d8e9bdf5538b19681f21949368d862fab8a89ad..97c744508cc535418eba65fa722859c81c22d647 100644
|
||||
--- a/src/main/java/net/minecraft/util/ZeroBitStorage.java
|
||||
+++ b/src/main/java/net/minecraft/util/ZeroBitStorage.java
|
||||
@@ -5,7 +5,7 @@ import java.util.function.IntConsumer;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
public class ZeroBitStorage implements BitStorage {
|
||||
- public static final long[] RAW = new long[0];
|
||||
+ public static final long[] RAW = me.titaniumtown.Constants.EMPTY_long_arr; // JettPack
|
||||
private final int size;
|
||||
|
||||
public ZeroBitStorage(int size) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/EquipmentSlot.java b/src/main/java/net/minecraft/world/entity/EquipmentSlot.java
|
||||
index c82bb38b5b1c9204daef21455723d21509ad1c44..4aa044ab8748c01b0022096733e5bacf7220510a 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/EquipmentSlot.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/EquipmentSlot.java
|
||||
@@ -12,6 +12,7 @@ public enum EquipmentSlot {
|
||||
private final int index;
|
||||
private final int filterFlag;
|
||||
private final String name;
|
||||
+ public static final EquipmentSlot[] VALUES = EquipmentSlot.values(); // JettPack
|
||||
|
||||
private EquipmentSlot(EquipmentSlot.Type type, int entityId, int armorStandId, String name) {
|
||||
this.type = type;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 26efc49b4530112c8bd3f580ce375ab4203c9609..c0e316582e085873c05a76c16e612eabd2e8cf2a 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3070,7 +3070,7 @@ public abstract class LivingEntity extends Entity {
|
||||
@Nullable
|
||||
private Map<EquipmentSlot, ItemStack> collectEquipmentChanges() {
|
||||
Map<EquipmentSlot, ItemStack> map = null;
|
||||
- EquipmentSlot[] aenumitemslot = EquipmentSlot.values();
|
||||
+ EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // JettPack
|
||||
int i = aenumitemslot.length;
|
||||
|
||||
for (int j = 0; j < i; ++j) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
index e89b88eb3d4202ea7ff043dc9e92163332cd10d3..78b1fc7b4cacfc98a9e3e6ba93e17c3307d5449c 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
@@ -1027,7 +1027,7 @@ public abstract class Mob extends LivingEntity {
|
||||
@Override
|
||||
protected void dropCustomDeathLoot(DamageSource source, int lootingMultiplier, boolean allowDrops) {
|
||||
super.dropCustomDeathLoot(source, lootingMultiplier, allowDrops);
|
||||
- EquipmentSlot[] aenumitemslot = EquipmentSlot.values();
|
||||
+ EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // JettPack
|
||||
int j = aenumitemslot.length;
|
||||
|
||||
for (int k = 0; k < j; ++k) {
|
||||
@@ -1089,7 +1089,7 @@ public abstract class Mob extends LivingEntity {
|
||||
}
|
||||
|
||||
boolean flag = true;
|
||||
- EquipmentSlot[] aenumitemslot = EquipmentSlot.values();
|
||||
+ EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // JettPack
|
||||
int j = aenumitemslot.length;
|
||||
|
||||
for (int k = 0; k < j; ++k) {
|
||||
@@ -1176,7 +1176,7 @@ public abstract class Mob extends LivingEntity {
|
||||
float f = localDifficulty.getSpecialMultiplier();
|
||||
|
||||
this.enchantSpawnedWeapon(random, f);
|
||||
- EquipmentSlot[] aenumitemslot = EquipmentSlot.values();
|
||||
+ EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // JettPack
|
||||
int i = aenumitemslot.length;
|
||||
|
||||
for (int j = 0; j < i; ++j) {
|
||||
@@ -1390,7 +1390,7 @@ public abstract class Mob extends LivingEntity {
|
||||
t0.setInvulnerable(this.isInvulnerable());
|
||||
if (flag) {
|
||||
t0.setCanPickUpLoot(this.canPickUpLoot());
|
||||
- EquipmentSlot[] aenumitemslot = EquipmentSlot.values();
|
||||
+ EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // JettPack
|
||||
int i = aenumitemslot.length;
|
||||
|
||||
for (int j = 0; j < i; ++j) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
|
||||
index fb0a77b4cf1ba47c73c00993bd9b7454240fe5d6..df1dfaea8b49794d9e3ecb792a129113829b60c9 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
|
||||
@@ -233,7 +233,7 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder {
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
||||
- EquipmentSlot[] aenumitemslot = EquipmentSlot.values();
|
||||
+ EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // JettPack
|
||||
int i = aenumitemslot.length;
|
||||
|
||||
for (int j = 0; j < i; ++j) {
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
index c18a0bc94d0210396046f4475e49a739088593f3..4fea1c9873b4dd9c9f21722adbb02200487caf3c 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -969,7 +969,7 @@ public final class ItemStack {
|
||||
int k;
|
||||
|
||||
if (ItemStack.shouldShowInTooltip(i, ItemStack.TooltipPart.MODIFIERS)) {
|
||||
- EquipmentSlot[] aenumitemslot = EquipmentSlot.values();
|
||||
+ EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // JettPack
|
||||
|
||||
k = aenumitemslot.length;
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
|
||||
index 9e3f9099cc47e6c6e40d11ef6d6e83fbf19a3cf7..b9c1db394ee35ed1acead620f7e9e47c60fa1532 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
|
||||
@@ -242,7 +242,7 @@ public class ShapedRecipe implements CraftingRecipe {
|
||||
}
|
||||
|
||||
if (pattern.length == l) {
|
||||
- return new String[0];
|
||||
+ return me.titaniumtown.Constants.EMPTY_string_arr; // JettPack
|
||||
} else {
|
||||
String[] astring1 = new String[pattern.length - l - k];
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/enchantment/Enchantments.java b/src/main/java/net/minecraft/world/item/enchantment/Enchantments.java
|
||||
index 1367908a54e1c1703d14b3c25852da5ec1b02019..be33c4c28bbc0bf80cbf2921664fcc4aaa465950 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/enchantment/Enchantments.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/enchantment/Enchantments.java
|
||||
@@ -43,8 +43,8 @@ public class Enchantments {
|
||||
public static final Enchantment MULTISHOT = Enchantments.register("multishot", new MultiShotEnchantment(Enchantment.Rarity.RARE, new EquipmentSlot[]{EquipmentSlot.MAINHAND}));
|
||||
public static final Enchantment QUICK_CHARGE = Enchantments.register("quick_charge", new QuickChargeEnchantment(Enchantment.Rarity.UNCOMMON, new EquipmentSlot[]{EquipmentSlot.MAINHAND}));
|
||||
public static final Enchantment PIERCING = Enchantments.register("piercing", new ArrowPiercingEnchantment(Enchantment.Rarity.COMMON, new EquipmentSlot[]{EquipmentSlot.MAINHAND}));
|
||||
- public static final Enchantment MENDING = Enchantments.register("mending", new MendingEnchantment(Enchantment.Rarity.RARE, EquipmentSlot.values()));
|
||||
- public static final Enchantment VANISHING_CURSE = Enchantments.register("vanishing_curse", new VanishingCurseEnchantment(Enchantment.Rarity.VERY_RARE, EquipmentSlot.values()));
|
||||
+ public static final Enchantment MENDING = Enchantments.register("mending", new MendingEnchantment(Enchantment.Rarity.RARE, EquipmentSlot.VALUES)); // JettPack
|
||||
+ public static final Enchantment VANISHING_CURSE = Enchantments.register("vanishing_curse", new VanishingCurseEnchantment(Enchantment.Rarity.VERY_RARE, EquipmentSlot.VALUES)); // JettPack
|
||||
|
||||
// CraftBukkit start
|
||||
static {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/EntityBasedExplosionDamageCalculator.java b/src/main/java/net/minecraft/world/level/EntityBasedExplosionDamageCalculator.java
|
||||
index 2f9f15d99f8b31e9f13f7f32378b2a9e09bcb5e5..b9579e3d1610ddcb5251baa2dd9462e0557c4cf4 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/EntityBasedExplosionDamageCalculator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/EntityBasedExplosionDamageCalculator.java
|
||||
@@ -15,9 +15,17 @@ public class EntityBasedExplosionDamageCalculator extends ExplosionDamageCalcula
|
||||
|
||||
@Override
|
||||
public Optional<Float> getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState) {
|
||||
- return super.getBlockExplosionResistance(explosion, world, pos, blockState, fluidState).map((max) -> {
|
||||
- return this.source.getBlockExplosionResistance(explosion, world, pos, blockState, fluidState, max);
|
||||
- });
|
||||
+ // JettPack start - lithium: reduce allocs
|
||||
+ Optional<Float> optionalBlastResistance = super.getBlockExplosionResistance(explosion, world, pos, blockState, fluidState);
|
||||
+ if (optionalBlastResistance.isPresent()) {
|
||||
+ float blastResistance = optionalBlastResistance.get();
|
||||
+ float effectiveExplosionResistance = this.source.getBlockExplosionResistance(explosion, world, pos, blockState, fluidState, blastResistance);
|
||||
+ if (effectiveExplosionResistance != blastResistance) {
|
||||
+ return Optional.of(effectiveExplosionResistance);
|
||||
+ }
|
||||
+ }
|
||||
+ return optionalBlastResistance;
|
||||
+ // JettPack end
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 0277633fd328ef9993fea4ac29df83b5b00c0f42..0948242ecebe507c90af343faeffc7c9388fa7e4 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -1521,7 +1521,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
public org.bukkit.entity.Entity[] getChunkEntities(int chunkX, int chunkZ) {
|
||||
io.papermc.paper.world.ChunkEntitySlices slices = ((ServerLevel)this).getEntityLookup().getChunk(chunkX, chunkZ);
|
||||
if (slices == null) {
|
||||
- return new org.bukkit.entity.Entity[0];
|
||||
+ return me.titaniumtown.Constants.EMPTY_bukkit_entity_arr; // JettPack
|
||||
}
|
||||
return slices.getChunkEntities();
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
|
||||
index 492e3ffd6a4588a521486db631f3e8b2a25b74ec..111635d43ac0b93e089f5a115521a502ca463c39 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
|
||||
@@ -383,7 +383,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder {
|
||||
|
||||
@Override
|
||||
public int[] getSlotsForFace(Direction side) {
|
||||
- return side == Direction.DOWN ? new int[]{0} : new int[0];
|
||||
+ return side == Direction.DOWN ? me.titaniumtown.Constants.ZERO_int_arr : me.titaniumtown.Constants.EMPTY_int_arr; // JettPack
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -432,7 +432,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder {
|
||||
|
||||
@Override
|
||||
public int[] getSlotsForFace(Direction side) {
|
||||
- return side == Direction.UP ? new int[]{0} : new int[0];
|
||||
+ return side == Direction.UP ? me.titaniumtown.Constants.ZERO_int_arr : me.titaniumtown.Constants.EMPTY_int_arr; // JettPack
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -469,7 +469,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder {
|
||||
|
||||
@Override
|
||||
public int[] getSlotsForFace(Direction side) {
|
||||
- return new int[0];
|
||||
+ return me.titaniumtown.Constants.EMPTY_int_arr; // JettPack
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
index c6aeda6497cb59673b469588142f5f15a338389d..ebf718cea97d4ff88e888675eeceeca253dc01cb 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
@@ -64,7 +64,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
protected static final int SLOT_FUEL = 1;
|
||||
protected static final int SLOT_RESULT = 2;
|
||||
public static final int DATA_LIT_TIME = 0;
|
||||
- private static final int[] SLOTS_FOR_UP = new int[]{0};
|
||||
+ private static final int[] SLOTS_FOR_UP = me.titaniumtown.Constants.ZERO_int_arr; // JettPack
|
||||
private static final int[] SLOTS_FOR_DOWN = new int[]{2, 1};
|
||||
private static final int[] SLOTS_FOR_SIDES = new int[]{1};
|
||||
public static final int DATA_LIT_DURATION = 1;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
index 601f8099f74e81c17600566b3c9b7a6dd39c9bcb..f816fae46568b83ef4441bd3bb06f2081308921e 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
@@ -119,7 +119,7 @@ public class PlayerDataStorage {
|
||||
String[] astring = this.playerDir.list();
|
||||
|
||||
if (astring == null) {
|
||||
- astring = new String[0];
|
||||
+ astring = me.titaniumtown.Constants.EMPTY_string_arr; // JettPack
|
||||
}
|
||||
|
||||
for (int i = 0; i < astring.length; ++i) {
|
||||
diff --git a/src/main/java/net/minecraft/world/scores/Team.java b/src/main/java/net/minecraft/world/scores/Team.java
|
||||
index 16d2aa4556bc9f32a2def7f9ca282aa3fa23fb87..290a0d35e1e4ca8b7281aa6d8cdb66dabdadf0f7 100644
|
||||
--- a/src/main/java/net/minecraft/world/scores/Team.java
|
||||
+++ b/src/main/java/net/minecraft/world/scores/Team.java
|
||||
@@ -80,7 +80,7 @@ public abstract class Team {
|
||||
public final int id;
|
||||
|
||||
public static String[] getAllNames() {
|
||||
- return BY_NAME.keySet().toArray(new String[0]);
|
||||
+ return BY_NAME.keySet().toArray(me.titaniumtown.Constants.EMPTY_string_arr); // JettPack
|
||||
}
|
||||
|
||||
@Nullable
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftEquipmentSlot.java b/src/main/java/org/bukkit/craftbukkit/CraftEquipmentSlot.java
|
||||
index 402a238cf502003a232bb95473bd13e59e067fab..6ab50d7ed8481d14152f19a4b63a3d96e52a40a7 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftEquipmentSlot.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftEquipmentSlot.java
|
||||
@@ -5,8 +5,8 @@ import org.bukkit.inventory.EquipmentSlot;
|
||||
|
||||
public class CraftEquipmentSlot {
|
||||
|
||||
- private static final net.minecraft.world.entity.EquipmentSlot[] slots = new net.minecraft.world.entity.EquipmentSlot[EquipmentSlot.values().length];
|
||||
- private static final EquipmentSlot[] enums = new EquipmentSlot[net.minecraft.world.entity.EquipmentSlot.values().length];
|
||||
+ private static final net.minecraft.world.entity.EquipmentSlot[] slots = net.minecraft.world.entity.EquipmentSlot.VALUES; // JettPack
|
||||
+ private static final EquipmentSlot[] enums = new EquipmentSlot[net.minecraft.world.entity.EquipmentSlot.VALUES.length]; // JettPack
|
||||
|
||||
static {
|
||||
set(EquipmentSlot.HAND, net.minecraft.world.entity.EquipmentSlot.MAINHAND);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java
|
||||
index 6827979a5b270ced53b46ecb9eff548727dadb81..4b42ae96bc786d2a9d57086ae8d1f5cadc70f2bb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java
|
||||
@@ -165,7 +165,7 @@ public class CraftEntityEquipment implements EntityEquipment {
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
- for (net.minecraft.world.entity.EquipmentSlot slot : net.minecraft.world.entity.EquipmentSlot.values()) {
|
||||
+ for (net.minecraft.world.entity.EquipmentSlot slot : net.minecraft.world.entity.EquipmentSlot.VALUES) { // JettPack
|
||||
this.setEquipment(slot, null, false);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java b/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java
|
||||
index 049d750d3af991dd14ac8cf644330404e74b2151..2f69484a8970f78c11f8fbb187e7a9f8f0fb994d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java
|
||||
@@ -166,7 +166,7 @@ public final class WeakCollection<T> implements Collection<T> {
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
- return this.toArray(new Object[0]);
|
||||
+ return this.toArray(me.titaniumtown.Constants.EMPTY_object_arr); // JettPack
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,131 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: JellySquid <jellysquid+atwork@protonmail.com>
|
||||
Date: Fri, 5 Feb 2021 00:16:30 -0600
|
||||
Subject: [PATCH] lithium: CompactSineLUT
|
||||
|
||||
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
|
||||
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
|
||||
|
||||
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/math/CompactSineLUT.java b/src/main/java/me/jellysquid/mods/lithium/common/util/math/CompactSineLUT.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..b8c9cb28876c2c1781cd72870076d528b9647916
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/jellysquid/mods/lithium/common/util/math/CompactSineLUT.java
|
||||
@@ -0,0 +1,90 @@
|
||||
+package me.jellysquid.mods.lithium.common.util.math;
|
||||
+
|
||||
+import net.minecraft.util.Mth;
|
||||
+
|
||||
+/**
|
||||
+ * A replacement for the sine angle lookup table used in {@link Mth}, both reducing the size of LUT and improving
|
||||
+ * the access patterns for common paired sin/cos operations.
|
||||
+ *
|
||||
+ * sin(-x) = -sin(x)
|
||||
+ * ... to eliminate negative angles from the LUT.
|
||||
+ *
|
||||
+ * sin(x) = sin(pi/2 - x)
|
||||
+ * ... to eliminate supplementary angles from the LUT.
|
||||
+ *
|
||||
+ * Using these identities allows us to reduce the LUT from 64K entries (256 KB) to just 16K entries (64 KB), enabling
|
||||
+ * it to better fit into the CPU's caches at the expense of some cycles on the fast path. The implementation has been
|
||||
+ * tightly optimized to avoid branching where possible and to use very quick integer operations.
|
||||
+ *
|
||||
+ * Generally speaking, reducing the size of a lookup table is always a good optimization, but since we need to spend
|
||||
+ * extra CPU cycles trying to maintain parity with vanilla, there is the potential risk that this implementation ends
|
||||
+ * up being slower than vanilla when the lookup table is able to be kept in cache memory.
|
||||
+ *
|
||||
+ * Unlike other "fast math" implementations, the values returned by this class are *bit-for-bit identical* with those
|
||||
+ * from {@link Mth}. Validation is performed during runtime to ensure that the table is correct.
|
||||
+ *
|
||||
+ * @author coderbot16 Author of the original (and very clever) implementation in Rust:
|
||||
+ * https://gitlab.com/coderbot16/i73/-/tree/master/i73-trig/src
|
||||
+ * @author jellysquid3 Additional optimizations, port to Java
|
||||
+ */
|
||||
+public class CompactSineLUT {
|
||||
+ private static final int[] SINE_TABLE_INT = new int[16384 + 1];
|
||||
+ private static final float SINE_TABLE_MIDPOINT;
|
||||
+
|
||||
+ static {
|
||||
+ final float[] SINE_TABLE = Mth.getSinTable();
|
||||
+ // Copy the sine table, covering to raw int bits
|
||||
+ for (int i = 0; i < SINE_TABLE_INT.length; i++) {
|
||||
+ SINE_TABLE_INT[i] = Float.floatToRawIntBits(SINE_TABLE[i]);
|
||||
+ }
|
||||
+
|
||||
+ SINE_TABLE_MIDPOINT = SINE_TABLE[SINE_TABLE.length / 2];
|
||||
+
|
||||
+ // Test that the lookup table is correct during runtime
|
||||
+ for (int i = 0; i < SINE_TABLE.length; i++) {
|
||||
+ float expected = SINE_TABLE[i];
|
||||
+ float value = lookup(i);
|
||||
+
|
||||
+ if (expected != value) {
|
||||
+ throw new IllegalArgumentException(String.format("LUT error at index %d (expected: %s, found: %s)", i, expected, value));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // [VanillaCopy] MathHelper#sin(float)
|
||||
+ public static float sin(float f) {
|
||||
+ return lookup((int) (f * 10430.378f) & 0xFFFF);
|
||||
+ }
|
||||
+
|
||||
+ // [VanillaCopy] MathHelper#cos(float)
|
||||
+ public static float cos(float f) {
|
||||
+ return lookup((int) (f * 10430.378f + 16384.0f) & 0xFFFF);
|
||||
+ }
|
||||
+
|
||||
+ private static float lookup(int index) {
|
||||
+ // A special case... Is there some way to eliminate this?
|
||||
+ if (index == 32768) {
|
||||
+ return SINE_TABLE_MIDPOINT;
|
||||
+ }
|
||||
+
|
||||
+ // Trigonometric identity: sin(-x) = -sin(x)
|
||||
+ // Given a domain of 0 <= x <= 2*pi, just negate the value if x > pi.
|
||||
+ // This allows the sin table size to be halved.
|
||||
+ int neg = (index & 0x8000) << 16;
|
||||
+
|
||||
+ // All bits set if (pi/2 <= x), none set otherwise
|
||||
+ // Extracts the 15th bit from 'half'
|
||||
+ int mask = (index << 17) >> 31;
|
||||
+
|
||||
+ // Trigonometric identity: sin(x) = sin(pi/2 - x)
|
||||
+ int pos = (0x8001 & mask) + (index ^ mask);
|
||||
+
|
||||
+ // Wrap the position in the table. Moving this down to immediately before the array access
|
||||
+ // seems to help the Hotspot compiler optimize the bit math better.
|
||||
+ pos &= 0x7fff;
|
||||
+
|
||||
+ // Fetch the corresponding value from the LUT and invert the sign bit as needed
|
||||
+ // This directly manipulate the sign bit on the float bits to simplify logic
|
||||
+ return Float.intBitsToFloat(SINE_TABLE_INT[pos] ^ neg);
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/net/minecraft/util/Mth.java b/src/main/java/net/minecraft/util/Mth.java
|
||||
index 9b22034aa655ceb0da151d9d8ca3147f6487889a..ec587cf6592a1dc0d90d6f54af1bdfab97aec7c6 100644
|
||||
--- a/src/main/java/net/minecraft/util/Mth.java
|
||||
+++ b/src/main/java/net/minecraft/util/Mth.java
|
||||
@@ -32,6 +32,7 @@ public class Mth {
|
||||
|
||||
});
|
||||
private static final RandomSource RANDOM = RandomSource.createThreadSafe();
|
||||
+ public static float[] getSinTable() { return SIN; } // DivineMC - lithium: CompactSineLUT
|
||||
private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[]{0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
|
||||
private static final double ONE_SIXTH = 0.16666666666666666D;
|
||||
private static final int FRAC_EXP = 8;
|
||||
@@ -41,11 +42,11 @@ public class Mth {
|
||||
private static final double[] COS_TAB = new double[257];
|
||||
|
||||
public static float sin(float value) {
|
||||
- return SIN[(int)(value * 10430.378F) & '\uffff'];
|
||||
+ return me.jellysquid.mods.lithium.common.util.math.CompactSineLUT.sin(value); // DivineMC - lithium: CompactSineLUT
|
||||
}
|
||||
|
||||
public static float cos(float value) {
|
||||
- return SIN[(int)(value * 10430.378F + 16384.0F) & '\uffff'];
|
||||
+ return me.jellysquid.mods.lithium.common.util.math.CompactSineLUT.cos(value); // DivineMC - lithium: CompactSineLUT
|
||||
}
|
||||
|
||||
public static float sqrt(float value) {
|
||||
@@ -1,102 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: 2No2Name <2No2Name@web.de>
|
||||
Date: Wed, 15 Dec 2021 11:20:48 -0500
|
||||
Subject: [PATCH] lithium: fast retrieval
|
||||
|
||||
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
|
||||
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java b/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java
|
||||
index f54ca6383298848b2ee7108c41fcea593f924881..ad12d9660cd57d147859a0e3e123c5b87c8e9748 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java
|
||||
@@ -33,7 +33,7 @@ public class EntitySectionStorage<T extends EntityAccess> {
|
||||
}
|
||||
|
||||
public void forEachAccessibleNonEmptySection(AABB box, Consumer<EntitySection<T>> action) {
|
||||
- int i = 2;
|
||||
+ // DivineMC start - lithium: fast retrieval
|
||||
int j = SectionPos.posToSectionCoord(box.minX - 2.0D);
|
||||
int k = SectionPos.posToSectionCoord(box.minY - 4.0D);
|
||||
int l = SectionPos.posToSectionCoord(box.minZ - 2.0D);
|
||||
@@ -41,25 +41,67 @@ public class EntitySectionStorage<T extends EntityAccess> {
|
||||
int n = SectionPos.posToSectionCoord(box.maxY + 0.0D);
|
||||
int o = SectionPos.posToSectionCoord(box.maxZ + 2.0D);
|
||||
|
||||
- for(int p = j; p <= m; ++p) {
|
||||
- long q = SectionPos.asLong(p, 0, 0);
|
||||
- long r = SectionPos.asLong(p, -1, -1);
|
||||
- LongIterator longIterator = this.sectionIds.subSet(q, r + 1L).iterator();
|
||||
-
|
||||
- while(longIterator.hasNext()) {
|
||||
- long s = longIterator.nextLong();
|
||||
- int t = SectionPos.y(s);
|
||||
- int u = SectionPos.z(s);
|
||||
- if (t >= k && t <= n && u >= l && u <= o) {
|
||||
- EntitySection<T> entitySection = this.sections.get(s);
|
||||
- if (entitySection != null && !entitySection.isEmpty() && entitySection.getStatus().isAccessible()) {
|
||||
- action.accept(entitySection);
|
||||
+ if (m >= j + 4 || o >= l + 4) {
|
||||
+ // Vanilla is likely more optimized when shooting entities with TNT cannons over huge distances.
|
||||
+ // Choosing a cutoff of 4 chunk size, as it becomes more likely that these entity sections do not exist when
|
||||
+ // they are far away from the shot entity (player despawn range, position maybe not on the ground, etc)
|
||||
+ for (int p = j; p <= m; p++) {
|
||||
+ long q = SectionPos.asLong(p, 0, 0);
|
||||
+ long r = SectionPos.asLong(p, -1, -1);
|
||||
+ LongIterator longIterator = this.sectionIds.subSet(q, r + 1L).iterator();
|
||||
+
|
||||
+ while (longIterator.hasNext()) {
|
||||
+ long s = longIterator.nextLong();
|
||||
+ int t = SectionPos.y(s);
|
||||
+ int u = SectionPos.z(s);
|
||||
+ if (t >= k && t <= n && u >= l && u <= o) {
|
||||
+ EntitySection<T> entitySection = this.sections.get(s);
|
||||
+ if (entitySection != null && !entitySection.isEmpty() && entitySection.getStatus().isAccessible()) {
|
||||
+ action.accept(entitySection);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
+ } else {
|
||||
+ // Vanilla order of the AVL long set is sorting by ascending long value. The x, y, z positions are packed into
|
||||
+ // a long with the x position's lowest 22 bits placed at the MSB.
|
||||
+ // Therefore the long is negative iff the 22th bit of the x position is set, which happens iff the x position
|
||||
+ // is negative. A positive x position will never have its 22th bit set, as these big coordinates are far outside
|
||||
+ // the world. y and z positions are treated as unsigned when sorting by ascending long value, as their sign bits
|
||||
+ // are placed somewhere inside the packed long
|
||||
+ for (int x = j; x <= m; x++) {
|
||||
+ for (int z = Math.max(l, 0); z <= o; z++) {
|
||||
+ this.forEachInColumn(x, k, n, z, action);
|
||||
+ }
|
||||
+
|
||||
+ int bound = Math.min(-1, o);
|
||||
+ for (int z = l; z <= bound; z++) {
|
||||
+ this.forEachInColumn(x, k, n, z, action);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
+ // DivineMC end
|
||||
+ }
|
||||
|
||||
+ // DivineMC start - lithium: fast retrieval
|
||||
+ private void forEachInColumn(int x, int k, int n, int z, Consumer<EntitySection<T>> action) {
|
||||
+ //y from negative to positive, but y is treated as unsigned
|
||||
+ for (int y = Math.max(k, 0); y <= n; y++) {
|
||||
+ this.consumeSection(SectionPos.asLong(x, y, z), action);
|
||||
+ }
|
||||
+ int bound = Math.min(-1, n);
|
||||
+ for (int y = k; y <= bound; y++) {
|
||||
+ this.consumeSection(SectionPos.asLong(x, y, z), action);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private void consumeSection(long pos, Consumer<EntitySection<T>> action) {
|
||||
+ EntitySection<T> entitySection = this.getSection(pos);
|
||||
+ if (entitySection != null && 0 != entitySection.size() && entitySection.getStatus().isAccessible()) {
|
||||
+ action.accept(entitySection);
|
||||
+ }
|
||||
}
|
||||
+ // DivineMC end
|
||||
|
||||
public LongStream getExistingSectionPositionsInChunk(long chunkPos) {
|
||||
int i = ChunkPos.getX(chunkPos);
|
||||
@@ -1,29 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: 2No2Name <2No2Name@web.de>
|
||||
Date: Sun, 12 Dec 2021 16:41:06 -0500
|
||||
Subject: [PATCH] lithium: replace AI goal set with optimized collection
|
||||
|
||||
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
|
||||
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
||||
index 0cc0d719e95e108263683b7a40f4ce3a8ca9465b..abc27a60986602e84eb556436a65b997617852a1 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
||||
@@ -12,6 +12,7 @@ import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import org.slf4j.Logger;
|
||||
+import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; // Lithium
|
||||
|
||||
public class GoalSelector {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
@@ -27,7 +28,7 @@ public class GoalSelector {
|
||||
}
|
||||
};
|
||||
private final Map<Goal.Flag, WrappedGoal> lockedFlags = new EnumMap<>(Goal.Flag.class);
|
||||
- public final Set<WrappedGoal> availableGoals = Sets.newLinkedHashSet();
|
||||
+ public final Set<WrappedGoal> availableGoals = new ObjectLinkedOpenHashSet<>(); // Lithium - replace AI goal set with optimized collection
|
||||
private final Supplier<ProfilerFiller> profiler;
|
||||
private final EnumSet<Goal.Flag> disabledFlags = EnumSet.noneOf(Goal.Flag.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be.
|
||||
private final com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<net.minecraft.world.entity.ai.goal.Goal.Flag> goalTypes = new com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector
|
||||
@@ -1,243 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: SuperCoder7979 <25208576+SuperCoder7979@users.noreply.github.com>
|
||||
Date: Fri, 22 Jan 2021 16:38:19 -0500
|
||||
Subject: [PATCH] lithium: gen
|
||||
|
||||
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
|
||||
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
|
||||
|
||||
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/Pos.java b/src/main/java/me/jellysquid/mods/lithium/common/util/Pos.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c99eff34c1be07508c88fe9525c3ae1a087fdef7
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/jellysquid/mods/lithium/common/util/Pos.java
|
||||
@@ -0,0 +1,92 @@
|
||||
+package me.jellysquid.mods.lithium.common.util;
|
||||
+
|
||||
+import net.minecraft.core.SectionPos;
|
||||
+import net.minecraft.world.level.LevelHeightAccessor;
|
||||
+
|
||||
+public class Pos {
|
||||
+
|
||||
+ public static class BlockCoord {
|
||||
+ public static int getYSize(LevelHeightAccessor view) {
|
||||
+ return view.getHeight();
|
||||
+ }
|
||||
+ public static int getMinY(LevelHeightAccessor view) {
|
||||
+ return view.getMinBuildHeight();
|
||||
+ }
|
||||
+ public static int getMaxYInclusive(LevelHeightAccessor view) {
|
||||
+ return view.getMaxBuildHeight() - 1;
|
||||
+ }
|
||||
+ public static int getMaxYExclusive(LevelHeightAccessor view) {
|
||||
+ return view.getMaxBuildHeight();
|
||||
+ }
|
||||
+
|
||||
+ public static int getMaxInSectionCoord(int sectionCoord) {
|
||||
+ return 15 + getMinInSectionCoord(sectionCoord);
|
||||
+ }
|
||||
+
|
||||
+ public static int getMaxYInSectionIndex(LevelHeightAccessor view, int sectionIndex){
|
||||
+ return getMaxInSectionCoord(SectionYCoord.fromSectionIndex(view, sectionIndex));
|
||||
+ }
|
||||
+
|
||||
+ public static int getMinInSectionCoord(int sectionCoord) {
|
||||
+ return SectionPos.sectionToBlockCoord(sectionCoord);
|
||||
+ }
|
||||
+
|
||||
+ public static int getMinYInSectionIndex(LevelHeightAccessor view, int sectionIndex) {
|
||||
+ return getMinInSectionCoord(SectionYCoord.fromSectionIndex(view, sectionIndex));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static class ChunkCoord {
|
||||
+ public static int fromBlockCoord(int blockCoord) {
|
||||
+ return SectionPos.blockToSectionCoord(blockCoord);
|
||||
+ }
|
||||
+
|
||||
+ public static int fromBlockSize(int i) {
|
||||
+ return i >> 4; //same method as fromBlockCoord, just be clear about coord/size semantic difference
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static class SectionYCoord {
|
||||
+ public static int getNumYSections(LevelHeightAccessor view) {
|
||||
+ return view.getSectionsCount();
|
||||
+ }
|
||||
+ public static int getMinYSection(LevelHeightAccessor view) {
|
||||
+ return view.getMinSection();
|
||||
+ }
|
||||
+ public static int getMaxYSectionInclusive(LevelHeightAccessor view) {
|
||||
+ return view.getMaxSection() - 1;
|
||||
+ }
|
||||
+ public static int getMaxYSectionExclusive(LevelHeightAccessor view) {
|
||||
+ return view.getMaxSection();
|
||||
+ }
|
||||
+
|
||||
+ public static int fromSectionIndex(LevelHeightAccessor view, int sectionCoord) {
|
||||
+ return sectionCoord + SectionYCoord.getMinYSection(view);
|
||||
+ }
|
||||
+ public static int fromBlockCoord(int blockCoord) {
|
||||
+ return SectionPos.blockToSectionCoord(blockCoord);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static class SectionYIndex {
|
||||
+ public static int getNumYSections(LevelHeightAccessor view) {
|
||||
+ return view.getSectionsCount();
|
||||
+ }
|
||||
+ public static int getMinYSectionIndex(LevelHeightAccessor view) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ public static int getMaxYSectionIndexInclusive(LevelHeightAccessor view) {
|
||||
+ return view.getSectionsCount() - 1;
|
||||
+ }
|
||||
+ public static int getMaxYSectionIndexExclusive(LevelHeightAccessor view) {
|
||||
+ return view.getSectionsCount();
|
||||
+ }
|
||||
+
|
||||
+ public static int fromSectionCoord(LevelHeightAccessor view, int sectionCoord) {
|
||||
+ return sectionCoord - SectionYCoord.getMinYSection(view);
|
||||
+ }
|
||||
+ public static int fromBlockCoord(LevelHeightAccessor view, int blockCoord) {
|
||||
+ return fromSectionCoord(view, SectionPos.blockToSectionCoord(blockCoord));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java
|
||||
index 91b273d058d2fe83207cc562a25711e4d621c862..982ebf0fe6aa4d4f42e8e3b8820fbaf1f7736849 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java
|
||||
@@ -54,6 +54,7 @@ import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.ticks.LevelTickAccess;
|
||||
import net.minecraft.world.ticks.WorldGenTickAccess;
|
||||
import org.slf4j.Logger;
|
||||
+import me.jellysquid.mods.lithium.common.util.Pos; // DivineMC - lithium: gen
|
||||
|
||||
public class WorldGenRegion implements WorldGenLevel {
|
||||
|
||||
@@ -82,6 +83,8 @@ public class WorldGenRegion implements WorldGenLevel {
|
||||
private Supplier<String> currentlyGenerating;
|
||||
private final AtomicLong subTickCount = new AtomicLong();
|
||||
private static final ResourceLocation WORLDGEN_REGION_RANDOM = new ResourceLocation("worldgen_region_random");
|
||||
+ private ChunkAccess[] chunksArr; // DivineMC - lithium: gen
|
||||
+ private int minChunkX, minChunkZ; // DivineMC - lithium: gen
|
||||
|
||||
public WorldGenRegion(ServerLevel world, List<ChunkAccess> chunks, ChunkStatus status, int placementRadius) {
|
||||
this.generatingStatus = status;
|
||||
@@ -104,6 +107,12 @@ public class WorldGenRegion implements WorldGenLevel {
|
||||
this.lastPos = ((ChunkAccess) chunks.get(chunks.size() - 1)).getPos();
|
||||
this.structureManager = world.structureManager().forWorldGenRegion(this);
|
||||
}
|
||||
+ // DivineMC start - lithium: gen
|
||||
+ this.minChunkX = this.firstPos.x;
|
||||
+ this.minChunkZ = this.firstPos.z;
|
||||
+
|
||||
+ this.chunksArr = chunks.toArray(new ChunkAccess[0]);
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
public boolean isOldChunkAround(ChunkPos chunkPos, int checkRadius) {
|
||||
@@ -119,11 +128,33 @@ public class WorldGenRegion implements WorldGenLevel {
|
||||
this.currentlyGenerating = structureName;
|
||||
}
|
||||
|
||||
+ // DivineMC start - lithium: gen
|
||||
+ /**
|
||||
+ * @reason Use the chunk array for faster access
|
||||
+ * @author SuperCoder7979, 2No2Name
|
||||
+ */
|
||||
@Override
|
||||
public ChunkAccess getChunk(int chunkX, int chunkZ) {
|
||||
- return this.getChunk(chunkX, chunkZ, ChunkStatus.EMPTY);
|
||||
+ int x = chunkX - this.minChunkX;
|
||||
+ int z = chunkZ - this.minChunkZ;
|
||||
+ int w = this.size;
|
||||
+
|
||||
+ if (x >= 0 && z >= 0 && x < w && z < w) {
|
||||
+ return this.chunksArr[x + z * w];
|
||||
+ } else {
|
||||
+ throw new NullPointerException("No chunk exists at " + new ChunkPos(chunkX, chunkZ));
|
||||
+ }
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Use our chunk fetch function
|
||||
+ */
|
||||
+ public ChunkAccess getChunk(BlockPos pos) {
|
||||
+ // Skip checking chunk.getStatus().isAtLeast(ChunkStatus.EMPTY) here, because it is always true
|
||||
+ return this.getChunk(Pos.ChunkCoord.fromBlockCoord(pos.getX()), Pos.ChunkCoord.fromBlockCoord(pos.getZ()));
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
+
|
||||
@Nullable
|
||||
@Override
|
||||
public ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) {
|
||||
@@ -179,10 +210,24 @@ public class WorldGenRegion implements WorldGenLevel {
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ // DivineMC start - lithium: gen
|
||||
+ /**
|
||||
+ * @reason Avoid pointer de-referencing, make method easier to inline
|
||||
+ * @author JellySquid
|
||||
+ */
|
||||
@Override
|
||||
public BlockState getBlockState(BlockPos pos) {
|
||||
- return this.getChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ())).getBlockState(pos);
|
||||
+ int x = (Pos.ChunkCoord.fromBlockCoord(pos.getX())) - this.minChunkX;
|
||||
+ int z = (Pos.ChunkCoord.fromBlockCoord(pos.getZ())) - this.minChunkZ;
|
||||
+ int w = this.size;
|
||||
+
|
||||
+ if (x >= 0 && z >= 0 && x < w && z < w) {
|
||||
+ return this.chunksArr[x + z * w].getBlockState(pos);
|
||||
+ } else {
|
||||
+ throw new NullPointerException("No chunk exists at " + new ChunkPos(pos));
|
||||
+ }
|
||||
}
|
||||
+ // DivineMC end
|
||||
|
||||
@Override
|
||||
public FluidState getFluidState(BlockPos pos) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
||||
index cf87490a446285132daaf9d90154ac6d477a62fe..3d6c50822701a3828cbde704f419d1c900a67954 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
||||
@@ -67,6 +67,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
|
||||
public final Registry<NormalNoise.NoiseParameters> noises;
|
||||
public final Holder<NoiseGeneratorSettings> settings;
|
||||
private final Aquifer.FluidPicker globalFluidPicker;
|
||||
+ private int cachedSeaLevel; // DivineMC - lithium: gen
|
||||
|
||||
public NoiseBasedChunkGenerator(Registry<StructureSet> structureSetRegistry, Registry<NormalNoise.NoiseParameters> noiseRegistry, BiomeSource populationSource, Holder<NoiseGeneratorSettings> settings) {
|
||||
super(structureSetRegistry, Optional.empty(), populationSource);
|
||||
@@ -83,6 +84,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
|
||||
this.globalFluidPicker = (j, k, l) -> {
|
||||
return k < Math.min(-54, i) ? aquifer_b : aquifer_b1;
|
||||
};
|
||||
+ this.cachedSeaLevel = ((NoiseGeneratorSettings) this.settings.value()).seaLevel(); // DivineMC - lithium: gen
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -398,10 +400,19 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
|
||||
return ((NoiseGeneratorSettings) this.settings.value()).noiseSettings().height();
|
||||
}
|
||||
|
||||
+ // DivineMC start - lithium: gen
|
||||
+ /**
|
||||
+ * Use cached sea level instead of retrieving from the registry every time.
|
||||
+ * This method is called for every block in the chunk so this will save a lot of registry lookups.
|
||||
+ *
|
||||
+ * @author SuperCoder79
|
||||
+ * @reason avoid registry lookup
|
||||
+ */
|
||||
@Override
|
||||
public int getSeaLevel() {
|
||||
- return ((NoiseGeneratorSettings) this.settings.value()).seaLevel();
|
||||
+ return this.cachedSeaLevel;
|
||||
}
|
||||
+ // DivineMC end
|
||||
|
||||
@Override
|
||||
public int getMinY() {
|
||||
@@ -1,20 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Tue, 14 Mar 2023 21:03:19 +0300
|
||||
Subject: [PATCH] Update Bungeecord Chat API
|
||||
|
||||
ok, it will be build 9
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index 181e9cd8623995f40e696ccfe49754dc340405d8..ba11fc979aac6f9a4bc812bc83b42b5ff2916b6d 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -25,7 +25,7 @@ dependencies {
|
||||
// api dependencies are listed transitively to API consumers
|
||||
api("com.google.guava:guava:31.1-jre")
|
||||
api("com.google.code.gson:gson:2.10")
|
||||
- api("net.md-5:bungeecord-chat:1.16-R0.4-deprecated+build.9") // Paper
|
||||
+ api("net.md-5:bungeecord-chat:1.19-R0.1-SNAPSHOT") // Paper // DivineMC
|
||||
api("org.yaml:snakeyaml:1.33")
|
||||
// Paper start
|
||||
api("com.googlecode.json-simple:json-simple:1.1.1") {
|
||||
@@ -1,21 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Tue, 4 Jun 2019 15:50:08 -0500
|
||||
Subject: [PATCH] Fix 'outdated server' showing in ping before server fully
|
||||
boots
|
||||
|
||||
Original code by PurpurMC, licensed under MIT (removed now)
|
||||
You can find the original code on https://github.com/PurpurMC/Purpur
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java
|
||||
index 0725c39d9cbec3282f93975a0ae76f060f70d86d..b1afe7d9fff390cc9668ce9bbb408d64147553e6 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java
|
||||
@@ -152,6 +152,7 @@ public class ServerStatusPacketListenerImpl implements ServerStatusPacketListene
|
||||
this.connection.send(new ClientboundStatusResponsePacket(ping));
|
||||
// CraftBukkit end
|
||||
*/
|
||||
+ if (this.server.getStatus().getVersion() == null) return; // Purpur - do not respond to pings before we know the protocol version
|
||||
com.destroystokyo.paper.network.StandardPaperServerListPingEventImpl.processRequest(this.server, this.connection);
|
||||
// Paper end
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: foss-mc <69294560+foss-mc@users.noreply.github.com>
|
||||
Date: Thu, 1 Jul 2021 11:59:11 +0000
|
||||
Subject: [PATCH] Remove TickTask
|
||||
|
||||
Original code by PatinaMC, licensed under GNU General Public License v3.0
|
||||
You can find the original code on https://github.com/PatinaMC/Patina
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 60ce593f25bdd90d53407c1281f580ef5429c9ee..91c1a7010bc46c5b515207b053caf356ae833079 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -194,7 +194,7 @@ import org.bukkit.event.server.ServerLoadEvent;
|
||||
|
||||
import co.aikar.timings.MinecraftTimings; // Paper
|
||||
|
||||
-public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTask> implements CommandSource, AutoCloseable {
|
||||
+public abstract class MinecraftServer extends ReentrantBlockableEventLoop<Runnable> implements CommandSource, AutoCloseable { // Patina
|
||||
|
||||
private static MinecraftServer SERVER; // Paper
|
||||
public static final Logger LOGGER = LogUtils.getLogger();
|
||||
@@ -1297,19 +1297,21 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
@Override
|
||||
- public TickTask wrapRunnable(Runnable runnable) {
|
||||
+ public Runnable wrapRunnable(Runnable runnable) { // Patina
|
||||
// Paper start - anything that does try to post to main during watchdog crash, run on watchdog
|
||||
if (this.hasStopped && Thread.currentThread().equals(shutdownThread)) {
|
||||
runnable.run();
|
||||
runnable = () -> {};
|
||||
}
|
||||
// Paper end
|
||||
- return new TickTask(this.tickCount, runnable);
|
||||
+ return runnable; // Patina
|
||||
}
|
||||
|
||||
+ /* // Patina
|
||||
protected boolean shouldRun(TickTask ticktask) {
|
||||
return ticktask.getTick() + 3 < this.tickCount || this.haveTime();
|
||||
}
|
||||
+ */
|
||||
|
||||
@Override
|
||||
public boolean pollTask() {
|
||||
@@ -1341,10 +1343,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
}
|
||||
|
||||
+ /* // Patina
|
||||
public void doRunTask(TickTask ticktask) { // CraftBukkit - decompile error
|
||||
this.getProfiler().incrementCounter("runTask");
|
||||
super.doRunTask(ticktask);
|
||||
}
|
||||
+ */
|
||||
|
||||
private void updateStatusIcon(ServerStatus metadata) {
|
||||
Optional<File> optional = Optional.of(this.getFile("server-icon.png")).filter(File::isFile);
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
index c6f5d6756fa0e068a462d9c0ded12e0771abba37..6b8b99f32629c0b4a6db3f7c808430dd88249f8e 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -1012,10 +1012,12 @@ public class ServerChunkCache extends ChunkSource {
|
||||
return runnable;
|
||||
}
|
||||
|
||||
+ /* // Patina
|
||||
@Override
|
||||
protected boolean shouldRun(Runnable task) {
|
||||
return true;
|
||||
}
|
||||
+ */
|
||||
|
||||
@Override
|
||||
protected boolean scheduleExecutables() {
|
||||
diff --git a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java
|
||||
index 83701fbfaa56a232593ee8f11a3afb8941238bfa..9b71f38bf10b63c0a4304a053540c9c00099bf47 100644
|
||||
--- a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java
|
||||
+++ b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java
|
||||
@@ -29,7 +29,7 @@ public abstract class BlockableEventLoop<R extends Runnable> implements Profiler
|
||||
|
||||
protected abstract R wrapRunnable(Runnable runnable);
|
||||
|
||||
- protected abstract boolean shouldRun(R task);
|
||||
+ //protected abstract boolean shouldRun(R task); // Patina
|
||||
|
||||
public boolean isSameThread() {
|
||||
return Thread.currentThread() == this.getRunningThread();
|
||||
@@ -120,7 +120,7 @@ public abstract class BlockableEventLoop<R extends Runnable> implements Profiler
|
||||
R runnable = this.pendingRunnables.peek();
|
||||
if (runnable == null) {
|
||||
return false;
|
||||
- } else if (this.blockingCount == 0 && !this.shouldRun(runnable)) {
|
||||
+ } else if (this.blockingCount == 0 && !true/*this.shouldRun(runnable)*/) { // Patina
|
||||
return false;
|
||||
} else {
|
||||
this.doRunTask(this.pendingRunnables.remove());
|
||||
@@ -1,30 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: foss-mc <69294560+foss-mc@users.noreply.github.com>
|
||||
Date: Thu, 1 Jul 2021 12:26:15 +0000
|
||||
Subject: [PATCH] Completely remove bootstrapExecutor
|
||||
|
||||
Original code by PatinaMC, licensed under GNU General Public License v3.0
|
||||
You can find the original code on https://github.com/PatinaMC/Patina
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
|
||||
index 5ef58831a857fd8aa4ac30147762dc17d773a53e..93b41dec42423e3967df8f1a8f4fdd6eafd8d023 100644
|
||||
--- a/src/main/java/net/minecraft/Util.java
|
||||
+++ b/src/main/java/net/minecraft/Util.java
|
||||
@@ -79,7 +79,7 @@ public class Util {
|
||||
private static final int DEFAULT_MAX_THREADS = 255;
|
||||
private static final String MAX_THREADS_SYSTEM_PROPERTY = "max.bg.threads";
|
||||
private static final AtomicInteger WORKER_COUNT = new AtomicInteger(1);
|
||||
- private static final ExecutorService BOOTSTRAP_EXECUTOR = makeExecutor("Bootstrap", -2); // Paper - add -2 priority
|
||||
+ //private static final ExecutorService BOOTSTRAP_EXECUTOR = makeExecutor("Bootstrap", -2); // Paper - add -2 priority // Patina
|
||||
private static final ExecutorService BACKGROUND_EXECUTOR = makeExecutor("Main", -1); // Paper - add -1 priority
|
||||
// Paper start - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread
|
||||
public static final ExecutorService PROFILE_EXECUTOR = Executors.newFixedThreadPool(2, new java.util.concurrent.ThreadFactory() {
|
||||
@@ -207,7 +207,7 @@ public class Util {
|
||||
}
|
||||
|
||||
public static ExecutorService bootstrapExecutor() {
|
||||
- return BOOTSTRAP_EXECUTOR;
|
||||
+ return BACKGROUND_EXECUTOR; // Patina
|
||||
}
|
||||
|
||||
public static ExecutorService backgroundExecutor() {
|
||||
@@ -1,34 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Gardling <titaniumtown@gmail.com>
|
||||
Date: Mon, 6 Dec 2021 10:27:12 -0500
|
||||
Subject: [PATCH] Remove 'sync-chunk-writes' in server.properties
|
||||
|
||||
Original code by Titaniumtown, licensed under GNU General Public License v3.0
|
||||
You can find the original code on https://gitlab.com/Titaniumtown/JettPack
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 0bcba79cec1919af1719ab05c183c821c434d5c6..40f11933defbac1a5d4494e643b19af20e5997f1 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -395,7 +395,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
BufferedWriter bufferedwriter = Files.newBufferedWriter(file);
|
||||
|
||||
try {
|
||||
- bufferedwriter.write(String.format(Locale.ROOT, "sync-chunk-writes=%s%n", dedicatedserverproperties.syncChunkWrites));
|
||||
+ //bufferedwriter.write(String.format(Locale.ROOT, "sync-chunk-writes=%s%n", dedicatedserverproperties.syncChunkWrites)); // JettPack - remove 'sync-chunk-writes' in server.properties
|
||||
bufferedwriter.write(String.format(Locale.ROOT, "gamemode=%s%n", dedicatedserverproperties.gamemode));
|
||||
bufferedwriter.write(String.format(Locale.ROOT, "spawn-monsters=%s%n", dedicatedserverproperties.spawnMonsters));
|
||||
bufferedwriter.write(String.format(Locale.ROOT, "entity-broadcast-range-percentage=%d%n", dedicatedserverproperties.entityBroadcastRangePercentage));
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
index c7e4330c93baff1f3027d7c75cf857b673d38970..cc0784560a7405edc8695ec9e652309920d54281 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
@@ -144,7 +144,7 @@ public class DedicatedServerProperties extends Settings<DedicatedServerPropertie
|
||||
this.maxWorldSize = this.get("max-world-size", (integer) -> {
|
||||
return Mth.clamp(integer, (int) 1, 29999984);
|
||||
}, 29999984);
|
||||
- this.syncChunkWrites = this.get("sync-chunk-writes", true) && Boolean.getBoolean("Paper.enable-sync-chunk-writes"); // Paper - hide behind flag
|
||||
+ this.syncChunkWrites = Boolean.getBoolean("Paper.enable-sync-chunk-writes"); // Paper - hide behind flag // JettPack - remove 'sync-chunk-writes' in server.properties
|
||||
this.enableJmxMonitoring = this.get("enable-jmx-monitoring", false);
|
||||
this.enableStatus = this.get("enable-status", true);
|
||||
this.hideOnlinePlayers = this.get("hide-online-players", false);
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Fri, 31 Mar 2023 00:39:40 +0300
|
||||
Subject: [PATCH] Bump Bungeecord Chat API to 1.19-R0.1-SNAPSHOT
|
||||
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index fc107bffc4efe56816d42c7f78d04897fe253729..3c52299eb08d0a15264f98127605a706597bf6ba 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -27,7 +27,7 @@ dependencies {
|
||||
// api dependencies are listed transitively to API consumers
|
||||
api("com.google.guava:guava:31.1-jre")
|
||||
api("com.google.code.gson:gson:2.10")
|
||||
- api("net.md-5:bungeecord-chat:1.16-R0.4-deprecated+build.9") // Paper
|
||||
+ api("net.md-5:bungeecord-chat:1.19-R0.1-SNAPSHOT") // Paper // DivineMC
|
||||
api("org.yaml:snakeyaml:1.33")
|
||||
api("org.joml:joml:1.10.5")
|
||||
// Paper start
|
||||
@@ -1,84 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Fri, 31 Mar 2023 23:38:43 +0300
|
||||
Subject: [PATCH] Rework Spigot Deprecations
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/OfflinePlayer.java b/src/main/java/org/bukkit/OfflinePlayer.java
|
||||
index df642a55003517040be795b44a8bf107dd88810b..09ae729cfdcc60c3315e3d87422e92db8c482fe5 100644
|
||||
--- a/src/main/java/org/bukkit/OfflinePlayer.java
|
||||
+++ b/src/main/java/org/bukkit/OfflinePlayer.java
|
||||
@@ -165,9 +165,11 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||
* UTC.
|
||||
*
|
||||
* @return Date of last log-in for this player, or 0
|
||||
- * @deprecated The API contract is ambiguous and the implementation may or may not return the correct value given this API ambiguity. It is instead recommended use {@link #getLastLogin()} or {@link #getLastSeen()} depending on your needs.
|
||||
+ * @see #hasPlayedBefore()
|
||||
+ * @see #getLastLogin()
|
||||
+ * @see #getLastSeen()
|
||||
*/
|
||||
- @Deprecated
|
||||
+ // @Deprecated // DivineMC - remove deprecated
|
||||
public long getLastPlayed();
|
||||
|
||||
/**
|
||||
diff --git a/src/main/java/org/bukkit/entity/Damageable.java b/src/main/java/org/bukkit/entity/Damageable.java
|
||||
index fc4d3bcd9b16097086fef7975274d825b65adb10..e485975dbb6973d2b21259c4e4d5d75191bacb60 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Damageable.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Damageable.java
|
||||
@@ -60,9 +60,9 @@ public interface Damageable extends Entity {
|
||||
* Gets the maximum health this entity has.
|
||||
*
|
||||
* @return Maximum health
|
||||
- * @deprecated use {@link Attribute#GENERIC_MAX_HEALTH}.
|
||||
+ * @see Attribute#GENERIC_MAX_HEALTH
|
||||
*/
|
||||
- @Deprecated
|
||||
+ // @Deprecated // DivineMC
|
||||
double getMaxHealth();
|
||||
|
||||
/**
|
||||
@@ -75,15 +75,15 @@ public interface Damageable extends Entity {
|
||||
* {@link Wither}, etc...} will have their bar scaled accordingly.
|
||||
*
|
||||
* @param health amount of health to set the maximum to
|
||||
- * @deprecated use {@link Attribute#GENERIC_MAX_HEALTH}.
|
||||
+ * @see Attribute#GENERIC_MAX_HEALTH
|
||||
*/
|
||||
- @Deprecated
|
||||
+ // @Deprecated // DivineMC
|
||||
void setMaxHealth(double health);
|
||||
|
||||
/**
|
||||
* Resets the max health to the original amount.
|
||||
- * @deprecated use {@link Attribute#GENERIC_MAX_HEALTH}.
|
||||
+ * @see Attribute#GENERIC_MAX_HEALTH
|
||||
*/
|
||||
- @Deprecated
|
||||
+ // @Deprecated // DivineMC
|
||||
void resetMaxHealth();
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index 482c7893ecd14f189ae4fa2d5a0f4c96f4a85137..de4fe49abe3dba096e63247cbba92a58c5486aee 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -281,14 +281,15 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* Returns true if the entity is supported by a block.
|
||||
*
|
||||
* This value is a state updated by the client after each movement.
|
||||
- *
|
||||
- * @return True if entity is on ground.
|
||||
- * @deprecated This value is controlled only by the client and is therefore
|
||||
+ * <p>
|
||||
+ * Note: This value is controlled only by the client and is therefore
|
||||
* unreliable and vulnerable to spoofing and/or desync depending on the
|
||||
* context/time which it is accessed
|
||||
+ *
|
||||
+ * @return True if entity is on ground.
|
||||
*/
|
||||
@Override
|
||||
- @Deprecated
|
||||
+ // @Deprecated // DivineMC
|
||||
public boolean isOnGround();
|
||||
|
||||
/**
|
||||
@@ -1,55 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sat, 11 Dec 2021 12:18:47 -0500
|
||||
Subject: [PATCH] Paper PR - Add Movement Direction API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
index 654dc0c6d98b29cf45d3826aece374726e3e9802..a1dfe9e1509a1b852e991e29c720fdfad596a2f8 100644
|
||||
--- a/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
@@ -1149,6 +1149,44 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
|
||||
* @see Location#setYaw(float)
|
||||
*/
|
||||
void setBodyYaw(float bodyYaw);
|
||||
+
|
||||
+ /**
|
||||
+ * This number represents how much the entity is trying to move sideways.
|
||||
+ * <p>
|
||||
+ * This number is ranges from -1 to 1,
|
||||
+ * where positive 1 represents the left and -1 represents the right.
|
||||
+ * <p>
|
||||
+ * Note that for {@link Player} entities only update this value when riding an entity, which may cause it
|
||||
+ * to be inaccurate when dismounted.
|
||||
+ *
|
||||
+ * @return direction repesented as -1 to 1
|
||||
+ */
|
||||
+ float getSidewaysMotion();
|
||||
+
|
||||
+ /**
|
||||
+ * This number represents how much the entity is trying to move
|
||||
+ * in the upwards direction.
|
||||
+ * <p>
|
||||
+ * This number is ranges from -1 to 1,
|
||||
+ * where positive 1 represents the up and -1 represents the down.
|
||||
+ * <p>
|
||||
+ * Note that for {@link Player} entities this value is never updated.
|
||||
+ *
|
||||
+ * @return direction repesented as -1 to 1
|
||||
+ */
|
||||
+ float getUpwardsMotion();
|
||||
+
|
||||
+ /**
|
||||
+ * This number represents how much the entity is trying to move forward.
|
||||
+ * <p>
|
||||
+ * This number is ranges from -1 to 1,
|
||||
+ * where positive 1 represents the up and -1 represents the down.
|
||||
+ * <p>
|
||||
+ * Note that for {@link Player} entities only update this value when riding an entity, so it may be inaccurate when dismounted.
|
||||
+ *
|
||||
+ * @return direction repesented as -1 to 1
|
||||
+ */
|
||||
+ float getForwardMotion();
|
||||
// Paper end
|
||||
|
||||
// Purpur start
|
||||
@@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sun, 17 Oct 2021 14:53:28 -0400
|
||||
Subject: [PATCH] Paper PR - BoneMeal API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
|
||||
index adf8169d5baefa7a33c33ef066180a8116617756..d1071fe098d60ecbdf45bc3f387dab54aaaa8b77 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -4121,4 +4121,20 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Applies bonemeal at a specific location
|
||||
+ * <p>
|
||||
+ * Modifications done in the predicate are respected
|
||||
+ * and will not be applied if false is returned.
|
||||
+ *
|
||||
+ * @param location Location to apply
|
||||
+ * @param face Blockface to apply as
|
||||
+ * @param showParticles If particles should be shown on success
|
||||
+ * @param predicate blockstate predicate
|
||||
+ * @return true if the bonemeal was applied, false if not
|
||||
+ */
|
||||
+ boolean applyBoneMeal(@NotNull Location location, @NotNull org.bukkit.block.BlockFace face, boolean showParticles, @Nullable Predicate<org.bukkit.block.BlockState> predicate);
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sat, 1 Apr 2023 00:31:15 +0300
|
||||
Subject: [PATCH] Additional pathfinding API
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java b/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java
|
||||
index 43f062257472a06e9e64c2feef6c3b1012aee00e..d3f12a2edeb5c0c548cfa1a13e93dbd1774b83a3 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java
|
||||
@@ -208,5 +208,14 @@ public interface Pathfinder {
|
||||
* @return The closest point the path can get to the target location
|
||||
*/
|
||||
@Nullable Location getFinalPoint();
|
||||
+
|
||||
+ // DivineMC start
|
||||
+ /**
|
||||
+ * Checks whether the final point if this path can be reached
|
||||
+ *
|
||||
+ * @return whether the final point if this path can be reached
|
||||
+ */
|
||||
+ boolean canReachFinalPoint();
|
||||
+ // DivineMC end
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bjarne Koll <lynxplay101@gmail.com>
|
||||
Date: Thu, 9 Dec 2021 01:53:30 +0100
|
||||
Subject: [PATCH] Optimize spigot event bus
|
||||
|
||||
This patch contains a lot of small optimizations to the spigot event bus
|
||||
to improve its speed as much as possible, allowing for a large amount of
|
||||
events to be published by the server without impacting the overall
|
||||
performance too much.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/Event.java b/src/main/java/org/bukkit/event/Event.java
|
||||
index 8ec56cd6b8e0f5c5dd8c7c88b4671e18dcf109d0..caae79275802bc5e5a5385d6a11903dfa84325d1 100644
|
||||
--- a/src/main/java/org/bukkit/event/Event.java
|
||||
+++ b/src/main/java/org/bukkit/event/Event.java
|
||||
@@ -14,7 +14,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public abstract class Event {
|
||||
private String name;
|
||||
- private final boolean async;
|
||||
+ private final net.kyori.adventure.util.TriState async; // KTP - optimize spigot event bus
|
||||
|
||||
/**
|
||||
* The default constructor is defined for cleaner code. This constructor
|
||||
@@ -32,9 +32,35 @@ public abstract class Event {
|
||||
* by default from default constructor
|
||||
*/
|
||||
public Event(boolean isAsync) {
|
||||
+ // KTP start - optimize spigot event bus
|
||||
+ this(net.kyori.adventure.util.TriState.byBoolean(isAsync));
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * This constructor is used to explicitly declare an event as synchronous
|
||||
+ * or asynchronous or potentially unset.
|
||||
+ *
|
||||
+ * @param isAsync true indicates the event will fire asynchronously, false
|
||||
+ * by default from default constructor, unset indicates that the event may be called on either the server thread or off the server
|
||||
+ * thread.
|
||||
+ */
|
||||
+ public Event(@NotNull final net.kyori.adventure.util.TriState isAsync) {
|
||||
this.async = isAsync;
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Returns a tristate that, when resolving to true or false, has the exact indications defined by {@link #isAsynchronous()}.
|
||||
+ * <p>
|
||||
+ * If the tristate resolves to NOT_SET, the event may or may not have been fired off the main thread, meaning a plugin would have
|
||||
+ * to validate what thread the spigot event bus was called on.
|
||||
+ *
|
||||
+ * @return the tristate enum.
|
||||
+ */
|
||||
+ public final @NotNull net.kyori.adventure.util.TriState asynchronous() {
|
||||
+ return this.async;
|
||||
+ }
|
||||
+ // KTP end - optimize spigot event bus
|
||||
+
|
||||
// Paper start
|
||||
/**
|
||||
* Calls the event and tests if cancelled.
|
||||
@@ -92,7 +118,7 @@ public abstract class Event {
|
||||
* @return false by default, true if the event fires asynchronously
|
||||
*/
|
||||
public final boolean isAsynchronous() {
|
||||
- return async;
|
||||
+ return this.async == net.kyori.adventure.util.TriState.TRUE; // KTP - optimize spigot event bus
|
||||
}
|
||||
|
||||
public enum Result {
|
||||
diff --git a/src/main/java/org/bukkit/plugin/RegisteredListener.java b/src/main/java/org/bukkit/plugin/RegisteredListener.java
|
||||
index 3b3d9642a8d63798dc28f2f8df77f0466451cbff..2dad4a19f4ec6f7463d749465189acfb206e58e3 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/RegisteredListener.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/RegisteredListener.java
|
||||
@@ -62,8 +62,10 @@ public class RegisteredListener {
|
||||
* @throws EventException If an event handler throws an exception.
|
||||
*/
|
||||
public void callEvent(@NotNull final Event event) throws EventException {
|
||||
- if (event instanceof Cancellable) {
|
||||
- if (((Cancellable) event).isCancelled() && isIgnoringCancelled()) {
|
||||
+ // KTP start - optimize spigot event bus
|
||||
+ if (isIgnoringCancelled()) {
|
||||
+ if (event instanceof Cancellable cancellable && cancellable.isCancelled()) {
|
||||
+ // KTP end - optimize spigot event bus
|
||||
return;
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
|
||||
index 13da387d3b59bc67c0d73e3fbd3a4034b1281527..ea67676bcbbd475c6b820079273e80492488c459 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
|
||||
@@ -304,4 +304,11 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm
|
||||
}
|
||||
|
||||
// Paper end
|
||||
+
|
||||
+ // KTP start - expose addURL
|
||||
+ @Override
|
||||
+ public void addURL(final URL url) {
|
||||
+ super.addURL(url);
|
||||
+ }
|
||||
+ // KTP end - expose addURL
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Mon, 27 Mar 2023 13:16:41 +0300
|
||||
Subject: [PATCH] Accept EULA
|
||||
|
||||
I removed this patch, because on new server startup without entering eula=true in eula.txt, server.properties file only contains `eula: true` and no more.
|
||||
So this patch was removed.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
|
||||
index dae36c6452ccd57a436dd918547b64d59957ab0a..023f20b759027302aea7a646f63f335998baf848 100644
|
||||
--- a/src/main/java/net/minecraft/server/Main.java
|
||||
+++ b/src/main/java/net/minecraft/server/Main.java
|
||||
@@ -165,6 +165,20 @@ public class Main {
|
||||
System.err.println( "If you do not agree to the above EULA please stop your server and remove this flag immediately." );
|
||||
}
|
||||
// Spigot End
|
||||
+
|
||||
+ // DivineMC start - Accept EULA by default
|
||||
+ if (!eula.hasAgreedToEULA()) {
|
||||
+ Main.LOGGER.warn("Automatically accepting Mojang's EULA. Please, stop using this Software immediately if you do not agree with this.");
|
||||
+ Main.LOGGER.warn("Note: this is a persistent change and will be stored in eula.txt from now on.");
|
||||
+ try (java.io.OutputStream outputStream = java.nio.file.Files.newOutputStream(path1)) {
|
||||
+ var properties = new java.util.Properties();
|
||||
+ properties.setProperty("eula", "true");
|
||||
+ properties.store(outputStream, null);
|
||||
+ }
|
||||
+ eulaAgreed = true;
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
+
|
||||
if (!eula.hasAgreedToEULA() && !eulaAgreed) { // Spigot
|
||||
Main.LOGGER.info("You need to agree to the EULA in order to run the server. Go to eula.txt for more info.");
|
||||
return;
|
||||
@@ -1,45 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Fri, 31 Mar 2023 00:39:40 +0300
|
||||
Subject: [PATCH] Fix entity serialization
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index f2c6b52fe7fbb05afa0074684cd195f6ae598f1f..8f948df85246ecbbca2c3c2b99e24f847b7386c6 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -2356,15 +2356,6 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
||||
}
|
||||
}
|
||||
|
||||
- // Paper start - Entity serialization api
|
||||
- public boolean serializeEntity(CompoundTag compound) {
|
||||
- List<Entity> pass = new java.util.ArrayList<>(this.getPassengers());
|
||||
- this.passengers = ImmutableList.of();
|
||||
- boolean result = save(compound);
|
||||
- this.passengers = ImmutableList.copyOf(pass);
|
||||
- return result;
|
||||
- }
|
||||
- // Paper end - Entity serialization api
|
||||
public boolean save(CompoundTag nbt) {
|
||||
return this.isPassenger() ? false : this.saveAsPassenger(nbt);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
index e29dc1101c7aa4b7b2a2d2e732e27a1a14a2a234..bdbf2724204cb36de171900c2a8f92097da5102d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
@@ -528,8 +528,13 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
Preconditions.checkNotNull(entity, "null cannot be serialized");
|
||||
Preconditions.checkArgument(entity instanceof org.bukkit.craftbukkit.entity.CraftEntity, "only CraftEntities can be serialized");
|
||||
|
||||
+ net.minecraft.world.entity.Entity nmsEntity = ((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle();
|
||||
CompoundTag compound = new CompoundTag();
|
||||
- ((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().serializeEntity(compound);
|
||||
+ compound.putString("id", net.minecraft.world.entity.EntityType.getKey(nmsEntity.getType()).toString());
|
||||
+ List<net.minecraft.world.entity.Entity> pass = new java.util.ArrayList<>(nmsEntity.getPassengers());
|
||||
+ nmsEntity.passengers = com.google.common.collect.ImmutableList.of();
|
||||
+ nmsEntity.saveWithoutId(compound);
|
||||
+ nmsEntity.passengers = com.google.common.collect.ImmutableList.copyOf(pass);
|
||||
return serializeNbtToBytes(compound);
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 17 Jun 2018 22:16:25 -0400
|
||||
Subject: [PATCH] EMC - Allow negative Amplifier values
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/effect/MobEffectInstance.java b/src/main/java/net/minecraft/world/effect/MobEffectInstance.java
|
||||
index d94497083f3da89dbef6479ef8f70591e630e3e7..51eacc67a3aff80811f4a6878ce8867dc151d14b 100644
|
||||
--- a/src/main/java/net/minecraft/world/effect/MobEffectInstance.java
|
||||
+++ b/src/main/java/net/minecraft/world/effect/MobEffectInstance.java
|
||||
@@ -375,7 +375,7 @@ public class MobEffectInstance implements Comparable<MobEffectInstance> {
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
- return new MobEffectInstance(type, j, Math.max(i, 0), bl, bl2, bl3, mobEffectInstance, optional, key); // Purpur - add key
|
||||
+ return new MobEffectInstance(type, j, i, bl, bl2, bl3, mobEffectInstance, optional, key); // Purpur - add key // EMC - always use Amplifier, don't check > 0
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,18 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Fri, 31 Mar 2023 22:47:12 +0300
|
||||
Subject: [PATCH] Use unused ghast sound
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Ghast.java b/src/main/java/net/minecraft/world/entity/monster/Ghast.java
|
||||
index 77dcae6ecd87fade2b529386ba1360836363593a..20f6a52a635dded35e780c8e73604abfe5820068 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Ghast.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Ghast.java
|
||||
@@ -164,6 +164,7 @@ public class Ghast extends FlyingMob implements Enemy {
|
||||
|
||||
@Override
|
||||
protected SoundEvent getAmbientSound() {
|
||||
+ if (!level.dimensionType().ultraWarm() && random.nextInt(8) == 0) return SoundEvents.GHAST_SCREAM; // DivineMC
|
||||
return SoundEvents.GHAST_AMBIENT;
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sun, 2 Apr 2023 21:27:33 +0300
|
||||
Subject: [PATCH] Fallback to Dimension if World UUID is unknown
|
||||
|
||||
|
||||
diff --git a/src/main/java/gq/bxteam/divinemc/configuration/DivineConfig.java b/src/main/java/gq/bxteam/divinemc/configuration/DivineConfig.java
|
||||
index 9e802fbe8e5f1a3c24cb6bc9254c72a2a0c3fde1..cdf83dc33915632e29291c59eb1841991c03e8a0 100644
|
||||
--- a/src/main/java/gq/bxteam/divinemc/configuration/DivineConfig.java
|
||||
+++ b/src/main/java/gq/bxteam/divinemc/configuration/DivineConfig.java
|
||||
@@ -152,4 +152,9 @@ public class DivineConfig {
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
+
|
||||
+ public static boolean fallbackToDimensionIfWorldUUIDUnknown = true;
|
||||
+ private static void fallbackToDimensionIfWorldUUIDUnknown() {
|
||||
+ fallbackToDimensionIfWorldUUIDUnknown = getBoolean("settings.fallback-to-dimension-if-world-uuid-unknown", fallbackToDimensionIfWorldUUIDUnknown);
|
||||
+ }
|
||||
}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 9942ab57f883f79719dff20f666912face27d5c4..72a36cb6decaefe3195520445bbfbcb490c083b3 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -103,6 +103,7 @@ import net.minecraft.world.scores.PlayerTeam;
|
||||
import net.minecraft.world.scores.Scoreboard; // Paper
|
||||
import net.minecraft.world.scores.Team;
|
||||
import org.slf4j.Logger;
|
||||
+import gq.bxteam.divinemc.configuration.DivineConfig;
|
||||
|
||||
// CraftBukkit start
|
||||
import java.util.stream.Collectors;
|
||||
@@ -212,7 +213,14 @@ public abstract class PlayerList {
|
||||
if (bWorld != null) {
|
||||
resourcekey = ((CraftWorld) bWorld).getHandle().dimension();
|
||||
} else {
|
||||
- resourcekey = Level.OVERWORLD;
|
||||
+ // DivineMC start - Fallback to Dimension if World UUID is unknown
|
||||
+ if (DivineConfig.fallbackToDimensionIfWorldUUIDUnknown) {
|
||||
+ DataResult<ResourceKey<Level>> dataResult = Level.RESOURCE_KEY_CODEC.parse(new Dynamic<>(NbtOps.INSTANCE, nbttagcompound.get("Dimension")));
|
||||
+ resourcekey = dataResult.result().orElse(Level.OVERWORLD);
|
||||
+ } else {
|
||||
+ resourcekey = Level.OVERWORLD;
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
}
|
||||
} else if (nbttagcompound != null) {
|
||||
// Vanilla migration support
|
||||
@@ -1,35 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sat, 11 Dec 2021 12:18:42 -0500
|
||||
Subject: [PATCH] Paper PR - Add Movement Direction API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 7ef5980f7321662aa7034a74c2f6926846425db9..d26fb49a39880d650a82b59925d40b8d09fbc84b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -980,6 +980,24 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
throw new UnsupportedOperationException("Cannot set the hurt direction on a non player");
|
||||
}
|
||||
|
||||
+ // Paper start - Movement Direction API
|
||||
+ @Override
|
||||
+ public float getSidewaysMotion() {
|
||||
+ return this.getHandle().xxa;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public float getUpwardsMotion() {
|
||||
+ return this.getHandle().yya;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public float getForwardMotion() {
|
||||
+ return this.getHandle().zza;
|
||||
+ }
|
||||
+ // Paper end - Movement Direction API
|
||||
+
|
||||
+
|
||||
public static MobType fromBukkitEntityCategory(EntityCategory entityCategory) {
|
||||
switch (entityCategory) {
|
||||
case NONE:
|
||||
@@ -1,87 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sun, 17 Oct 2021 14:53:35 -0400
|
||||
Subject: [PATCH] Paper PR - BoneMeal API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/BoneMealItem.java b/src/main/java/net/minecraft/world/item/BoneMealItem.java
|
||||
index c26665bc59c18c4da467fb6ae33e51a65ecf1de6..bf65490f0239fc6d9d9c101ebce5845dd278ee48 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/BoneMealItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/BoneMealItem.java
|
||||
@@ -37,14 +37,16 @@ public class BoneMealItem extends Item {
|
||||
return BoneMealItem.applyBonemeal(context);
|
||||
}
|
||||
|
||||
- public static InteractionResult applyBonemeal(UseOnContext itemactioncontext) {
|
||||
- // CraftBukkit end
|
||||
+ // Paper start - BoneMeal API
|
||||
+ public static InteractionResult applyBonemeal(UseOnContext itemactioncontext) { return applyBonemeal(itemactioncontext, true); }
|
||||
+ public static InteractionResult applyBonemeal(UseOnContext itemactioncontext, boolean showParticles) {
|
||||
+ // Paper end - BoneMeal API
|
||||
Level world = itemactioncontext.getLevel();
|
||||
BlockPos blockposition = itemactioncontext.getClickedPos();
|
||||
BlockPos blockposition1 = blockposition.relative(itemactioncontext.getClickedFace());
|
||||
|
||||
if (BoneMealItem.growCrop(itemactioncontext.getItemInHand(), world, blockposition)) {
|
||||
- if (!world.isClientSide) {
|
||||
+ if (showParticles && !world.isClientSide) { // Paper - BoneMeal API
|
||||
world.levelEvent(1505, blockposition, 0);
|
||||
}
|
||||
|
||||
@@ -54,7 +56,7 @@ public class BoneMealItem extends Item {
|
||||
boolean flag = iblockdata.isFaceSturdy(world, blockposition, itemactioncontext.getClickedFace());
|
||||
|
||||
if (flag && BoneMealItem.growWaterPlant(itemactioncontext.getItemInHand(), world, blockposition1, itemactioncontext.getClickedFace())) {
|
||||
- if (!world.isClientSide) {
|
||||
+ if (showParticles && !world.isClientSide) { // Paper - BoneMeal API
|
||||
world.levelEvent(1505, blockposition1, 0);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 68df53648c9b76cf1b6abcaa90c5e8938e9e0d05..ad76c55fbd5ed4d3cfd0c30875547bebd1bac406 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -2472,5 +2472,43 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
return this.adventure$pointers;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean applyBoneMeal(@org.jetbrains.annotations.NotNull Location location, org.bukkit.block.BlockFace face, boolean showParticles, @org.jetbrains.annotations.Nullable Predicate<BlockState> predicate) {
|
||||
+ BlockPos pos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
+ net.minecraft.world.item.context.UseOnContext context = new net.minecraft.world.item.context.UseOnContext(this.getHandle(), null, net.minecraft.world.InteractionHand.MAIN_HAND, net.minecraft.world.item.Items.BONE_MEAL.getDefaultInstance(), new net.minecraft.world.phys.BlockHitResult(Vec3.ZERO, CraftBlock.blockFaceToNotch(face), pos, false));
|
||||
+
|
||||
+ // Save old capturing state
|
||||
+ boolean wasCapturingTrees = world.captureTreeGeneration;
|
||||
+ boolean wasCapturingBlockStates = world.captureBlockStates;
|
||||
+
|
||||
+ Map<BlockPos, org.bukkit.craftbukkit.block.CraftBlockState> capturedBlocks = world.capturedBlockStates;
|
||||
+ Map<BlockPos, net.minecraft.world.level.block.entity.BlockEntity> capturedTileEntities = world.capturedTileEntities;
|
||||
+
|
||||
+ // Create new state, capture everything
|
||||
+ world.capturedBlockStates = new java.util.LinkedHashMap<>();
|
||||
+ world.capturedTileEntities = new java.util.LinkedHashMap<>();
|
||||
+
|
||||
+ world.captureTreeGeneration = true;
|
||||
+ world.captureBlockStates = true;
|
||||
+
|
||||
+ net.minecraft.world.InteractionResult result = net.minecraft.world.item.BoneMealItem.applyBonemeal(context, showParticles);
|
||||
+
|
||||
+ // Revert back booleans
|
||||
+ world.captureTreeGeneration = wasCapturingTrees;
|
||||
+ world.captureBlockStates = wasCapturingBlockStates;
|
||||
+
|
||||
+ for (BlockState blockState : world.capturedBlockStates.values()) {
|
||||
+ if (predicate != null && predicate.test(blockState)) {
|
||||
+ blockState.update(true);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Revertback maps
|
||||
+ world.capturedBlockStates = capturedBlocks;
|
||||
+ world.capturedTileEntities = capturedTileEntities;
|
||||
+
|
||||
+ return result == net.minecraft.world.InteractionResult.CONSUME;
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sat, 1 Apr 2023 00:13:31 +0300
|
||||
Subject: [PATCH] Paper PR - Fire ServerListPingEvent for secondary motd send
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java b/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java
|
||||
index 6b0bdc266109cdfb874f08bf74323603921d2260..a355470f6b0e8286a178ad279ad93bcaf931cb51 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java
|
||||
@@ -75,13 +75,24 @@ public final class StandardPaperServerListPingEventImpl extends PaperServerListP
|
||||
}
|
||||
|
||||
public static void processRequest(MinecraftServer server, Connection networkManager) {
|
||||
+ ServerStatus ping = getEventResponse(server, networkManager);
|
||||
+
|
||||
+ if (ping == null) {
|
||||
+ networkManager.disconnect(null);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // Send response
|
||||
+ networkManager.send(new ClientboundStatusResponsePacket(ping));
|
||||
+ }
|
||||
+
|
||||
+ public static ServerStatus getEventResponse(MinecraftServer server, Connection networkManager) {
|
||||
StandardPaperServerListPingEventImpl event = new StandardPaperServerListPingEventImpl(server, networkManager, server.getStatus());
|
||||
server.server.getPluginManager().callEvent(event);
|
||||
|
||||
// Close connection immediately if event is cancelled
|
||||
if (event.isCancelled()) {
|
||||
- networkManager.disconnect(null);
|
||||
- return;
|
||||
+ return null;
|
||||
}
|
||||
|
||||
// Setup response
|
||||
@@ -107,10 +118,6 @@ public final class StandardPaperServerListPingEventImpl extends PaperServerListP
|
||||
} else {
|
||||
favicon = Optional.empty();
|
||||
}
|
||||
- final ServerStatus ping = new ServerStatus(description, players, Optional.of(version), favicon, server.enforceSecureProfile());
|
||||
-
|
||||
- // Send response
|
||||
- networkManager.send(new ClientboundStatusResponsePacket(ping));
|
||||
+ return new ServerStatus(description, players, Optional.of(version), favicon, server.enforceSecureProfile());
|
||||
}
|
||||
-
|
||||
-}
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index c27e455321951e76e4818fec0e64301f5620dbf6..1a90a7d91288b9a8ab3539785de2616a6f24aa48 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -304,11 +304,13 @@ public abstract class PlayerList {
|
||||
Component joinMessage = ichatmutablecomponent; // Paper - Adventure
|
||||
|
||||
playerconnection.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot());
|
||||
- ServerStatus serverping = this.server.getStatus();
|
||||
-
|
||||
- if (serverping != null) {
|
||||
- player.sendServerStatus(serverping);
|
||||
- }
|
||||
+ // Paper start - fire ServerListPingEvent
|
||||
+ io.papermc.paper.util.MCUtil.scheduleAsyncTask(() -> {
|
||||
+ if (player.hasDisconnected()) return;
|
||||
+ net.minecraft.network.protocol.status.ServerStatus status = com.destroystokyo.paper.network.StandardPaperServerListPingEventImpl.getEventResponse(this.server, player.connection.connection);
|
||||
+ if (status != null) player.sendServerStatus(status);
|
||||
+ });
|
||||
+ // Paper end
|
||||
|
||||
// player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players)); // Paper
|
||||
this.players.add(player);
|
||||
@@ -1,126 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sat, 1 Apr 2023 00:35:19 +0300
|
||||
Subject: [PATCH] Additional pathfinding API
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
|
||||
index 2d799fec40afe7dade649a294761d272c83157f0..81753d128d71bc6495d84358e861e919f731f4d0 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
|
||||
@@ -135,6 +135,13 @@ public class PaperPathfinder implements com.destroystokyo.paper.entity.Pathfinde
|
||||
}
|
||||
return toLoc(path.nodes.get(path.getNextNodeIndex()));
|
||||
}
|
||||
+
|
||||
+ // DivineMC start
|
||||
+ @Override
|
||||
+ public boolean canReachFinalPoint() {
|
||||
+ return path.canReach();
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
private Location toLoc(Node point) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
|
||||
index 3395bc1d9140ab5496ad998343a963ae12f630d6..43fbc659d1f789510d6aba3ea9b465e3ccde5a70 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
|
||||
@@ -595,7 +595,7 @@ public class Rabbit extends Animal implements VariantHolder<Rabbit.Variant> {
|
||||
}
|
||||
}
|
||||
|
||||
- private static class RabbitPanicGoal extends PanicGoal {
|
||||
+ public static class RabbitPanicGoal extends PanicGoal {
|
||||
|
||||
private final Rabbit rabbit;
|
||||
|
||||
@@ -611,7 +611,7 @@ public class Rabbit extends Animal implements VariantHolder<Rabbit.Variant> {
|
||||
}
|
||||
}
|
||||
|
||||
- private static class RabbitAvoidEntityGoal<T extends LivingEntity> extends AvoidEntityGoal<T> {
|
||||
+ public static class RabbitAvoidEntityGoal<T extends LivingEntity> extends AvoidEntityGoal<T> {
|
||||
|
||||
private final Rabbit rabbit;
|
||||
|
||||
@@ -626,7 +626,7 @@ public class Rabbit extends Animal implements VariantHolder<Rabbit.Variant> {
|
||||
}
|
||||
}
|
||||
|
||||
- private static class RaidGardenGoal extends MoveToBlockGoal {
|
||||
+ public static class RaidGardenGoal extends MoveToBlockGoal {
|
||||
|
||||
private final Rabbit rabbit;
|
||||
private boolean wantsToRaid;
|
||||
@@ -744,7 +744,7 @@ public class Rabbit extends Animal implements VariantHolder<Rabbit.Variant> {
|
||||
}
|
||||
}
|
||||
|
||||
- private static class EvilRabbitAttackGoal extends MeleeAttackGoal {
|
||||
+ public static class EvilRabbitAttackGoal extends MeleeAttackGoal {
|
||||
|
||||
public EvilRabbitAttackGoal(Rabbit rabbit) {
|
||||
super(rabbit, 1.4D, true);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
index 89978fcb14362af2527693f3e6ec57e169080c9f..e1d591a33ee544011effaebd56bf5ade7681c899 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
@@ -554,7 +554,7 @@ public class Slime extends Mob implements Enemy {
|
||||
}
|
||||
}
|
||||
|
||||
- private static class SlimeFloatGoal extends Goal {
|
||||
+ public static class SlimeFloatGoal extends Goal {
|
||||
|
||||
private final Slime slime;
|
||||
|
||||
@@ -591,7 +591,7 @@ public class Slime extends Mob implements Enemy {
|
||||
}
|
||||
}
|
||||
|
||||
- private static class SlimeAttackGoal extends Goal {
|
||||
+ public static class SlimeAttackGoal extends Goal {
|
||||
|
||||
private final Slime slime;
|
||||
private int growTiredTimer;
|
||||
@@ -668,7 +668,7 @@ public class Slime extends Mob implements Enemy {
|
||||
// Paper end
|
||||
}
|
||||
|
||||
- private static class SlimeRandomDirectionGoal extends Goal {
|
||||
+ public static class SlimeRandomDirectionGoal extends Goal {
|
||||
|
||||
private final Slime slime;
|
||||
private float chosenDegrees;
|
||||
@@ -707,7 +707,7 @@ public class Slime extends Mob implements Enemy {
|
||||
}
|
||||
}
|
||||
|
||||
- private static class SlimeKeepOnJumpingGoal extends Goal {
|
||||
+ public static class SlimeKeepOnJumpingGoal extends Goal {
|
||||
|
||||
private final Slime slime;
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
index 8e071a0922164970e033029c12058db9e8da261a..c5464e61d1ae6abb6a44bcdae292e8d763f47bdd 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
@@ -226,7 +226,7 @@ public class Spider extends Monster {
|
||||
return 0.65F;
|
||||
}
|
||||
|
||||
- private static class SpiderAttackGoal extends MeleeAttackGoal {
|
||||
+ public static class SpiderAttackGoal extends MeleeAttackGoal {
|
||||
|
||||
public SpiderAttackGoal(Spider spider) {
|
||||
super(spider, 1.0D, true);
|
||||
@@ -255,7 +255,7 @@ public class Spider extends Monster {
|
||||
}
|
||||
}
|
||||
|
||||
- private static class SpiderTargetGoal<T extends LivingEntity> extends NearestAttackableTargetGoal<T> {
|
||||
+ public static class SpiderTargetGoal<T extends LivingEntity> extends NearestAttackableTargetGoal<T> {
|
||||
|
||||
public SpiderTargetGoal(Spider spider, Class<T> targetEntityClass) {
|
||||
super(spider, targetEntityClass, true);
|
||||
@@ -1,80 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sat, 10 Jun 2023 13:22:43 +0300
|
||||
Subject: [PATCH] Better Impaling
|
||||
|
||||
|
||||
diff --git a/src/main/java/gq/bxteam/divinemc/configuration/DivineWorldConfig.java b/src/main/java/gq/bxteam/divinemc/configuration/DivineWorldConfig.java
|
||||
index ca344da743a7503795bdaeff0a1b14e0721f5092..55e9c680e31ef8dd0ede05e8b33a705e268338bc 100644
|
||||
--- a/src/main/java/gq/bxteam/divinemc/configuration/DivineWorldConfig.java
|
||||
+++ b/src/main/java/gq/bxteam/divinemc/configuration/DivineWorldConfig.java
|
||||
@@ -89,4 +89,9 @@ public class DivineWorldConfig {
|
||||
private void despawnShulkerBulletsOnOwnerDeath() {
|
||||
despawnShulkerBulletsOnOwnerDeath = getBoolean("gameplay-mechanics.mob.shulker.despawn-bullets-on-player-death", despawnShulkerBulletsOnOwnerDeath);
|
||||
}
|
||||
+
|
||||
+ public boolean enableBetterImpaling = true;
|
||||
+ private void enableBetterImpaling() {
|
||||
+ enableBetterImpaling = getBoolean("gameplay-mechanics.tools.trident.better-impaling", enableBetterImpaling);
|
||||
+ }
|
||||
}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
index 3162c27ee305f5280a326b953288c846d0b6cae0..73833f073e6ed25a1db6633ad82137619d265234 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
@@ -1682,6 +1682,15 @@ public abstract class Mob extends LivingEntity implements Targeting {
|
||||
|
||||
if (target instanceof LivingEntity) {
|
||||
f += EnchantmentHelper.getDamageBonus(this.getMainHandItem(), ((LivingEntity) target).getMobType());
|
||||
+ // DivineMC start - Better Impaling
|
||||
+ if (this.level().divinemcConfig.enableBetterImpaling) {
|
||||
+ if (((LivingEntity) target).getMobType() != net.minecraft.world.entity.MobType.WATER && target.isInWaterRainOrBubble()) {
|
||||
+ int impalingLevel = EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.IMPALING, getMainHandItem());
|
||||
+ if (impalingLevel > 0)
|
||||
+ f += net.minecraft.world.item.enchantment.Enchantments.IMPALING.getDamageBonus(impalingLevel, net.minecraft.world.entity.MobType.WATER);
|
||||
+ }
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
f1 += (float) EnchantmentHelper.getKnockbackBonus(this);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 9f5153580f96f643240a8817a74a47b22e2a85cc..8eabfbabb2b588bd6b7eed92b017b5dbb0672ce5 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -1295,6 +1295,14 @@ public abstract class Player extends LivingEntity {
|
||||
|
||||
if (target instanceof LivingEntity) {
|
||||
f1 = EnchantmentHelper.getDamageBonus(this.getMainHandItem(), ((LivingEntity) target).getMobType());
|
||||
+ // DivineMC start - Better Impaling
|
||||
+ if (this.level().divinemcConfig.enableBetterImpaling) {
|
||||
+ if (((LivingEntity) target).getMobType() != MobType.WATER && target.isInWaterRainOrBubble()) {
|
||||
+ int impalingLevel = EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.IMPALING, getMainHandItem());
|
||||
+ if (impalingLevel > 0)
|
||||
+ f += net.minecraft.world.item.enchantment.Enchantments.IMPALING.getDamageBonus(impalingLevel, MobType.WATER);
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
} else {
|
||||
f1 = EnchantmentHelper.getDamageBonus(this.getMainHandItem(), MobType.UNDEFINED);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java
|
||||
index 0ea182962d6647629fc98c9e7406f7b7ce012c5e..c7209c1decdd8a1c787b986c3db410042f0b60e1 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java
|
||||
@@ -134,6 +134,15 @@ public class ThrownTrident extends AbstractArrow {
|
||||
LivingEntity entityliving = (LivingEntity) entity;
|
||||
|
||||
f += EnchantmentHelper.getDamageBonus(this.tridentItem, entityliving.getMobType());
|
||||
+ // DivineMC start - Better Impaling
|
||||
+ if (this.level().divinemcConfig.enableBetterImpaling) {
|
||||
+ if (entityliving.getMobType() != net.minecraft.world.entity.MobType.WATER && entityliving.isInWaterRainOrBubble()) {
|
||||
+ int impalingLevel = EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.IMPALING, tridentItem);
|
||||
+ if (impalingLevel > 0)
|
||||
+ f += net.minecraft.world.item.enchantment.Enchantments.IMPALING.getDamageBonus(impalingLevel, net.minecraft.world.entity.MobType.WATER);
|
||||
+ }
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
Entity entity1 = this.getOwner();
|
||||
@@ -1,41 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Mon, 18 Sep 2023 00:35:27 +0300
|
||||
Subject: [PATCH] Do not process chat/commands before player has joined
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 9ba9356260d54ec318f07a8af221e9567ee03b12..28c46673995549a879e222d52abb9a7d2c24d6ed 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -6,6 +6,7 @@ import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.brigadier.ParseResults;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.logging.LogUtils;
|
||||
+import space.bxteam.divinemc.configuration.DivineConfig;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
@@ -2338,6 +2339,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
if (this.player.isRemoved() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) { // CraftBukkit - dead men tell no tales
|
||||
this.send(new ClientboundSystemChatPacket(Component.translatable("chat.disabled.options").withStyle(ChatFormatting.RED), false));
|
||||
return Optional.empty();
|
||||
+ } else if (player.joining && DivineConfig.doNotProcessChatCommands) { // DivineMC - EMC - do not handle chat messages before they joined
|
||||
+ return Optional.empty();
|
||||
} else {
|
||||
this.player.resetLastActionTime();
|
||||
return optional;
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
index c10403d781d25e4bb9e43d3f064fb1aebde00bfb..ef7983863da3b4febef3da2fab93fe581fbd65af 100644
|
||||
--- a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
+++ b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
@@ -152,4 +152,9 @@ public class DivineConfig {
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
+
|
||||
+ public static boolean doNotProcessChatCommands = true;
|
||||
+ private static void doNotProcessChatCommands() {
|
||||
+ doNotProcessChatCommands = getBoolean("settings.do-not-process-chat-commands", doNotProcessChatCommands);
|
||||
+ }
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Mon, 12 Jun 2023 18:33:05 +0300
|
||||
Subject: [PATCH] Paper PR - Optimize Varints
|
||||
|
||||
Original license: GPLv3
|
||||
Original project: https://github.com/PaperMC/Velocity
|
||||
Paper pull request: https://github.com/PaperMC/Paper/pull/8418
|
||||
UPD: it will be added back as soon as I figure out the minecraft network
|
||||
|
||||
diff --git a/src/main/java/gq/bxteam/divinemc/configuration/DivineConfig.java b/src/main/java/gq/bxteam/divinemc/configuration/DivineConfig.java
|
||||
index 512afaa97e89e3beb92cf2ebc46248eddd22cf5c..50878e4948df45bc2928edbe373be639d133060f 100644
|
||||
--- a/src/main/java/gq/bxteam/divinemc/configuration/DivineConfig.java
|
||||
+++ b/src/main/java/gq/bxteam/divinemc/configuration/DivineConfig.java
|
||||
@@ -162,4 +162,9 @@ public class DivineConfig {
|
||||
private static void allowAnyUsername() {
|
||||
allowAnyUsername = getBoolean("settings.player.allow-any-username", allowAnyUsername);
|
||||
}
|
||||
+
|
||||
+ public static boolean doOptimizeVarints = true;
|
||||
+ private static void doOptimizeVarints() {
|
||||
+ doOptimizeVarints = getBoolean("settings.optimization.optimize-varints", doOptimizeVarints);
|
||||
+ }
|
||||
}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
index 1f4b64a5f812376c499c98cb4be62469bd0b7dbe..2b1ae08ec33daedd0148f6731145a1d10a89277c 100644
|
||||
--- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
@@ -84,6 +84,8 @@ import org.joml.Vector3f;
|
||||
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack; // CraftBukkit
|
||||
|
||||
+import gq.bxteam.divinemc.configuration.DivineConfig; // DivineMC
|
||||
+
|
||||
public class FriendlyByteBuf extends ByteBuf {
|
||||
|
||||
private static final int MAX_VARINT_SIZE = 5;
|
||||
@@ -104,7 +106,22 @@ public class FriendlyByteBuf extends ByteBuf {
|
||||
this.source = parent;
|
||||
}
|
||||
|
||||
+ // DivineMC start - Optimize varints
|
||||
+ private static final int[] VARINT_EXACT_BYTE_LENGTHS = new int[33];
|
||||
+ static {
|
||||
+ for (int i = 0; i <= 32; ++i) {
|
||||
+ VARINT_EXACT_BYTE_LENGTHS[i] = (int) Math.ceil((31d - (i - 1)) / 7d);
|
||||
+ }
|
||||
+ VARINT_EXACT_BYTE_LENGTHS[32] = 1; // Special case for the number 0.
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
+
|
||||
public static int getVarIntSize(int value) {
|
||||
+ // DivineMC start - Optimize varints
|
||||
+ if (DivineConfig.doOptimizeVarints) {
|
||||
+ return VARINT_EXACT_BYTE_LENGTHS[Integer.numberOfLeadingZeros(value)];
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
for (int j = 1; j < 5; ++j) {
|
||||
if ((value & -1 << j * 7) == 0) {
|
||||
return j;
|
||||
@@ -615,6 +632,23 @@ public class FriendlyByteBuf extends ByteBuf {
|
||||
}
|
||||
|
||||
public FriendlyByteBuf writeVarInt(int value) {
|
||||
+ // DivineMC start - Optimize varints
|
||||
+ if (DivineConfig.doOptimizeVarints) {
|
||||
+ if ((value & (0xFFFFFFFF << 7)) == 0) {
|
||||
+ writeByte(value);
|
||||
+ } else if ((value & (0xFFFFFFFF << 14)) == 0) {
|
||||
+ int w = (value & 0x7F | 0x80) << 8 | (value >>> 7);
|
||||
+ writeShort(w);
|
||||
+ } else {
|
||||
+ while ((value & -128) != 0) {
|
||||
+ this.writeByte(value & 127 | 128);
|
||||
+ value >>>= 7;
|
||||
+ }
|
||||
+ this.writeByte(value);
|
||||
+ }
|
||||
+ return this;
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
while ((value & -128) != 0) {
|
||||
this.writeByte(value & 127 | 128);
|
||||
value >>>= 7;
|
||||
@@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Thu, 6 Jul 2023 17:03:31 +0300
|
||||
Subject: [PATCH] Bump Dependencies
|
||||
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index 4cdc840231642ad03fb0db1bfa1282315a02b2de..791b19148c2edae5d900d817ee164aa94a971908 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -47,7 +47,7 @@ dependencies {
|
||||
runtimeOnly("com.mysql:mysql-connector-j:8.0.33")
|
||||
runtimeOnly("com.lmax:disruptor:3.4.4") // Paper
|
||||
// Paper start - Use Velocity cipher
|
||||
- implementation("com.velocitypowered:velocity-native:3.1.2-SNAPSHOT") {
|
||||
+ implementation("com.velocitypowered:velocity-native:3.2.0-SNAPSHOT") { // DivineMC - bump dependencies
|
||||
isTransitive = false
|
||||
}
|
||||
// Paper end
|
||||
@@ -67,9 +67,9 @@ dependencies {
|
||||
}
|
||||
// Pufferfish end
|
||||
|
||||
- testImplementation("io.github.classgraph:classgraph:4.8.47") // Paper - mob goal test
|
||||
+ testImplementation("io.github.classgraph:classgraph:4.8.151") // Paper - mob goal test // DivineMC - bump dependencies
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
- testImplementation("org.hamcrest:hamcrest-library:1.3")
|
||||
+ testImplementation("org.hamcrest:hamcrest-library:2.2") // DivineMC - bump dependencies
|
||||
|
||||
implementation("io.netty:netty-all:4.1.87.Final"); // Paper - Bump netty
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sat, 8 Apr 2023 01:40:11 +0300
|
||||
Subject: [PATCH] lithium: collections.attributes
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
index 210a0bee1227e4671909dd553ab22027cfc868fb..083621765f9936df869ec1f90133198cf882e7fa 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
@@ -1,8 +1,6 @@
|
||||
package net.minecraft.world.entity.ai.attributes;
|
||||
|
||||
-import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
-import com.google.common.collect.Sets;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
@@ -17,11 +15,15 @@ import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.slf4j.Logger;
|
||||
+import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
|
||||
+import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
|
||||
|
||||
public class AttributeMap {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
- private final Map<Attribute, AttributeInstance> attributes = Maps.newHashMap();
|
||||
- private final Set<AttributeInstance> dirtyAttributes = Sets.newHashSet();
|
||||
+ // DivineMC start - lithium: collections.attributes
|
||||
+ private final Map<Attribute, AttributeInstance> attributes = new Reference2ReferenceOpenHashMap<>(0);
|
||||
+ private final Set<AttributeInstance> dirtyAttributes = new ReferenceOpenHashSet<>(0);
|
||||
+ // DivineMC end
|
||||
private final AttributeSupplier supplier;
|
||||
private final java.util.function.Function<Attribute, AttributeInstance> createInstance; // Pufferfish
|
||||
private final net.minecraft.world.entity.LivingEntity entity; // Purpur
|
||||
@@ -1,29 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sat, 8 Apr 2023 01:22:35 +0300
|
||||
Subject: [PATCH] lithium: collections.goals
|
||||
|
||||
Original code by CaffeineMC, licensed under LGPL v3
|
||||
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
||||
index a2cca3d528625d49411a94e2b6ec578fec9b10da..e5c8b62cd431a86d9f1e5e4f1e48adfef81518c8 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
||||
@@ -14,6 +14,7 @@ import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import org.slf4j.Logger;
|
||||
+import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
|
||||
|
||||
public class GoalSelector {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
@@ -29,7 +30,7 @@ public class GoalSelector {
|
||||
}
|
||||
};
|
||||
private final Map<Goal.Flag, WrappedGoal> lockedFlags = new EnumMap<>(Goal.Flag.class);
|
||||
- private final Set<WrappedGoal> availableGoals = Sets.newLinkedHashSet();
|
||||
+ private final Set<WrappedGoal> availableGoals = new ObjectLinkedOpenHashSet<>(); // DivineMC - lithium: collections.goals
|
||||
private final Supplier<ProfilerFiller> profiler;
|
||||
private final EnumSet<Goal.Flag> disabledFlags = EnumSet.noneOf(Goal.Flag.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be.
|
||||
private final com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<net.minecraft.world.entity.ai.goal.Goal.Flag> goalTypes = new com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector
|
||||
@@ -1,28 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sat, 13 Jan 2024 20:04:54 +0300
|
||||
Subject: [PATCH] lithium: collections.attributes
|
||||
|
||||
Original code by CaffeineMC, licensed under LGPL v3
|
||||
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
index 74d4f017484f13754a1f266625331a4124976afe..ce48d8a8382b78262d20151ba721ca1c99a9e189 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
@@ -17,11 +17,13 @@ import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.slf4j.Logger;
|
||||
+import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; // DivineMC
|
||||
+import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; // DivineMC
|
||||
|
||||
public class AttributeMap {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
- private final Map<Attribute, AttributeInstance> attributes = Maps.newHashMap();
|
||||
- private final Set<AttributeInstance> dirtyAttributes = Sets.newHashSet();
|
||||
+ private final Map<Attribute, AttributeInstance> attributes = new Reference2ReferenceOpenHashMap<>(0); // DivineMC
|
||||
+ private final Set<AttributeInstance> dirtyAttributes = new ReferenceOpenHashSet<>(0); // DivineMC
|
||||
private final AttributeSupplier supplier;
|
||||
private final java.util.function.Function<Attribute, AttributeInstance> createInstance; // Pufferfish
|
||||
private final net.minecraft.world.entity.LivingEntity entity; // Purpur
|
||||
@@ -1,38 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sat, 8 Apr 2023 23:55:01 +0300
|
||||
Subject: [PATCH] lithium: gen.cached_generator_settings
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
||||
index 0d8fd4eaf912eb4d40bb9f600dd2a8d5c21ab572..cf4db1a610a2bfb8f6ce4ed0d502d180b5b67f3b 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
||||
@@ -62,12 +62,17 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
|
||||
private static final BlockState AIR = Blocks.AIR.defaultBlockState();
|
||||
public final Holder<NoiseGeneratorSettings> settings;
|
||||
private final Supplier<Aquifer.FluidPicker> globalFluidPicker;
|
||||
+ private int cachedSeaLevel; // DivineMC - lithium: gen.cached_generator_settings
|
||||
|
||||
public NoiseBasedChunkGenerator(BiomeSource biomeSource, Holder<NoiseGeneratorSettings> settings) {
|
||||
super(biomeSource);
|
||||
this.settings = settings;
|
||||
this.globalFluidPicker = Suppliers.memoize(() -> {
|
||||
- return NoiseBasedChunkGenerator.createFluidPicker((NoiseGeneratorSettings) settings.value());
|
||||
+ // DivineMC start - lithium: gen.cached_generator_settings
|
||||
+ var fluidPicker = NoiseBasedChunkGenerator.createFluidPicker((NoiseGeneratorSettings) settings.value());
|
||||
+ this.cachedSeaLevel = settings.value().seaLevel();
|
||||
+ return fluidPicker;
|
||||
+ // DivineMC end
|
||||
});
|
||||
}
|
||||
|
||||
@@ -397,7 +402,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
|
||||
|
||||
@Override
|
||||
public int getSeaLevel() {
|
||||
- return ((NoiseGeneratorSettings) this.settings.value()).seaLevel();
|
||||
+ return this.cachedSeaLevel; // DivineMC - lithium: gen.cached_generator_settings
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,115 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Wed, 12 Apr 2023 00:45:28 +0300
|
||||
Subject: [PATCH] Replace shape full block cache with hashtable
|
||||
|
||||
This patch is based on the following mixins and classes:
|
||||
* "me/jellysquid/mods/lithium/common/util/collections/Object2BooleanCacheTable.java"
|
||||
* "me/jellysquid/mods/lithium/mixin/shapes/blockstate_cache/BlockMixin.java"
|
||||
|
||||
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/collections/Object2BooleanCacheTable.java b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/Object2BooleanCacheTable.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0a6ab285cb870cfff7cc6a3115353457903965cd
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/Object2BooleanCacheTable.java
|
||||
@@ -0,0 +1,60 @@
|
||||
+package me.jellysquid.mods.lithium.common.util.collections;
|
||||
+
|
||||
+import it.unimi.dsi.fastutil.HashCommon;
|
||||
+import net.minecraft.util.Mth;
|
||||
+
|
||||
+import java.util.function.Predicate;
|
||||
+
|
||||
+/**
|
||||
+ * A lossy hashtable implementation that stores a mapping between an object and a boolean.
|
||||
+ * <p>
|
||||
+ * Any hash collisions will result in an overwrite: this is safe because the correct value can always be recomputed,
|
||||
+ * given that the given operator is deterministic.
|
||||
+ * <p>
|
||||
+ * This implementation is safe to use from multiple threads
|
||||
+ */
|
||||
+public final class Object2BooleanCacheTable<T> {
|
||||
+
|
||||
+ private final int mask;
|
||||
+ private final Node<T>[] nodes;
|
||||
+ private final Predicate<T> operator;
|
||||
+
|
||||
+ @SuppressWarnings("unchecked")
|
||||
+ public Object2BooleanCacheTable(int capacity, Predicate<T> operator) {
|
||||
+ int capacity1 = Mth.smallestEncompassingPowerOfTwo(capacity);
|
||||
+ this.mask = capacity1 - 1;
|
||||
+ this.nodes = (Node<T>[]) new Node[capacity1];
|
||||
+ this.operator = operator;
|
||||
+ }
|
||||
+
|
||||
+ private static <T> int hash(T key) {
|
||||
+ return HashCommon.mix(key.hashCode());
|
||||
+ }
|
||||
+
|
||||
+ public boolean get(T key) {
|
||||
+ int idx = hash(key) & this.mask;
|
||||
+
|
||||
+ Node<T> node = this.nodes[idx];
|
||||
+ if (node != null && key.equals(node.key)) {
|
||||
+ return node.value;
|
||||
+ }
|
||||
+
|
||||
+ boolean test = this.operator.test(key);
|
||||
+ this.nodes[idx] = new Node<>(key, test);
|
||||
+
|
||||
+ return test;
|
||||
+ }
|
||||
+
|
||||
+ static class Node<T> {
|
||||
+
|
||||
+ final T key;
|
||||
+ final boolean value;
|
||||
+
|
||||
+ Node(T key, boolean value) {
|
||||
+ this.key = key;
|
||||
+ this.value = value;
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
index cc4a2bafc319fb54e8d1168cba85746c5dfafbc2..39121b8450c645f3ec003751f0716a9b102a7e5b 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
@@ -62,6 +62,7 @@ import net.minecraft.world.phys.shapes.BooleanOp;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import org.slf4j.Logger;
|
||||
+import me.jellysquid.mods.lithium.common.util.collections.Object2BooleanCacheTable;
|
||||
|
||||
// Purpur start
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -75,11 +76,12 @@ public class Block extends BlockBehaviour implements ItemLike {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final Holder.Reference<Block> builtInRegistryHolder;
|
||||
public static final IdMapper<BlockState> BLOCK_STATE_REGISTRY = new IdMapper<>();
|
||||
- private static final LoadingCache<VoxelShape, Boolean> SHAPE_FULL_BLOCK_CACHE = CacheBuilder.newBuilder().maximumSize(512L).weakKeys().build(new CacheLoader<VoxelShape, Boolean>() {
|
||||
- public Boolean load(VoxelShape voxelshape) {
|
||||
- return !Shapes.joinIsNotEmpty(Shapes.block(), voxelshape, BooleanOp.NOT_SAME);
|
||||
- }
|
||||
- });
|
||||
+ // DivineMC start - Replace shape full block cache with hashtable
|
||||
+ private static final Object2BooleanCacheTable<VoxelShape> SHAPE_FULL_BLOCK_CACHE = new Object2BooleanCacheTable<>(
|
||||
+ 1536,
|
||||
+ shape -> !Shapes.joinIsNotEmpty(Shapes.block(), shape, BooleanOp.NOT_SAME)
|
||||
+ );
|
||||
+ // DivineMC end
|
||||
public static final int UPDATE_NEIGHBORS = 1;
|
||||
public static final int UPDATE_CLIENTS = 2;
|
||||
public static final int UPDATE_INVISIBLE = 4;
|
||||
@@ -290,7 +292,7 @@ public class Block extends BlockBehaviour implements ItemLike {
|
||||
}
|
||||
|
||||
public static boolean isShapeFullBlock(VoxelShape shape) {
|
||||
- return (Boolean) Block.SHAPE_FULL_BLOCK_CACHE.getUnchecked(shape);
|
||||
+ return Block.SHAPE_FULL_BLOCK_CACHE.get(shape); // DivineMC end - Replace shape full block cache with hashtable
|
||||
}
|
||||
|
||||
public boolean propagatesSkylightDown(BlockState state, BlockGetter world, BlockPos pos) {
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sat, 13 Jan 2024 14:57:08 +0300
|
||||
Subject: [PATCH] Add Higher Java Version for Pufferfish
|
||||
|
||||
|
||||
diff --git a/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java
|
||||
index 3441cdad70da1bd523c5933b1a914688718c2657..f0c33c55bcbbd93c658179b1b573354fc9480b79 100644
|
||||
--- a/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java
|
||||
+++ b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java
|
||||
@@ -15,7 +15,7 @@ public class SIMDChecker {
|
||||
@Deprecated
|
||||
public static boolean canEnable(Logger logger) {
|
||||
try {
|
||||
- if (SIMDDetection.getJavaVersion() < 17 || SIMDDetection.getJavaVersion() > 21) {
|
||||
+ if (SIMDDetection.getJavaVersion() < 17) { // DivineMC - Add Higher Java Version for Pufferfish
|
||||
return false;
|
||||
} else {
|
||||
SIMDDetection.testRun = true;
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Fri, 31 Mar 2023 00:39:40 +0300
|
||||
Subject: [PATCH] Fix MC-98160 and MC-105103
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
|
||||
index c45bb20e5355b0e0f87447572b6f60e8e2ee47be..294b337ebbefa964975988be3a5476b21adced9e 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
|
||||
@@ -913,7 +913,7 @@ public class Boat extends VehicleEntity implements Leashable, VariantHolder<Boat
|
||||
if (!this.isPassenger()) {
|
||||
if (onGround) {
|
||||
if (this.fallDistance > 3.0F) {
|
||||
- if (this.status != Boat.Status.ON_LAND) {
|
||||
+ if (this.status != Boat.Status.ON_LAND && this.status != Status.IN_AIR) { // DivineMC - Fix MC-98160 and MC-105103
|
||||
this.resetFallDistance();
|
||||
return;
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sun, 11 Jun 2023 23:59:29 +0300
|
||||
Subject: [PATCH] Fix MC-2025
|
||||
|
||||
Original post on Mojira: https://bugs.mojang.com/browse/MC-2025
|
||||
Fix taken from Reddit: https://redd.it/8pgd4q
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index da7ffdf85907c92fe6c4c6a5ebe571ef4666fcb8..7fba17c4802159c50a57f23820a153dcd85a2470 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -2745,6 +2745,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
nbttagcompound.putBoolean("Purpur.FireImmune", immuneToFire);
|
||||
}
|
||||
// Purpur end
|
||||
+
|
||||
+ // DivineMC start - Fix MC-2025
|
||||
+ // This fix was taken from Reddit: https://redd.it/8pgd4q
|
||||
+ AABB boundingBox = getBoundingBox();
|
||||
+ ListTag boundingBoxList = new ListTag();
|
||||
+ for (double coord : new double[]{boundingBox.minX, boundingBox.minY, boundingBox.minZ, boundingBox.maxX, boundingBox.maxY, boundingBox.maxZ}) {
|
||||
+ boundingBoxList.add(DoubleTag.valueOf(coord));
|
||||
+ }
|
||||
+ nbttagcompound.put("DivineMC.BoundingBox", boundingBoxList);
|
||||
+ // DivineMC end
|
||||
+
|
||||
return nbttagcompound;
|
||||
} catch (Throwable throwable) {
|
||||
CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT");
|
||||
@@ -2825,6 +2836,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
this.reapplyPosition();
|
||||
}
|
||||
|
||||
+ // DivineMC start - Fix MC-2025
|
||||
+ // This fix was taken from Reddit: https://redd.it/8pgd4q
|
||||
+ if (nbt.contains("DivineMC.BoundingBox", net.minecraft.nbt.Tag.TAG_LIST)) {
|
||||
+ ListTag boundingBoxList = nbt.getList("DivineMC.BoundingBox", net.minecraft.nbt.Tag.TAG_DOUBLE);
|
||||
+ setBoundingBox(new AABB(boundingBoxList.getDouble(0), boundingBoxList.getDouble(1), boundingBoxList.getDouble(2), boundingBoxList.getDouble(3), boundingBoxList.getDouble(4), boundingBoxList.getDouble(5)));
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
+
|
||||
} else {
|
||||
throw new IllegalStateException("Entity has invalid rotation");
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sun, 16 Jul 2023 13:51:26 +0300
|
||||
Subject: [PATCH] Fix MC-93018
|
||||
|
||||
Original post on Mojira: https://bugs.mojang.com/browse/MC-93018
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Wolf.java b/src/main/java/net/minecraft/world/entity/animal/Wolf.java
|
||||
index 30b4c09c6046c1d0843ccb8e4ff326e189b6cb95..bf3cd5381250cd77da6969214077ceae537a1d95 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Wolf.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Wolf.java
|
||||
@@ -762,14 +762,17 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder<Hol
|
||||
public boolean canMate(Animal other) {
|
||||
if (other == this) {
|
||||
return false;
|
||||
- } else if (!this.isTame()) {
|
||||
- return false;
|
||||
} else if (!(other instanceof Wolf)) {
|
||||
return false;
|
||||
} else {
|
||||
- Wolf entitywolf = (Wolf) other;
|
||||
-
|
||||
- return !entitywolf.isTame() ? false : (entitywolf.isInSittingPose() ? false : this.isInLove() && entitywolf.isInLove());
|
||||
+ // DivineMC start - Fix MC-93018
|
||||
+ Wolf wolf = (Wolf) other;
|
||||
+ if (wolf.isInSittingPose()) {
|
||||
+ return false;
|
||||
+ } else {
|
||||
+ return this.isInLove() && wolf.isInLove();
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Wed, 17 Apr 2024 02:08:02 +0300
|
||||
Subject: [PATCH] lithium: precompute shape arrays
|
||||
|
||||
Original code by CaffeineMC, licensed under LGPL v3
|
||||
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/Direction.java b/src/main/java/net/minecraft/core/Direction.java
|
||||
index 03c45ee77276462818a6f774b5945b25924aa3f0..7c56228639027d0bfcf8901a5f3c996c6b1faa8c 100644
|
||||
--- a/src/main/java/net/minecraft/core/Direction.java
|
||||
+++ b/src/main/java/net/minecraft/core/Direction.java
|
||||
@@ -46,7 +46,7 @@ public enum Direction implements StringRepresentable {
|
||||
private final Direction.Axis axis;
|
||||
private final Direction.AxisDirection axisDirection;
|
||||
private final Vec3i normal;
|
||||
- private static final Direction[] VALUES = values();
|
||||
+ public static final Direction[] VALUES = values(); // DivineMC - lithium: precompute shape arrays
|
||||
private static final Direction[] BY_3D_DATA = Arrays.stream(VALUES)
|
||||
.sorted(Comparator.comparingInt(direction -> direction.data3d))
|
||||
.toArray(Direction[]::new);
|
||||
diff --git a/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java b/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java
|
||||
index ad02cdb00360165f6405eb3044bd8320f01a7ef1..61f6f612470076c7b6930dcb63911a2ac6d45be1 100644
|
||||
--- a/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java
|
||||
+++ b/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java
|
||||
@@ -4,6 +4,7 @@ import it.unimi.dsi.fastutil.doubles.AbstractDoubleList;
|
||||
|
||||
public class CubePointRange extends AbstractDoubleList {
|
||||
private final int parts;
|
||||
+ private double scale; // DivineMC - lithium: precompute shape arrays
|
||||
|
||||
public CubePointRange(int sectionCount) {
|
||||
if (sectionCount <= 0) {
|
||||
@@ -11,10 +12,11 @@ public class CubePointRange extends AbstractDoubleList {
|
||||
} else {
|
||||
this.parts = sectionCount;
|
||||
}
|
||||
+ this.scale = 1.0D / sectionCount; // DivineMC - lithium: precompute shape arrays
|
||||
}
|
||||
|
||||
public double getDouble(int i) {
|
||||
- return (double)i / (double)this.parts;
|
||||
+ return i * this.scale; // DivineMC - lithium: precompute shape arrays
|
||||
}
|
||||
|
||||
public int size() {
|
||||
diff --git a/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java
|
||||
index d812949c7329ae2696b38dc792fa011ba87decb9..98e218c65d489822f334c06fddd1ab608662597b 100644
|
||||
--- a/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java
|
||||
+++ b/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java
|
||||
@@ -5,13 +5,23 @@ import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.Mth;
|
||||
|
||||
public final class CubeVoxelShape extends VoxelShape {
|
||||
+ private DoubleList[] list; // DivineMC - lithium: precompute shape arrays
|
||||
+
|
||||
protected CubeVoxelShape(DiscreteVoxelShape voxels) {
|
||||
super(voxels);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DoubleList getCoords(Direction.Axis axis) {
|
||||
- return new CubePointRange(this.shape.getSize(axis));
|
||||
+ // DivineMC start - lithium: precompute shape arrays
|
||||
+ if (this.list == null) {
|
||||
+ this.list = new DoubleList[Direction.Axis.VALUES.length];
|
||||
+ for (Direction.Axis existingAxis : Direction.Axis.VALUES) {
|
||||
+ this.list[existingAxis.ordinal()] = new CubePointRange(this.shape.getSize(axis));
|
||||
+ }
|
||||
+ }
|
||||
+ return this.list[axis.ordinal()];
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,43 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sat, 25 May 2024 17:13:35 +0300
|
||||
Subject: [PATCH] lithium: cached_hashcode
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
index 4ff7e3693305069e7fad185802a3b0481ab70a4a..26dd81b4a6fb929f2b4304442f79e7f3f6c46aa3 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
@@ -633,11 +633,19 @@ public class Block extends BlockBehaviour implements ItemLike {
|
||||
private final BlockState first;
|
||||
private final BlockState second;
|
||||
private final Direction direction;
|
||||
+ private final int hash; // DivineMC - lithium: cached_hashcode
|
||||
|
||||
public BlockStatePairKey(BlockState self, BlockState other, Direction facing) {
|
||||
this.first = self;
|
||||
this.second = other;
|
||||
this.direction = facing;
|
||||
+
|
||||
+ // DivineMC start - lithium: cached_hashcode
|
||||
+ int i = this.first.hashCode();
|
||||
+ i = 31 * i + this.second.hashCode();
|
||||
+ i = 31 * i + this.direction.hashCode();
|
||||
+ this.hash = i;
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
public boolean equals(Object object) {
|
||||
@@ -653,11 +661,7 @@ public class Block extends BlockBehaviour implements ItemLike {
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
- int i = this.first.hashCode();
|
||||
-
|
||||
- i = 31 * i + this.second.hashCode();
|
||||
- i = 31 * i + this.direction.hashCode();
|
||||
- return i;
|
||||
+ return this.hash; // DivineMC - lithium: cached_hashcode
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sat, 13 Jan 2024 20:59:28 +0300
|
||||
Subject: [PATCH] Carpet-Fixes: Sheep Optimization
|
||||
|
||||
Original project: https://github.com/fxmorin/carpet-fixes
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Sheep.java b/src/main/java/net/minecraft/world/entity/animal/Sheep.java
|
||||
index a13ce089bacfb6644eea81fbe7c6d640aedaea96..9cde7eafbf6d8dbb13087379e567bc0dfd24f4a6 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Sheep.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Sheep.java
|
||||
@@ -60,6 +60,7 @@ import net.minecraft.world.item.DyeItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
import org.bukkit.event.entity.SheepRegrowWoolEvent;
|
||||
+import space.bxteam.divinemc.util.carpetfixes.ProperDyeMixin; // DivineMC
|
||||
// CraftBukkit end
|
||||
|
||||
public class Sheep extends Animal implements Shearable {
|
||||
@@ -376,21 +377,30 @@ public class Sheep extends Animal implements Shearable {
|
||||
return super.finalizeSpawn(world, difficulty, spawnReason, entityData);
|
||||
}
|
||||
|
||||
+ // DivineMC start - Carpet-Fixes: Sheep Optimization
|
||||
private DyeColor getOffspringColor(ServerLevel world, Sheep firstParent, Sheep secondParent) {
|
||||
- DyeColor enumcolor = firstParent.getColor();
|
||||
- DyeColor enumcolor1 = secondParent.getColor();
|
||||
- CraftingInput craftinginput = Sheep.makeCraftInput(enumcolor, enumcolor1);
|
||||
- Optional<Item> optional = world.recipeAccess().getRecipeFor(RecipeType.CRAFTING, craftinginput, world).map((recipeholder) -> { // CraftBukkit - decompile error
|
||||
- return ((CraftingRecipe) recipeholder.value()).assemble(craftinginput, world.registryAccess());
|
||||
- }).map(ItemStack::getItem);
|
||||
-
|
||||
- Objects.requireNonNull(DyeItem.class);
|
||||
- optional = optional.filter(DyeItem.class::isInstance);
|
||||
- Objects.requireNonNull(DyeItem.class);
|
||||
- return (DyeColor) optional.map(DyeItem.class::cast).map(DyeItem::getDyeColor).orElseGet(() -> {
|
||||
- return world.random.nextBoolean() ? enumcolor : enumcolor1;
|
||||
- });
|
||||
+ DyeColor firstColor = firstParent.getColor();
|
||||
+ DyeColor secondColor = secondParent.getColor();
|
||||
+
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.sheepOptimization) {
|
||||
+ DyeColor col = ProperDyeMixin.properDye(firstColor, secondColor);
|
||||
+ if (col == null) col = world.random.nextBoolean() ? firstColor : secondColor;
|
||||
+ return col;
|
||||
+ } else {
|
||||
+ CraftingInput craftinginput = Sheep.makeCraftInput(firstColor, secondColor);
|
||||
+ Optional<Item> optional = world.recipeAccess().getRecipeFor(RecipeType.CRAFTING, craftinginput, world).map((recipeholder) -> { // CraftBukkit - decompile error
|
||||
+ return ((CraftingRecipe) recipeholder.value()).assemble(craftinginput, world.registryAccess());
|
||||
+ }).map(ItemStack::getItem);
|
||||
+
|
||||
+ Objects.requireNonNull(DyeItem.class);
|
||||
+ optional = optional.filter(DyeItem.class::isInstance);
|
||||
+ Objects.requireNonNull(DyeItem.class);
|
||||
+ return (DyeColor) optional.map(DyeItem.class::cast).map(DyeItem::getDyeColor).orElseGet(() -> {
|
||||
+ return world.random.nextBoolean() ? firstColor : secondColor;
|
||||
+ });
|
||||
+ }
|
||||
}
|
||||
+ // DivineMC end
|
||||
|
||||
private static CraftingInput makeCraftInput(DyeColor firstColor, DyeColor secondColor) {
|
||||
return CraftingInput.of(2, 1, List.of(new ItemStack(DyeItem.byColor(firstColor)), new ItemStack(DyeItem.byColor(secondColor))));
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
index aaf3afd0fe1f13ed7375d272e2690e9db0410417..bc6642e1a6dd8254efe65cbac1acdcd4462e430b 100644
|
||||
--- a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
+++ b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
@@ -163,9 +163,11 @@ public class DivineConfig {
|
||||
public static boolean biomeManagerOptimization = true;
|
||||
public static boolean optimizedDragonRespawn = true;
|
||||
public static boolean optimizeNoiseGeneration = true;
|
||||
+ public static boolean sheepOptimization = true;
|
||||
private static void optimizations() {
|
||||
biomeManagerOptimization = getBoolean("settings.optimizations.biome-manager-optimization", biomeManagerOptimization);
|
||||
optimizedDragonRespawn = getBoolean("settings.optimizations.optimized-dragon-respawn", optimizedDragonRespawn);
|
||||
optimizeNoiseGeneration = getBoolean("settings.optimizations.optimize-noise-generation", optimizeNoiseGeneration);
|
||||
+ sheepOptimization = getBoolean("settings.optimizations.sheep-optimization", sheepOptimization);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/util/carpetfixes/ProperDyeMixin.java b/src/main/java/space/bxteam/divinemc/util/carpetfixes/ProperDyeMixin.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..6cbcf1580312a9275e41813a26b36e42a2481a2c
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/space/bxteam/divinemc/util/carpetfixes/ProperDyeMixin.java
|
||||
@@ -0,0 +1,46 @@
|
||||
+package space.bxteam.divinemc.util.carpetfixes;
|
||||
+
|
||||
+import net.minecraft.world.item.DyeColor;
|
||||
+
|
||||
+public class ProperDyeMixin {
|
||||
+ public static DyeColor properDye(DyeColor firstColor, DyeColor secondColor) {
|
||||
+ if (firstColor.equals(secondColor)) return firstColor;
|
||||
+ switch (firstColor) {
|
||||
+ case WHITE -> {
|
||||
+ switch (secondColor) {
|
||||
+ case BLUE -> {return DyeColor.LIGHT_BLUE;}
|
||||
+ case GRAY -> {return DyeColor.LIGHT_GRAY;}
|
||||
+ case BLACK -> {return DyeColor.GRAY;}
|
||||
+ case GREEN -> {return DyeColor.LIME;}
|
||||
+ case RED -> {return DyeColor.PINK;}
|
||||
+ }
|
||||
+ }
|
||||
+ case BLUE -> {
|
||||
+ switch (secondColor) {
|
||||
+ case WHITE -> {return DyeColor.LIGHT_BLUE;}
|
||||
+ case GREEN -> {return DyeColor.CYAN;}
|
||||
+ case RED -> {return DyeColor.PURPLE;}
|
||||
+ }
|
||||
+ }
|
||||
+ case RED -> {
|
||||
+ switch (secondColor) {
|
||||
+ case YELLOW -> {return DyeColor.ORANGE;}
|
||||
+ case WHITE -> {return DyeColor.PINK;}
|
||||
+ case BLUE -> {return DyeColor.PURPLE;}
|
||||
+ }
|
||||
+ }
|
||||
+ case GREEN -> {
|
||||
+ switch (secondColor) {
|
||||
+ case BLUE -> {return DyeColor.CYAN;}
|
||||
+ case WHITE -> {return DyeColor.LIME;}
|
||||
+ }
|
||||
+ }
|
||||
+ case YELLOW -> {if (secondColor.equals(DyeColor.RED)) return DyeColor.ORANGE;}
|
||||
+ case PURPLE -> {if (secondColor.equals(DyeColor.PINK)) return DyeColor.MAGENTA;}
|
||||
+ case PINK -> {if (secondColor.equals(DyeColor.PURPLE)) return DyeColor.MAGENTA;}
|
||||
+ case GRAY -> {if (secondColor.equals(DyeColor.WHITE)) return DyeColor.LIGHT_GRAY;}
|
||||
+ case BLACK -> {if (secondColor.equals(DyeColor.WHITE)) return DyeColor.GRAY;}
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+}
|
||||
@@ -1,28 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sun, 14 Jan 2024 22:54:49 +0300
|
||||
Subject: [PATCH] Improve biome temperature cache
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/biome/Biome.java b/src/main/java/net/minecraft/world/level/biome/Biome.java
|
||||
index 15f82c9a1ce1fef2e951d1b3c7a65e64b82061ea..b80135286ca41398cae9f0c96566cc7c126de453 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/biome/Biome.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/biome/Biome.java
|
||||
@@ -63,7 +63,7 @@ public final class Biome {
|
||||
private final BiomeGenerationSettings generationSettings;
|
||||
private final MobSpawnSettings mobSettings;
|
||||
private final BiomeSpecialEffects specialEffects;
|
||||
- private final ThreadLocal<Long2FloatLinkedOpenHashMap> temperatureCache = ThreadLocal.withInitial(() -> Util.make(() -> {
|
||||
+ private static final ThreadLocal<Long2FloatLinkedOpenHashMap> temperatureCache = ThreadLocal.withInitial(() -> Util.make(() -> { // DivineMC
|
||||
Long2FloatLinkedOpenHashMap long2FloatLinkedOpenHashMap = new Long2FloatLinkedOpenHashMap(1024, 0.25F) {
|
||||
protected void rehash(int i) {
|
||||
}
|
||||
@@ -112,7 +112,7 @@ public final class Biome {
|
||||
@Deprecated
|
||||
public float getTemperature(BlockPos blockPos) {
|
||||
long l = blockPos.asLong();
|
||||
- Long2FloatLinkedOpenHashMap long2FloatLinkedOpenHashMap = this.temperatureCache.get();
|
||||
+ Long2FloatLinkedOpenHashMap long2FloatLinkedOpenHashMap = temperatureCache.get(); // DivineMC
|
||||
float f = long2FloatLinkedOpenHashMap.get(l);
|
||||
if (!Float.isNaN(f)) {
|
||||
return f;
|
||||
@@ -1,28 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Tue, 16 Apr 2024 01:20:51 +0300
|
||||
Subject: [PATCH] Add Higher Java Version for Pufferfish SIMD
|
||||
|
||||
|
||||
diff --git a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java
|
||||
index 8afc58f35deb49084a20b803e91ce4692ce6e4d6..581eb4ca8d7a09729ad9194d35f3cceeb291ecf7 100644
|
||||
--- a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java
|
||||
+++ b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java
|
||||
@@ -87,7 +87,7 @@ public class PufferfishConfig {
|
||||
// Attempt to detect vectorization
|
||||
try {
|
||||
SIMDDetection.isEnabled = SIMDDetection.canEnable(PufferfishLogger.LOGGER);
|
||||
- SIMDDetection.versionLimited = SIMDDetection.getJavaVersion() < 17 || SIMDDetection.getJavaVersion() > 21;
|
||||
+ SIMDDetection.versionLimited = SIMDDetection.getJavaVersion() < 17; // DivineMC - Add Higher Java Version for Pufferfish SIMD
|
||||
} catch (NoClassDefFoundError | Exception ignored) {
|
||||
ignored.printStackTrace();
|
||||
}
|
||||
@@ -95,7 +95,7 @@ public class PufferfishConfig {
|
||||
if (SIMDDetection.isEnabled) {
|
||||
PufferfishLogger.LOGGER.info("SIMD operations detected as functional. Will replace some operations with faster versions.");
|
||||
} else if (SIMDDetection.versionLimited) {
|
||||
- PufferfishLogger.LOGGER.warning("Will not enable SIMD! These optimizations are only safely supported on Java 17 through Java 21.");
|
||||
+ PufferfishLogger.LOGGER.warning("Will not enable SIMD! These optimizations are only safely supported on Java 17 and higher.");
|
||||
} else {
|
||||
PufferfishLogger.LOGGER.warning("SIMD operations are available for your server, but are not configured!");
|
||||
PufferfishLogger.LOGGER.warning("To enable additional optimizations, add \"--add-modules=jdk.incubator.vector\" to your startup flags, BEFORE the \"-jar\".");
|
||||
@@ -1,22 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: WMGameLive <andu890201@gmail.com>
|
||||
Date: Sun, 21 Jul 2024 19:36:01 +0800
|
||||
Subject: [PATCH] Fix MC-167242
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
index d58f845dc814011b8126cc641476b6e4e25bc328..45f3b7fa89d8004608efa402e64619bf40464d2e 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
@@ -999,6 +999,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
world.addFreshEntityWithPassengers(entitywitch, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING);
|
||||
// CraftBukkit end
|
||||
this.releaseAllPois();
|
||||
+
|
||||
+ if(this.isSleeping()) {
|
||||
+ this.stopSleeping();
|
||||
+ }
|
||||
+
|
||||
this.discard(EntityRemoveEvent.Cause.TRANSFORMATION); // CraftBukkit - add Bukkit remove cause
|
||||
} else {
|
||||
super.thunderHit(world, lightning);
|
||||
@@ -1,76 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sat, 10 Jun 2023 13:01:08 +0300
|
||||
Subject: [PATCH] Boat Settings
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java
|
||||
index 1a4fb057025689a22b3dd05f531f0d8639d7e47b..c1bdc94a7c0084341fe857a0caff0764fc9e8b1e 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java
|
||||
@@ -296,7 +296,18 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable {
|
||||
}
|
||||
|
||||
if (!this.level().isClientSide && this.outOfControlTicks >= 60.0F) {
|
||||
- this.ejectPassengers();
|
||||
+ // DivineMC start - Don't eject players
|
||||
+ if (this.level().divinemcConfig.dontEjectPlayerFromBoatUnderwater) {
|
||||
+ for (int i = this.passengers.size() - 1; i >= 0; --i) {
|
||||
+ Entity passenger = this.passengers.get(i);
|
||||
+ if (!(passenger instanceof Player)) {
|
||||
+ passenger.stopRiding();
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ this.ejectPassengers();
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
if (this.getHurtTime() > 0) {
|
||||
@@ -839,7 +850,13 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable {
|
||||
public InteractionResult interact(Player player, InteractionHand hand) {
|
||||
InteractionResult enuminteractionresult = super.interact(player, hand);
|
||||
|
||||
- return (InteractionResult) (enuminteractionresult != InteractionResult.PASS ? enuminteractionresult : (!player.isSecondaryUseActive() && this.outOfControlTicks < 60.0F && (this.level().isClientSide || player.startRiding(this)) ? InteractionResult.SUCCESS : InteractionResult.PASS));
|
||||
+ // DivineMC start - always allow to enter the boat
|
||||
+ if (this.level().divinemcConfig.alwaysAllowToEnterTheBoat) {
|
||||
+ return enuminteractionresult != InteractionResult.PASS ? enuminteractionresult : (player.isSecondaryUseActive() ? InteractionResult.PASS : (!this.level().isClientSide ? (player.startRiding(this) ? InteractionResult.CONSUME : InteractionResult.PASS) : InteractionResult.SUCCESS));
|
||||
+ } else {
|
||||
+ return enuminteractionresult != InteractionResult.PASS ? enuminteractionresult : (!player.isSecondaryUseActive() && this.outOfControlTicks < 60.0F && (this.level().isClientSide || player.startRiding(this)) ? InteractionResult.SUCCESS : InteractionResult.PASS);
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -889,7 +906,13 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable {
|
||||
|
||||
@Override
|
||||
protected boolean canAddPassenger(Entity passenger) {
|
||||
- return this.getPassengers().size() < this.getMaxPassengers() && !this.isEyeInFluid(FluidTags.WATER);
|
||||
+ // DivineMC start - always allow to enter the boat
|
||||
+ if (this.level().divinemcConfig.alwaysAllowToEnterTheBoat) {
|
||||
+ return this.getPassengers().size() < this.getMaxPassengers()/* && !this.isEyeInFluid(FluidTags.WATER)*/;
|
||||
+ } else {
|
||||
+ return this.getPassengers().size() < this.getMaxPassengers() && !this.isEyeInFluid(FluidTags.WATER);
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
protected int getMaxPassengers() {
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfig.java
|
||||
index 243b3d4379f4f6f273222a3611d8a463053d3e70..e1274fe3b0ff369d1f6f229026ced2e03ea335ca 100644
|
||||
--- a/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfig.java
|
||||
+++ b/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfig.java
|
||||
@@ -82,4 +82,11 @@ public class DivineWorldConfig {
|
||||
private void saveFireworks() {
|
||||
saveFireworks = getBoolean("gameplay-mechanics.should-save-fireworks", saveFireworks);
|
||||
}
|
||||
+
|
||||
+ public boolean dontEjectPlayerFromBoatUnderwater = true;
|
||||
+ public boolean alwaysAllowToEnterTheBoat = true;
|
||||
+ private void boatFeatures() {
|
||||
+ dontEjectPlayerFromBoatUnderwater = getBoolean("gameplay-mechanics.boat.dont-eject-players-from-boat-underwater", dontEjectPlayerFromBoatUnderwater);
|
||||
+ alwaysAllowToEnterTheBoat = getBoolean("gameplay-mechanics.boat.always-allow-to-enter-the-boat", alwaysAllowToEnterTheBoat);
|
||||
+ }
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sat, 10 Jun 2023 19:43:52 +0300
|
||||
Subject: [PATCH] Reduce sensor work
|
||||
|
||||
Original project: Bloom-host/Petal
|
||||
Link: https://github.com/Bloom-host/Petal
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 8096e094381062f26172eb1758ee18fda61ca961..7d2b571adf0e010ee5af7917cc06ee7702884aaa 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1079,20 +1079,19 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
|
||||
if (entity != null) {
|
||||
- ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD);
|
||||
EntityType<?> entitytypes = entity.getType();
|
||||
|
||||
// Purpur start
|
||||
- if (entitytypes == EntityType.SKELETON && itemstack.is(Items.SKELETON_SKULL)) {
|
||||
+ if (entitytypes == EntityType.SKELETON && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.SKELETON_SKULL)) { // DivineMC - Reduce sensor work
|
||||
d0 *= entity.level().purpurConfig.skeletonHeadVisibilityPercent;
|
||||
}
|
||||
- else if (entitytypes == EntityType.ZOMBIE && itemstack.is(Items.ZOMBIE_HEAD)) {
|
||||
+ else if (entitytypes == EntityType.ZOMBIE && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.ZOMBIE_HEAD)) { // DivineMC - Reduce sensor work
|
||||
d0 *= entity.level().purpurConfig.zombieHeadVisibilityPercent;
|
||||
}
|
||||
- else if (entitytypes == EntityType.CREEPER && itemstack.is(Items.CREEPER_HEAD)) {
|
||||
+ else if (entitytypes == EntityType.CREEPER && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.CREEPER_HEAD)) { // DivineMC - Reduce sensor work
|
||||
d0 *= entity.level().purpurConfig.creeperHeadVisibilityPercent;
|
||||
}
|
||||
- else if ((entitytypes == EntityType.PIGLIN || entitytypes == EntityType.PIGLIN_BRUTE) && itemstack.is(Items.PIGLIN_HEAD)) {
|
||||
+ else if ((entitytypes == EntityType.PIGLIN || entitytypes == EntityType.PIGLIN_BRUTE) && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.PIGLIN_HEAD)) { // DivineMC - Reduce sensor work
|
||||
d0 *= entity.level().purpurConfig.piglinHeadVisibilityPercent;
|
||||
}
|
||||
// Purpur end
|
||||
@@ -1,68 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Wed, 17 Apr 2024 02:02:02 +0300
|
||||
Subject: [PATCH] Snowball and Egg knockback
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java
|
||||
index 6fdacf2f6934521a0dd4b25aea35a6a14123da0a..477a6326f19a15c9ea7e0329515ec0007ac2cd20 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java
|
||||
@@ -3,6 +3,7 @@ package net.minecraft.world.entity.projectile;
|
||||
import net.minecraft.core.particles.ItemParticleOption;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
@@ -61,6 +62,13 @@ public class Snowball extends ThrowableItemProjectile {
|
||||
int i = entity.level().purpurConfig.snowballDamage >= 0 ? entity.level().purpurConfig.snowballDamage : entity instanceof Blaze ? 3 : 0; // Purpur
|
||||
|
||||
entity.hurt(this.damageSources().thrown(this, this.getOwner()), (float) i);
|
||||
+
|
||||
+ // DivineMC start - Snowball and Egg knockback
|
||||
+ if (this.level().divinemcConfig.snowballCanKnockback && entity instanceof ServerPlayer) {
|
||||
+ entity.hurt(this.damageSources().thrown(this, this.getOwner()), 0.0000001F);
|
||||
+ ((ServerPlayer) entity).knockback(0.4000000059604645D, this.getX() - entity.getX(), this.getZ() - entity.getZ(), this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE);
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
// Purpur start - borrowed and modified code from ThrownPotion#onHitBlock and ThrownPotion#dowseFire
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java
|
||||
index 155c2bbd35adacb7c3668fbe81a7c454e5102c8b..8c48ad7b52bc7914531abe0319b30aebac38c6e6 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java
|
||||
@@ -51,7 +51,15 @@ public class ThrownEgg extends ThrowableItemProjectile {
|
||||
@Override
|
||||
protected void onHitEntity(EntityHitResult entityHitResult) {
|
||||
super.onHitEntity(entityHitResult);
|
||||
+ Entity entity = entityHitResult.getEntity(); // DivineMC
|
||||
entityHitResult.getEntity().hurt(this.damageSources().thrown(this, this.getOwner()), 0.0F);
|
||||
+
|
||||
+ // DivineMC start - Snowball and Egg knockback
|
||||
+ if (this.level().divinemcConfig.eggCanKnockback && entity instanceof ServerPlayer) {
|
||||
+ entity.hurt(this.damageSources().thrown(this, this.getOwner()), 0.0000001F);
|
||||
+ ((ServerPlayer) entity).knockback(0.4000000059604645D, this.getX() - entity.getX(), this.getZ() - entity.getZ(), this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE);
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfig.java
|
||||
index 7e62ee9418d5add5b0b4ddb885d3a1745ce799b2..242da697c957508c8e75bfd232c44ea34ba3a62a 100644
|
||||
--- a/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfig.java
|
||||
+++ b/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfig.java
|
||||
@@ -94,4 +94,11 @@ public class DivineWorldConfig {
|
||||
private void despawnShulkerBulletsOnOwnerDeath() {
|
||||
despawnShulkerBulletsOnOwnerDeath = getBoolean("gameplay-mechanics.mob.shulker.despawn-bullets-on-player-death", despawnShulkerBulletsOnOwnerDeath);
|
||||
}
|
||||
+
|
||||
+ public boolean snowballCanKnockback = true;
|
||||
+ public boolean eggCanKnockback = true;
|
||||
+ private void setSnowballAndEggKnockback() {
|
||||
+ snowballCanKnockback = getBoolean("gameplay-mechanics.projectiles.snowball.knockback", snowballCanKnockback);
|
||||
+ eggCanKnockback = getBoolean("gameplay-mechanics.projectiles.egg.knockback", eggCanKnockback);
|
||||
+ }
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sat, 13 Jan 2024 19:19:16 +0300
|
||||
Subject: [PATCH] Carpet-Fixes: getBiome Optimize
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java
|
||||
index 90f8360f547ce709fd13ee34f8e67d8bfa94b498..e71cfe169d8113b1e38fb1f3f12dc9b5177c83de 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java
|
||||
@@ -14,6 +14,7 @@ public class BiomeManager {
|
||||
private static final int ZOOM_MASK = 3;
|
||||
private final BiomeManager.NoiseBiomeSource noiseBiomeSource;
|
||||
private final long biomeZoomSeed;
|
||||
+ private static final double maxOffset = 0.4500000001D; // DivineMC - Carpet-Fixes: getBiome Optimize
|
||||
|
||||
public BiomeManager(BiomeManager.NoiseBiomeSource storage, long seed) {
|
||||
this.noiseBiomeSource = storage;
|
||||
@@ -29,39 +30,103 @@ public class BiomeManager {
|
||||
}
|
||||
|
||||
public Holder<Biome> getBiome(BlockPos pos) {
|
||||
- int i = pos.getX() - 2;
|
||||
- int j = pos.getY() - 2;
|
||||
- int k = pos.getZ() - 2;
|
||||
- int l = i >> 2;
|
||||
- int m = j >> 2;
|
||||
- int n = k >> 2;
|
||||
- double d = (double)(i & 3) / 4.0;
|
||||
- double e = (double)(j & 3) / 4.0;
|
||||
- double f = (double)(k & 3) / 4.0;
|
||||
- int o = 0;
|
||||
- double g = Double.POSITIVE_INFINITY;
|
||||
-
|
||||
- for (int p = 0; p < 8; p++) {
|
||||
- boolean bl = (p & 4) == 0;
|
||||
- boolean bl2 = (p & 2) == 0;
|
||||
- boolean bl3 = (p & 1) == 0;
|
||||
- int q = bl ? l : l + 1;
|
||||
- int r = bl2 ? m : m + 1;
|
||||
- int s = bl3 ? n : n + 1;
|
||||
- double h = bl ? d : d - 1.0;
|
||||
- double t = bl2 ? e : e - 1.0;
|
||||
- double u = bl3 ? f : f - 1.0;
|
||||
- double v = getFiddledDistance(this.biomeZoomSeed, q, r, s, h, t, u);
|
||||
- if (g > v) {
|
||||
- o = p;
|
||||
- g = v;
|
||||
+ // DivineMC start - Carpet-Fixes: getBiome Optimize
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.biomeManagerOptimization) {
|
||||
+ int xMinus2 = pos.getX() - 2;
|
||||
+ int yMinus2 = pos.getY() - 2;
|
||||
+ int zMinus2 = pos.getZ() - 2;
|
||||
+ int x = xMinus2 >> 2; // BlockPos to BiomePos
|
||||
+ int y = yMinus2 >> 2;
|
||||
+ int z = zMinus2 >> 2;
|
||||
+ double quartX = (double) (xMinus2 & 3) / 4.0D; // quartLocal divided by 4
|
||||
+ double quartY = (double) (yMinus2 & 3) / 4.0D; // 0/4, 1/4, 2/4, 3/4
|
||||
+ double quartZ = (double) (zMinus2 & 3) / 4.0D; // [0, 0.25, 0.5, 0.75]
|
||||
+ int smallestX = 0;
|
||||
+ double smallestDist = Double.POSITIVE_INFINITY;
|
||||
+ for (int biomeX = 0; biomeX < 8; ++biomeX) {
|
||||
+ boolean everyOtherQuad = (biomeX & 4) == 0; // 1 1 1 1 0 0 0 0
|
||||
+ boolean everyOtherPair = (biomeX & 2) == 0; // 1 1 0 0 1 1 0 0
|
||||
+ boolean everyOther = (biomeX & 1) == 0; // 1 0 1 0 1 0 1 0
|
||||
+ double quartXX = everyOtherQuad ? quartX : quartX - 1.0D; //[-1.0,-0.75,-0.5,-0.25,0.0,0.25,0.5,0.75]
|
||||
+ double quartYY = everyOtherPair ? quartY : quartY - 1.0D;
|
||||
+ double quartZZ = everyOther ? quartZ : quartZ - 1.0D;
|
||||
+
|
||||
+ double maxQuartYY = 0.0D, maxQuartZZ = 0.0D;
|
||||
+ if (biomeX != 0) {
|
||||
+ maxQuartYY = Mth.square(Math.max(quartYY + maxOffset, Math.abs(quartYY - maxOffset)));
|
||||
+ maxQuartZZ = Mth.square(Math.max(quartZZ + maxOffset, Math.abs(quartZZ - maxOffset)));
|
||||
+ double maxQuartXX = Mth.square(Math.max(quartXX + maxOffset, Math.abs(quartXX - maxOffset)));
|
||||
+ if (smallestDist < maxQuartXX + maxQuartYY + maxQuartZZ) continue;
|
||||
+ }
|
||||
+
|
||||
+ int xx = everyOtherQuad ? x : x + 1;
|
||||
+ int yy = everyOtherPair ? y : y + 1;
|
||||
+ int zz = everyOther ? z : z + 1;
|
||||
+
|
||||
+ //I transferred the code from method_38106 to here, so I could call continue halfway through
|
||||
+ long seed = LinearCongruentialGenerator.next(this.biomeZoomSeed, xx);
|
||||
+ seed = LinearCongruentialGenerator.next(seed, yy);
|
||||
+ seed = LinearCongruentialGenerator.next(seed, zz);
|
||||
+ seed = LinearCongruentialGenerator.next(seed, xx);
|
||||
+ seed = LinearCongruentialGenerator.next(seed, yy);
|
||||
+ seed = LinearCongruentialGenerator.next(seed, zz);
|
||||
+ double offsetX = getFiddle(seed);
|
||||
+ double sqrX = Mth.square(quartXX + offsetX);
|
||||
+ if (biomeX != 0 && smallestDist < sqrX + maxQuartYY + maxQuartZZ) continue; //skip the rest of the loop
|
||||
+ seed = LinearCongruentialGenerator.next(seed, this.biomeZoomSeed);
|
||||
+ double offsetY = getFiddle(seed);
|
||||
+ double sqrY = Mth.square(quartYY + offsetY);
|
||||
+ if (biomeX != 0 && smallestDist < sqrX + sqrY + maxQuartZZ) continue; // skip the rest of the loop
|
||||
+ seed = LinearCongruentialGenerator.next(seed, this.biomeZoomSeed);
|
||||
+ double offsetZ = getFiddle(seed);
|
||||
+ double biomeDist = sqrX + sqrY + Mth.square(quartZZ + offsetZ);
|
||||
+
|
||||
+ if (smallestDist > biomeDist) {
|
||||
+ smallestX = biomeX;
|
||||
+ smallestDist = biomeDist;
|
||||
+ }
|
||||
+ }
|
||||
+ return this.noiseBiomeSource.getNoiseBiome(
|
||||
+ (smallestX & 4) == 0 ? x : x + 1,
|
||||
+ (smallestX & 2) == 0 ? y : y + 1,
|
||||
+ (smallestX & 1) == 0 ? z : z + 1
|
||||
+ );
|
||||
+ } else {
|
||||
+ int i = pos.getX() - 2;
|
||||
+ int j = pos.getY() - 2;
|
||||
+ int k = pos.getZ() - 2;
|
||||
+ int l = i >> 2;
|
||||
+ int m = j >> 2;
|
||||
+ int n = k >> 2;
|
||||
+ double d = (double)(i & 3) / 4.0;
|
||||
+ double e = (double)(j & 3) / 4.0;
|
||||
+ double f = (double)(k & 3) / 4.0;
|
||||
+ int o = 0;
|
||||
+ double g = Double.POSITIVE_INFINITY;
|
||||
+
|
||||
+ for (int p = 0; p < 8; p++) {
|
||||
+ boolean bl = (p & 4) == 0;
|
||||
+ boolean bl2 = (p & 2) == 0;
|
||||
+ boolean bl3 = (p & 1) == 0;
|
||||
+ int q = bl ? l : l + 1;
|
||||
+ int r = bl2 ? m : m + 1;
|
||||
+ int s = bl3 ? n : n + 1;
|
||||
+ double h = bl ? d : d - 1.0;
|
||||
+ double t = bl2 ? e : e - 1.0;
|
||||
+ double u = bl3 ? f : f - 1.0;
|
||||
+ double v = getFiddledDistance(this.biomeZoomSeed, q, r, s, h, t, u);
|
||||
+ if (g > v) {
|
||||
+ o = p;
|
||||
+ g = v;
|
||||
+ }
|
||||
}
|
||||
- }
|
||||
|
||||
- int w = (o & 4) == 0 ? l : l + 1;
|
||||
- int x = (o & 2) == 0 ? m : m + 1;
|
||||
- int y = (o & 1) == 0 ? n : n + 1;
|
||||
- return this.noiseBiomeSource.getNoiseBiome(w, x, y);
|
||||
+ int w = (o & 4) == 0 ? l : l + 1;
|
||||
+ int x = (o & 2) == 0 ? m : m + 1;
|
||||
+ int y = (o & 1) == 0 ? n : n + 1;
|
||||
+ return this.noiseBiomeSource.getNoiseBiome(w, x, y);
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
public Holder<Biome> getNoiseBiomeAtPosition(double x, double y, double z) {
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
index 882e08b1eef89dd01129c89aa5fa1094d35788c5..911c9144cdf15930995fbd3c2b8ff01c74138c74 100644
|
||||
--- a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
+++ b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
@@ -159,4 +159,9 @@ public class DivineConfig {
|
||||
private static void miscSettings() {
|
||||
disableNonEditableSignWarning = getBoolean("settings.misc.disable-non-editable-sign-warning", disableNonEditableSignWarning);
|
||||
}
|
||||
+
|
||||
+ public static boolean biomeManagerOptimization = true;
|
||||
+ private static void optimizations() {
|
||||
+ biomeManagerOptimization = getBoolean("settings.optimizations.biome-manager-optimization", biomeManagerOptimization);
|
||||
+ }
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Wed, 22 May 2024 22:44:05 +0300
|
||||
Subject: [PATCH] Carpet-AMS-Addition: Optimized dragon respawn
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/state/pattern/BlockPattern.java b/src/main/java/net/minecraft/world/level/block/state/pattern/BlockPattern.java
|
||||
index ee99519ebd46b1db3e76e7eb86e5cc121c867dc4..43174e6b5bd306273736d1c2971f976c149d3517 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/state/pattern/BlockPattern.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/state/pattern/BlockPattern.java
|
||||
@@ -59,7 +59,7 @@ public class BlockPattern {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
- private BlockPattern.BlockPatternMatch matches(BlockPos frontTopLeft, Direction forwards, Direction up, LoadingCache<BlockPos, BlockInWorld> cache) {
|
||||
+ public BlockPattern.BlockPatternMatch matches(BlockPos frontTopLeft, Direction forwards, Direction up, LoadingCache<BlockPos, BlockInWorld> cache) { // DivineMC - private -> public
|
||||
for (int i = 0; i < this.width; i++) {
|
||||
for (int j = 0; j < this.height; j++) {
|
||||
for (int k = 0; k < this.depth; k++) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
index b331c93c82c27f9456fec208a0c008c5bedfa8c4..ec3142ae55686e13c2984eaf8cf0bcc8db0e39a3 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
@@ -46,6 +46,7 @@ import net.minecraft.world.entity.boss.enderdragon.phases.EnderDragonPhase;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
+import net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.TheEndPortalBlockEntity;
|
||||
import net.minecraft.world.level.block.state.pattern.BlockInWorld;
|
||||
import net.minecraft.world.level.block.state.pattern.BlockPattern;
|
||||
@@ -292,8 +293,67 @@ public class EndDragonFight {
|
||||
return false;
|
||||
}
|
||||
|
||||
+ // DivineMC start - Optimized dragon respawn
|
||||
+ private int cachePortalChunkIteratorX = -8;
|
||||
+ private int cachePortalChunkIteratorZ = -8;
|
||||
+ private int cachePortalOriginIteratorY = -1;
|
||||
+
|
||||
@Nullable
|
||||
public BlockPattern.BlockPatternMatch findExitPortal() {
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.optimizedDragonRespawn) {
|
||||
+ int i, j;
|
||||
+ for (i = cachePortalChunkIteratorX; i <= 8; ++i) {
|
||||
+ for (j = cachePortalChunkIteratorZ; j <= 8; ++j) {
|
||||
+ LevelChunk worldChunk = this.level.getChunk(i, j);
|
||||
+ for (BlockEntity blockEntity : worldChunk.getBlockEntities().values()) {
|
||||
+ if (blockEntity instanceof TheEndGatewayBlockEntity) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (blockEntity instanceof TheEndPortalBlockEntity) {
|
||||
+ BlockPattern.BlockPatternMatch blockPatternMatch = this.exitPortalPattern.find(this.level, blockEntity.getBlockPos());
|
||||
+ if (blockPatternMatch != null) {
|
||||
+ BlockPos blockPos = blockPatternMatch.getBlock(3, 3, 3).getPos();
|
||||
+ if (this.portalLocation == null) {
|
||||
+ this.portalLocation = blockPos;
|
||||
+ }
|
||||
+ //No need to judge whether optimizing option is open
|
||||
+ cachePortalChunkIteratorX = i;
|
||||
+ cachePortalChunkIteratorZ = j;
|
||||
+ return blockPatternMatch;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (this.needsStateScanning || this.portalLocation == null) {
|
||||
+ if (cachePortalOriginIteratorY != -1) {
|
||||
+ i = cachePortalOriginIteratorY;
|
||||
+ } else {
|
||||
+ i = this.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, EndPodiumFeature.getLocation(BlockPos.ZERO)).getY();
|
||||
+ }
|
||||
+ boolean notFirstSearch = false;
|
||||
+ for (j = i; j >= 0; --j) {
|
||||
+ BlockPattern.BlockPatternMatch result2 = null;
|
||||
+ if (notFirstSearch) {
|
||||
+ result2 = space.bxteam.divinemc.util.carpetams.BlockPatternHelper.partialSearchAround(this.exitPortalPattern, this.level, new BlockPos(EndPodiumFeature.getLocation(BlockPos.ZERO).getY(), j, EndPodiumFeature.getLocation(BlockPos.ZERO).getZ()));
|
||||
+ } else {
|
||||
+ result2 = this.exitPortalPattern.find(this.level, new BlockPos(EndPodiumFeature.getLocation(BlockPos.ZERO).getX(), j, EndPodiumFeature.getLocation(BlockPos.ZERO).getZ()));
|
||||
+ }
|
||||
+ if (result2 != null) {
|
||||
+ if (this.portalLocation == null) {
|
||||
+ this.portalLocation = result2.getBlock(3, 3, 3).getPos();
|
||||
+ }
|
||||
+ cachePortalOriginIteratorY = j;
|
||||
+ return result2;
|
||||
+ }
|
||||
+ notFirstSearch = true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return null;
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
ChunkPos chunkcoordintpair = new ChunkPos(this.origin);
|
||||
|
||||
int i;
|
||||
@@ -624,6 +684,11 @@ public class EndDragonFight {
|
||||
}
|
||||
|
||||
public boolean respawnDragon(List<EndCrystal> list) { // CraftBukkit - return boolean
|
||||
+ // DivineMC start - Optimized dragon respawn
|
||||
+ cachePortalChunkIteratorX = -8;
|
||||
+ cachePortalChunkIteratorZ = -8;
|
||||
+ cachePortalOriginIteratorY = -1;
|
||||
+ // DivineMC end
|
||||
if (this.dragonKilled && this.respawnStage == null) {
|
||||
for (BlockPattern.BlockPatternMatch shapedetector_shapedetectorcollection = this.findExitPortal(); shapedetector_shapedetectorcollection != null; shapedetector_shapedetectorcollection = this.findExitPortal()) {
|
||||
for (int i = 0; i < this.exitPortalPattern.getWidth(); ++i) {
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
index 911c9144cdf15930995fbd3c2b8ff01c74138c74..c88157b27b344b2ed1153a44daee751f5b53b45d 100644
|
||||
--- a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
+++ b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
@@ -161,7 +161,9 @@ public class DivineConfig {
|
||||
}
|
||||
|
||||
public static boolean biomeManagerOptimization = true;
|
||||
+ public static boolean optimizedDragonRespawn = true;
|
||||
private static void optimizations() {
|
||||
biomeManagerOptimization = getBoolean("settings.optimizations.biome-manager-optimization", biomeManagerOptimization);
|
||||
+ optimizedDragonRespawn = getBoolean("settings.optimizations.optimized-dragon-respawn", optimizedDragonRespawn);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/util/carpetams/BlockPatternHelper.java b/src/main/java/space/bxteam/divinemc/util/carpetams/BlockPatternHelper.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..1bf8f3d814d513ea2806bba9c26d207d14533cbd
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/space/bxteam/divinemc/util/carpetams/BlockPatternHelper.java
|
||||
@@ -0,0 +1,32 @@
|
||||
+package space.bxteam.divinemc.util.carpetams;
|
||||
+
|
||||
+import com.google.common.cache.LoadingCache;
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.core.Direction;
|
||||
+import net.minecraft.world.level.Level;
|
||||
+import net.minecraft.world.level.block.state.pattern.BlockInWorld;
|
||||
+import net.minecraft.world.level.block.state.pattern.BlockPattern;
|
||||
+
|
||||
+/**
|
||||
+ * Original <a href="https://github.com/Minecraft-AMS/Carpet-AMS-Addition">here</a>
|
||||
+ *
|
||||
+ * @author 1024-byteeeee
|
||||
+ */
|
||||
+public class BlockPatternHelper {
|
||||
+ public static BlockPattern.BlockPatternMatch partialSearchAround(BlockPattern pattern, Level world, BlockPos pos) {
|
||||
+ LoadingCache<BlockPos, BlockInWorld> loadingCache = BlockPattern.createLevelCache(world, false);
|
||||
+ int i = Math.max(Math.max(pattern.getWidth(), pattern.getHeight()), pattern.getDepth());
|
||||
+
|
||||
+ for (BlockPos blockPos : BlockPos.betweenClosed(pos, pos.offset(i - 1, 0, i - 1))) {
|
||||
+ for (Direction direction : Direction.values()) {
|
||||
+ for (Direction direction2 : Direction.values()) {
|
||||
+ BlockPattern.BlockPatternMatch result;
|
||||
+ if (direction2 == direction || direction2 == direction.getOpposite() || (result = pattern.matches(blockPos, direction, direction2, loadingCache)) == null)
|
||||
+ continue;
|
||||
+ return result;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+}
|
||||
@@ -1,297 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Wed, 22 May 2024 23:15:23 +0300
|
||||
Subject: [PATCH] C2ME: opts math
|
||||
|
||||
Original code by RelativityMC, licensed under MIT
|
||||
You can find the original code on https://github.com/RelativityMC/C2ME-fabric (Yarn mappings)
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java b/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java
|
||||
index 9a97e5cd23d839183ac4d243d28df92af3119fe7..04f3adc26999aebe039436bdd6ef85ab0197c5b4 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java
|
||||
@@ -11,6 +11,27 @@ public final class ImprovedNoise {
|
||||
public final double yo;
|
||||
public final double zo;
|
||||
|
||||
+ // DivineMC start - C2ME: opts math
|
||||
+ private static final double[] FLAT_SIMPLEX_GRAD = new double[]{
|
||||
+ 1, 1, 0, 0,
|
||||
+ -1, 1, 0, 0,
|
||||
+ 1, -1, 0, 0,
|
||||
+ -1, -1, 0, 0,
|
||||
+ 1, 0, 1, 0,
|
||||
+ -1, 0, 1, 0,
|
||||
+ 1, 0, -1, 0,
|
||||
+ -1, 0, -1, 0,
|
||||
+ 0, 1, 1, 0,
|
||||
+ 0, -1, 1, 0,
|
||||
+ 0, 1, -1, 0,
|
||||
+ 0, -1, -1, 0,
|
||||
+ 1, 1, 0, 0,
|
||||
+ 0, -1, 1, 0,
|
||||
+ -1, 1, 0, 0,
|
||||
+ 0, -1, -1, 0,
|
||||
+ };
|
||||
+ // DivineMC end
|
||||
+
|
||||
public ImprovedNoise(RandomSource random) {
|
||||
this.xo = random.nextDouble() * 256.0;
|
||||
this.yo = random.nextDouble() * 256.0;
|
||||
@@ -41,9 +62,20 @@ public final class ImprovedNoise {
|
||||
int i = Mth.floor(d);
|
||||
int j = Mth.floor(e);
|
||||
int k = Mth.floor(f);
|
||||
- double g = d - (double)i;
|
||||
- double h = e - (double)j;
|
||||
- double l = f - (double)k;
|
||||
+ // DivineMC start - C2ME: opts math
|
||||
+ double g;
|
||||
+ double h;
|
||||
+ double l;
|
||||
+ if (!space.bxteam.divinemc.configuration.DivineConfig.optimizeNoiseGeneration) {
|
||||
+ g = d - (double)i;
|
||||
+ h = e - (double)j;
|
||||
+ l = f - (double)k;
|
||||
+ } else {
|
||||
+ g = d - i;
|
||||
+ h = e - j;
|
||||
+ l = f - k;
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
double o;
|
||||
if (yScale != 0.0) {
|
||||
double m;
|
||||
@@ -53,12 +85,24 @@ public final class ImprovedNoise {
|
||||
m = h;
|
||||
}
|
||||
|
||||
- o = (double)Mth.floor(m / yScale + 1.0E-7F) * yScale;
|
||||
+ // DivineMC start - C2ME: opts math
|
||||
+ if (!space.bxteam.divinemc.configuration.DivineConfig.optimizeNoiseGeneration) {
|
||||
+ o = (double)Mth.floor(m / yScale + 1.0E-7F) * yScale;
|
||||
+ } else {
|
||||
+ o = Math.floor(m / yScale + (double)1.0E-7F) * yScale;
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
} else {
|
||||
o = 0.0;
|
||||
}
|
||||
|
||||
- return this.sampleAndLerp(i, j, k, g, h - o, l, h);
|
||||
+ // DivineMC start - C2ME: opts math
|
||||
+ if (!space.bxteam.divinemc.configuration.DivineConfig.optimizeNoiseGeneration) {
|
||||
+ return this.sampleAndLerp(i, j, k, g, h - o, l, h);
|
||||
+ } else {
|
||||
+ return this.sampleAndLerp((int) i, (int) j, (int) k, g, h - o, l, h);
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
public double noiseWithDerivative(double x, double y, double z, double[] ds) {
|
||||
@@ -68,10 +112,19 @@ public final class ImprovedNoise {
|
||||
int i = Mth.floor(d);
|
||||
int j = Mth.floor(e);
|
||||
int k = Mth.floor(f);
|
||||
- double g = d - (double)i;
|
||||
- double h = e - (double)j;
|
||||
- double l = f - (double)k;
|
||||
- return this.sampleWithDerivative(i, j, k, g, h, l, ds);
|
||||
+ // DivineMC start - C2ME: opts math
|
||||
+ if (!space.bxteam.divinemc.configuration.DivineConfig.optimizeNoiseGeneration) {
|
||||
+ double g = d - (double)i;
|
||||
+ double h = e - (double)j;
|
||||
+ double l = f - (double)k;
|
||||
+ return this.sampleWithDerivative(i, j, k, g, h, l, ds);
|
||||
+ } else {
|
||||
+ double g = d - i;
|
||||
+ double h = e - j;
|
||||
+ double l = f - k;
|
||||
+ return this.sampleWithDerivative((int) i, (int) j, (int) k, g, h, l, ds);
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
private static double gradDot(int hash, double x, double y, double z) {
|
||||
@@ -83,24 +136,90 @@ public final class ImprovedNoise {
|
||||
}
|
||||
|
||||
private double sampleAndLerp(int sectionX, int sectionY, int sectionZ, double localX, double localY, double localZ, double fadeLocalY) {
|
||||
- int i = this.p(sectionX);
|
||||
- int j = this.p(sectionX + 1);
|
||||
- int k = this.p(i + sectionY);
|
||||
- int l = this.p(i + sectionY + 1);
|
||||
- int m = this.p(j + sectionY);
|
||||
- int n = this.p(j + sectionY + 1);
|
||||
- double d = gradDot(this.p(k + sectionZ), localX, localY, localZ);
|
||||
- double e = gradDot(this.p(m + sectionZ), localX - 1.0, localY, localZ);
|
||||
- double f = gradDot(this.p(l + sectionZ), localX, localY - 1.0, localZ);
|
||||
- double g = gradDot(this.p(n + sectionZ), localX - 1.0, localY - 1.0, localZ);
|
||||
- double h = gradDot(this.p(k + sectionZ + 1), localX, localY, localZ - 1.0);
|
||||
- double o = gradDot(this.p(m + sectionZ + 1), localX - 1.0, localY, localZ - 1.0);
|
||||
- double p = gradDot(this.p(l + sectionZ + 1), localX, localY - 1.0, localZ - 1.0);
|
||||
- double q = gradDot(this.p(n + sectionZ + 1), localX - 1.0, localY - 1.0, localZ - 1.0);
|
||||
- double r = Mth.smoothstep(localX);
|
||||
- double s = Mth.smoothstep(fadeLocalY);
|
||||
- double t = Mth.smoothstep(localZ);
|
||||
- return Mth.lerp3(r, s, t, d, e, f, g, h, o, p, q);
|
||||
+ // DivineMC start - C2ME: opts math
|
||||
+ if (!space.bxteam.divinemc.configuration.DivineConfig.optimizeNoiseGeneration) {
|
||||
+ int i = this.p(sectionX);
|
||||
+ int j = this.p(sectionX + 1);
|
||||
+ int k = this.p(i + sectionY);
|
||||
+ int l = this.p(i + sectionY + 1);
|
||||
+ int m = this.p(j + sectionY);
|
||||
+ int n = this.p(j + sectionY + 1);
|
||||
+ double d = gradDot(this.p(k + sectionZ), localX, localY, localZ);
|
||||
+ double e = gradDot(this.p(m + sectionZ), localX - 1.0, localY, localZ);
|
||||
+ double f = gradDot(this.p(l + sectionZ), localX, localY - 1.0, localZ);
|
||||
+ double g = gradDot(this.p(n + sectionZ), localX - 1.0, localY - 1.0, localZ);
|
||||
+ double h = gradDot(this.p(k + sectionZ + 1), localX, localY, localZ - 1.0);
|
||||
+ double o = gradDot(this.p(m + sectionZ + 1), localX - 1.0, localY, localZ - 1.0);
|
||||
+ double p = gradDot(this.p(l + sectionZ + 1), localX, localY - 1.0, localZ - 1.0);
|
||||
+ double q = gradDot(this.p(n + sectionZ + 1), localX - 1.0, localY - 1.0, localZ - 1.0);
|
||||
+ double r = Mth.smoothstep(localX);
|
||||
+ double s = Mth.smoothstep(fadeLocalY);
|
||||
+ double t = Mth.smoothstep(localZ);
|
||||
+ return Mth.lerp3(r, s, t, d, e, f, g, h, o, p, q);
|
||||
+ } else {
|
||||
+ final int var0 = sectionX & 0xFF;
|
||||
+ final int var1 = (sectionX + 1) & 0xFF;
|
||||
+ final int var2 = this.p[var0] & 0xFF;
|
||||
+ final int var3 = this.p[var1] & 0xFF;
|
||||
+ final int var4 = (var2 + sectionY) & 0xFF;
|
||||
+ final int var5 = (var3 + sectionY) & 0xFF;
|
||||
+ final int var6 = (var2 + sectionY + 1) & 0xFF;
|
||||
+ final int var7 = (var3 + sectionY + 1) & 0xFF;
|
||||
+ final int var8 = this.p[var4] & 0xFF;
|
||||
+ final int var9 = this.p[var5] & 0xFF;
|
||||
+ final int var10 = this.p[var6] & 0xFF;
|
||||
+ final int var11 = this.p[var7] & 0xFF;
|
||||
+
|
||||
+ final int var12 = (var8 + sectionZ) & 0xFF;
|
||||
+ final int var13 = (var9 + sectionZ) & 0xFF;
|
||||
+ final int var14 = (var10 + sectionZ) & 0xFF;
|
||||
+ final int var15 = (var11 + sectionZ) & 0xFF;
|
||||
+ final int var16 = (var8 + sectionZ + 1) & 0xFF;
|
||||
+ final int var17 = (var9 + sectionZ + 1) & 0xFF;
|
||||
+ final int var18 = (var10 + sectionZ + 1) & 0xFF;
|
||||
+ final int var19 = (var11 + sectionZ + 1) & 0xFF;
|
||||
+ final int var20 = (this.p[var12] & 15) << 2;
|
||||
+ final int var21 = (this.p[var13] & 15) << 2;
|
||||
+ final int var22 = (this.p[var14] & 15) << 2;
|
||||
+ final int var23 = (this.p[var15] & 15) << 2;
|
||||
+ final int var24 = (this.p[var16] & 15) << 2;
|
||||
+ final int var25 = (this.p[var17] & 15) << 2;
|
||||
+ final int var26 = (this.p[var18] & 15) << 2;
|
||||
+ final int var27 = (this.p[var19] & 15) << 2;
|
||||
+ final double var60 = localX - 1.0;
|
||||
+ final double var61 = localY - 1.0;
|
||||
+ final double var62 = localZ - 1.0;
|
||||
+ final double var87 = FLAT_SIMPLEX_GRAD[(var20) | 0] * localX + FLAT_SIMPLEX_GRAD[(var20) | 1] * localY + FLAT_SIMPLEX_GRAD[(var20) | 2] * localZ;
|
||||
+ final double var88 = FLAT_SIMPLEX_GRAD[(var21) | 0] * var60 + FLAT_SIMPLEX_GRAD[(var21) | 1] * localY + FLAT_SIMPLEX_GRAD[(var21) | 2] * localZ;
|
||||
+ final double var89 = FLAT_SIMPLEX_GRAD[(var22) | 0] * localX + FLAT_SIMPLEX_GRAD[(var22) | 1] * var61 + FLAT_SIMPLEX_GRAD[(var22) | 2] * localZ;
|
||||
+ final double var90 = FLAT_SIMPLEX_GRAD[(var23) | 0] * var60 + FLAT_SIMPLEX_GRAD[(var23) | 1] * var61 + FLAT_SIMPLEX_GRAD[(var23) | 2] * localZ;
|
||||
+ final double var91 = FLAT_SIMPLEX_GRAD[(var24) | 0] * localX + FLAT_SIMPLEX_GRAD[(var24) | 1] * localY + FLAT_SIMPLEX_GRAD[(var24) | 2] * var62;
|
||||
+ final double var92 = FLAT_SIMPLEX_GRAD[(var25) | 0] * var60 + FLAT_SIMPLEX_GRAD[(var25) | 1] * localY + FLAT_SIMPLEX_GRAD[(var25) | 2] * var62;
|
||||
+ final double var93 = FLAT_SIMPLEX_GRAD[(var26) | 0] * localX + FLAT_SIMPLEX_GRAD[(var26) | 1] * var61 + FLAT_SIMPLEX_GRAD[(var26) | 2] * var62;
|
||||
+ final double var94 = FLAT_SIMPLEX_GRAD[(var27) | 0] * var60 + FLAT_SIMPLEX_GRAD[(var27) | 1] * var61 + FLAT_SIMPLEX_GRAD[(var27) | 2] * var62;
|
||||
+
|
||||
+ final double var95 = localX * 6.0 - 15.0;
|
||||
+ final double var96 = fadeLocalY * 6.0 - 15.0;
|
||||
+ final double var97 = localZ * 6.0 - 15.0;
|
||||
+ final double var98 = localX * var95 + 10.0;
|
||||
+ final double var99 = fadeLocalY * var96 + 10.0;
|
||||
+ final double var100 = localZ * var97 + 10.0;
|
||||
+ final double var101 = localX * localX * localX * var98;
|
||||
+ final double var102 = fadeLocalY * fadeLocalY * fadeLocalY * var99;
|
||||
+ final double var103 = localZ * localZ * localZ * var100;
|
||||
+
|
||||
+ final double var113 = var87 + var101 * (var88 - var87);
|
||||
+ final double var114 = var93 + var101 * (var94 - var93);
|
||||
+ final double var115 = var91 + var101 * (var92 - var91);
|
||||
+ final double var116 = var89 + var101 * (var90 - var89);
|
||||
+ final double var117 = var114 - var115;
|
||||
+ final double var118 = var102 * (var116 - var113);
|
||||
+ final double var119 = var102 * var117;
|
||||
+ final double var120 = var113 + var118;
|
||||
+ final double var121 = var115 + var119;
|
||||
+ return var120 + (var103 * (var121 - var120));
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
private double sampleWithDerivative(int sectionX, int sectionY, int sectionZ, double localX, double localY, double localZ, double[] ds) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java b/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
|
||||
index 35820670837376bcad8891241724d5b946fbd31f..74a666a45289f0902b426ba57986cd93b41cb42c 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
|
||||
@@ -26,6 +26,10 @@ public class PerlinNoise {
|
||||
private final double lowestFreqValueFactor;
|
||||
private final double lowestFreqInputFactor;
|
||||
private final double maxValue;
|
||||
+ // DivineMC start - C2ME: opts math
|
||||
+ private final int octaveSamplersCount;
|
||||
+ private final double [] amplitudesArray;
|
||||
+ // DivineMC end
|
||||
|
||||
@Deprecated
|
||||
public static PerlinNoise createLegacyForBlendedNoise(RandomSource random, IntStream octaves) {
|
||||
@@ -127,6 +131,10 @@ public class PerlinNoise {
|
||||
this.lowestFreqInputFactor = Math.pow(2.0, (double)(-j));
|
||||
this.lowestFreqValueFactor = Math.pow(2.0, (double)(i - 1)) / (Math.pow(2.0, (double)i) - 1.0);
|
||||
this.maxValue = this.edgeValue(2.0);
|
||||
+ // DivineMC start - C2ME: opts math
|
||||
+ this.octaveSamplersCount = this.noiseLevels.length;
|
||||
+ this.amplitudesArray = this.amplitudes.toDoubleArray();
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
protected double maxValue() {
|
||||
@@ -138,7 +146,30 @@ public class PerlinNoise {
|
||||
}
|
||||
|
||||
public double getValue(double x, double y, double z) {
|
||||
- return this.getValue(x, y, z, 0.0, 0.0, false);
|
||||
+ // DivineMC start - C2ME: opts math
|
||||
+ if (!space.bxteam.divinemc.configuration.DivineConfig.optimizeNoiseGeneration) {
|
||||
+ return this.getValue(x, y, z, 0.0, 0.0, false);
|
||||
+ } else {
|
||||
+ double d = 0.0;
|
||||
+ double e = this.lowestFreqInputFactor;
|
||||
+ double f = this.lowestFreqValueFactor;
|
||||
+
|
||||
+ for(int i = 0; i < this.octaveSamplersCount; ++i) {
|
||||
+ ImprovedNoise perlinNoiseSampler = this.noiseLevels[i];
|
||||
+ if (perlinNoiseSampler != null) {
|
||||
+ @SuppressWarnings("deprecation")
|
||||
+ double g = perlinNoiseSampler.noise(
|
||||
+ wrap(x * e), wrap(y * e), wrap(z * e), 0.0, 0.0
|
||||
+ );
|
||||
+ d += this.amplitudesArray[i] * g * f;
|
||||
+ }
|
||||
+
|
||||
+ e *= 2.0;
|
||||
+ f /= 2.0;
|
||||
+ }
|
||||
+ return d;
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
index c88157b27b344b2ed1153a44daee751f5b53b45d..aaf3afd0fe1f13ed7375d272e2690e9db0410417 100644
|
||||
--- a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
+++ b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
@@ -162,8 +162,10 @@ public class DivineConfig {
|
||||
|
||||
public static boolean biomeManagerOptimization = true;
|
||||
public static boolean optimizedDragonRespawn = true;
|
||||
+ public static boolean optimizeNoiseGeneration = true;
|
||||
private static void optimizations() {
|
||||
biomeManagerOptimization = getBoolean("settings.optimizations.biome-manager-optimization", biomeManagerOptimization);
|
||||
optimizedDragonRespawn = getBoolean("settings.optimizations.optimized-dragon-respawn", optimizedDragonRespawn);
|
||||
+ optimizeNoiseGeneration = getBoolean("settings.optimizations.optimize-noise-generation", optimizeNoiseGeneration);
|
||||
}
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sun, 12 May 2024 19:49:57 +0300
|
||||
Subject: [PATCH] No chat sign
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java
|
||||
index 14e412ebf75b0e06ab53a1c8f9dd1be6ad1e2680..a643f3fb7bf6ae8394fa43adf5a2149137d46c4b 100644
|
||||
--- a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java
|
||||
+++ b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java
|
||||
@@ -317,7 +317,7 @@ public final class ChatProcessor {
|
||||
|
||||
private void sendToServer(final ChatType.Bound chatType, final @Nullable Function<Audience, net.minecraft.network.chat.Component> msgFunction) {
|
||||
final PlayerChatMessage toConsoleMessage = msgFunction == null ? ChatProcessor.this.message : ChatProcessor.this.message.withUnsignedContent(msgFunction.apply(ChatProcessor.this.server.console));
|
||||
- ChatProcessor.this.server.logChatMessage(toConsoleMessage.decoratedContent(), chatType, ChatProcessor.this.server.getPlayerList().verifyChatTrusted(toConsoleMessage) ? null : "Not Secure");
|
||||
+ ChatProcessor.this.server.logChatMessage(toConsoleMessage.decoratedContent(), chatType, ChatProcessor.this.server.getPlayerList().verifyChatTrusted(toConsoleMessage) || space.bxteam.divinemc.configuration.DivineConfig.noChatSign ? null : "Not Secure"); // DivineMC - No chat sign
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/commands/arguments/ArgumentSignatures.java b/src/main/java/net/minecraft/commands/arguments/ArgumentSignatures.java
|
||||
index 479e6e2aa88a22ef7f8fccb06add6806f5b71d9d..370543f7f710971a37a0d05da8ef484a91d79f01 100644
|
||||
--- a/src/main/java/net/minecraft/commands/arguments/ArgumentSignatures.java
|
||||
+++ b/src/main/java/net/minecraft/commands/arguments/ArgumentSignatures.java
|
||||
@@ -14,9 +14,16 @@ public record ArgumentSignatures(List<ArgumentSignatures.Entry> entries) {
|
||||
private static final int MAX_ARGUMENT_NAME_LENGTH = 16;
|
||||
|
||||
public ArgumentSignatures(FriendlyByteBuf buf) {
|
||||
- this(buf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 8), ArgumentSignatures.Entry::new));
|
||||
+ this(readSign(buf)); // DivineMC - No chat sign
|
||||
}
|
||||
|
||||
+ // DivineMC start - No chat sign
|
||||
+ private static List<ArgumentSignatures.Entry> readSign(FriendlyByteBuf buf) {
|
||||
+ var entries = buf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 8), Entry::new);
|
||||
+ return space.bxteam.divinemc.configuration.DivineConfig.noChatSign ? List.of() : entries;
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
+
|
||||
public void write(FriendlyByteBuf buf) {
|
||||
buf.writeCollection(this.entries, (buf2, entry) -> entry.write(buf2));
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
index a523a83aec3a6ecbec4d60a187edc0c0167d15b4..b7c6b3b31860d372bead4cd2d3ea00fa4ffe1be3 100644
|
||||
--- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
@@ -129,6 +129,16 @@ public class FriendlyByteBuf extends ByteBuf {
|
||||
// Paper end - Adventure; add max length parameter
|
||||
DataResult<JsonElement> dataresult = codec.encodeStart(JsonOps.INSTANCE, value);
|
||||
|
||||
+ // DivineMC start - No chat sign
|
||||
+ if (codec == net.minecraft.network.protocol.status.ServerStatus.CODEC) {
|
||||
+ JsonElement element = dataresult.getOrThrow(string -> new EncoderException("Failed to encode: " + string + " " + value));
|
||||
+ element.getAsJsonObject().addProperty("preventsChatReports", space.bxteam.divinemc.configuration.DivineConfig.noChatSign);
|
||||
+
|
||||
+ this.writeUtf(GSON.toJson(element));
|
||||
+ return;
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
+
|
||||
this.writeUtf(FriendlyByteBuf.GSON.toJson((JsonElement) dataresult.getOrThrow((s) -> {
|
||||
return new EncoderException("Failed to encode: " + s + " " + String.valueOf(value));
|
||||
})), maxLength); // Paper - Adventure; add max length parameter
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ServerboundChatPacket.java b/src/main/java/net/minecraft/network/protocol/game/ServerboundChatPacket.java
|
||||
index 07df3299f1d1aa5506e1f6f146347d53e0278d9c..02fafc64d6178f2ae0be36b38ed5de7e0c31448c 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ServerboundChatPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundChatPacket.java
|
||||
@@ -16,7 +16,7 @@ public record ServerboundChatPacket(String message, Instant timeStamp, long salt
|
||||
);
|
||||
|
||||
private ServerboundChatPacket(FriendlyByteBuf buf) {
|
||||
- this(buf.readUtf(256), buf.readInstant(), buf.readLong(), buf.readNullable(MessageSignature::read), new LastSeenMessages.Update(buf));
|
||||
+ this(buf.readUtf(256), buf.readInstant(), buf.readLong(), buf.readNullable(ServerboundChatPacket::readSign), new LastSeenMessages.Update(buf)); // DivineMC - No chat sign
|
||||
}
|
||||
|
||||
private void write(FriendlyByteBuf buf) {
|
||||
@@ -27,6 +27,14 @@ public record ServerboundChatPacket(String message, Instant timeStamp, long salt
|
||||
this.lastSeenMessages.write(buf);
|
||||
}
|
||||
|
||||
+ // DivineMC start - No chat sign
|
||||
+ private static MessageSignature readSign(FriendlyByteBuf buf) {
|
||||
+ byte[] bs = new byte[256];
|
||||
+ buf.readBytes(bs);
|
||||
+ return space.bxteam.divinemc.configuration.DivineConfig.noChatSign ? null : new MessageSignature(bs);
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
+
|
||||
@Override
|
||||
public PacketType<ServerboundChatPacket> type() {
|
||||
return GamePacketTypes.SERVERBOUND_CHAT;
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java b/src/main/java/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java
|
||||
index 5705cb920084b775cce4b361683b32c6b6e003ed..9c031dd0fa279a23405e5b7d77e4c11e5a762684 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java
|
||||
@@ -26,6 +26,11 @@ public record ServerboundChatSessionUpdatePacket(RemoteChatSession.Data chatSess
|
||||
|
||||
@Override
|
||||
public void handle(ServerGamePacketListener listener) {
|
||||
+ // DivineMC start - No chat sign
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.noChatSign) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
listener.handleChatSessionUpdate(this);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 75919064593167b51c4325ba6d500366ba8408f1..23b3bfaebb8bfbb3bed77535526235c3db9e750f 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -705,7 +705,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
// Paper start - Add setting for proxy online mode status
|
||||
return dedicatedserverproperties.enforceSecureProfile
|
||||
&& io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode()
|
||||
- && this.services.canValidateProfileKeys();
|
||||
+ && this.services.canValidateProfileKeys() && !DivineConfig.noChatSign; // DivineMC - No chat sign
|
||||
// Paper end - Add setting for proxy online mode status
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
index df48c2754dc1ebd52addd8ae768cba5916ce3969..955cfbe0bd97d65fb757d6e9e76ec60440bc5b84 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
@@ -332,10 +332,24 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
}
|
||||
|
||||
public void send(Packet<?> packet) {
|
||||
+ // DivineMC start - No chat sign
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.noChatSign) {
|
||||
+ if (this instanceof ServerGamePacketListenerImpl && packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat) {
|
||||
+ packet = new net.minecraft.network.protocol.game.ClientboundSystemChatPacket(chat.chatType().decorate(chat.unsignedContent() != null ? chat.unsignedContent() : Component.literal(chat.body().content())), false);
|
||||
+ }
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
this.send(packet, (PacketSendListener) null);
|
||||
}
|
||||
|
||||
public void send(Packet<?> packet, @Nullable PacketSendListener callbacks) {
|
||||
+ // DivineMC start - No chat sign
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.noChatSign) {
|
||||
+ if (packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat && callbacks != null) {
|
||||
+ callbacks = null;
|
||||
+ }
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
// CraftBukkit start
|
||||
if (packet == null || this.processedDisconnect) { // Spigot
|
||||
return;
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 5b1705794a8c3914cb11fdd35f75c8e0c128ecd0..10f6b7e9fdc64760a8bcce34f5f453074a305a94 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -1426,7 +1426,7 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public boolean verifyChatTrusted(PlayerChatMessage message) { // Paper - private -> public
|
||||
- return message.hasSignature() && !message.hasExpiredServer(Instant.now());
|
||||
+ return space.bxteam.divinemc.configuration.DivineConfig.noChatSign || (message.hasSignature() && !message.hasExpiredServer(Instant.now())); // DivineMC - No chat sign
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
index aaf3afd0fe1f13ed7375d272e2690e9db0410417..261a55a4a5171f4ceb57fda8532bc1f795dc30ed 100644
|
||||
--- a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
+++ b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
@@ -168,4 +168,9 @@ public class DivineConfig {
|
||||
optimizedDragonRespawn = getBoolean("settings.optimizations.optimized-dragon-respawn", optimizedDragonRespawn);
|
||||
optimizeNoiseGeneration = getBoolean("settings.optimizations.optimize-noise-generation", optimizeNoiseGeneration);
|
||||
}
|
||||
+
|
||||
+ public static boolean noChatSign = true;
|
||||
+ private static void chatMessageSignatures() {
|
||||
+ noChatSign = getBoolean("settings.no-chat-sign", noChatSign);
|
||||
+ }
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Mon, 8 Jul 2024 09:03:56 +0300
|
||||
Subject: [PATCH] Akarin: Save Json list asynchronously
|
||||
|
||||
Original project: https://github.com/Akarin-project/Akarin
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/StoredUserList.java b/src/main/java/net/minecraft/server/players/StoredUserList.java
|
||||
index c038da20b76c0b7b1c18471b20be01e849d29f3a..e961374a6ba23c0e46b01e8fa01656c047989483 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/StoredUserList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/StoredUserList.java
|
||||
@@ -103,37 +103,47 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
|
||||
}
|
||||
|
||||
public void save() throws IOException {
|
||||
- this.removeExpired(); // Paper - remove expired values before saving
|
||||
- JsonArray jsonarray = new JsonArray();
|
||||
- Stream<JsonObject> stream = this.map.values().stream().map((jsonlistentry) -> { // CraftBukkit - decompile error
|
||||
- JsonObject jsonobject = new JsonObject();
|
||||
+ Runnable saveTask = () -> { // DivineMC - Save json list async
|
||||
+ this.removeExpired(); // Paper - remove expired values before saving
|
||||
+ JsonArray jsonarray = new JsonArray();
|
||||
+ Stream<JsonObject> stream = this.map.values().stream().map((jsonlistentry) -> { // CraftBukkit - decompile error
|
||||
+ JsonObject jsonobject = new JsonObject();
|
||||
|
||||
- Objects.requireNonNull(jsonlistentry);
|
||||
- return (JsonObject) Util.make(jsonobject, jsonlistentry::serialize);
|
||||
- });
|
||||
+ Objects.requireNonNull(jsonlistentry);
|
||||
+ return (JsonObject) Util.make(jsonobject, jsonlistentry::serialize);
|
||||
+ });
|
||||
|
||||
- Objects.requireNonNull(jsonarray);
|
||||
- stream.forEach(jsonarray::add);
|
||||
- BufferedWriter bufferedwriter = Files.newWriter(this.file, StandardCharsets.UTF_8);
|
||||
+ Objects.requireNonNull(jsonarray);
|
||||
+ stream.forEach(jsonarray::add);
|
||||
+
|
||||
+ try { // DivineMC - Save json list async
|
||||
+ BufferedWriter bufferedwriter = Files.newWriter(this.file, StandardCharsets.UTF_8);
|
||||
|
||||
- try {
|
||||
- StoredUserList.GSON.toJson(jsonarray, StoredUserList.GSON.newJsonWriter(bufferedwriter));
|
||||
- } catch (Throwable throwable) {
|
||||
- if (bufferedwriter != null) {
|
||||
try {
|
||||
- bufferedwriter.close();
|
||||
- } catch (Throwable throwable1) {
|
||||
- throwable.addSuppressed(throwable1);
|
||||
- }
|
||||
- }
|
||||
+ StoredUserList.GSON.toJson(jsonarray, StoredUserList.GSON.newJsonWriter(bufferedwriter));
|
||||
+ } catch (Throwable throwable) {
|
||||
+ if (bufferedwriter != null) {
|
||||
+ try {
|
||||
+ bufferedwriter.close();
|
||||
+ } catch (Throwable throwable1) {
|
||||
+ throwable.addSuppressed(throwable1);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- throw throwable;
|
||||
- }
|
||||
+ throw throwable;
|
||||
+ }
|
||||
|
||||
- if (bufferedwriter != null) {
|
||||
- bufferedwriter.close();
|
||||
- }
|
||||
+ if (bufferedwriter != null) {
|
||||
+ bufferedwriter.close();
|
||||
+ }
|
||||
|
||||
+ // DivineMC start
|
||||
+ } catch (Exception e) {
|
||||
+ StoredUserList.LOGGER.warn("Failed to async save " + this.file, e);
|
||||
+ }
|
||||
+ };
|
||||
+ io.papermc.paper.util.MCUtil.scheduleAsyncTask(saveTask);
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
public void load() throws IOException {
|
||||
@@ -1,832 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Sat, 20 Jul 2024 22:04:52 +0300
|
||||
Subject: [PATCH] Implement Secure Seed
|
||||
|
||||
Original license: GPLv3
|
||||
Original project: https://github.com/plasmoapp/matter
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/commands/SeedCommand.java b/src/main/java/net/minecraft/server/commands/SeedCommand.java
|
||||
index 0b500b19a99fa6c2740c0db350a166462668df9c..f13185628dec90a044bf03cf38394b5be8ab2003 100644
|
||||
--- a/src/main/java/net/minecraft/server/commands/SeedCommand.java
|
||||
+++ b/src/main/java/net/minecraft/server/commands/SeedCommand.java
|
||||
@@ -12,6 +12,17 @@ public class SeedCommand {
|
||||
long l = context.getSource().getLevel().getSeed();
|
||||
Component component = ComponentUtils.copyOnClickText(String.valueOf(l));
|
||||
context.getSource().sendSuccess(() -> Component.translatable("commands.seed.success", component), false);
|
||||
+
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
|
||||
+ space.bxteam.divinemc.seed.Globals.setupGlobals(context.getSource().getLevel());
|
||||
+ String seedStr = space.bxteam.divinemc.seed.Globals.seedToString(space.bxteam.divinemc.seed.Globals.worldSeed);
|
||||
+ Component featureSeedComponent = ComponentUtils.copyOnClickText(seedStr);
|
||||
+
|
||||
+ context.getSource().sendSuccess(() -> Component.translatable(("Feature seed: %s"), featureSeedComponent), false);
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
+
|
||||
return (int)l;
|
||||
}));
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
index 05e16103af3fd276f0196ddf1a2e5b729b025c34..e0118dfee89d4319f70a0d2f84ba4c21b03a9ed9 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
@@ -167,7 +167,17 @@ public class DedicatedServerProperties extends Settings<DedicatedServerPropertie
|
||||
boolean flag = this.get("generate-structures", true);
|
||||
long i = WorldOptions.parseSeed(s).orElse(WorldOptions.randomSeed());
|
||||
|
||||
- this.worldOptions = new WorldOptions(i, flag, false);
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
|
||||
+ String featureSeedStr = this.get("feature-level-seed", "");
|
||||
+ long[] featureSeed = space.bxteam.divinemc.seed.Globals.parseSeed(featureSeedStr)
|
||||
+ .orElse(space.bxteam.divinemc.seed.Globals.createRandomWorldSeed());
|
||||
+
|
||||
+ this.worldOptions = new WorldOptions(i, featureSeed, flag, false);
|
||||
+ } else {
|
||||
+ this.worldOptions = new WorldOptions(i, flag, false);
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
this.worldDimensionData = new DedicatedServerProperties.WorldDimensionData((JsonObject) this.get("generator-settings", (s1) -> {
|
||||
return GsonHelper.parse(!s1.isEmpty() ? s1 : "{}");
|
||||
}, new JsonObject()), (String) this.get("level-type", (s1) -> {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
index aea9a45c0916501f71018d3250b56da435f5664e..564395b9be9f161dc3ea7956b9b2432dc8bf45fa 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -692,6 +692,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||
}
|
||||
|
||||
public ChunkGenerator getGenerator() {
|
||||
+ space.bxteam.divinemc.seed.Globals.setupGlobals(level); // DivineMC - Implement Secure Seed
|
||||
return this.chunkMap.generator();
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index fe8a1a073920b7cbbe3791ac1fcac3fccec6b9f7..b0095c0848ca0162944961a24c7b807fb5846b06 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -644,6 +644,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
chunkgenerator = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, chunkgenerator, gen);
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ space.bxteam.divinemc.seed.Globals.setupGlobals(this); // DivineMC - Implement Secure Seed
|
||||
boolean flag2 = minecraftserver.forceSynchronousWrites();
|
||||
DataFixer datafixer = minecraftserver.getFixerUpper();
|
||||
EntityPersistentStorage<Entity> entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
index d58f7b251d0c322d63e7e5e8ed30b41427a11227..7fe1ae012dc3fec82bd75c6f44f1d32bf30fd666 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
@@ -433,8 +433,13 @@ public class Slime extends Mob implements Enemy {
|
||||
return false;
|
||||
}
|
||||
|
||||
- ChunkPos chunkcoordintpair = new ChunkPos(pos);
|
||||
- boolean flag = world.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper
|
||||
+ ChunkPos chunkcoordintpair = new ChunkPos(pos);
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ boolean isSlimeChunk = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
|
||||
+ ? world.getChunk(chunkcoordintpair.x, chunkcoordintpair.z).isSlimeChunk()
|
||||
+ : WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper
|
||||
+ boolean flag = world.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || isSlimeChunk;
|
||||
+ // DivineMC end
|
||||
|
||||
// Paper start - Replace rules for Height in Slime Chunks
|
||||
final double maxHeightSlimeChunk = world.getMinecraftWorld().paperConfig().entities.spawning.slimeSpawnHeight.slimeChunk.maximum;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
index f87abb22dd161b2b74401086de80dc95c9ac2dbb..5ca052b94ff9fa36e3241a745229839a1e9bc852 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
@@ -85,6 +85,11 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
|
||||
protected final LevelHeightAccessor levelHeightAccessor;
|
||||
protected final LevelChunkSection[] sections;
|
||||
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ private boolean slimeChunk;
|
||||
+ private boolean hasComputedSlimeChunk;
|
||||
+ // DivineMC end
|
||||
+
|
||||
// CraftBukkit start - SPIGOT-6814: move to IChunkAccess to account for 1.17 to 1.18 chunk upgrading.
|
||||
private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry();
|
||||
public org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer(ChunkAccess.DATA_TYPE_REGISTRY);
|
||||
@@ -189,6 +194,17 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
|
||||
return GameEventListenerRegistry.NOOP;
|
||||
}
|
||||
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ public boolean isSlimeChunk() {
|
||||
+ if (!hasComputedSlimeChunk) {
|
||||
+ hasComputedSlimeChunk = true;
|
||||
+ slimeChunk = space.bxteam.divinemc.seed.WorldgenCryptoRandom.seedSlimeChunk(chunkPos.x, chunkPos.z).nextInt(10) == 0;
|
||||
+ }
|
||||
+
|
||||
+ return slimeChunk;
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
+
|
||||
public abstract BlockState getBlockState(final int x, final int y, final int z); // Paper
|
||||
@Nullable
|
||||
public abstract BlockState setBlockState(BlockPos pos, BlockState state, boolean moved);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
index e0cb360ece042c4fc6aa0d10106923fe25288f5c..b42ab192fec723a17acd70aeb093895c8938ece2 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
@@ -345,7 +345,11 @@ public abstract class ChunkGenerator {
|
||||
return structure.step().ordinal();
|
||||
}));
|
||||
List<FeatureSorter.StepFeatureData> list = (List) this.featuresPerStep.get();
|
||||
- WorldgenRandom seededrandom = new WorldgenRandom(new XoroshiroRandomSource(RandomSupport.generateUniqueSeed()));
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ WorldgenRandom seededrandom = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
|
||||
+ ? new space.bxteam.divinemc.seed.WorldgenCryptoRandom(blockposition.getX(), blockposition.getZ(), space.bxteam.divinemc.seed.Globals.Salt.UNDEFINED, 0)
|
||||
+ : new WorldgenRandom(new XoroshiroRandomSource(RandomSupport.generateUniqueSeed()));
|
||||
+ // DivineMC end
|
||||
long i = seededrandom.setDecorationSeed(generatoraccessseed.getSeed(), blockposition.getX(), blockposition.getZ());
|
||||
Set<Holder<Biome>> set = new ObjectArraySet();
|
||||
|
||||
@@ -584,9 +588,18 @@ public abstract class ChunkGenerator {
|
||||
ArrayList<StructureSet.StructureSelectionEntry> arraylist = new ArrayList(list.size());
|
||||
|
||||
arraylist.addAll(list);
|
||||
- WorldgenRandom seededrandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
-
|
||||
- seededrandom.setLargeFeatureSeed(placementCalculator.getLevelSeed(), chunkcoordintpair.x, chunkcoordintpair.z);
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ WorldgenRandom seededrandom;
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
|
||||
+ seededrandom = new space.bxteam.divinemc.seed.WorldgenCryptoRandom(
|
||||
+ chunkcoordintpair.x, chunkcoordintpair.z, space.bxteam.divinemc.seed.Globals.Salt.GENERATE_FEATURE, 0
|
||||
+ );
|
||||
+ } else {
|
||||
+ seededrandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
+
|
||||
+ seededrandom.setLargeFeatureSeed(placementCalculator.getLevelSeed(), chunkcoordintpair.x, chunkcoordintpair.z);
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
int i = 0;
|
||||
|
||||
StructureSet.StructureSelectionEntry structureset_a1;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
|
||||
index a20520a6bd28bae1cee82258ac49d9753faba2bd..a0fbcf642f5a2aa6354d4287961d93779893d852 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
|
||||
@@ -224,15 +224,20 @@ public class ChunkGeneratorStructureState {
|
||||
List<CompletableFuture<ChunkPos>> list = new ArrayList(j);
|
||||
int k = placement.spread();
|
||||
HolderSet<Biome> holderset = placement.preferredBiomes();
|
||||
- RandomSource randomsource = RandomSource.create();
|
||||
-
|
||||
- // Paper start - Add missing structure set seed configs
|
||||
- if (this.conf.strongholdSeed != null && structureSetEntry.is(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS)) {
|
||||
- randomsource.setSeed(this.conf.strongholdSeed);
|
||||
- } else {
|
||||
- // Paper end - Add missing structure set seed configs
|
||||
- randomsource.setSeed(this.concentricRingsSeed);
|
||||
- } // Paper - Add missing structure set seed configs
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ RandomSource randomsource = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
|
||||
+ ? new space.bxteam.divinemc.seed.WorldgenCryptoRandom(0, 0, space.bxteam.divinemc.seed.Globals.Salt.STRONGHOLDS, 0)
|
||||
+ : RandomSource.create();
|
||||
+
|
||||
+ if (!space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
|
||||
+ // Paper start - Add missing structure set seed configs
|
||||
+ if (this.conf.strongholdSeed != null && structureSetEntry.is(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS)) {
|
||||
+ randomsource.setSeed(this.conf.strongholdSeed);
|
||||
+ } else {
|
||||
+ // Paper end - Add missing structure set seed configs
|
||||
+ randomsource.setSeed(this.concentricRingsSeed);
|
||||
+ } // Paper - Add missing structure set seed configs
|
||||
+ } // DivineMC end
|
||||
double d0 = randomsource.nextDouble() * Math.PI * 2.0D;
|
||||
int l = 0;
|
||||
int i1 = 0;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStep.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStep.java
|
||||
index f9aad1b8c02b70e620efdc2a58cadf4fff0f3ed5..261661977c3670d5173c677f041b2305a212718c 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStep.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStep.java
|
||||
@@ -60,6 +60,7 @@ public final class ChunkStep implements ca.spottedleaf.moonrise.patches.chunk_sy
|
||||
}
|
||||
|
||||
public CompletableFuture<ChunkAccess> apply(WorldGenContext context, StaticCache2D<GenerationChunkHolder> staticCache2D, ChunkAccess chunk) {
|
||||
+ space.bxteam.divinemc.seed.Globals.setupGlobals(context.level()); // DivineMC - Implement Secure Seed
|
||||
if (chunk.getPersistedStatus().isBefore(this.targetStatus)) {
|
||||
ProfiledDuration profiledDuration = JvmProfiler.INSTANCE.onChunkGenerate(chunk.getPos(), context.level().dimension(), this.targetStatus.getName());
|
||||
return this.task.doWork(context, this, staticCache2D, chunk).thenApply(generated -> this.completeChunkGeneration(generated, profiledDuration));
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/WorldOptions.java b/src/main/java/net/minecraft/world/level/levelgen/WorldOptions.java
|
||||
index 41c19e4e7bde4632879da564f52f3d373de27ec4..6070110bdfada835dd6b04f66644a47aa868fe4e 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/WorldOptions.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/WorldOptions.java
|
||||
@@ -9,8 +9,19 @@ import net.minecraft.util.RandomSource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class WorldOptions {
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ private static final boolean isSecureSeedEnabled = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed;
|
||||
public static final MapCodec<WorldOptions> CODEC = RecordCodecBuilder.mapCodec(
|
||||
- instance -> instance.group(
|
||||
+ instance -> isSecureSeedEnabled
|
||||
+ ? instance.group(
|
||||
+ Codec.LONG.fieldOf("seed").stable().forGetter(WorldOptions::seed),
|
||||
+ Codec.LONG_STREAM.fieldOf("feature_seed").stable().forGetter(WorldOptions::featureSeedStream),
|
||||
+ Codec.BOOL.fieldOf("generate_features").orElse(true).stable().forGetter(WorldOptions::generateStructures),
|
||||
+ Codec.BOOL.fieldOf("bonus_chest").orElse(false).stable().forGetter(WorldOptions::generateBonusChest),
|
||||
+ Codec.STRING.lenientOptionalFieldOf("legacy_custom_options").stable().forGetter(generatorOptions -> generatorOptions.legacyCustomOptions)
|
||||
+ )
|
||||
+ .apply(instance, instance.stable(WorldOptions::new))
|
||||
+ : instance.group(
|
||||
Codec.LONG.fieldOf("seed").stable().forGetter(WorldOptions::seed),
|
||||
Codec.BOOL.fieldOf("generate_features").orElse(true).stable().forGetter(WorldOptions::generateStructures),
|
||||
Codec.BOOL.fieldOf("bonus_chest").orElse(false).stable().forGetter(WorldOptions::generateBonusChest),
|
||||
@@ -18,8 +29,14 @@ public class WorldOptions {
|
||||
)
|
||||
.apply(instance, instance.stable(WorldOptions::new))
|
||||
);
|
||||
- public static final WorldOptions DEMO_OPTIONS = new WorldOptions((long)"North Carolina".hashCode(), true, true);
|
||||
+ // DivineMC end
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ public static final WorldOptions DEMO_OPTIONS = isSecureSeedEnabled
|
||||
+ ? new WorldOptions((long) "North Carolina".hashCode(), space.bxteam.divinemc.seed.Globals.createRandomWorldSeed(), true, true)
|
||||
+ : new WorldOptions("North Carolina".hashCode(), true, true);
|
||||
+ // DivineMC end
|
||||
private final long seed;
|
||||
+ private long[] featureSeed = space.bxteam.divinemc.seed.Globals.createRandomWorldSeed(); // DivineMC - Implement Secure Seed
|
||||
private final boolean generateStructures;
|
||||
private final boolean generateBonusChest;
|
||||
private final Optional<String> legacyCustomOptions;
|
||||
@@ -28,8 +45,18 @@ public class WorldOptions {
|
||||
this(seed, generateStructures, bonusChest, Optional.empty());
|
||||
}
|
||||
|
||||
+ public WorldOptions(long seed, long[] featureSeed, boolean generateStructures, boolean bonusChest) {
|
||||
+ this(seed, featureSeed, generateStructures, bonusChest, Optional.empty());
|
||||
+ }
|
||||
+
|
||||
public static WorldOptions defaultWithRandomSeed() {
|
||||
- return new WorldOptions(randomSeed(), true, false);
|
||||
+ return isSecureSeedEnabled
|
||||
+ ? new WorldOptions(randomSeed(), space.bxteam.divinemc.seed.Globals.createRandomWorldSeed(), true, false)
|
||||
+ : new WorldOptions(randomSeed(), true, false);
|
||||
+ }
|
||||
+
|
||||
+ private WorldOptions(long seed, java.util.stream.LongStream featureSeed, boolean generateStructures, boolean bonusChest, Optional<String> legacyCustomOptions) {
|
||||
+ this(seed, featureSeed.toArray(), generateStructures, bonusChest, legacyCustomOptions);
|
||||
}
|
||||
|
||||
public static WorldOptions testWorldWithRandomSeed() {
|
||||
@@ -43,10 +70,27 @@ public class WorldOptions {
|
||||
this.legacyCustomOptions = legacyCustomOptions;
|
||||
}
|
||||
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ private WorldOptions(long seed, long[] featureSeed, boolean generateStructures, boolean bonusChest, Optional<String> legacyCustomOptions) {
|
||||
+ this(seed, generateStructures, bonusChest, legacyCustomOptions);
|
||||
+ this.featureSeed = featureSeed;
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
+
|
||||
public long seed() {
|
||||
return this.seed;
|
||||
}
|
||||
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ public long[] featureSeed() {
|
||||
+ return this.featureSeed;
|
||||
+ }
|
||||
+
|
||||
+ public java.util.stream.LongStream featureSeedStream() {
|
||||
+ return java.util.stream.LongStream.of(this.featureSeed);
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
+
|
||||
public boolean generateStructures() {
|
||||
return this.generateStructures;
|
||||
}
|
||||
@@ -59,17 +103,25 @@ public class WorldOptions {
|
||||
return this.legacyCustomOptions.isPresent();
|
||||
}
|
||||
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
public WorldOptions withBonusChest(boolean bonusChest) {
|
||||
- return new WorldOptions(this.seed, this.generateStructures, bonusChest, this.legacyCustomOptions);
|
||||
+ return isSecureSeedEnabled
|
||||
+ ? new WorldOptions(this.seed, this.featureSeed, this.generateStructures, bonusChest, this.legacyCustomOptions)
|
||||
+ : new WorldOptions(this.seed, this.generateStructures, bonusChest, this.legacyCustomOptions);
|
||||
}
|
||||
|
||||
public WorldOptions withStructures(boolean structures) {
|
||||
- return new WorldOptions(this.seed, structures, this.generateBonusChest, this.legacyCustomOptions);
|
||||
+ return isSecureSeedEnabled
|
||||
+ ? new WorldOptions(this.seed, this.featureSeed, structures, this.generateBonusChest, this.legacyCustomOptions)
|
||||
+ : new WorldOptions(this.seed, structures, this.generateBonusChest, this.legacyCustomOptions);
|
||||
}
|
||||
|
||||
public WorldOptions withSeed(OptionalLong seed) {
|
||||
- return new WorldOptions(seed.orElse(randomSeed()), this.generateStructures, this.generateBonusChest, this.legacyCustomOptions);
|
||||
+ return isSecureSeedEnabled
|
||||
+ ? new WorldOptions(seed.orElse(randomSeed()), space.bxteam.divinemc.seed.Globals.createRandomWorldSeed(), this.generateStructures, this.generateBonusChest, this.legacyCustomOptions)
|
||||
+ : new WorldOptions(seed.orElse(randomSeed()), this.generateStructures, this.generateBonusChest, this.legacyCustomOptions);
|
||||
}
|
||||
+ // DivineMC end
|
||||
|
||||
public static OptionalLong parseSeed(String seed) {
|
||||
seed = seed.trim();
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
|
||||
index 270db8b29cdf65e9bb932637425214eefeca86b7..6cf307b4ddb87ad54ead02dd10290a7a825095e3 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
|
||||
@@ -41,7 +41,11 @@ public class GeodeFeature extends Feature<GeodeConfiguration> {
|
||||
int j = geodeConfiguration.maxGenOffset;
|
||||
List<Pair<BlockPos, Integer>> list = Lists.newLinkedList();
|
||||
int k = geodeConfiguration.distributionPoints.sample(randomSource);
|
||||
- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(worldGenLevel.getSeed()));
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ WorldgenRandom worldgenRandom = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
|
||||
+ ? new space.bxteam.divinemc.seed.WorldgenCryptoRandom(0, 0, space.bxteam.divinemc.seed.Globals.Salt.GEODE_FEATURE, 0)
|
||||
+ : new WorldgenRandom(new LegacyRandomSource(worldGenLevel.getSeed()));
|
||||
+ // DivineMC end
|
||||
NormalNoise normalNoise = NormalNoise.create(worldgenRandom, -4, 1.0);
|
||||
List<BlockPos> list2 = Lists.newLinkedList();
|
||||
double d = (double)k / (double)geodeConfiguration.outerWallDistance.getMaxValue();
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/Structure.java b/src/main/java/net/minecraft/world/level/levelgen/structure/Structure.java
|
||||
index 13f7fce1959c0f44e047616674198176e667067f..23528e2eef5d097cad44e8f51a6199a7bf718044 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/Structure.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/Structure.java
|
||||
@@ -248,6 +248,14 @@ public abstract class Structure {
|
||||
}
|
||||
|
||||
private static WorldgenRandom makeRandom(long seed, ChunkPos chunkPos) {
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
|
||||
+ return new space.bxteam.divinemc.seed.WorldgenCryptoRandom(
|
||||
+ chunkPos.x, chunkPos.z, space.bxteam.divinemc.seed.Globals.Salt.GENERATE_FEATURE, seed
|
||||
+ );
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
+
|
||||
WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
worldgenRandom.setLargeFeatureSeed(seed, chunkPos.x, chunkPos.z);
|
||||
return worldgenRandom;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java b/src/main/java/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java
|
||||
index f873a0a0734b4fe74ba5b5f8ae0cc3c78fa76b9f..1e29d5554ac2be3219f075092778e49022788723 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java
|
||||
@@ -71,8 +71,17 @@ public class RandomSpreadStructurePlacement extends StructurePlacement {
|
||||
public ChunkPos getPotentialStructureChunk(long seed, int chunkX, int chunkZ) {
|
||||
int i = Math.floorDiv(chunkX, this.spacing);
|
||||
int j = Math.floorDiv(chunkZ, this.spacing);
|
||||
- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
- worldgenRandom.setLargeFeatureWithSalt(seed, i, j, this.salt());
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ WorldgenRandom worldgenRandom;
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
|
||||
+ worldgenRandom = new space.bxteam.divinemc.seed.WorldgenCryptoRandom(
|
||||
+ i, j, space.bxteam.divinemc.seed.Globals.Salt.POTENTIONAL_FEATURE, this.salt
|
||||
+ );
|
||||
+ } else {
|
||||
+ worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
+ worldgenRandom.setLargeFeatureWithSalt(seed, i, j, this.salt());
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
int k = this.spacing - this.separation;
|
||||
int l = this.spreadType.evaluate(worldgenRandom, k);
|
||||
int m = this.spreadType.evaluate(worldgenRandom, k);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java b/src/main/java/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
|
||||
index cbf13e4f2da6a27619e9bc9a7cd73bb6e69cad2a..8aebe917973f65123a3b0744172a307f95b05cb0 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
|
||||
@@ -118,8 +118,18 @@ public abstract class StructurePlacement {
|
||||
public abstract StructurePlacementType<?> type();
|
||||
|
||||
private static boolean probabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs; ignore here
|
||||
- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
- worldgenRandom.setLargeFeatureWithSalt(seed, salt, chunkX, chunkZ);
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ WorldgenRandom worldgenRandom;
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
|
||||
+ worldgenRandom = new space.bxteam.divinemc.seed.WorldgenCryptoRandom(
|
||||
+ chunkX, chunkZ, space.bxteam.divinemc.seed.Globals.Salt.UNDEFINED, salt
|
||||
+ );
|
||||
+ } else {
|
||||
+ worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
+ worldgenRandom.setLargeFeatureWithSalt(seed, salt, chunkX, chunkZ);
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
+
|
||||
return worldgenRandom.nextFloat() < frequency;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java b/src/main/java/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java
|
||||
index 65a0d9e7dd742732974774daabce02e9e52039ac..53e1261ef3ec66d90bcc17e99cb21e7d8ef9ccea 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java
|
||||
@@ -64,7 +64,11 @@ public class JigsawPlacement {
|
||||
ChunkGenerator chunkGenerator = context.chunkGenerator();
|
||||
StructureTemplateManager structureTemplateManager = context.structureTemplateManager();
|
||||
LevelHeightAccessor levelHeightAccessor = context.heightAccessor();
|
||||
- WorldgenRandom worldgenRandom = context.random();
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ WorldgenRandom worldgenRandom = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
|
||||
+ ? new space.bxteam.divinemc.seed.WorldgenCryptoRandom(context.chunkPos().x, context.chunkPos().z, space.bxteam.divinemc.seed.Globals.Salt.JIGSAW_PLACEMENT, 0)
|
||||
+ : context.random();
|
||||
+ // DivineMC end
|
||||
Registry<StructureTemplatePool> registry = registryAccess.lookupOrThrow(Registries.TEMPLATE_POOL);
|
||||
Rotation rotation = Rotation.getRandom(worldgenRandom);
|
||||
StructureTemplatePool structureTemplatePool = structurePool.unwrapKey()
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
index c2bffe3450ee9f768e00a23ec09df74d7a06d49b..922d1037352198432c16b782c892467c76e17428 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
@@ -206,7 +206,12 @@ public class CraftChunk implements Chunk {
|
||||
@Override
|
||||
public boolean isSlimeChunk() {
|
||||
// 987234911L is deterimined in EntitySlime when seeing if a slime can spawn in a chunk
|
||||
- return this.worldServer.paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0; // Paper
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ boolean isSlimeChunk = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
|
||||
+ ? worldServer.getChunk(this.getX(), this.getZ()).isSlimeChunk()
|
||||
+ : WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0; // Paper
|
||||
+ return this.worldServer.paperConfig().entities.spawning.allChunksAreSlimeChunks || isSlimeChunk;
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 88343cbdaa95f7f2bf6a196b58f23195186749a2..62807b021b936477db6e266633767d81a9436bb2 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -1409,7 +1409,11 @@ public final class CraftServer implements Server {
|
||||
iregistrycustom_dimension = leveldataanddimensions.dimensions().dimensionsRegistryAccess();
|
||||
} else {
|
||||
LevelSettings worldsettings;
|
||||
- WorldOptions worldoptions = new WorldOptions(creator.seed(), creator.generateStructures(), false);
|
||||
+ // DivineMC start - Implement Secure Seed
|
||||
+ WorldOptions worldoptions = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
|
||||
+ ? new WorldOptions(creator.seed(), space.bxteam.divinemc.seed.Globals.createRandomWorldSeed(), creator.generateStructures(), false)
|
||||
+ : new WorldOptions(creator.seed(), creator.generateStructures(), false);
|
||||
+ // DivineMC end
|
||||
WorldDimensions worlddimensions;
|
||||
|
||||
DedicatedServerProperties.WorldDimensionData properties = new DedicatedServerProperties.WorldDimensionData(GsonHelper.parse((creator.generatorSettings().isEmpty()) ? "{}" : creator.generatorSettings()), creator.type().name().toLowerCase(Locale.ROOT));
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
index 9deb9310b6829f2e1bac36327bbb21cee099b22b..c494d88cda016ff7a4da37ac1cee2a05876e595f 100644
|
||||
--- a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
+++ b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
@@ -158,10 +158,12 @@ public class DivineConfig {
|
||||
public static boolean disableNonEditableSignWarning = true;
|
||||
public static boolean removeVanillaUsernameCheck = false;
|
||||
public static boolean disableMovedWronglyThreshold = false;
|
||||
+ public static boolean enableSecureSeed = false;
|
||||
private static void miscSettings() {
|
||||
disableNonEditableSignWarning = getBoolean("settings.misc.disable-non-editable-sign-warning", disableNonEditableSignWarning);
|
||||
removeVanillaUsernameCheck = getBoolean("settings.misc.remove-vanilla-username-check", removeVanillaUsernameCheck);
|
||||
disableMovedWronglyThreshold = getBoolean("settings.misc.disable-moved-wrongly-threshold", disableMovedWronglyThreshold);
|
||||
+ enableSecureSeed = getBoolean("settings.misc.enable-secure-seed", enableSecureSeed);
|
||||
}
|
||||
|
||||
public static boolean biomeManagerOptimization = true;
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/seed/Globals.java b/src/main/java/space/bxteam/divinemc/seed/Globals.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..39d2d74f6a89ecbe42ef45d9fc500762a2dfce51
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/space/bxteam/divinemc/seed/Globals.java
|
||||
@@ -0,0 +1,94 @@
|
||||
+package space.bxteam.divinemc.seed;
|
||||
+
|
||||
+import com.google.common.collect.Iterables;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+
|
||||
+import java.math.BigInteger;
|
||||
+import java.security.SecureRandom;
|
||||
+import java.util.Optional;
|
||||
+
|
||||
+public class Globals {
|
||||
+ public static final int WORLD_SEED_LONGS = 16;
|
||||
+ public static final int WORLD_SEED_BITS = WORLD_SEED_LONGS * 64;
|
||||
+
|
||||
+ public static final long[] worldSeed = new long[WORLD_SEED_LONGS];
|
||||
+ public static final ThreadLocal<Integer> dimension = ThreadLocal.withInitial(() -> 0);
|
||||
+
|
||||
+ public enum Salt {
|
||||
+ UNDEFINED,
|
||||
+ BASTION_FEATURE,
|
||||
+ WOODLAND_MANSION_FEATURE,
|
||||
+ MINESHAFT_FEATURE,
|
||||
+ BURIED_TREASURE_FEATURE,
|
||||
+ NETHER_FORTRESS_FEATURE,
|
||||
+ PILLAGER_OUTPOST_FEATURE,
|
||||
+ GEODE_FEATURE,
|
||||
+ NETHER_FOSSIL_FEATURE,
|
||||
+ OCEAN_MONUMENT_FEATURE,
|
||||
+ RUINED_PORTAL_FEATURE,
|
||||
+ POTENTIONAL_FEATURE,
|
||||
+ GENERATE_FEATURE,
|
||||
+ JIGSAW_PLACEMENT,
|
||||
+ STRONGHOLDS,
|
||||
+ POPULATION,
|
||||
+ DECORATION,
|
||||
+ SLIME_CHUNK
|
||||
+ }
|
||||
+
|
||||
+ public static void setupGlobals(ServerLevel world) {
|
||||
+ if (!space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) return;
|
||||
+
|
||||
+ long[] seed = world.getServer().getWorldData().worldGenOptions().featureSeed();
|
||||
+ System.arraycopy(seed, 0, worldSeed, 0, WORLD_SEED_LONGS);
|
||||
+ int worldIndex = Iterables.indexOf(world.getServer().levelKeys(), it -> it == world.dimension());
|
||||
+ if (worldIndex == -1)
|
||||
+ worldIndex = world.getServer().levelKeys().size(); // if we are in world construction it may not have been added to the map yet
|
||||
+ dimension.set(worldIndex);
|
||||
+ }
|
||||
+
|
||||
+ public static long[] createRandomWorldSeed() {
|
||||
+ long[] seed = new long[WORLD_SEED_LONGS];
|
||||
+ SecureRandom rand = new SecureRandom();
|
||||
+ for (int i = 0; i < WORLD_SEED_LONGS; i++) {
|
||||
+ seed[i] = rand.nextLong();
|
||||
+ }
|
||||
+ return seed;
|
||||
+ }
|
||||
+
|
||||
+ // 1024-bit string -> 16 * 64 long[]
|
||||
+ public static Optional<long[]> parseSeed(String seedStr) {
|
||||
+ if (seedStr.isEmpty()) return Optional.empty();
|
||||
+
|
||||
+ if (seedStr.length() != WORLD_SEED_BITS) {
|
||||
+ throw new IllegalArgumentException("Secure seed length must be " + WORLD_SEED_BITS + "-bit but found " + seedStr.length() + "-bit.");
|
||||
+ }
|
||||
+
|
||||
+ long[] seed = new long[WORLD_SEED_LONGS];
|
||||
+
|
||||
+ for (int i = 0; i < WORLD_SEED_LONGS; i++) {
|
||||
+ int start = i * 64;
|
||||
+ int end = start + 64;
|
||||
+ String seedSection = seedStr.substring(start, end);
|
||||
+
|
||||
+ BigInteger seedInDecimal = new BigInteger(seedSection, 2);
|
||||
+ seed[i] = seedInDecimal.longValue();
|
||||
+ }
|
||||
+
|
||||
+ return Optional.of(seed);
|
||||
+ }
|
||||
+
|
||||
+ // 16 * 64 long[] -> 1024-bit string
|
||||
+ public static String seedToString(long[] seed) {
|
||||
+ StringBuilder sb = new StringBuilder();
|
||||
+
|
||||
+ for (long longV : seed) {
|
||||
+ // Convert to 64-bit binary string per long
|
||||
+ // Use format to keep 64-bit length, and use 0 to complete space
|
||||
+ String binaryStr = String.format("%64s", Long.toBinaryString(longV)).replace(' ', '0');
|
||||
+
|
||||
+ sb.append(binaryStr);
|
||||
+ }
|
||||
+
|
||||
+ return sb.toString();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/seed/Hashing.java b/src/main/java/space/bxteam/divinemc/seed/Hashing.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5974e52ec4ad6422ef0eac19d0b32be233889a40
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/space/bxteam/divinemc/seed/Hashing.java
|
||||
@@ -0,0 +1,73 @@
|
||||
+package space.bxteam.divinemc.seed;
|
||||
+
|
||||
+public class Hashing {
|
||||
+ // https://en.wikipedia.org/wiki/BLAKE_(hash_function)
|
||||
+ // https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/digests/Blake2bDigest.java
|
||||
+
|
||||
+ private final static long[] blake2b_IV = {
|
||||
+ 0x6a09e667f3bcc908L, 0xbb67ae8584caa73bL, 0x3c6ef372fe94f82bL,
|
||||
+ 0xa54ff53a5f1d36f1L, 0x510e527fade682d1L, 0x9b05688c2b3e6c1fL,
|
||||
+ 0x1f83d9abfb41bd6bL, 0x5be0cd19137e2179L
|
||||
+ };
|
||||
+
|
||||
+ private final static byte[][] blake2b_sigma = {
|
||||
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
+ {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
|
||||
+ {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
|
||||
+ {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
|
||||
+ {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
|
||||
+ {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
|
||||
+ {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
|
||||
+ {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
|
||||
+ {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
|
||||
+ {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0},
|
||||
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
+ {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}
|
||||
+ };
|
||||
+
|
||||
+ public static long[] hashWorldSeed(long[] worldSeed) {
|
||||
+ long[] result = blake2b_IV.clone();
|
||||
+ result[0] ^= 0x01010040;
|
||||
+ hash(worldSeed, result, new long[16], 0, false);
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ public static void hash(long[] message, long[] chainValue, long[] internalState, long messageOffset, boolean isFinal) {
|
||||
+ assert message.length == 16;
|
||||
+ assert chainValue.length == 8;
|
||||
+ assert internalState.length == 16;
|
||||
+
|
||||
+ System.arraycopy(chainValue, 0, internalState, 0, chainValue.length);
|
||||
+ System.arraycopy(blake2b_IV, 0, internalState, chainValue.length, 4);
|
||||
+ internalState[12] = messageOffset ^ blake2b_IV[4];
|
||||
+ internalState[13] = blake2b_IV[5];
|
||||
+ if (isFinal) internalState[14] = ~blake2b_IV[6];
|
||||
+ internalState[15] = blake2b_IV[7];
|
||||
+
|
||||
+ for (int round = 0; round < 12; round++) {
|
||||
+ G(message[blake2b_sigma[round][0]], message[blake2b_sigma[round][1]], 0, 4, 8, 12, internalState);
|
||||
+ G(message[blake2b_sigma[round][2]], message[blake2b_sigma[round][3]], 1, 5, 9, 13, internalState);
|
||||
+ G(message[blake2b_sigma[round][4]], message[blake2b_sigma[round][5]], 2, 6, 10, 14, internalState);
|
||||
+ G(message[blake2b_sigma[round][6]], message[blake2b_sigma[round][7]], 3, 7, 11, 15, internalState);
|
||||
+ G(message[blake2b_sigma[round][8]], message[blake2b_sigma[round][9]], 0, 5, 10, 15, internalState);
|
||||
+ G(message[blake2b_sigma[round][10]], message[blake2b_sigma[round][11]], 1, 6, 11, 12, internalState);
|
||||
+ G(message[blake2b_sigma[round][12]], message[blake2b_sigma[round][13]], 2, 7, 8, 13, internalState);
|
||||
+ G(message[blake2b_sigma[round][14]], message[blake2b_sigma[round][15]], 3, 4, 9, 14, internalState);
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < 8; i++) {
|
||||
+ chainValue[i] ^= internalState[i] ^ internalState[i + 8];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void G(long m1, long m2, int posA, int posB, int posC, int posD, long[] internalState) {
|
||||
+ internalState[posA] = internalState[posA] + internalState[posB] + m1;
|
||||
+ internalState[posD] = Long.rotateRight(internalState[posD] ^ internalState[posA], 32);
|
||||
+ internalState[posC] = internalState[posC] + internalState[posD];
|
||||
+ internalState[posB] = Long.rotateRight(internalState[posB] ^ internalState[posC], 24); // replaces 25 of BLAKE
|
||||
+ internalState[posA] = internalState[posA] + internalState[posB] + m2;
|
||||
+ internalState[posD] = Long.rotateRight(internalState[posD] ^ internalState[posA], 16);
|
||||
+ internalState[posC] = internalState[posC] + internalState[posD];
|
||||
+ internalState[posB] = Long.rotateRight(internalState[posB] ^ internalState[posC], 63); // replaces 11 of BLAKE
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/seed/WorldgenCryptoRandom.java b/src/main/java/space/bxteam/divinemc/seed/WorldgenCryptoRandom.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f6e69a105c8267c1cf85e77e406ec9fc634a8dd6
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/space/bxteam/divinemc/seed/WorldgenCryptoRandom.java
|
||||
@@ -0,0 +1,159 @@
|
||||
+package space.bxteam.divinemc.seed;
|
||||
+
|
||||
+import net.minecraft.util.Mth;
|
||||
+import net.minecraft.util.RandomSource;
|
||||
+import net.minecraft.world.level.levelgen.LegacyRandomSource;
|
||||
+import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+import java.util.Arrays;
|
||||
+
|
||||
+public class WorldgenCryptoRandom extends WorldgenRandom {
|
||||
+ // hash the world seed to guard against badly chosen world seeds
|
||||
+ private static final long[] HASHED_ZERO_SEED = Hashing.hashWorldSeed(new long[Globals.WORLD_SEED_LONGS]);
|
||||
+ private static final ThreadLocal<long[]> LAST_SEEN_WORLD_SEED = ThreadLocal.withInitial(() -> new long[Globals.WORLD_SEED_LONGS]);
|
||||
+ private static final ThreadLocal<long[]> HASHED_WORLD_SEED = ThreadLocal.withInitial(() -> HASHED_ZERO_SEED);
|
||||
+
|
||||
+ private final long[] worldSeed = new long[Globals.WORLD_SEED_LONGS];
|
||||
+ private final long[] randomBits = new long[8];
|
||||
+ private int randomBitIndex;
|
||||
+ private static final int MAX_RANDOM_BIT_INDEX = 64 * 8;
|
||||
+ private static final int LOG2_MAX_RANDOM_BIT_INDEX = 9;
|
||||
+ private long counter;
|
||||
+ private final long[] message = new long[16];
|
||||
+ private final long[] cachedInternalState = new long[16];
|
||||
+
|
||||
+ public WorldgenCryptoRandom(int x, int z, Globals.Salt typeSalt, long salt) {
|
||||
+ super(new LegacyRandomSource(0L));
|
||||
+ if (typeSalt != null) {
|
||||
+ this.setSecureSeed(x, z, typeSalt, salt);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public void setSecureSeed(int x, int z, Globals.Salt typeSalt, long salt) {
|
||||
+ System.arraycopy(Globals.worldSeed, 0, this.worldSeed, 0, Globals.WORLD_SEED_LONGS);
|
||||
+ message[0] = ((long) x << 32) | ((long) z & 0xffffffffL);
|
||||
+ message[1] = ((long) Globals.dimension.get() << 32) | ((long) salt & 0xffffffffL);
|
||||
+ message[2] = typeSalt.ordinal();
|
||||
+ message[3] = counter = 0;
|
||||
+ randomBitIndex = MAX_RANDOM_BIT_INDEX;
|
||||
+ }
|
||||
+
|
||||
+ private long[] getHashedWorldSeed() {
|
||||
+ if (!Arrays.equals(worldSeed, LAST_SEEN_WORLD_SEED.get())) {
|
||||
+ HASHED_WORLD_SEED.set(Hashing.hashWorldSeed(worldSeed));
|
||||
+ System.arraycopy(worldSeed, 0, LAST_SEEN_WORLD_SEED.get(), 0, Globals.WORLD_SEED_LONGS);
|
||||
+ }
|
||||
+ return HASHED_WORLD_SEED.get();
|
||||
+ }
|
||||
+
|
||||
+ private void moreRandomBits() {
|
||||
+ message[3] = counter++;
|
||||
+ System.arraycopy(getHashedWorldSeed(), 0, randomBits, 0, 8);
|
||||
+ Hashing.hash(message, randomBits, cachedInternalState, 64, true);
|
||||
+ }
|
||||
+
|
||||
+ private long getBits(int count) {
|
||||
+ if (randomBitIndex >= MAX_RANDOM_BIT_INDEX) {
|
||||
+ moreRandomBits();
|
||||
+ randomBitIndex -= MAX_RANDOM_BIT_INDEX;
|
||||
+ }
|
||||
+
|
||||
+ int alignment = randomBitIndex & 63;
|
||||
+ if ((randomBitIndex >>> 6) == ((randomBitIndex + count) >>> 6)) {
|
||||
+ long result = (randomBits[randomBitIndex >>> 6] >>> alignment) & ((1L << count) - 1);
|
||||
+ randomBitIndex += count;
|
||||
+ return result;
|
||||
+ } else {
|
||||
+ long result = (randomBits[randomBitIndex >>> 6] >>> alignment) & ((1L << (64 - alignment)) - 1);
|
||||
+ randomBitIndex += count;
|
||||
+ if (randomBitIndex >= MAX_RANDOM_BIT_INDEX) {
|
||||
+ moreRandomBits();
|
||||
+ randomBitIndex -= MAX_RANDOM_BIT_INDEX;
|
||||
+ }
|
||||
+ alignment = randomBitIndex & 63;
|
||||
+ result <<= alignment;
|
||||
+ result |= (randomBits[randomBitIndex >>> 6] >>> (64 - alignment)) & ((1L << alignment) - 1);
|
||||
+
|
||||
+ return result;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull RandomSource fork() {
|
||||
+ WorldgenCryptoRandom fork = new WorldgenCryptoRandom(0, 0, null, 0);
|
||||
+
|
||||
+ System.arraycopy(Globals.worldSeed, 0, fork.worldSeed, 0, Globals.WORLD_SEED_LONGS);
|
||||
+ fork.message[0] = this.message[0];
|
||||
+ fork.message[1] = this.message[1];
|
||||
+ fork.message[2] = this.message[2];
|
||||
+ fork.message[3] = this.message[3];
|
||||
+ fork.randomBitIndex = this.randomBitIndex;
|
||||
+ fork.counter = this.counter;
|
||||
+ fork.nextLong();
|
||||
+
|
||||
+ return fork;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int next(int bits) {
|
||||
+ return (int) getBits(bits);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void consumeCount(int count) {
|
||||
+ randomBitIndex += count;
|
||||
+ if (randomBitIndex >= MAX_RANDOM_BIT_INDEX * 2) {
|
||||
+ randomBitIndex -= MAX_RANDOM_BIT_INDEX;
|
||||
+ counter += randomBitIndex >>> LOG2_MAX_RANDOM_BIT_INDEX;
|
||||
+ randomBitIndex &= MAX_RANDOM_BIT_INDEX - 1;
|
||||
+ randomBitIndex += MAX_RANDOM_BIT_INDEX;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int nextInt(int bound) {
|
||||
+ int bits = Mth.ceillog2(bound);
|
||||
+ int result;
|
||||
+ do {
|
||||
+ result = (int) getBits(bits);
|
||||
+ } while (result >= bound);
|
||||
+
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public long nextLong() {
|
||||
+ return getBits(64);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public double nextDouble() {
|
||||
+ return getBits(53) * 0x1.0p-53;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public long setDecorationSeed(long worldSeed, int blockX, int blockZ) {
|
||||
+ setSecureSeed(blockX, blockZ, Globals.Salt.POPULATION, 0);
|
||||
+ return ((long) blockX << 32) | ((long) blockZ & 0xffffffffL);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setFeatureSeed(long populationSeed, int index, int step) {
|
||||
+ setSecureSeed((int) (populationSeed >> 32), (int) populationSeed, Globals.Salt.DECORATION, index + 10000L * step);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLargeFeatureSeed(long worldSeed, int chunkX, int chunkZ) {
|
||||
+ super.setLargeFeatureSeed(worldSeed, chunkX, chunkZ);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLargeFeatureWithSalt(long worldSeed, int regionX, int regionZ, int salt) {
|
||||
+ super.setLargeFeatureWithSalt(worldSeed, regionX, regionZ, salt);
|
||||
+ }
|
||||
+
|
||||
+ public static RandomSource seedSlimeChunk(int chunkX, int chunkZ) {
|
||||
+ return new WorldgenCryptoRandom(chunkX, chunkZ, Globals.Salt.SLIME_CHUNK, 0);
|
||||
+ }
|
||||
+}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,544 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Mon, 16 Dec 2024 20:43:11 +0300
|
||||
Subject: [PATCH] Multithreaded Tracker
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
|
||||
index 2219edf3e56a2eade1049f448360247f48e3c52a..6f50be80a88504d0948ce9635eadfee9a208ae82 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
|
||||
@@ -42,6 +42,12 @@ class PaperEventManager {
|
||||
if (event.isAsynchronous() && this.server.isPrimaryThread()) {
|
||||
throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously.");
|
||||
} else if (!event.isAsynchronous() && !this.server.isPrimaryThread() && !this.server.isStopping()) {
|
||||
+ // DivineMC start - Multithreaded tracker
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled) {
|
||||
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(event::callEvent);
|
||||
+ return;
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously.");
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 7ef101bdb4e9b37bd2e73247ef916769789de2ea..9d344cc8b50a70efdd325a7b7fd8768f73285f58 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -243,9 +243,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
return;
|
||||
}
|
||||
final ServerPlayer[] backingSet = inRange.getRawDataUnchecked();
|
||||
- for (int i = 0, len = inRange.size(); i < len; i++) {
|
||||
- ++(backingSet[i].mobCounts[index]);
|
||||
+ // DivineMC start - Multithreaded tracker
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled) {
|
||||
+ for (int i = 0, len = inRange.size(); i < len; i++) {
|
||||
+ final ServerPlayer player = backingSet[i];
|
||||
+ if (player == null) continue;
|
||||
+ ++(player.mobCounts[index]);
|
||||
+ }
|
||||
+ } else {
|
||||
+ for (int i = 0, len = inRange.size(); i < len; i++) {
|
||||
+ ++(backingSet[i].mobCounts[index]);
|
||||
+ }
|
||||
}
|
||||
+ // DivineMC end
|
||||
}
|
||||
// Paper start - per player mob count backoff
|
||||
public void updateFailurePlayerMobTypeMap(int chunkX, int chunkZ, net.minecraft.world.entity.MobCategory mobCategory) {
|
||||
@@ -956,6 +966,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$setTrackedEntity(null); // Paper - optimise entity tracker
|
||||
}
|
||||
|
||||
+ // DivineMC start - Multithreaded tracker
|
||||
+ private final java.util.concurrent.ConcurrentLinkedQueue<Runnable> trackerMainThreadTasks = new java.util.concurrent.ConcurrentLinkedQueue<>();
|
||||
+ private boolean tracking = false;
|
||||
+
|
||||
+ public void runOnTrackerMainThread(final Runnable runnable) {
|
||||
+ //final boolean isOnMain = ca.spottedleaf.moonrise.common.util.TickThread.isTickThread();
|
||||
+ //System.out.println(isOnMain);
|
||||
+ if (false && this.tracking) { // TODO: check here
|
||||
+ this.trackerMainThreadTasks.add(runnable);
|
||||
+ } else {
|
||||
+ runnable.run();
|
||||
+ }
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
+
|
||||
// Paper start - optimise entity tracker
|
||||
private void newTrackerTick() {
|
||||
final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup entityLookup = (ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup)((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getEntityLookup();;
|
||||
@@ -978,6 +1003,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
// Paper end - optimise entity tracker
|
||||
|
||||
protected void tick() {
|
||||
+ // DivineMC start - Multithreaded tracker
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled) {
|
||||
+ final ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel level = this.level;
|
||||
+ space.bxteam.divinemc.tracker.MultithreadedTracker.tick(level);
|
||||
+ return;
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
// Paper start - optimise entity tracker
|
||||
if (true) {
|
||||
this.newTrackerTick();
|
||||
@@ -1127,7 +1159,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
final Entity entity;
|
||||
private final int range;
|
||||
SectionPos lastSectionPos;
|
||||
- public final Set<ServerPlayerConnection> seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl
|
||||
+ public final Set<ServerPlayerConnection> seenBy = space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled
|
||||
+ ? Sets.newConcurrentHashSet()
|
||||
+ : new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl // DivineMC - Multithreaded tracker
|
||||
|
||||
// Paper start - optimise entity tracker
|
||||
private long lastChunkUpdate = -1L;
|
||||
@@ -1154,21 +1188,55 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
this.lastTrackedChunk = chunk;
|
||||
|
||||
final ServerPlayer[] playersRaw = players.getRawDataUnchecked();
|
||||
+ final int playersLen = players.size(); // Ensure length won't change in the future tasks
|
||||
+
|
||||
+ // DivineMC start - Multithreaded tracker
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled && space.bxteam.divinemc.configuration.DivineConfig.multithreadedCompatModeEnabled) {
|
||||
+ final boolean isServerPlayer = this.entity instanceof ServerPlayer;
|
||||
+ final boolean isRealPlayer = isServerPlayer && ((ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer) this.entity).moonrise$isRealPlayer();
|
||||
+ Runnable updatePlayerTasks = () -> {
|
||||
+ for (int i = 0; i < playersLen; ++i) {
|
||||
+ final ServerPlayer player = playersRaw[i];
|
||||
+ this.updatePlayer(player);
|
||||
+ }
|
||||
|
||||
- for (int i = 0, len = players.size(); i < len; ++i) {
|
||||
- final ServerPlayer player = playersRaw[i];
|
||||
- this.updatePlayer(player);
|
||||
- }
|
||||
+ if (lastChunkUpdate != currChunkUpdate || lastTrackedChunk != chunk) {
|
||||
+ // need to purge any players possible not in the chunk list
|
||||
+ for (final ServerPlayerConnection conn : new java.util.ArrayList<>(this.seenBy)) {
|
||||
+ final ServerPlayer player = conn.getPlayer();
|
||||
+ if (!players.contains(player)) {
|
||||
+ this.removePlayer(player);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ // Only update asynchronously for real player, and sync update for fake players
|
||||
+ // This can fix compatibility issue with NPC plugins using real entity type, like Citizens
|
||||
+ // To prevent visible issue with player type NPCs
|
||||
+ // btw, still recommend to use packet based NPC plugins, like ZNPC Plus, Adyeshach, Fancy NPC, etc.
|
||||
+ if (isRealPlayer || !isServerPlayer) {
|
||||
+ space.bxteam.divinemc.tracker.MultithreadedTracker.getTrackerExecutor().execute(updatePlayerTasks);
|
||||
+ } else {
|
||||
+ updatePlayerTasks.run();
|
||||
+ }
|
||||
+ } else {
|
||||
+ for (int i = 0, len = players.size(); i < len; ++i) {
|
||||
+ final ServerPlayer player = playersRaw[i];
|
||||
+ this.updatePlayer(player);
|
||||
+ }
|
||||
|
||||
- if (lastChunkUpdate != currChunkUpdate || lastTrackedChunk != chunk) {
|
||||
- // need to purge any players possible not in the chunk list
|
||||
- for (final ServerPlayerConnection conn : new java.util.ArrayList<>(this.seenBy)) {
|
||||
- final ServerPlayer player = conn.getPlayer();
|
||||
- if (!players.contains(player)) {
|
||||
- this.removePlayer(player);
|
||||
+ if (lastChunkUpdate != currChunkUpdate || lastTrackedChunk != chunk) {
|
||||
+ // need to purge any players possible not in the chunk list
|
||||
+ for (final ServerPlayerConnection conn : new java.util.ArrayList<>(this.seenBy)) {
|
||||
+ final ServerPlayer player = conn.getPlayer();
|
||||
+ if (!players.contains(player)) {
|
||||
+ this.removePlayer(player);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1228,14 +1296,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
public void broadcast(Packet<?> packet) {
|
||||
- Iterator iterator = this.seenBy.iterator();
|
||||
-
|
||||
- while (iterator.hasNext()) {
|
||||
- ServerPlayerConnection serverplayerconnection = (ServerPlayerConnection) iterator.next();
|
||||
-
|
||||
+ // DivineMC start - Multithreaded tracker
|
||||
+ for (ServerPlayerConnection serverplayerconnection : this.seenBy.toArray(new ServerPlayerConnection[0])) {
|
||||
serverplayerconnection.send(packet);
|
||||
}
|
||||
-
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
public void broadcastAndSend(Packet<?> packet) {
|
||||
@@ -1247,18 +1312,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
public void broadcastRemoved() {
|
||||
- Iterator iterator = this.seenBy.iterator();
|
||||
-
|
||||
- while (iterator.hasNext()) {
|
||||
- ServerPlayerConnection serverplayerconnection = (ServerPlayerConnection) iterator.next();
|
||||
-
|
||||
+ // DivineMC start - Multithreaded tracker
|
||||
+ for (ServerPlayerConnection serverplayerconnection : this.seenBy.toArray(new ServerPlayerConnection[0])) {
|
||||
this.serverEntity.removePairing(serverplayerconnection.getPlayer());
|
||||
}
|
||||
-
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
public void removePlayer(ServerPlayer player) {
|
||||
- org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot
|
||||
+ //org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot // DivineMC - Multithreaded tracker - we don't need this
|
||||
if (this.seenBy.remove(player.connection)) {
|
||||
this.serverEntity.removePairing(player);
|
||||
}
|
||||
@@ -1266,8 +1328,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
public void updatePlayer(ServerPlayer player) {
|
||||
- org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
|
||||
+ //org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot // DivineMC - Multithreaded tracker - we don't need this
|
||||
if (player != this.entity) {
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled && player == null) return; // DivineMC - Multithreaded tracker
|
||||
// Paper start - remove allocation of Vec3D here
|
||||
// Vec3 vec3d = player.position().subtract(this.entity.position());
|
||||
double vec3d_dx = player.getX() - this.entity.getX();
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerBossEvent.java b/src/main/java/net/minecraft/server/level/ServerBossEvent.java
|
||||
index 4f91107f9ae42f96c060c310596db9aa869a8dbc..39dada67dd2ed13f7f191e42c366f4a96767f275 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerBossEvent.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerBossEvent.java
|
||||
@@ -13,7 +13,9 @@ import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.BossEvent;
|
||||
|
||||
public class ServerBossEvent extends BossEvent {
|
||||
- private final Set<ServerPlayer> players = Sets.newHashSet();
|
||||
+ private final Set<ServerPlayer> players = space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled
|
||||
+ ? Sets.newConcurrentHashSet()
|
||||
+ : Sets.newHashSet(); // DivineMC - Multithreaded tracker - players can be removed in async tracking
|
||||
private final Set<ServerPlayer> unmodifiablePlayers = Collections.unmodifiableSet(this.players);
|
||||
public boolean visible = true;
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
index 944de5ff109b15b76b69326e69b6b1c2afb63dd1..415fe9e2bf9a110021edbdc39e4498ccc8366636 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -119,7 +119,13 @@ public class ServerEntity {
|
||||
this.broadcastAndSend(new ClientboundSetPassengersPacket(this.entity)); // CraftBukkit
|
||||
ServerEntity.removedPassengers(list, this.lastPassengers).forEach((entity) -> {
|
||||
if (entity instanceof ServerPlayer entityplayer) {
|
||||
- entityplayer.connection.teleport(entityplayer.getX(), entityplayer.getY(), entityplayer.getZ(), entityplayer.getYRot(), entityplayer.getXRot());
|
||||
+ // DivineMC start - Multithreaded tracker - Ensure teleport is executed on server thread
|
||||
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled && Thread.currentThread() instanceof space.bxteam.divinemc.tracker.MultithreadedTracker.MultithreadedTrackerThread) {
|
||||
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> entityplayer.connection.teleport(entityplayer.getX(), entityplayer.getY(), entityplayer.getZ(), entityplayer.getYRot(), entityplayer.getXRot()));
|
||||
+ } else {
|
||||
+ entityplayer.connection.teleport(entityplayer.getX(), entityplayer.getY(), entityplayer.getZ(), entityplayer.getYRot(), entityplayer.getXRot());
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
});
|
||||
@@ -336,7 +342,11 @@ public class ServerEntity {
|
||||
|
||||
public void removePairing(ServerPlayer player) {
|
||||
this.entity.stopSeenByPlayer(player);
|
||||
- player.connection.send(new ClientboundRemoveEntitiesPacket(new int[]{this.entity.getId()}));
|
||||
+ // DivineMC start - Multithreaded tracker - send in main thread
|
||||
+ ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() ->
|
||||
+ player.connection.send(new ClientboundRemoveEntitiesPacket(this.entity.getId()))
|
||||
+ );
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
public void addPairing(ServerPlayer player) {
|
||||
@@ -344,7 +354,11 @@ public class ServerEntity {
|
||||
|
||||
Objects.requireNonNull(list);
|
||||
this.sendPairingData(player, list::add);
|
||||
- player.connection.send(new ClientboundBundlePacket(list));
|
||||
+ // DivineMC start - Multithreaded tracker - send in main thread
|
||||
+ ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() ->
|
||||
+ player.connection.send(new ClientboundBundlePacket(list))
|
||||
+ );
|
||||
+ // DivineMC end
|
||||
this.entity.startSeenByPlayer(player);
|
||||
}
|
||||
|
||||
@@ -451,7 +465,10 @@ public class ServerEntity {
|
||||
|
||||
if (list != null) {
|
||||
this.trackedDataValues = datawatcher.getNonDefaultValues();
|
||||
- this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), list));
|
||||
+ // DivineMC start - Multithreaded tracker - send in main thread
|
||||
+ ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() ->
|
||||
+ this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), list))
|
||||
+ );
|
||||
}
|
||||
|
||||
if (this.entity instanceof LivingEntity) {
|
||||
@@ -461,12 +478,16 @@ public class ServerEntity {
|
||||
// DivineMC end
|
||||
|
||||
if (!set.isEmpty()) {
|
||||
+ final Set<AttributeInstance> copy = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(set);
|
||||
+ ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() -> {
|
||||
// CraftBukkit start - Send scaled max health
|
||||
if (this.entity instanceof ServerPlayer) {
|
||||
- ((ServerPlayer) this.entity).getBukkitEntity().injectScaledMaxHealth(set, false);
|
||||
+ ((ServerPlayer) this.entity).getBukkitEntity().injectScaledMaxHealth(copy, false);
|
||||
}
|
||||
// CraftBukkit end
|
||||
- this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), set));
|
||||
+ this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), copy));
|
||||
+ });
|
||||
+ // DivineMC end
|
||||
}
|
||||
|
||||
attributes.clear(); // DivineMC
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index b0095c0848ca0162944961a24c7b807fb5846b06..8b812d1ec336fa30cd779d5ebb02b5811c97d369 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -2604,7 +2604,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
|
||||
@Override
|
||||
public LevelEntityGetter<Entity> getEntities() {
|
||||
- org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot
|
||||
+ //org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot // DivineMC - Multithreaded tracker
|
||||
return this.moonrise$getEntityLookup(); // Paper - rewrite chunk system
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index ac1d8c5eb616d11fc1bda929a8607daf2d616b46..40e2da69d6907bf664ef37fe8dbe0951b03d3aec 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -1888,7 +1888,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
}
|
||||
|
||||
public void internalTeleport(PositionMoveRotation positionmoverotation, Set<Relative> set) {
|
||||
- org.spigotmc.AsyncCatcher.catchOp("teleport"); // Paper
|
||||
+ //org.spigotmc.AsyncCatcher.catchOp("teleport"); // Paper // DivineMC - Multithreaded tracker
|
||||
// Paper start - Prevent teleporting dead entities
|
||||
if (player.isRemoved()) {
|
||||
LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName());
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeInstance.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
|
||||
index 27a7852a5d3f8c8960f098646ff5587c50556aa5..ac9534203a256b2a5c1d94e4b3996990e8861aca 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
|
||||
@@ -24,8 +24,11 @@ public class AttributeInstance {
|
||||
private final Map<AttributeModifier.Operation, Map<ResourceLocation, AttributeModifier>> modifiersByOperation = Maps.newEnumMap(
|
||||
AttributeModifier.Operation.class
|
||||
);
|
||||
- private final Map<ResourceLocation, AttributeModifier> modifierById = new Object2ObjectArrayMap<>();
|
||||
- private final Map<ResourceLocation, AttributeModifier> permanentModifiers = new Object2ObjectArrayMap<>();
|
||||
+ // DivineMC start - Multithreaded tracker
|
||||
+ private final boolean multiThreadedTrackingEnabled = space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled;
|
||||
+ private final Map<ResourceLocation, AttributeModifier> modifierById = multiThreadedTrackingEnabled ? new java.util.concurrent.ConcurrentHashMap<>() : new Object2ObjectArrayMap<>();
|
||||
+ private final Map<ResourceLocation, AttributeModifier> permanentModifiers = multiThreadedTrackingEnabled ? new java.util.concurrent.ConcurrentHashMap<>() : new Object2ObjectArrayMap<>();
|
||||
+ // DivineMC end
|
||||
private double baseValue;
|
||||
private boolean dirty = true;
|
||||
private double cachedValue;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
index 98fa43c8a34650795a0ae1ebc28ce17ec1ba5271..3b27e866185f6dcd1c7baaa3fdef591f1a0bdac3 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
@@ -19,9 +19,12 @@ import org.slf4j.Logger;
|
||||
|
||||
public class AttributeMap {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
- private final Map<Holder<Attribute>, AttributeInstance> attributes = new Object2ObjectOpenHashMap<>();
|
||||
- private final Set<AttributeInstance> attributesToSync = new ObjectOpenHashSet<>();
|
||||
- private final Set<AttributeInstance> attributesToUpdate = new ObjectOpenHashSet<>();
|
||||
+ // DivineMC start - Multithreaded tracker
|
||||
+ private final boolean multiThreadedTrackingEnabled = space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled;
|
||||
+ private final Map<Holder<Attribute>, AttributeInstance> attributes = multiThreadedTrackingEnabled ? new java.util.concurrent.ConcurrentHashMap<>() : new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(0);
|
||||
+ private final Set<AttributeInstance> attributesToSync = multiThreadedTrackingEnabled ? com.google.common.collect.Sets.newConcurrentHashSet() : new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0);
|
||||
+ private final Set<AttributeInstance> attributesToUpdate = multiThreadedTrackingEnabled ? com.google.common.collect.Sets.newConcurrentHashSet() : new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0);
|
||||
+ // DivineMC end
|
||||
private final AttributeSupplier supplier;
|
||||
private final java.util.function.Function<Holder<Attribute>, AttributeInstance> createInstance; // Pufferfish
|
||||
private final net.minecraft.world.entity.LivingEntity entity; // Purpur - Ridables
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
index ed44eaad59afa76d8ca8ac74d0cee4fb681dfe83..fe9bff9d542d731aede4903e807acd876b0286d0 100644
|
||||
--- a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
+++ b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
@@ -196,4 +196,25 @@ public class DivineConfig {
|
||||
else
|
||||
Bukkit.getLogger().log(Level.INFO, "Using " + asyncPathfindingMaxThreads + " threads for Async Pathfinding");
|
||||
}
|
||||
+
|
||||
+ public static boolean multithreadedEnabled = false;
|
||||
+ public static boolean multithreadedCompatModeEnabled = false;
|
||||
+ public static int asyncEntityTrackerMaxThreads = 0;
|
||||
+ public static int asyncEntityTrackerKeepalive = 60;
|
||||
+ private static void multithreadedTracker() {
|
||||
+ multithreadedEnabled = getBoolean("settings.multithreaded-tracker.enable", multithreadedEnabled);
|
||||
+ multithreadedCompatModeEnabled = getBoolean("settings.multithreaded-tracker.compat-mode", multithreadedCompatModeEnabled);
|
||||
+ asyncEntityTrackerMaxThreads = getInt("settings.multithreaded-tracker.max-threads", asyncEntityTrackerMaxThreads);
|
||||
+ asyncEntityTrackerKeepalive = getInt("settings.multithreaded-tracker.keepalive", asyncEntityTrackerKeepalive);
|
||||
+
|
||||
+ if (asyncEntityTrackerMaxThreads < 0)
|
||||
+ asyncEntityTrackerMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() + asyncEntityTrackerMaxThreads, 1);
|
||||
+ else if (asyncEntityTrackerMaxThreads == 0)
|
||||
+ asyncEntityTrackerMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() / 4, 1);
|
||||
+
|
||||
+ if (!multithreadedEnabled)
|
||||
+ asyncEntityTrackerMaxThreads = 0;
|
||||
+ else
|
||||
+ Bukkit.getLogger().log(Level.INFO, "Using " + asyncEntityTrackerMaxThreads + " threads for Async Entity Tracker");
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/tracker/MultithreadedTracker.java b/src/main/java/space/bxteam/divinemc/tracker/MultithreadedTracker.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..3621d8641eb657d84b886589bc957bdf8798785a
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/space/bxteam/divinemc/tracker/MultithreadedTracker.java
|
||||
@@ -0,0 +1,139 @@
|
||||
+package space.bxteam.divinemc.tracker;
|
||||
+
|
||||
+import ca.spottedleaf.moonrise.common.list.ReferenceList;
|
||||
+import ca.spottedleaf.moonrise.common.misc.NearbyPlayers;
|
||||
+import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel;
|
||||
+import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup;
|
||||
+import ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity;
|
||||
+import ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity;
|
||||
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
+import net.minecraft.server.level.ChunkMap;
|
||||
+import net.minecraft.server.level.FullChunkStatus;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.world.entity.Entity;
|
||||
+import org.apache.logging.log4j.LogManager;
|
||||
+import org.apache.logging.log4j.Logger;
|
||||
+
|
||||
+import java.util.concurrent.Executor;
|
||||
+import java.util.concurrent.LinkedBlockingQueue;
|
||||
+import java.util.concurrent.ThreadPoolExecutor;
|
||||
+import java.util.concurrent.TimeUnit;
|
||||
+
|
||||
+public class MultithreadedTracker {
|
||||
+ private static final Logger LOGGER = LogManager.getLogger("MultithreadedTracker");
|
||||
+ public static class MultithreadedTrackerThread extends Thread {
|
||||
+ @Override
|
||||
+ public void run() {
|
||||
+ super.run();
|
||||
+ }
|
||||
+ }
|
||||
+ private static final Executor trackerExecutor = new ThreadPoolExecutor(
|
||||
+ 1,
|
||||
+ space.bxteam.divinemc.configuration.DivineConfig.asyncEntityTrackerMaxThreads,
|
||||
+ space.bxteam.divinemc.configuration.DivineConfig.asyncEntityTrackerKeepalive, TimeUnit.SECONDS,
|
||||
+ new LinkedBlockingQueue<>(),
|
||||
+ new ThreadFactoryBuilder()
|
||||
+ .setThreadFactory(
|
||||
+ r -> new MultithreadedTrackerThread() {
|
||||
+ @Override
|
||||
+ public void run() {
|
||||
+ r.run();
|
||||
+ }
|
||||
+ }
|
||||
+ )
|
||||
+ .setNameFormat("DivineMC Async Tracker Thread - %d")
|
||||
+ .setPriority(Thread.NORM_PRIORITY - 2)
|
||||
+ .build());
|
||||
+
|
||||
+ private MultithreadedTracker() {
|
||||
+ }
|
||||
+
|
||||
+ public static Executor getTrackerExecutor() {
|
||||
+ return trackerExecutor;
|
||||
+ }
|
||||
+
|
||||
+ public static void tick(ChunkSystemServerLevel level) {
|
||||
+ try {
|
||||
+ if (!space.bxteam.divinemc.configuration.DivineConfig.multithreadedCompatModeEnabled) {
|
||||
+ tickAsync(level);
|
||||
+ } else {
|
||||
+ tickAsyncWithCompatMode(level);
|
||||
+ }
|
||||
+ } catch (Exception e) {
|
||||
+ LOGGER.error("Error occurred while executing async task.", e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void tickAsync(ChunkSystemServerLevel level) {
|
||||
+ final NearbyPlayers nearbyPlayers = level.moonrise$getNearbyPlayers();
|
||||
+ final ServerEntityLookup entityLookup = (ServerEntityLookup) level.moonrise$getEntityLookup();
|
||||
+
|
||||
+ final ReferenceList<Entity> trackerEntities = entityLookup.trackerEntities;
|
||||
+ final Entity[] trackerEntitiesRaw = trackerEntities.getRawDataUnchecked();
|
||||
+
|
||||
+ // Move tracking to off-main
|
||||
+ trackerExecutor.execute(() -> {
|
||||
+ for (final Entity entity : trackerEntitiesRaw) {
|
||||
+ if (entity == null) continue;
|
||||
+
|
||||
+ final ChunkMap.TrackedEntity tracker = ((EntityTrackerEntity) entity).moonrise$getTrackedEntity();
|
||||
+
|
||||
+ if (tracker == null) continue;
|
||||
+
|
||||
+ ((EntityTrackerTrackedEntity) tracker).moonrise$tick(nearbyPlayers.getChunk(entity.chunkPosition()));
|
||||
+ tracker.serverEntity.sendChanges();
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ private static void tickAsyncWithCompatMode(ChunkSystemServerLevel level) {
|
||||
+ final NearbyPlayers nearbyPlayers = level.moonrise$getNearbyPlayers();
|
||||
+ final ServerEntityLookup entityLookup = (ServerEntityLookup) level.moonrise$getEntityLookup();
|
||||
+
|
||||
+ final ReferenceList<Entity> trackerEntities = entityLookup.trackerEntities;
|
||||
+ final Entity[] trackerEntitiesRaw = trackerEntities.getRawDataUnchecked();
|
||||
+ final Runnable[] sendChangesTasks = new Runnable[trackerEntitiesRaw.length];
|
||||
+ int index = 0;
|
||||
+
|
||||
+ for (final Entity entity : trackerEntitiesRaw) {
|
||||
+ if (entity == null) continue;
|
||||
+
|
||||
+ final ChunkMap.TrackedEntity tracker = ((EntityTrackerEntity) entity).moonrise$getTrackedEntity();
|
||||
+
|
||||
+ if (tracker == null) continue;
|
||||
+
|
||||
+ ((EntityTrackerTrackedEntity) tracker).moonrise$tick(nearbyPlayers.getChunk(entity.chunkPosition()));
|
||||
+ sendChangesTasks[index++] = () -> tracker.serverEntity.sendChanges(); // Collect send changes to task array
|
||||
+ }
|
||||
+
|
||||
+ // batch submit tasks
|
||||
+ trackerExecutor.execute(() -> {
|
||||
+ for (final Runnable sendChanges : sendChangesTasks) {
|
||||
+ if (sendChanges == null) continue;
|
||||
+
|
||||
+ sendChanges.run();
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ // Original ChunkMap#newTrackerTick of Paper
|
||||
+ // Just for diff usage for future update
|
||||
+ private static void tickOriginal(ServerLevel level) {
|
||||
+ final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup entityLookup = (ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup) ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel) level).moonrise$getEntityLookup();
|
||||
+
|
||||
+ final ca.spottedleaf.moonrise.common.list.ReferenceList<net.minecraft.world.entity.Entity> trackerEntities = entityLookup.trackerEntities;
|
||||
+ final Entity[] trackerEntitiesRaw = trackerEntities.getRawDataUnchecked();
|
||||
+ for (int i = 0, len = trackerEntities.size(); i < len; ++i) {
|
||||
+ final Entity entity = trackerEntitiesRaw[i];
|
||||
+ final ChunkMap.TrackedEntity tracker = ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity) entity).moonrise$getTrackedEntity();
|
||||
+ if (tracker == null) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity) tracker).moonrise$tick(((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity) entity).moonrise$getChunkData().nearbyPlayers);
|
||||
+ if (((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity) tracker).moonrise$hasPlayers()
|
||||
+ || ((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity) entity).moonrise$getChunkStatus().isOrAfter(FullChunkStatus.ENTITY_TICKING)) {
|
||||
+ tracker.serverEntity.sendChanges();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
@@ -1,858 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||
Date: Wed, 10 Jul 2024 02:40:08 +0300
|
||||
Subject: [PATCH] Implement Linear region format
|
||||
|
||||
Status: may be replaced with SlimeWorldManager soon
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index 3e2a092c797ec7918f5c4b838f28b0778c70531c..bb44922202e3cdb705a4773ea7c9ec807b5f3de2 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -30,6 +30,10 @@ dependencies {
|
||||
alsoShade(log4jPlugins.output)
|
||||
implementation("io.netty:netty-codec-haproxy:4.1.97.Final") // Paper - Add support for proxy protocol
|
||||
// Paper end
|
||||
+ // DivineMC start
|
||||
+ implementation("com.github.luben:zstd-jni:1.5.6-3")
|
||||
+ implementation("org.lz4:lz4-java:1.8.0")
|
||||
+ // DivineMC end
|
||||
implementation("org.apache.logging.log4j:log4j-iostreams:2.22.1") // Paper - remove exclusion
|
||||
implementation("org.ow2.asm:asm-commons:9.7.1")
|
||||
implementation("org.spongepowered:configurate-yaml:4.2.0-SNAPSHOT") // Paper - config files
|
||||
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java
|
||||
index 73df26b27146bbad2106d57b22dd3c792ed3dd1d..a4d16996fae07f943ee078ce3d2e7b22747fc2d1 100644
|
||||
--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java
|
||||
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java
|
||||
@@ -7,8 +7,8 @@ public interface ChunkSystemRegionFileStorage {
|
||||
|
||||
public boolean moonrise$doesRegionFileNotExistNoIO(final int chunkX, final int chunkZ);
|
||||
|
||||
- public RegionFile moonrise$getRegionFileIfLoaded(final int chunkX, final int chunkZ);
|
||||
+ public space.bxteam.divinemc.region.AbstractRegionFile moonrise$getRegionFileIfLoaded(final int chunkX, final int chunkZ); // DivineMC
|
||||
|
||||
- public RegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException;
|
||||
+ public space.bxteam.divinemc.region.AbstractRegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException; // DivineMC
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java
|
||||
index 3218cbf84f54daf06e84442d5eb1a36d8da6b215..0db1f8f64a261780e6692755669fa573a2c2b199 100644
|
||||
--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java
|
||||
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java
|
||||
@@ -1043,9 +1043,9 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread {
|
||||
return ((ChunkSystemRegionFileStorage)(Object)this.getCache()).moonrise$doesRegionFileNotExistNoIO(chunkX, chunkZ);
|
||||
}
|
||||
|
||||
- public <T> T computeForRegionFile(final int chunkX, final int chunkZ, final boolean existingOnly, final Function<RegionFile, T> function) {
|
||||
+ public <T> T computeForRegionFile(final int chunkX, final int chunkZ, final boolean existingOnly, final Function<space.bxteam.divinemc.region.AbstractRegionFile, T> function) { // DivineMC
|
||||
final RegionFileStorage cache = this.getCache();
|
||||
- final RegionFile regionFile;
|
||||
+ final space.bxteam.divinemc.region.AbstractRegionFile regionFile; // DivineMC
|
||||
synchronized (cache) {
|
||||
try {
|
||||
if (existingOnly) {
|
||||
@@ -1061,9 +1061,9 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread {
|
||||
}
|
||||
}
|
||||
|
||||
- public <T> T computeForRegionFileIfLoaded(final int chunkX, final int chunkZ, final Function<RegionFile, T> function) {
|
||||
+ public <T> T computeForRegionFileIfLoaded(final int chunkX, final int chunkZ, final Function<space.bxteam.divinemc.region.AbstractRegionFile, T> function) { // DivineMC
|
||||
final RegionFileStorage cache = this.getCache();
|
||||
- final RegionFile regionFile;
|
||||
+ final space.bxteam.divinemc.region.AbstractRegionFile regionFile;
|
||||
|
||||
synchronized (cache) {
|
||||
regionFile = ((ChunkSystemRegionFileStorage)(Object)cache).moonrise$getRegionFileIfLoaded(chunkX, chunkZ);
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 8658296b919fd6fa28e64a64186060d3704271db..52bdfd853cf9d42a6c58f0616faf031c8e91fed8 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -981,10 +981,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
while (iterator1.hasNext()) {
|
||||
ServerLevel worldserver2 = (ServerLevel) iterator1.next();
|
||||
|
||||
- MinecraftServer.LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", worldserver2.getChunkSource().chunkMap.getStorageName());
|
||||
+ MinecraftServer.LOGGER.info("ThreadedChunkStorage ({}): All chunks are saved", worldserver2.getChunkSource().chunkMap.getStorageName()); // DivineMC
|
||||
}
|
||||
|
||||
- MinecraftServer.LOGGER.info("ThreadedAnvilChunkStorage: All dimensions are saved");
|
||||
+ MinecraftServer.LOGGER.info("ThreadedChunkStorage: All dimensions are saved"); // DivineMC
|
||||
}
|
||||
|
||||
return flag3;
|
||||
diff --git a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
|
||||
index cb39c629af1827078f35904a373d35a63fea17ff..08a4a333ab294e95bee95376788df5229aca6598 100644
|
||||
--- a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
|
||||
+++ b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
|
||||
@@ -76,7 +76,7 @@ public class WorldUpgrader {
|
||||
volatile int skipped;
|
||||
final Reference2FloatMap<ResourceKey<Level>> progressMap = Reference2FloatMaps.synchronize(new Reference2FloatOpenHashMap());
|
||||
volatile Component status = Component.translatable("optimizeWorld.stage.counting");
|
||||
- static final Pattern REGEX = Pattern.compile("^r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.mca$");
|
||||
+ static final Pattern REGEX = Pattern.compile("^r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.(linear | mca)$"); // DivineMC
|
||||
final DimensionDataStorage overworldDataStorage;
|
||||
|
||||
public WorldUpgrader(LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, RegistryAccess dynamicRegistryManager, boolean eraseCache, boolean recreateRegionFiles) {
|
||||
@@ -400,7 +400,7 @@ public class WorldUpgrader {
|
||||
|
||||
private static List<WorldUpgrader.FileToUpgrade> getAllChunkPositions(RegionStorageInfo key, Path regionDirectory) {
|
||||
File[] afile = regionDirectory.toFile().listFiles((file, s) -> {
|
||||
- return s.endsWith(".mca");
|
||||
+ return s.endsWith(".linear") || s.endsWith(".mca"); // DivineMC
|
||||
});
|
||||
|
||||
if (afile == null) {
|
||||
@@ -420,7 +420,7 @@ public class WorldUpgrader {
|
||||
List<ChunkPos> list1 = Lists.newArrayList();
|
||||
|
||||
try {
|
||||
- RegionFile regionfile = new RegionFile(key, file.toPath(), regionDirectory, true);
|
||||
+ space.bxteam.divinemc.region.AbstractRegionFile regionfile = space.bxteam.divinemc.region.AbstractRegionFileFactory.getAbstractRegionFile(key, file.toPath(), regionDirectory, true); // DivineMC
|
||||
|
||||
try {
|
||||
for (int i1 = 0; i1 < 32; ++i1) {
|
||||
@@ -483,7 +483,7 @@ public class WorldUpgrader {
|
||||
|
||||
protected abstract boolean tryProcessOnePosition(T storage, ChunkPos chunkPos, ResourceKey<Level> worldKey);
|
||||
|
||||
- private void onFileFinished(RegionFile regionFile) {
|
||||
+ private void onFileFinished(space.bxteam.divinemc.region.AbstractRegionFile regionFile) { // DivineMC
|
||||
if (WorldUpgrader.this.recreateRegionFiles) {
|
||||
if (this.previousWriteFuture != null) {
|
||||
this.previousWriteFuture.join();
|
||||
@@ -508,7 +508,7 @@ public class WorldUpgrader {
|
||||
}
|
||||
}
|
||||
|
||||
- static record FileToUpgrade(RegionFile file, List<ChunkPos> chunksToUpgrade) {
|
||||
+ static record FileToUpgrade(space.bxteam.divinemc.region.AbstractRegionFile file, List<ChunkPos> chunksToUpgrade) { // DivineMC
|
||||
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
index 1e0439cf3f4008fa430acb90b45f5bc4cdd6d7f2..05b356177fc0f65de51f03f7ef1a2f03d85e92ff 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
@@ -28,7 +28,7 @@ import net.minecraft.nbt.NbtIo; // Paper
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
-public class RegionFile implements AutoCloseable {
|
||||
+public class RegionFile implements AutoCloseable, space.bxteam.divinemc.region.AbstractRegionFile { // DivineMC
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final int SECTOR_BYTES = 4096;
|
||||
@@ -129,7 +129,7 @@ public class RegionFile implements AutoCloseable {
|
||||
}
|
||||
|
||||
// note: only call for CHUNK regionfiles
|
||||
- boolean recalculateHeader() throws IOException {
|
||||
+ public boolean recalculateHeader() throws IOException { // DivineMC - make public
|
||||
if (!this.canRecalcHeader) {
|
||||
return false;
|
||||
}
|
||||
@@ -928,10 +928,10 @@ public class RegionFile implements AutoCloseable {
|
||||
private static int getChunkIndex(int x, int z) {
|
||||
return (x & 31) + (z & 31) * 32;
|
||||
}
|
||||
- synchronized boolean isOversized(int x, int z) {
|
||||
+ public synchronized boolean isOversized(int x, int z) { // DivineMC
|
||||
return this.oversized[getChunkIndex(x, z)] == 1;
|
||||
}
|
||||
- synchronized void setOversized(int x, int z, boolean oversized) throws IOException {
|
||||
+ public synchronized void setOversized(int x, int z, boolean oversized) throws IOException { // DivineMC
|
||||
final int offset = getChunkIndex(x, z);
|
||||
boolean previous = this.oversized[offset] == 1;
|
||||
this.oversized[offset] = (byte) (oversized ? 1 : 0);
|
||||
@@ -970,7 +970,7 @@ public class RegionFile implements AutoCloseable {
|
||||
return this.path.getParent().resolve(this.path.getFileName().toString().replaceAll("\\.mca$", "") + "_oversized_" + x + "_" + z + ".nbt");
|
||||
}
|
||||
|
||||
- synchronized CompoundTag getOversizedData(int x, int z) throws IOException {
|
||||
+ public synchronized CompoundTag getOversizedData(int x, int z) throws IOException { // DivineMC
|
||||
Path file = getOversizedFile(x, z);
|
||||
try (DataInputStream out = new DataInputStream(new java.io.BufferedInputStream(new InflaterInputStream(Files.newInputStream(file))))) {
|
||||
return NbtIo.read((java.io.DataInput) out);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
index e623bb14c44a734607e7c6365620d59a3db9f1da..f64715e4fc875dcd714e3d5e9b4d53f32b8ea2e7 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
@@ -21,7 +21,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
|
||||
public static final String ANVIL_EXTENSION = ".mca";
|
||||
private static final int MAX_CACHE_SIZE = 256;
|
||||
- public final Long2ObjectLinkedOpenHashMap<RegionFile> regionCache = new Long2ObjectLinkedOpenHashMap();
|
||||
+ public final Long2ObjectLinkedOpenHashMap<space.bxteam.divinemc.region.AbstractRegionFile> regionCache = new Long2ObjectLinkedOpenHashMap(); // DivineMC
|
||||
private final RegionStorageInfo info;
|
||||
private final Path folder;
|
||||
private final boolean sync;
|
||||
@@ -30,7 +30,9 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
private static final int REGION_SHIFT = 5;
|
||||
private static final int MAX_NON_EXISTING_CACHE = 1024 * 64;
|
||||
private final it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet nonExistingRegionFiles = new it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet(MAX_NON_EXISTING_CACHE+1);
|
||||
- private static String getRegionFileName(final int chunkX, final int chunkZ) {
|
||||
+ private static String getRegionFileName(final RegionStorageInfo info, final int chunkX, final int chunkZ) {
|
||||
+ if (info.regionFormat().equals(space.bxteam.divinemc.region.RegionFileFormat.LINEAR))
|
||||
+ return "r." + (chunkX >> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + ".linear"; // DivineMC - linear
|
||||
return "r." + (chunkX >> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + ".mca";
|
||||
}
|
||||
|
||||
@@ -66,15 +68,15 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
}
|
||||
|
||||
@Override
|
||||
- public synchronized final RegionFile moonrise$getRegionFileIfLoaded(final int chunkX, final int chunkZ) {
|
||||
+ public synchronized final space.bxteam.divinemc.region.AbstractRegionFile moonrise$getRegionFileIfLoaded(final int chunkX, final int chunkZ) { // DivineMC
|
||||
return this.regionCache.getAndMoveToFirst(ChunkPos.asLong(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
- public synchronized final RegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException {
|
||||
+ public synchronized final space.bxteam.divinemc.region.AbstractRegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException { // DivineMC
|
||||
final long key = ChunkPos.asLong(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT);
|
||||
|
||||
- RegionFile ret = this.regionCache.getAndMoveToFirst(key);
|
||||
+ space.bxteam.divinemc.region.AbstractRegionFile ret = this.regionCache.getAndMoveToFirst(key); // DivineMC
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
@@ -87,7 +89,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
this.regionCache.removeLast().close();
|
||||
}
|
||||
|
||||
- final Path regionPath = this.folder.resolve(getRegionFileName(chunkX, chunkZ));
|
||||
+ final Path regionPath = this.folder.resolve(getRegionFileName(this.info, chunkX, chunkZ)); // DivineMC
|
||||
|
||||
if (!java.nio.file.Files.exists(regionPath)) {
|
||||
this.markNonExisting(key);
|
||||
@@ -98,7 +100,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
|
||||
FileUtil.createDirectoriesSafe(this.folder);
|
||||
|
||||
- ret = new RegionFile(this.info, regionPath, this.folder, this.sync);
|
||||
+ ret = space.bxteam.divinemc.region.AbstractRegionFileFactory.getAbstractRegionFile(this.info, regionPath, this.folder, this.sync); // DivineMC
|
||||
|
||||
this.regionCache.putAndMoveToFirst(key, ret);
|
||||
|
||||
@@ -143,7 +145,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
this.isChunkData = isChunkDataFolder(this.folder); // Paper - recalculate region file headers
|
||||
}
|
||||
|
||||
- public RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit // Paper - public
|
||||
+ public space.bxteam.divinemc.region.AbstractRegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit // Paper - public // DivineMC
|
||||
// Paper start - rewrite chunk system
|
||||
if (existingOnly) {
|
||||
return this.moonrise$getRegionFileIfExists(chunkcoordintpair.x, chunkcoordintpair.z);
|
||||
@@ -151,7 +153,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
synchronized (this) {
|
||||
final long key = ChunkPos.asLong(chunkcoordintpair.x >> REGION_SHIFT, chunkcoordintpair.z >> REGION_SHIFT);
|
||||
|
||||
- RegionFile ret = this.regionCache.getAndMoveToFirst(key);
|
||||
+ space.bxteam.divinemc.region.AbstractRegionFile ret = this.regionCache.getAndMoveToFirst(key); // DivineMC
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
@@ -160,13 +162,13 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
this.regionCache.removeLast().close();
|
||||
}
|
||||
|
||||
- final Path regionPath = this.folder.resolve(getRegionFileName(chunkcoordintpair.x, chunkcoordintpair.z));
|
||||
+ final Path regionPath = this.folder.resolve(getRegionFileName(this.info, chunkcoordintpair.x, chunkcoordintpair.z)); // DivineMC
|
||||
|
||||
this.createRegionFile(key);
|
||||
|
||||
FileUtil.createDirectoriesSafe(this.folder);
|
||||
|
||||
- ret = new RegionFile(this.info, regionPath, this.folder, this.sync);
|
||||
+ ret = space.bxteam.divinemc.region.AbstractRegionFileFactory.getAbstractRegionFile(this.info, regionPath, this.folder, this.sync); // DivineMC
|
||||
|
||||
this.regionCache.putAndMoveToFirst(key, ret);
|
||||
|
||||
@@ -180,7 +182,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO DIVINEMC - You may ask for help on Discord, but do not file an issue. These error messages can not be removed."); // DivineMC
|
||||
}
|
||||
|
||||
- private static CompoundTag readOversizedChunk(RegionFile regionfile, ChunkPos chunkCoordinate) throws IOException {
|
||||
+ private static CompoundTag readOversizedChunk(space.bxteam.divinemc.region.AbstractRegionFile regionfile, ChunkPos chunkCoordinate) throws IOException { // DivineMC
|
||||
synchronized (regionfile) {
|
||||
try (DataInputStream datainputstream = regionfile.getChunkDataInputStream(chunkCoordinate)) {
|
||||
CompoundTag oversizedData = regionfile.getOversizedData(chunkCoordinate.x, chunkCoordinate.z);
|
||||
@@ -215,7 +217,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
@Nullable
|
||||
public CompoundTag read(ChunkPos pos) throws IOException {
|
||||
// CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing
|
||||
- RegionFile regionfile = this.getRegionFile(pos, true);
|
||||
+ space.bxteam.divinemc.region.AbstractRegionFile regionfile = this.getRegionFile(pos, true); // DivineMC
|
||||
if (regionfile == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -279,7 +281,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
|
||||
public void scanChunk(ChunkPos chunkPos, StreamTagVisitor scanner) throws IOException {
|
||||
// CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing
|
||||
- RegionFile regionfile = this.getRegionFile(chunkPos, true);
|
||||
+ space.bxteam.divinemc.region.AbstractRegionFile regionfile = this.getRegionFile(chunkPos, true); // DivineMC
|
||||
if (regionfile == null) {
|
||||
return;
|
||||
}
|
||||
@@ -309,7 +311,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
}
|
||||
|
||||
public void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException { // Paper - public
|
||||
- RegionFile regionfile = this.getRegionFile(pos, nbt == null); // CraftBukkit // Paper - rewrite chunk system
|
||||
+ space.bxteam.divinemc.region.AbstractRegionFile regionfile = this.getRegionFile(pos, nbt == null); // CraftBukkit // Paper - rewrite chunk system // DivineMC
|
||||
// Paper start - rewrite chunk system
|
||||
if (regionfile == null) {
|
||||
// if the RegionFile doesn't exist, no point in deleting from it
|
||||
@@ -368,7 +370,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
// Paper start - rewrite chunk system
|
||||
synchronized (this) {
|
||||
final ExceptionCollector<IOException> exceptionCollector = new ExceptionCollector<>();
|
||||
- for (final RegionFile regionFile : this.regionCache.values()) {
|
||||
+ for (final space.bxteam.divinemc.region.AbstractRegionFile regionFile : this.regionCache.values()) { // DivineMC
|
||||
try {
|
||||
regionFile.close();
|
||||
} catch (final IOException ex) {
|
||||
@@ -385,7 +387,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
// Paper start - rewrite chunk system
|
||||
synchronized (this) {
|
||||
final ExceptionCollector<IOException> exceptionCollector = new ExceptionCollector<>();
|
||||
- for (final RegionFile regionFile : this.regionCache.values()) {
|
||||
+ for (final space.bxteam.divinemc.region.AbstractRegionFile regionFile : this.regionCache.values()) { // DivineMC
|
||||
try {
|
||||
regionFile.flush();
|
||||
} catch (final IOException ex) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionStorageInfo.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionStorageInfo.java
|
||||
index 6111631c6673948b266286894603cc5e30451b02..8bfc0fe2b8389359a682458fde5ef1b0670f7a2d 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionStorageInfo.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionStorageInfo.java
|
||||
@@ -7,4 +7,20 @@ public record RegionStorageInfo(String level, ResourceKey<Level> dimension, Stri
|
||||
public RegionStorageInfo withTypeSuffix(String suffix) {
|
||||
return new RegionStorageInfo(this.level, this.dimension, this.type + suffix);
|
||||
}
|
||||
+
|
||||
+ // DivineMC start
|
||||
+ public space.bxteam.divinemc.region.RegionFileFormat regionFormat() {
|
||||
+ return ((org.bukkit.craftbukkit.CraftWorld) org.bukkit.Bukkit.getWorld(level))
|
||||
+ .getHandle()
|
||||
+ .divinemcConfig
|
||||
+ .regionFormat;
|
||||
+ }
|
||||
+
|
||||
+ public int linearCompressionLevel() {
|
||||
+ return ((org.bukkit.craftbukkit.CraftWorld) org.bukkit.Bukkit.getWorld(level))
|
||||
+ .getHandle()
|
||||
+ .divinemcConfig
|
||||
+ .linearCompressionLevel;
|
||||
+ }
|
||||
+ // DivineMC end
|
||||
}
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
index acf4a5287ba8d1ec8b4157426aa5794211654b7b..e8cbdcc5c41acfc18fa040997421fb712de801cb 100644
|
||||
--- a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
+++ b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
||||
@@ -194,4 +194,16 @@ public class DivineConfig {
|
||||
private static void chatMessageSignatures() {
|
||||
noChatSign = getBoolean("settings.no-chat-sign", noChatSign);
|
||||
}
|
||||
+
|
||||
+ public static int linearFlushFrequency = 10;
|
||||
+ public static int linearFlushThreads = 1;
|
||||
+ private static void linearSettings() {
|
||||
+ linearFlushFrequency = getInt("settings.region-format.linear.flush-frequency", linearFlushFrequency);
|
||||
+ linearFlushThreads = getInt("settings.region-format.linear.flush-max-threads", linearFlushThreads);
|
||||
+
|
||||
+ if (linearFlushThreads < 0)
|
||||
+ linearFlushThreads = Math.max(Runtime.getRuntime().availableProcessors() + linearFlushThreads, 1);
|
||||
+ else
|
||||
+ linearFlushThreads = Math.max(linearFlushThreads, 1);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfig.java
|
||||
index d94c51ea18d299dd52b9a8521a9cdc0d95b79356..f216f728dd5ca6e7b67f4f1384ce73faf9814384 100644
|
||||
--- a/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfig.java
|
||||
+++ b/src/main/java/space/bxteam/divinemc/configuration/DivineWorldConfig.java
|
||||
@@ -3,10 +3,12 @@ package space.bxteam.divinemc.configuration;
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
+import space.bxteam.divinemc.region.RegionFileFormat;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
+import java.util.logging.Level;
|
||||
|
||||
import static space.bxteam.divinemc.configuration.DivineConfig.log;
|
||||
|
||||
@@ -106,4 +108,22 @@ public class DivineWorldConfig {
|
||||
private void suppressErrorsFromDirtyAttributes() {
|
||||
suppressErrorsFromDirtyAttributes = getBoolean("suppress-errors-from-dirty-attributes", suppressErrorsFromDirtyAttributes);
|
||||
}
|
||||
+
|
||||
+ public RegionFileFormat regionFormat = RegionFileFormat.ANVIL;
|
||||
+ public int linearCompressionLevel = 1;
|
||||
+ private void regionFormatSettings() {
|
||||
+ regionFormat = RegionFileFormat.fromString(getString("region-format.format", regionFormat.name()));
|
||||
+ if (regionFormat.equals(RegionFileFormat.INVALID)) {
|
||||
+ log(Level.SEVERE, "Unknown region format in linear.yml: " + regionFormat);
|
||||
+ log(Level.SEVERE, "Falling back to ANVIL region file format.");
|
||||
+ regionFormat = RegionFileFormat.ANVIL;
|
||||
+ }
|
||||
+
|
||||
+ linearCompressionLevel = getInt("region-format.linear.compression-level", linearCompressionLevel);
|
||||
+ if (linearCompressionLevel > 23 || linearCompressionLevel < 1) {
|
||||
+ log(Level.SEVERE, "Linear region compression level should be between 1 and 22 in linear.yml: " + linearCompressionLevel);
|
||||
+ log(Level.SEVERE, "Falling back to compression level 1.");
|
||||
+ linearCompressionLevel = 1;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/region/AbstractRegionFile.java b/src/main/java/space/bxteam/divinemc/region/AbstractRegionFile.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..8bc4681e38ab29dae8173492d3430986d8baa164
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/space/bxteam/divinemc/region/AbstractRegionFile.java
|
||||
@@ -0,0 +1,26 @@
|
||||
+package space.bxteam.divinemc.region;
|
||||
+
|
||||
+import java.io.DataInputStream;
|
||||
+import java.io.DataOutputStream;
|
||||
+import java.io.IOException;
|
||||
+import java.nio.file.Path;
|
||||
+import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.world.level.ChunkPos;
|
||||
+
|
||||
+public interface AbstractRegionFile {
|
||||
+
|
||||
+ Path getPath();
|
||||
+ DataInputStream getChunkDataInputStream(ChunkPos pos) throws IOException;
|
||||
+ DataOutputStream getChunkDataOutputStream(ChunkPos pos) throws IOException;
|
||||
+ CompoundTag getOversizedData(int x, int z) throws IOException;
|
||||
+
|
||||
+ boolean hasChunk(ChunkPos pos);
|
||||
+ boolean doesChunkExist(ChunkPos pos);
|
||||
+ boolean isOversized(int x, int z);
|
||||
+ boolean recalculateHeader() throws IOException;
|
||||
+
|
||||
+ void flush() throws IOException;
|
||||
+ void close() throws IOException;
|
||||
+ void clear(ChunkPos pos) throws IOException;
|
||||
+ void setOversized(int x, int z, boolean oversized) throws IOException;
|
||||
+}
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/region/AbstractRegionFileFactory.java b/src/main/java/space/bxteam/divinemc/region/AbstractRegionFileFactory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..eb019b4863c2f812902318bdc8f3ab34ddb7aac5
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/space/bxteam/divinemc/region/AbstractRegionFileFactory.java
|
||||
@@ -0,0 +1,22 @@
|
||||
+package space.bxteam.divinemc.region;
|
||||
+
|
||||
+import java.io.IOException;
|
||||
+import java.nio.file.Path;
|
||||
+import net.minecraft.world.level.chunk.storage.RegionFile;
|
||||
+import net.minecraft.world.level.chunk.storage.RegionFileVersion;
|
||||
+import net.minecraft.world.level.chunk.storage.RegionStorageInfo;
|
||||
+
|
||||
+public class AbstractRegionFileFactory {
|
||||
+
|
||||
+ public static AbstractRegionFile getAbstractRegionFile(RegionStorageInfo storageKey, Path directory, Path path, boolean dsync) throws IOException {
|
||||
+ return getAbstractRegionFile(storageKey, directory, path, RegionFileVersion.getCompressionFormat(), dsync);
|
||||
+ }
|
||||
+
|
||||
+ public static AbstractRegionFile getAbstractRegionFile(RegionStorageInfo storageKey, Path path, Path directory, RegionFileVersion compressionFormat, boolean dsync) throws IOException {
|
||||
+ if (path.toString().endsWith(".linear")) {
|
||||
+ return new LinearRegionFile(path, storageKey.linearCompressionLevel());
|
||||
+ } else {
|
||||
+ return new RegionFile(storageKey, path, directory, compressionFormat, dsync);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/region/LinearRegionFile.java b/src/main/java/space/bxteam/divinemc/region/LinearRegionFile.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..bcb69f307a63ae6aa2b1e8bdfbb1a499ad88d402
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/space/bxteam/divinemc/region/LinearRegionFile.java
|
||||
@@ -0,0 +1,304 @@
|
||||
+package space.bxteam.divinemc.region;
|
||||
+
|
||||
+import com.github.luben.zstd.ZstdInputStream;
|
||||
+import com.github.luben.zstd.ZstdOutputStream;
|
||||
+import com.mojang.logging.LogUtils;
|
||||
+import java.io.BufferedOutputStream;
|
||||
+import java.io.ByteArrayInputStream;
|
||||
+import java.io.ByteArrayOutputStream;
|
||||
+import java.io.DataInputStream;
|
||||
+import java.io.DataOutputStream;
|
||||
+import java.io.File;
|
||||
+import java.io.FileInputStream;
|
||||
+import java.io.FileOutputStream;
|
||||
+import java.io.IOException;
|
||||
+import java.io.InputStream;
|
||||
+import java.nio.ByteBuffer;
|
||||
+import java.nio.file.Files;
|
||||
+import java.nio.file.Path;
|
||||
+import java.nio.file.StandardCopyOption;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Arrays;
|
||||
+import java.util.List;
|
||||
+import java.util.concurrent.atomic.AtomicBoolean;
|
||||
+import javax.annotation.Nullable;
|
||||
+import net.jpountz.lz4.LZ4Compressor;
|
||||
+import net.jpountz.lz4.LZ4Factory;
|
||||
+import net.jpountz.lz4.LZ4FastDecompressor;
|
||||
+import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.world.level.ChunkPos;
|
||||
+import org.slf4j.Logger;
|
||||
+
|
||||
+public class LinearRegionFile implements AbstractRegionFile, AutoCloseable {
|
||||
+
|
||||
+ private static final long SUPERBLOCK = -4323716122432332390L;
|
||||
+ private static final byte VERSION = 2;
|
||||
+ private static final int HEADER_SIZE = 32;
|
||||
+ private static final int FOOTER_SIZE = 8;
|
||||
+ private static final Logger LOGGER = LogUtils.getLogger();
|
||||
+ private static final List<Byte> SUPPORTED_VERSIONS = Arrays.asList((byte) 1, (byte) 2);
|
||||
+ private static final LinearRegionFileFlusher linearRegionFileFlusher = new LinearRegionFileFlusher();
|
||||
+ private final byte[][] buffer = new byte[1024][];
|
||||
+ private final int[] bufferUncompressedSize = new int[1024];
|
||||
+ private final int[] chunkTimestamps = new int[1024];
|
||||
+ private final LZ4Compressor compressor;
|
||||
+ private final LZ4FastDecompressor decompressor;
|
||||
+ private final int compressionLevel;
|
||||
+ private final AtomicBoolean markedToSave = new AtomicBoolean(false);
|
||||
+ public boolean closed = false;
|
||||
+ public Path path;
|
||||
+
|
||||
+
|
||||
+ public LinearRegionFile(Path file, int compression) throws IOException {
|
||||
+ this.path = file;
|
||||
+ this.compressionLevel = compression;
|
||||
+ this.compressor = LZ4Factory.fastestInstance().fastCompressor();
|
||||
+ this.decompressor = LZ4Factory.fastestInstance().fastDecompressor();
|
||||
+
|
||||
+ File regionFile = new File(this.path.toString());
|
||||
+
|
||||
+ Arrays.fill(this.bufferUncompressedSize, 0);
|
||||
+
|
||||
+ if (!regionFile.canRead()) return;
|
||||
+
|
||||
+ try (FileInputStream fileStream = new FileInputStream(regionFile);
|
||||
+ DataInputStream rawDataStream = new DataInputStream(fileStream)) {
|
||||
+
|
||||
+ long superBlock = rawDataStream.readLong();
|
||||
+ if (superBlock != SUPERBLOCK)
|
||||
+ throw new RuntimeException("Invalid superblock: " + superBlock + " in " + file);
|
||||
+
|
||||
+ byte version = rawDataStream.readByte();
|
||||
+ if (!SUPPORTED_VERSIONS.contains(version))
|
||||
+ throw new RuntimeException("Invalid version: " + version + " in " + file);
|
||||
+
|
||||
+ // Skip newestTimestamp (Long) + Compression level (Byte) + Chunk count (Short): Unused.
|
||||
+ rawDataStream.skipBytes(11);
|
||||
+
|
||||
+ int dataCount = rawDataStream.readInt();
|
||||
+ long fileLength = file.toFile().length();
|
||||
+ if (fileLength != HEADER_SIZE + dataCount + FOOTER_SIZE)
|
||||
+ throw new IOException("Invalid file length: " + this.path + " " + fileLength + " " + (HEADER_SIZE + dataCount + FOOTER_SIZE));
|
||||
+
|
||||
+ rawDataStream.skipBytes(8); // Skip data hash (Long): Unused.
|
||||
+
|
||||
+ byte[] rawCompressed = new byte[dataCount];
|
||||
+ rawDataStream.readFully(rawCompressed, 0, dataCount);
|
||||
+
|
||||
+ superBlock = rawDataStream.readLong();
|
||||
+ if (superBlock != SUPERBLOCK)
|
||||
+ throw new IOException("Footer superblock invalid " + this.path);
|
||||
+
|
||||
+ try (DataInputStream dataStream = new DataInputStream(new ZstdInputStream(new ByteArrayInputStream(rawCompressed)))) {
|
||||
+
|
||||
+ int[] starts = new int[1024];
|
||||
+ for (int i = 0; i < 1024; i++) {
|
||||
+ starts[i] = dataStream.readInt();
|
||||
+ dataStream.skipBytes(4); // Skip timestamps (Int): Unused.
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < 1024; i++) {
|
||||
+ if (starts[i] > 0) {
|
||||
+ int size = starts[i];
|
||||
+ byte[] b = new byte[size];
|
||||
+ dataStream.readFully(b, 0, size);
|
||||
+
|
||||
+ int maxCompressedLength = this.compressor.maxCompressedLength(size);
|
||||
+ byte[] compressed = new byte[maxCompressedLength];
|
||||
+ int compressedLength = this.compressor.compress(b, 0, size, compressed, 0, maxCompressedLength);
|
||||
+ b = new byte[compressedLength];
|
||||
+ System.arraycopy(compressed, 0, b, 0, compressedLength);
|
||||
+
|
||||
+ this.buffer[i] = b;
|
||||
+ this.bufferUncompressedSize[i] = size;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static int getChunkIndex(int x, int z) {
|
||||
+ return (x & 31) + ((z & 31) << 5);
|
||||
+ }
|
||||
+
|
||||
+ private static int getTimestamp() {
|
||||
+ return (int) (System.currentTimeMillis() / 1000L);
|
||||
+ }
|
||||
+
|
||||
+ public Path getPath() {
|
||||
+ return this.path;
|
||||
+ }
|
||||
+
|
||||
+ public void flush() throws IOException {
|
||||
+ if (isMarkedToSave()) flushWrapper(); // sync
|
||||
+ }
|
||||
+
|
||||
+ private void markToSave() {
|
||||
+ linearRegionFileFlusher.scheduleSave(this);
|
||||
+ markedToSave.set(true);
|
||||
+ }
|
||||
+
|
||||
+ public boolean isMarkedToSave() {
|
||||
+ return markedToSave.getAndSet(false);
|
||||
+ }
|
||||
+
|
||||
+ public void flushWrapper() {
|
||||
+ try {
|
||||
+ save();
|
||||
+ } catch (IOException e) {
|
||||
+ LOGGER.error("Failed to flush region file {}", path.toAbsolutePath(), e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public boolean doesChunkExist(ChunkPos pos) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ private synchronized void save() throws IOException {
|
||||
+ long timestamp = getTimestamp();
|
||||
+ short chunkCount = 0;
|
||||
+
|
||||
+ File tempFile = new File(path.toString() + ".tmp");
|
||||
+
|
||||
+ try (FileOutputStream fileStream = new FileOutputStream(tempFile);
|
||||
+ ByteArrayOutputStream zstdByteArray = new ByteArrayOutputStream();
|
||||
+ ZstdOutputStream zstdStream = new ZstdOutputStream(zstdByteArray, this.compressionLevel);
|
||||
+ DataOutputStream zstdDataStream = new DataOutputStream(zstdStream);
|
||||
+ DataOutputStream dataStream = new DataOutputStream(fileStream)) {
|
||||
+
|
||||
+ dataStream.writeLong(SUPERBLOCK);
|
||||
+ dataStream.writeByte(VERSION);
|
||||
+ dataStream.writeLong(timestamp);
|
||||
+ dataStream.writeByte(this.compressionLevel);
|
||||
+
|
||||
+ ArrayList<byte[]> byteBuffers = new ArrayList<>();
|
||||
+ for (int i = 0; i < 1024; i++) {
|
||||
+ if (this.bufferUncompressedSize[i] != 0) {
|
||||
+ chunkCount += 1;
|
||||
+ byte[] content = new byte[bufferUncompressedSize[i]];
|
||||
+ this.decompressor.decompress(buffer[i], 0, content, 0, bufferUncompressedSize[i]);
|
||||
+
|
||||
+ byteBuffers.add(content);
|
||||
+ } else byteBuffers.add(null);
|
||||
+ }
|
||||
+ for (int i = 0; i < 1024; i++) {
|
||||
+ zstdDataStream.writeInt(this.bufferUncompressedSize[i]); // Write uncompressed size
|
||||
+ zstdDataStream.writeInt(this.chunkTimestamps[i]); // Write timestamp
|
||||
+ }
|
||||
+ for (int i = 0; i < 1024; i++) {
|
||||
+ if (byteBuffers.get(i) != null)
|
||||
+ zstdDataStream.write(byteBuffers.get(i), 0, byteBuffers.get(i).length);
|
||||
+ }
|
||||
+ zstdDataStream.close();
|
||||
+
|
||||
+ dataStream.writeShort(chunkCount);
|
||||
+
|
||||
+ byte[] compressed = zstdByteArray.toByteArray();
|
||||
+
|
||||
+ dataStream.writeInt(compressed.length);
|
||||
+ dataStream.writeLong(0);
|
||||
+
|
||||
+ dataStream.write(compressed, 0, compressed.length);
|
||||
+ dataStream.writeLong(SUPERBLOCK);
|
||||
+
|
||||
+ dataStream.flush();
|
||||
+ fileStream.getFD().sync();
|
||||
+ fileStream.getChannel().force(true); // Ensure atomicity on Btrfs
|
||||
+ }
|
||||
+ Files.move(tempFile.toPath(), this.path, StandardCopyOption.REPLACE_EXISTING);
|
||||
+ }
|
||||
+
|
||||
+ public synchronized void write(ChunkPos pos, ByteBuffer buffer) {
|
||||
+ try {
|
||||
+ byte[] b = toByteArray(new ByteArrayInputStream(buffer.array()));
|
||||
+ int uncompressedSize = b.length;
|
||||
+
|
||||
+ int maxCompressedLength = this.compressor.maxCompressedLength(b.length);
|
||||
+ byte[] compressed = new byte[maxCompressedLength];
|
||||
+ int compressedLength = this.compressor.compress(b, 0, b.length, compressed, 0, maxCompressedLength);
|
||||
+ b = new byte[compressedLength];
|
||||
+ System.arraycopy(compressed, 0, b, 0, compressedLength);
|
||||
+
|
||||
+ int index = getChunkIndex(pos.x, pos.z);
|
||||
+ this.buffer[index] = b;
|
||||
+ this.chunkTimestamps[index] = getTimestamp();
|
||||
+ this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] = uncompressedSize;
|
||||
+ } catch (IOException e) {
|
||||
+ LOGGER.error("Chunk write IOException {} {}", e, this.path);
|
||||
+ }
|
||||
+ markToSave();
|
||||
+ }
|
||||
+
|
||||
+ public DataOutputStream getChunkDataOutputStream(ChunkPos pos) {
|
||||
+ return new DataOutputStream(new BufferedOutputStream(new ChunkBuffer(pos)));
|
||||
+ }
|
||||
+
|
||||
+ private byte[] toByteArray(InputStream in) throws IOException {
|
||||
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
+ byte[] tempBuffer = new byte[4096];
|
||||
+
|
||||
+ int length;
|
||||
+ while ((length = in.read(tempBuffer)) >= 0) {
|
||||
+ out.write(tempBuffer, 0, length);
|
||||
+ }
|
||||
+
|
||||
+ return out.toByteArray();
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public synchronized DataInputStream getChunkDataInputStream(ChunkPos pos) {
|
||||
+ if (this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] != 0) {
|
||||
+ byte[] content = new byte[bufferUncompressedSize[getChunkIndex(pos.x, pos.z)]];
|
||||
+ this.decompressor.decompress(this.buffer[getChunkIndex(pos.x, pos.z)], 0, content, 0, bufferUncompressedSize[getChunkIndex(pos.x, pos.z)]);
|
||||
+ return new DataInputStream(new ByteArrayInputStream(content));
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ public void clear(ChunkPos pos) {
|
||||
+ int i = getChunkIndex(pos.x, pos.z);
|
||||
+ this.buffer[i] = null;
|
||||
+ this.bufferUncompressedSize[i] = 0;
|
||||
+ this.chunkTimestamps[i] = getTimestamp();
|
||||
+ markToSave();
|
||||
+ }
|
||||
+
|
||||
+ public boolean hasChunk(ChunkPos pos) {
|
||||
+ return this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] > 0;
|
||||
+ }
|
||||
+
|
||||
+ public void close() throws IOException {
|
||||
+ if (closed) return;
|
||||
+ closed = true;
|
||||
+ flush(); // sync
|
||||
+ }
|
||||
+
|
||||
+ public boolean recalculateHeader() {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ public void setOversized(int x, int z, boolean something) {
|
||||
+ }
|
||||
+
|
||||
+ public CompoundTag getOversizedData(int x, int z) throws IOException {
|
||||
+ throw new IOException("getOversizedData is a stub " + this.path);
|
||||
+ }
|
||||
+
|
||||
+ public boolean isOversized(int x, int z) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ private class ChunkBuffer extends ByteArrayOutputStream {
|
||||
+ private final ChunkPos pos;
|
||||
+
|
||||
+ public ChunkBuffer(ChunkPos chunkcoordintpair) {
|
||||
+ super();
|
||||
+ this.pos = chunkcoordintpair;
|
||||
+ }
|
||||
+
|
||||
+ public void close() {
|
||||
+ ByteBuffer bytebuffer = ByteBuffer.wrap(this.buf, 0, this.count);
|
||||
+ LinearRegionFile.this.write(this.pos, bytebuffer);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/region/LinearRegionFileFlusher.java b/src/main/java/space/bxteam/divinemc/region/LinearRegionFileFlusher.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..731dd3516a597e9cb97596bb7647db6c94363a9a
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/space/bxteam/divinemc/region/LinearRegionFileFlusher.java
|
||||
@@ -0,0 +1,50 @@
|
||||
+package space.bxteam.divinemc.region;
|
||||
+
|
||||
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
+import java.util.Queue;
|
||||
+import java.util.concurrent.ExecutorService;
|
||||
+import java.util.concurrent.Executors;
|
||||
+import java.util.concurrent.LinkedBlockingQueue;
|
||||
+import java.util.concurrent.ScheduledExecutorService;
|
||||
+import java.util.concurrent.TimeUnit;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import space.bxteam.divinemc.configuration.DivineConfig;
|
||||
+
|
||||
+public class LinearRegionFileFlusher {
|
||||
+
|
||||
+ private final Queue<LinearRegionFile> savingQueue = new LinkedBlockingQueue<>();
|
||||
+ private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(
|
||||
+ new ThreadFactoryBuilder()
|
||||
+ .setNameFormat("linear-flush-scheduler")
|
||||
+ .build()
|
||||
+ );
|
||||
+ private final ExecutorService executor = Executors.newFixedThreadPool(
|
||||
+ DivineConfig.linearFlushThreads,
|
||||
+ new ThreadFactoryBuilder()
|
||||
+ .setNameFormat("linear-flusher-%d")
|
||||
+ .build()
|
||||
+ );
|
||||
+
|
||||
+ public LinearRegionFileFlusher() {
|
||||
+ Bukkit.getLogger().info("Using " + DivineConfig.linearFlushThreads + " threads for linear region flushing.");
|
||||
+ scheduler.scheduleAtFixedRate(this::pollAndFlush, 0L, DivineConfig.linearFlushFrequency, TimeUnit.SECONDS);
|
||||
+ }
|
||||
+
|
||||
+ public void scheduleSave(LinearRegionFile regionFile) {
|
||||
+ if (savingQueue.contains(regionFile)) return;
|
||||
+ savingQueue.add(regionFile);
|
||||
+ }
|
||||
+
|
||||
+ private void pollAndFlush() {
|
||||
+ while (!savingQueue.isEmpty()) {
|
||||
+ LinearRegionFile regionFile = savingQueue.poll();
|
||||
+ if (!regionFile.closed && regionFile.isMarkedToSave())
|
||||
+ executor.execute(regionFile::flushWrapper);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public void shutdown() {
|
||||
+ executor.shutdown();
|
||||
+ scheduler.shutdown();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/space/bxteam/divinemc/region/RegionFileFormat.java b/src/main/java/space/bxteam/divinemc/region/RegionFileFormat.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..a799c9b2bb262b86be3872ba2a920ca3e8cb9d02
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/space/bxteam/divinemc/region/RegionFileFormat.java
|
||||
@@ -0,0 +1,16 @@
|
||||
+package space.bxteam.divinemc.region;
|
||||
+
|
||||
+public enum RegionFileFormat {
|
||||
+ ANVIL,
|
||||
+ LINEAR,
|
||||
+ INVALID;
|
||||
+
|
||||
+ public static RegionFileFormat fromString(String format) {
|
||||
+ for (RegionFileFormat rff : values()) {
|
||||
+ if (rff.name().equalsIgnoreCase(format)) {
|
||||
+ return rff;
|
||||
+ }
|
||||
+ }
|
||||
+ return RegionFileFormat.INVALID;
|
||||
+ }
|
||||
+}
|
||||
Reference in New Issue
Block a user