9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-19 14:59:25 +00:00

Finish hard fork process in #20

Merge Paper hard fork into ver/1.21.4 branch
This commit is contained in:
Artem Ostrasev
2025-01-18 22:37:39 +03:00
committed by GitHub
220 changed files with 7589 additions and 7757 deletions

44
.editorconfig Normal file
View File

@@ -0,0 +1,44 @@
[*]
charset=utf-8
end_of_line=lf
insert_final_newline=true
indent_style=space
indent_size=4
ij_any_block_comment_add_space = false
ij_any_block_comment_at_first_column = false
ij_any_line_comment_at_first_column = false
ij_any_line_comment_add_space = true
[*.tiny]
indent_style=tab
[*.bat]
end_of_line=crlf
[*.yml]
indent_size=2
[*.patch]
trim_trailing_whitespace=false
[*.java]
ij_continuation_indent_size = 4
ij_java_class_count_to_use_import_on_demand = 999999
ij_java_insert_inner_class_imports = false
ij_java_names_count_to_use_import_on_demand = 999999
ij_java_imports_layout = *,|,$*
ij_java_generate_final_locals = true
ij_java_generate_final_parameters = true
ij_java_method_parameters_new_line_after_left_paren = true
ij_java_method_parameters_right_paren_on_new_line = true
ij_java_use_fq_class_names = false
ij_java_class_names_in_javadoc = 1
[divinemc-server/src/minecraft/java/**/*.java]
ij_java_use_fq_class_names = true
[divinemc-server/src/minecraft/resources/data/**/*.json]
indent_size = 2
[paper-api/src/generated/**/*.java]
ij_java_imports_layout = $*,|,*

7
.gitattributes vendored Normal file
View File

@@ -0,0 +1,7 @@
* text=auto eol=lf
*.sh text eol=lf
gradlew text eol=lf
*.bat text eol=crlf
*.jar binary

View File

@@ -37,12 +37,9 @@ jobs:
chmod +x gradlew
- name: Patch
run: ./gradlew applyPatches --stacktrace
run: ./gradlew applyAllPatches --stacktrace
- name: Create Reobf Jar
run: ./gradlew createReobfPaperclipJar --stacktrace
- name: Create Mojmap Jar
- name: Build Paperclip Jar
run: ./gradlew createMojmapPaperclipJar --stacktrace
- name: Publish API
@@ -53,8 +50,8 @@ jobs:
if: env.debug == 'true' || github.ref_name != env.branch
uses: actions/upload-artifact@main
with:
name: Artifacts
path: build/libs
name: DivineMC
path: divinemc-server/build/libs/divinemc-paperclip-*-mojmap.jar
- name: Release Artifacts
if: github.ref_name == env.branch
@@ -63,7 +60,7 @@ jobs:
title: "Release #${{ env.workflow }}"
automatic_release_tag: release-${{ env.workflow }}
repo_token: "${{ secrets.GITHUB_TOKEN }}"
files: build/libs/*.jar
files: divinemc-server/build/libs/divinemc-paperclip-*-mojmap.jar
prerelease: false
- name: Release Artifacts (Latest)
@@ -73,5 +70,5 @@ jobs:
title: "Release #${{ env.workflow }}"
automatic_release_tag: latest-${{ env.version }}
repo_token: "${{ secrets.GITHUB_TOKEN }}"
files: build/libs/*.jar
files: divinemc-server/build/libs/divinemc-paperclip-*-mojmap.jar
prerelease: false

16
.gitignore vendored
View File

@@ -1,13 +1,15 @@
# DivineMC-API and DivineMC-Server changes + paper-api-generator
DivineMC-API
DivineMC-Server
paper-api-generator/*
# IDE and Gradle things
build
.gradle
run
.idea
# Other files and folders
build-data
# Server things
/divinemc-server/build.gradle.kts
/divinemc-server/src/minecraft
/paper-server
/purpur-server
/divinemc-api/build.gradle.kts
/paper-api
/purpur-api
*.jar

View File

@@ -72,18 +72,16 @@ dependencies {
### Initial setup
First, clone this repository (do not download it) and the run the following command in the root directory:
```bash
./gradlew applyPatches
./gradlew applyAllPatches
```
After that, project is ready to use and editing it.
### Creating a patch
Patches are effectively just commits in either `DivineMC-API` or `DivineMC-Server`. To create one, just add a commit to either repo and run `./gradlew rebuildPatches`, and a patch will be placed in the patches folder. Modifying commits will also modify its corresponding patch file.
Read our [documentation](https://docs.bx-team.space/divinemc/dev/contributing) to learn more about patches
Patches are effectively just commits in either `paper-api`, `paper-server`, `purpur-api`, `purpur-server` or `divinemc-server`. If you want to learn how to work with patch system, you can read our [contributing documentation](https://docs.bx-team.space/documentation/divinemc/development/contributing).
### Compiling
Use the command `./gradlew build` to build the API and server. Compiled JARs will be placed under `DivineMC-API/build/libs` and `DivineMC-Server/build/libs`. **These JARs are not used to start a server**.
Use the command `./gradlew build` to build the API and server. Compiled JARs will be placed under `divinemc-api/build/libs` and `divinemc-server/build/libs`. **These JARs are not used to start a server**.
To compile a server-ready paperclip jar, run `./gradlew createMojmapPaperclipJar`. The compiled paperclip jar will be in `build/libs/` in the main root.
To compile a server-ready paperclip jar, run `./gradlew createMojmapPaperclipJar`. The compiled paperclip jar will be put in `divinemc-server/build/libs`.
###### We don't steal logo from YatopiaMC! [List of all forks](https://gist.github.com/NONPLAYT/48742353af8ae36bcef5d1c36de9730a)

View File

@@ -8,3 +8,7 @@
# To import classes from the vanilla Minecraft jar use `minecraft` as the artifactId:
# minecraft net.minecraft.world.level.entity.LevelEntityGetterAdapter
# minecraft net/minecraft/world/level/entity/LevelEntityGetter.java
# To import minecraft data files, like the default chat type, use `mc_data` as the prefix:
# mc_data chat_type/chat.json
# mc_data dimension_type/overworld.json
#

9
build-data/divinemc.at Normal file
View File

@@ -0,0 +1,9 @@
# This file is auto generated, any changes may be overridden!
# See CONTRIBUTING.md on how to add access transformers.
public net.minecraft.world.level.block.state.pattern.BlockPattern matches(Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Direction;Lnet/minecraft/core/Direction;Lcom/google/common/cache/LoadingCache;)Lnet/minecraft/world/level/block/state/pattern/BlockPattern$BlockPatternMatch;
public net.minecraft.world.level.chunk.storage.RegionFile getOversizedData(II)Lnet/minecraft/nbt/CompoundTag;
public net.minecraft.world.level.chunk.storage.RegionFile isOversized(II)Z
public net.minecraft.world.level.chunk.storage.RegionFile recalculateHeader()Z
public net.minecraft.world.level.chunk.storage.RegionFile setOversized(IIZ)V
public net.minecraft.world.level.chunk.storage.RegionFile write(Lnet/minecraft/world/level/ChunkPos;Ljava/nio/ByteBuffer;)V
public net.minecraft.world.level.pathfinder.SwimNodeEvaluator allowBreaching

View File

@@ -1,43 +1,56 @@
import io.papermc.paperweight.util.constants.PAPERCLIP_CONFIG
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent
plugins {
java
`maven-publish`
id("io.papermc.paperweight.patcher") version "1.7.7"
id("io.papermc.paperweight.patcher") version "2.0.0-beta.14"
}
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
repositories {
mavenCentral()
maven("https://papermc.io/repo/repository/maven-public/") {
content {
onlyForConfigurations(PAPERCLIP_CONFIG)
paperweight {
upstreams.register("purpur") {
repo = github("PurpurMC", "Purpur")
ref = providers.gradleProperty("purpurRef")
patchFile {
path = "purpur-server/build.gradle.kts"
outputFile = file("divinemc-server/build.gradle.kts")
patchFile = file("divinemc-server/build.gradle.kts.patch")
}
}
}
dependencies {
remapper("net.fabricmc:tiny-remapper:0.10.3:fat")
decompiler("org.vineflower:vineflower:1.10.1")
paperclip("io.papermc:paperclip:3.0.3")
}
allprojects {
apply(plugin = "java")
apply(plugin = "maven-publish")
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
patchFile {
path = "purpur-api/build.gradle.kts"
outputFile = file("divinemc-api/build.gradle.kts")
patchFile = file("divinemc-api/build.gradle.kts.patch")
}
patchRepo("paperApi") {
upstreamPath = "paper-api"
patchesDir = file("divinemc-api/paper-patches")
outputDir = file("paper-api")
}
patchDir("purpurApi") {
upstreamPath = "purpur-api"
excludes = listOf("build.gradle.kts", "build.gradle.kts.patch", "paper-patches")
patchesDir = file("divinemc-api/purpur-patches")
outputDir = file("purpur-api")
}
}
}
subprojects {
apply(plugin = "java-library")
apply(plugin = "maven-publish")
extensions.configure<JavaPluginExtension> {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
tasks.withType<JavaCompile> {
options.encoding = Charsets.UTF_8.name()
options.release.set(21)
options.release = 21
options.isFork = true
}
tasks.withType<Javadoc> {
options.encoding = Charsets.UTF_8.name()
@@ -45,64 +58,29 @@ subprojects {
tasks.withType<ProcessResources> {
filteringCharset = Charsets.UTF_8.name()
}
tasks.withType<Test> {
testLogging {
showStackTraces = true
exceptionFormat = TestExceptionFormat.FULL
events(TestLogEvent.STANDARD_OUT)
}
}
tasks.withType<AbstractArchiveTask>().configureEach {
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}
repositories {
mavenCentral()
maven(paperMavenPublicUrl)
maven("https://oss.sonatype.org/content/groups/public/")
maven("https://ci.emc.gs/nexus/content/groups/aikar/")
maven("https://repo.aikar.co/content/groups/aikar")
maven("https://repo.md-5.net/content/repositories/releases/")
maven("https://hub.spigotmc.org/nexus/content/groups/public/")
maven("https://jitpack.io")
}
}
paperweight {
serverProject.set(project(":divinemc-server"))
remapRepo.set("https://maven.fabricmc.net/")
decompileRepo.set(paperMavenPublicUrl)
useStandardUpstream("purpur") {
url.set(github("PurpurMC", "Purpur"))
ref.set(providers.gradleProperty("purpurRef"))
withStandardPatcher {
apiSourceDirPath.set("Purpur-API")
serverSourceDirPath.set("Purpur-Server")
apiPatchDir.set(layout.projectDirectory.dir("patches/api"))
apiOutputDir.set(layout.projectDirectory.dir("DivineMC-API"))
serverPatchDir.set(layout.projectDirectory.dir("patches/server"))
serverOutputDir.set(layout.projectDirectory.dir("DivineMC-Server"))
}
patchTasks.register("generatedApi") {
isBareDirectory = true
upstreamDirPath = "paper-api-generator/generated"
patchDir = layout.projectDirectory.dir("patches/generated-api")
outputDir = layout.projectDirectory.dir("paper-api-generator/generated")
}
}
}
tasks.generateDevelopmentBundle {
apiCoordinates = "space.bxteam.divinemc:divinemc-api"
libraryRepositories.set(
listOf(
"https://repo.maven.apache.org/maven2/",
paperMavenPublicUrl
)
)
}
publishing {
if (project.providers.gradleProperty("publishDevBundle").isPresent) {
publications.create<MavenPublication>("devBundle") {
artifact(tasks.generateDevelopmentBundle) {
artifactId = "dev-bundle"
extensions.configure<PublishingExtension> {
repositories {
maven("https://repo.bx-team.space/snapshots") {
name = "divinemc"
credentials(PasswordCredentials::class)
}
}
}

View File

@@ -0,0 +1,40 @@
--- a/purpur-api/build.gradle.kts
+++ b/purpur-api/build.gradle.kts
@@ -104,17 +_,21 @@
java {
srcDir(generatedApiPath)
srcDir(file("../paper-api/src/main/java"))
+ srcDir(file("../purpur-api/src/main/java"))
}
resources {
srcDir(file("../paper-api/src/main/resources"))
+ srcDir(file("../purpur-api/src/main/resources"))
}
}
test {
java {
srcDir(file("../paper-api/src/test/java"))
+ srcDir(file("../purpur-api/src/test/java"))
}
resources {
srcDir(file("../paper-api/src/test/resources"))
+ srcDir(file("../purpur-api/src/test/resources"))
}
}
}
@@ -161,6 +_,15 @@
pomProps.get().asFile.writeText("version=$projectVersion")
}
}
+
+// DivineMC start - Hide unnecessary compilation warnings
+tasks.withType<JavaCompile> {
+ val compilerArgs = options.compilerArgs
+ compilerArgs.add("-Xlint:-module")
+ compilerArgs.add("-Xlint:-removal")
+ compilerArgs.add("-Xlint:-dep-ann")
+}
+// DivineMC end - Hide unnecessary compilation warnings
tasks.jar {
from(generateApiVersioningFile.map { it.outputs.files.singleFile }) {

View File

@@ -1,26 +1,24 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Mon, 12 Jun 2023 00:23:38 +0300
Date: Sat, 11 Jan 2025 23:50:00 +0300
Subject: [PATCH] Disable reload command by default
This is fully rewritten reload command, you can enable or disable it with -DDivineMC.EnableReloadCommand flag
Read this article why reload is VERY UNSAFE in Bukkit: https://madelinemiller.dev/blog/problem-with-reload/
diff --git a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
index bdfe68b386b5ca2878475e548d3c9a3808fce848..0a21f2138969f75425b720487e626aac796821d1 100644
index bdfe68b386b5ca2878475e548d3c9a3808fce848..55387ddbf5734b3a860f129789b9ce95f0a69618 100644
--- a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
+++ b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
@@ -1,8 +1,7 @@
@@ -1,7 +1,5 @@
package org.bukkit.command.defaults;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
+
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
@@ -15,7 +14,7 @@ public class ReloadCommand extends BukkitCommand {
@@ -15,7 +13,7 @@ public class ReloadCommand extends BukkitCommand {
this.description = "Reloads the server configuration and plugins";
this.usageMessage = "/reload [permissions|commands|confirm]"; // Paper
this.setPermission("bukkit.command.reload");
@@ -29,7 +27,7 @@ index bdfe68b386b5ca2878475e548d3c9a3808fce848..0a21f2138969f75425b720487e626aac
}
@org.jetbrains.annotations.ApiStatus.Internal // Paper
@@ -25,48 +24,53 @@ public class ReloadCommand extends BukkitCommand {
@@ -25,47 +23,50 @@ public class ReloadCommand extends BukkitCommand {
public boolean execute(@NotNull CommandSender sender, @NotNull String currentAlias, @NotNull String[] args) { // Paper
if (!testPermission(sender)) return true;
@@ -45,7 +43,7 @@ index bdfe68b386b5ca2878475e548d3c9a3808fce848..0a21f2138969f75425b720487e626aac
- Command.broadcastCommandMessage(sender, net.kyori.adventure.text.Component.text("Command aliases successfully reloaded.", net.kyori.adventure.text.format.NamedTextColor.GREEN));
+ // DivineMC start - disable reload command by default & add startup flag
+ if (System.getProperty("DivineMC.EnableReloadCommand") == null || false) {
+ sender.sendMessage(net.kyori.adventure.text.Component.text("Operation denied, command disabled.", net.kyori.adventure.text.format.NamedTextColor.RED ));
+ sender.sendMessage(net.kyori.adventure.text.Component.text("Operation denied, command disabled.", net.kyori.adventure.text.format.NamedTextColor.RED));
+ sender.sendMessage(net.kyori.adventure.text.Component.text("Reload command SHOULD NEVER be used in whatever circumstances.", net.kyori.adventure.text.format.NamedTextColor.YELLOW));
+ sender.sendMessage(net.kyori.adventure.text.Component.text("DivineMC has intentionally disabled it in order to stop you using it, instead of restarting your server.", net.kyori.adventure.text.format.NamedTextColor.YELLOW));
+ sender.sendMessage(net.kyori.adventure.text.Component.text("If you still want to enable reload command, add -DDivineMC.EnableReloadCommand=true flag to your startup arguments.", net.kyori.adventure.text.format.NamedTextColor.YELLOW));
@@ -83,7 +81,7 @@ index bdfe68b386b5ca2878475e548d3c9a3808fce848..0a21f2138969f75425b720487e626aac
- return true;
- }
- // Paper end
-
- Command.broadcastCommandMessage(sender, ChatColor.RED + "Please note that this command is not supported and may cause issues when using some plugins.");
- Command.broadcastCommandMessage(sender, ChatColor.RED + "If you encounter any issues please use the /stop command to restart your server.");
- // Paper start - lifecycle events
@@ -104,16 +102,15 @@ index bdfe68b386b5ca2878475e548d3c9a3808fce848..0a21f2138969f75425b720487e626aac
+ return true;
+ }
}
+ // Paper end - lifecycle events
+ Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Reload complete.");
+
+ return true;
}
- }
- // Paper end - lifecycle events
- Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Reload complete.");
+ // Paper end - lifecycle events
+ Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Reload complete.");
return true;
+ return true;
+ }
+ // DivineMC end
return true;
}
@NotNull

View File

@@ -1,6 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sun, 12 May 2024 20:24:24 +0300
Date: Sat, 11 Jan 2025 23:57:34 +0300
Subject: [PATCH] Delete Timings
@@ -179,7 +179,7 @@ index 42e7e712403676171d34d5f2be27e48e7a071ebd..00000000000000000000000000000000
-}
diff --git a/src/main/java/co/aikar/timings/TimedEventExecutor.java b/src/main/java/co/aikar/timings/TimedEventExecutor.java
deleted file mode 100644
index 438a9c76381ea3f5b774e2232ff56c5dc6f82586..0000000000000000000000000000000000000000
index c178d77bd23a484043f50e46ccd603734f7b6059..0000000000000000000000000000000000000000
--- a/src/main/java/co/aikar/timings/TimedEventExecutor.java
+++ /dev/null
@@ -1,93 +0,0 @@
@@ -265,9 +265,9 @@ index 438a9c76381ea3f5b774e2232ff56c5dc6f82586..00000000000000000000000000000000
- executor.execute(listener, event);
- return;
- }
- //try (Timing ignored = timings.startTiming()){ // Purpur
- //try (Timing ignored = timings.startTiming()){ // Purpur - Remove Timings
- executor.execute(listener, event);
- //} // Purpur
- //} // Purpur - Remove Timings
- }
-
- @Override
@@ -278,7 +278,7 @@ index 438a9c76381ea3f5b774e2232ff56c5dc6f82586..00000000000000000000000000000000
-}
diff --git a/src/main/java/co/aikar/timings/Timing.java b/src/main/java/co/aikar/timings/Timing.java
deleted file mode 100644
index 8709c955bac34bc546a8e022cfac808bc61ee793..0000000000000000000000000000000000000000
index acd06662bf1da1f12f73e2e85c0fd1b10f3b8b93..0000000000000000000000000000000000000000
--- a/src/main/java/co/aikar/timings/Timing.java
+++ /dev/null
@@ -1,92 +0,0 @@
@@ -323,7 +323,7 @@ index 8709c955bac34bc546a8e022cfac808bc61ee793..00000000000000000000000000000000
- * @return Timing
- */
- @NotNull
- @io.papermc.paper.annotation.DoNotUse // Purpur
- @io.papermc.paper.annotation.DoNotUse // Purpur - Remove Timings
- Timing startTiming();
-
- /**
@@ -331,7 +331,7 @@ index 8709c955bac34bc546a8e022cfac808bc61ee793..00000000000000000000000000000000
- *
- * Will automatically be called when this Timing is used with try-with-resources
- */
- @io.papermc.paper.annotation.DoNotUse // Purpur
- @io.papermc.paper.annotation.DoNotUse // Purpur - Remove Timings
- void stopTiming();
-
- /**
@@ -342,7 +342,7 @@ index 8709c955bac34bc546a8e022cfac808bc61ee793..00000000000000000000000000000000
- * @return Timing
- */
- @NotNull
- @io.papermc.paper.annotation.DoNotUse // Purpur
- @io.papermc.paper.annotation.DoNotUse // Purpur - Remove Timings
- Timing startTimingIfSync();
-
- /**
@@ -352,14 +352,14 @@ index 8709c955bac34bc546a8e022cfac808bc61ee793..00000000000000000000000000000000
- *
- * But only if we are on the primary thread.
- */
- @io.papermc.paper.annotation.DoNotUse // Purpur
- @io.papermc.paper.annotation.DoNotUse // Purpur - Remove Timings
- void stopTimingIfSync();
-
- /**
- * @deprecated Doesn't do anything - Removed
- */
- @Deprecated
- @io.papermc.paper.annotation.DoNotUse // Purpur
- @io.papermc.paper.annotation.DoNotUse // Purpur - Remove Timings
- void abort();
-
- /**
@@ -371,7 +371,7 @@ index 8709c955bac34bc546a8e022cfac808bc61ee793..00000000000000000000000000000000
- TimingHandler getTimingHandler();
-
- @Override
- @io.papermc.paper.annotation.DoNotUse // Purpur
- @io.papermc.paper.annotation.DoNotUse // Purpur - Remove Timings
- void close();
-}
diff --git a/src/main/java/co/aikar/timings/TimingData.java b/src/main/java/co/aikar/timings/TimingData.java
@@ -1285,10 +1285,10 @@ index df142a89b8c43acb81eb383eac0ef048a1f49a6e..00000000000000000000000000000000
-}
diff --git a/src/main/java/co/aikar/timings/Timings.java b/src/main/java/co/aikar/timings/Timings.java
deleted file mode 100644
index 27a02f0c3261067d8e4ee6169c62cecbbfe50d42..0000000000000000000000000000000000000000
index 627922fa5c65e9b77e79cd896c8c52889f5a0cc5..0000000000000000000000000000000000000000
--- a/src/main/java/co/aikar/timings/Timings.java
+++ /dev/null
@@ -1,325 +0,0 @@
@@ -1,324 +0,0 @@
-/*
- * This file is licensed under the MIT License (MIT).
- *
@@ -1415,7 +1415,7 @@ index 27a02f0c3261067d8e4ee6169c62cecbbfe50d42..00000000000000000000000000000000
- @NotNull
- public static Timing ofStart(@NotNull Plugin plugin, @NotNull String name, @Nullable Timing groupHandler) {
- Timing timing = of(plugin, name, groupHandler);
- //timing.startTiming(); // Purpur
- //timing.startTiming(); // Purpur - Remove Timings
- return timing;
- }
-
@@ -1437,7 +1437,7 @@ index 27a02f0c3261067d8e4ee6169c62cecbbfe50d42..00000000000000000000000000000000
- */
- public static void setTimingsEnabled(boolean enabled) {
- if (enabled && !warnedAboutDeprecationOnEnable) {
- //Bukkit.getLogger().severe(PlainTextComponentSerializer.plainText().serialize(deprecationMessage()));
- //Bukkit.getLogger().severe(PlainTextComponentSerializer.plainText().serialize(deprecationMessage())); // Purpur - Remove Timings
- warnedAboutDeprecationOnEnable = true;
- }
- }
@@ -1613,13 +1613,12 @@ index 27a02f0c3261067d8e4ee6169c62cecbbfe50d42..00000000000000000000000000000000
- return TimingsManager.getHandler(groupName, name, groupHandler);
- }
-}
-
diff --git a/src/main/java/co/aikar/timings/TimingsCommand.java b/src/main/java/co/aikar/timings/TimingsCommand.java
deleted file mode 100644
index f28eec202237461cb489a2b13289d813381a25bc..0000000000000000000000000000000000000000
index 04d0dc27406e9f96224f88edb1c535176e84d395..0000000000000000000000000000000000000000
--- a/src/main/java/co/aikar/timings/TimingsCommand.java
+++ /dev/null
@@ -1,130 +0,0 @@
@@ -1,132 +0,0 @@
-/*
- * This file is licensed under the MIT License (MIT).
- *
@@ -1669,7 +1668,7 @@ index f28eec202237461cb489a2b13289d813381a25bc..00000000000000000000000000000000
- public TimingsCommand(@NotNull String name) {
- super(name);
- this.description = "Manages Spigot Timings data to see performance of the server.";
- this.usageMessage = "/timings";// <reset|report|on|off|verbon|verboff>"; // Purpur
- this.usageMessage = "/timings";// <reset|report|on|off|verbon|verboff>"; // Purpur - Remove Timings
- this.setPermission("bukkit.command.timings");
- }
-
@@ -1679,10 +1678,12 @@ index f28eec202237461cb489a2b13289d813381a25bc..00000000000000000000000000000000
- return true;
- }
- if (true) {
- // Purpur start - Remove Timings
- net.kyori.adventure.text.minimessage.MiniMessage mm = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage();
- sender.sendMessage(mm.deserialize("<gold>Purpur has removed timings to save your performance. Please use <click:suggest_command:'/spark'><grey>/spark</grey></click> instead"));
- sender.sendMessage(mm.deserialize("<gold>For more information, view its documentation at"));
- sender.sendMessage(mm.deserialize("<gold><click:open_url:'https://spark.lucko.me/docs/Command-Usage'>https://spark.lucko.me/docs/Command-Usage</click>")); // Purpur
- sender.sendMessage(mm.deserialize("<gold><click:open_url:'https://spark.lucko.me/docs/Command-Usage'>https://spark.lucko.me/docs/Command-Usage</click>"));
- // Purpur end - Remove Timings
- return true;
- }
- if (args.length < 1) {
@@ -1743,7 +1744,7 @@ index f28eec202237461cb489a2b13289d813381a25bc..00000000000000000000000000000000
- Preconditions.checkNotNull(args, "Arguments cannot be null");
- Preconditions.checkNotNull(alias, "Alias cannot be null");
-
- if (false && args.length == 1) { // Purpur
- if (false && args.length == 1) { // Purpur - Remove Timings
- return StringUtil.copyPartialMatches(args[0], TIMINGS_SUBCOMMANDS,
- new ArrayList<String>(TIMINGS_SUBCOMMANDS.size()));
- }
@@ -2103,158 +2104,9 @@ index 632c4961515f5052551f841cfa840e60bba7a257..00000000000000000000000000000000
- super.stopTiming();
- }
-}
diff --git a/src/main/java/org/bukkit/command/Command.java b/src/main/java/org/bukkit/command/Command.java
index 74384a56eebbce41d431db2507c55eddbcf50a41..7d1ac11cfffbaf7d799f2a0032221fb23ee6daf5 100644
--- a/src/main/java/org/bukkit/command/Command.java
+++ b/src/main/java/org/bukkit/command/Command.java
@@ -33,16 +33,6 @@ public abstract class Command {
protected String usageMessage;
private String permission;
private net.kyori.adventure.text.Component permissionMessage; // Paper
- /**
- * @deprecated Timings will be removed in the future
- */
- @Deprecated(forRemoval = true)
- public co.aikar.timings.Timing timings; // Paper
- /**
- * @deprecated Timings will be removed in the future
- */
- @Deprecated(forRemoval = true)
- @NotNull public String getTimingName() {return getName();} // Paper
protected Command(@NotNull String name) {
this(name, "", "/" + name, new ArrayList<String>());
diff --git a/src/main/java/org/bukkit/command/FormattedCommandAlias.java b/src/main/java/org/bukkit/command/FormattedCommandAlias.java
index abe256e1e45ce28036da4aa1586715bc8a1a3414..9eab8024e0675865f17669847759a26d28f74f3a 100644
--- a/src/main/java/org/bukkit/command/FormattedCommandAlias.java
+++ b/src/main/java/org/bukkit/command/FormattedCommandAlias.java
@@ -12,7 +12,6 @@ public class FormattedCommandAlias extends Command {
public FormattedCommandAlias(@NotNull String alias, @NotNull String[] formatStrings) {
super(alias);
- timings = co.aikar.timings.TimingsManager.getCommandTiming("minecraft", this); // Spigot
this.formatStrings = formatStrings;
}
@@ -120,10 +119,6 @@ public class FormattedCommandAlias extends Command {
return formatString.trim(); // Paper - Causes an extra space at the end, breaks with brig commands
}
- @NotNull
- @Override // Paper
- public String getTimingName() {return "Command Forwarder - " + super.getTimingName();} // Paper
-
private static boolean inRange(int i, int j, int k) {
return i >= j && i <= k;
}
diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java
index 7740ad53796d08584bb0110f99af5639993e4d71..f0da5a8ae7e989e120f9d5ef2a417a9840aed7d0 100644
--- a/src/main/java/org/bukkit/command/SimpleCommandMap.java
+++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java
@@ -39,7 +39,6 @@ public class SimpleCommandMap implements CommandMap {
register("bukkit", new VersionCommand("version"));
register("bukkit", new ReloadCommand("reload"));
//register("bukkit", new PluginsCommand("plugins")); // Paper
- register("bukkit", new co.aikar.timings.TimingsCommand("timings")); // Paper
}
public void setFallbackCommands() {
@@ -71,7 +70,6 @@ public class SimpleCommandMap implements CommandMap {
*/
@Override
public boolean register(@NotNull String label, @NotNull String fallbackPrefix, @NotNull Command command) {
- command.timings = co.aikar.timings.TimingsManager.getCommandTiming(fallbackPrefix, command); // Paper
label = label.toLowerCase(Locale.ROOT).trim();
fallbackPrefix = fallbackPrefix.toLowerCase(Locale.ROOT).trim();
boolean registered = register(label, command, false, fallbackPrefix);
@@ -166,17 +164,9 @@ public class SimpleCommandMap implements CommandMap {
parsedArgs = event.getArgs();
// Purpur end
- // Paper start - Plugins do weird things to workaround normal registration
- if (target.timings == null) {
- target.timings = co.aikar.timings.TimingsManager.getCommandTiming(null, target);
- }
- // Paper end
-
try {
- //try (co.aikar.timings.Timing ignored = target.timings.startTiming()) { // Paper - use try with resources // Purpur
// Note: we don't return the result of target.execute as thats success / failure, we return handled (true) or not handled (false)
target.execute(sender, sentCommandLabel, parsedArgs); // Purpur
- //} // target.timings.stopTiming(); // Spigot // Paper // Purpur
} catch (CommandException ex) {
server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerCommandException(ex, target, sender, args))); // Paper
//target.timings.stopTiming(); // Spigot // Paper
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
index 2e6d62c4f3687e299c34e876c503b400e13be05a..0f5b442ea8e18d21c310205c217d22d18be3c863 100644
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
@@ -724,12 +724,7 @@ public final class SimplePluginManager implements PluginManager {
throw new IllegalPluginAccessException("Plugin attempted to register " + event + " while not enabled");
}
- executor = new co.aikar.timings.TimedEventExecutor(executor, plugin, null, event); // Paper
- if (false) { // Spigot - RL handles useTimings check now // Paper
- getEventListeners(event).register(new TimedRegisteredListener(listener, executor, priority, plugin, ignoreCancelled));
- } else {
- getEventListeners(event).register(new RegisteredListener(listener, executor, priority, plugin, ignoreCancelled));
- }
+ getEventListeners(event).register(new RegisteredListener(listener, executor, priority, plugin, ignoreCancelled));
}
@NotNull
@@ -959,8 +954,7 @@ public final class SimplePluginManager implements PluginManager {
@Override
public boolean useTimings() {
- if (true) {return this.paperPluginManager.useTimings();} // Paper
- return co.aikar.timings.Timings.isTimingsEnabled(); // Spigot
+ return false; // DivineMC - Delete Timings
}
/**
@@ -970,7 +964,7 @@ public final class SimplePluginManager implements PluginManager {
*/
@Deprecated(forRemoval = true)
public void useTimings(boolean use) {
- co.aikar.timings.Timings.setTimingsEnabled(use); // Paper
+
}
// Paper start
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
index e2b631fc160f13ea6e27b69f835bbdf83d6d3dec..b1b15caa19137e92ab08df7affcd37d1c249570d 100644
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
@@ -43,7 +43,6 @@ import org.bukkit.plugin.TimedRegisteredListener;
import org.bukkit.plugin.UnknownDependencyException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.spigotmc.CustomTimingsHandler; // Spigot
import org.yaml.snakeyaml.error.YAMLException;
/**
@@ -294,7 +293,7 @@ public final class JavaPluginLoader implements PluginLoader {
}
}
- EventExecutor executor = new co.aikar.timings.TimedEventExecutor(new EventExecutor() { // Paper
+ EventExecutor executor = new EventExecutor() { // Paper
@Override
public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException { // Paper
try {
@@ -308,7 +307,7 @@ public final class JavaPluginLoader implements PluginLoader {
throw new EventException(t);
}
}
- }, plugin, method, eventClass); // Paper
+ }; // DivineMC - Delete Timings
if (false) { // Spigot - RL handles useTimings check now
eventSet.add(new TimedRegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled()));
} else {
diff --git a/src/main/java/org/spigotmc/CustomTimingsHandler.java b/src/main/java/org/spigotmc/CustomTimingsHandler.java
deleted file mode 100644
index 9c2d605c50cbf9aefa56ec209df9f6cea1392e89..0000000000000000000000000000000000000000
index b4249da3eb26eae26ec000cc4d56cd21ac2fc6d5..0000000000000000000000000000000000000000
--- a/src/main/java/org/spigotmc/CustomTimingsHandler.java
+++ /dev/null
@@ -1,67 +0,0 @@
@@ -2308,7 +2160,7 @@ index 9c2d605c50cbf9aefa56ec209df9f6cea1392e89..00000000000000000000000000000000
- public CustomTimingsHandler(@NotNull String name) {
- Timing timing;
-
- new AuthorNagException("Deprecated use of CustomTimingsHandler. Please Switch to Timings.of ASAP").printStackTrace();
- new AuthorNagException("Deprecated use of CustomTimingsHandler. Timings has been removed.").printStackTrace();
- try {
- final Method ofSafe = TimingsManager.class.getDeclaredMethod("getHandler", String.class, String.class, Timing.class);
- ofSafe.setAccessible(true);
@@ -2321,7 +2173,7 @@ index 9c2d605c50cbf9aefa56ec209df9f6cea1392e89..00000000000000000000000000000000
- handler = timing;
- }
-
- public void startTiming() { /*handler.startTiming();*/ } // Purpur
- public void stopTiming() { /*handler.stopTiming();*/ } // Purpur
- public void startTiming() { /*handler.startTiming();*/ } // Purpur - Remove Timings
- public void stopTiming() { /*handler.stopTiming();*/ } // Purpur - Remove Timings
-
-}

View File

@@ -0,0 +1,77 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Tue, 14 Jan 2025 19:49:49 +0300
Subject: [PATCH] Expanded Adventure support
Adds support for Adventure in a few places where it was previously missing.
Original patch was taken from Parchment: https://github.com/ProjectEdenGG/Parchment
diff --git a/src/main/java/org/bukkit/Color.java b/src/main/java/org/bukkit/Color.java
index f8edb964c4af597b03a2de06c464cc06a96b791c..596e2e09c6a64fa5861221789185d2fd7b004248 100644
--- a/src/main/java/org/bukkit/Color.java
+++ b/src/main/java/org/bukkit/Color.java
@@ -17,7 +17,7 @@ import org.jetbrains.annotations.Nullable;
* but subject to change.
*/
@SerializableAs("Color")
-public final class Color implements ConfigurationSerializable {
+public final class Color implements ConfigurationSerializable, net.kyori.adventure.text.format.TextColor { // DivineMC - Expanded Adventure support
private static final int BIT_MASK = 0xff;
private static final int DEFAULT_ALPHA = 255;
@@ -310,6 +310,13 @@ public final class Color implements ConfigurationSerializable {
return getAlpha() << 24 | getRed() << 16 | getGreen() << 8 | getBlue();
}
+ // DivineMC start - Expanded Adventure support
+ @Override
+ public int value() {
+ return asRGB();
+ }
+ // DivineMC end - Expanded Adventure support
+
/**
* Gets the color as an BGR integer.
*
diff --git a/src/main/java/org/bukkit/DyeColor.java b/src/main/java/org/bukkit/DyeColor.java
index 2f038f233afd4210687586800070d5f61e40562a..24068f23f45a0d3b837b04565d143a5cd8cd8869 100644
--- a/src/main/java/org/bukkit/DyeColor.java
+++ b/src/main/java/org/bukkit/DyeColor.java
@@ -8,7 +8,7 @@ import org.jetbrains.annotations.Nullable;
/**
* All supported color values for dyes and cloth
*/
-public enum DyeColor {
+public enum DyeColor implements net.kyori.adventure.util.RGBLike, net.kyori.adventure.text.format.StyleBuilderApplicable { // DivineMC - Expanded Adventure support
/**
* Represents white dye.
@@ -135,6 +135,28 @@ public enum DyeColor {
return firework;
}
+ // DivineMC start - Expanded Adventure support
+ @Override
+ public @org.jetbrains.annotations.Range(from = 0L, to = 255L) int red() {
+ return color.getRed();
+ }
+
+ @Override
+ public @org.jetbrains.annotations.Range(from = 0L, to = 255L) int green() {
+ return color.getGreen();
+ }
+
+ @Override
+ public @org.jetbrains.annotations.Range(from = 0L, to = 255L) int blue() {
+ return color.getBlue();
+ }
+
+ @Override
+ public void styleApply(net.kyori.adventure.text.format.Style.@org.jetbrains.annotations.NotNull Builder style) {
+ style.color(net.kyori.adventure.text.format.TextColor.color(color));
+ }
+ // DivineMC end - Expanded Adventure support
+
/**
* Gets the DyeColor with the given wool data value.
*

View File

@@ -0,0 +1,181 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Tue, 14 Jan 2025 20:36:30 +0300
Subject: [PATCH] Extend Location API
diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java
index 8bc340c9d4d8d1b113d877e25af769ef9251dc94..1311f7c82e412aec415a7f2a581400b84f86df9b 100644
--- a/src/main/java/org/bukkit/Location.java
+++ b/src/main/java/org/bukkit/Location.java
@@ -1212,4 +1212,170 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
public @NotNull Location toLocation(@NotNull World world) {
return new Location(world, this.x(), this.y(), this.z(), this.getYaw(), this.getPitch());
}
+
+ // DivineMC start - Extend Location API
+ /**
+ * Sets the x-coordinate of this location.
+ *
+ * @param x The x-coordinate
+ * @return this location
+ */
+ public @NotNull Location x(double x) {
+ this.x = x;
+ return this;
+ }
+
+ /**
+ * Sets the y-coordinate of this location.
+ *
+ * @param y The y-coordinate
+ * @return this location
+ */
+ public @NotNull Location y(double y) {
+ this.y = y;
+ return this;
+ }
+
+ /**
+ * Sets the z-coordinate of this location.
+ *
+ * @param z The z-coordinate
+ * @return this location
+ */
+ public @NotNull Location z(double z) {
+ this.z = z;
+ return this;
+ }
+
+ /**
+ * Sets the yaw of this location, measured in degrees.
+ * <ul>
+ * <li>A yaw of 0 or 360 represents the positive z direction.
+ * <li>A yaw of 180 represents the negative z direction.
+ * <li>A yaw of 90 represents the negative x direction.
+ * <li>A yaw of 270 represents the positive x direction.
+ * </ul>
+ * Increasing yaw values are the equivalent of turning to your
+ * right-facing, increasing the scale of the next respective axis, and
+ * decreasing the scale of the previous axis.
+ *
+ * @param yaw new rotation's yaw
+ * @return this location
+ */
+ public @NotNull Location yaw(float yaw) {
+ this.yaw = yaw;
+ return this;
+ }
+
+ /**
+ * Sets the pitch of this location, measured in degrees.
+ * <ul>
+ * <li>A pitch of 0 represents level forward facing.
+ * <li>A pitch of 90 represents downward facing, or negative y
+ * direction.
+ * <li>A pitch of -90 represents upward facing, or positive y direction.
+ * </ul>
+ * Increasing pitch values the equivalent of looking down.
+ *
+ * @param pitch new incline's pitch
+ * @return this location
+ */
+ public @NotNull Location pitch(float pitch) {
+ this.pitch = pitch;
+ return this;
+ }
+
+ /**
+ * Sets the world that this location resides in
+ *
+ * @param world New world that this location resides in
+ * @return this location
+ */
+ public @NotNull Location world(@Nullable World world) {
+ this.world = (world == null) ? null : new WeakReference<>(world);
+ return this;
+ }
+
+ /**
+ * Increments the x-coordinate by the given value.
+ *
+ * @param x Amount to increment the x-coordinate by
+ * @return this location
+ */
+ public @NotNull Location addX(double x) {
+ this.x += x;
+ return this;
+ }
+
+ /**
+ * Increments the y-coordinate by the given value.
+ *
+ * @param y Amount to increment the y-coordinate by
+ * @return this location
+ */
+ public @NotNull Location addY(double y) {
+ this.y += y;
+ return this;
+ }
+
+ /**
+ * Increments the z-coordinate by the given value.
+ *
+ * @param z Amount to increment the z-coordinate by
+ * @return this location
+ */
+ public @NotNull Location addZ(double z) {
+ this.z += z;
+ return this;
+ }
+
+ /**
+ * Returns location with centered X, Y and Z values.
+ *
+ * @return this location
+ */
+ public @NotNull Location center() {
+ return center(0.5);
+ }
+
+ /**
+ * Returns location with centered X and Z values.
+ * Y will be set to provided.
+ *
+ * @param y Y adding value
+ * @return this location
+ */
+ public @NotNull Location center(double y) {
+ return set(getBlockX() + 0.5, getBlockY() + y, getBlockZ() + 0.5);
+ }
+
+ /**
+ * Checks if locations have the same X, Y and Z values.
+ *
+ * @param loc Location to check
+ * @return true if locations have same coordinates
+ * @apiNote Ignores world
+ */
+ public boolean isSame(@NotNull Location loc) {
+ return getY() == loc.getY() && getX() == loc.getX() && getZ() == loc.getZ();
+ }
+
+ /**
+ * Shifts this location by one block up
+ *
+ * @return this location
+ */
+ public @NotNull Location above() {
+ return addY(1);
+ }
+
+ /**
+ * Shifts this location by one block down
+ *
+ * @return this location
+ */
+ public @NotNull Location below() {
+ return addY(-1);
+ }
+ // DivineMC end - Extend Location API
}

View File

@@ -0,0 +1,80 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Tue, 14 Jan 2025 20:42:04 +0300
Subject: [PATCH] Extend Sound API
diff --git a/src/main/java/org/bukkit/block/Block.java b/src/main/java/org/bukkit/block/Block.java
index b703ad820ff873097dadff9e55b53fcc6b1b8698..b35c3852a3b8e62c7d2f67fc3ff651c8e0a4d5f2 100644
--- a/src/main/java/org/bukkit/block/Block.java
+++ b/src/main/java/org/bukkit/block/Block.java
@@ -817,4 +817,29 @@ public interface Block extends Metadatable, Translatable, net.kyori.adventure.tr
return this.getBlockData().getDestroySpeed(itemStack, considerEnchants);
}
// Paper end - destroy speed API
+
+ // DivineMC start - Extend Sound API
+ /**
+ * Plays a sound at the location of the block
+ *
+ * @param sound sound to play
+ * @param volume volume of the sound
+ * @param pitch pitch of the sound
+ */
+ default void emitSound(@NotNull org.bukkit.Sound sound, float volume, float pitch) {
+ emitSound(sound, org.bukkit.SoundCategory.BLOCKS, volume, pitch);
+ }
+
+ /**
+ * Plays a sound at the location of the block
+ *
+ * @param sound sound to play
+ * @param category category of the sound
+ * @param volume volume of the sound
+ * @param pitch pitch of the sound
+ */
+ default void emitSound(@NotNull org.bukkit.Sound sound, @NotNull org.bukkit.SoundCategory category, float volume, float pitch) {
+ getWorld().playSound(getLocation().toCenterLocation(), sound, category, volume, pitch);
+ }
+ // DivineMC end - Extend Sound API
}
diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
index 49d3ca54a761e08cfe1bc770cb879223bf0e21e8..942f7497a56baa8e717980795e605a8907039fe6 100644
--- a/src/main/java/org/bukkit/entity/Entity.java
+++ b/src/main/java/org/bukkit/entity/Entity.java
@@ -1251,4 +1251,35 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
*/
void setImmuneToFire(@Nullable Boolean fireImmune);
// Purpur end - Fire Immunity API
+
+ // DivineMC start - Extend Sound API
+ /**
+ * Plays a sound at the location of the entity
+ *
+ * @param sound sound to play
+ * @param volume volume of the sound
+ * @param pitch pitch of the sound
+ */
+ default void emitSound(@NotNull org.bukkit.Sound sound, float volume, float pitch) {
+ org.bukkit.SoundCategory soundGroup = switch (this) {
+ case HumanEntity humanEntity -> org.bukkit.SoundCategory.PLAYERS;
+ case Ambient ambient -> org.bukkit.SoundCategory.AMBIENT;
+ case Monster monster -> org.bukkit.SoundCategory.HOSTILE;
+ default -> org.bukkit.SoundCategory.NEUTRAL;
+ };
+ emitSound(sound, soundGroup, volume, pitch);
+ }
+
+ /**
+ * Plays a sound at the location of the block
+ *
+ * @param sound sound to play
+ * @param category category of the sound
+ * @param volume volume of the sound
+ * @param pitch pitch of the sound
+ */
+ default void emitSound(@NotNull org.bukkit.Sound sound, @NotNull org.bukkit.SoundCategory category, float volume, float pitch) {
+ getWorld().playSound(this, sound, category, volume, pitch);
+ }
+ // DivineMC end - Extend Sound API
}

View File

@@ -0,0 +1,17 @@
--- a/src/main/java/io/papermc/paper/ServerBuildInfo.java
+++ b/src/main/java/io/papermc/paper/ServerBuildInfo.java
@@ -25,6 +_,14 @@
*/
Key BRAND_PURPUR_ID = Key.key("purpurmc", "purpur");
// Purpur end
+
+ // DivineMC start
+ /**
+ * The brand id for DivineMC.
+ */
+ Key BRAND_DIVINEMC_ID = Key.key("divinemc", "divinemc");
+ // DivineMC end
+
/**
* Gets the {@code ServerBuildInfo}.
*

View File

@@ -0,0 +1,73 @@
--- a/src/main/java/org/bukkit/Note.java
+++ b/src/main/java/org/bukkit/Note.java
@@ -127,6 +_,7 @@
}
private final byte note;
+ private final net.kyori.adventure.text.format.TextColor color; // DivineMC - Note Color API
/**
* Creates a new note.
@@ -138,6 +_,7 @@
Preconditions.checkArgument(note >= 0 && note <= 24, "The note value has to be between 0 and 24.");
this.note = (byte) note;
+ this.color = getColor(note); // DivineMC - Note Color API
}
/**
@@ -158,6 +_,7 @@
}
this.note = (byte) (octave * Tone.TONES_COUNT + tone.getId(sharped));
+ this.color = getColor(note); // DivineMC - Note Color API
}
/**
@@ -298,4 +_,46 @@
public String toString() {
return "Note{" + getTone().toString() + (isSharped() ? "#" : "") + "}";
}
+
+ // DivineMC start - Note Color API
+ /**
+ * Get color of the played note.
+ *
+ * @return the color of the note
+ */
+ @NotNull
+ public net.kyori.adventure.text.format.TextColor getColor() {
+ return color;
+ }
+
+ private static @NotNull net.kyori.adventure.text.format.TextColor getColor(int note) {
+ return switch (note) {
+ case 0 -> net.kyori.adventure.text.format.TextColor.fromHexString("#77D700");
+ case 1 -> net.kyori.adventure.text.format.TextColor.fromHexString("#95C000");
+ case 2 -> net.kyori.adventure.text.format.TextColor.fromHexString("#B2A500");
+ case 3 -> net.kyori.adventure.text.format.TextColor.fromHexString("#CC8600");
+ case 4 -> net.kyori.adventure.text.format.TextColor.fromHexString("#E26500");
+ case 5 -> net.kyori.adventure.text.format.TextColor.fromHexString("#F34100");
+ case 6 -> net.kyori.adventure.text.format.TextColor.fromHexString("#FC1E00");
+ case 7 -> net.kyori.adventure.text.format.TextColor.fromHexString("#FE000F");
+ case 8 -> net.kyori.adventure.text.format.TextColor.fromHexString("#F70033");
+ case 9 -> net.kyori.adventure.text.format.TextColor.fromHexString("#E8005A");
+ case 10 -> net.kyori.adventure.text.format.TextColor.fromHexString("#CF0083");
+ case 11 -> net.kyori.adventure.text.format.TextColor.fromHexString("#AE00A9");
+ case 12 -> net.kyori.adventure.text.format.TextColor.fromHexString("#8600CC");
+ case 13 -> net.kyori.adventure.text.format.TextColor.fromHexString("#5B00E7");
+ case 14 -> net.kyori.adventure.text.format.TextColor.fromHexString("#2D00F9");
+ case 15 -> net.kyori.adventure.text.format.TextColor.fromHexString("#020AFE");
+ case 16 -> net.kyori.adventure.text.format.TextColor.fromHexString("#0037F6");
+ case 17 -> net.kyori.adventure.text.format.TextColor.fromHexString("#0068E0");
+ case 18 -> net.kyori.adventure.text.format.TextColor.fromHexString("#009ABC");
+ case 19 -> net.kyori.adventure.text.format.TextColor.fromHexString("#00C68D");
+ case 20 -> net.kyori.adventure.text.format.TextColor.fromHexString("#00E958");
+ case 21 -> net.kyori.adventure.text.format.TextColor.fromHexString("#00FC21");
+ case 22 -> net.kyori.adventure.text.format.TextColor.fromHexString("#1FFC00");
+ case 23 -> net.kyori.adventure.text.format.TextColor.fromHexString("#59E800");
+ default -> net.kyori.adventure.text.format.TextColor.fromHexString("#94C100");
+ };
+ }
+ // DivineMC end - Note Color API
}

View File

@@ -0,0 +1,16 @@
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -2342,6 +_,13 @@
}
// Purpur end
+ // DivineMC start
+ @NotNull
+ public org.bukkit.configuration.file.YamlConfiguration getDivineConfig() {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+ // DivineMC end
+
/**
* Sends the component to the player
*

View File

@@ -0,0 +1,19 @@
--- a/src/main/java/org/bukkit/command/Command.java
+++ b/src/main/java/org/bukkit/command/Command.java
@@ -33,16 +_,6 @@
protected String usageMessage;
private String permission;
private net.kyori.adventure.text.Component permissionMessage; // Paper
- /**
- * @deprecated Timings will be removed in the future
- */
- @Deprecated(forRemoval = true)
- public co.aikar.timings.Timing timings; // Paper
- /**
- * @deprecated Timings will be removed in the future
- */
- @Deprecated(forRemoval = true)
- @NotNull public String getTimingName() {return getName();} // Paper
protected Command(@NotNull String name) {
this(name, "", "/" + name, new ArrayList<String>());

View File

@@ -0,0 +1,21 @@
--- a/src/main/java/org/bukkit/command/FormattedCommandAlias.java
+++ b/src/main/java/org/bukkit/command/FormattedCommandAlias.java
@@ -12,7 +_,6 @@
public FormattedCommandAlias(@NotNull String alias, @NotNull String[] formatStrings) {
super(alias);
- timings = co.aikar.timings.TimingsManager.getCommandTiming("minecraft", this); // Spigot
this.formatStrings = formatStrings;
}
@@ -119,10 +_,6 @@
return formatString.trim(); // Paper - Causes an extra space at the end, breaks with brig commands
}
-
- @NotNull
- @Override // Paper
- public String getTimingName() {return "Command Forwarder - " + super.getTimingName();} // Paper
private static boolean inRange(int i, int j, int k) {
return i >= j && i <= k;

View File

@@ -0,0 +1,31 @@
--- a/src/main/java/org/bukkit/command/SimpleCommandMap.java
+++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java
@@ -39,7 +_,6 @@
register("bukkit", new VersionCommand("version"));
register("bukkit", new ReloadCommand("reload"));
//register("bukkit", new PluginsCommand("plugins")); // Paper
- register("bukkit", new co.aikar.timings.TimingsCommand("timings")); // Paper
}
public void setFallbackCommands() {
@@ -71,7 +_,6 @@
*/
@Override
public boolean register(@NotNull String label, @NotNull String fallbackPrefix, @NotNull Command command) {
- command.timings = co.aikar.timings.TimingsManager.getCommandTiming(fallbackPrefix, command); // Paper
label = label.toLowerCase(Locale.ROOT).trim();
fallbackPrefix = fallbackPrefix.toLowerCase(Locale.ROOT).trim();
boolean registered = register(label, command, false, fallbackPrefix);
@@ -165,12 +_,6 @@
sentCommandLabel = event.getLabel();
parsedArgs = event.getArgs();
// Purpur end - ExecuteCommandEvent
-
- // Paper start - Plugins do weird things to workaround normal registration
- if (target.timings == null) {
- target.timings = co.aikar.timings.TimingsManager.getCommandTiming(null, target);
- }
- // Paper end
try {
//try (co.aikar.timings.Timing ignored = target.timings.startTiming()) { // Paper - use try with resources // Purpur - Remove Timings

View File

@@ -0,0 +1,11 @@
--- a/src/main/java/org/bukkit/command/defaults/VersionCommand.java
+++ b/src/main/java/org/bukkit/command/defaults/VersionCommand.java
@@ -259,7 +_,7 @@
// Purpur start
int distance = getVersionFetcher().distance();
final Component message = Component.join(net.kyori.adventure.text.JoinConfiguration.separator(Component.newline()),
- ChatColor.parseMM("<grey>Current Purpur Version: %s%s*", distance == 0 ? "<green>" : distance > 0 ? "<yellow>" : "<red>", Bukkit.getVersion()),
+ ChatColor.parseMM("<grey>Current DivineMC Version: %s%s*", distance == 0 ? "<green>" : distance > 0 ? "<yellow>" : "<red>", Bukkit.getVersion()), // DivineMC - Rebrand
// Purpur end
msg
);

View File

@@ -0,0 +1,14 @@
--- a/src/main/java/org/bukkit/entity/AbstractArrow.java
+++ b/src/main/java/org/bukkit/entity/AbstractArrow.java
@@ -282,4 +_,11 @@
*/
void setShooter(@Nullable org.bukkit.projectiles.ProjectileSource source, boolean resetPickupStatus);
// Paper end - Fix PickupStatus getting reset
+
+ // DivineMC start - Add startFalling method to AbstractArrow
+ /**
+ * Asks projectile to start falling if possible
+ */
+ void startFalling();
+ // DivineMC end - Add startFalling method to AbstractArrow
}

View File

@@ -0,0 +1,17 @@
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -4011,4 +_,14 @@
sendDeathScreen(message);
}
// Purpur end
+
+ // DivineMC start - Open Ender Chest API
+ /**
+ * Opens ender chest for the player
+ *
+ * @param enderChest ender chest
+ * @return whether the chest was opened
+ */
+ boolean openEnderChest(@NotNull org.bukkit.block.EnderChest enderChest);
+ // DivineMC end - Open Ender Chest API
}

View File

@@ -0,0 +1,43 @@
--- a/src/main/java/org/bukkit/event/block/NotePlayEvent.java
+++ b/src/main/java/org/bukkit/event/block/NotePlayEvent.java
@@ -16,13 +_,21 @@
private static HandlerList handlers = new HandlerList();
private Instrument instrument;
private Note note;
+ private final @org.jetbrains.annotations.Nullable org.bukkit.entity.Player player; // DivineMC - Add player to NotePlayEvent
private boolean cancelled = false;
+ // DivineMC start - Add player to NotePlayEvent
public NotePlayEvent(@NotNull Block block, @NotNull Instrument instrument, @NotNull Note note) {
+ this(block, instrument, note, null);
+ }
+
+ public NotePlayEvent(@NotNull Block block, @NotNull Instrument instrument, @NotNull Note note, @org.jetbrains.annotations.Nullable org.bukkit.entity.Player player) {
super(block);
this.instrument = instrument;
this.note = note;
+ this.player = player;
}
+ // DivineMC end - Add player to NotePlayEvent
@Override
public boolean isCancelled() {
@@ -53,6 +_,18 @@
public Note getNote() {
return note;
}
+
+ // DivineMC start - Add player to NotePlayEvent
+ /**
+ * Gets the {@link org.bukkit.entity.Player} who played the note
+ *
+ * @return player who played the note, if present
+ */
+ @org.jetbrains.annotations.Nullable
+ public org.bukkit.entity.Player getPlayer() {
+ return this.player;
+ }
+ // DivineMC end - Add player to NotePlayEvent
/**
* Overrides the {@link Instrument} to be used.

View File

@@ -0,0 +1,35 @@
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
@@ -720,12 +_,7 @@
throw new IllegalPluginAccessException("Plugin attempted to register " + event + " while not enabled");
}
- executor = new co.aikar.timings.TimedEventExecutor(executor, plugin, null, event); // Paper
- if (false) { // Spigot - RL handles useTimings check now // Paper
- getEventListeners(event).register(new TimedRegisteredListener(listener, executor, priority, plugin, ignoreCancelled));
- } else {
- getEventListeners(event).register(new RegisteredListener(listener, executor, priority, plugin, ignoreCancelled));
- }
+ getEventListeners(event).register(new RegisteredListener(listener, executor, priority, plugin, ignoreCancelled));
}
@NotNull
@@ -955,8 +_,7 @@
@Override
public boolean useTimings() {
- if (true) {return this.paperPluginManager.useTimings();} // Paper
- return co.aikar.timings.Timings.isTimingsEnabled(); // Spigot
+ return false;
}
/**
@@ -966,7 +_,7 @@
*/
@Deprecated(forRemoval = true)
public void useTimings(boolean use) {
- co.aikar.timings.Timings.setTimingsEnabled(use); // Paper
+ // DivineMC - Delete timings
}
// Paper start

View File

@@ -0,0 +1,28 @@
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
@@ -43,7 +_,6 @@
import org.bukkit.plugin.UnknownDependencyException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.spigotmc.CustomTimingsHandler; // Spigot
import org.yaml.snakeyaml.error.YAMLException;
/**
@@ -294,7 +_,7 @@
}
}
- EventExecutor executor = new co.aikar.timings.TimedEventExecutor(new EventExecutor() { // Paper
+ EventExecutor executor = new EventExecutor() { // Paper
@Override
public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException { // Paper
try {
@@ -308,7 +_,7 @@
throw new EventException(t);
}
}
- }, plugin, method, eventClass); // Paper
+ }; // DivineMC - Delete Timings
if (false) { // Spigot - RL handles useTimings check now
eventSet.add(new TimedRegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled()));
} else {

View File

@@ -0,0 +1,111 @@
--- a/purpur-server/build.gradle.kts
+++ b/purpur-server/build.gradle.kts
@@ -22,6 +_,7 @@
// gitFilePatches = true
val purpur = forks.register("purpur") {
+ rootDirectory = upstreamsDirectory().map { it.dir("purpur") }
upstream.patchDir("paperServer") {
upstreamPath = "paper-server"
excludes = setOf("src/minecraft", "patches", "build.gradle.kts")
@@ -29,7 +_,23 @@
outputDir = rootDirectory.dir("paper-server")
}
}
- activeFork = purpur
+
+ val divinemc = forks.register("divinemc") {
+ forks = purpur
+ upstream.patchRepo("paperServer") {
+ upstreamRepo = purpur.patchedRepo("paperServer")
+ patchesDir = rootDirectory.dir("divinemc-server/paper-patches")
+ outputDir = rootDirectory.dir("paper-server")
+ }
+ upstream.patchDir("purpurServer") {
+ upstreamPath = "purpur-server"
+ excludes = setOf("src/minecraft", "paper-patches", "minecraft-patches", "build.gradle.kts", "build.gradle.kts.patch")
+ patchesDir = rootDirectory.dir("divinemc-server/purpur-patches")
+ outputDir = rootDirectory.dir("purpur-server")
+ }
+ }
+
+ activeFork = divinemc
spigot {
buildDataRef = "3edaf46ec1eed4115ce1b18d2846cded42577e42"
@@ -115,10 +_,14 @@
main {
java { srcDir("../paper-server/src/main/java") }
resources { srcDir("../paper-server/src/main/resources") }
+ java { srcDir("../purpur-server/src/main/java") }
+ resources { srcDir("../purpur-server/src/main/resources") }
}
test {
java { srcDir("../paper-server/src/test/java") }
resources { srcDir("../paper-server/src/test/resources") }
+ java { srcDir("../purpur-server/src/test/java") }
+ resources { srcDir("../purpur-server/src/test/resources") }
}
}
@@ -142,7 +_,7 @@
}
dependencies {
- implementation(project(":purpur-api"))
+ implementation(project(":divinemc-api")) // DivineMC
implementation("ca.spottedleaf:concurrentutil:0.0.3")
implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+
implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21
@@ -176,6 +_,9 @@
implementation("org.mozilla:rhino-engine:1.7.14") // Purpur
implementation("dev.omega24:upnp4j:1.0") // Purpur
+ implementation("com.github.luben:zstd-jni:1.5.6-9") // DivineMC
+ implementation("org.lz4:lz4-java:1.8.0") // DivineMC
+
runtimeOnly("org.apache.maven:maven-resolver-provider:3.9.6")
runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18")
runtimeOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18")
@@ -203,26 +_,35 @@
implementation("me.lucko:spark-paper:1.10.119-SNAPSHOT")
}
+// DivineMC start - hide irrelevant compilation warnings
+tasks.withType<JavaCompile> {
+ val compilerArgs = options.compilerArgs
+ compilerArgs.add("-Xlint:-module")
+ compilerArgs.add("-Xlint:-removal")
+ compilerArgs.add("-Xlint:-dep-ann")
+}
+// DivineMC end - hide irrelevant compilation warnings
+
tasks.jar {
manifest {
val git = Git(rootProject.layout.projectDirectory.path)
val mcVersion = rootProject.providers.gradleProperty("mcVersion").get()
val build = System.getenv("BUILD_NUMBER") ?: null
- val buildTime = if (build != null) Instant.now() else Instant.EPOCH
+ val buildTime = Instant.now() // DivineMC - Build time to current, we dont have a build server rn
val gitHash = git.exec(providers, "rev-parse", "--short=7", "HEAD").get().trim()
val implementationVersion = "$mcVersion-${build ?: "DEV"}-$gitHash"
val date = git.exec(providers, "show", "-s", "--format=%ci", gitHash).get().trim()
val gitBranch = git.exec(providers, "rev-parse", "--abbrev-ref", "HEAD").get().trim()
attributes(
"Main-Class" to "org.bukkit.craftbukkit.Main",
- "Implementation-Title" to "Purpur", // Purpur
+ "Implementation-Title" to "DivineMC", // DivineMC
"Implementation-Version" to implementationVersion,
"Implementation-Vendor" to date,
- "Specification-Title" to "Purpur", // Purpur
+ "Specification-Title" to "DivineMC", // DivineMC
"Specification-Version" to project.version,
- "Specification-Vendor" to "Purpur Team", // Purpur
- "Brand-Id" to "purpurmc:purpur", // Purpur
- "Brand-Name" to "Purpur", // Purpur
+ "Specification-Vendor" to "BX Team", // DivineMC
+ "Brand-Id" to "divinemc:divinemc", // DivineMC
+ "Brand-Name" to "DivineMC", // DivineMC
"Build-Number" to (build ?: ""),
"Build-Time" to buildTime.toString(),
"Git-Branch" to gitBranch,

View File

@@ -0,0 +1,32 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sat, 11 Jan 2025 22:22:01 +0300
Subject: [PATCH] Rebrand
diff --git a/net/minecraft/CrashReport.java b/net/minecraft/CrashReport.java
index 394443d00e661715439be1e56dddc129947699a4..480ad57a6b7b74e6b83e9c6ceb69ea1feacca106 100644
--- a/net/minecraft/CrashReport.java
+++ b/net/minecraft/CrashReport.java
@@ -30,7 +30,7 @@ public class CrashReport {
private boolean trackingStackTrace = true;
private StackTraceElement[] uncategorizedStackTrace = new StackTraceElement[0];
private final SystemReport systemReport = new SystemReport();
- private List<String> extraInfo = List.of("", "DO NOT REPORT THIS TO PAPER! REPORT TO PURPUR INSTEAD!", ""); // Purpur - Rebrand
+ private List<String> extraInfo = List.of("", "DO NOT REPORT THIS TO PAPER! REPORT TO DIVINEMC INSTEAD!", ""); // DivineMC - Rebrand
public CrashReport(String title, Throwable exception) {
io.papermc.paper.util.StacktraceDeobfuscator.INSTANCE.deobfuscateThrowable(exception); // Paper
diff --git a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
index 80ed0e4b8c867d031413b4140e52af1342fdcb54..6ebd1300c2561116b83cb2472ac7939ead36d576 100644
--- a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -283,7 +283,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
// Paper start
private static void printOversizedLog(String msg, Path file, int x, int z) {
- org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO PURPUR - You may ask for help on Discord, but do not file an issue. These error messages can not be removed."); // Purpur - Rebrand
+ org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO DIVINEMC - You may ask for help on Discord, but do not file an issue. These error messages can not be removed."); // DivineMC - Rebrand
}
private static CompoundTag readOversizedChunk(RegionFile regionfile, ChunkPos chunkCoordinate) throws IOException {

View File

@@ -0,0 +1,48 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sun, 12 Jan 2025 16:19:14 +0300
Subject: [PATCH] DivineMC Configuration
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 2d7493122db9067ecbc9ca66cc62e7df4ae78a90..c85023893fbb227894f8f888244f1f53e25dff3f 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -243,6 +243,17 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
}
org.purpurmc.purpur.PurpurConfig.registerCommands();
// Purpur end - Purpur config files
+
+ // DivineMC start - DivineMC configuration
+ try {
+ space.bxteam.divinemc.configuration.DivineConfig.init((java.io.File) options.valueOf("divinemc-settings"));
+ } catch (Exception e) {
+ DedicatedServer.LOGGER.error("Unable to load server configuration", e);
+ return false;
+ }
+ space.bxteam.divinemc.command.DivineCommands.registerCommands(this); // DivineMC - register commands
+ // DivineMC end - DivineMC configuration
+
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now
this.setPvpAllowed(properties.pvp);
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index 1b2d152649bc12b37db1cd7a4f54517f417d46e8..71c4c79d94473a95479bc73cfb7415e1813970de 100644
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
@@ -171,6 +171,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
public final io.papermc.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray
public final org.purpurmc.purpur.PurpurWorldConfig purpurConfig; // Purpur - Purpur config files
+ public final space.bxteam.divinemc.configuration.DivineWorldConfig divinemcConfig; // DivineMC - DivineMC config files
public static BlockPos lastPhysicsProblem; // Spigot
private int tileTickPosition;
public final Map<ServerExplosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
@@ -896,6 +897,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName()); // Spigot
this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config
this.purpurConfig = new org.purpurmc.purpur.PurpurWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName(), env); // Purpur - Purpur config files
+ this.divinemcConfig = new space.bxteam.divinemc.configuration.DivineWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName(), env); // DivineMC - DivineMC configuration
this.playerBreedingCooldowns = this.getNewBreedingCooldownCache(); // Purpur - Add adjustable breeding cooldown to config
this.generator = gen;
this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env);

View File

@@ -0,0 +1,183 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sun, 12 Jan 2025 00:14:45 +0300
Subject: [PATCH] Add missing purpur config options
diff --git a/net/minecraft/world/entity/animal/allay/Allay.java b/net/minecraft/world/entity/animal/allay/Allay.java
index 22e0fad86da2e7b932863ef30182355aa41424a1..d4eee24b5ab89f82e4e90f551d6651330d4508cb 100644
--- a/net/minecraft/world/entity/animal/allay/Allay.java
+++ b/net/minecraft/world/entity/animal/allay/Allay.java
@@ -181,6 +181,18 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS
}
// Purpur end - Configurable entity base attributes
+ // DivineMC start - Add missing purpur config options
+ @Override
+ public boolean isSensitiveToWater() {
+ return level().purpurConfig.allayTakeDamageFromWater;
+ }
+
+ @Override
+ public boolean isAlwaysExperienceDropper() {
+ return level().purpurConfig.allayAlwaysDropExp;
+ }
+ // DivineMC end - Add missing purpur config options
+
@Override
protected Brain.Provider<Allay> brainProvider() {
return Brain.provider(MEMORY_TYPES, SENSOR_TYPES);
diff --git a/net/minecraft/world/entity/animal/camel/Camel.java b/net/minecraft/world/entity/animal/camel/Camel.java
index 1d7ae2a08968860636918e7c66b60139a9d761b4..126af60a694600d40e3ae6bd39e94e55dd9d0b6e 100644
--- a/net/minecraft/world/entity/animal/camel/Camel.java
+++ b/net/minecraft/world/entity/animal/camel/Camel.java
@@ -97,6 +97,18 @@ public class Camel extends AbstractHorse {
}
// Purpur end - Make entity breeding times configurable
+ // DivineMC start - Add missing purpur config options
+ @Override
+ public boolean isSensitiveToWater() {
+ return level().purpurConfig.camelTakeDamageFromWater;
+ }
+
+ @Override
+ public boolean isAlwaysExperienceDropper() {
+ return level().purpurConfig.camelAlwaysDropExp;
+ }
+ // DivineMC end - Add missing purpur config options
+
@Override
public void addAdditionalSaveData(CompoundTag compound) {
super.addAdditionalSaveData(compound);
diff --git a/net/minecraft/world/entity/animal/frog/Frog.java b/net/minecraft/world/entity/animal/frog/Frog.java
index c4ea9485294b7dec2582c638802f003ad70659b6..d286d4a45b6c8d5c684ad11500d2ad1a10a70c18 100644
--- a/net/minecraft/world/entity/animal/frog/Frog.java
+++ b/net/minecraft/world/entity/animal/frog/Frog.java
@@ -165,6 +165,23 @@ public class Frog extends Animal implements VariantHolder<Holder<FrogVariant>> {
}
// Purpur end - Ridables
+ // DivineMC start - Add missing purpur config options
+ @Override
+ public boolean isSensitiveToWater() {
+ return level().purpurConfig.frogTakeDamageFromWater;
+ }
+
+ @Override
+ public boolean isAlwaysExperienceDropper() {
+ return level().purpurConfig.frogAlwaysDropExp;
+ }
+
+ @Override
+ public void initAttributes() {
+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level().purpurConfig.frogMaxHealth);
+ }
+ // DivineMC end
+
// Purpur start - Make entity breeding times configurable
@Override
public int getPurpurBreedTime() {
diff --git a/net/minecraft/world/entity/animal/frog/Tadpole.java b/net/minecraft/world/entity/animal/frog/Tadpole.java
index e888e606b4b14fa6485de7426bc146b6005962af..a4383a7d41c91f9e478c7e221828ba92437af06c 100644
--- a/net/minecraft/world/entity/animal/frog/Tadpole.java
+++ b/net/minecraft/world/entity/animal/frog/Tadpole.java
@@ -107,6 +107,23 @@ public class Tadpole extends AbstractFish {
}
// Purpur end - Ridables
+ // DivineMC start - Add missing purpur config options
+ @Override
+ public boolean isSensitiveToWater() {
+ return level().purpurConfig.tadpoleTakeDamageFromWater;
+ }
+
+ @Override
+ public boolean isAlwaysExperienceDropper() {
+ return level().purpurConfig.tadpoleAlwaysDropExp;
+ }
+
+ @Override
+ public void initAttributes() {
+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level().purpurConfig.tadpoleMaxHealth);
+ }
+ // DivineMC end - Add missing purpur config options
+
@Override
protected PathNavigation createNavigation(Level level) {
return new WaterBoundPathNavigation(this, level);
diff --git a/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/net/minecraft/world/entity/animal/sniffer/Sniffer.java
index 11a5da22149a61ca48bbb0a8ed10b71e91a5cc98..ed1ffc1578e50fa6fedc6124fe016a1535c0e968 100644
--- a/net/minecraft/world/entity/animal/sniffer/Sniffer.java
+++ b/net/minecraft/world/entity/animal/sniffer/Sniffer.java
@@ -120,6 +120,18 @@ public class Sniffer extends Animal {
}
// Purpur end - Make entity breeding times configurable
+ // DivineMC start - Add missing purpur config options
+ @Override
+ public boolean isSensitiveToWater() {
+ return level().purpurConfig.snifferTakeDamageFromWater;
+ }
+
+ @Override
+ public boolean isAlwaysExperienceDropper() {
+ return level().purpurConfig.snifferAlwaysDropExp;
+ }
+ // DivineMC end
+
@Override
protected void defineSynchedData(SynchedEntityData.Builder builder) {
super.defineSynchedData(builder);
diff --git a/net/minecraft/world/entity/monster/warden/Warden.java b/net/minecraft/world/entity/monster/warden/Warden.java
index f968e5c99bdb23b268bc34ea1ba5d54ae9ad0ff9..f74c784906208034f51b31bd9aba45733c3ebebe 100644
--- a/net/minecraft/world/entity/monster/warden/Warden.java
+++ b/net/minecraft/world/entity/monster/warden/Warden.java
@@ -155,6 +155,23 @@ public class Warden extends Monster implements VibrationSystem {
}
// Purpur end - Ridables
+ // DivineMC start - Add missing purpur config options
+ @Override
+ public boolean isSensitiveToWater() {
+ return level().purpurConfig.wardenTakeDamageFromWater;
+ }
+
+ @Override
+ public boolean isAlwaysExperienceDropper() {
+ return level().purpurConfig.wardenAlwaysDropExp;
+ }
+
+ @Override
+ public void initAttributes() {
+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level().purpurConfig.wardenMaxHealth);
+ }
+ // DivineMC end
+
@Override
public Packet<ClientGamePacketListener> getAddEntityPacket(ServerEntity entity) {
return new ClientboundAddEntityPacket(this, entity, this.hasPose(Pose.EMERGING) ? 1 : 0);
diff --git a/net/minecraft/world/entity/vehicle/AbstractChestBoat.java b/net/minecraft/world/entity/vehicle/AbstractChestBoat.java
index b230955ae880d84fde40b4feffa5caf3c4449eb7..5b88c69427d5915ff547e4caf7b5656e96912e93 100644
--- a/net/minecraft/world/entity/vehicle/AbstractChestBoat.java
+++ b/net/minecraft/world/entity/vehicle/AbstractChestBoat.java
@@ -26,8 +26,8 @@ import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.storage.loot.LootTable;
public abstract class AbstractChestBoat extends AbstractBoat implements HasCustomInventoryScreen, ContainerEntity {
- private static final int CONTAINER_SIZE = 27;
- private NonNullList<ItemStack> itemStacks = NonNullList.withSize(27, ItemStack.EMPTY);
+ private static final int CONTAINER_SIZE = org.purpurmc.purpur.PurpurConfig.chestBoatRows * 9; // DivineMC - Add missing purpur config options
+ private NonNullList<ItemStack> itemStacks = NonNullList.withSize(org.purpurmc.purpur.PurpurConfig.chestBoatRows * 9, ItemStack.EMPTY); // DivineMC - Add missing purpur config options
@Nullable
private ResourceKey<LootTable> lootTable;
private long lootTableSeed;
@@ -118,7 +118,7 @@ public abstract class AbstractChestBoat extends AbstractBoat implements HasCusto
@Override
public int getContainerSize() {
- return 27;
+ return org.purpurmc.purpur.PurpurConfig.chestBoatRows * 9; // DivineMC - Add missing purpur config options
}
@Override

View File

@@ -1,15 +1,13 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Mon, 16 Dec 2024 20:52:48 +0300
Date: Sun, 12 Jan 2025 15:27:57 +0300
Subject: [PATCH] lithium: fast_util
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
diff --git a/src/main/java/net/minecraft/core/Direction.java b/src/main/java/net/minecraft/core/Direction.java
index 928f38fd6beb00753c92ae9f4678f7507519a39b..4c53995d6d173ff6f544d52f11b675015efde26e 100644
--- a/src/main/java/net/minecraft/core/Direction.java
+++ b/src/main/java/net/minecraft/core/Direction.java
diff --git a/net/minecraft/core/Direction.java b/net/minecraft/core/Direction.java
index 216f97207dac88cc1dc3df59c6ee8a62c7614b4a..05c7de5729466786a0196fa5f91eccc3cfffc675 100644
--- a/net/minecraft/core/Direction.java
+++ b/net/minecraft/core/Direction.java
@@ -217,7 +217,7 @@ public enum Direction implements StringRepresentable, ca.spottedleaf.moonrise.pa
}
@@ -28,10 +26,10 @@ index 928f38fd6beb00753c92ae9f4678f7507519a39b..4c53995d6d173ff6f544d52f11b67501
}
public static Direction getApproximateNearest(double x, double y, double z) {
diff --git a/src/main/java/net/minecraft/world/phys/AABB.java b/src/main/java/net/minecraft/world/phys/AABB.java
index e74866e5195a5eeae7666ad7be750edac5947094..25d7e7116282ec4b2cf85fe0b8e920af77fe4206 100644
--- a/src/main/java/net/minecraft/world/phys/AABB.java
+++ b/src/main/java/net/minecraft/world/phys/AABB.java
diff --git a/net/minecraft/world/phys/AABB.java b/net/minecraft/world/phys/AABB.java
index c9c6e4e460ad8435f12761704bb9b0284d6aa708..9581e7d51edaa6c51538a5267f421b034f4bfff0 100644
--- a/net/minecraft/world/phys/AABB.java
+++ b/net/minecraft/world/phys/AABB.java
@@ -18,6 +18,15 @@ public class AABB {
public final double maxY;
public final double maxZ;
@@ -43,12 +41,12 @@ index e74866e5195a5eeae7666ad7be750edac5947094..25d7e7116282ec4b2cf85fe0b8e920af
+ assert Direction.Axis.Z.ordinal() == 2;
+ assert Direction.Axis.values().length == 3;
+ }
+ // DivineMC end
+ // DivineMC end - lithium: fast_util
+
public AABB(double x1, double y1, double z1, double x2, double y2, double z2) {
this.minX = Math.min(x1, x2);
this.minY = Math.min(y1, y2);
@@ -86,11 +95,33 @@ public class AABB {
@@ -79,11 +88,33 @@ public class AABB {
}
public double min(Direction.Axis axis) {
@@ -64,7 +62,7 @@ index e74866e5195a5eeae7666ad7be750edac5947094..25d7e7116282ec4b2cf85fe0b8e920af
+ }
+
+ throw new IllegalArgumentException();
+ // DivineMC end
+ // DivineMC end - lithium: fast_util
}
public double max(Direction.Axis axis) {
@@ -80,7 +78,7 @@ index e74866e5195a5eeae7666ad7be750edac5947094..25d7e7116282ec4b2cf85fe0b8e920af
+ }
+
+ throw new IllegalArgumentException();
+ // DivineMC end
+ // DivineMC end - lithium: fast_util
}
@Override

View File

@@ -1,26 +1,26 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Thu, 11 Jul 2024 19:28:20 +0300
Date: Sun, 12 Jan 2025 20:57:25 +0300
Subject: [PATCH] Petal: Reduce work done by game event system
Original code by Bloom-host, licensed under GPL v3
You can find the original code on https://github.com/Bloom-host/Petal
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
index 4729befa12732a9fd65cce243b33b3b479026c41..4f63d2d9e37be27724eddea2c61f681ceb318a97 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
@@ -68,7 +68,7 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi
diff --git a/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java b/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
index 1638eccef431fb68775af624110f1968f0c6dabd..2799db1223c9f279322869bdd19605e6d835af2e 100644
--- a/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
@@ -65,7 +65,7 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi
return this.catalystListener;
}
- public static class CatalystListener implements GameEventListener {
+ public class CatalystListener implements GameEventListener { // DivineMC - static -> non-static
public static final int PULSE_TICKS = 8;
final SculkSpreader sculkSpreader;
@@ -139,6 +139,13 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi
world.playSound((Player) null, pos, SoundEvents.SCULK_CATALYST_BLOOM, SoundSource.BLOCKS, 2.0F, 0.6F + random.nextFloat() * 0.4F);
private final BlockState blockState;
@@ -127,6 +127,13 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi
level.playSound(null, pos, SoundEvents.SCULK_CATALYST_BLOOM, SoundSource.BLOCKS, 2.0F, 0.6F + random.nextFloat() * 0.4F);
}
+ // DivineMC start - Petal: Reduce work done by game event system
@@ -28,16 +28,16 @@ index 4729befa12732a9fd65cce243b33b3b479026c41..4f63d2d9e37be27724eddea2c61f681c
+ public boolean listensToEvent(GameEvent gameEvent, GameEvent.Context context) {
+ return !SculkCatalystBlockEntity.this.isRemoved() && gameEvent == GameEvent.ENTITY_DIE.value() && context.sourceEntity() instanceof LivingEntity;
+ }
+ // DivineMC end
+ // DivineMC end - Petal: Reduce work done by game event system
+
private void tryAwardItSpreadsAdvancement(Level world, LivingEntity deadEntity) {
LivingEntity entityliving1 = deadEntity.getLastHurtByMob();
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
index 00ea1c2037c7c7780764bfcc3e07b6554e910db2..32d64bdb475fdaa5aba0e9082c6ee6655f38fa1e 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -84,7 +84,18 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
private void tryAwardItSpreadsAdvancement(Level level, LivingEntity entity) {
if (entity.getLastHurtByMob() instanceof ServerPlayer serverPlayer) {
DamageSource damageSource = entity.getLastDamageSource() == null
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index 761fdcd4a4e18f45547afd8edff44f61c6eeacb4..03264d2b170002c640cec34530909ebb34c7e54e 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -81,7 +81,18 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
private Supplier<FullChunkStatus> fullStatus;
@Nullable
private LevelChunk.PostLoadProcessor postLoad;
@@ -53,28 +53,32 @@ index 00ea1c2037c7c7780764bfcc3e07b6554e910db2..32d64bdb475fdaa5aba0e9082c6ee665
+ private static int getGameEventSectionLength(int sectionCount) {
+ return sectionCount + (GAME_EVENT_DISPATCHER_RADIUS * 2);
+ }
+ // DivineMC end
+ // DivineMC end - Petal: Reduce work done by game event system
private final LevelChunkTicks<Block> blockTicks;
private final LevelChunkTicks<Fluid> fluidTicks;
private LevelChunk.UnsavedListener unsavedListener;
@@ -111,7 +122,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
this.unsavedListener = (chunkcoordintpair1) -> {
};
this.level = (ServerLevel) world; // CraftBukkit - type
- this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap();
private LevelChunk.UnsavedListener unsavedListener = chunkPos -> {};
@@ -144,7 +155,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
) {
super(pos, data, level, net.minecraft.server.MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BIOME), inhabitedTime, sections, blendingData); // Paper - Anti-Xray - The world isn't ready yet, use server singleton for registry
this.level = (ServerLevel) level; // CraftBukkit - type
- this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap<>();
+ this.gameEventListenerRegistrySections = new GameEventListenerRegistry[getGameEventSectionLength(this.getSectionsCount())]; // DivineMC - Petal: Reduce work done by game event system
Heightmap.Types[] aheightmap_type = Heightmap.Types.values();
int j = aheightmap_type.length;
@@ -273,9 +284,23 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
Level world = this.level;
for (Heightmap.Types types : Heightmap.Types.values()) {
if (ChunkStatus.FULL.heightmapsAfter().contains(types)) {
@@ -254,10 +265,29 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
if (world instanceof ServerLevel worldserver) {
- return (GameEventListenerRegistry) this.gameEventListenerRegistrySections.computeIfAbsent(ySectionCoord, (j) -> {
- return new EuclideanGameEventListenerRegistry(worldserver, ySectionCoord, this::removeGameEventListenerRegistry);
- });
@Override
public GameEventListenerRegistry getListenerRegistry(int sectionY) {
- return this.level instanceof ServerLevel serverLevel
- ? this.gameEventListenerRegistrySections
- .computeIfAbsent(sectionY, i -> new EuclideanGameEventListenerRegistry(serverLevel, sectionY, this::removeGameEventListenerRegistry))
- : super.getListenerRegistry(sectionY);
+ Level world = this.level;
+
+ if (world instanceof ServerLevel worldserver) {
+ // DivineMC start - Petal: Reduce work done by game event system
+ int sectionIndex = getGameEventSectionIndex(this.getSectionIndexFromSectionY(ySectionCoord));
+ int sectionIndex = getGameEventSectionIndex(this.getSectionIndexFromSectionY(sectionY));
+
+ // drop game events that are too far away (32 blocks) from loaded sections
+ // this matches the highest radius of game events in the game
@@ -85,35 +89,38 @@ index 00ea1c2037c7c7780764bfcc3e07b6554e910db2..32d64bdb475fdaa5aba0e9082c6ee665
+ var dispatcher = this.gameEventListenerRegistrySections[sectionIndex];
+
+ if (dispatcher == null) {
+ dispatcher = this.gameEventListenerRegistrySections[sectionIndex] = new EuclideanGameEventListenerRegistry(worldserver, ySectionCoord, this::removeGameEventListenerRegistry);
+ dispatcher = this.gameEventListenerRegistrySections[sectionIndex] = new EuclideanGameEventListenerRegistry(worldserver, sectionY, this::removeGameEventListenerRegistry);
+ }
+
+ return dispatcher;
+ // DivineMC end
} else {
return super.getListenerRegistry(ySectionCoord);
}
@@ -671,7 +696,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
+ // DivineMC end - Petal: Reduce work done by game event system
+ } else {
+ return super.getListenerRegistry(sectionY);
+ }
}
private void removeGameEventListenerRegistry(int ySectionCoord) {
- this.gameEventListenerRegistrySections.remove(ySectionCoord);
+ this.gameEventListenerRegistrySections[getGameEventSectionIndex(this.getSectionIndexFromSectionY(ySectionCoord))] = null; // DivineMC - Petal: Reduce work done by game event system
// Paper start - Perf: Reduce instructions and provide final method
@@ -601,7 +631,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
}
private void removeGameEventListenerRegistry(int sectionY) {
- this.gameEventListenerRegistrySections.remove(sectionY);
+ this.gameEventListenerRegistrySections[getGameEventSectionIndex(this.getSectionIndexFromSectionY(sectionY))] = null; // DivineMC - Petal: Reduce work done by game event system
}
private void removeBlockEntityTicker(BlockPos pos) {
diff --git a/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java b/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java
index 1e93f3a1b11196a431a1f5a0957036fe0c9191a4..a28b48676b459e8cfa0c3ef2d4ad6de55fc91d66 100644
--- a/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java
+++ b/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java
diff --git a/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java b/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java
index 5175fc90a1fc61c832c6697997a97ae199b195ac..f40511b5be6cf72298d30188fd550d1d768d875a 100644
--- a/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java
+++ b/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java
@@ -14,8 +14,8 @@ import net.minecraft.world.phys.Vec3;
public class EuclideanGameEventListenerRegistry implements GameEventListenerRegistry {
private final List<GameEventListener> listeners = Lists.newArrayList();
- private final Set<GameEventListener> listenersToRemove = Sets.newHashSet();
- private final List<GameEventListener> listenersToAdd = Lists.newArrayList();
+ //private final Set<GameEventListener> listenersToRemove = Sets.newHashSet(); // DivineMC - unused
+ //private final List<GameEventListener> listenersToAdd = Lists.newArrayList(); // DivineMC - unused
+ //private final Set<GameEventListener> listenersToRemove = Sets.newHashSet(); // DivineMC - Commented out
+ //private final List<GameEventListener> listenersToAdd = Lists.newArrayList(); // DivineMC - Commented out
private boolean processing;
private final ServerLevel level;
private final int sectionY;
@@ -143,7 +150,7 @@ index 1e93f3a1b11196a431a1f5a0957036fe0c9191a4..a28b48676b459e8cfa0c3ef2d4ad6de5
+ if (false) { // DivineMC - Disallow concurrent modification
iterator.remove();
} else {
Optional<Vec3> optional = getPostableListenerPosition(this.level, pos, gameEventListener);
Optional<Vec3> postableListenerPosition = getPostableListenerPosition(this.level, pos, gameEventListener);
@@ -80,6 +80,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi
this.processing = false;
}
@@ -156,26 +163,26 @@ index 1e93f3a1b11196a431a1f5a0957036fe0c9191a4..a28b48676b459e8cfa0c3ef2d4ad6de5
this.listeners.removeAll(this.listenersToRemove);
this.listenersToRemove.clear();
}
+ */ // DivineMC end
+ */ // DivineMC end - Petal: Reduce work done by game event system
return bl;
return flag;
}
diff --git a/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java b/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java
index df6c97be1b278c97a20390be5d3e60f429383702..a99253227677f6d68cbb2d79ea847d36e5879175 100644
--- a/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java
+++ b/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java
@@ -45,6 +45,7 @@ public class GameEventDispatcher {
int k1 = SectionPos.blockToSectionCoord(blockposition.getZ() + i);
List<GameEvent.ListenerInfo> list = new ArrayList();
GameEventListenerRegistry.ListenerVisitor gameeventlistenerregistry_a = (gameeventlistener, vec3d1) -> {
+ if (!gameeventlistener.listensToEvent(event.value(), emitter)) return; // DivineMC - If they don't listen, ignore
if (gameeventlistener.getDeliveryMode() == GameEventListener.DeliveryMode.BY_DISTANCE) {
list.add(new GameEvent.ListenerInfo(event, emitterPos, emitter, gameeventlistener, vec3d1));
diff --git a/net/minecraft/world/level/gameevent/GameEventDispatcher.java b/net/minecraft/world/level/gameevent/GameEventDispatcher.java
index 1e9b066ef468ae840eda3c1f6c4b68111a5e862c..cf31dadc73c66e4d4fcca9d81d587480d1c530c5 100644
--- a/net/minecraft/world/level/gameevent/GameEventDispatcher.java
+++ b/net/minecraft/world/level/gameevent/GameEventDispatcher.java
@@ -44,6 +44,7 @@ public class GameEventDispatcher {
int sectionPosCoord5 = SectionPos.blockToSectionCoord(blockPos.getZ() + notificationRadius);
List<GameEvent.ListenerInfo> list = new ArrayList<>();
GameEventListenerRegistry.ListenerVisitor listenerVisitor = (listener, pos1) -> {
+ if (!listener.listensToEvent(gameEvent.value(), context)) return; // DivineMC - If they don't listen, ignore
if (listener.getDeliveryMode() == GameEventListener.DeliveryMode.BY_DISTANCE) {
list.add(new GameEvent.ListenerInfo(gameEvent, pos, context, listener, pos1));
} else {
diff --git a/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java b/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java
index 0f3a79cc644a5b89fa35fdd413ff5781987c4ef3..57e6902990e163ff80b83df30d64e5959ac9d585 100644
--- a/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java
+++ b/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java
diff --git a/net/minecraft/world/level/gameevent/GameEventListener.java b/net/minecraft/world/level/gameevent/GameEventListener.java
index 5a31b5f1e75dd7b412ab577ea6621b7e87fc0590..32a79d5a247ddf953d18594897c5e9565353593a 100644
--- a/net/minecraft/world/level/gameevent/GameEventListener.java
+++ b/net/minecraft/world/level/gameevent/GameEventListener.java
@@ -23,4 +23,10 @@ public interface GameEventListener {
public interface Provider<T extends GameEventListener> {
T getListener();
@@ -185,5 +192,5 @@ index 0f3a79cc644a5b89fa35fdd413ff5781987c4ef3..57e6902990e163ff80b83df30d64e595
+ default boolean listensToEvent(GameEvent gameEvent, GameEvent.Context context) {
+ return true;
+ }
+ // DivineMC end
+ // DivineMC end - Add check for seeing if this listener cares about an event
}

View File

@@ -0,0 +1,65 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sun, 12 Jan 2025 21:03:27 +0300
Subject: [PATCH] Fix MC-65198
Original post on Mojira: https://bugs.mojang.com/browse/MC-65198
diff --git a/net/minecraft/world/inventory/ItemCombinerMenu.java b/net/minecraft/world/inventory/ItemCombinerMenu.java
index c605bd700fd9f5a6596a2bf9648492786306b025..ae594513799defffa3d3c29ef753fa01337e0df2 100644
--- a/net/minecraft/world/inventory/ItemCombinerMenu.java
+++ b/net/minecraft/world/inventory/ItemCombinerMenu.java
@@ -120,6 +120,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
if (slot != null && slot.hasItem()) {
ItemStack item = slot.getItem();
itemStack = item.copy();
+ ItemStack itemStack2 = itemStack.copy(); // DivineMC - Fix MC-65198
int inventorySlotStart = this.getInventorySlotStart();
int useRowEnd = this.getUseRowEnd();
if (index == this.getResultSlot()) {
@@ -157,7 +158,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
}
this.activeQuickItem = itemStack; // Purpur - Anvil API
- slot.onTake(player, item);
+ slot.onTake(player, itemStack2); // DivineMC - Fix MC-65198
this.activeQuickItem = null; // Purpur - Anvil API
}
diff --git a/net/minecraft/world/inventory/ResultSlot.java b/net/minecraft/world/inventory/ResultSlot.java
index 01b8d73b1be9b41d6f51d11a0bead37a7bd9023f..d3865b375293e29162f08aa447bd91f90ef27513 100644
--- a/net/minecraft/world/inventory/ResultSlot.java
+++ b/net/minecraft/world/inventory/ResultSlot.java
@@ -49,7 +49,7 @@ public class ResultSlot extends Slot {
@Override
protected void checkTakeAchievements(ItemStack stack) {
if (this.removeCount > 0) {
- stack.onCraftedBy(this.player.level(), this.player, this.removeCount);
+ stack.onCraftedBy(this.player.level(), this.player, stack.getCount()); // DivineMC - Fix MC-65198
}
if (this.container instanceof RecipeCraftingHolder recipeCraftingHolder) {
diff --git a/net/minecraft/world/inventory/StonecutterMenu.java b/net/minecraft/world/inventory/StonecutterMenu.java
index d6854d0ebe5cb4205963e879d71eb3940d54de1f..dbc4ca21120daf3a63750274db8cff671d12fcd2 100644
--- a/net/minecraft/world/inventory/StonecutterMenu.java
+++ b/net/minecraft/world/inventory/StonecutterMenu.java
@@ -238,6 +238,7 @@ public class StonecutterMenu extends AbstractContainerMenu {
ItemStack item = slot.getItem();
Item item1 = item.getItem();
itemStack = item.copy();
+ ItemStack itemStack2 = itemStack.copy(); // DivineMC - Fix MC-65198
if (index == 1) {
item1.onCraftedBy(item, player.level(), player);
if (!this.moveItemStackTo(item, 2, 38, true)) {
@@ -270,9 +271,9 @@ public class StonecutterMenu extends AbstractContainerMenu {
return ItemStack.EMPTY;
}
- slot.onTake(player, item);
+ slot.onTake(player, itemStack2); // DivineMC - Fix MC-65198
if (index == 1) {
- player.drop(item, false);
+ player.drop(itemStack2, false); // DivineMC - Fix MC-65198
}
this.broadcastChanges();

View File

@@ -0,0 +1,75 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sun, 12 Jan 2025 21:07:52 +0300
Subject: [PATCH] C2ME: Optimize world gen math
diff --git a/net/minecraft/world/level/ChunkPos.java b/net/minecraft/world/level/ChunkPos.java
index 55ce935a2fab7e32904d9ff599867269035d703f..4fa84743ba7f570f11a4979b7e5381478c844aef 100644
--- a/net/minecraft/world/level/ChunkPos.java
+++ b/net/minecraft/world/level/ChunkPos.java
@@ -110,7 +110,12 @@ public class ChunkPos {
@Override
public boolean equals(Object other) {
- return this == other || other instanceof ChunkPos chunkPos && this.x == chunkPos.x && this.z == chunkPos.z;
+ // DivineMC start - Use standard equals
+ if (other == this) return true;
+ if (other == null || other.getClass() != this.getClass()) return false;
+ ChunkPos thatPos = (ChunkPos) other;
+ return this.x == thatPos.x && this.z == thatPos.z;
+ // DivineMC end - Use standard equals
}
public int getMiddleBlockX() {
diff --git a/net/minecraft/world/level/levelgen/Beardifier.java b/net/minecraft/world/level/levelgen/Beardifier.java
index 131923282c9ecbcb1d7f45a826da907c02bd2716..e7c0de38ef689510860dc0b626f744617a694956 100644
--- a/net/minecraft/world/level/levelgen/Beardifier.java
+++ b/net/minecraft/world/level/levelgen/Beardifier.java
@@ -132,8 +132,14 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker {
}
private static double getBuryContribution(double x, double y, double z) {
- double len = Mth.length(x, y, z);
- return Mth.clampedMap(len, 0.0, 6.0, 1.0, 0.0);
+ // DivineMC start - Optimize method for beardifier
+ double d = Math.sqrt(x * x + y * y + z * z);
+ if (d > 6.0) {
+ return 0.0;
+ } else {
+ return 1.0 - d / 6.0;
+ }
+ // DivineMC end - Optimize method for beardifier
}
private static double getBeardContribution(int x, int y, int z, int height) {
diff --git a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
index 65728ef17e63d71833677fdcbd5bb90794b4822b..832a26760a777fe2d62f2f5f7a885bae63f67517 100644
--- a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
+++ b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
@@ -68,8 +68,10 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
Aquifer.FluidStatus fluidStatus = new Aquifer.FluidStatus(-54, Blocks.LAVA.defaultBlockState());
int seaLevel = settings.seaLevel();
Aquifer.FluidStatus fluidStatus1 = new Aquifer.FluidStatus(seaLevel, settings.defaultFluid());
- Aquifer.FluidStatus fluidStatus2 = new Aquifer.FluidStatus(DimensionType.MIN_Y * 2, Blocks.AIR.defaultBlockState());
- return (x, y, z) -> y < Math.min(-54, seaLevel) ? fluidStatus : fluidStatus1;
+ // DivineMC start - Optimize world gen
+ final int min = Math.min(-54, seaLevel);
+ return (j, k, l) -> k < min ? fluidStatus : fluidStatus1;
+ // DivineMC end - Optimize world gen
}
@Override
diff --git a/net/minecraft/world/level/levelgen/synth/PerlinNoise.java b/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
index da3c26fbad32d75d71f7e59c8c3341316a754756..6e1ebd6110da183a8f97abd81ced16cd89df725f 100644
--- a/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
+++ b/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
@@ -187,7 +187,7 @@ public class PerlinNoise {
}
public static double wrap(double value) {
- return value - Mth.lfloor(value / 3.3554432E7 + 0.5) * 3.3554432E7;
+ return value - Math.floor(value / 3.3554432E7 + 0.5) * 3.3554432E7; // DivineMC - Avoid casting
}
protected int firstOctave() {

View File

@@ -1,6 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sun, 15 Dec 2024 23:32:36 +0300
Date: Sun, 12 Jan 2025 21:10:42 +0300
Subject: [PATCH] Carpet-Fixes: RecipeManager Optimize
Original project: https://github.com/fxmorin/carpet-fixes
@@ -8,26 +8,26 @@ Optimized the RecipeManager getFirstMatch call to be up to 3x faster
This is a fully vanilla optimization. Improves: [Blast]Furnace/Campfire/Smoker/Stonecutter/Crafting/Sheep Color Choosing
This was mostly made for the auto crafting table, since the performance boost is much more visible while using that mod
diff --git a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java
index 2483627f807d7a3907f6848a8bc45d7a798e746d..01b63bf331a39b5fb23734f72a4f9880a98094b2 100644
--- a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java
+++ b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java
@@ -197,7 +197,7 @@ public class RecipeManager extends SimplePreparableReloadListener<RecipeMap> imp
diff --git a/net/minecraft/world/item/crafting/RecipeManager.java b/net/minecraft/world/item/crafting/RecipeManager.java
index aefaac550b58be479cc282f52dea91d4b1e530f6..2877a3229e03285e9ba5ec2bb68e17c9da202816 100644
--- a/net/minecraft/world/item/crafting/RecipeManager.java
+++ b/net/minecraft/world/item/crafting/RecipeManager.java
@@ -167,7 +167,7 @@ public class RecipeManager extends SimplePreparableReloadListener<RecipeMap> imp
public <I extends RecipeInput, T extends Recipe<I>> Optional<RecipeHolder<T>> getRecipeFor(RecipeType<T> type, I input, Level world) {
public <I extends RecipeInput, T extends Recipe<I>> Optional<RecipeHolder<T>> getRecipeFor(RecipeType<T> recipeType, I input, Level level) {
// CraftBukkit start
- List<RecipeHolder<T>> list = this.recipes.getRecipesFor(type, input, world).toList();
+ List<RecipeHolder<T>> list = this.recipes.getRecipesForList(type, input, world); // DivineMC - Carpet-Fixes - Remove streams to be faster
- List<RecipeHolder<T>> list = this.recipes.getRecipesFor(recipeType, input, level).toList();
+ List<RecipeHolder<T>> list = this.recipes.getRecipesForList(recipeType, input, level); // DivineMC - Carpet-Fixes - Remove streams to be faster
return (list.isEmpty()) ? Optional.empty() : Optional.of(list.getLast()); // CraftBukkit - SPIGOT-4638: last recipe gets priority
// CraftBukkit end
}
diff --git a/src/main/java/net/minecraft/world/item/crafting/RecipeMap.java b/src/main/java/net/minecraft/world/item/crafting/RecipeMap.java
index c4067fbf827fed882772962a0e4b3ead0d642e62..2d289139f80855f07121861b1f840058f0bc9ec1 100644
--- a/src/main/java/net/minecraft/world/item/crafting/RecipeMap.java
+++ b/src/main/java/net/minecraft/world/item/crafting/RecipeMap.java
@@ -105,4 +105,24 @@ public class RecipeMap {
return recipeholder.value().matches(input, world);
});
diff --git a/net/minecraft/world/item/crafting/RecipeMap.java b/net/minecraft/world/item/crafting/RecipeMap.java
index 098753ddd215b6ef5915fac71d8c4f0b19cf4142..1778e58dca9430756d59d07bf017ebe4cc1f4ed4 100644
--- a/net/minecraft/world/item/crafting/RecipeMap.java
+++ b/net/minecraft/world/item/crafting/RecipeMap.java
@@ -75,4 +75,24 @@ public class RecipeMap {
public <I extends RecipeInput, T extends Recipe<I>> Stream<RecipeHolder<T>> getRecipesFor(RecipeType<T> type, I input, Level level) {
return input.isEmpty() ? Stream.empty() : this.byType(type).stream().filter(recipeHolder -> recipeHolder.value().matches(input, level));
}
+
+ // DivineMC start - Carpet-Fixes - Remove streams to be faster

View File

@@ -0,0 +1,149 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Mon, 13 Jan 2025 19:35:57 +0300
Subject: [PATCH] No chat sign
diff --git a/net/minecraft/commands/arguments/ArgumentSignatures.java b/net/minecraft/commands/arguments/ArgumentSignatures.java
index 47cb25aa9c37bd84d156288c397321009f1d9ae2..259fd0401a4a0547cf83ba1793f2b3d2898a58fe 100644
--- a/net/minecraft/commands/arguments/ArgumentSignatures.java
+++ b/net/minecraft/commands/arguments/ArgumentSignatures.java
@@ -14,9 +14,16 @@ public record ArgumentSignatures(List<ArgumentSignatures.Entry> entries) {
private static final int MAX_ARGUMENT_NAME_LENGTH = 16;
public ArgumentSignatures(FriendlyByteBuf buffer) {
- this(buffer.readCollection(FriendlyByteBuf.<List<ArgumentSignatures.Entry>>limitValue(ArrayList::new, 8), ArgumentSignatures.Entry::new));
+ this(readSign(buffer)); // DivineMC - No chat sign
}
+ // DivineMC start - No chat sign
+ private static List<ArgumentSignatures.Entry> readSign(FriendlyByteBuf buf) {
+ var entries = buf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 8), Entry::new);
+ return space.bxteam.divinemc.configuration.DivineConfig.noChatSign ? List.of() : entries;
+ }
+ // DivineMC end - No chat sign
+
public void write(FriendlyByteBuf buffer) {
buffer.writeCollection(this.entries, (buffer1, entry) -> entry.write(buffer1));
}
diff --git a/net/minecraft/network/FriendlyByteBuf.java b/net/minecraft/network/FriendlyByteBuf.java
index e5e5d9bc095ccd9fbf1c8aaa09e5c4ebb1d1c920..d8c98e596f938f103f8155269a2096a6d1b7ffbb 100644
--- a/net/minecraft/network/FriendlyByteBuf.java
+++ b/net/minecraft/network/FriendlyByteBuf.java
@@ -114,6 +114,17 @@ public class FriendlyByteBuf extends ByteBuf {
public <T> void writeJsonWithCodec(Codec<T> codec, T value, int maxLength) {
// Paper end - Adventure; add max length parameter
DataResult<JsonElement> dataResult = codec.encodeStart(JsonOps.INSTANCE, value);
+
+ // DivineMC start - No chat sign
+ if (codec == net.minecraft.network.protocol.status.ServerStatus.CODEC) {
+ JsonElement element = dataResult.getOrThrow(string -> new EncoderException("Failed to encode: " + string + " " + value));
+ element.getAsJsonObject().addProperty("preventsChatReports", space.bxteam.divinemc.configuration.DivineConfig.noChatSign);
+
+ this.writeUtf(GSON.toJson(element));
+ return;
+ }
+ // DivineMC end - No chat sign
+
this.writeUtf(GSON.toJson(dataResult.getOrThrow(exception -> new EncoderException("Failed to encode: " + exception + " " + value))), maxLength); // Paper - Adventure; add max length parameter
}
diff --git a/net/minecraft/network/protocol/game/ServerboundChatPacket.java b/net/minecraft/network/protocol/game/ServerboundChatPacket.java
index b5afc05924ae899e020c303c8b86398e1d4ab8a0..468ec7f1a9ee73c7748ca36850bf810a1811e372 100644
--- a/net/minecraft/network/protocol/game/ServerboundChatPacket.java
+++ b/net/minecraft/network/protocol/game/ServerboundChatPacket.java
@@ -16,7 +16,7 @@ public record ServerboundChatPacket(String message, Instant timeStamp, long salt
);
private ServerboundChatPacket(FriendlyByteBuf buffer) {
- this(buffer.readUtf(256), buffer.readInstant(), buffer.readLong(), buffer.readNullable(MessageSignature::read), new LastSeenMessages.Update(buffer));
+ this(buffer.readUtf(256), buffer.readInstant(), buffer.readLong(), buffer.readNullable(ServerboundChatPacket::readSign), new LastSeenMessages.Update(buffer)); // DivineMC - No chat sign
}
private void write(FriendlyByteBuf buffer) {
@@ -27,6 +27,14 @@ public record ServerboundChatPacket(String message, Instant timeStamp, long salt
this.lastSeenMessages.write(buffer);
}
+ // DivineMC start - No chat sign
+ private static MessageSignature readSign(FriendlyByteBuf buf) {
+ byte[] bs = new byte[256];
+ buf.readBytes(bs);
+ return space.bxteam.divinemc.configuration.DivineConfig.noChatSign ? null : new MessageSignature(bs);
+ }
+ // DivineMC end - No chat sign
+
@Override
public PacketType<ServerboundChatPacket> type() {
return GamePacketTypes.SERVERBOUND_CHAT;
diff --git a/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java b/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java
index 1df628ac0b414511aaed6e09d78f884c4170f730..2d674c7ef305469c0483f24720e673e04a8fd963 100644
--- a/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java
+++ b/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java
@@ -26,6 +26,11 @@ public record ServerboundChatSessionUpdatePacket(RemoteChatSession.Data chatSess
@Override
public void handle(ServerGamePacketListener handler) {
+ // DivineMC start - No chat sign
+ if (space.bxteam.divinemc.configuration.DivineConfig.noChatSign) {
+ return;
+ }
+ // DivineMC end - No chat sign
handler.handleChatSessionUpdate(this);
}
}
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index c85023893fbb227894f8f888244f1f53e25dff3f..0755bd59ab467da4a42cf5dae0f2e409d3132fea 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -668,7 +668,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
// Paper start - Add setting for proxy online mode status
return properties.enforceSecureProfile
&& io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode()
- && this.services.canValidateProfileKeys();
+ && this.services.canValidateProfileKeys() && !space.bxteam.divinemc.configuration.DivineConfig.noChatSign; // DivineMC - No chat sign
// Paper end - Add setting for proxy online mode status
}
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
index 398c1733824b689520170de0be94006731afa5cd..289d8d2420f6298a4fc10e0563e99cc13c18880a 100644
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
@@ -312,10 +312,24 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
}
public void send(Packet<?> packet) {
+ // DivineMC start - No chat sign
+ if (space.bxteam.divinemc.configuration.DivineConfig.noChatSign) {
+ if (this instanceof ServerGamePacketListenerImpl && packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat) {
+ packet = new net.minecraft.network.protocol.game.ClientboundSystemChatPacket(chat.chatType().decorate(chat.unsignedContent() != null ? chat.unsignedContent() : Component.literal(chat.body().content())), false);
+ }
+ }
+ // DivineMC end - No chat sign
this.send(packet, null);
}
public void send(Packet<?> packet, @Nullable PacketSendListener listener) {
+ // DivineMC start - No chat sign
+ if (space.bxteam.divinemc.configuration.DivineConfig.noChatSign) {
+ if (packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat && listener != null) {
+ listener = null;
+ }
+ }
+ // DivineMC end - No chat sign
// CraftBukkit start
if (packet == null || this.processedDisconnect) { // Spigot
return;
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 94abb9d8f6381aee000dbd0720477db8b7ca279c..cb43a189e286afd858738e2590f8e812c510c3d3 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -1319,7 +1319,7 @@ public abstract class PlayerList {
}
public boolean verifyChatTrusted(PlayerChatMessage message) { // Paper - private -> public
- return message.hasSignature() && !message.hasExpiredServer(Instant.now());
+ return space.bxteam.divinemc.configuration.DivineConfig.noChatSign || (message.hasSignature() && !message.hasExpiredServer(Instant.now())); // DivineMC - No chat sign
}
// CraftBukkit start

View File

@@ -0,0 +1,810 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Wed, 15 Jan 2025 18:12:55 +0300
Subject: [PATCH] Petal: Async Pathfinding
Original code by Bloom-host, licensed under GPL v3
You can find the original code on https://github.com/Bloom-host/Petal
Makes most pathfinding-related work happen asynchronously
diff --git a/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
index 67cbf9f5760fae5db6f31e64095cd1b6be6ade8e..3f4e42c6ee1a1aa14250de4f71ae61f324d335e9 100644
--- a/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
+++ b/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
@@ -94,21 +94,54 @@ public class AcquirePoi {
}
}
// Paper end - optimise POI access
- Path path = findPathToPois(mob, set);
- if (path != null && path.canReach()) {
- BlockPos target = path.getTarget();
- poiManager.getType(target).ifPresent(holder -> {
- poiManager.take(acquirablePois, (holder1, blockPos) -> blockPos.equals(target), target, 1);
- memoryAccessor.set(GlobalPos.of(level.dimension(), target));
- entityEventId.ifPresent(id -> level.broadcastEntityEvent(mob, id));
- map.clear();
- DebugPackets.sendPoiTicketCountPacket(level, target);
+ // DivineMC start - Async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ // await on path async
+ Path possiblePath = findPathToPois(mob, set);
+
+ // wait on the path to be processed
+ space.bxteam.divinemc.pathfinding.AsyncPathProcessor.awaitProcessing(possiblePath, path -> {
+ // read canReach check
+ if (path == null || !path.canReach()) {
+ for (Pair<Holder<PoiType>, BlockPos> pair : set) {
+ map.computeIfAbsent(
+ pair.getSecond().asLong(),
+ m -> new JitteredLinearRetry(mob.level().random, time)
+ );
+ }
+ return;
+ }
+ BlockPos blockPos = path.getTarget();
+ poiManager.getType(blockPos).ifPresent(poiType -> {
+ poiManager.take(acquirablePois,
+ (holder, blockPos2) -> blockPos2.equals(blockPos),
+ blockPos,
+ 1
+ );
+ memoryAccessor.set(GlobalPos.of(level.dimension(), blockPos));
+ entityEventId.ifPresent(status -> level.broadcastEntityEvent(mob, status));
+ map.clear();
+ DebugPackets.sendPoiTicketCountPacket(level, blockPos);
+ });
});
} else {
- for (Pair<Holder<PoiType>, BlockPos> pair : set) {
- map.computeIfAbsent(pair.getSecond().asLong(), l -> new AcquirePoi.JitteredLinearRetry(level.random, time));
+ Path path = findPathToPois(mob, set);
+ if (path != null && path.canReach()) {
+ BlockPos target = path.getTarget();
+ poiManager.getType(target).ifPresent(holder -> {
+ poiManager.take(acquirablePois, (holder1, blockPos) -> blockPos.equals(target), target, 1);
+ memoryAccessor.set(GlobalPos.of(level.dimension(), target));
+ entityEventId.ifPresent(id -> level.broadcastEntityEvent(mob, id));
+ map.clear();
+ DebugPackets.sendPoiTicketCountPacket(level, target);
+ });
+ } else {
+ for (Pair<Holder<PoiType>, BlockPos> pair : set) {
+ map.computeIfAbsent(pair.getSecond().asLong(), l -> new AcquirePoi.JitteredLinearRetry(level.random, time));
+ }
}
}
+ // DivineMC end - Async path processing
return true;
}
diff --git a/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java b/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
index 621ba76784f2b92790eca62be4d0688834335ab6..11a124ad7df99b3ddfc92496a8950dc6e46cdf07 100644
--- a/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
+++ b/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
@@ -21,6 +21,7 @@ public class MoveToTargetSink extends Behavior<Mob> {
private int remainingCooldown;
@Nullable
private Path path;
+ private boolean finishedProcessing; // DivineMC - async path processing
@Nullable
private BlockPos lastTargetPos;
private float speedModifier;
@@ -53,9 +54,11 @@ public class MoveToTargetSink extends Behavior<Mob> {
Brain<?> brain = owner.getBrain();
WalkTarget walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get();
boolean flag = this.reachedTarget(owner, walkTarget);
- if (!flag && this.tryComputePath(owner, walkTarget, level.getGameTime())) {
+ if (!space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding && !flag && this.tryComputePath(owner, walkTarget, level.getGameTime())) { // DivineMC - async path processing
this.lastTargetPos = walkTarget.getTarget().currentBlockPosition();
return true;
+ } else if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding && !flag) { // DivineMC - async pathfinding
+ return true;
} else {
brain.eraseMemory(MemoryModuleType.WALK_TARGET);
if (flag) {
@@ -69,6 +72,7 @@ public class MoveToTargetSink extends Behavior<Mob> {
@Override
protected boolean canStillUse(ServerLevel level, Mob entity, long gameTime) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding && !this.finishedProcessing) return true; // DivineMC - wait for processing
if (this.path != null && this.lastTargetPos != null) {
Optional<WalkTarget> memory = entity.getBrain().getMemory(MemoryModuleType.WALK_TARGET);
boolean flag = memory.map(MoveToTargetSink::isWalkTargetSpectator).orElse(false);
@@ -95,27 +99,98 @@ public class MoveToTargetSink extends Behavior<Mob> {
@Override
protected void start(ServerLevel level, Mob entity, long gameTime) {
+ // DivineMC start - start processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ Brain<?> brain = entity.getBrain();
+ WalkTarget walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get();
+
+ this.finishedProcessing = false;
+ this.lastTargetPos = walkTarget.getTarget().currentBlockPosition();
+ this.path = this.computePath(entity, walkTarget);
+ return;
+ }
+ // DivineMC end - start processing
entity.getBrain().setMemory(MemoryModuleType.PATH, this.path);
entity.getNavigation().moveTo(this.path, (double)this.speedModifier);
}
@Override
protected void tick(ServerLevel level, Mob owner, long gameTime) {
- Path path = owner.getNavigation().getPath();
- Brain<?> brain = owner.getBrain();
- if (this.path != path) {
- this.path = path;
- brain.setMemory(MemoryModuleType.PATH, path);
- }
+ // DivineMC start - Async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ if (this.path != null && !this.path.isProcessed()) return; // wait for processing
- if (path != null && this.lastTargetPos != null) {
- WalkTarget walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get();
- if (walkTarget.getTarget().currentBlockPosition().distSqr(this.lastTargetPos) > 4.0 && this.tryComputePath(owner, walkTarget, level.getGameTime())) {
- this.lastTargetPos = walkTarget.getTarget().currentBlockPosition();
- this.start(level, owner, gameTime);
+ if (!this.finishedProcessing) {
+ this.finishedProcessing = true;
+
+ Brain<?> brain = owner.getBrain();
+ boolean canReach = this.path != null && this.path.canReach();
+ if (canReach) {
+ brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE);
+ } else if (!brain.hasMemoryValue(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE)) {
+ brain.setMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, gameTime);
+ }
+
+ if (!canReach) {
+ Optional<WalkTarget> walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET);
+
+ if (!walkTarget.isPresent()) return;
+
+ BlockPos blockPos = walkTarget.get().getTarget().currentBlockPosition();
+ Vec3 vec3 = DefaultRandomPos.getPosTowards((PathfinderMob) owner, 10, 7, Vec3.atBottomCenterOf(blockPos), (float) Math.PI / 2F);
+ if (vec3 != null) {
+ // try recalculating the path using a random position
+ this.path = owner.getNavigation().createPath(vec3.x, vec3.y, vec3.z, 0);
+ this.finishedProcessing = false;
+ return;
+ }
+ }
+
+ owner.getBrain().setMemory(MemoryModuleType.PATH, this.path);
+ owner.getNavigation().moveTo(this.path, this.speedModifier);
}
+
+ Path path = owner.getNavigation().getPath();
+ Brain<?> brain = owner.getBrain();
+
+ if (path != null && this.lastTargetPos != null && brain.hasMemoryValue(MemoryModuleType.WALK_TARGET)) {
+ WalkTarget walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get(); // we know isPresent = true
+ if (walkTarget.getTarget().currentBlockPosition().distSqr(this.lastTargetPos) > 4.0D) {
+ this.start(level, owner, gameTime);
+ }
+ }
+ } else {
+ Path path = owner.getNavigation().getPath();
+ Brain<?> brain = owner.getBrain();
+ if (this.path != path) {
+ this.path = path;
+ brain.setMemory(MemoryModuleType.PATH, path);
+ }
+
+ if (path != null && this.lastTargetPos != null) {
+ WalkTarget walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get();
+ if (walkTarget.getTarget().currentBlockPosition().distSqr(this.lastTargetPos) > 4.0
+ && this.tryComputePath(owner, walkTarget, level.getGameTime())) {
+ this.lastTargetPos = walkTarget.getTarget().currentBlockPosition();
+ this.start(level, owner, gameTime);
+ }
+ }
+ }
+ // DivineMC end - Async path processing
+ }
+
+ // DivineMC start - Async path processing
+ @Nullable
+ private Path computePath(Mob entity, WalkTarget walkTarget) {
+ BlockPos blockPos = walkTarget.getTarget().currentBlockPosition();
+ this.speedModifier = walkTarget.getSpeedModifier();
+ Brain<?> brain = entity.getBrain();
+ if (this.reachedTarget(entity, walkTarget)) {
+ brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE);
}
+ return entity.getNavigation().createPath(blockPos, 0);
}
+ // DivineMC end - Async path processing
private boolean tryComputePath(Mob mob, WalkTarget target, long time) {
BlockPos blockPos = target.getTarget().currentBlockPosition();
diff --git a/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java b/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java
index 4f9f3367b1ca3903df03a80fa2b01a3d24e6e77d..8308934ec65d1f49ea356e19c940407bae7041f2 100644
--- a/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java
+++ b/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java
@@ -60,17 +60,38 @@ public class SetClosestHomeAsWalkTarget {
poi -> poi.is(PoiTypes.HOME), predicate, mob.blockPosition(), 48, PoiManager.Occupancy.ANY
)
.collect(Collectors.toSet());
- Path path = AcquirePoi.findPathToPois(mob, set);
- if (path != null && path.canReach()) {
- BlockPos target = path.getTarget();
- Optional<Holder<PoiType>> type = poiManager.getType(target);
- if (type.isPresent()) {
- walkTarget.set(new WalkTarget(target, speedModifier, 1));
- DebugPackets.sendPoiTicketCountPacket(level, target);
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ // await on path async
+ Path possiblePath = AcquirePoi.findPathToPois(mob, set);
+
+ // wait on the path to be processed
+ space.bxteam.divinemc.pathfinding.AsyncPathProcessor.awaitProcessing(possiblePath, path -> {
+ if (path == null || !path.canReach() || mutableInt.getValue() < 5) { // read canReach check
+ map.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < mutableLong.getValue());
+ return;
+ }
+ BlockPos blockPos = path.getTarget();
+ Optional<Holder<PoiType>> optional2 = poiManager.getType(blockPos);
+ if (optional2.isPresent()) {
+ walkTarget.set(new WalkTarget(blockPos, speedModifier, 1));
+ DebugPackets.sendPoiTicketCountPacket(level, blockPos);
+ }
+ });
+ } else {
+ Path path = AcquirePoi.findPathToPois(mob, set);
+ if (path != null && path.canReach()) {
+ BlockPos target = path.getTarget();
+ Optional<Holder<PoiType>> type = poiManager.getType(target);
+ if (type.isPresent()) {
+ walkTarget.set(new WalkTarget(target, speedModifier, 1));
+ DebugPackets.sendPoiTicketCountPacket(level, target);
+ }
+ } else if (mutableInt.getValue() < 5) {
+ map.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < mutableLong.getValue());
}
- } else if (mutableInt.getValue() < 5) {
- map.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < mutableLong.getValue());
}
+ // DivineMC end - async path processing
return true;
} else {
diff --git a/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java b/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java
index d8f532c5e68ff4dff933556c4f981e9474c044e6..37f3d3888ea2a862d006cf2b201f9715bcb8ce1e 100644
--- a/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java
+++ b/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java
@@ -56,7 +56,7 @@ public abstract class DoorInteractGoal extends Goal {
} else {
GroundPathNavigation groundPathNavigation = (GroundPathNavigation)this.mob.getNavigation();
Path path = groundPathNavigation.getPath();
- if (path != null && !path.isDone()) {
+ if (path != null && path.isProcessed() && !path.isDone()) { // DivineMC - async path processing
for (int i = 0; i < Math.min(path.getNextNodeIndex() + 2, path.getNodeCount()); i++) {
Node node = path.getNode(i);
this.doorPos = new BlockPos(node.x, node.y + 1, node.z);
diff --git a/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java b/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java
index 66a02fe7594522ef391d67e09856bf3f70fe597d..d560bbfb1272f8fd9b0d9b7af80f748afa61246c 100644
--- a/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java
+++ b/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java
@@ -12,9 +12,25 @@ public class AmphibiousPathNavigation extends PathNavigation {
super(mob, level);
}
+ // DivineMC start - async path processing
+ private static final space.bxteam.divinemc.pathfinding.NodeEvaluatorGenerator nodeEvaluatorGenerator = (space.bxteam.divinemc.pathfinding.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> {
+ AmphibiousNodeEvaluator nodeEvaluator = new AmphibiousNodeEvaluator(false);
+ nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors());
+ nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat());
+ nodeEvaluator.setCanWalkOverFences(nodeEvaluatorFeatures.canWalkOverFences());
+ nodeEvaluator.setCanOpenDoors(nodeEvaluatorFeatures.canOpenDoors());
+ return nodeEvaluator;
+ };
+ // DivineMC end - async path processing
+
@Override
protected PathFinder createPathFinder(int maxVisitedNodes) {
this.nodeEvaluator = new AmphibiousNodeEvaluator(false);
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
+ }
+ // DivineMC end - async path processing
return new PathFinder(this.nodeEvaluator, maxVisitedNodes);
}
diff --git a/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java b/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java
index 71ea68b56b3069bdf8e47931156b6ef49ea8ce5d..da804d3feef49555677ab6485d7aa6b1114b9d7f 100644
--- a/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java
+++ b/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java
@@ -16,9 +16,25 @@ public class FlyingPathNavigation extends PathNavigation {
super(mob, level);
}
+ // DivineMC start - async path processing
+ private static final space.bxteam.divinemc.pathfinding.NodeEvaluatorGenerator nodeEvaluatorGenerator = (space.bxteam.divinemc.pathfinding.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> {
+ FlyNodeEvaluator nodeEvaluator = new FlyNodeEvaluator();
+ nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors());
+ nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat());
+ nodeEvaluator.setCanWalkOverFences(nodeEvaluatorFeatures.canWalkOverFences());
+ nodeEvaluator.setCanOpenDoors(nodeEvaluatorFeatures.canOpenDoors());
+ return nodeEvaluator;
+ };
+ // DivineMC end - async path processing
+
@Override
protected PathFinder createPathFinder(int maxVisitedNodes) {
this.nodeEvaluator = new FlyNodeEvaluator();
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
+ }
+ // DivineMC end - async path processing
return new PathFinder(this.nodeEvaluator, maxVisitedNodes);
}
@@ -48,6 +64,7 @@ public class FlyingPathNavigation extends PathNavigation {
if (this.hasDelayedRecomputation) {
this.recomputePath();
}
+ if (this.path != null && !this.path.isProcessed()) return; // DivineMC - async path processing
if (!this.isDone()) {
if (this.canUpdatePath()) {
diff --git a/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java b/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java
index 045cfafb3afe8271d60852ae3c7cdcb039b44d4f..fc02c7ca984dd2bcfca47002d7353427a1a70264 100644
--- a/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java
+++ b/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java
@@ -24,9 +24,25 @@ public class GroundPathNavigation extends PathNavigation {
super(mob, level);
}
+ // DivineMC start - async path processing
+ protected static final space.bxteam.divinemc.pathfinding.NodeEvaluatorGenerator nodeEvaluatorGenerator = (space.bxteam.divinemc.pathfinding.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> {
+ WalkNodeEvaluator nodeEvaluator = new WalkNodeEvaluator();
+ nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors());
+ nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat());
+ nodeEvaluator.setCanWalkOverFences(nodeEvaluatorFeatures.canWalkOverFences());
+ nodeEvaluator.setCanOpenDoors(nodeEvaluatorFeatures.canOpenDoors());
+ return nodeEvaluator;
+ };
+ // DivineMC end - async path processing
+
@Override
protected PathFinder createPathFinder(int maxVisitedNodes) {
this.nodeEvaluator = new WalkNodeEvaluator();
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
+ }
+ // DivineMC end - async path processing
return new PathFinder(this.nodeEvaluator, maxVisitedNodes);
}
diff --git a/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/net/minecraft/world/entity/ai/navigation/PathNavigation.java
index b44f2c49509d847817a78e9c4fb1499fb378054b..aaa4e1d36d486baa767d427be51390b013214905 100644
--- a/net/minecraft/world/entity/ai/navigation/PathNavigation.java
+++ b/net/minecraft/world/entity/ai/navigation/PathNavigation.java
@@ -169,6 +169,10 @@ public abstract class PathNavigation {
return null;
} else if (!this.canUpdatePath()) {
return null;
+ // DivineMC start - catch early if it's still processing these positions let it keep processing
+ } else if (this.path instanceof space.bxteam.divinemc.pathfinding.AsyncPath asyncPath && !asyncPath.isProcessed() && asyncPath.hasSameProcessingPositions(targets)) {
+ return this.path;
+ // DivineMC end - catch early if it's still processing these positions let it keep processing
} else if (this.path != null && !this.path.isDone() && targets.contains(this.targetPos)) {
return this.path;
} else {
@@ -195,12 +199,30 @@ public abstract class PathNavigation {
int i = (int)(followRange + regionOffset);
PathNavigationRegion pathNavigationRegion = new PathNavigationRegion(this.level, blockPos.offset(-i, -i, -i), blockPos.offset(i, i, i));
Path path = this.pathFinder.findPath(pathNavigationRegion, this.mob, targets, followRange, accuracy, this.maxVisitedNodesMultiplier);
- profilerFiller.pop();
- if (path != null && path.getTarget() != null) {
- this.targetPos = path.getTarget();
- this.reachRange = accuracy;
- this.resetStuckTimeout();
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ // assign early a target position. most calls will only have 1 position
+ if (!targets.isEmpty()) this.targetPos = targets.iterator().next();
+
+ space.bxteam.divinemc.pathfinding.AsyncPathProcessor.awaitProcessing(path, processedPath -> {
+ // check that processing didn't take so long that we calculated a new path
+ if (processedPath != this.path) return;
+
+ if (processedPath != null && processedPath.getTarget() != null) {
+ this.targetPos = processedPath.getTarget();
+ this.reachRange = accuracy;
+ this.resetStuckTimeout();
+ }
+ });
+ } else {
+ profilerFiller.pop();
+ if (path != null && path.getTarget() != null) {
+ this.targetPos = path.getTarget();
+ this.reachRange = accuracy;
+ this.resetStuckTimeout();
+ }
}
+ // DivineMC end - async path processing
return path;
}
@@ -251,8 +273,8 @@ public abstract class PathNavigation {
if (this.isDone()) {
return false;
} else {
- this.trimPath();
- if (this.path.getNodeCount() <= 0) {
+ if (path.isProcessed()) this.trimPath(); // DivineMC - only trim if processed
+ if (path.isProcessed() && this.path.getNodeCount() <= 0) { // DivineMC - only check node count if processed
return false;
} else {
this.speedModifier = speed;
@@ -275,6 +297,7 @@ public abstract class PathNavigation {
if (this.hasDelayedRecomputation) {
this.recomputePath();
}
+ if (this.path != null && !this.path.isProcessed()) return; // DivineMC - skip pathfinding if we're still processing
if (!this.isDone()) {
if (this.canUpdatePath()) {
@@ -304,6 +327,7 @@ public abstract class PathNavigation {
}
protected void followThePath() {
+ if (!this.path.isProcessed()) return; // DivineMC - skip if not processed
Vec3 tempMobPos = this.getTempMobPos();
this.maxDistanceToWaypoint = this.mob.getBbWidth() > 0.75F ? this.mob.getBbWidth() / 2.0F : 0.75F - this.mob.getBbWidth() / 2.0F;
Vec3i nextNodePos = this.path.getNextNodePos();
@@ -460,7 +484,7 @@ public abstract class PathNavigation {
public boolean shouldRecomputePath(BlockPos pos) {
if (this.hasDelayedRecomputation) {
return false;
- } else if (this.path != null && !this.path.isDone() && this.path.getNodeCount() != 0) {
+ } else if (this.path != null && this.path.isProcessed() && !this.path.isDone() && this.path.getNodeCount() != 0) { // DivineMC - Skip if not processed
Node endNode = this.path.getEndNode();
Vec3 vec3 = new Vec3((endNode.x + this.mob.getX()) / 2.0, (endNode.y + this.mob.getY()) / 2.0, (endNode.z + this.mob.getZ()) / 2.0);
return pos.closerToCenterThan(vec3, this.path.getNodeCount() - this.path.getNextNodeIndex());
diff --git a/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java b/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java
index 2979846853898d78a2df19df2287da16dbe4ae71..fbecca6fa274bcc6d07b9d300c31873fdb64c773 100644
--- a/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java
+++ b/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java
@@ -15,11 +15,27 @@ public class WaterBoundPathNavigation extends PathNavigation {
super(mob, level);
}
+ // DivineMC start - async path processing
+ private static final space.bxteam.divinemc.pathfinding.NodeEvaluatorGenerator nodeEvaluatorGenerator = (space.bxteam.divinemc.pathfinding.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> {
+ SwimNodeEvaluator nodeEvaluator = new SwimNodeEvaluator(nodeEvaluatorFeatures.allowBreaching());
+ nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors());
+ nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat());
+ nodeEvaluator.setCanWalkOverFences(nodeEvaluatorFeatures.canWalkOverFences());
+ nodeEvaluator.setCanOpenDoors(nodeEvaluatorFeatures.canOpenDoors());
+ return nodeEvaluator;
+ };
+ // DivineMC end - async path processing
+
@Override
protected PathFinder createPathFinder(int maxVisitedNodes) {
this.allowBreaching = this.mob.getType() == EntityType.DOLPHIN;
this.nodeEvaluator = new SwimNodeEvaluator(this.allowBreaching);
this.nodeEvaluator.setCanPassDoors(false);
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
+ }
+ // DivineMC end - async path processing
return new PathFinder(this.nodeEvaluator, maxVisitedNodes);
}
diff --git a/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java b/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
index 1f96fd5085bacb4c584576c7cb9f51e7898e9b03..cc202eb0848a2faecd556fa279565717be11b382 100644
--- a/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
+++ b/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
@@ -57,17 +57,37 @@ public class NearestBedSensor extends Sensor<Mob> {
java.util.List<Pair<Holder<PoiType>, BlockPos>> poiposes = new java.util.ArrayList<>();
// don't ask me why it's unbounded. ask mojang.
io.papermc.paper.util.PoiAccess.findAnyPoiPositions(poiManager, type -> type.is(PoiTypes.HOME), predicate, entity.blockPosition(), level.purpurConfig.villagerNearestBedSensorSearchRadius, PoiManager.Occupancy.ANY, false, Integer.MAX_VALUE, poiposes); // Purpur - Configurable villager search radius
- Path path = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes));
// Paper end - optimise POI access
- if (path != null && path.canReach()) {
- BlockPos target = path.getTarget();
- Optional<Holder<PoiType>> type = poiManager.getType(target);
- if (type.isPresent()) {
- entity.getBrain().setMemory(MemoryModuleType.NEAREST_BED, target);
+ // DivineMC start - async pathfinding
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ Path possiblePath = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes));
+ space.bxteam.divinemc.pathfinding.AsyncPathProcessor.awaitProcessing(possiblePath, path -> {
+ // read canReach check
+ if ((path == null || !path.canReach()) && this.triedCount < 5) {
+ this.batchCache.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < this.lastUpdate);
+ return;
+ }
+ if (path == null) return;
+
+ BlockPos blockPos = path.getTarget();
+ Optional<Holder<PoiType>> optional = poiManager.getType(blockPos);
+ if (optional.isPresent()) {
+ entity.getBrain().setMemory(MemoryModuleType.NEAREST_BED, blockPos);
+ }
+ });
+ } else {
+ Path path = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes));
+ if (path != null && path.canReach()) {
+ BlockPos target = path.getTarget();
+ Optional<Holder<PoiType>> type = poiManager.getType(target);
+ if (type.isPresent()) {
+ entity.getBrain().setMemory(MemoryModuleType.NEAREST_BED, target);
+ }
+ } else if (this.triedCount < 5) {
+ this.batchCache.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < this.lastUpdate);
}
- } else if (this.triedCount < 5) {
- this.batchCache.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < this.lastUpdate);
}
+ // DivineMC end - async pathfinding
}
}
}
diff --git a/net/minecraft/world/entity/animal/Bee.java b/net/minecraft/world/entity/animal/Bee.java
index 57c50ce5724b073b1aedf4df3129285143097303..5bdf82df2dbb79b8933813b61e617c4882fd5c60 100644
--- a/net/minecraft/world/entity/animal/Bee.java
+++ b/net/minecraft/world/entity/animal/Bee.java
@@ -934,7 +934,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
} else {
Bee.this.pathfindRandomlyTowards(Bee.this.hivePos);
}
- } else {
+ } else if (navigation.getPath() != null && navigation.getPath().isProcessed()) { // DivineMC - check processing
boolean flag = this.pathfindDirectlyTowards(Bee.this.hivePos);
if (!flag) {
this.dropAndBlacklistHive();
@@ -988,7 +988,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
return true;
} else {
Path path = Bee.this.navigation.getPath();
- return path != null && path.getTarget().equals(pos) && path.canReach() && path.isDone();
+ return path != null && path.isProcessed() && path.getTarget().equals(pos) && path.canReach() && path.isDone(); // DivineMC - ensure path is processed
}
}
}
diff --git a/net/minecraft/world/entity/animal/frog/Frog.java b/net/minecraft/world/entity/animal/frog/Frog.java
index d286d4a45b6c8d5c684ad11500d2ad1a10a70c18..9c97f7bd3eaf1a962793287d1b6c7911cdf149fd 100644
--- a/net/minecraft/world/entity/animal/frog/Frog.java
+++ b/net/minecraft/world/entity/animal/frog/Frog.java
@@ -496,6 +496,17 @@ public class Frog extends Animal implements VariantHolder<Holder<FrogVariant>> {
super(mob, level);
}
+ // DivineMC start - async path processing
+ private static final space.bxteam.divinemc.pathfinding.NodeEvaluatorGenerator nodeEvaluatorGenerator = (space.bxteam.divinemc.pathfinding.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> {
+ Frog.FrogNodeEvaluator nodeEvaluator = new Frog.FrogNodeEvaluator(true);
+ nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors());
+ nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat());
+ nodeEvaluator.setCanWalkOverFences(nodeEvaluatorFeatures.canWalkOverFences());
+ nodeEvaluator.setCanOpenDoors(nodeEvaluatorFeatures.canOpenDoors());
+ return nodeEvaluator;
+ };
+ // DivineMC end - async path processing
+
@Override
public boolean canCutCorner(PathType pathType) {
return pathType != PathType.WATER_BORDER && super.canCutCorner(pathType);
@@ -504,6 +515,11 @@ public class Frog extends Animal implements VariantHolder<Holder<FrogVariant>> {
@Override
protected PathFinder createPathFinder(int maxVisitedNodes) {
this.nodeEvaluator = new Frog.FrogNodeEvaluator(true);
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
+ }
+ // DivineMC end - async path processing
return new PathFinder(this.nodeEvaluator, maxVisitedNodes);
}
}
diff --git a/net/minecraft/world/entity/monster/Drowned.java b/net/minecraft/world/entity/monster/Drowned.java
index 6c73245b8d04f194e72165aa0000ca79a95db59d..2686df57d9d48db1438278d0d053bdbd3c65c0a7 100644
--- a/net/minecraft/world/entity/monster/Drowned.java
+++ b/net/minecraft/world/entity/monster/Drowned.java
@@ -313,7 +313,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
protected boolean closeToNextPos() {
Path path = this.getNavigation().getPath();
- if (path != null) {
+ if (path != null && path.isProcessed()) { // DivineMC - ensure path is processed
BlockPos target = path.getTarget();
if (target != null) {
double d = this.distanceToSqr(target.getX(), target.getY(), target.getZ());
diff --git a/net/minecraft/world/entity/monster/Strider.java b/net/minecraft/world/entity/monster/Strider.java
index 241526239bdbd5d9276f85e7fca46a7051f46a25..026ec71bff3e4e0c2098e331f6a2bd9ba5955ccb 100644
--- a/net/minecraft/world/entity/monster/Strider.java
+++ b/net/minecraft/world/entity/monster/Strider.java
@@ -579,9 +579,25 @@ public class Strider extends Animal implements ItemSteerable, Saddleable {
super(strider, level);
}
+ // DivineMC start - async path processing
+ private static final space.bxteam.divinemc.pathfinding.NodeEvaluatorGenerator nodeEvaluatorGenerator = (space.bxteam.divinemc.pathfinding.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> {
+ WalkNodeEvaluator nodeEvaluator = new WalkNodeEvaluator();
+ nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors());
+ nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat());
+ nodeEvaluator.setCanWalkOverFences(nodeEvaluatorFeatures.canWalkOverFences());
+ nodeEvaluator.setCanOpenDoors(nodeEvaluatorFeatures.canOpenDoors());
+ return nodeEvaluator;
+ };
+ // DivineMC end - async path processing
+
@Override
protected PathFinder createPathFinder(int maxVisitedNodes) {
this.nodeEvaluator = new WalkNodeEvaluator();
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
+ }
+ // DivineMC end
return new PathFinder(this.nodeEvaluator, maxVisitedNodes);
}
diff --git a/net/minecraft/world/entity/monster/warden/Warden.java b/net/minecraft/world/entity/monster/warden/Warden.java
index f74c784906208034f51b31bd9aba45733c3ebebe..a1fa17eaef088e36284fc79d6afd4c43b8a0a1a9 100644
--- a/net/minecraft/world/entity/monster/warden/Warden.java
+++ b/net/minecraft/world/entity/monster/warden/Warden.java
@@ -619,6 +619,16 @@ public class Warden extends Monster implements VibrationSystem {
@Override
protected PathFinder createPathFinder(int maxVisitedNodes) {
this.nodeEvaluator = new WalkNodeEvaluator();
+ // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, GroundPathNavigation.nodeEvaluatorGenerator) {
+ @Override
+ protected float distance(Node first, Node second) {
+ return first.distanceToXZ(second);
+ }
+ };
+ }
+ // DivineMC end - async path processing
return new PathFinder(this.nodeEvaluator, maxVisitedNodes) {
@Override
protected float distance(Node first, Node second) {
diff --git a/net/minecraft/world/level/pathfinder/Path.java b/net/minecraft/world/level/pathfinder/Path.java
index d6d3c8f5e5dd4a8cab0d3fcc131c3a59f06130c6..839653a997f1e10970fa2956fadaf493808cb206 100644
--- a/net/minecraft/world/level/pathfinder/Path.java
+++ b/net/minecraft/world/level/pathfinder/Path.java
@@ -26,6 +26,17 @@ public class Path {
this.reached = reached;
}
+ // DivineMC start - async path processing
+ /**
+ * checks if the path is completely processed in the case of it being computed async
+ *
+ * @return true if the path is processed
+ */
+ public boolean isProcessed() {
+ return true;
+ }
+ // DivineMC end - async path processing
+
public void advance() {
this.nextNodeIndex++;
}
@@ -99,6 +110,7 @@ public class Path {
}
public boolean sameAs(@Nullable Path pathentity) {
+ if (pathentity == this) return true; // DivineMC - async path processing
if (pathentity == null) {
return false;
} else if (pathentity.nodes.size() != this.nodes.size()) {
diff --git a/net/minecraft/world/level/pathfinder/PathFinder.java b/net/minecraft/world/level/pathfinder/PathFinder.java
index 81de6c1bbef1cafd3036e736dd305fbedc8368c6..4b8182414ca9aa22e096babb25a32f2b5ba60312 100644
--- a/net/minecraft/world/level/pathfinder/PathFinder.java
+++ b/net/minecraft/world/level/pathfinder/PathFinder.java
@@ -25,11 +25,19 @@ public class PathFinder {
public final NodeEvaluator nodeEvaluator;
private static final boolean DEBUG = false;
private final BinaryHeap openSet = new BinaryHeap();
+ private final @Nullable space.bxteam.divinemc.pathfinding.NodeEvaluatorGenerator nodeEvaluatorGenerator; // DivineMC - we use this later to generate an evaluator
- public PathFinder(NodeEvaluator nodeEvaluator, int maxVisitedNodes) {
+ // DivineMC start - support nodeEvaluatorgenerators
+ public PathFinder(NodeEvaluator nodeEvaluator, int maxVisitedNodes, @Nullable space.bxteam.divinemc.pathfinding.NodeEvaluatorGenerator nodeEvaluatorGenerator) { // DivineMC - add nodeEvaluatorGenerator
this.nodeEvaluator = nodeEvaluator;
this.maxVisitedNodes = maxVisitedNodes;
+ this.nodeEvaluatorGenerator = nodeEvaluatorGenerator;
+ }
+
+ public PathFinder(NodeEvaluator nodeEvaluator, int maxVisitedNodes) {
+ this(nodeEvaluator, maxVisitedNodes, null);
}
+ // DivineMC end - support nodeEvaluatorgenerators
public void setMaxVisitedNodes(int maxVisitedNodes) {
this.maxVisitedNodes = maxVisitedNodes;
@@ -37,26 +45,63 @@ public class PathFinder {
@Nullable
public Path findPath(PathNavigationRegion region, Mob mob, Set<BlockPos> targetPositions, float maxRange, int accuracy, float searchDepthMultiplier) {
- this.openSet.clear();
- this.nodeEvaluator.prepare(region, mob);
- Node start = this.nodeEvaluator.getStart();
+ // DivineMC start - use a generated evaluator if we have one otherwise run sync
+ if (!space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding)
+ this.openSet.clear(); // it's always cleared in processPath
+ NodeEvaluator nodeEvaluator = this.nodeEvaluatorGenerator == null
+ ? this.nodeEvaluator
+ : space.bxteam.divinemc.pathfinding.NodeEvaluatorCache.takeNodeEvaluator(this.nodeEvaluatorGenerator, this.nodeEvaluator);
+ nodeEvaluator.prepare(region, mob);
+ Node start = nodeEvaluator.getStart();
+ // DivineMC end - use a generated evaluator if we have one otherwise run sync
if (start == null) {
+ space.bxteam.divinemc.pathfinding.NodeEvaluatorCache.removeNodeEvaluator(nodeEvaluator); // DivineMC - handle nodeEvaluatorGenerator
return null;
} else {
// Paper start - Perf: remove streams and optimize collection
List<Map.Entry<Target, BlockPos>> map = Lists.newArrayList();
for (BlockPos pos : targetPositions) {
- map.add(new java.util.AbstractMap.SimpleEntry<>(this.nodeEvaluator.getTarget(pos.getX(), pos.getY(), pos.getZ()), pos));
+ map.add(new java.util.AbstractMap.SimpleEntry<>(nodeEvaluator.getTarget(pos.getX(), pos.getY(), pos.getZ()), pos)); // DivineMC - handle nodeEvaluatorGenerator
}
// Paper end - Perf: remove streams and optimize collection
- Path path = this.findPath(start, map, maxRange, accuracy, searchDepthMultiplier);
- this.nodeEvaluator.done();
- return path;
+ // DivineMC start - async path processing
+ if (this.nodeEvaluatorGenerator == null) {
+ // run sync :(
+ space.bxteam.divinemc.pathfinding.NodeEvaluatorCache.removeNodeEvaluator(nodeEvaluator);
+ return this.findPath(start, map, maxRange, accuracy, searchDepthMultiplier);
+ }
+
+ return new space.bxteam.divinemc.pathfinding.AsyncPath(Lists.newArrayList(), targetPositions, () -> {
+ try {
+ return this.processPath(nodeEvaluator, start, map, maxRange, accuracy, searchDepthMultiplier);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ } finally {
+ nodeEvaluator.done();
+ space.bxteam.divinemc.pathfinding.NodeEvaluatorCache.returnNodeEvaluator(nodeEvaluator);
+ }
+ });
+ // DivineMC end - async path processing
}
}
@Nullable
private Path findPath(Node node, List<Map.Entry<Target, BlockPos>> positions, float maxRange, int accuracy, float searchDepthMultiplier) { // Paper - optimize collection
+ // DivineMC start - split pathfinding into the original sync method for compat and processing for delaying
+ try {
+ return this.processPath(this.nodeEvaluator, node, positions, maxRange, accuracy, searchDepthMultiplier);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ } finally {
+ this.nodeEvaluator.done();
+ }
+ }
+
+ private synchronized @org.jetbrains.annotations.NotNull Path processPath(NodeEvaluator nodeEvaluator, Node node, List<Map.Entry<Target, BlockPos>> positions, float maxRange, int accuracy, float searchDepthMultiplier) { // sync to only use the caching functions in this class on a single thread
+ org.apache.commons.lang3.Validate.isTrue(!positions.isEmpty()); // ensure that we have at least one position, which means we'll always return a path
+ // DivineMC end - split pathfinding into the original sync method for compat and processing for delaying
ProfilerFiller profilerFiller = Profiler.get();
profilerFiller.push("find_path");
profilerFiller.markForCharting(MetricCategory.PATH_FINDING);
@@ -95,7 +140,7 @@ public class PathFinder {
}
if (!(node1.distanceTo(node) >= maxRange)) {
- int neighbors = this.nodeEvaluator.getNeighbors(this.neighbors, node1);
+ int neighbors = nodeEvaluator.getNeighbors(this.neighbors, node1); // DivineMC - use provided nodeEvaluator
for (int i2 = 0; i2 < neighbors; i2++) {
Node node2 = this.neighbors[i2];

View File

@@ -0,0 +1,433 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sat, 20 Jul 2024 22:04:52 +0300
Subject: [PATCH] Implement Secure Seed
Original license: GPLv3
Original project: https://github.com/plasmoapp/matter
diff --git a/net/minecraft/server/commands/SeedCommand.java b/net/minecraft/server/commands/SeedCommand.java
index a65affc41a4fc299bc2281f0f53f2e075633899d..2ba3b8150bb753eebd5694275917c2ca8464b12e 100644
--- a/net/minecraft/server/commands/SeedCommand.java
+++ b/net/minecraft/server/commands/SeedCommand.java
@@ -12,6 +12,17 @@ public class SeedCommand {
long seed = context.getSource().getLevel().getSeed();
Component component = ComponentUtils.copyOnClickText(String.valueOf(seed));
context.getSource().sendSuccess(() -> Component.translatable("commands.seed.success", component), false);
+
+ // DivineMC start - Implement Secure Seed
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ space.bxteam.divinemc.seed.Globals.setupGlobals(context.getSource().getLevel());
+ String seedStr = space.bxteam.divinemc.seed.Globals.seedToString(space.bxteam.divinemc.seed.Globals.worldSeed);
+ Component featureSeedComponent = ComponentUtils.copyOnClickText(seedStr);
+
+ context.getSource().sendSuccess(() -> Component.translatable(("Feature seed: %s"), featureSeedComponent), false);
+ }
+ // DivineMC end - Implement Secure Seed
+
return (int)seed;
}));
}
diff --git a/net/minecraft/server/dedicated/DedicatedServerProperties.java b/net/minecraft/server/dedicated/DedicatedServerProperties.java
index 5748658abf0b90812005ae9d426df92daf5532f0..f4af49555bcf69cfaf7467f1fa7d4292a5652fa5 100644
--- a/net/minecraft/server/dedicated/DedicatedServerProperties.java
+++ b/net/minecraft/server/dedicated/DedicatedServerProperties.java
@@ -114,7 +114,17 @@ public class DedicatedServerProperties extends Settings<DedicatedServerPropertie
String string = this.get("level-seed", "");
boolean flag = this.get("generate-structures", true);
long l = WorldOptions.parseSeed(string).orElse(WorldOptions.randomSeed());
- this.worldOptions = new WorldOptions(l, flag, false);
+ // DivineMC start - Implement Secure Seed
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ String featureSeedStr = this.get("feature-level-seed", "");
+ long[] featureSeed = space.bxteam.divinemc.seed.Globals.parseSeed(featureSeedStr)
+ .orElse(space.bxteam.divinemc.seed.Globals.createRandomWorldSeed());
+
+ this.worldOptions = new WorldOptions(l, featureSeed, flag, false);
+ } else {
+ this.worldOptions = new WorldOptions(l, flag, false);
+ }
+ // DivineMC end - Implement Secure Seed
this.worldDimensionData = new DedicatedServerProperties.WorldDimensionData(
this.get("generator-settings", property -> GsonHelper.parse(!property.isEmpty() ? property : "{}"), new JsonObject()),
this.get("level-type", property -> property.toLowerCase(Locale.ROOT), WorldPresets.NORMAL.location().toString())
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
index 6540b2d6a1062d883811ce240c49d30d1925b291..bceaf150f7e9b5c4a08be6102571d8fef68a2fc2 100644
--- a/net/minecraft/server/level/ServerChunkCache.java
+++ b/net/minecraft/server/level/ServerChunkCache.java
@@ -652,6 +652,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
}
public ChunkGenerator getGenerator() {
+ space.bxteam.divinemc.seed.Globals.setupGlobals(level); // DivineMC - Implement Secure Seed
return this.chunkMap.generator();
}
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 3770dc90d9412c6378c0bd57a651b9c3e62b9a72..8127a71fd7d45541525be75e6699c2a5bae95f5f 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -634,6 +634,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
chunkGenerator = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, chunkGenerator, gen);
}
// CraftBukkit end
+ space.bxteam.divinemc.seed.Globals.setupGlobals(this); // DivineMC - Implement Secure Seed
boolean flag = server.forceSynchronousWrites();
DataFixer fixerUpper = server.getFixerUpper();
// Paper - rewrite chunk system
diff --git a/net/minecraft/world/entity/monster/Slime.java b/net/minecraft/world/entity/monster/Slime.java
index 240a54b210e23d5b79e6bcaf3806aa454668135d..f8cf35cf6837b810a28b64e834d810fc92bdb9d3 100644
--- a/net/minecraft/world/entity/monster/Slime.java
+++ b/net/minecraft/world/entity/monster/Slime.java
@@ -423,8 +423,13 @@ public class Slime extends Mob implements Enemy {
return false;
}
- ChunkPos chunkPos = new ChunkPos(pos);
- boolean flag = level.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(chunkPos.x, chunkPos.z, ((WorldGenLevel) level).getSeed(), level.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper
+ ChunkPos chunkPos = new ChunkPos(pos);
+ // DivineMC start - Implement Secure Seed
+ boolean isSlimeChunk = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
+ ? level.getChunk(chunkPos.x, chunkPos.z).isSlimeChunk()
+ : WorldgenRandom.seedSlimeChunk(chunkPos.x, chunkPos.z, ((WorldGenLevel) level).getSeed(), level.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper
+ boolean flag = level.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || isSlimeChunk;
+ // DivineMC end - Implement Secure Seed
// Paper start - Replace rules for Height in Slime Chunks
final double maxHeightSlimeChunk = level.getMinecraftWorld().paperConfig().entities.spawning.slimeSpawnHeight.slimeChunk.maximum;
if (random.nextInt(10) == 0 && flag && pos.getY() < maxHeightSlimeChunk) {
diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java
index 6d565b52552534ce9cacfc35ad1bf4adcb69eac3..7c3321b43e9eb1e6d15a571a8292853be4930448 100644
--- a/net/minecraft/world/level/chunk/ChunkAccess.java
+++ b/net/minecraft/world/level/chunk/ChunkAccess.java
@@ -82,6 +82,10 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
public final Map<BlockPos, BlockEntity> blockEntities = new Object2ObjectOpenHashMap<>();
protected final LevelHeightAccessor levelHeightAccessor;
protected final LevelChunkSection[] sections;
+ // DivineMC start - Implement Secure Seed
+ private boolean slimeChunk;
+ private boolean hasComputedSlimeChunk;
+ // DivineMC end - Implement Secure Seed
// CraftBukkit start - SPIGOT-6814: move to IChunkAccess to account for 1.17 to 1.18 chunk upgrading.
private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry();
public org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer(ChunkAccess.DATA_TYPE_REGISTRY);
@@ -191,6 +195,17 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
return GameEventListenerRegistry.NOOP;
}
+ // DivineMC start - Implement Secure Seed
+ public boolean isSlimeChunk() {
+ if (!hasComputedSlimeChunk) {
+ hasComputedSlimeChunk = true;
+ slimeChunk = space.bxteam.divinemc.seed.WorldgenCryptoRandom.seedSlimeChunk(chunkPos.x, chunkPos.z).nextInt(10) == 0;
+ }
+
+ return slimeChunk;
+ }
+ // DivineMC end - Implement Secure Seed
+
public abstract BlockState getBlockState(final int x, final int y, final int z); // Paper
@Nullable
public abstract BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving);
diff --git a/net/minecraft/world/level/chunk/ChunkGenerator.java b/net/minecraft/world/level/chunk/ChunkGenerator.java
index 6ed51cf42b5864194d671b5b56f5b9bdf0291dc0..a565b61cd0919fa874d9ab8d00e879b860d3dab5 100644
--- a/net/minecraft/world/level/chunk/ChunkGenerator.java
+++ b/net/minecraft/world/level/chunk/ChunkGenerator.java
@@ -343,7 +343,11 @@ public abstract class ChunkGenerator {
Registry<Structure> registry = level.registryAccess().lookupOrThrow(Registries.STRUCTURE);
Map<Integer, List<Structure>> map = registry.stream().collect(Collectors.groupingBy(structure1 -> structure1.step().ordinal()));
List<FeatureSorter.StepFeatureData> list = this.featuresPerStep.get();
- WorldgenRandom worldgenRandom = new WorldgenRandom(new XoroshiroRandomSource(RandomSupport.generateUniqueSeed()));
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom worldgenRandom = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
+ ? new space.bxteam.divinemc.seed.WorldgenCryptoRandom(blockPos.getX(), blockPos.getZ(), space.bxteam.divinemc.seed.Globals.Salt.UNDEFINED, 0)
+ : new WorldgenRandom(new XoroshiroRandomSource(RandomSupport.generateUniqueSeed()));
+ // DivineMC end - Implement Secure Seed
long l = worldgenRandom.setDecorationSeed(level.getSeed(), blockPos.getX(), blockPos.getZ());
Set<Holder<Biome>> set = new ObjectArraySet<>();
ChunkPos.rangeClosed(sectionPos.chunk(), 1).forEach(chunkPos -> {
@@ -556,8 +560,18 @@ public abstract class ChunkGenerator {
} else {
ArrayList<StructureSet.StructureSelectionEntry> list1 = new ArrayList<>(list.size());
list1.addAll(list);
- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
- worldgenRandom.setLargeFeatureSeed(structureState.getLevelSeed(), pos.x, pos.z);
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom worldgenRandom;
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ worldgenRandom = new space.bxteam.divinemc.seed.WorldgenCryptoRandom(
+ pos.x, pos.z, space.bxteam.divinemc.seed.Globals.Salt.GENERATE_FEATURE, 0
+ );
+ } else {
+ worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
+
+ worldgenRandom.setLargeFeatureSeed(structureState.getLevelSeed(), pos.x, pos.z);
+ }
+ // DivineMC end - Implement Secure Seed
int i = 0;
for (StructureSet.StructureSelectionEntry structureSelectionEntry1 : list1) {
diff --git a/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java b/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
index 619b98e42e254c0c260c171a26a2472ddf59b885..797d0c8e836150b17dedb8ee00e0f245aff434ee 100644
--- a/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
+++ b/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
@@ -205,14 +205,21 @@ public class ChunkGeneratorStructureState {
List<CompletableFuture<ChunkPos>> list = new ArrayList<>(count);
int spread = placement.spread();
HolderSet<Biome> holderSet = placement.preferredBiomes();
- RandomSource randomSource = RandomSource.create();
- // Paper start - Add missing structure set seed configs
- if (this.conf.strongholdSeed != null && structureSet.is(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS)) {
- randomSource.setSeed(this.conf.strongholdSeed);
- } else {
- // Paper end - Add missing structure set seed configs
- randomSource.setSeed(this.concentricRingsSeed);
- } // Paper - Add missing structure set seed configs
+ // DivineMC start - Implement Secure Seed
+ RandomSource randomSource = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
+ ? new space.bxteam.divinemc.seed.WorldgenCryptoRandom(0, 0, space.bxteam.divinemc.seed.Globals.Salt.STRONGHOLDS, 0)
+ : RandomSource.create();
+
+ if (!space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ // Paper start - Add missing structure set seed configs
+ if (this.conf.strongholdSeed != null && structureSet.is(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS)) {
+ randomSource.setSeed(this.conf.strongholdSeed);
+ } else {
+ // Paper end - Add missing structure set seed configs
+ randomSource.setSeed(this.concentricRingsSeed);
+ } // Paper - Add missing structure set seed configs
+ }
+ // DivineMC end - Implement Secure Seed
double d = randomSource.nextDouble() * Math.PI * 2.0;
int i = 0;
int i1 = 0;
diff --git a/net/minecraft/world/level/chunk/status/ChunkStep.java b/net/minecraft/world/level/chunk/status/ChunkStep.java
index b8348976e80578d9eff64eea68c04c603fed49ad..d84099c67704881a99d371ff79177257faa1abfc 100644
--- a/net/minecraft/world/level/chunk/status/ChunkStep.java
+++ b/net/minecraft/world/level/chunk/status/ChunkStep.java
@@ -60,6 +60,7 @@ public final class ChunkStep implements ca.spottedleaf.moonrise.patches.chunk_sy
}
public CompletableFuture<ChunkAccess> apply(WorldGenContext worldGenContext, StaticCache2D<GenerationChunkHolder> cache, ChunkAccess chunk) {
+ space.bxteam.divinemc.seed.Globals.setupGlobals(worldGenContext.level()); // DivineMC - Implement Secure Seed
if (chunk.getPersistedStatus().isBefore(this.targetStatus)) {
ProfiledDuration profiledDuration = JvmProfiler.INSTANCE
.onChunkGenerate(chunk.getPos(), worldGenContext.level().dimension(), this.targetStatus.getName());
diff --git a/net/minecraft/world/level/levelgen/WorldOptions.java b/net/minecraft/world/level/levelgen/WorldOptions.java
index c92508741439a8d0d833ea02d0104416adb83c92..05a2c2e7830fda9d7c22904ee3ff44734e3a38af 100644
--- a/net/minecraft/world/level/levelgen/WorldOptions.java
+++ b/net/minecraft/world/level/levelgen/WorldOptions.java
@@ -9,17 +9,28 @@ import net.minecraft.util.RandomSource;
import org.apache.commons.lang3.StringUtils;
public class WorldOptions {
+ // DivineMC start - Implement Secure Seed
+ private static final boolean isSecureSeedEnabled = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed;
public static final MapCodec<WorldOptions> CODEC = RecordCodecBuilder.mapCodec(
- instance -> instance.group(
+ instance -> isSecureSeedEnabled
+ ? instance.group(
Codec.LONG.fieldOf("seed").stable().forGetter(WorldOptions::seed),
+ Codec.LONG_STREAM.fieldOf("feature_seed").stable().forGetter(WorldOptions::featureSeedStream),
Codec.BOOL.fieldOf("generate_features").orElse(true).stable().forGetter(WorldOptions::generateStructures),
Codec.BOOL.fieldOf("bonus_chest").orElse(false).stable().forGetter(WorldOptions::generateBonusChest),
- Codec.STRING.lenientOptionalFieldOf("legacy_custom_options").stable().forGetter(worldOptions -> worldOptions.legacyCustomOptions)
- )
- .apply(instance, instance.stable(WorldOptions::new))
+ Codec.STRING.lenientOptionalFieldOf("legacy_custom_options").stable().forGetter(generatorOptions -> generatorOptions.legacyCustomOptions)).apply(instance, instance.stable(WorldOptions::new))
+ : instance.group(
+ Codec.LONG.fieldOf("seed").stable().forGetter(WorldOptions::seed),
+ Codec.BOOL.fieldOf("generate_features").orElse(true).stable().forGetter(WorldOptions::generateStructures),
+ Codec.BOOL.fieldOf("bonus_chest").orElse(false).stable().forGetter(WorldOptions::generateBonusChest),
+ Codec.STRING.lenientOptionalFieldOf("legacy_custom_options").stable().forGetter(worldOptions -> worldOptions.legacyCustomOptions)).apply(instance, instance.stable(WorldOptions::new))
);
- public static final WorldOptions DEMO_OPTIONS = new WorldOptions("North Carolina".hashCode(), true, true);
+ public static final WorldOptions DEMO_OPTIONS = isSecureSeedEnabled
+ ? new WorldOptions("North Carolina".hashCode(), space.bxteam.divinemc.seed.Globals.createRandomWorldSeed(), true, true)
+ : new WorldOptions("North Carolina".hashCode(), true, true);
+ // DivineMC end - Implement Secure Seed
private final long seed;
+ private long[] featureSeed = space.bxteam.divinemc.seed.Globals.createRandomWorldSeed(); // DivineMC - Implement Secure Seed
private final boolean generateStructures;
private final boolean generateBonusChest;
private final Optional<String> legacyCustomOptions;
@@ -28,9 +39,21 @@ public class WorldOptions {
this(seed, generateStructures, generateBonusChest, Optional.empty());
}
+ // DivineMC start - Implement Secure Seed
+ public WorldOptions(long seed, long[] featureSeed, boolean generateStructures, boolean bonusChest) {
+ this(seed, featureSeed, generateStructures, bonusChest, Optional.empty());
+ }
+
public static WorldOptions defaultWithRandomSeed() {
- return new WorldOptions(randomSeed(), true, false);
+ return isSecureSeedEnabled
+ ? new WorldOptions(randomSeed(), space.bxteam.divinemc.seed.Globals.createRandomWorldSeed(), true, false)
+ : new WorldOptions(randomSeed(), true, false);
+ }
+
+ private WorldOptions(long seed, java.util.stream.LongStream featureSeed, boolean generateStructures, boolean bonusChest, Optional<String> legacyCustomOptions) {
+ this(seed, featureSeed.toArray(), generateStructures, bonusChest, legacyCustomOptions);
}
+ // DivineMC end - Implement Secure Seed
public static WorldOptions testWorldWithRandomSeed() {
return new WorldOptions(randomSeed(), false, false);
@@ -43,10 +66,27 @@ public class WorldOptions {
this.legacyCustomOptions = legacyCustomOptions;
}
+ // DivineMC start - Implement Secure Seed
+ private WorldOptions(long seed, long[] featureSeed, boolean generateStructures, boolean bonusChest, Optional<String> legacyCustomOptions) {
+ this(seed, generateStructures, bonusChest, legacyCustomOptions);
+ this.featureSeed = featureSeed;
+ }
+ // DivineMC end - Implement Secure Seed
+
public long seed() {
return this.seed;
}
+ // DivineMC start - Implement Secure Seed
+ public long[] featureSeed() {
+ return this.featureSeed;
+ }
+
+ public java.util.stream.LongStream featureSeedStream() {
+ return java.util.stream.LongStream.of(this.featureSeed);
+ }
+ // DivineMC end - Implement Secure Seed
+
public boolean generateStructures() {
return this.generateStructures;
}
@@ -59,17 +99,25 @@ public class WorldOptions {
return this.legacyCustomOptions.isPresent();
}
+ // DivineMC start - Implement Secure Seed
public WorldOptions withBonusChest(boolean generateBonusChest) {
- return new WorldOptions(this.seed, this.generateStructures, generateBonusChest, this.legacyCustomOptions);
+ return isSecureSeedEnabled
+ ? new WorldOptions(this.seed, this.featureSeed, this.generateStructures, generateBonusChest, this.legacyCustomOptions)
+ : new WorldOptions(this.seed, this.generateStructures, generateBonusChest, this.legacyCustomOptions);
}
public WorldOptions withStructures(boolean generateStructures) {
- return new WorldOptions(this.seed, generateStructures, this.generateBonusChest, this.legacyCustomOptions);
+ return isSecureSeedEnabled
+ ? new WorldOptions(this.seed, this.featureSeed, generateStructures, this.generateBonusChest, this.legacyCustomOptions)
+ : new WorldOptions(this.seed, generateStructures, this.generateBonusChest, this.legacyCustomOptions);
}
public WorldOptions withSeed(OptionalLong seed) {
- return new WorldOptions(seed.orElse(randomSeed()), this.generateStructures, this.generateBonusChest, this.legacyCustomOptions);
+ return isSecureSeedEnabled
+ ? new WorldOptions(seed.orElse(randomSeed()), space.bxteam.divinemc.seed.Globals.createRandomWorldSeed(), this.generateStructures, this.generateBonusChest, this.legacyCustomOptions)
+ : new WorldOptions(seed.orElse(randomSeed()), this.generateStructures, this.generateBonusChest, this.legacyCustomOptions);
}
+ // DivineMC end - Implement Secure Seed
public static OptionalLong parseSeed(String seed) {
seed = seed.trim();
diff --git a/net/minecraft/world/level/levelgen/feature/GeodeFeature.java b/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
index 38475f6975533909924c8d54f438cf43cdfe31a3..528a69cf7c1f0f31988cc3902f41559826c4d27d 100644
--- a/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
+++ b/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
@@ -41,7 +41,11 @@ public class GeodeFeature extends Feature<GeodeConfiguration> {
int i1 = geodeConfiguration.maxGenOffset;
List<Pair<BlockPos, Integer>> list = Lists.newLinkedList();
int i2 = geodeConfiguration.distributionPoints.sample(randomSource);
- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(worldGenLevel.getSeed()));
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom worldgenRandom = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
+ ? new space.bxteam.divinemc.seed.WorldgenCryptoRandom(0, 0, space.bxteam.divinemc.seed.Globals.Salt.GEODE_FEATURE, 0)
+ : new WorldgenRandom(new LegacyRandomSource(worldGenLevel.getSeed()));
+ // DivineMC end - Implement Secure Seed
NormalNoise normalNoise = NormalNoise.create(worldgenRandom, -4, 1.0);
List<BlockPos> list1 = Lists.newLinkedList();
double d = (double)i2 / geodeConfiguration.outerWallDistance.getMaxValue();
diff --git a/net/minecraft/world/level/levelgen/structure/Structure.java b/net/minecraft/world/level/levelgen/structure/Structure.java
index 8328e864c72b7a358d6bb1f33459b8c4df2ecb1a..c8bf9b3c08903b95dd92c5eb7135d3426580c004 100644
--- a/net/minecraft/world/level/levelgen/structure/Structure.java
+++ b/net/minecraft/world/level/levelgen/structure/Structure.java
@@ -249,6 +249,14 @@ public abstract class Structure {
}
private static WorldgenRandom makeRandom(long seed, ChunkPos chunkPos) {
+ // DivineMC start - Implement Secure Seed
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ return new space.bxteam.divinemc.seed.WorldgenCryptoRandom(
+ chunkPos.x, chunkPos.z, space.bxteam.divinemc.seed.Globals.Salt.GENERATE_FEATURE, seed
+ );
+ }
+ // DivineMC end - Implement Secure Seed
+
WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
worldgenRandom.setLargeFeatureSeed(seed, chunkPos.x, chunkPos.z);
return worldgenRandom;
diff --git a/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java b/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java
index ee0d9dddb36b6879fa113299e24f1aa3b2b151cc..3859e80ef432a27df09fe89ef25e0a401cf970b5 100644
--- a/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java
+++ b/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java
@@ -67,8 +67,17 @@ public class RandomSpreadStructurePlacement extends StructurePlacement {
public ChunkPos getPotentialStructureChunk(long seed, int regionX, int regionZ) {
int i = Math.floorDiv(regionX, this.spacing);
int i1 = Math.floorDiv(regionZ, this.spacing);
- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
- worldgenRandom.setLargeFeatureWithSalt(seed, i, i1, this.salt());
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom worldgenRandom;
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ worldgenRandom = new space.bxteam.divinemc.seed.WorldgenCryptoRandom(
+ i, i1, space.bxteam.divinemc.seed.Globals.Salt.POTENTIONAL_FEATURE, this.salt
+ );
+ } else {
+ worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
+ worldgenRandom.setLargeFeatureWithSalt(seed, i, i1, this.salt());
+ }
+ // DivineMC end - Implement Secure Seed
int i2 = this.spacing - this.separation;
int i3 = this.spreadType.evaluate(worldgenRandom, i2);
int i4 = this.spreadType.evaluate(worldgenRandom, i2);
diff --git a/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java b/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
index 670335a7bbfbc9da64c389977498c22dfcd03251..7b49200486e59a6546aa50d098492280e51d5873 100644
--- a/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
+++ b/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
@@ -118,8 +118,17 @@ public abstract class StructurePlacement {
public abstract StructurePlacementType<?> type();
private static boolean probabilityReducer(long levelSeed, int regionX, int regionZ, int salt, float probability, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs; ignore here
- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
- worldgenRandom.setLargeFeatureWithSalt(levelSeed, regionX, regionZ, salt);
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom worldgenRandom;
+ if (space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed) {
+ worldgenRandom = new space.bxteam.divinemc.seed.WorldgenCryptoRandom(
+ regionX, regionZ, space.bxteam.divinemc.seed.Globals.Salt.UNDEFINED, salt
+ );
+ } else {
+ worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
+ worldgenRandom.setLargeFeatureWithSalt(levelSeed, salt, regionX, regionZ);
+ }
+ // DivineMC end - Implement Secure Seed
return worldgenRandom.nextFloat() < probability;
}
diff --git a/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java b/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java
index eb85edaa3b7fab4f11545b0fa8bfea882dedb67d..b9b15705ee20175451cfcac5795939d787ce0cef 100644
--- a/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java
+++ b/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java
@@ -64,7 +64,11 @@ public class JigsawPlacement {
ChunkGenerator chunkGenerator = context.chunkGenerator();
StructureTemplateManager structureTemplateManager = context.structureTemplateManager();
LevelHeightAccessor levelHeightAccessor = context.heightAccessor();
- WorldgenRandom worldgenRandom = context.random();
+ // DivineMC start - Implement Secure Seed
+ WorldgenRandom worldgenRandom = space.bxteam.divinemc.configuration.DivineConfig.enableSecureSeed
+ ? new space.bxteam.divinemc.seed.WorldgenCryptoRandom(context.chunkPos().x, context.chunkPos().z, space.bxteam.divinemc.seed.Globals.Salt.JIGSAW_PLACEMENT, 0)
+ : context.random();
+ // DivineMC end - Implement Secure Seed
Registry<StructureTemplatePool> registry = registryAccess.lookupOrThrow(Registries.TEMPLATE_POOL);
Rotation random = Rotation.getRandom(worldgenRandom);
StructureTemplatePool structureTemplatePool = startPool.unwrapKey()

View File

@@ -0,0 +1,335 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Wed, 15 Jan 2025 19:48:24 +0300
Subject: [PATCH] Multithreaded Tracker
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
index 718487155b923bfffa215b70a12d42681a8ae141..19e98a8d905541f72becd0f61a86cc5c08e09daa 100644
--- a/net/minecraft/server/level/ChunkMap.java
+++ b/net/minecraft/server/level/ChunkMap.java
@@ -250,9 +250,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
final ServerPlayer[] backingSet = inRange.getRawDataUnchecked();
- for (int i = 0, len = inRange.size(); i < len; i++) {
- ++(backingSet[i].mobCounts[index]);
+ // DivineMC start - Multithreaded tracker
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled) {
+ for (int i = 0, len = inRange.size(); i < len; i++) {
+ final ServerPlayer player = backingSet[i];
+ if (player == null) continue;
+ ++(player.mobCounts[index]);
+ }
+ } else {
+ for (int i = 0, len = inRange.size(); i < len; i++) {
+ ++(backingSet[i].mobCounts[index]);
+ }
}
+ // DivineMC end - Multithreaded tracker
}
// Paper start - per player mob count backoff
@@ -936,6 +946,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$setTrackedEntity(null); // Paper - optimise entity tracker
}
+ // DivineMC start - Multithreaded tracker
+ private final java.util.concurrent.ConcurrentLinkedQueue<Runnable> trackerMainThreadTasks = new java.util.concurrent.ConcurrentLinkedQueue<>();
+ private boolean tracking = false;
+
+ public void runOnTrackerMainThread(final Runnable runnable) {
+ //final boolean isOnMain = ca.spottedleaf.moonrise.common.util.TickThread.isTickThread();
+ //System.out.println(isOnMain);
+ if (false && this.tracking) { // TODO: check here
+ this.trackerMainThreadTasks.add(runnable);
+ } else {
+ runnable.run();
+ }
+ }
+ // DivineMC end - Multithreaded tracker
+
// Paper start - optimise entity tracker
private void newTrackerTick() {
final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup entityLookup = (ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup)((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getEntityLookup();;
@@ -958,6 +983,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper end - optimise entity tracker
protected void tick() {
+ // DivineMC start - Multithreaded tracker
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled) {
+ final ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel level = this.level;
+ space.bxteam.divinemc.tracker.MultithreadedTracker.tick(level);
+ return;
+ }
+ // DivineMC end - Multithreaded tracker
// Paper start - optimise entity tracker
if (true) {
this.newTrackerTick();
@@ -1080,7 +1112,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
final Entity entity;
private final int range;
SectionPos lastSectionPos;
- public final Set<ServerPlayerConnection> seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl
+ // DivineMC start - Multithreaded tracker
+ public final Set<ServerPlayerConnection> seenBy = space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled
+ ? com.google.common.collect.Sets.newConcurrentHashSet()
+ : new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl
+ // DivineMC end - Multithreaded tracker
// Paper start - optimise entity tracker
private long lastChunkUpdate = -1L;
@@ -1107,21 +1143,55 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.lastTrackedChunk = chunk;
final ServerPlayer[] playersRaw = players.getRawDataUnchecked();
+ final int playersLen = players.size(); // Ensure length won't change in the future tasks
+
+ // DivineMC start - Multithreaded tracker
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled && space.bxteam.divinemc.configuration.DivineConfig.multithreadedCompatModeEnabled) {
+ final boolean isServerPlayer = this.entity instanceof ServerPlayer;
+ final boolean isRealPlayer = isServerPlayer && ((ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer) this.entity).moonrise$isRealPlayer();
+ Runnable updatePlayerTasks = () -> {
+ for (int i = 0; i < playersLen; ++i) {
+ final ServerPlayer player = playersRaw[i];
+ this.updatePlayer(player);
+ }
- for (int i = 0, len = players.size(); i < len; ++i) {
- final ServerPlayer player = playersRaw[i];
- this.updatePlayer(player);
- }
+ if (lastChunkUpdate != currChunkUpdate || lastTrackedChunk != chunk) {
+ // need to purge any players possible not in the chunk list
+ for (final ServerPlayerConnection conn : new java.util.ArrayList<>(this.seenBy)) {
+ final ServerPlayer player = conn.getPlayer();
+ if (!players.contains(player)) {
+ this.removePlayer(player);
+ }
+ }
+ }
+ };
+
+ // Only update asynchronously for real player, and sync update for fake players
+ // This can fix compatibility issue with NPC plugins using real entity type, like Citizens
+ // To prevent visible issue with player type NPCs
+ // btw, still recommend to use packet based NPC plugins, like ZNPC Plus, Adyeshach, Fancy NPC, etc.
+ if (isRealPlayer || !isServerPlayer) {
+ space.bxteam.divinemc.tracker.MultithreadedTracker.getTrackerExecutor().execute(updatePlayerTasks);
+ } else {
+ updatePlayerTasks.run();
+ }
+ } else {
+ for (int i = 0, len = players.size(); i < len; ++i) {
+ final ServerPlayer player = playersRaw[i];
+ this.updatePlayer(player);
+ }
- if (lastChunkUpdate != currChunkUpdate || lastTrackedChunk != chunk) {
- // need to purge any players possible not in the chunk list
- for (final ServerPlayerConnection conn : new java.util.ArrayList<>(this.seenBy)) {
- final ServerPlayer player = conn.getPlayer();
- if (!players.contains(player)) {
- this.removePlayer(player);
+ if (lastChunkUpdate != currChunkUpdate || lastTrackedChunk != chunk) {
+ // need to purge any players possible not in the chunk list
+ for (final ServerPlayerConnection conn : new java.util.ArrayList<>(this.seenBy)) {
+ final ServerPlayer player = conn.getPlayer();
+ if (!players.contains(player)) {
+ this.removePlayer(player);
+ }
}
}
}
+ // DivineMC end - Multithreaded tracker
}
@Override
@@ -1183,9 +1253,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
public void broadcast(Packet<?> packet) {
- for (ServerPlayerConnection serverPlayerConnection : this.seenBy) {
+ // DivineMC start - Multithreaded tracker
+ for (ServerPlayerConnection serverPlayerConnection : this.seenBy.toArray(new ServerPlayerConnection[0])) {
serverPlayerConnection.send(packet);
}
+ // DivineMC end - Multithreaded tracker
}
public void broadcastAndSend(Packet<?> packet) {
@@ -1196,9 +1268,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
public void broadcastRemoved() {
- for (ServerPlayerConnection serverPlayerConnection : this.seenBy) {
+ // DivineMC start - Multithreaded tracker
+ for (ServerPlayerConnection serverPlayerConnection : this.seenBy.toArray(new ServerPlayerConnection[0])) {
this.serverEntity.removePairing(serverPlayerConnection.getPlayer());
}
+ // DivineMC end - Multithreaded tracker
}
public void removePlayer(ServerPlayer player) {
@@ -1209,8 +1283,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
public void updatePlayer(ServerPlayer player) {
- org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
+ //org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // DivineMC - Multithreaded tracker - we don't need this
if (player != this.entity) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled && player == null) return; // DivineMC - Multithreaded tracker
// Paper start - remove allocation of Vec3D here
// Vec3 vec3 = player.position().subtract(this.entity.position());
double vec3_dx = player.getX() - this.entity.getX();
diff --git a/net/minecraft/server/level/ServerBossEvent.java b/net/minecraft/server/level/ServerBossEvent.java
index f106373ef3ac4a8685c2939c9e8361688a285913..7b0663caa87fa91c6eba3b88dfe9fe83a1cf5cbf 100644
--- a/net/minecraft/server/level/ServerBossEvent.java
+++ b/net/minecraft/server/level/ServerBossEvent.java
@@ -13,7 +13,11 @@ import net.minecraft.util.Mth;
import net.minecraft.world.BossEvent;
public class ServerBossEvent extends BossEvent {
- private final Set<ServerPlayer> players = Sets.newHashSet();
+ // DivineMC start - Multithreaded tracker - players can be removed in async tracking
+ private final Set<ServerPlayer> players = space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled
+ ? Sets.newConcurrentHashSet()
+ : Sets.newHashSet();
+ // DivineMC end - Multithreaded tracker
private final Set<ServerPlayer> unmodifiablePlayers = Collections.unmodifiableSet(this.players);
public boolean visible = true;
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
index 6d2c892207c2299c64f59630fb7740d6407e76a7..50195569421527faf7d3a65cb6be3b559936af07 100644
--- a/net/minecraft/server/level/ServerEntity.java
+++ b/net/minecraft/server/level/ServerEntity.java
@@ -110,8 +110,13 @@ public class ServerEntity {
.forEach(
removedPassenger -> {
if (removedPassenger instanceof ServerPlayer serverPlayer1) {
- serverPlayer1.connection
- .teleport(serverPlayer1.getX(), serverPlayer1.getY(), serverPlayer1.getZ(), serverPlayer1.getYRot(), serverPlayer1.getXRot());
+ // DivineMC start - Multithreaded tracker
+ if (space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled && Thread.currentThread() instanceof space.bxteam.divinemc.tracker.MultithreadedTracker.MultithreadedTrackerThread) {
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> serverPlayer1.connection.teleport(serverPlayer1.getX(), serverPlayer1.getY(), serverPlayer1.getZ(), serverPlayer1.getYRot(), serverPlayer1.getXRot()));
+ } else {
+ serverPlayer1.connection.teleport(serverPlayer1.getX(), serverPlayer1.getY(), serverPlayer1.getZ(), serverPlayer1.getYRot(), serverPlayer1.getXRot());
+ }
+ // DivineMC end - Multithreaded tracker
}
}
);
@@ -304,7 +309,11 @@ public class ServerEntity {
public void removePairing(ServerPlayer player) {
this.entity.stopSeenByPlayer(player);
- player.connection.send(new ClientboundRemoveEntitiesPacket(this.entity.getId()));
+ // DivineMC start - Multithreaded tracker - send in main thread
+ ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() ->
+ player.connection.send(new ClientboundRemoveEntitiesPacket(this.entity.getId()))
+ );
+ // DivineMC end - Multithreaded tracker
}
public void addPairing(ServerPlayer player) {
@@ -404,7 +413,11 @@ public class ServerEntity {
List<SynchedEntityData.DataValue<?>> list = entityData.packDirty();
if (list != null) {
this.trackedDataValues = entityData.getNonDefaultValues();
- this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), list));
+ // DivineMC start - Multithreaded tracker - send in main thread
+ ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() ->
+ this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), list))
+ );
+ // DivineMC end - Multithreaded tracker
}
if (this.entity instanceof LivingEntity) {
@@ -413,12 +426,17 @@ public class ServerEntity {
final Set<AttributeInstance> attributesToSync = this.level.divinemcConfig.suppressErrorsFromDirtyAttributes ? Collections.synchronizedSet(attributes) : attributes;
// DivineMC end - Suppress errors from dirty attributes
if (!attributesToSync.isEmpty()) {
- // CraftBukkit start - Send scaled max health
- if (this.entity instanceof ServerPlayer serverPlayer) {
- serverPlayer.getBukkitEntity().injectScaledMaxHealth(attributesToSync, false);
- }
- // CraftBukkit end
- this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), attributesToSync));
+ // DivineMC start - Multithreaded tracker
+ final Set<AttributeInstance> copy = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(attributesToSync);
+ ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() -> {
+ // CraftBukkit start - Send scaled max health
+ if (this.entity instanceof ServerPlayer serverPlayer) {
+ serverPlayer.getBukkitEntity().injectScaledMaxHealth(copy, false);
+ }
+ // CraftBukkit end
+ this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), copy));
+ });
+ // DivineMC end - Multithreaded tracker
}
attributes.clear();
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 8127a71fd7d45541525be75e6699c2a5bae95f5f..e6a55f6fa9f4b827d14ae29c82cb7e30cfa5d56a 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -2512,7 +2512,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@Override
public LevelEntityGetter<Entity> getEntities() {
- org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot
+ //org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // DivineMC - Multithreaded tracker
return this.moonrise$getEntityLookup(); // Paper - rewrite chunk system
}
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index b2f2682c44eeed9ed4f5421113cc7cc704454ba5..33730967df54467b2f046f66a1590c7069e44c5d 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1806,7 +1806,7 @@ public class ServerGamePacketListenerImpl
}
public void internalTeleport(PositionMoveRotation posMoveRotation, Set<Relative> relatives) {
- org.spigotmc.AsyncCatcher.catchOp("teleport"); // Paper
+ //org.spigotmc.AsyncCatcher.catchOp("teleport"); // DivineMC - Multithreaded tracker
// Paper start - Prevent teleporting dead entities
if (this.player.isRemoved()) {
LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName());
diff --git a/net/minecraft/world/entity/ai/attributes/AttributeInstance.java b/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
index 8013594bb4844e7a8abf28123958e7f632d39341..55a2777ed76baef8fa6ed899e96028db0d4682f8 100644
--- a/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
+++ b/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
@@ -24,8 +24,11 @@ public class AttributeInstance {
private final Map<AttributeModifier.Operation, Map<ResourceLocation, AttributeModifier>> modifiersByOperation = Maps.newEnumMap(
AttributeModifier.Operation.class
);
- private final Map<ResourceLocation, AttributeModifier> modifierById = new Object2ObjectArrayMap<>();
- private final Map<ResourceLocation, AttributeModifier> permanentModifiers = new Object2ObjectArrayMap<>();
+ // DivineMC start - Multithreaded tracker
+ private final boolean multiThreadedTrackingEnabled = space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled;
+ private final Map<ResourceLocation, AttributeModifier> modifierById = multiThreadedTrackingEnabled ? new java.util.concurrent.ConcurrentHashMap<>() : new Object2ObjectArrayMap<>();
+ private final Map<ResourceLocation, AttributeModifier> permanentModifiers = multiThreadedTrackingEnabled ? new java.util.concurrent.ConcurrentHashMap<>() : new Object2ObjectArrayMap<>();
+ // DivineMC end - Multithreaded tracker
private double baseValue;
private boolean dirty = true;
private double cachedValue;
diff --git a/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/net/minecraft/world/entity/ai/attributes/AttributeMap.java
index a25d74592e89e3d6339479c6dc2b6f45d1932cfc..328474691eb42505cd535494c04fab0bdeb0a953 100644
--- a/net/minecraft/world/entity/ai/attributes/AttributeMap.java
+++ b/net/minecraft/world/entity/ai/attributes/AttributeMap.java
@@ -19,9 +19,12 @@ import org.slf4j.Logger;
public class AttributeMap {
private static final Logger LOGGER = LogUtils.getLogger();
- private final Map<Holder<Attribute>, AttributeInstance> attributes = new Object2ObjectOpenHashMap<>();
- private final Set<AttributeInstance> attributesToSync = new ObjectOpenHashSet<>();
- private final Set<AttributeInstance> attributesToUpdate = new ObjectOpenHashSet<>();
+ // DivineMC start - Multithreaded tracker
+ private final boolean multiThreadedTrackingEnabled = space.bxteam.divinemc.configuration.DivineConfig.multithreadedEnabled;
+ private final Map<Holder<Attribute>, AttributeInstance> attributes = multiThreadedTrackingEnabled ? new java.util.concurrent.ConcurrentHashMap<>() : new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(0);
+ private final Set<AttributeInstance> attributesToSync = multiThreadedTrackingEnabled ? com.google.common.collect.Sets.newConcurrentHashSet() : new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0);
+ private final Set<AttributeInstance> attributesToUpdate = multiThreadedTrackingEnabled ? com.google.common.collect.Sets.newConcurrentHashSet() : new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0);
+ // DivineMC end - Multithreaded tracker
private final AttributeSupplier supplier;
private final net.minecraft.world.entity.LivingEntity entity; // Purpur - Ridables

View File

@@ -0,0 +1,365 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sat, 18 Jan 2025 01:00:23 +0300
Subject: [PATCH] Implement Linear region format
Linear is a region file format that uses ZSTD compression instead of ZLIB. This format saves about 50% of disk space.
Documentation: https://github.com/xymb-endcrystalme/LinearRegionFileFormatTools
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java b/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java
index a814512fcfb85312474ae2c2c21443843bf57831..c2bc8464cf3f1722394d55d91f638f576ee47f49 100644
--- a/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java
@@ -8,9 +8,9 @@ public interface ChunkSystemRegionFileStorage {
public boolean moonrise$doesRegionFileNotExistNoIO(final int chunkX, final int chunkZ);
- public RegionFile moonrise$getRegionFileIfLoaded(final int chunkX, final int chunkZ);
+ public space.bxteam.divinemc.region.AbstractRegionFile moonrise$getRegionFileIfLoaded(final int chunkX, final int chunkZ); // DivineMC - linear region format
- public RegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException;
+ public space.bxteam.divinemc.region.AbstractRegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException; // DivineMC - linear region format
public MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite(
final int chunkX, final int chunkZ, final CompoundTag compound
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
index 1acea58838f057ab87efd103cbecb6f5aeaef393..4fcf988346b8bf60ac0ad1165e18ed86fe52fd2d 100644
--- a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
@@ -1462,7 +1462,7 @@ public final class MoonriseRegionFileIO {
public static interface IORunnable {
- public void run(final RegionFile regionFile) throws IOException;
+ public void run(final space.bxteam.divinemc.region.AbstractRegionFile regionFile) throws IOException; // DivineMC - linear region format
}
}
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java b/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java
index 51c126735ace8fdde89ad97b5cab62f244212db0..cf497c3919a1d5114a18474f04ccce182a6b7e0b 100644
--- a/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java
@@ -8,5 +8,5 @@ public interface ChunkSystemChunkBuffer {
public void moonrise$setWriteOnClose(final boolean value);
- public void moonrise$write(final RegionFile regionFile) throws IOException;
+ public void moonrise$write(final space.bxteam.divinemc.region.AbstractRegionFile regionFile) throws IOException; // DivineMC - linear region format
}
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index d04c06fafd133f773f311e7c2708fa8b049da67c..b3f2e7bb4519cc078d3cede11bce232f1255c6a0 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -950,10 +950,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// CraftBukkit end
if (flush) {
for (ServerLevel serverLevel2 : this.getAllLevels()) {
- LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", serverLevel2.getChunkSource().chunkMap.getStorageName());
+ LOGGER.info("ThreadedChunkStorage ({}): All chunks are saved", serverLevel2.getChunkSource().chunkMap.getStorageName()); // DivineMC - linear region format
}
- LOGGER.info("ThreadedAnvilChunkStorage: All dimensions are saved");
+ LOGGER.info("ThreadedChunkStorage: All dimensions are saved"); // DivineMC - linear region format
}
return flag;
diff --git a/net/minecraft/util/worldupdate/WorldUpgrader.java b/net/minecraft/util/worldupdate/WorldUpgrader.java
index e0bcda2ddea0d6633445a7440fbf0d18e50a7653..6509662ee5de204f7ecf58f533d8d2cb38f67e97 100644
--- a/net/minecraft/util/worldupdate/WorldUpgrader.java
+++ b/net/minecraft/util/worldupdate/WorldUpgrader.java
@@ -72,7 +72,7 @@ public class WorldUpgrader implements AutoCloseable {
volatile int skipped;
final Reference2FloatMap<ResourceKey<Level>> progressMap = Reference2FloatMaps.synchronize(new Reference2FloatOpenHashMap<>());
volatile Component status = Component.translatable("optimizeWorld.stage.counting");
- static final Pattern REGEX = Pattern.compile("^r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.mca$");
+ static final Pattern REGEX = Pattern.compile("^r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.(linear | mca)$"); // DivineMC - linear region format
final DimensionDataStorage overworldDataStorage;
public WorldUpgrader(
@@ -261,7 +261,7 @@ public class WorldUpgrader implements AutoCloseable {
}
private static List<WorldUpgrader.FileToUpgrade> getAllChunkPositions(RegionStorageInfo regionStorageInfo, Path path) {
- File[] files = path.toFile().listFiles((directory, filename) -> filename.endsWith(".mca"));
+ File[] files = path.toFile().listFiles((directory, filename) -> filename.endsWith(".linear") || filename.endsWith(".mca")); // DivineMC - linear region format
if (files == null) {
return List.of();
} else {
@@ -274,7 +274,7 @@ public class WorldUpgrader implements AutoCloseable {
int i1 = Integer.parseInt(matcher.group(2)) << 5;
List<ChunkPos> list1 = Lists.newArrayList();
- try (RegionFile regionFile = new RegionFile(regionStorageInfo, file.toPath(), path, true)) {
+ try (space.bxteam.divinemc.region.AbstractRegionFile regionFile = space.bxteam.divinemc.region.AbstractRegionFileFactory.getAbstractRegionFile(regionStorageInfo, file.toPath(), path, true)) { // DivineMC - linear region format
for (int i2 = 0; i2 < 32; i2++) {
for (int i3 = 0; i3 < 32; i3++) {
ChunkPos chunkPos = new ChunkPos(i2 + i, i3 + i1);
@@ -322,7 +322,7 @@ public class WorldUpgrader implements AutoCloseable {
protected abstract boolean tryProcessOnePosition(T chunkStorage, ChunkPos chunkPos, ResourceKey<Level> dimension);
- private void onFileFinished(RegionFile regionFile) {
+ private void onFileFinished(space.bxteam.divinemc.region.AbstractRegionFile regionFile) { // DivineMC - linear region format
if (WorldUpgrader.this.recreateRegionFiles) {
if (this.previousWriteFuture != null) {
this.previousWriteFuture.join();
@@ -424,7 +424,7 @@ public class WorldUpgrader implements AutoCloseable {
}
}
- record FileToUpgrade(RegionFile file, List<ChunkPos> chunksToUpgrade) {
+ record FileToUpgrade(space.bxteam.divinemc.region.AbstractRegionFile file, List<ChunkPos> chunksToUpgrade) { // DivineMC - linear region format
}
class PoiUpgrader extends WorldUpgrader.SimpleRegionStorageUpgrader {
diff --git a/net/minecraft/world/level/chunk/storage/RegionFile.java b/net/minecraft/world/level/chunk/storage/RegionFile.java
index c72494e757a9dc50e053dbc873f7b30e83d5cb8c..236035219dd2442592bb94994a44fab712b5ca9d 100644
--- a/net/minecraft/world/level/chunk/storage/RegionFile.java
+++ b/net/minecraft/world/level/chunk/storage/RegionFile.java
@@ -22,7 +22,7 @@ import net.minecraft.util.profiling.jfr.JvmProfiler;
import net.minecraft.world.level.ChunkPos;
import org.slf4j.Logger;
-public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile { // Paper - rewrite chunk system
+public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile, space.bxteam.divinemc.region.AbstractRegionFile { // Paper - rewrite chunk system // DivineMC - linear region format
private static final Logger LOGGER = LogUtils.getLogger();
public static final int MAX_CHUNK_SIZE = 500 * 1024 * 1024; // Paper - don't write garbage data to disk if writing serialization fails
private static final int SECTOR_BYTES = 4096;
@@ -904,7 +904,7 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
}
@Override
- public final void moonrise$write(final RegionFile regionFile) throws IOException {
+ public final void moonrise$write(final space.bxteam.divinemc.region.AbstractRegionFile regionFile) throws IOException { // DivineMC - linear region format
regionFile.write(this.pos, ByteBuffer.wrap(this.buf, 0, this.count));
}
// Paper end - rewrite chunk system
diff --git a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
index 6ebd1300c2561116b83cb2472ac7939ead36d576..6da756cb0a406a76151a5b2f624e08592f35d835 100644
--- a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -18,7 +18,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
private static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); // Paper
public static final String ANVIL_EXTENSION = ".mca";
private static final int MAX_CACHE_SIZE = 256;
- public final Long2ObjectLinkedOpenHashMap<RegionFile> regionCache = new Long2ObjectLinkedOpenHashMap<>();
+ public final Long2ObjectLinkedOpenHashMap<space.bxteam.divinemc.region.AbstractRegionFile> regionCache = new Long2ObjectLinkedOpenHashMap<>(); // DivineMC - linear region format
private final RegionStorageInfo info;
private final Path folder;
private final boolean sync;
@@ -33,7 +33,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
@Nullable
public static ChunkPos getRegionFileCoordinates(Path file) {
String fileName = file.getFileName().toString();
- if (!fileName.startsWith("r.") || !fileName.endsWith(".mca")) {
+ if (!fileName.startsWith("r.") || !fileName.endsWith(".mca") || !fileName.endsWith(".linear")) { // DivineMC - linear region format
return null;
}
@@ -57,9 +57,14 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
private static final int REGION_SHIFT = 5;
private static final int MAX_NON_EXISTING_CACHE = 1024 * 4;
private final it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet nonExistingRegionFiles = new it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet();
- private static String getRegionFileName(final int chunkX, final int chunkZ) {
+ // DivineMC start - Linear region format
+ private static String getRegionFileName(final RegionStorageInfo info, final int chunkX, final int chunkZ) {
+ if (info.regionFormat().equals(space.bxteam.divinemc.region.RegionFileFormat.LINEAR)) {
+ return "r." + (chunkX >> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + ".linear";
+ }
return "r." + (chunkX >> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + ".mca";
}
+ // DivineMC end - Linear region format
private boolean doesRegionFilePossiblyExist(final long position) {
synchronized (this.nonExistingRegionFiles) {
@@ -93,15 +98,15 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
}
@Override
- public synchronized final RegionFile moonrise$getRegionFileIfLoaded(final int chunkX, final int chunkZ) {
+ public synchronized final space.bxteam.divinemc.region.AbstractRegionFile moonrise$getRegionFileIfLoaded(final int chunkX, final int chunkZ) { // DivineMC - linear region format
return this.regionCache.getAndMoveToFirst(ChunkPos.asLong(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT));
}
@Override
- public synchronized final RegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException {
+ public synchronized final space.bxteam.divinemc.region.AbstractRegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException { // DivineMC - linear region format
final long key = ChunkPos.asLong(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT);
- RegionFile ret = this.regionCache.getAndMoveToFirst(key);
+ space.bxteam.divinemc.region.AbstractRegionFile ret = this.regionCache.getAndMoveToFirst(key); // DivineMC - linear region format
if (ret != null) {
return ret;
}
@@ -114,7 +119,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
this.regionCache.removeLast().close();
}
- final Path regionPath = this.folder.resolve(getRegionFileName(chunkX, chunkZ));
+ final Path regionPath = this.folder.resolve(getRegionFileName(this.info, chunkX, chunkZ)); // DivineMC - linear region format
if (!java.nio.file.Files.exists(regionPath)) {
this.markNonExisting(key);
@@ -125,7 +130,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
FileUtil.createDirectoriesSafe(this.folder);
- ret = new RegionFile(this.info, regionPath, this.folder, this.sync);
+ ret = space.bxteam.divinemc.region.AbstractRegionFileFactory.getAbstractRegionFile(this.info, regionPath, this.folder, this.sync); // DivineMC - linear region format
this.regionCache.putAndMoveToFirst(key, ret);
@@ -144,11 +149,11 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
}
final ChunkPos pos = new ChunkPos(chunkX, chunkZ);
- final RegionFile regionFile = this.getRegionFile(pos);
+ final space.bxteam.divinemc.region.AbstractRegionFile regionFile = this.getRegionFile(pos); // DivineMC - linear region format
// note: not required to keep regionfile loaded after this call, as the write param takes a regionfile as input
// (and, the regionfile parameter is unused for writing until the write call)
- final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData writeData = ((ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile)regionFile).moonrise$startWrite(compound, pos);
+ final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData writeData = regionFile.moonrise$startWrite(compound, pos); // DivineMC - linear region format
try { // Paper - implement RegionFileSizeException
try {
@@ -178,7 +183,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
) throws IOException {
final ChunkPos pos = new ChunkPos(chunkX, chunkZ);
if (writeData.result() == ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData.WriteResult.DELETE) {
- final RegionFile regionFile = this.moonrise$getRegionFileIfExists(chunkX, chunkZ);
+ final space.bxteam.divinemc.region.AbstractRegionFile regionFile = this.moonrise$getRegionFileIfExists(chunkX, chunkZ); // DivineMC - linear region format
if (regionFile != null) {
regionFile.clear(pos);
} // else: didn't exist
@@ -193,7 +198,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData moonrise$readData(
final int chunkX, final int chunkZ
) throws IOException {
- final RegionFile regionFile = this.moonrise$getRegionFileIfExists(chunkX, chunkZ);
+ final space.bxteam.divinemc.region.AbstractRegionFile regionFile = this.moonrise$getRegionFileIfExists(chunkX, chunkZ); // DivineMC - linear region format
final DataInputStream input = regionFile == null ? null : regionFile.getChunkDataInputStream(new ChunkPos(chunkX, chunkZ));
@@ -237,7 +242,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
}
// Paper end - rewrite chunk system
// Paper start - rewrite chunk system
- public RegionFile getRegionFile(ChunkPos chunkcoordintpair) throws IOException {
+ public space.bxteam.divinemc.region.AbstractRegionFile getRegionFile(ChunkPos chunkcoordintpair) throws IOException { // DivineMC - linear region format
return this.getRegionFile(chunkcoordintpair, false);
}
// Paper end - rewrite chunk system
@@ -249,7 +254,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
this.isChunkData = isChunkDataFolder(this.folder); // Paper - recalculate region file headers
}
- @org.jetbrains.annotations.Contract("_, false -> !null") @Nullable private RegionFile getRegionFile(ChunkPos chunkPos, boolean existingOnly) throws IOException { // CraftBukkit
+ @org.jetbrains.annotations.Contract("_, false -> !null") @Nullable private space.bxteam.divinemc.region.AbstractRegionFile getRegionFile(ChunkPos chunkPos, boolean existingOnly) throws IOException { // CraftBukkit // DivineMC - linear region format
// Paper start - rewrite chunk system
if (existingOnly) {
return this.moonrise$getRegionFileIfExists(chunkPos.x, chunkPos.z);
@@ -257,7 +262,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
synchronized (this) {
final long key = ChunkPos.asLong(chunkPos.x >> REGION_SHIFT, chunkPos.z >> REGION_SHIFT);
- RegionFile ret = this.regionCache.getAndMoveToFirst(key);
+ space.bxteam.divinemc.region.AbstractRegionFile ret = this.regionCache.getAndMoveToFirst(key); // DivineMC - linear region format
if (ret != null) {
return ret;
}
@@ -266,13 +271,13 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
this.regionCache.removeLast().close();
}
- final Path regionPath = this.folder.resolve(getRegionFileName(chunkPos.x, chunkPos.z));
+ final Path regionPath = this.folder.resolve(getRegionFileName(this.info, chunkPos.x, chunkPos.z)); // DivineMC - linear region format
this.createRegionFile(key);
FileUtil.createDirectoriesSafe(this.folder);
- ret = new RegionFile(this.info, regionPath, this.folder, this.sync);
+ ret = space.bxteam.divinemc.region.AbstractRegionFileFactory.getAbstractRegionFile(this.info, regionPath, this.folder, this.sync); // DivineMC - linear region format
this.regionCache.putAndMoveToFirst(key, ret);
@@ -286,7 +291,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO DIVINEMC - You may ask for help on Discord, but do not file an issue. These error messages can not be removed."); // DivineMC - Rebrand
}
- private static CompoundTag readOversizedChunk(RegionFile regionfile, ChunkPos chunkCoordinate) throws IOException {
+ private static CompoundTag readOversizedChunk(space.bxteam.divinemc.region.AbstractRegionFile regionfile, ChunkPos chunkCoordinate) throws IOException {
synchronized (regionfile) {
try (DataInputStream datainputstream = regionfile.getChunkDataInputStream(chunkCoordinate)) {
CompoundTag oversizedData = regionfile.getOversizedData(chunkCoordinate.x, chunkCoordinate.z);
@@ -321,7 +326,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
@Nullable
public CompoundTag read(ChunkPos chunkPos) throws IOException {
// CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing
- RegionFile regionFile = this.getRegionFile(chunkPos, true);
+ space.bxteam.divinemc.region.AbstractRegionFile regionFile = this.getRegionFile(chunkPos, true); // DivineMC - linear region format
if (regionFile == null) {
return null;
}
@@ -360,7 +365,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
public void scanChunk(ChunkPos chunkPos, StreamTagVisitor visitor) throws IOException {
// CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing
- RegionFile regionFile = this.getRegionFile(chunkPos, true);
+ space.bxteam.divinemc.region.AbstractRegionFile regionFile = this.getRegionFile(chunkPos, true); // DivineMC - linear region format
if (regionFile == null) {
return;
}
@@ -374,7 +379,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
}
public void write(ChunkPos chunkPos, @Nullable CompoundTag chunkData) throws IOException { // Paper - rewrite chunk system - public
- RegionFile regionFile = this.getRegionFile(chunkPos, chunkData == null); // CraftBukkit // Paper - rewrite chunk system
+ space.bxteam.divinemc.region.AbstractRegionFile regionFile = this.getRegionFile(chunkPos, chunkData == null); // CraftBukkit // Paper - rewrite chunk system // DivineMC - linear region format
// Paper start - rewrite chunk system
if (regionFile == null) {
// if the RegionFile doesn't exist, no point in deleting from it
@@ -404,7 +409,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
// Paper start - rewrite chunk system
synchronized (this) {
final ExceptionCollector<IOException> exceptionCollector = new ExceptionCollector<>();
- for (final RegionFile regionFile : this.regionCache.values()) {
+ for (final space.bxteam.divinemc.region.AbstractRegionFile regionFile : this.regionCache.values()) { // DivineMC - linear region format
try {
regionFile.close();
} catch (final IOException ex) {
@@ -420,7 +425,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
// Paper start - rewrite chunk system
synchronized (this) {
final ExceptionCollector<IOException> exceptionCollector = new ExceptionCollector<>();
- for (final RegionFile regionFile : this.regionCache.values()) {
+ for (final space.bxteam.divinemc.region.AbstractRegionFile regionFile : this.regionCache.values()) { // DivineMC - linear region format
try {
regionFile.flush();
} catch (final IOException ex) {
diff --git a/net/minecraft/world/level/chunk/storage/RegionStorageInfo.java b/net/minecraft/world/level/chunk/storage/RegionStorageInfo.java
index 6111631c6673948b266286894603cc5e30451b02..b49781472b34176503505e2cf2fbfd99f1d24e48 100644
--- a/net/minecraft/world/level/chunk/storage/RegionStorageInfo.java
+++ b/net/minecraft/world/level/chunk/storage/RegionStorageInfo.java
@@ -7,4 +7,20 @@ public record RegionStorageInfo(String level, ResourceKey<Level> dimension, Stri
public RegionStorageInfo withTypeSuffix(String suffix) {
return new RegionStorageInfo(this.level, this.dimension, this.type + suffix);
}
+
+ // DivineMC start - Linear Region format
+ public space.bxteam.divinemc.region.RegionFileFormat regionFormat() {
+ return ((org.bukkit.craftbukkit.CraftWorld) org.bukkit.Bukkit.getWorld(level))
+ .getHandle()
+ .divinemcConfig
+ .regionFormatName;
+ }
+
+ public int linearCompressionLevel() {
+ return ((org.bukkit.craftbukkit.CraftWorld) org.bukkit.Bukkit.getWorld(level))
+ .getHandle()
+ .divinemcConfig
+ .linearCompressionLevel;
+ }
+ // DivineMC end - Linear Region format
}

View File

@@ -0,0 +1,42 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sat, 18 Jan 2025 15:44:29 +0300
Subject: [PATCH] Snowball and Egg knockback
diff --git a/net/minecraft/world/entity/projectile/Snowball.java b/net/minecraft/world/entity/projectile/Snowball.java
index 1d399532c67c213c95c06837b0c7855384f1a25c..9e9afd77ba50c2ab06e97f1c80b1290fb8f91715 100644
--- a/net/minecraft/world/entity/projectile/Snowball.java
+++ b/net/minecraft/world/entity/projectile/Snowball.java
@@ -54,6 +54,12 @@ public class Snowball extends ThrowableItemProjectile {
Entity entity = result.getEntity();
int i = entity.level().purpurConfig.snowballDamage >= 0 ? entity.level().purpurConfig.snowballDamage : entity instanceof Blaze ? 3 : 0; // Purpur - Add configurable snowball damage
entity.hurt(this.damageSources().thrown(this, this.getOwner()), i);
+ // DivineMC start - Make snowball can knockback player
+ if (this.level().divinemcConfig.snowballCanKnockback && entity instanceof net.minecraft.server.level.ServerPlayer serverPlayer) {
+ entity.hurt(this.damageSources().thrown(this, this.getOwner()), 0.0000001F);
+ serverPlayer.knockback(0.4000000059604645D, this.getX() - entity.getX(), this.getZ() - entity.getZ());
+ }
+ // DivineMC end - Make snowball can knockback player
}
// Purpur start - options to extinguish fire blocks with snowballs - borrowed and modified code from ThrownPotion#onHitBlock and ThrownPotion#dowseFire
diff --git a/net/minecraft/world/entity/projectile/ThrownEgg.java b/net/minecraft/world/entity/projectile/ThrownEgg.java
index 76481c0e77fc3a2e4be8eeb9de8d1e6de5507c64..7165bad72f761a0a3b2168d6df5f154b4a82d74e 100644
--- a/net/minecraft/world/entity/projectile/ThrownEgg.java
+++ b/net/minecraft/world/entity/projectile/ThrownEgg.java
@@ -52,7 +52,14 @@ public class ThrownEgg extends ThrowableItemProjectile {
@Override
protected void onHitEntity(EntityHitResult result) {
super.onHitEntity(result);
+ net.minecraft.world.entity.Entity entity = result.getEntity(); // DivineMC - make egg can knockback player
result.getEntity().hurt(this.damageSources().thrown(this, this.getOwner()), 0.0F);
+ // DivineMC start - Make egg can knockback player
+ if (this.level().divinemcConfig.eggCanKnockback && entity instanceof net.minecraft.server.level.ServerPlayer serverPlayer) {
+ entity.hurt(this.damageSources().thrown(this, this.getOwner()), 0.0000001F);
+ serverPlayer.knockback(0.4000000059604645D, this.getX() - entity.getX(), this.getZ() - entity.getZ());
+ }
+ // DivineMC end - Make egg can knockback player
}
@Override

View File

@@ -1,15 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Fri, 21 Jun 2024 04:19:11 +0300
Subject: [PATCH] Parchment: Make FixLight use action bar
Original project: https://github.com/ProjectEdenGG/Parchment
diff --git a/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java b/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java
index 85950a1aa732ab8c01ad28bec9e0de140e1a172e..a6df6eeeda88c50894e03742e25aa5652a770ba9 100644
--- a/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java
+++ b/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java
@@ -95,17 +95,20 @@ public final class FixLightCommand implements PaperSubcommand {
--- a/io/papermc/paper/command/subcommands/FixLightCommand.java
+++ b/io/papermc/paper/command/subcommands/FixLightCommand.java
@@ -95,17 +_,22 @@
((StarLightLightingProvider)lightengine).starlight$serverRelightChunks(chunks,
(final ChunkPos chunkPos) -> {
++relitChunks[0];
@@ -17,13 +8,14 @@ index 85950a1aa732ab8c01ad28bec9e0de140e1a172e..a6df6eeeda88c50894e03742e25aa565
- text("Relit chunk ", BLUE), text(chunkPos.toString()),
- text(", progress: ", BLUE), text(ONE_DECIMAL_PLACES.get().format(100.0 * (double) (relitChunks[0]) / (double) pending[0]) + "%")
- ));
+ // DivineMC start - Make FixLight use action bar
+ sender.getBukkitEntity().sendActionBar(text().color(DARK_AQUA).append(
+ text("Relighting Chunks: ", DARK_AQUA), text(chunkPos.toString()),
+ text(" " + relitChunks[0], net.kyori.adventure.text.format.NamedTextColor.YELLOW),
+ text("/", DARK_AQUA),
+ text(pending[0] + " ", net.kyori.adventure.text.format.NamedTextColor.YELLOW),
+ text("(" + (int) (Math.round(100.0 * (double) (relitChunks[0]) / (double) pending[0])) + "%)", net.kyori.adventure.text.format.NamedTextColor.YELLOW)
+ )); // DivineMC // Parchment - Make FixLight use action bar
+ )); // DivineMC end - Make FixLight use action bar
},
(final int totalRelit) -> {
final long end = System.nanoTime();
@@ -31,9 +23,10 @@ index 85950a1aa732ab8c01ad28bec9e0de140e1a172e..a6df6eeeda88c50894e03742e25aa565
- text("Relit ", BLUE), text(totalRelit),
- text(" chunks. Took ", BLUE), text(ONE_DECIMAL_PLACES.get().format(1.0e-6 * (end - start)) + "ms")
- ));
+ text("Relit ", DARK_AQUA), text(totalRelit, net.kyori.adventure.text.format.NamedTextColor.YELLOW),
+ text(" chunks. Took ", DARK_AQUA), text(ONE_DECIMAL_PLACES.get().format(1.0e-6 * (end - start)) + "ms", net.kyori.adventure.text.format.NamedTextColor.YELLOW)
+ )); // DivineMC // Parchment - Make FixLight use action bar
+ // DivineMC start - Make FixLight use action bar
+ text("Relit ", DARK_AQUA), text(totalRelit, net.kyori.adventure.text.format.NamedTextColor.YELLOW),
+ text(" chunks. Took ", DARK_AQUA), text(ONE_DECIMAL_PLACES.get().format(1.0e-6 * (end - start)) + "ms", net.kyori.adventure.text.format.NamedTextColor.YELLOW)
+ )); // DivineMC end - Make FixLight use action bar
if (done != null) {
done.run();
}

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -326,7 +_,7 @@
String proxyFlavor = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "Velocity" : "BungeeCord";
String proxyLink = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "https://docs.papermc.io/velocity/security" : "http://www.spigotmc.org/wiki/firewall-guide/";
// Paper end - Add Velocity IP Forwarding Support
- if (!this.usesAuthentication()) {
+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode()) { // DivineMC - if server uses proxy (velocity or bungee), disable offline warning
LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!");
LOGGER.warn("The server will make no attempt to authenticate usernames. Beware.");
// Spigot start

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/server/level/ChunkMap.java
+++ b/net/minecraft/server/level/ChunkMap.java
@@ -129,7 +_,7 @@
public final AtomicInteger tickingGenerated = new AtomicInteger(); // Paper - public
private final String storageName;
private final PlayerMap playerMap = new PlayerMap();
- public final Int2ObjectMap<ChunkMap.TrackedEntity> entityMap = new Int2ObjectOpenHashMap<>();
+ public final Int2ObjectMap<ChunkMap.TrackedEntity> entityMap = new it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap<>(); // DivineMC - vmp: use linked map for entity trackers for faster iteration
private final Long2ByteMap chunkTypeCache = new Long2ByteOpenHashMap();
// Paper - rewrite chunk system
public int serverViewDistance;

View File

@@ -0,0 +1,23 @@
--- a/net/minecraft/server/level/ServerEntity.java
+++ b/net/minecraft/server/level/ServerEntity.java
@@ -408,7 +_,10 @@
}
if (this.entity instanceof LivingEntity) {
- Set<AttributeInstance> attributesToSync = ((LivingEntity)this.entity).getAttributes().getAttributesToSync();
+ // DivineMC start - Suppress errors from dirty attributes
+ Set<AttributeInstance> attributes = ((LivingEntity) this.entity).getAttributes().getAttributesToSync();
+ final Set<AttributeInstance> attributesToSync = this.level.divinemcConfig.suppressErrorsFromDirtyAttributes ? Collections.synchronizedSet(attributes) : attributes;
+ // DivineMC end - Suppress errors from dirty attributes
if (!attributesToSync.isEmpty()) {
// CraftBukkit start - Send scaled max health
if (this.entity instanceof ServerPlayer serverPlayer) {
@@ -418,7 +_,7 @@
this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), attributesToSync));
}
- attributesToSync.clear();
+ attributes.clear();
}
}

View File

@@ -0,0 +1,10 @@
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -2259,6 +_,7 @@
this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, gameMode.getId()));
if (gameMode == GameType.SPECTATOR) {
this.removeEntitiesOnShoulder();
+ this.stopSleeping(); // DivineMC - Fix MC-119417
this.stopRiding();
EnchantmentHelper.stopLocationBasedEffects(this);
} else {

View File

@@ -0,0 +1,44 @@
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -572,7 +_,7 @@
return;
}
// Paper end - Prevent moving into unloaded chunks
- if (d7 - d6 > Math.max(100.0, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) {
+ if (!space.bxteam.divinemc.configuration.DivineConfig.disableMovedWronglyThreshold && d7 - d6 > Math.max(100.0, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { // DivineMC - Option to disable moved wrongly threshold
// CraftBukkit end
LOGGER.warn(
"{} (vehicle of {}) moved too quickly! {},{},{}", rootVehicle.getName().getString(), this.player.getName().getString(), d3, d4, d5
@@ -602,7 +_,7 @@
d5 = d2 - rootVehicle.getZ();
d7 = d3 * d3 + d4 * d4 + d5 * d5;
boolean flag2 = false;
- if (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot
+ if (!space.bxteam.divinemc.configuration.DivineConfig.disableMovedWronglyThreshold && d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot // DivineMC - Option to disable moved wrongly threshold
flag2 = true; // Paper - diff on change, this should be moved wrongly
LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", rootVehicle.getName().getString(), this.player.getName().getString(), Math.sqrt(d7));
}
@@ -2397,6 +_,7 @@
}
private void tryHandleChat(String message, Runnable handler, boolean sync) { // CraftBukkit
+ if (ServerGamePacketListenerImpl.isLog4ShellExploit(message)) return; // DivineMC - Block Log4Shell exploit
if (isChatMessageIllegal(message)) {
this.disconnectAsync(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper - add proper async disconnect
} else if (this.player.isRemoved() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) { // CraftBukkit - dead men tell no tales
@@ -2424,6 +_,15 @@
return optional;
}
}
+
+ // DivineMC start - Block Log4Shell exploit
+ public static boolean isLog4ShellExploit(String message) {
+ java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(".*\\$\\{[^}]*}.*");
+ java.util.regex.Matcher matcher = pattern.matcher(message);
+
+ return matcher.find();
+ }
+ // DivineMC end - Block Log4Shell exploit
public static boolean isChatMessageIllegal(String message) {
for (int i = 0; i < message.length(); i++) {

View File

@@ -0,0 +1,12 @@
--- a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
@@ -172,7 +_,8 @@
public void handleHello(ServerboundHelloPacket packet) {
Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet");
// Paper start - Validate usernames
- if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode()
+ if (!space.bxteam.divinemc.configuration.DivineConfig.removeVanillaUsernameCheck // DivineMC - Remove vanilla username check
+ && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode()
&& io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.performUsernameValidation
&& !this.iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation) {
Validate.validState(StringUtil.isReasonablePlayerName(packet.name()), "Invalid characters in username");

View File

@@ -0,0 +1,29 @@
--- a/net/minecraft/server/players/StoredUserList.java
+++ b/net/minecraft/server/players/StoredUserList.java
@@ -97,13 +_,20 @@
}
public void save() throws IOException {
- this.removeExpired(); // Paper - remove expired values before saving
- JsonArray jsonArray = new JsonArray();
- this.map.values().stream().map(storedEntry -> Util.make(new JsonObject(), storedEntry::serialize)).forEach(jsonArray::add);
+ // DivineMC start - Save json list async
+ Runnable saveTask = () -> {
+ this.removeExpired(); // Paper - remove expired values before saving
+ JsonArray jsonArray = new JsonArray();
+ this.map.values().stream().map(storedEntry -> Util.make(new JsonObject(), storedEntry::serialize)).forEach(jsonArray::add);
- try (BufferedWriter writer = Files.newWriter(this.file, StandardCharsets.UTF_8)) {
- GSON.toJson(jsonArray, GSON.newJsonWriter(writer));
- }
+ try (BufferedWriter writer = Files.newWriter(this.file, StandardCharsets.UTF_8)) {
+ GSON.toJson(jsonArray, GSON.newJsonWriter(writer));
+ } catch (java.io.IOException e) {
+ StoredUserList.LOGGER.warn("Failed to async save " + this.file, e);
+ }
+ };
+ io.papermc.paper.util.MCUtil.scheduleAsyncTask(saveTask);
+ // DivineMC end - Save json list async
}
public void load() throws IOException {

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/server/rcon/RconConsoleSource.java
+++ b/net/minecraft/server/rcon/RconConsoleSource.java
@@ -51,7 +_,7 @@
@Override
public void sendSystemMessage(Component component) {
- this.buffer.append(component.getString());
+ this.buffer.append(component.getString()).append(System.lineSeparator()); // DivineMC - Fix MC-7569
}
@Override

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/util/ClassInstanceMultiMap.java
+++ b/net/minecraft/util/ClassInstanceMultiMap.java
@@ -14,7 +_,7 @@
import net.minecraft.Util;
public class ClassInstanceMultiMap<T> extends AbstractCollection<T> {
- private final Map<Class<?>, List<T>> byClass = Maps.newHashMap();
+ private final Map<Class<?>, List<T>> byClass = new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(); // DivineMC - lithium: collections.entity_by_type
private final Class<T> baseClass;
private final List<T> allInstances = Lists.newArrayList();

View File

@@ -0,0 +1,25 @@
--- a/net/minecraft/util/Mth.java
+++ b/net/minecraft/util/Mth.java
@@ -29,7 +_,7 @@
public static final Vector3f Y_AXIS = new Vector3f(0.0F, 1.0F, 0.0F);
public static final Vector3f X_AXIS = new Vector3f(1.0F, 0.0F, 0.0F);
public static final Vector3f Z_AXIS = new Vector3f(0.0F, 0.0F, 1.0F);
- private static final float[] SIN = Util.make(new float[65536], floats -> {
+ public static final float[] SIN = Util.make(new float[65536], floats -> { // DivineMC - lithium: math.sine_lut
for (int i1 = 0; i1 < floats.length; i1++) {
floats[i1] = (float)Math.sin(i1 * Math.PI * 2.0 / 65536.0);
}
@@ -46,11 +_,11 @@
private static final double[] COS_TAB = new double[257];
public static float sin(float value) {
- return SIN[(int)(value * 10430.378F) & 65535];
+ return space.bxteam.divinemc.util.lithium.CompactSineLUT.sin(value); // DivineMC - lithium: math.sine_lut
}
public static float cos(float value) {
- return SIN[(int)(value * 10430.378F + 16384.0F) & 65535];
+ return space.bxteam.divinemc.util.lithium.CompactSineLUT.cos(value); // DivineMC - lithium: math.sine_lut
}
public static float sqrt(float value) {

Some files were not shown because too many files have changed in this diff Show More