Compare commits

..

1 Commits

Author SHA1 Message Date
Sofiane H. Djerbi
55012f8ddd Internal compression introduction 2023-03-06 06:30:06 +02:00
18 changed files with 768 additions and 376 deletions

View File

@@ -1,22 +1,20 @@
name: Generate Jars name: Generate Jars
on: [ push, pull_request ] on: [ push, pull_request ]
env: env:
version: '1.19.4' version: '1.19.3'
branch: ver/1.19.4 branch: ver/1.19.3
jobs: jobs:
paperclip: paperclip:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout Git Repository - name: Checkout Git Repository
uses: actions/checkout@v3 uses: actions/checkout@v2
- name: Set up JDK - name: Set up JDK
uses: graalvm/setup-graalvm@v1 uses: actions/setup-java@v2.5.0
with: with:
java-version: '17' java-version: '17'
cache: 'gradle' cache: 'gradle'
distribution: 'GraalVM' distribution: 'temurin'
github-token: ${{ secrets.GITHUB_TOKEN }}
version: 'latest'
- name: Configure Git User Details - name: Configure Git User Details
run: | run: |
git config --global user.email "actions@github.com" && git config --global user.name "Github Actions" git config --global user.email "actions@github.com" && git config --global user.name "Github Actions"

View File

@@ -1,22 +1,20 @@
name: Release Jars name: Release Jars
on: [push, workflow_dispatch] on: [push, workflow_dispatch]
env: env:
version: '1.19.4' version: '1.19.3'
branch: ver/1.19.4 branch: ver/1.19.3
jobs: jobs:
paperclip: paperclip:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout Git Repository - name: Checkout Git Repository
uses: actions/checkout@v3 uses: actions/checkout@v2
- name: Set up JDK - name: Set up JDK
uses: graalvm/setup-graalvm@v1 uses: actions/setup-java@v2.5.0
with: with:
java-version: '17' java-version: '17'
cache: 'gradle' cache: 'gradle'
distribution: 'GraalVM' distribution: 'temurin'
github-token: ${{ secrets.GITHUB_TOKEN }}
version: 'latest'
- name: Configure Git User Details - name: Configure Git User Details
run: | run: |
git config --global user.email "actions@github.com" && git config --global user.name "Github Actions" git config --global user.email "actions@github.com" && git config --global user.name "Github Actions"

View File

@@ -2,7 +2,8 @@
<div align="center"> <div align="center">
<img src="https://github.com/kugge/Kaiiju/blob/ver/1.19.3/logo.png?" width="32%" height="32%"/> <img src="https://github.com/kugge/Kaiiju/blob/ver/1.19.3/logo.png?" width="32%" height="32%"/>
<h1>Kaiiju</h1> <h1>Kaiiju</h1>
<h3>Designed for vanilla/anarchy servers</h3> <h3>A Server Software Designed For Anarchy</h3>
<h4>❗ [ Warning ] Work in progress, contributions are welcome ❗</h4>
[![License](https://img.shields.io/github/license/kugge/Kaiiju?style=for-the-badge&logo=github)](LICENSE) [![License](https://img.shields.io/github/license/kugge/Kaiiju?style=for-the-badge&logo=github)](LICENSE)
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/kugge/Kaiiju/build.yml?style=for-the-badge)](https://github.com/kugge/Kaiiju/actions) [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/kugge/Kaiiju/build.yml?style=for-the-badge)](https://github.com/kugge/Kaiiju/actions)
@@ -17,11 +18,12 @@
- **Lobotomize**: Lobotomize mobs and villagers without breaking vanilla mechanics. - **Lobotomize**: Lobotomize mobs and villagers without breaking vanilla mechanics.
### Roadmap ### Roadmap
- **Lithium**: Implementation of Lithium server mixins. - **Lithium**: Full implementation of Lithium.
- **C2ME**: Implementation of C2ME server mixins. - **C2ME**: Full implementation of C2ME.
- **VMP**: Implementation of VMP server mixins. - **VMP**: Full implementation of VMP.
## Building ## Building
In order to distribute and use this server software, you need a paperclip file:
```bash ```bash
./gradlew applyPatches # Apply Kaiiju patches ./gradlew applyPatches # Apply Kaiiju patches
@@ -29,6 +31,7 @@
``` ```
## License ## License
Original patches are licensed under GPL-3.0. Patches are licensed under GPL-3.0.
All other files are licensed under MIT.
Made with <span style="color: #e25555;">&#9829;</span> on Earth. Made with <span style="color: #e25555;">&#9829;</span> on Earth.

View File

@@ -84,7 +84,7 @@ paperweight {
) )
val purpurLatestCommitJson = layout.cache.resolve("purpurLatestCommit.json"); val purpurLatestCommitJson = layout.cache.resolve("purpurLatestCommit.json");
download.get().download("https://api.github.com/repos/PurpurMC/Purpur/commits/ver/1.19.4", purpurLatestCommitJson); download.get().download("https://api.github.com/repos/PurpurMC/Purpur/commits/ver/1.19.3", purpurLatestCommitJson);
val purpurLatestCommit = gson.fromJson<paper.libs.com.google.gson.JsonObject>(purpurLatestCommitJson)["sha"].asString; val purpurLatestCommit = gson.fromJson<paper.libs.com.google.gson.JsonObject>(purpurLatestCommitJson)["sha"].asString;
copy { copy {

View File

@@ -1,10 +1,9 @@
group = dev.kaiijumc.kaiiju group = dev.kaiijumc.kaiiju
version = 1.19.4-R0.1-SNAPSHOT version = 1.19.3-R0.1-SNAPSHOT
mcVersion = 1.19.4 mcVersion = 1.19.3
purpurRef = f5a789d40bc8b55efaf69143067e76a9305354c5 purpurRef = ade1ed1d98e936bfce92cc50ba0444d05310add4
org.gradle.caching=true org.gradle.caching=true
org.gradle.parallel=true org.gradle.parallel=true
org.gradle.vfs.watch=false org.gradle.vfs.watch=false
org.gradle.jvmargs=-Xmx4G -Dfile.encoding=UTF-8 -Dgraal.UsePriorityInlining=true -Dgraal.Vectorization=true -Dgraal.OptDuplication=true -Dgraal.SpeculativeGuardMovement=true -Dgraal.WriteableCodeCache=true

View File

@@ -5,43 +5,37 @@ Subject: [PATCH] Kaiiju Rebranding
diff --git a/build.gradle.kts b/build.gradle.kts diff --git a/build.gradle.kts b/build.gradle.kts
index 22470f0ab8354a9f31a0f195f3fe80f2f5ee2f0e..845cf3838fc014e59b52c0ffa4cae1bc370d9b47 100644 index f25c0557cf984b97e0ab361f579eccbf46f82170..7f1f4988a25a5ebac36c25c045c51eefecab6862 100644
--- a/build.gradle.kts --- a/build.gradle.kts
+++ b/build.gradle.kts +++ b/build.gradle.kts
@@ -7,8 +7,12 @@ plugins { @@ -7,7 +7,7 @@ plugins {
} }
dependencies { dependencies {
- implementation(project(":purpur-api")) // Purpur - implementation(project(":purpur-api")) // Purpur
- implementation("io.papermc.paper:paper-mojangapi:1.19.4-R0.1-SNAPSHOT") // Purpur
+ implementation(project(":kaiiju-api")) // Purpur // Kaiiju + implementation(project(":kaiiju-api")) // Purpur // Kaiiju
+ // Pufferfish start // Pufferfish start
+ implementation("io.papermc.paper:paper-mojangapi:1.19.4-R0.1-SNAPSHOT") { implementation("io.papermc.paper:paper-mojangapi:1.19.3-R0.1-SNAPSHOT") {
+ exclude("io.papermc.paper", "paper-api") exclude("io.papermc.paper", "paper-api")
+ } @@ -84,7 +84,7 @@ tasks.jar {
+ // Pufferfish end
// Paper start
implementation("org.jline:jline-terminal-jansi:3.21.0")
implementation("net.minecrell:terminalconsoleappender:1.3.0")
@@ -81,7 +85,7 @@ tasks.jar {
attributes( attributes(
"Main-Class" to "org.bukkit.craftbukkit.Main", "Main-Class" to "org.bukkit.craftbukkit.Main",
"Implementation-Title" to "CraftBukkit", "Implementation-Title" to "CraftBukkit",
- "Implementation-Version" to "git-Purpur-$implementationVersion", // Pufferfish // Purpur - "Implementation-Version" to "git-Purpur-$implementationVersion", // Purpur
+ "Implementation-Version" to "git-Kaiiju-$implementationVersion", // Pufferfish // Purpur // Kaiiju + "Implementation-Version" to "git-Kaiiju-$implementationVersion", // Purpur // Kaiiju
"Implementation-Vendor" to date, // Paper "Implementation-Vendor" to date, // Paper
"Specification-Title" to "Bukkit", "Specification-Title" to "Bukkit",
"Specification-Version" to project.version, "Specification-Version" to project.version,
diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java
index 8cde30544e14f8fc2dac32966ae3c21f8cf3a551..f9e3659dee7171b37a07d9880d7b21857f87ff00 100644 index 9713263c3bd34ab8a3bfc0a8797ba0b1b88ed733..0b95cd5305e4559d6dca59011869e5b203d51576 100644
--- a/src/main/java/com/destroystokyo/paper/Metrics.java --- a/src/main/java/com/destroystokyo/paper/Metrics.java
+++ b/src/main/java/com/destroystokyo/paper/Metrics.java +++ b/src/main/java/com/destroystokyo/paper/Metrics.java
@@ -593,7 +593,7 @@ public class Metrics { @@ -593,7 +593,7 @@ public class Metrics {
boolean logFailedRequests = config.getBoolean("logFailedRequests", false); boolean logFailedRequests = config.getBoolean("logFailedRequests", false);
// Only start Metrics, if it's enabled in the config // Only start Metrics, if it's enabled in the config
if (config.getBoolean("enabled", true)) { if (config.getBoolean("enabled", true)) {
- Metrics metrics = new Metrics("Purpur", serverUUID, logFailedRequests, Bukkit.getLogger()); // Pufferfish // Purpur - Metrics metrics = new Metrics("Purpur", serverUUID, logFailedRequests, Bukkit.getLogger()); // Purpur
+ Metrics metrics = new Metrics("Kaiiju", serverUUID, logFailedRequests, Bukkit.getLogger()); // Pufferfish // Purpur // Kaiiju + Metrics metrics = new Metrics("Kaiiju", serverUUID, logFailedRequests, Bukkit.getLogger()); // Purpur // Kaiiju
metrics.addCustomChart(new Metrics.SimplePie("minecraft_version", () -> { metrics.addCustomChart(new Metrics.SimplePie("minecraft_version", () -> {
String minecraftVersion = Bukkit.getVersion(); String minecraftVersion = Bukkit.getVersion();
@@ -55,7 +49,7 @@ index 8cde30544e14f8fc2dac32966ae3c21f8cf3a551..f9e3659dee7171b37a07d9880d7b2185
metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> { metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> {
Map<String, Map<String, Integer>> map = new HashMap<>(); Map<String, Map<String, Integer>> map = new HashMap<>();
diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
index 462a6eed350fd660ddaf25d567bb6e97b77d0b2b..ecde56de475b5a69e2ad22c1cbe903e6f3d40466 100644 index fba5dbdb7bcbb55400ef18342c9b54612972a718..8aaa2942d35d6447655f8355106841a30429b653 100644
--- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java --- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
+++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java +++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
@@ -20,7 +20,7 @@ import java.util.stream.StreamSupport; @@ -20,7 +20,7 @@ import java.util.stream.StreamSupport;
@@ -134,10 +128,10 @@ index b5b6657e52e4f7a630229bd3ba433438af293e22..afda0d4198398de29a62159fae701b22
stringbuilder.append("// "); stringbuilder.append("// ");
stringbuilder.append(CrashReport.getErrorComment()); stringbuilder.append(CrashReport.getErrorComment());
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 2cc20cc768bbbd386972c426d3a131af33612294..5f5e9db2cbde552216c8990054b96443f180cb3b 100644 index cea4447aad2d64db56a76e4ba180dc7326d2e13b..40b4bd2f1a61c2d9a59c9c09b72713401969460b 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java --- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -929,7 +929,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -927,7 +927,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
shutdownThread = Thread.currentThread(); shutdownThread = Thread.currentThread();
org.spigotmc.WatchdogThread.doStop(); // Paper org.spigotmc.WatchdogThread.doStop(); // Paper
if (!isSameThread()) { if (!isSameThread()) {
@@ -147,20 +141,20 @@ index 2cc20cc768bbbd386972c426d3a131af33612294..5f5e9db2cbde552216c8990054b96443
this.getRunningThread().stop(); this.getRunningThread().stop();
try { try {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index bc1a2df0a7ddaf030917e4723994464d77e55d02..c8641ee7cf081b86a461c640ccd70ec4fc39330b 100644 index c32e32005968b46d1f7d5162ab15c61e36f398f5..23f4edebbfa045716f956128703b58baced58f49 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -256,7 +256,7 @@ import javax.annotation.Nullable; // Paper @@ -261,7 +261,7 @@ import javax.annotation.Nullable; // Paper
import javax.annotation.Nonnull; // Paper import javax.annotation.Nonnull; // Paper
public final class CraftServer implements Server { public final class CraftServer implements Server {
- private final String serverName = "Purpur"; // Paper // Pufferfish // Purpur - private final String serverName = "Purpur"; // Paper // Purpur
+ private final String serverName = "Kaiiju"; // Paper // Pufferfish // Purpur // Kaiiju + private final String serverName = "Kaiiju"; // Paper // Purpur // Kaiiju
private final String serverVersion; private final String serverVersion;
private final String bukkitVersion = Versioning.getBukkitVersion(); private final String bukkitVersion = Versioning.getBukkitVersion();
private final Logger logger = Logger.getLogger("Minecraft"); private final Logger logger = Logger.getLogger("Minecraft");
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index cf7ba8724ab68f6955b5ebfa1ba46c4397da32b3..d5b65d6d0e8c8dea86c69b666448e6f6d7d4e9d6 100644 index 78ac748859e21a61140e9bff67e4527a8d35b4b6..5e14153433f5c7854a357aad4776b2aad4cd6fa0 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -883,7 +883,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { @@ -883,7 +883,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
@@ -186,20 +180,20 @@ index 5402098dce0d64d3dceea51f248d7d366850a74f..2b7a67c339994c34296f7057ffc8822b
// (async tasks must live with race-conditions if they attempt to cancel between these few lines of code) // (async tasks must live with race-conditions if they attempt to cancel between these few lines of code)
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
index 99597258e8e88cd9e2c901c4ac3ff7faeeabee2b..6e863169f510332f659ac2a24f796ee32730cda7 100644 index fb87620c742ff7912f5e8ccd2a7930dd605576d9..0f56013165cd61023b4f30a4da424b701e14a8e2 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java --- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java +++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
@@ -11,7 +11,7 @@ public final class Versioning { @@ -11,7 +11,7 @@ public final class Versioning {
public static String getBukkitVersion() { public static String getBukkitVersion() {
String result = "Unknown-Version"; String result = "Unknown-Version";
- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/org.purpurmc.purpur/purpur-api/pom.properties"); // Pufferfish // Purpur - InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/org.purpurmc.purpur/purpur-api/pom.properties"); // Purpur
+ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/dev.kaiijumc.kaiiju/kaiiju-api/pom.properties"); // Pufferfish // Purpur // Kaiiju + InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/dev.kaiijumc.kaiiju/kaiiju-api/pom.properties"); // Purpur // Kaiiju
Properties properties = new Properties(); Properties properties = new Properties();
if (stream != null) { if (stream != null) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index 0bcbe1f07ff8e552d2abd6e432af5710005acc04..c6f09e562dd0eb25f3e556627d07758a045d7409 100644 index c7c0ed8dfe58c841faf684a1fe228eeda6cd57b7..410ce2dc98c48871d2ddfb0195f2885adc18cba8 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java --- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -227,7 +227,7 @@ public class PurpurConfig { @@ -227,7 +227,7 @@ public class PurpurConfig {
@@ -257,3 +251,525 @@ index a810bfd3b8d6bd4d8f2ef8797e4281ae4fe8a67f..7e92d77edb448f2ec818bf4b876d3df5
} }
log.log( Level.SEVERE, "------------------------------" ); log.log( Level.SEVERE, "------------------------------" );
diff --git a/src/main/resources/logo.png b/src/main/resources/logo.png
index 518591dd83289e041a16e2c2e7d7e7640d4b2e1b..d51e050fef81600d005e153c6a2a4c6ba7ff3388 100644
GIT binary patch
literal 17586
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
Ef}Ok25&!@I
literal 9260
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
HqBZh=dic2S

View File

@@ -413,7 +413,7 @@ index 0000000000000000000000000000000000000000..0dde8879856f8882f2840b4b8bfb5aa0
+} +}
\ No newline at end of file \ No newline at end of file
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 582467e3419c23446b20d3076fbfce22115250a8..429223724ee5f90cda8d15fa8095a2335a6eacba 100644 index fd1b0564d2d2b45128e6f2556fb93ee56bd683b5..948ae5f96b1d54e69b49f6314d11078f197c946e 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -227,6 +227,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -227,6 +227,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -433,19 +433,18 @@ index 582467e3419c23446b20d3076fbfce22115250a8..429223724ee5f90cda8d15fa8095a233
io.papermc.paper.brigadier.PaperBrigadierProviderImpl.INSTANCE.getClass(); // init PaperBrigadierProvider io.papermc.paper.brigadier.PaperBrigadierProviderImpl.INSTANCE.getClass(); // init PaperBrigadierProvider
// Paper end // Paper end
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index b8001bca2a33ec1e60566948a651400418a6e9e7..666b96835338d4407ef5093668055cbab5c3b6f2 100644 index fef709fce7309795b6d62d33a220a2be2399efd3..213665dc92e572d7efc6e28d3ceaa74c733bc291 100644
--- a/src/main/java/net/minecraft/world/level/Level.java --- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -178,6 +178,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -174,6 +174,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
public final com.destroystokyo.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray public final com.destroystokyo.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray
public final org.purpurmc.purpur.PurpurWorldConfig purpurConfig; // Purpur public final org.purpurmc.purpur.PurpurWorldConfig purpurConfig; // Purpur
+ public final dev.kaiijumc.kaiiju.KaiijuWorldConfig kaiijuConfig; // Kaiiju + public final dev.kaiijumc.kaiiju.KaiijuWorldConfig kaiijuConfig; // Kaiiju
+
public final co.aikar.timings.WorldTimingsHandler timings; // Paper public final co.aikar.timings.WorldTimingsHandler timings; // Paper
public static BlockPos lastPhysicsProblem; // Spigot public static BlockPos lastPhysicsProblem; // Spigot
private org.spigotmc.TickLimiter entityLimiter; @@ -330,6 +331,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@@ -333,6 +335,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot
this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper
this.purpurConfig = new org.purpurmc.purpur.PurpurWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName(), env); // Purpur this.purpurConfig = new org.purpurmc.purpur.PurpurWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName(), env); // Purpur
@@ -454,10 +453,10 @@ index b8001bca2a33ec1e60566948a651400418a6e9e7..666b96835338d4407ef5093668055cba
this.generator = gen; this.generator = gen;
this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env); this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index c8641ee7cf081b86a461c640ccd70ec4fc39330b..46dc1072e2237e8c9bb4ddbc7d6ca5aab0de4885 100644 index e9cc9ff401233f50279bbc622050fd0894968ae1..a52ff5f8f883ba21f036b7d6830f7470567fe2b6 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -971,6 +971,7 @@ public final class CraftServer implements Server { @@ -976,6 +976,7 @@ public final class CraftServer implements Server {
org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot
this.console.paperConfigurations.reloadConfigs(this.console); this.console.paperConfigurations.reloadConfigs(this.console);
org.purpurmc.purpur.PurpurConfig.init((File) console.options.valueOf("purpur-settings")); // Purpur org.purpurmc.purpur.PurpurConfig.init((File) console.options.valueOf("purpur-settings")); // Purpur
@@ -465,7 +464,7 @@ index c8641ee7cf081b86a461c640ccd70ec4fc39330b..46dc1072e2237e8c9bb4ddbc7d6ca5aa
for (ServerLevel world : this.console.getAllLevels()) { for (ServerLevel world : this.console.getAllLevels()) {
// world.serverLevelData.setDifficulty(config.difficulty); // Paper - per level difficulty // world.serverLevelData.setDifficulty(config.difficulty); // Paper - per level difficulty
world.setSpawnSettings(world.serverLevelData.getDifficulty() != Difficulty.PEACEFUL && config.spawnMonsters, config.spawnAnimals); // Paper - per level difficulty (from MinecraftServer#setDifficulty(ServerLevel, Difficulty, boolean)) world.setSpawnSettings(world.serverLevelData.getDifficulty() != Difficulty.PEACEFUL && config.spawnMonsters, config.spawnAnimals); // Paper - per level difficulty (from MinecraftServer#setDifficulty(ServerLevel, Difficulty, boolean))
@@ -987,6 +988,7 @@ public final class CraftServer implements Server { @@ -992,6 +993,7 @@ public final class CraftServer implements Server {
} }
world.spigotConfig.init(); // Spigot world.spigotConfig.init(); // Spigot
world.purpurConfig.init(); // Purpur world.purpurConfig.init(); // Purpur
@@ -473,7 +472,7 @@ index c8641ee7cf081b86a461c640ccd70ec4fc39330b..46dc1072e2237e8c9bb4ddbc7d6ca5aa
} }
Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper
@@ -1003,6 +1005,7 @@ public final class CraftServer implements Server { @@ -1008,6 +1010,7 @@ public final class CraftServer implements Server {
org.spigotmc.SpigotConfig.registerCommands(); // Spigot org.spigotmc.SpigotConfig.registerCommands(); // Spigot
io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper
org.purpurmc.purpur.PurpurConfig.registerCommands(); // Purpur org.purpurmc.purpur.PurpurConfig.registerCommands(); // Purpur
@@ -481,7 +480,7 @@ index c8641ee7cf081b86a461c640ccd70ec4fc39330b..46dc1072e2237e8c9bb4ddbc7d6ca5aa
this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*"); this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*");
this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions"); this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions");
@@ -2828,6 +2831,13 @@ public final class CraftServer implements Server { @@ -2830,6 +2833,13 @@ public final class CraftServer implements Server {
} }
// Purpur end // Purpur end
@@ -496,10 +495,10 @@ index c8641ee7cf081b86a461c640ccd70ec4fc39330b..46dc1072e2237e8c9bb4ddbc7d6ca5aa
public void restart() { public void restart() {
org.spigotmc.RestartCommand.restart(); org.spigotmc.RestartCommand.restart();
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
index ab05f4151e6ec7404a85ddb3a141ed39d9ed86d7..f722c000ddff9718319d0cb07d18b6f4d9291309 100644 index 576cd8e20982bb20d10213b6c7a229428eec1c2f..190b4bc55d8b1e9983f7b77fd3545a59fa39e6f8 100644
--- a/src/main/java/org/bukkit/craftbukkit/Main.java --- a/src/main/java/org/bukkit/craftbukkit/Main.java
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -187,6 +187,14 @@ public class Main { @@ -180,6 +180,14 @@ public class Main {
.describedAs("Yml file"); .describedAs("Yml file");
// Purpur end // Purpur end

View File

@@ -4,23 +4,8 @@ Date: Fri, 10 Feb 2023 20:03:58 +0200
Subject: [PATCH] Kaiiju RegionFormat Configuration Subject: [PATCH] Kaiiju RegionFormat Configuration
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
index 7da7e0aeb5eac9ac73a3570e716f1ceb11fd7027..b86c90cc3601e666998cfa12f44515f605bb53eb 100644
--- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
@@ -192,4 +192,10 @@ public class KaiijuConfig {
}
return builder.build();
}
+
+ public static boolean regionFormatDebug = false;
+
+ private static void regionFormatSettings() {
+ regionFormatDebug = getBoolean("region-format.debug", regionFormatDebug);
+ }
}
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java
index dd4c3ca77acb3aeefc69b8eb948b8b202ff87a19..b194f4dbebcbbf5bb4e026a0169e2d24806b46ec 100644 index dd4c3ca77acb3aeefc69b8eb948b8b202ff87a19..1b180af49adee16c2d8305d01cf213322c4d721b 100644
--- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java --- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java +++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java
@@ -4,9 +4,11 @@ import org.apache.commons.lang.BooleanUtils; @@ -4,9 +4,11 @@ import org.apache.commons.lang.BooleanUtils;
@@ -35,7 +20,7 @@ index dd4c3ca77acb3aeefc69b8eb948b8b202ff87a19..b194f4dbebcbbf5bb4e026a0169e2d24
import static dev.kaiijumc.kaiiju.KaiijuConfig.log; import static dev.kaiijumc.kaiiju.KaiijuConfig.log;
@@ -122,4 +124,23 @@ public class KaiijuWorldConfig { @@ -122,4 +124,30 @@ public class KaiijuWorldConfig {
final Map<String, Object> value = getMap("world-settings." + worldName + "." + path, null); final Map<String, Object> value = getMap("world-settings." + worldName + "." + path, null);
return value.isEmpty() ? fallback : value; return value.isEmpty() ? fallback : value;
} }
@@ -43,6 +28,7 @@ index dd4c3ca77acb3aeefc69b8eb948b8b202ff87a19..b194f4dbebcbbf5bb4e026a0169e2d24
+ public List<String> regionFormatList = Arrays.asList("ANVIL", "LINEAR"); + public List<String> regionFormatList = Arrays.asList("ANVIL", "LINEAR");
+ public String regionFormatName = "ANVIL"; + public String regionFormatName = "ANVIL";
+ public int regionFormatLinearCompressionLevel = 1; + public int regionFormatLinearCompressionLevel = 1;
+ public int regionFormatLinearInternalCompressionLevel = 1;
+ +
+ private void regionFormatSettings() { + private void regionFormatSettings() {
+ regionFormatName = getString("region-format.format", regionFormatName).toUpperCase(); + regionFormatName = getString("region-format.format", regionFormatName).toUpperCase();
@@ -52,19 +38,25 @@ index dd4c3ca77acb3aeefc69b8eb948b8b202ff87a19..b194f4dbebcbbf5bb4e026a0169e2d24
+ regionFormatName = "ANVIL"; + regionFormatName = "ANVIL";
+ } + }
+ regionFormatLinearCompressionLevel = getInt("region-format.linear.compression-level", regionFormatLinearCompressionLevel); + regionFormatLinearCompressionLevel = getInt("region-format.linear.compression-level", regionFormatLinearCompressionLevel);
+ regionFormatLinearInternalCompressionLevel = getInt("region-format.linear.internal-compression-level", regionFormatLinearInternalCompressionLevel);
+ if (regionFormatLinearCompressionLevel > 23 || regionFormatLinearCompressionLevel < 1) { + if (regionFormatLinearCompressionLevel > 23 || regionFormatLinearCompressionLevel < 1) {
+ log(Level.SEVERE, "Linear region compression level should be between 1 and 22 in kaiiju.yml: " + regionFormatLinearCompressionLevel); + log(Level.SEVERE, "Linear region compression level should be between 1 and 22 in kaiiju.yml: " + regionFormatLinearCompressionLevel);
+ log(Level.SEVERE, "Falling back to compression level 1."); + log(Level.SEVERE, "Falling back to compression level 1.");
+ regionFormatLinearCompressionLevel = 1; + regionFormatLinearCompressionLevel = 1;
+ } + }
+ if (regionFormatLinearInternalCompressionLevel > 23 || regionFormatLinearInternalCompressionLevel < 1) {
+ log(Level.SEVERE, "Linear region compression level should be between 1 and 22 in kaiiju.yml: " + regionFormatLinearCompressionLevel);
+ log(Level.SEVERE, "Falling back to compression level 1.");
+ regionFormatLinearCompressionLevel = 1;
+ }
+ } + }
} }
\ No newline at end of file \ No newline at end of file
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 5f5e9db2cbde552216c8990054b96443f180cb3b..de9a1fb5e43170bf7251b3a0faa9a45eee88f328 100644 index c1b88ae704b3d2b8ebbad28c0291a4ad12e6d5d9..ae4dd7db4e4e32fe8100309d770307fccf31110d 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java --- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -857,7 +857,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -855,7 +855,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Paper start - rewrite chunk system // Paper start - rewrite chunk system
worldserver.save((ProgressListener) null, flush, worldserver.noSave && !force, close); worldserver.save((ProgressListener) null, flush, worldserver.noSave && !force, close);
if (flush) { if (flush) {
@@ -73,7 +65,7 @@ index 5f5e9db2cbde552216c8990054b96443f180cb3b..de9a1fb5e43170bf7251b3a0faa9a45e
} }
// Paper end - rewrite chunk system // Paper end - rewrite chunk system
} }
@@ -881,7 +881,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -879,7 +879,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
//MinecraftServer.LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", worldserver2.getChunkSource().chunkMap.getStorageName()); // Paper - move up //MinecraftServer.LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", worldserver2.getChunkSource().chunkMap.getStorageName()); // Paper - move up
} }

View File

@@ -8,7 +8,7 @@ Copyright xymb@endcrystal.me
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build.gradle.kts b/build.gradle.kts diff --git a/build.gradle.kts b/build.gradle.kts
index d4f74093cb1bf46eb94e8a47c2fd6e8ee06980f0..9ff2d0cc6d1c6f17f656f0d46dbaf593032844c8 100644 index abfd4d5faf23511284b4efac771ef79da0ef72da..0a6549d0f545e81ae95527797333f2e2da85e1f1 100644
--- a/build.gradle.kts --- a/build.gradle.kts
+++ b/build.gradle.kts +++ b/build.gradle.kts
@@ -13,6 +13,10 @@ dependencies { @@ -13,6 +13,10 @@ dependencies {
@@ -76,10 +76,10 @@ index 0000000000000000000000000000000000000000..249303116d3cfadd078ebf0ae6e44bf9
+} +}
diff --git a/src/main/java/dev/kaiijumc/kaiiju/region/AbstractRegionFileFactory.java b/src/main/java/dev/kaiijumc/kaiiju/region/AbstractRegionFileFactory.java diff --git a/src/main/java/dev/kaiijumc/kaiiju/region/AbstractRegionFileFactory.java b/src/main/java/dev/kaiijumc/kaiiju/region/AbstractRegionFileFactory.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..dcfbabf54b19a4c29d5c95830242c5c26bf2f4aa index 0000000000000000000000000000000000000000..67991815a0ff9235a846ca8db817c90f094c4a58
--- /dev/null --- /dev/null
+++ b/src/main/java/dev/kaiijumc/kaiiju/region/AbstractRegionFileFactory.java +++ b/src/main/java/dev/kaiijumc/kaiiju/region/AbstractRegionFileFactory.java
@@ -0,0 +1,29 @@ @@ -0,0 +1,30 @@
+package dev.kaiijumc.kaiiju.region; +package dev.kaiijumc.kaiiju.region;
+ +
+import net.minecraft.world.level.chunk.storage.RegionFile; +import net.minecraft.world.level.chunk.storage.RegionFile;
@@ -89,21 +89,22 @@ index 0000000000000000000000000000000000000000..dcfbabf54b19a4c29d5c95830242c5c2
+import java.nio.file.Path; +import java.nio.file.Path;
+ +
+public class AbstractRegionFileFactory { +public class AbstractRegionFileFactory {
+ public static AbstractRegionFile getAbstractRegionFile(int linearCompression, Path file, Path directory, boolean dsync) throws IOException { +
+ return getAbstractRegionFile(linearCompression, file, directory, RegionFileVersion.VERSION_DEFLATE, dsync); + public static AbstractRegionFile getAbstractRegionFile(int linearCompression, int linearInternalCompression, Path file, Path directory, boolean dsync) throws IOException {
+ return getAbstractRegionFile(linearCompression, linearInternalCompression, file, directory, RegionFileVersion.VERSION_DEFLATE, dsync);
+ } + }
+ +
+ public static AbstractRegionFile getAbstractRegionFile(int linearCompression, Path file, Path directory, boolean dsync, boolean canRecalcHeader) throws IOException { + public static AbstractRegionFile getAbstractRegionFile(int linearCompression, int linearInternalCompression, Path file, Path directory, boolean dsync, boolean canRecalcHeader) throws IOException {
+ return getAbstractRegionFile(linearCompression, file, directory, RegionFileVersion.VERSION_DEFLATE, dsync, canRecalcHeader); + return getAbstractRegionFile(linearCompression, linearInternalCompression, file, directory, RegionFileVersion.VERSION_DEFLATE, dsync, canRecalcHeader);
+ } + }
+ +
+ public static AbstractRegionFile getAbstractRegionFile(int linearCompression, Path file, Path directory, RegionFileVersion outputChunkStreamVersion, boolean dsync) throws IOException { + public static AbstractRegionFile getAbstractRegionFile(int linearCompression, int linearInternalCompression, Path file, Path directory, RegionFileVersion outputChunkStreamVersion, boolean dsync) throws IOException {
+ return getAbstractRegionFile(linearCompression, file, directory, outputChunkStreamVersion, dsync, false); + return getAbstractRegionFile(linearCompression, linearInternalCompression, file, directory, outputChunkStreamVersion, dsync, false);
+ } + }
+ +
+ public static AbstractRegionFile getAbstractRegionFile(int linearCompression, Path file, Path directory, RegionFileVersion outputChunkStreamVersion, boolean dsync, boolean canRecalcHeader) throws IOException { + public static AbstractRegionFile getAbstractRegionFile(int linearCompression, int linearInternalCompression, Path file, Path directory, RegionFileVersion outputChunkStreamVersion, boolean dsync, boolean canRecalcHeader) throws IOException {
+ if (file.toString().endsWith(".linear")) { + if (file.toString().endsWith(".linear")) {
+ return new LinearRegionFile(file, linearCompression); + return new LinearRegionFile(file, linearCompression, linearInternalCompression);
+ } else { + } else {
+ return new RegionFile(file, directory, outputChunkStreamVersion, dsync, canRecalcHeader); + return new RegionFile(file, directory, outputChunkStreamVersion, dsync, canRecalcHeader);
+ } + }
@@ -111,18 +112,15 @@ index 0000000000000000000000000000000000000000..dcfbabf54b19a4c29d5c95830242c5c2
+} +}
diff --git a/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFile.java b/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFile.java diff --git a/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFile.java b/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFile.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..f05d6313012560c32a3ec574b7169ec8e8930282 index 0000000000000000000000000000000000000000..df2edc187480aef6af1cbeb82824984e31672068
--- /dev/null --- /dev/null
+++ b/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFile.java +++ b/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFile.java
@@ -0,0 +1,334 @@ @@ -0,0 +1,325 @@
+package dev.kaiijumc.kaiiju.region; +package dev.kaiijumc.kaiiju.region;
+ +
+import com.github.luben.zstd.ZstdInputStream; +import com.github.luben.zstd.Zstd;import com.github.luben.zstd.ZstdInputStream;
+import com.github.luben.zstd.ZstdOutputStream; +import com.github.luben.zstd.ZstdOutputStream;
+import com.mojang.logging.LogUtils; +import com.mojang.logging.LogUtils;
+import net.jpountz.lz4.LZ4Compressor;
+import net.jpountz.lz4.LZ4Factory;
+import net.jpountz.lz4.LZ4FastDecompressor;
+import net.jpountz.xxhash.XXHashFactory; +import net.jpountz.xxhash.XXHashFactory;
+import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.CompoundTag;
+import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.ChunkPos;
@@ -136,6 +134,7 @@ index 0000000000000000000000000000000000000000..f05d6313012560c32a3ec574b7169ec8
+import java.nio.file.Path; +import java.nio.file.Path;
+import java.nio.file.StandardCopyOption; +import java.nio.file.StandardCopyOption;
+import java.util.ArrayList; +import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantLock;
+ +
+public class LinearRegionFile extends Thread implements AbstractRegionFile { +public class LinearRegionFile extends Thread implements AbstractRegionFile {
@@ -153,6 +152,7 @@ index 0000000000000000000000000000000000000000..f05d6313012560c32a3ec574b7169ec8
+ public Path regionFile; + public Path regionFile;
+ +
+ private final int compressionLevel; + private final int compressionLevel;
+ private final int internalCompressionLevel;
+ +
+ public Path getRegionFile() { + public Path getRegionFile() {
+ return this.regionFile; + return this.regionFile;
@@ -162,13 +162,12 @@ index 0000000000000000000000000000000000000000..f05d6313012560c32a3ec574b7169ec8
+ return this.fileLock; + return this.fileLock;
+ } + }
+ +
+ public LinearRegionFile(Path file, int compression) throws IOException { + public LinearRegionFile(Path file, int compression, int internalCompression) throws IOException {
+ this.regionFile = file; + this.regionFile = file;
+ this.compressionLevel = compression; + this.compressionLevel = compression;
+ this.internalCompressionLevel = internalCompression;
+ File regionFile = new File(this.regionFile.toString()); + File regionFile = new File(this.regionFile.toString());
+ +
+ LZ4Compressor compressor = LZ4Factory.fastestInstance().fastCompressor();
+
+ for (int i = 0; i < 32 * 32; i++) + for (int i = 0; i < 32 * 32; i++)
+ this.bufferUncompressedSize[i] = 0; + this.bufferUncompressedSize[i] = 0;
+ +
@@ -184,21 +183,24 @@ index 0000000000000000000000000000000000000000..f05d6313012560c32a3ec574b7169ec8
+ +
+ long superBlock = rawDataStream.readLong(); + long superBlock = rawDataStream.readLong();
+ +
+ if (superBlock != SUPERBLOCK) + if (superBlock != SUPERBLOCK) {
+ throw new RuntimeException("Superblock invalid: " + superBlock + " file " + file); + throw new IOException("SUPERBLOCK VERSION! " + file);
+ }
+ +
+ byte version = rawDataStream.readByte(); + byte version = rawDataStream.readByte();
+ +
+ if (version != VERSION) + if (version != VERSION) {
+ throw new RuntimeException("Version invalid: " + version + " file " + file); + throw new IOException("INVALID VERSION! " + file);
+ }
+ +
+ rawDataStream.readLong(); // newestTimestamp + rawDataStream.readLong(); // newestTimestamp
+ rawDataStream.readByte(); // Compression level + rawDataStream.readByte(); // Compression level
+ rawDataStream.readShort(); // Chunk count + rawDataStream.readShort(); // Chunk count
+ int dataCount = rawDataStream.readInt(); + int dataCount = rawDataStream.readInt();
+ +
+ if (fileLength != HEADER_SIZE + dataCount + FOOTER_SIZE) + if (fileLength != HEADER_SIZE + dataCount + FOOTER_SIZE) {
+ throw new IOException("File length invalid " + this.regionFile + " " + fileLength + " " + (HEADER_SIZE + dataCount + FOOTER_SIZE)); + throw new IOException("File length invalid " + this.regionFile + " " + fileLength + " " + (HEADER_SIZE + dataCount + FOOTER_SIZE));
+ }
+ +
+ rawDataStream.readLong(); // Data Hash + rawDataStream.readLong(); // Data Hash
+ byte[] rawCompressed = new byte[dataCount]; + byte[] rawCompressed = new byte[dataCount];
@@ -225,11 +227,10 @@ index 0000000000000000000000000000000000000000..f05d6313012560c32a3ec574b7169ec8
+ byte[] b = new byte[size]; + byte[] b = new byte[size];
+ dataStream.readFully(b, 0, size); + dataStream.readFully(b, 0, size);
+ +
+ int maxCompressedLength = compressor.maxCompressedLength(size); + int maxCompressedLength = (int)Zstd.compressBound(size);
+ byte[] compressed = new byte[maxCompressedLength]; + byte[] compressed = new byte[maxCompressedLength];
+ int compressedLength = compressor.compress(b, 0, size, compressed, 0, maxCompressedLength); + long compressedLength = Zstd.compress(compressed, b, this.internalCompressionLevel);
+ b = new byte[compressedLength]; + b = Arrays.copyOfRange(compressed, 0, (int) compressedLength);
+ System.arraycopy(compressed, 0, b, 0, compressedLength);
+ +
+ this.buffer[i] = b; + this.buffer[i] = b;
+ this.bufferUncompressedSize[i] = size; + this.bufferUncompressedSize[i] = size;
@@ -262,7 +263,7 @@ index 0000000000000000000000000000000000000000..f05d6313012560c32a3ec574b7169ec8
+ try { + try {
+ flush(); + flush();
+ } catch(IOException ex) { + } catch(IOException ex) {
+ LOGGER.error("Region file " + this.regionFile.toAbsolutePath() + " flush failed"); + LOGGER.error("Region file " + this.regionFile.toAbsolutePath() + " flush failed", ex);
+ } + }
+ } + }
+ for(int i = 0 ; i < 100 ; i++) { + for(int i = 0 ; i < 100 ; i++) {
@@ -302,14 +303,12 @@ index 0000000000000000000000000000000000000000..f05d6313012560c32a3ec574b7169ec8
+ dataStream.writeLong(timestamp); + dataStream.writeLong(timestamp);
+ dataStream.writeByte(this.compressionLevel); + dataStream.writeByte(this.compressionLevel);
+ +
+ LZ4FastDecompressor decompressor = LZ4Factory.fastestInstance().fastDecompressor();
+
+ ArrayList<byte[]> byteBuffers = new ArrayList<>(); + ArrayList<byte[]> byteBuffers = new ArrayList<>();
+ for(int i = 0 ; i < 32 * 32 ; i++) { + for(int i = 0 ; i < 32 * 32 ; i++) {
+ if(this.bufferUncompressedSize[i] != 0) { + if(this.bufferUncompressedSize[i] != 0) {
+ chunkCount += 1; + chunkCount += 1;
+ byte[] content = new byte[bufferUncompressedSize[i]]; + byte[] content = new byte[bufferUncompressedSize[i]];
+ decompressor.decompress(buffer[i], 0, content, 0, bufferUncompressedSize[i]); + Zstd.decompress(content, buffer[i]);
+ +
+ byteBuffers.add(content); + byteBuffers.add(content);
+ } else byteBuffers.add(null); + } else byteBuffers.add(null);
@@ -345,18 +344,11 @@ index 0000000000000000000000000000000000000000..f05d6313012560c32a3ec574b7169ec8
+ } + }
+ +
+ public synchronized void write(ChunkPos pos, ByteBuffer buffer) { + public synchronized void write(ChunkPos pos, ByteBuffer buffer) {
+ LZ4Compressor compressor = LZ4Factory.fastestInstance().fastCompressor();
+ try { + try {
+ byte[] b = toByteArray(new ByteArrayInputStream(buffer.array())); + byte[] b = toByteArray(new ByteArrayInputStream(buffer.array()));
+ int uncompressedSize = b.length; + int uncompressedSize = b.length;
+ + byte[] compressed = Zstd.compress(b, this.internalCompressionLevel);
+ int maxCompressedLength = compressor.maxCompressedLength(b.length); + this.buffer[getChunkIndex(pos.x, pos.z)] = compressed;
+ byte[] compressed = new byte[maxCompressedLength];
+ int compressedLength = compressor.compress(b, 0, b.length, compressed, 0, maxCompressedLength);
+ b = new byte[compressedLength];
+ System.arraycopy(compressed, 0, b, 0, compressedLength);
+
+ this.buffer[getChunkIndex(pos.x, pos.z)] = b;
+ this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] = uncompressedSize; + this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] = uncompressedSize;
+ } catch (IOException e) { + } catch (IOException e) {
+ LOGGER.error("Chunk write IOException " + e + " " + this.regionFile); + LOGGER.error("Chunk write IOException " + e + " " + this.regionFile);
@@ -398,10 +390,10 @@ index 0000000000000000000000000000000000000000..f05d6313012560c32a3ec574b7169ec8
+ +
+ @Nullable + @Nullable
+ public synchronized DataInputStream getChunkDataInputStream(ChunkPos pos) { + public synchronized DataInputStream getChunkDataInputStream(ChunkPos pos) {
+ if(this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] != 0) { + if (this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] != 0) {
+ LZ4FastDecompressor decompressor = LZ4Factory.fastestInstance().fastDecompressor(); + byte[] compressedData = this.buffer[getChunkIndex(pos.x, pos.z)];
+ byte[] content = new byte[bufferUncompressedSize[getChunkIndex(pos.x, pos.z)]]; + byte[] content = new byte[bufferUncompressedSize[getChunkIndex(pos.x, pos.z)]];
+ decompressor.decompress(this.buffer[getChunkIndex(pos.x, pos.z)], 0, content, 0, bufferUncompressedSize[getChunkIndex(pos.x, pos.z)]); + Zstd.decompress(content, compressedData);
+ return new DataInputStream(new ByteArrayInputStream(content)); + return new DataInputStream(new ByteArrayInputStream(content));
+ } + }
+ return null; + return null;
@@ -517,48 +509,50 @@ index a08cde4eefe879adcee7c4118bc38f98c5097ed0..1cfc20b7496f93aff1d6c2387dc5bb8b
} }
} }
diff --git a/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java b/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java diff --git a/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java b/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java
index 513833c2ea23df5b079d157bc5cb89d5c9754c0b..a62a1b281bd0b6ad7d59b45b9470d84f496f6539 100644 index 95cac7edae8ac64811fc6a2f6b97dd4a0fceb0b0..e340878efb93499acd7fdf83a66ead9b53210a76 100644
--- a/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java --- a/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java
+++ b/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java +++ b/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java
@@ -83,9 +83,13 @@ public class ThreadedWorldUpgrader { @@ -83,9 +83,15 @@ public class ThreadedWorldUpgrader {
} }
LOGGER.info("Found " + regionFiles.length + " regionfiles to convert"); LOGGER.info("Found " + regionFiles.length + " regionfiles to convert");
LOGGER.info("Starting conversion now for world " + this.worldName); LOGGER.info("Starting conversion now for world " + this.worldName);
- -
+ // Kaiiju start + // Kaiiju start
+ String formatName = ((org.bukkit.craftbukkit.CraftWorld) org.bukkit.Bukkit.getWorld(worldName)).getHandle().kaiijuConfig.regionFormatName; + net.minecraft.server.level.ServerLevel level = ((org.bukkit.craftbukkit.CraftWorld) org.bukkit.Bukkit.getWorld(worldName)).getHandle();
+ int linearCompression = ((org.bukkit.craftbukkit.CraftWorld) org.bukkit.Bukkit.getWorld(worldName)).getHandle().kaiijuConfig.regionFormatLinearCompressionLevel; + String formatName = level.kaiijuConfig.regionFormatName;
+ int linearCompression = level.kaiijuConfig.regionFormatLinearCompressionLevel;
+ int internalLinearCompression = level.kaiijuConfig.regionFormatLinearInternalCompressionLevel;
+ LOGGER.info("Using format " + formatName + " (" + linearCompression + ")"); + LOGGER.info("Using format " + formatName + " (" + linearCompression + ")");
+ // Kaiiju end + // Kaiiju end
final WorldInfo info = new WorldInfo(() -> worldPersistentData, final WorldInfo info = new WorldInfo(() -> worldPersistentData,
- new ChunkStorage(regionFolder.toPath(), this.dataFixer, false), this.removeCaches, this.dimensionType, this.generatorKey); - new ChunkStorage(regionFolder.toPath(), this.dataFixer, false), this.removeCaches, this.dimensionType, this.generatorKey);
+ new ChunkStorage(formatName, linearCompression, regionFolder.toPath(), this.dataFixer, false), this.removeCaches, this.dimensionType, this.generatorKey); // Kaiiju + new ChunkStorage(formatName, linearCompression, internalLinearCompression, regionFolder.toPath(), this.dataFixer, false), this.removeCaches, this.dimensionType, this.generatorKey); // Kaiiju
long expectedChunks = (long)regionFiles.length * (32L * 32L); long expectedChunks = (long)regionFiles.length * (32L * 32L);
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 5d330c938aa0d707460b740ecf5c51d001c89c49..86dc7e23fb53f6ba8baff1aa0309af78b248844b 100644 index 75965afd7b4bed23a5ecf618c7f91ff5e7ffd92f..3dd88803c5897ac856c107e7f54c3b73cba5adf8 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -294,7 +294,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -291,7 +291,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper end // Paper end
public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor executor, BlockableEventLoop<Runnable> mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier<DimensionDataStorage> persistentStateManagerFactory, int viewDistance, boolean dsync) { public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor executor, BlockableEventLoop<Runnable> mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier<DimensionDataStorage> persistentStateManagerFactory, int viewDistance, boolean dsync) {
- super(session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync); - super(session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync);
+ super(world.getLevel().kaiijuConfig.regionFormatName, world.getLevel().kaiijuConfig.regionFormatLinearCompressionLevel, session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync); // Kaiiju + super(world.getLevel().kaiijuConfig.regionFormatName, world.getLevel().kaiijuConfig.regionFormatLinearCompressionLevel, world.getLevel().kaiijuConfig.regionFormatLinearInternalCompressionLevel, session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync); // Kaiiju
// Paper - rewrite chunk system // Paper - rewrite chunk system
this.tickingGenerated = new AtomicInteger(); this.tickingGenerated = new AtomicInteger();
this.playerMap = new PlayerMap(); this.playerMap = new PlayerMap();
@@ -339,7 +339,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -336,7 +336,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.lightEngine = new ThreadedLevelLightEngine(chunkProvider, this, this.level.dimensionType().hasSkyLight(), null, null); // Paper - rewrite chunk system this.lightEngine = new ThreadedLevelLightEngine(chunkProvider, this, this.level.dimensionType().hasSkyLight(), null, null); // Paper - rewrite chunk system
this.distanceManager = new ChunkMap.ChunkDistanceManager(executor, mainThreadExecutor); this.distanceManager = new ChunkMap.ChunkDistanceManager(executor, mainThreadExecutor);
this.overworldDataStorage = persistentStateManagerFactory; this.overworldDataStorage = persistentStateManagerFactory;
- this.poiManager = new PoiManager(path.resolve("poi"), dataFixer, dsync, iregistrycustom, world); - this.poiManager = new PoiManager(path.resolve("poi"), dataFixer, dsync, iregistrycustom, world);
+ this.poiManager = new PoiManager(this.level.kaiijuConfig.regionFormatName, this.level.kaiijuConfig.regionFormatLinearCompressionLevel, path.resolve("poi"), dataFixer, dsync, iregistrycustom, world); // Kaiiju + this.poiManager = new PoiManager(this.level.kaiijuConfig.regionFormatName, this.level.kaiijuConfig.regionFormatLinearCompressionLevel, this.level.kaiijuConfig.regionFormatLinearInternalCompressionLevel, path.resolve("poi"), dataFixer, dsync, iregistrycustom, world); // Kaiiju
this.setViewDistance(viewDistance); this.setViewDistance(viewDistance);
// Paper start // Paper start
this.dataRegionManager = new io.papermc.paper.chunk.SingleThreadChunkRegionManager(this.level, 2, (1.0 / 3.0), 1, 6, "Data", DataRegionData::new, DataRegionSectionData::new); this.dataRegionManager = new io.papermc.paper.chunk.SingleThreadChunkRegionManager(this.level, 2, (1.0 / 3.0), 1, 6, "Data", DataRegionData::new, DataRegionSectionData::new);
@@ -953,13 +953,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -950,13 +950,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper start - chunk status cache "api" // Paper start - chunk status cache "api"
public ChunkStatus getChunkStatusOnDiskIfCached(ChunkPos chunkPos) { public ChunkStatus getChunkStatusOnDiskIfCached(ChunkPos chunkPos) {
@@ -574,7 +568,7 @@ index 5d330c938aa0d707460b740ecf5c51d001c89c49..86dc7e23fb53f6ba8baff1aa0309af78
if (regionFile == null || !regionFileCache.chunkExists(chunkPos)) { if (regionFile == null || !regionFileCache.chunkExists(chunkPos)) {
return null; return null;
@@ -977,7 +977,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -974,7 +974,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
} }
public void updateChunkStatusOnDisk(ChunkPos chunkPos, @Nullable CompoundTag compound) throws IOException { public void updateChunkStatusOnDisk(ChunkPos chunkPos, @Nullable CompoundTag compound) throws IOException {
@@ -584,18 +578,18 @@ index 5d330c938aa0d707460b740ecf5c51d001c89c49..86dc7e23fb53f6ba8baff1aa0309af78
regionFile.setStatus(chunkPos.x, chunkPos.z, ChunkSerializer.getStatus(compound)); regionFile.setStatus(chunkPos.x, chunkPos.z, ChunkSerializer.getStatus(compound));
} }
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 69ba84de4880a579c400b6daefdb98b44e9e28e8..83126ee9d737cf695c34e239c204fe8c4d02c243 100644 index a5655ebb233f1e1e1dd7f79fdd948020478928fc..92430e71f64d88352838ee9cf0f4d22c050e7acc 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java --- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -388,9 +388,8 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -390,9 +390,8 @@ public class ServerLevel extends Level implements WorldGenLevel {
private final EntityRegionFileStorage entityStorage; private final EntityRegionFileStorage entityStorage;
private static final class EntityRegionFileStorage extends net.minecraft.world.level.chunk.storage.RegionFileStorage { private static final class EntityRegionFileStorage extends net.minecraft.world.level.chunk.storage.RegionFileStorage {
- -
- public EntityRegionFileStorage(Path directory, boolean dsync) { - public EntityRegionFileStorage(Path directory, boolean dsync) {
- super(directory, dsync); - super(directory, dsync);
+ public EntityRegionFileStorage(String format, int linearCompression, Path directory, boolean dsync) { // Kaiiju + public EntityRegionFileStorage(String format, int linearCompression, int linearInternalCompression, Path directory, boolean dsync) { // Kaiiju
+ super(format, linearCompression, directory, dsync); // Kaiiju + super(format, linearCompression, linearInternalCompression, directory, dsync); // Kaiiju
} }
protected void write(ChunkPos pos, net.minecraft.nbt.CompoundTag nbt) throws IOException { protected void write(ChunkPos pos, net.minecraft.nbt.CompoundTag nbt) throws IOException {
@@ -604,12 +598,12 @@ index 69ba84de4880a579c400b6daefdb98b44e9e28e8..83126ee9d737cf695c34e239c204fe8c
boolean flag2 = minecraftserver.forceSynchronousWrites(); boolean flag2 = minecraftserver.forceSynchronousWrites();
DataFixer datafixer = minecraftserver.getFixerUpper(); DataFixer datafixer = minecraftserver.getFixerUpper();
- this.entityStorage = new EntityRegionFileStorage(convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), flag2); // Paper - rewrite chunk system //EntityPersistentStorage<Entity> entitypersistentstorage = new EntityStorage(this, convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, minecraftserver); - this.entityStorage = new EntityRegionFileStorage(convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), flag2); // Paper - rewrite chunk system //EntityPersistentStorage<Entity> entitypersistentstorage = new EntityStorage(this, convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, minecraftserver);
+ this.entityStorage = new EntityRegionFileStorage(this.getLevel().kaiijuConfig.regionFormatName, this.getLevel().kaiijuConfig.regionFormatLinearCompressionLevel, convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), flag2); // Paper - rewrite chunk system //EntityPersistentStorage<Entity> entitypersistentstorage = new EntityStorage(this, convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, minecraftserver); // Kaiiju + this.entityStorage = new EntityRegionFileStorage(this.getLevel().kaiijuConfig.regionFormatName, this.getLevel().kaiijuConfig.regionFormatLinearCompressionLevel, this.getLevel().kaiijuConfig.regionFormatLinearInternalCompressionLevel, convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), flag2); // Paper - rewrite chunk system //EntityPersistentStorage<Entity> entitypersistentstorage = new EntityStorage(this, convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, minecraftserver); // Kaiiju
// this.entityManager = new PersistentEntitySectionManager<>(Entity.class, new ServerLevel.EntityCallbacks(), entitypersistentstorage, this.entitySliceManager); // Paper // Paper - rewrite chunk system // this.entityManager = new PersistentEntitySectionManager<>(Entity.class, new ServerLevel.EntityCallbacks(), entitypersistentstorage, this.entitySliceManager); // Paper // Paper - rewrite chunk system
StructureTemplateManager structuretemplatemanager = minecraftserver.getStructureManager(); StructureTemplateManager structuretemplatemanager = minecraftserver.getStructureManager();
diff --git a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java diff --git a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
index e0bfeebeaac1aaea64bc07cdfdf7790e3e43ca7b..469802b9c454c5e98c0a55ba89559d9d8ba0c4c0 100644 index 759b125cc1251b9b4f1f443c9f70c482ef5b32f8..761293b17cf12e28487034508906702bae2a3feb 100644
--- a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java --- a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
+++ b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java +++ b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
@@ -61,7 +61,7 @@ public class WorldUpgrader { @@ -61,7 +61,7 @@ public class WorldUpgrader {
@@ -621,7 +615,7 @@ index e0bfeebeaac1aaea64bc07cdfdf7790e3e43ca7b..469802b9c454c5e98c0a55ba89559d9d
private final DimensionDataStorage overworldDataStorage; private final DimensionDataStorage overworldDataStorage;
public WorldUpgrader(LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, Registry<LevelStem> dimensionOptionsRegistry, boolean eraseCache) { public WorldUpgrader(LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, Registry<LevelStem> dimensionOptionsRegistry, boolean eraseCache) {
@@ -115,8 +115,12 @@ public class WorldUpgrader { @@ -115,8 +115,14 @@ public class WorldUpgrader {
while (iterator1.hasNext()) { while (iterator1.hasNext()) {
ResourceKey<LevelStem> resourcekey1 = (ResourceKey) iterator1.next(); // CraftBukkit ResourceKey<LevelStem> resourcekey1 = (ResourceKey) iterator1.next(); // CraftBukkit
Path path = this.levelStorage.getDimensionPath((ResourceKey) null); // CraftBukkit Path path = this.levelStorage.getDimensionPath((ResourceKey) null); // CraftBukkit
@@ -629,14 +623,16 @@ index e0bfeebeaac1aaea64bc07cdfdf7790e3e43ca7b..469802b9c454c5e98c0a55ba89559d9d
- builder1.put(resourcekey1, new ChunkStorage(path.resolve("region"), this.dataFixer, true)); - builder1.put(resourcekey1, new ChunkStorage(path.resolve("region"), this.dataFixer, true));
+ // Kaiiju start + // Kaiiju start
+ String worldName = this.levelStorage.getLevelId(); + String worldName = this.levelStorage.getLevelId();
+ String formatName = ((org.bukkit.craftbukkit.CraftWorld) org.bukkit.Bukkit.getWorld(worldName)).getHandle().kaiijuConfig.regionFormatName; + net.minecraft.server.level.ServerLevel level = ((org.bukkit.craftbukkit.CraftWorld) org.bukkit.Bukkit.getWorld(worldName)).getHandle();
+ int linearCompression = ((org.bukkit.craftbukkit.CraftWorld) org.bukkit.Bukkit.getWorld(worldName)).getHandle().kaiijuConfig.regionFormatLinearCompressionLevel; + String formatName = level.kaiijuConfig.regionFormatName;
+ builder1.put(resourcekey1, new ChunkStorage(formatName, linearCompression, path.resolve("region"), this.dataFixer, true)); + int linearCompression = level.kaiijuConfig.regionFormatLinearCompressionLevel;
+ int linearInternalCompression = level.kaiijuConfig.regionFormatLinearInternalCompressionLevel;
+ builder1.put(resourcekey1, new ChunkStorage(formatName, linearCompression, linearInternalCompression, path.resolve("region"), this.dataFixer, true));
+ // Kaiiju end + // Kaiiju end
} }
ImmutableMap<ResourceKey<LevelStem>, ChunkStorage> immutablemap1 = builder1.build(); // CraftBukkit ImmutableMap<ResourceKey<LevelStem>, ChunkStorage> immutablemap1 = builder1.build(); // CraftBukkit
@@ -235,7 +239,7 @@ public class WorldUpgrader { @@ -235,7 +241,7 @@ public class WorldUpgrader {
File file = this.levelStorage.getDimensionPath((ResourceKey) null).toFile(); // CraftBukkit File file = this.levelStorage.getDimensionPath((ResourceKey) null).toFile(); // CraftBukkit
File file1 = new File(file, "region"); File file1 = new File(file, "region");
File[] afile = file1.listFiles((file2, s) -> { File[] afile = file1.listFiles((file2, s) -> {
@@ -645,21 +641,23 @@ index e0bfeebeaac1aaea64bc07cdfdf7790e3e43ca7b..469802b9c454c5e98c0a55ba89559d9d
}); });
if (afile == null) { if (afile == null) {
@@ -254,7 +258,11 @@ public class WorldUpgrader { @@ -254,7 +260,13 @@ public class WorldUpgrader {
int l = Integer.parseInt(matcher.group(2)) << 5; int l = Integer.parseInt(matcher.group(2)) << 5;
try { try {
- RegionFile regionfile = new RegionFile(file2.toPath(), file1.toPath(), true); - RegionFile regionfile = new RegionFile(file2.toPath(), file1.toPath(), true);
+ // Kaiiju start + // Kaiiju start
+ String worldName = this.levelStorage.getLevelId(); + String worldName = this.levelStorage.getLevelId();
+ int linearCompression = ((org.bukkit.craftbukkit.CraftWorld) org.bukkit.Bukkit.getWorld(worldName)).getHandle().kaiijuConfig.regionFormatLinearCompressionLevel; + net.minecraft.server.level.ServerLevel level = ((org.bukkit.craftbukkit.CraftWorld) org.bukkit.Bukkit.getWorld(worldName)).getHandle();
+ dev.kaiijumc.kaiiju.region.AbstractRegionFile regionfile = dev.kaiijumc.kaiiju.region.AbstractRegionFileFactory.getAbstractRegionFile(linearCompression, file2.toPath(), file1.toPath(), true); + int linearCompression = level.kaiijuConfig.regionFormatLinearCompressionLevel;
+ int linearInternalCompression = level.kaiijuConfig.regionFormatLinearInternalCompressionLevel;
+ dev.kaiijumc.kaiiju.region.AbstractRegionFile regionfile = dev.kaiijumc.kaiiju.region.AbstractRegionFileFactory.getAbstractRegionFile(linearCompression, linearInternalCompression, file2.toPath(), file1.toPath(), true);
+ // Kaiiju end + // Kaiiju end
try { try {
for (int i1 = 0; i1 < 32; ++i1) { for (int i1 = 0; i1 < 32; ++i1) {
diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java
index 8950b220b9a3512cd4667beb7bdec0e82e07edc6..71b38521fd2039bb2ddfdc5dc89341282869ce30 100644 index 8950b220b9a3512cd4667beb7bdec0e82e07edc6..ca93af37207a78e41b6d20333638bec32c11c416 100644
--- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java
+++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java
@@ -57,8 +57,8 @@ public class PoiManager extends SectionStorage<PoiSection> { @@ -57,8 +57,8 @@ public class PoiManager extends SectionStorage<PoiSection> {
@@ -668,13 +666,13 @@ index 8950b220b9a3512cd4667beb7bdec0e82e07edc6..71b38521fd2039bb2ddfdc5dc8934128
- public PoiManager(Path path, DataFixer dataFixer, boolean dsync, RegistryAccess registryManager, LevelHeightAccessor world) { - public PoiManager(Path path, DataFixer dataFixer, boolean dsync, RegistryAccess registryManager, LevelHeightAccessor world) {
- super(path, PoiSection::codec, PoiSection::new, dataFixer, DataFixTypes.POI_CHUNK, dsync, registryManager, world); - super(path, PoiSection::codec, PoiSection::new, dataFixer, DataFixTypes.POI_CHUNK, dsync, registryManager, world);
+ public PoiManager(String formatName, int linearCompression, Path path, DataFixer dataFixer, boolean dsync, RegistryAccess registryManager, LevelHeightAccessor world) { // Kaiiju + public PoiManager(String formatName, int linearCompression, int linearInternalCompression, Path path, DataFixer dataFixer, boolean dsync, RegistryAccess registryManager, LevelHeightAccessor world) { // Kaiiju
+ super(formatName, linearCompression, path, PoiSection::codec, PoiSection::new, dataFixer, DataFixTypes.POI_CHUNK, dsync, registryManager, world); // Kaiiju + super(formatName, linearCompression, linearInternalCompression, path, PoiSection::codec, PoiSection::new, dataFixer, DataFixTypes.POI_CHUNK, dsync, registryManager, world); // Kaiiju
this.world = (net.minecraft.server.level.ServerLevel)world; // Paper - rewrite chunk system this.world = (net.minecraft.server.level.ServerLevel)world; // Paper - rewrite chunk system
} }
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
index 29facbdcbad17ce38bf785f7f3f8346d81cbc32f..52c2e0fe73a5af18535a2b0b9a506919e3f93003 100644 index 5a425be023d77f0370d102dfb52427147849ac1a..527384a43f5c512273cce0d16a3bc887e24357c2 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java --- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
@@ -37,11 +37,12 @@ public class ChunkStorage implements AutoCloseable { @@ -37,11 +37,12 @@ public class ChunkStorage implements AutoCloseable {
@@ -682,13 +680,13 @@ index 29facbdcbad17ce38bf785f7f3f8346d81cbc32f..52c2e0fe73a5af18535a2b0b9a506919
// Paper end - async chunk loading // Paper end - async chunk loading
- public ChunkStorage(Path directory, DataFixer dataFixer, boolean dsync) { - public ChunkStorage(Path directory, DataFixer dataFixer, boolean dsync) {
+ public ChunkStorage(String format, int linearCompression, Path directory, DataFixer dataFixer, boolean dsync) { // Kaiiju + public ChunkStorage(String format, int linearCompression, int linearInternalCompression, Path directory, DataFixer dataFixer, boolean dsync) { // Kaiiju
this.fixerUpper = dataFixer; this.fixerUpper = dataFixer;
+ +
// Paper start - async chunk io // Paper start - async chunk io
// remove IO worker // remove IO worker
- this.regionFileCache = new RegionFileStorage(directory, dsync, true); // Paper - nuke IOWorker // Paper - this.regionFileCache = new RegionFileStorage(directory, dsync, true); // Paper - nuke IOWorker // Paper
+ this.regionFileCache = new RegionFileStorage(format, linearCompression, directory, dsync, true); // Paper - nuke IOWorker // Paper + this.regionFileCache = new RegionFileStorage(format, linearCompression, linearInternalCompression, directory, dsync, true); // Paper - nuke IOWorker // Paper // Kaiiju
// Paper end - async chunk io // Paper end - async chunk io
} }
@@ -754,10 +752,10 @@ index dcfe090c269d4cbcc2eb1b6f85392848bb34656c..d42c320179ae055b8675d1ce6ce1788e
try (DataInputStream out = new DataInputStream(new java.io.BufferedInputStream(new InflaterInputStream(Files.newInputStream(file))))) { try (DataInputStream out = new DataInputStream(new java.io.BufferedInputStream(new InflaterInputStream(Files.newInputStream(file))))) {
return NbtIo.read((java.io.DataInput) out); 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 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 bd502ca721de0cab438d995efa00ad0554c0d2fe..254bc0d853770ef36ff10bce92be37f0300335fb 100644 index bd502ca721de0cab438d995efa00ad0554c0d2fe..ad784bc53d5c9a4abb944ce21e5bb81b939ecbea 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java --- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -22,17 +22,25 @@ public class RegionFileStorage implements AutoCloseable { @@ -22,17 +22,27 @@ public class RegionFileStorage implements AutoCloseable {
public static final String ANVIL_EXTENSION = ".mca"; public static final String ANVIL_EXTENSION = ".mca";
private static final int MAX_CACHE_SIZE = 256; private static final int MAX_CACHE_SIZE = 256;
@@ -768,26 +766,28 @@ index bd502ca721de0cab438d995efa00ad0554c0d2fe..254bc0d853770ef36ff10bce92be37f0
+ // Kaiiju start - Per world chunk format + // Kaiiju start - Per world chunk format
+ public final String format; + public final String format;
+ public final int linearCompression; + public final int linearCompression;
+ public final int linearInternalCompression;
+ // Kaiiju end + // Kaiiju end
private final boolean isChunkData; // Paper private final boolean isChunkData; // Paper
- protected RegionFileStorage(Path directory, boolean dsync) { // Paper - protected constructor - protected RegionFileStorage(Path directory, boolean dsync) { // Paper - protected constructor
+ protected RegionFileStorage(String format, int linearCompression, Path directory, boolean dsync) { // Paper - protected constructor + protected RegionFileStorage(String format, int linearCompression, int linearInternalCompression, Path directory, boolean dsync) { // Paper - protected constructor
// Paper start - add isChunkData param // Paper start - add isChunkData param
- this(directory, dsync, false); - this(directory, dsync, false);
+ this(format, linearCompression, directory, dsync, false); + this(format, linearCompression, linearInternalCompression, directory, dsync, false);
} }
- RegionFileStorage(Path directory, boolean dsync, boolean isChunkData) { - RegionFileStorage(Path directory, boolean dsync, boolean isChunkData) {
+ RegionFileStorage(String format, int linearCompression, Path directory, boolean dsync, boolean isChunkData) { // Kaiiju + RegionFileStorage(String format, int linearCompression, int linearInternalCompression, Path directory, boolean dsync, boolean isChunkData) { // Kaiiju
+ // Kaiiju start + // Kaiiju start
+ this.format = format; + this.format = format;
+ this.linearCompression = linearCompression; + this.linearCompression = linearCompression;
+ this.linearInternalCompression = linearInternalCompression;
+ // Kaiiju end + // Kaiiju end
this.isChunkData = isChunkData; this.isChunkData = isChunkData;
// Paper end - add isChunkData param // Paper end - add isChunkData param
this.folder = directory; this.folder = directory;
@@ -42,7 +50,7 @@ public class RegionFileStorage implements AutoCloseable { @@ -42,7 +52,7 @@ public class RegionFileStorage implements AutoCloseable {
// Paper start // Paper start
public static @Nullable ChunkPos getRegionFileCoordinates(Path file) { public static @Nullable ChunkPos getRegionFileCoordinates(Path file) {
String fileName = file.getFileName().toString(); String fileName = file.getFileName().toString();
@@ -796,7 +796,7 @@ index bd502ca721de0cab438d995efa00ad0554c0d2fe..254bc0d853770ef36ff10bce92be37f0
return null; return null;
} }
@@ -62,49 +70,68 @@ public class RegionFileStorage implements AutoCloseable { @@ -62,49 +72,66 @@ public class RegionFileStorage implements AutoCloseable {
} }
} }
@@ -860,12 +860,10 @@ index bd502ca721de0cab438d995efa00ad0554c0d2fe..254bc0d853770ef36ff10bce92be37f0
+ }; + };
+ path1 = path.resolve("r." + j + "." + chunkcoordintpair.getRegionZ() + "." + extension); + path1 = path.resolve("r." + j + "." + chunkcoordintpair.getRegionZ() + "." + extension);
+ } + }
+ if (dev.kaiijumc.kaiiju.KaiijuConfig.regionFormatDebug)
+ org.bukkit.Bukkit.getLogger().info("[Region File Storage] Opening file " + path1 + " with format " + this.format + " (existingOnly = " + existingOnly + ")");
+ //if (existingOnly && !java.nio.file.Files.exists(path1)) return null; // CraftBukkit + //if (existingOnly && !java.nio.file.Files.exists(path1)) return null; // CraftBukkit
+ // Kaiiju end + // Kaiiju end
+ +
+ dev.kaiijumc.kaiiju.region.AbstractRegionFile regionfile1 = dev.kaiijumc.kaiiju.region.AbstractRegionFileFactory.getAbstractRegionFile(this.linearCompression, path1, this.folder, this.sync, this.isChunkData); // Paper - allow for chunk regionfiles to regen header // Kaiiju + dev.kaiijumc.kaiiju.region.AbstractRegionFile regionfile1 = dev.kaiijumc.kaiiju.region.AbstractRegionFileFactory.getAbstractRegionFile(this.linearCompression, this.linearInternalCompression, path1, this.folder, this.sync, this.isChunkData); // Paper - allow for chunk regionfiles to regen header // Kaiiju
this.regionCache.putAndMoveToFirst(i, regionfile1); this.regionCache.putAndMoveToFirst(i, regionfile1);
// Paper start // Paper start
@@ -980,7 +978,7 @@ index bd502ca721de0cab438d995efa00ad0554c0d2fe..254bc0d853770ef36ff10bce92be37f0
regionfile.flush(); regionfile.flush();
} }
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java
index 5561b8499a0503b850974b1dc309edfb80219549..414aa3ae00c2d28e754235e3e93b6b623d4fd180 100644 index d783072bc964e45c308197e6f79874eb4a09f871..f335bb86031c4efbc88f44d542eefcc6815cd2b7 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java --- a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java
@@ -47,8 +47,8 @@ public class SectionStorage<R> extends RegionFileStorage implements AutoCloseabl @@ -47,8 +47,8 @@ public class SectionStorage<R> extends RegionFileStorage implements AutoCloseabl
@@ -989,13 +987,13 @@ index 5561b8499a0503b850974b1dc309edfb80219549..414aa3ae00c2d28e754235e3e93b6b62
- public SectionStorage(Path path, Function<Runnable, Codec<R>> codecFactory, Function<Runnable, R> factory, DataFixer dataFixer, DataFixTypes dataFixTypes, boolean dsync, RegistryAccess dynamicRegistryManager, LevelHeightAccessor world) { - public SectionStorage(Path path, Function<Runnable, Codec<R>> codecFactory, Function<Runnable, R> factory, DataFixer dataFixer, DataFixTypes dataFixTypes, boolean dsync, RegistryAccess dynamicRegistryManager, LevelHeightAccessor world) {
- super(path, dsync); // Paper - remove mojang I/O thread - super(path, dsync); // Paper - remove mojang I/O thread
+ public SectionStorage(String format, int linearCompression, Path path, Function<Runnable, Codec<R>> codecFactory, Function<Runnable, R> factory, DataFixer dataFixer, DataFixTypes dataFixTypes, boolean dsync, RegistryAccess dynamicRegistryManager, LevelHeightAccessor world) { // Kaiiju + public SectionStorage(String format, int linearCompression, int linearInternalCompression, Path path, Function<Runnable, Codec<R>> codecFactory, Function<Runnable, R> factory, DataFixer dataFixer, DataFixTypes dataFixTypes, boolean dsync, RegistryAccess dynamicRegistryManager, LevelHeightAccessor world) { // Kaiiju
+ super(format, linearCompression, path, dsync); // Paper - remove mojang I/O thread // Kaiiju + super(format, linearCompression, linearInternalCompression, path, dsync); // Paper - remove mojang I/O thread // Kaiiju
this.codec = codecFactory; this.codec = codecFactory;
this.factory = factory; this.factory = factory;
this.fixerUpper = dataFixer; this.fixerUpper = dataFixer;
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index c6a3b59c65466f9f2b16cefe0059a6e5dd84044c..e9cca721fb065fe6ac715bbeef65343f528d0a42 100644 index 6a327616cd590b70170f8441c003a2109640201d..2ef0a41fd9ee60bc0866cf5c678498c68250689c 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -552,7 +552,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -552,7 +552,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Kaiiju Lobotomize Configuration
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java
index b194f4dbebcbbf5bb4e026a0169e2d24806b46ec..907fdfb368c87bfe7b4374bb0b5f49d5ff095339 100644 index 1b180af49adee16c2d8305d01cf213322c4d721b..daa81b36696e82ba7bbd6eefd746362d7c2ba2f1 100644
--- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java --- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java +++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java
@@ -143,4 +143,7 @@ public class KaiijuWorldConfig { @@ -150,4 +150,7 @@ public class KaiijuWorldConfig {
regionFormatLinearCompressionLevel = 1; regionFormatLinearCompressionLevel = 1;
} }
} }

View File

@@ -7,10 +7,10 @@ Inspired by "Lobotomized animals" by @KioProject123
Checks might be a nuisance to performance. Checks might be a nuisance to performance.
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java
index 907fdfb368c87bfe7b4374bb0b5f49d5ff095339..b99b438b92587f23c77c5321d5d23e76dc5450de 100644 index daa81b36696e82ba7bbd6eefd746362d7c2ba2f1..f4af17136437cff7052827b027e3d2a75801b6eb 100644
--- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java --- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java +++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java
@@ -144,6 +144,17 @@ public class KaiijuWorldConfig { @@ -151,6 +151,17 @@ public class KaiijuWorldConfig {
} }
} }
@@ -31,7 +31,7 @@ index 907fdfb368c87bfe7b4374bb0b5f49d5ff095339..b99b438b92587f23c77c5321d5d23e76
\ No newline at end of file \ No newline at end of file
diff --git a/src/main/java/dev/kaiijumc/kaiiju/entity/Lobotomized.java b/src/main/java/dev/kaiijumc/kaiiju/entity/Lobotomized.java diff --git a/src/main/java/dev/kaiijumc/kaiiju/entity/Lobotomized.java b/src/main/java/dev/kaiijumc/kaiiju/entity/Lobotomized.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..14f085e75295882f52634622b40676295cd78d5f index 0000000000000000000000000000000000000000..805df3e27cfbbdf3525c96942afca12d50abc350
--- /dev/null --- /dev/null
+++ b/src/main/java/dev/kaiijumc/kaiiju/entity/Lobotomized.java +++ b/src/main/java/dev/kaiijumc/kaiiju/entity/Lobotomized.java
@@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
@@ -75,7 +75,7 @@ index 0000000000000000000000000000000000000000..14f085e75295882f52634622b4067629
+ } + }
+ +
+ private boolean canTravelFrom(LivingEntity entity, Level level, boolean ignoreTop) { + private boolean canTravelFrom(LivingEntity entity, Level level, boolean ignoreTop) {
+ BlockPos pos = new BlockPos(entity.getBlockX(), (int) (entity.getY() + 0.5D), entity.getBlockZ()); + BlockPos pos = new BlockPos(entity.getX(), entity.getY() + 0.5D, entity.getZ());
+ return canTravelTo(entity, pos.east(), level, ignoreTop) + return canTravelTo(entity, pos.east(), level, ignoreTop)
+ || canTravelTo(entity, pos.west(), level, ignoreTop) + || canTravelTo(entity, pos.west(), level, ignoreTop)
+ || canTravelTo(entity, pos.north(), level, ignoreTop) + || canTravelTo(entity, pos.north(), level, ignoreTop)
@@ -103,16 +103,16 @@ index 0000000000000000000000000000000000000000..14f085e75295882f52634622b4067629
+ } + }
+ +
+ private boolean canJump(LivingEntity entity, Level level, boolean ignoreTop) { + private boolean canJump(LivingEntity entity, Level level, boolean ignoreTop) {
+ BlockPos pos = new BlockPos(entity.getBlockX(), (int) (entity.getY() + 2.5D), entity.getBlockZ()); + BlockPos pos = new BlockPos(entity.getX(), entity.getY() + 2.5D, entity.getZ());
+ net.minecraft.world.level.block.Block above = level.getBlockIfLoaded(pos); + net.minecraft.world.level.block.Block above = level.getBlockIfLoaded(pos);
+ return !above.hasCollision; + return !above.hasCollision;
+ } + }
+} +}
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 8d7c33e16f9eaec2120c5aad75172ff656d1bd17..52b09f9ff2a7bc36ae742a53c5141d7de03fb848 100644 index b2e4b5c463ceb19356da18e7fc52d20801b674cd..32ea0b1542ef374db3290e01978d7965715b9de6 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -303,6 +303,8 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -308,6 +308,8 @@ public abstract class LivingEntity extends Entity {
this.brain = this.makeBrain(new Dynamic(dynamicopsnbt, (Tag) dynamicopsnbt.createMap((Map) ImmutableMap.of(dynamicopsnbt.createString("memories"), (Tag) dynamicopsnbt.emptyMap())))); this.brain = this.makeBrain(new Dynamic(dynamicopsnbt, (Tag) dynamicopsnbt.createMap((Map) ImmutableMap.of(dynamicopsnbt.createString("memories"), (Tag) dynamicopsnbt.emptyMap()))));
} }
@@ -226,10 +226,10 @@ index 2cbc9adc8e417def48be03d08174a5833068ec65..3234d5bf3b9ae01dbe8e26a0a3f21ff8
if (this.mob.distanceToSqr((Entity) this.player) < 36.0D) { if (this.mob.distanceToSqr((Entity) this.player) < 36.0D) {
if (this.player.distanceToSqr(this.px, this.py, this.pz) > 0.010000000000000002D) { if (this.player.distanceToSqr(this.px, this.py, this.pz) > 0.010000000000000002D) {
diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
index 6d127ed3da899851ca95b2be6792e2abca1aca12..31f98654389dc030b70ab38530d4a7be31686279 100644 index 2f2d9bb31194618ef5bba39cd1cbe7c4919e82c5..0d8f1f063b76357374022e4496ce0646757b150e 100644
--- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java --- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
@@ -198,6 +198,7 @@ public abstract class PathNavigation { @@ -197,6 +197,7 @@ public abstract class PathNavigation {
// Paper end // Paper end
public boolean moveTo(Entity entity, double speed) { public boolean moveTo(Entity entity, double speed) {
@@ -237,7 +237,7 @@ index 6d127ed3da899851ca95b2be6792e2abca1aca12..31f98654389dc030b70ab38530d4a7be
// Paper start - Pathfinding optimizations // Paper start - Pathfinding optimizations
if (this.pathfindFailures > 10 && this.path == null && net.minecraft.server.MinecraftServer.currentTick < this.lastFailure + 40) { if (this.pathfindFailures > 10 && this.path == null && net.minecraft.server.MinecraftServer.currentTick < this.lastFailure + 40) {
return false; return false;
@@ -218,6 +219,7 @@ public abstract class PathNavigation { @@ -217,6 +218,7 @@ public abstract class PathNavigation {
} }
public boolean moveTo(@Nullable Path path, double speed) { public boolean moveTo(@Nullable Path path, double speed) {
@@ -321,10 +321,10 @@ index 2ac88f06ebb79e515cd9934ac1e3e2c8003d9e3c..d89c0db4c4173d8558dc4f8b15ddb581
public static boolean checkAnimalSpawnRules(EntityType<? extends Animal> type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) { public static boolean checkAnimalSpawnRules(EntityType<? extends Animal> type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) {
diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java
index d47dc0c3fe8c2b80d7b7eb828a12af6eb32145e4..bb3a7efd11731d518cf8ef29f25c855bbbba0568 100644 index 87bd7991a81a2e30ecfccb60e614d7f13acd3744..1c2db953155498606f1e052580e7aa9ca846a53c 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Bee.java --- a/src/main/java/net/minecraft/world/entity/animal/Bee.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java
@@ -1042,6 +1042,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @@ -1047,6 +1047,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
@Override @Override
public boolean canBeeUse() { public boolean canBeeUse() {
@@ -332,7 +332,7 @@ index d47dc0c3fe8c2b80d7b7eb828a12af6eb32145e4..bb3a7efd11731d518cf8ef29f25c855b
return Bee.this.remainingCooldownBeforeLocatingNewHive == 0 && !Bee.this.hasHive() && Bee.this.wantsToEnterHive(); return Bee.this.remainingCooldownBeforeLocatingNewHive == 0 && !Bee.this.hasHive() && Bee.this.wantsToEnterHive();
} }
@@ -1108,6 +1109,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @@ -1113,6 +1114,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
@Override @Override
public boolean canBeeUse() { public boolean canBeeUse() {
@@ -340,7 +340,7 @@ index d47dc0c3fe8c2b80d7b7eb828a12af6eb32145e4..bb3a7efd11731d518cf8ef29f25c855b
return Bee.this.hivePos != null && !Bee.this.hasRestriction() && Bee.this.wantsToEnterHive() && !this.hasReachedTarget(Bee.this.hivePos) && Bee.this.level.getBlockState(Bee.this.hivePos).is(BlockTags.BEEHIVES); return Bee.this.hivePos != null && !Bee.this.hasRestriction() && Bee.this.wantsToEnterHive() && !this.hasReachedTarget(Bee.this.hivePos) && Bee.this.level.getBlockState(Bee.this.hivePos).is(BlockTags.BEEHIVES);
} }
@@ -1224,6 +1226,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @@ -1229,6 +1231,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
@Override @Override
public boolean canBeeUse() { public boolean canBeeUse() {
@@ -348,7 +348,7 @@ index d47dc0c3fe8c2b80d7b7eb828a12af6eb32145e4..bb3a7efd11731d518cf8ef29f25c855b
return Bee.this.savedFlowerPos != null && !Bee.this.hasRestriction() && this.wantsToGoToKnownFlower() && Bee.this.isFlowerValid(Bee.this.savedFlowerPos) && !Bee.this.closerThan(Bee.this.savedFlowerPos, 2); return Bee.this.savedFlowerPos != null && !Bee.this.hasRestriction() && this.wantsToGoToKnownFlower() && Bee.this.isFlowerValid(Bee.this.savedFlowerPos) && !Bee.this.closerThan(Bee.this.savedFlowerPos, 2);
} }
@@ -1276,6 +1279,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @@ -1281,6 +1284,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
@Override @Override
public boolean canBeeUse() { public boolean canBeeUse() {

View File

@@ -5,15 +5,16 @@ Subject: [PATCH] Kaiiju Lobotomize Villager
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java
index b99b438b92587f23c77c5321d5d23e76dc5450de..366948e447c0729389ec53286236a82cb57e97a2 100644 index f4af17136437cff7052827b027e3d2a75801b6eb..fc715266abdd604bf6c2403b758dcd22440adcbe 100644
--- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java --- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java +++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java
@@ -149,6 +149,12 @@ public class KaiijuWorldConfig { @@ -156,6 +156,13 @@ public class KaiijuWorldConfig {
public boolean lobotomizeAnimalCheckCanJump = true; public boolean lobotomizeAnimalCheckCanJump = true;
public boolean lobotomizeAnimalLookAtPlayer = false; public boolean lobotomizeAnimalLookAtPlayer = false;
public boolean lobotomizeAnimalFloat = true; public boolean lobotomizeAnimalFloat = true;
+ public boolean lobotomizeVillagerEnabled = false; + public boolean lobotomizeVillagerEnabled = false;
+ public int lobotomizeVillagerCheckInterval = 100; + public int lobotomizeVillagerCheckInterval = 100;
+ public boolean lobotomizeVillagerDoRaids = true;
+ public boolean lobotomizeVillagerCheckCanJump = true; + public boolean lobotomizeVillagerCheckCanJump = true;
+ public boolean lobotomizeVillagerCheckOnBed = true; + public boolean lobotomizeVillagerCheckOnBed = true;
+ public boolean lobotomizeVillagerCheckJobSite = true; + public boolean lobotomizeVillagerCheckJobSite = true;
@@ -21,11 +22,12 @@ index b99b438b92587f23c77c5321d5d23e76dc5450de..366948e447c0729389ec53286236a82c
private void lobotomizeSettings() { private void lobotomizeSettings() {
lobotomizeAnimalEnabled = getBoolean("lobotomize.animal.enabled", lobotomizeAnimalEnabled); lobotomizeAnimalEnabled = getBoolean("lobotomize.animal.enabled", lobotomizeAnimalEnabled);
@@ -156,5 +162,11 @@ public class KaiijuWorldConfig { @@ -163,5 +170,12 @@ public class KaiijuWorldConfig {
lobotomizeAnimalCheckCanJump = getBoolean("lobotomize.animal.check-can-jump", lobotomizeAnimalCheckCanJump); lobotomizeAnimalCheckCanJump = getBoolean("lobotomize.animal.check-can-jump", lobotomizeAnimalCheckCanJump);
lobotomizeAnimalLookAtPlayer = getBoolean("lobotomize.animal.look-at-player", lobotomizeAnimalLookAtPlayer); lobotomizeAnimalLookAtPlayer = getBoolean("lobotomize.animal.look-at-player", lobotomizeAnimalLookAtPlayer);
lobotomizeAnimalFloat = getBoolean("lobotomize.animal.float", lobotomizeAnimalFloat); lobotomizeAnimalFloat = getBoolean("lobotomize.animal.float", lobotomizeAnimalFloat);
+ lobotomizeVillagerEnabled = getBoolean("lobotomize.villager.enabled", lobotomizeVillagerEnabled); + lobotomizeVillagerEnabled = getBoolean("lobotomize.villager.enabled", lobotomizeVillagerEnabled);
+ lobotomizeVillagerDoRaids = getBoolean("lobotomize.villager.do-raids", lobotomizeVillagerDoRaids);
+ lobotomizeVillagerCheckInterval = getInt("lobotomize.villager.check-interval", lobotomizeVillagerCheckInterval); + lobotomizeVillagerCheckInterval = getInt("lobotomize.villager.check-interval", lobotomizeVillagerCheckInterval);
+ lobotomizeVillagerCheckCanJump = getBoolean("lobotomize.villager.check-can-jump", lobotomizeVillagerCheckCanJump); + lobotomizeVillagerCheckCanJump = getBoolean("lobotomize.villager.check-can-jump", lobotomizeVillagerCheckCanJump);
+ lobotomizeVillagerCheckOnBed = getBoolean("lobotomize.villager.check-on-bed", lobotomizeVillagerCheckOnBed); + lobotomizeVillagerCheckOnBed = getBoolean("lobotomize.villager.check-on-bed", lobotomizeVillagerCheckOnBed);
@@ -35,7 +37,7 @@ index b99b438b92587f23c77c5321d5d23e76dc5450de..366948e447c0729389ec53286236a82c
} }
\ No newline at end of file \ No newline at end of file
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java 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 26857b0e5134f56df47115031727e0ad68216bc6..ee50c838a7fb032e533ab3f861f843b8f8276772 100644 index aed1d9ccffe471b6c2a1d52d2d3d097f6431318b..f1a66bda9949eff5f8e420d28d23f47aec3d4587 100644
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
@@ -200,14 +200,14 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @@ -200,14 +200,14 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
@@ -49,34 +51,31 @@ index 26857b0e5134f56df47115031727e0ad68216bc6..ee50c838a7fb032e533ab3f861f843b8
interval *= 2; interval *= 2;
} }
- if (this.level.getGameTime() % interval == 0) { - if (this.level.getGameTime() % interval == 0) {
- // offset Y for short blocks like dirt_path/farmland TODO: check that it works
- this.isLobotomized = !canTravelFrom(this.getBlockPosBelowThatAffectsMyMovement());
+ if ((this.getId() + this.tickCount) % interval == 0) { // Kaiiju - Avoid check lags + if ((this.getId() + this.tickCount) % interval == 0) { // Kaiiju - Avoid check lags
+ // offset Y for short blocks like dirt_path/farmland // offset Y for short blocks like dirt_path/farmland
- this.isLobotomized = !canTravelFrom(new BlockPos(getX(), getY() + 0.0625D, getZ()));
+ this.isLobotomized = needLobotomy(); // Kaiiju - Override + this.isLobotomized = needLobotomy(); // Kaiiju - Override
if (this.isLobotomized) { if (this.isLobotomized) {
this.notLobotomizedCount = 0; this.notLobotomizedCount = 0;
@@ -219,8 +219,82 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @@ -219,9 +219,80 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
} }
private boolean canTravelFrom(BlockPos pos) { private boolean canTravelFrom(BlockPos pos) {
- return canTravelTo(pos.east()) || canTravelTo(pos.west()) || canTravelTo(pos.north()) || canTravelTo(pos.south()); - return canTravelTo(pos.east()) || canTravelTo(pos.west()) || canTravelTo(pos.north()) || canTravelTo(pos.south());
- } + return canInteractAt(pos.east()) || canInteractAt(pos.west()) || canInteractAt(pos.north()) || canInteractAt(pos.south()); // Kaiiju
}
+ // Kaiiju start - Customize canTravelTo checks + // Kaiiju start - Customize canTravelTo checks
+ return canInteractAt(pos.east()) || canInteractAt(pos.west()) || canInteractAt(pos.north()) || canInteractAt(pos.south());
+ }
+
+ private boolean needLobotomy() { + private boolean needLobotomy() {
+ if (this.isSleeping()) return false; + if (this.isSleeping()) return false;
+ if (this.level.kaiijuConfig.lobotomizeVillagerCheckOnBed && isOnBed()) return false; + if (this.level.kaiijuConfig.lobotomizeVillagerCheckOnBed && isOnBed()) return false;
+ return !canTravelFrom(new BlockPos(this.getBlockX(), (int) (this.getY() + 0.5D), this.getBlockZ())); + return !canTravelFrom(new BlockPos(getX(), getY() + 0.5D, getZ()));
+ } + }
+ +
+ private boolean canInteractAt(BlockPos pos) { + private boolean canInteractAt(BlockPos pos) {
+ net.minecraft.world.level.block.state.BlockState top = null; + net.minecraft.world.level.block.state.BlockState top = null;
+ // STEP 1: CHECK IF MOB CAN MOVE + // Check if mob can jump over block
+ // A/ MOVE BY JUMPING
+ if (this.level.kaiijuConfig.lobotomizeVillagerCheckCanJump && this.canJump()) { + if (this.level.kaiijuConfig.lobotomizeVillagerCheckCanJump && this.canJump()) {
+ top = this.level.getBlockStateIfLoaded(pos.above()); + top = this.level.getBlockStateIfLoaded(pos.above());
+ if (top == null) return false; + if (top == null) return false;
@@ -85,28 +84,27 @@ index 26857b0e5134f56df47115031727e0ad68216bc6..ee50c838a7fb032e533ab3f861f843b8
+ if (above.isPathfindable(level, pos, net.minecraft.world.level.pathfinder.PathComputationType.LAND)) return true; + if (above.isPathfindable(level, pos, net.minecraft.world.level.pathfinder.PathComputationType.LAND)) return true;
+ } + }
+ } + }
+ // B/ MOVE BY WALKING + // Otherwise, check if mob can interact with bottom block
+ net.minecraft.world.level.block.state.BlockState bottom = this.level.getBlockStateIfLoaded(pos); + net.minecraft.world.level.block.state.BlockState bottom = this.level.getBlockStateIfLoaded(pos);
+ if (bottom == null) return false; + if (bottom == null) return false;
+ net.minecraft.world.level.block.Block bottomBlock = bottom.getBlock(); + net.minecraft.world.level.block.Block bottomBlock = bottom.getBlock();
+ // BED CHECK
+ if (isTallBlock(bottomBlock)) return false; + if (isTallBlock(bottomBlock)) return false;
+ if (this.level.kaiijuConfig.lobotomizeVillagerCheckBedNearby && isBed(bottomBlock)) return true; + if (this.level.kaiijuConfig.lobotomizeVillagerCheckBedNearby && isBed(bottomBlock)) return true;
+ if (this.level.kaiijuConfig.lobotomizeVillagerCheckJobSite && isInteractiveJobSite(bottomBlock, this.getVillagerData().getProfession())) return true;
+ // If he can't interact, check if he can travel
+ if (!bottom.isPathfindable(level, pos, net.minecraft.world.level.pathfinder.PathComputationType.LAND)) return false; + if (!bottom.isPathfindable(level, pos, net.minecraft.world.level.pathfinder.PathComputationType.LAND)) return false;
+ if (top == null) top = this.level.getBlockState(pos.above()); + if (top == null) top = this.level.getBlockState(pos.above());
+ if (!top.isPathfindable(level, pos, net.minecraft.world.level.pathfinder.PathComputationType.LAND)) return false; + return top.isPathfindable(level, pos, net.minecraft.world.level.pathfinder.PathComputationType.LAND);
+ // STEP 2: IF ITS NEAR IS JOB SITE: LOBOTOMIZE
+ return !(this.level.kaiijuConfig.lobotomizeVillagerCheckJobSite && isAssociatedJobSite(bottomBlock, this.getVillagerData().getProfession()));
+ } + }
+ +
+ private boolean canJump() { + private boolean canJump() {
+ BlockPos pos = new BlockPos(this.getBlockX(), (int) (this.getY() + 2.5D), this.getBlockZ()); + BlockPos pos = new BlockPos(getX(), getY() + 2.5D, getZ());
+ net.minecraft.world.level.block.Block above = this.level.getBlockIfLoaded(pos); + net.minecraft.world.level.block.Block above = this.level.getBlockIfLoaded(pos);
+ return !above.hasCollision; + return !above.hasCollision;
+ } + }
+ +
+ private boolean isOnBed() { + private boolean isOnBed() {
+ BlockPos pos = new BlockPos(this.getBlockX(), (int) (this.getY() - 0.5D), this.getBlockZ()); + BlockPos pos = new BlockPos(getX(), getY() - 0.5D, getZ());
+ net.minecraft.world.level.block.Block below = this.level.getBlockIfLoaded(pos); + net.minecraft.world.level.block.Block below = this.level.getBlockIfLoaded(pos);
+ return isBed(below); + return isBed(below);
+ } + }
@@ -115,22 +113,21 @@ index 26857b0e5134f56df47115031727e0ad68216bc6..ee50c838a7fb032e533ab3f861f843b8
+ return block instanceof net.minecraft.world.level.block.BedBlock; + return block instanceof net.minecraft.world.level.block.BedBlock;
+ } + }
+ +
+ private boolean isAssociatedJobSite(net.minecraft.world.level.block.Block block, VillagerProfession profession) { + private boolean isInteractiveJobSite(net.minecraft.world.level.block.Block block, VillagerProfession profession) {
+ if (profession == VillagerProfession.NONE) return false; + if (this.lastTradedPlayer == null) return false;
+ if (this.lastTradedPlayer == null) return true; + return (block instanceof net.minecraft.world.level.block.BlastFurnaceBlock && profession != VillagerProfession.ARMORER) ||
+ return (block instanceof net.minecraft.world.level.block.BlastFurnaceBlock && profession == VillagerProfession.ARMORER) || + (block instanceof net.minecraft.world.level.block.SmokerBlock && profession != VillagerProfession.BUTCHER) ||
+ (block instanceof net.minecraft.world.level.block.SmokerBlock && profession == VillagerProfession.BUTCHER) || + (block instanceof net.minecraft.world.level.block.CartographyTableBlock && profession != VillagerProfession.CARTOGRAPHER) ||
+ (block instanceof net.minecraft.world.level.block.CartographyTableBlock && profession == VillagerProfession.CARTOGRAPHER) || + (block instanceof net.minecraft.world.level.block.BrewingStandBlock && profession != VillagerProfession.CLERIC) ||
+ (block instanceof net.minecraft.world.level.block.BrewingStandBlock && profession == VillagerProfession.CLERIC) || + (block instanceof net.minecraft.world.level.block.ComposterBlock && profession != VillagerProfession.FARMER) ||
+ (block instanceof net.minecraft.world.level.block.ComposterBlock && profession == VillagerProfession.FARMER) || + (block instanceof net.minecraft.world.level.block.BarrelBlock && profession != VillagerProfession.FISHERMAN) ||
+ (block instanceof net.minecraft.world.level.block.BarrelBlock && profession == VillagerProfession.FISHERMAN) || + (block instanceof net.minecraft.world.level.block.FletchingTableBlock && profession != VillagerProfession.FLETCHER) ||
+ (block instanceof net.minecraft.world.level.block.FletchingTableBlock && profession == VillagerProfession.FLETCHER) || + (block instanceof net.minecraft.world.level.block.CauldronBlock && profession != VillagerProfession.LEATHERWORKER) ||
+ (block instanceof net.minecraft.world.level.block.CauldronBlock && profession == VillagerProfession.LEATHERWORKER) || + (block instanceof net.minecraft.world.level.block.LecternBlock && profession != VillagerProfession.LIBRARIAN) ||
+ (block instanceof net.minecraft.world.level.block.LecternBlock && profession == VillagerProfession.LIBRARIAN) || + (block instanceof net.minecraft.world.level.block.StonecutterBlock && profession != VillagerProfession.MASON) ||
+ (block instanceof net.minecraft.world.level.block.StonecutterBlock && profession == VillagerProfession.MASON) || + (block instanceof net.minecraft.world.level.block.LoomBlock && profession != VillagerProfession.SHEPHERD) ||
+ (block instanceof net.minecraft.world.level.block.LoomBlock && profession == VillagerProfession.SHEPHERD) || + (block instanceof net.minecraft.world.level.block.SmithingTableBlock && profession != VillagerProfession.TOOLSMITH) ||
+ (block instanceof net.minecraft.world.level.block.SmithingTableBlock && profession == VillagerProfession.TOOLSMITH) || + (block instanceof net.minecraft.world.level.block.GrindstoneBlock && profession != VillagerProfession.WEAPONSMITH);
+ (block instanceof net.minecraft.world.level.block.GrindstoneBlock && profession == VillagerProfession.WEAPONSMITH);
+ } + }
+ +
+ private static boolean isTallBlock(net.minecraft.world.level.block.Block block) { + private static boolean isTallBlock(net.minecraft.world.level.block.Block block) {
@@ -139,10 +136,11 @@ index 26857b0e5134f56df47115031727e0ad68216bc6..ee50c838a7fb032e533ab3f861f843b8
+ block instanceof net.minecraft.world.level.block.WallBlock; + block instanceof net.minecraft.world.level.block.WallBlock;
+ } + }
+ // Kaiiju end + // Kaiiju end
+
private boolean canTravelTo(BlockPos pos) { private boolean canTravelTo(BlockPos pos) {
net.minecraft.world.level.block.state.BlockState state = this.level.getBlockStateIfLoaded(pos); net.minecraft.world.level.block.state.BlockState state = this.level.getBlockStateIfLoaded(pos);
@@ -337,7 +411,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler if (state == null) {
@@ -337,7 +408,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
protected void mobTick(boolean inactive) { protected void mobTick(boolean inactive) {
//this.level.getProfiler().push("villagerBrain"); // Purpur //this.level.getProfiler().push("villagerBrain"); // Purpur
// Purpur start // Purpur start
@@ -151,16 +149,16 @@ index 26857b0e5134f56df47115031727e0ad68216bc6..ee50c838a7fb032e533ab3f861f843b8
// treat as inactive if lobotomized // treat as inactive if lobotomized
inactive = inactive || checkLobotomized(); inactive = inactive || checkLobotomized();
} else { } else {
@@ -380,7 +454,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @@ -380,7 +451,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
this.lastTradedPlayer = null; this.lastTradedPlayer = null;
} }
- if (!inactive && !this.isNoAi() && this.random.nextInt(100) == 0) { // Paper - if (!inactive && !this.isNoAi() && this.random.nextInt(100) == 0) { // Paper
+ if ((!inactive || this.isLobotomized) && !this.isNoAi() && this.random.nextInt(100) == 0) { // Paper // Kaiiju + if ((!inactive || (this.level.kaiijuConfig.lobotomizeVillagerDoRaids && this.isLobotomized)) && !this.isNoAi() && this.random.nextInt(100) == 0) { // Paper // Kaiiju
Raid raid = ((ServerLevel) this.level).getRaidAt(this.blockPosition()); Raid raid = ((ServerLevel) this.level).getRaidAt(this.blockPosition());
if (raid != null && raid.isActive() && !raid.isOver()) { if (raid != null && raid.isActive() && !raid.isOver()) {
@@ -659,6 +733,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @@ -647,6 +718,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
if (this.assignProfessionWhenSpawned) { if (this.assignProfessionWhenSpawned) {
nbt.putBoolean("AssignProfessionWhenSpawned", true); nbt.putBoolean("AssignProfessionWhenSpawned", true);
} }
@@ -168,7 +166,7 @@ index 26857b0e5134f56df47115031727e0ad68216bc6..ee50c838a7fb032e533ab3f861f843b8
} }
@@ -699,6 +774,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @@ -687,6 +759,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
if (nbt.contains("AssignProfessionWhenSpawned")) { if (nbt.contains("AssignProfessionWhenSpawned")) {
this.assignProfessionWhenSpawned = nbt.getBoolean("AssignProfessionWhenSpawned"); this.assignProfessionWhenSpawned = nbt.getBoolean("AssignProfessionWhenSpawned");
} }

View File

@@ -5,12 +5,12 @@ Subject: [PATCH] Kaiiju Network Configuration
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
index b86c90cc3601e666998cfa12f44515f605bb53eb..7c6d43d8a360530344ef296f4477750c8a298607 100644 index 7da7e0aeb5eac9ac73a3570e716f1ceb11fd7027..2791fe6cc78cc13d969a903134c08e992a6ecdca 100644
--- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java --- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java +++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
@@ -198,4 +198,7 @@ public class KaiijuConfig { @@ -192,4 +192,7 @@ public class KaiijuConfig {
private static void regionFormatSettings() { }
regionFormatDebug = getBoolean("region-format.debug", regionFormatDebug); return builder.build();
} }
+ +
+ private static void networkSettings() { + private static void networkSettings() {

View File

@@ -5,27 +5,25 @@ Subject: [PATCH] Purpur Network Send Null Entity Packets
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
index 7c6d43d8a360530344ef296f4477750c8a298607..ab08e11f13921163b8ff1ff51ff9e9b86d2b47c7 100644 index 2791fe6cc78cc13d969a903134c08e992a6ecdca..276c0e2936dfd3ca752deb65c80565c477f65e7f 100644
--- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java --- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java +++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
@@ -198,7 +198,10 @@ public class KaiijuConfig { @@ -193,6 +193,8 @@ public class KaiijuConfig {
private static void regionFormatSettings() { return builder.build();
regionFormatDebug = getBoolean("region-format.debug", regionFormatDebug);
} }
+
+ public static boolean sendNullEntityPackets = true;
+ public static boolean sendNullEntityPackets = true;
private static void networkSettings() { private static void networkSettings() {
+ sendNullEntityPackets = getBoolean("network.send-null-entity-packets", sendNullEntityPackets); + sendNullEntityPackets = getBoolean("network.send-null-entity-packets", sendNullEntityPackets);
} }
} }
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
index 6afee2a744a3498d4a0eee35f77cde444f73d12c..06439712c2bfd0e817d8b9d8c301dc0283eb3ef4 100644 index 0f9a3a6c05fee59c29764f0c0d7a6cb8a2a861b1..9d0a52bf600583ecbf80c2233a01ff43e609266f 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java --- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -207,6 +207,11 @@ public class ServerEntity { @@ -186,6 +186,11 @@ public class ServerEntity {
flag4 = true; this.teleportDelay = 0;
flag5 = true; packet1 = new ClientboundTeleportEntityPacket(this.entity);
} }
+ // Kaiiju start - Don't send null move entity packets + // Kaiiju start - Don't send null move entity packets
+ if (!dev.kaiijumc.kaiiju.KaiijuConfig.sendNullEntityPackets && isNullMovePacket(packet1)) { + if (!dev.kaiijumc.kaiiju.KaiijuConfig.sendNullEntityPackets && isNullMovePacket(packet1)) {
@@ -35,8 +33,8 @@ index 6afee2a744a3498d4a0eee35f77cde444f73d12c..06439712c2bfd0e817d8b9d8c301dc02
} }
if ((this.trackDelta || this.entity.hasImpulse || this.entity instanceof LivingEntity && ((LivingEntity) this.entity).isFallFlying()) && this.tickCount > 0) { if ((this.trackDelta || this.entity.hasImpulse || this.entity instanceof LivingEntity && ((LivingEntity) this.entity).isFallFlying()) && this.tickCount > 0) {
@@ -281,6 +286,20 @@ public class ServerEntity { @@ -252,6 +257,20 @@ public class ServerEntity {
}));
} }
+ // Kaiiju start - Don't send null move entity packets + // Kaiiju start - Don't send null move entity packets
@@ -52,7 +50,7 @@ index 6afee2a744a3498d4a0eee35f77cde444f73d12c..06439712c2bfd0e817d8b9d8c301dc02
+ return false; + return false;
+ } + }
+ // Kaiiju end + // Kaiiju end
+ +
public void removePairing(ServerPlayer player) { public void removePairing(ServerPlayer player) {
this.entity.stopSeenByPlayer(player); this.entity.stopSeenByPlayer(player);
player.connection.send(new ClientboundRemoveEntitiesPacket(new int[]{this.entity.getId()})); player.connection.send(new ClientboundRemoveEntitiesPacket(new int[]{this.entity.getId()}));

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Kaiiju Lithium Configuration
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
index 6f16786e6107b9e9b52cdbd052c633e757fe351f..913f2f26b1d022e8a812af7caa5dfca5fa548782 100644 index 276c0e2936dfd3ca752deb65c80565c477f65e7f..98c11996a4f052e4e8f1b2782e214817a7999677 100644
--- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java --- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java +++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
@@ -204,4 +204,9 @@ public class KaiijuConfig { @@ -197,4 +197,9 @@ public class KaiijuConfig {
private static void networkSettings() { private static void networkSettings() {
sendNullEntityPackets = getBoolean("network.send-null-entity-packets", sendNullEntityPackets); sendNullEntityPackets = getBoolean("network.send-null-entity-packets", sendNullEntityPackets);
} }

View File

@@ -7,10 +7,10 @@ Author: JellySquid
Licence: LGPL-3.0 Licence: LGPL-3.0
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
index 3a59a816fe35a0f329fbbde871dcb1933015990d..c044fc55f106e521bacf58424d1284069730bbf3 100644 index 98c11996a4f052e4e8f1b2782e214817a7999677..259f7bdca1b9f59dd148492f8f8fe7dc959e55d9 100644
--- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java --- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java +++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
@@ -206,7 +206,9 @@ public class KaiijuConfig { @@ -199,7 +199,9 @@ public class KaiijuConfig {
} }
public static boolean lithiumEnable = true; public static boolean lithiumEnable = true;
@@ -63,10 +63,10 @@ index b5d8a60dc78a76c0a55bfc30cc49d26857bd914a..dd8d98acf21bb676e86f9befb45fd09e
} }
diff --git a/src/main/java/net/minecraft/core/Direction.java b/src/main/java/net/minecraft/core/Direction.java diff --git a/src/main/java/net/minecraft/core/Direction.java b/src/main/java/net/minecraft/core/Direction.java
index eaa620ad86abfb151b43f697973cbc731e2e5e92..e64a6f0d1b03c164d68ca8429d9f87c2dc90870a 100644 index a4dc96b1a3bf309584657e3a1e7dfaea967f9425..09c1989dc3b12d9488b8869e71f2a4890656cc36 100644
--- a/src/main/java/net/minecraft/core/Direction.java --- a/src/main/java/net/minecraft/core/Direction.java
+++ b/src/main/java/net/minecraft/core/Direction.java +++ b/src/main/java/net/minecraft/core/Direction.java
@@ -192,6 +192,7 @@ public enum Direction implements StringRepresentable { @@ -191,6 +191,7 @@ public enum Direction implements StringRepresentable {
} }
public Direction getOpposite() { public Direction getOpposite() {
@@ -74,7 +74,7 @@ index eaa620ad86abfb151b43f697973cbc731e2e5e92..e64a6f0d1b03c164d68ca8429d9f87c2
return from3DDataValue(this.oppositeIndex); return from3DDataValue(this.oppositeIndex);
} }
@@ -454,6 +455,7 @@ public enum Direction implements StringRepresentable { @@ -453,6 +454,7 @@ public enum Direction implements StringRepresentable {
} }
public static Direction getRandom(RandomSource random) { public static Direction getRandom(RandomSource random) {
@@ -83,7 +83,7 @@ index eaa620ad86abfb151b43f697973cbc731e2e5e92..e64a6f0d1b03c164d68ca8429d9f87c2
} }
diff --git a/src/main/java/net/minecraft/world/phys/AABB.java b/src/main/java/net/minecraft/world/phys/AABB.java diff --git a/src/main/java/net/minecraft/world/phys/AABB.java b/src/main/java/net/minecraft/world/phys/AABB.java
index 5b98d42b5d6bc07265fbb017e51a6281c148436a..e307429919ea4719dec89d7c7b54b888dd12b030 100644 index cfb2e46b34b2982d6724f18214557fc80cf4adfa..4fae201f57dc23ed0e25f17739f97133a7f7534c 100644
--- a/src/main/java/net/minecraft/world/phys/AABB.java --- a/src/main/java/net/minecraft/world/phys/AABB.java
+++ b/src/main/java/net/minecraft/world/phys/AABB.java +++ b/src/main/java/net/minecraft/world/phys/AABB.java
@@ -81,10 +81,36 @@ public class AABB { @@ -81,10 +81,36 @@ public class AABB {

View File

@@ -7,10 +7,10 @@ Author: JellySquid
Licence: LGPL-3.0 Licence: LGPL-3.0
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
index c044fc55f106e521bacf58424d1284069730bbf3..1fe1435b1cfe547ddbfccca01de580b8f0e59888 100644 index 259f7bdca1b9f59dd148492f8f8fe7dc959e55d9..a4f9f31941ddd119dca74f3e23bf8507ee4b7369 100644
--- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java --- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java +++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
@@ -207,8 +207,10 @@ public class KaiijuConfig { @@ -200,8 +200,10 @@ public class KaiijuConfig {
public static boolean lithiumEnable = true; public static boolean lithiumEnable = true;
public static boolean lithiumMathFastUtil = true; public static boolean lithiumMathFastUtil = true;
@@ -119,18 +119,13 @@ index 0000000000000000000000000000000000000000..ccb45e94ea6d1a627df786fb88baec7e
+} +}
\ No newline at end of file \ 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 diff --git a/src/main/java/net/minecraft/util/Mth.java b/src/main/java/net/minecraft/util/Mth.java
index a378a2ddd96e76925fa3409282d9606a86c72334..19531bb7e37d13bdffd43aebb6de105268119d2d 100644 index 618f19d70a61062ed5989ec6cf0c036f2e047466..dd320f3a3f2b51a723a2fcc65d477a22c0901455 100644
--- a/src/main/java/net/minecraft/util/Mth.java --- a/src/main/java/net/minecraft/util/Mth.java
+++ b/src/main/java/net/minecraft/util/Mth.java +++ b/src/main/java/net/minecraft/util/Mth.java
@@ -38,11 +38,24 @@ public class Mth { @@ -45,11 +45,19 @@ public class Mth {
private static final double[] ASIN_TAB = new double[257]; return (float)((int)(value * f)) / f;
private static final double[] COS_TAB = new double[257]; }
+ public static float truncate(float value, float digits) {
+ float f = (float)Math.pow(10.0D, (double)digits);
+ return (float)((int)(value * f)) / f;
+ }
+
+ // Kaiiju start + // Kaiiju start
+ public static float[] getSinTable() { + public static float[] getSinTable() {
+ return SIN; + return SIN;

View File

@@ -1,102 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: kugge <sofiane.djerbi38@gmail.com>
Date: Fri, 17 Feb 2023 19:43:55 +0100
Subject: [PATCH] Lithium Entity FastRetrieval
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
index 1fe1435b1cfe547ddbfccca01de580b8f0e59888..fd50b949135178a777abed362a0516591f5b9c98 100644
--- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
@@ -208,9 +208,11 @@ public class KaiijuConfig {
public static boolean lithiumEnable = true;
public static boolean lithiumMathFastUtil = true;
public static boolean lithiumMathSineLut = true;
+ public static boolean lithiumEntityFastRetrieval = true;
private static void lithiumSettings() {
lithiumEnable = getBoolean("lithium.enable", lithiumEnable);
lithiumMathFastUtil = getBoolean("lithium.math.fast-util", lithiumMathFastUtil) && lithiumEnable;
lithiumMathSineLut = getBoolean("lithium.math.sine-lut", lithiumMathSineLut) && lithiumEnable;
+ lithiumEntityFastRetrieval = getBoolean("lithium.entity.fast-retrieval", lithiumEntityFastRetrieval) && lithiumEnable;
}
}
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 ee692b49c62f36287bf9d008861f5d47e0e42c00..e2f0aefb59864ef88cce22dde33f8a72a18fe829 100644
--- a/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java
+++ b/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java
@@ -41,6 +41,43 @@ public class EntitySectionStorage<T extends EntityAccess> {
int n = SectionPos.posToSectionCoord(box.maxY + 0.0D);
int o = SectionPos.posToSectionCoord(box.maxZ + 2.0D);
+ // Kaiiju start
+ if (dev.kaiijumc.kaiiju.KaiijuConfig.lithiumEntityFastRetrieval) {
+ 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.)
+ this.forEachAccessibleNonEmptySectionVanilla(j, k, l, m, n, o, consumer);
+ } 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 22nd bit of the x position is set, which happens iff the x position
+ // is negative. A positive x position will never have its 22nd 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++) {
+ if (this.forEachInColumn(x, k, n, z, consumer).shouldAbort()) {
+ this.forEachAccessibleNonEmptySectionVanilla(j, k, l, m, n, o, consumer);
+ return;
+ }
+ }
+ int bound = Math.min(-1, o);
+ for (int z = l; z <= bound; z++) {
+ if (this.forEachInColumn(x, k, n, z, consumer).shouldAbort()) {
+ this.forEachAccessibleNonEmptySectionVanilla(j, k, l, m, n, o, consumer);
+ return;
+ }
+ }
+ }
+ }
+ } else {
+ this.forEachAccessibleNonEmptySectionVanilla(j, k, l, m, n, o, consumer);
+ }
+ }
+
+ private void forEachAccessibleNonEmptySectionVanilla(int j, int k, int l, int n, int m, int o, AbortableIterationConsumer<EntitySection<T>> consumer) {
+ // Kaiiju end
for(int p = j; p <= m; ++p) {
long q = SectionPos.asLong(p, 0, 0);
long r = SectionPos.asLong(p, -1, -1);
@@ -60,6 +97,31 @@ public class EntitySectionStorage<T extends EntityAccess> {
}
}
+ // Kaiiju start
+ private AbortableIterationConsumer.Continuation forEachInColumn(int x, int k, int n, int z, AbortableIterationConsumer<EntitySection<T>> action) {
+ AbortableIterationConsumer.Continuation ret = AbortableIterationConsumer.Continuation.CONTINUE;
+ //y from negative to positive, but y is treated as unsigned
+ for (int y = Math.max(k, 0); y <= n; y++) {
+ if ((ret = this.consumeSection(SectionPos.asLong(x, y, z), action)).shouldAbort()) {
+ return ret;
+ }
+ }
+ int bound = Math.min(-1, n);
+ for (int y = k; y <= bound; y++) {
+ if ((ret = this.consumeSection(SectionPos.asLong(x, y, z), action)).shouldAbort()) {
+ return ret;
+ }
+ }
+ return ret;
+ }
+ private AbortableIterationConsumer.Continuation consumeSection(long pos, AbortableIterationConsumer<EntitySection<T>> action) {
+ EntitySection<T> entitySection = this.getSection(pos);
+ if (entitySection != null && 0 != entitySection.size() && entitySection.getStatus().isAccessible()) {
+ return action.accept(entitySection);
+ }
+ return AbortableIterationConsumer.Continuation.CONTINUE;
+ }
+ // Kaiiju end
public LongStream getExistingSectionPositionsInChunk(long chunkPos) {
int i = ChunkPos.getX(chunkPos);