9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-28 19:29:09 +00:00

[ci-skip] remove old 1.19.4 patches

This commit is contained in:
NONPLAYT
2023-08-25 03:24:34 +03:00
parent 2f85171155
commit eadd2cdf55
54 changed files with 0 additions and 4855 deletions

View File

@@ -1,60 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ivan Pekov <ivan@mrivanplays.com>
Date: Sun, 27 Sep 2020 18:01:50 +0300
Subject: [PATCH] Add last tick time API
Original code by YatopiaMC, licensed under MIT
You can find the original code on https://github.com/YatopiaMC/Yatopia
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index ac9b690fcccb60b587e5345f12f1383afd0a73a1..4078ec0faa173d23b631cd221eec7f14aab1fc74 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -2432,6 +2432,16 @@ public final class Bukkit {
return server.isStopping();
}
+ // Yatopia start
+ @Deprecated
+ public static long getLastTickMs() {
+ return server.getLastTickMs();
+ }
+ @NotNull public static java.time.Duration getLastTickTime() {
+ return server.getLastTickTime();
+ }
+ // Yatopia end
+
/**
* Returns the {@link com.destroystokyo.paper.entity.ai.MobGoals} manager
*
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 2204336d8800311b65e894739ab1b27273e7c6f2..3b454a75809eec9d8294ec6fa15c7e918497489c 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -2118,6 +2118,26 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
*/
boolean isStopping();
+ // Yatopia start
+ /**
+ * Returns the time the last tick took in milliseconds.
+ *
+ * @return long time value
+ * @deprecated newer method with java's Duration and a possibility to convert it from millis to something else
+ */
+ @Deprecated
+ default long getLastTickMs() {
+ return getLastTickTime().toMillis();
+ }
+ /**
+ * Returns the time in {@link java.time.Duration} the last tick took.
+ *
+ * @return duration
+ */
+ @NotNull
+ java.time.Duration getLastTickTime();
+ // Yatopia end
+
/**
* Returns the {@link com.destroystokyo.paper.entity.ai.MobGoals} manager
*

View File

@@ -1,30 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Sun, 17 Oct 2021 14:53:28 -0400
Subject: [PATCH] Paper PR - BoneMeal API
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
index aa04d7df70d99402c91e920fd693d7d4fb655786..b572a760c09634d58485be71911bbae3c744e368 100644
--- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java
@@ -4069,4 +4069,19 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
}
}
}
+ // Paper start
+ /**
+ * Applies bonemeal at a specific location
+ * <p>
+ * Modifications done in the predicate are respected
+ * and will not be applied if false is returned.
+ *
+ * @param location Location to apply
+ * @param face Blockface to apply as
+ * @param showParticles If particles should be shown on success
+ * @param predicate blockstate predicate
+ * @return true if the bonemeal was applied, false if not
+ */
+ boolean applyBoneMeal(@NotNull Location location, @NotNull org.bukkit.block.BlockFace face, boolean showParticles, @Nullable Predicate<org.bukkit.block.BlockState> predicate);
+ // Paper end
}

View File

@@ -1,33 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 24 Apr 2017 20:27:23 -0400
Subject: [PATCH] EMC - Add ChatColor.getById
diff --git a/src/main/java/org/bukkit/ChatColor.java b/src/main/java/org/bukkit/ChatColor.java
index e3f185dc982d1c38195a4e01ddd485c13ffa58c0..8a3d05702ad0cfa8384d3a9c7a5695d82e13523e 100644
--- a/src/main/java/org/bukkit/ChatColor.java
+++ b/src/main/java/org/bukkit/ChatColor.java
@@ -233,6 +233,10 @@ public enum ChatColor {
}
};
+ public int getId() {
+ return intCode;
+ }
+
/**
* The special character which prefixes all chat colour codes. Use this if
* you need to dynamically convert colour codes from your custom format.
@@ -296,6 +300,11 @@ public enum ChatColor {
return !isFormat && this != RESET;
}
+ @Nullable
+ public static ChatColor getById(int id) {
+ return BY_ID.get(id);
+ }
+
/**
* Gets the color represented by the specified color code
*

View File

@@ -1,64 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Justin <justin@justinf.dev>
Date: Wed, 24 Aug 2022 05:08:52 -0700
Subject: [PATCH] Paper PR - Add Entity hidden by default API
This patch adds API that allows entities to be hidden by default. Entities that are hidden by
default are not shown to players until Player#showEntity is invoked on said entity. The same is
true for players that join the server after an Entity is hidden by default.
Hiding entities by default also respects precedent of keeping entities hidden when other plugins
explicitly hide them from a player. If an entity is hidden by default and by a plugin, the entity
must have the plugin that hid them from a player show them in order to be shown to a player again.
If no plugin had previously hidden the entity before the entity was hidden by default, then any
plugin that attempts to show the entity to a player will succeed in doing so.
diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
index 365350d38b2eee00d22bad09ab95c6054f11d536..565a3bcc49ccb4650188263632751e9f6326a5d1 100644
--- a/src/main/java/org/bukkit/entity/Entity.java
+++ b/src/main/java/org/bukkit/entity/Entity.java
@@ -953,4 +953,25 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
*/
boolean wouldCollideUsing(@NotNull BoundingBox boundingBox);
// Paper End - Collision API
+
+ // Paper start - Entity hiddenByDefault
+ /**
+ * Sets whether the entity is hidden by default. When an entity is hidden by default,
+ * {@link Player#showEntity(org.bukkit.plugin.Plugin, Entity)} must be called in order to
+ * display the entity again. Players that join the server do not see entities that are
+ * hidden by default at first and must be shown the entity with the same method above.
+ *
+ * This method also respects plugins hiding entities - if another plugin still wishes for an entity
+ * to be hidden (via {@link Player#hideEntity(org.bukkit.plugin.Plugin, Entity)}), then the entity will
+ * remain hidden even if hiddenByDefault is set to false again or if another plugin tries to show the entity.
+ *
+ * @param hiddenByDefault
+ */
+ void setHiddenByDefault(boolean hiddenByDefault);
+
+ /**
+ * @return true if the Entity is hidden by default, false otherwise
+ */
+ boolean isHiddenByDefault();
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index b5fd857896b3afcfa69cce55cbc2696dd625f805..7d44d455a550490e8e505c205dfe26e1d048719e 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -1568,9 +1568,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
/**
* Allows this player to see an entity that was previously hidden. If
- * another another plugin had hidden the entity too, then the entity will
+ * another plugin had hidden the entity too, then the entity will
* remain hidden until the other plugin calls this method too.
*
+ * If no other plugin is hiding the entity after this method is called,
+ * then this method also allows the player to see entities hidden by default
+ * with {@link Entity#setHiddenByDefault(boolean)}.
+ *
* @param plugin Plugin that wants to show the entity
* @param entity Entity to show
*/

View File

@@ -1,671 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Fri, 4 Nov 2022 17:00:07 +0300
Subject: [PATCH] Divine Branding
diff --git a/build.gradle.kts b/build.gradle.kts
index 3c8293f002f11b430083502362fdc801f44aa138..506456fd003dda0d544c9800301b1210a5d18457 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -7,7 +7,7 @@ plugins {
}
dependencies {
- implementation(project(":pufferfish-api")) // Pufferfish // Paper
+ implementation(project(":divinemc-api")) // DivineMC // Pufferfish // Paper
// Pufferfish start
implementation("io.papermc.paper:paper-mojangapi:1.19.2-R0.1-SNAPSHOT") {
exclude("io.papermc.paper", "paper-api")
@@ -82,7 +82,7 @@ tasks.jar {
attributes(
"Main-Class" to "org.bukkit.craftbukkit.Main",
"Implementation-Title" to "CraftBukkit",
- "Implementation-Version" to "git-Pufferfish-$implementationVersion", // Pufferfish
+ "Implementation-Version" to "git-DivineMC-$implementationVersion", // DivineMC // Pufferfish
"Implementation-Vendor" to date, // Paper
"Specification-Title" to "Bukkit",
"Specification-Version" to project.version,
diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java
index 692c962193cf9fcc6801fc93f3220bdc673d527b..2bf46834536d3702fa2ae49ce276a163a5cd1456 100644
--- a/src/main/java/com/destroystokyo/paper/Metrics.java
+++ b/src/main/java/com/destroystokyo/paper/Metrics.java
@@ -593,7 +593,7 @@ public class Metrics {
boolean logFailedRequests = config.getBoolean("logFailedRequests", false);
// Only start Metrics, if it's enabled in the config
if (config.getBoolean("enabled", true)) {
- Metrics metrics = new Metrics("Pufferfish", serverUUID, logFailedRequests, Bukkit.getLogger()); // Pufferfish
+ Metrics metrics = new Metrics("DivineMC", serverUUID, logFailedRequests, Bukkit.getLogger()); // Pufferfish // DivineMC
metrics.addCustomChart(new Metrics.SimplePie("minecraft_version", () -> {
String minecraftVersion = Bukkit.getVersion();
diff --git a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java
index c5d5648f4ca603ef2b1df723b58f9caf4dd3c722..05478a1ea04ec0396bc8c97090edef4a2aced2a9 100644
--- a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java
+++ b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java
@@ -17,7 +17,7 @@ public final class PaperConsole extends SimpleTerminalConsole {
@Override
protected LineReader buildReader(LineReaderBuilder builder) {
builder
- .appName("Paper")
+ .appName("DivineMC") // DivineMC
.variable(LineReader.HISTORY_FILE, java.nio.file.Paths.get(".console_history"))
.completer(new ConsoleCommandCompleter(this.server))
.option(LineReader.Option.COMPLETE_IN_WORD, true);
diff --git a/src/main/java/gq/bxteam/divinemc/DivineVersionFetcher.java b/src/main/java/gq/bxteam/divinemc/DivineVersionFetcher.java
new file mode 100644
index 0000000000000000000000000000000000000000..0dc13e363448d7a0f20993e0576af625b5ca334a
--- /dev/null
+++ b/src/main/java/gq/bxteam/divinemc/DivineVersionFetcher.java
@@ -0,0 +1,137 @@
+package gq.bxteam.divinemc;
+
+import com.destroystokyo.paper.VersionHistoryManager;
+import com.destroystokyo.paper.util.VersionFetcher;
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.JoinConfiguration;
+import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.text.format.TextDecoration;
+import org.bukkit.craftbukkit.CraftServer;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static net.kyori.adventure.text.Component.text;
+import static net.kyori.adventure.text.format.NamedTextColor.GREEN;
+import static net.kyori.adventure.text.format.NamedTextColor.RED;
+
+public class DivineVersionFetcher implements VersionFetcher {
+ private static final Logger LOGGER = Logger.getLogger("DivineVersionFetcher");
+ private static final HttpClient client = HttpClient.newHttpClient();
+
+ private static final URI JENKINS_URI = URI.create("https://raw.githubusercontent.com/DivineMC/Website/dev/latestBuild");
+ private static final String GITHUB_FORMAT = "https://api.github.com/repos/DivineMC/DivineMC/compare/ver/1.19.3...%s";
+
+ private static final HttpResponse.BodyHandler<JsonObject> JSON_OBJECT_BODY_HANDLER = responseInfo -> HttpResponse.BodySubscribers.mapping(
+ HttpResponse.BodySubscribers.ofString(StandardCharsets.UTF_8),
+ string -> new Gson().fromJson(string, JsonObject.class)
+ );
+
+ @Override
+ public long getCacheTime() {
+ return TimeUnit.MINUTES.toMillis(30);
+ }
+
+ @Override
+ public @NotNull Component getVersionMessage(final @NotNull String serverVersion) {
+ final String[] parts = CraftServer.class.getPackage().getImplementationVersion().split("-");
+ @NotNull Component component;
+
+ if (parts.length != 3) {
+ component = text("Unknown server version.", RED);
+ } else {
+ final String versionString = parts[2];
+
+ try {
+ component = this.fetchJenkinsVersion(Integer.parseInt(versionString));
+ } catch (NumberFormatException e) {
+ component = this.fetchGithubVersion(versionString.substring(1, versionString.length() - 1));
+ }
+ }
+
+ final @Nullable Component history = this.getHistory();
+ return history != null ? Component.join(JoinConfiguration.noSeparators(), component, Component.newline(), this.getHistory()) : component;
+ }
+
+ private @NotNull
+ Component fetchJenkinsVersion(final int versionNumber) {
+ final HttpRequest request = HttpRequest.newBuilder(JENKINS_URI).build();
+ try {
+ final HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ if (response.statusCode() != 200) {
+ return text("Received invalid status code (" + response.statusCode() + ") from server.", RED);
+ }
+
+ int latestVersionNumber;
+ try {
+ latestVersionNumber = Integer.parseInt(response.body());
+ } catch (NumberFormatException e) {
+ LOGGER.log(Level.WARNING, "Received invalid response from Jenkins \"" + response.body() + "\".");
+ return text("Received invalid response from server.", RED);
+ }
+
+ final int versionDiff = latestVersionNumber - versionNumber;
+ return this.getResponseMessage(versionDiff);
+ } catch (IOException | InterruptedException e) {
+ LOGGER.log(Level.WARNING, "Failed to look up version from Jenkins", e);
+ return text("Failed to retrieve version from server.", RED);
+ }
+ }
+
+ // Based off code contributed by Techcable <Techcable@outlook.com> in Paper/GH-65
+ private @NotNull
+ Component fetchGithubVersion(final @NotNull String hash) {
+ final URI uri = URI.create(String.format(GITHUB_FORMAT, hash));
+ final HttpRequest request = HttpRequest.newBuilder(uri).build();
+ try {
+ final HttpResponse<JsonObject> response = client.send(request, JSON_OBJECT_BODY_HANDLER);
+ if (response.statusCode() != 200) {
+ return text("Received invalid status code (" + response.statusCode() + ") from server.", RED);
+ }
+
+ final JsonObject obj = response.body();
+ final int versionDiff = obj.get("behind_by").getAsInt();
+
+ return this.getResponseMessage(versionDiff);
+ } catch (IOException | InterruptedException e) {
+ LOGGER.log(Level.WARNING, "Failed to look up version from GitHub", e);
+ return text("Failed to retrieve version from server.", RED);
+ }
+ }
+
+ private @NotNull
+ Component getResponseMessage(final int versionDiff) {
+ return switch (Math.max(-1, Math.min(1, versionDiff))) {
+ case -1 -> text("You are running an unsupported version of DivineMC.", RED);
+ case 0 -> text("You are on the latest version!", GREEN);
+ default -> text("You are running " + versionDiff + " version" + (versionDiff == 1 ? "" : "s") + " beyond. " +
+ "Please update your server when possible to maintain stability, security, and receive the latest optimizations.", RED);
+ };
+ }
+
+ private @Nullable
+ Component getHistory() {
+ final VersionHistoryManager.VersionData data = VersionHistoryManager.INSTANCE.getVersionData();
+ if (data == null) {
+ return null;
+ }
+
+ final String oldVersion = data.getOldVersion();
+ if (oldVersion == null) {
+ return null;
+ }
+
+ return text("Previous version: " + oldVersion, NamedTextColor.GRAY, TextDecoration.ITALIC);
+ }
+}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 6d5e9400892b86562519a893349ca55e566bfb24..9945d6efac1e1ea0d22d6fdfe8aa5d2805c615b2 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1683,7 +1683,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@DontObfuscate
public String getServerModName() {
- return "Pufferfish"; // Pufferfish - Pufferfish > // Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla!
+ return "DivineMC"; // DivineMC - DivineMC > // Pufferfish - Pufferfish > // Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla!
}
public SystemReport fillSystemReport(SystemReport details) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index b2d94582037c091bd6a04451bf62b3f9c4923d19..efc137a8a9f1da4a7ffff6028af368cc7f90d20a 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -256,7 +256,7 @@ import javax.annotation.Nullable; // Paper
import javax.annotation.Nonnull; // Paper
public final class CraftServer implements Server {
- private final String serverName = "Pufferfish"; // Paper // Pufferfish
+ private final String serverName = "DivineMC"; // Paper // Pufferfish // DivineMC
private final String serverVersion;
private final String bukkitVersion = Versioning.getBukkitVersion();
private final Logger logger = Logger.getLogger("Minecraft");
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
index 4966a1e3dd35357a8ea6a7d2944c84c9c3e9058e..5b4d42fd74a32e4e97690f0cd9a33c66dc1ae141 100644
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -285,7 +285,7 @@ public class Main {
if (buildDate.before(deadline.getTime())) {
// Paper start - This is some stupid bullshit
System.err.println("*** Warning, you've not updated in a while! ***");
- System.err.println("*** Please download a new build as per instructions from https://papermc.io/downloads ***"); // Paper
+ System.err.println("*** Please download a new build from https://github.com/DivineMC/DivineMC/releases/latest ***"); // DivineMC
//System.err.println("*** Server will start in 20 seconds ***");
//Thread.sleep(TimeUnit.SECONDS.toMillis(20));
// Paper End
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index d4f62940504e3ef7a70e13b1f4a7726f23b4c637..bd21dd728b6d47d354aeb879b083394e186d6a5c 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -464,7 +464,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
@Override
public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() {
- return new gg.pufferfish.pufferfish.PufferfishVersionFetcher(); // Pufferfish
+ return new gq.bxteam.divinemc.DivineVersionFetcher(); // DivineMC
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
index 80553face9c70c2a3d897681e7761df85b22d464..60ac52c6e12ee346133930394e9de8bf74e77ee6 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
@@ -11,7 +11,7 @@ public final class Versioning {
public static String getBukkitVersion() {
String result = "Unknown-Version";
- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/gg.pufferfish.pufferfish/pufferfish-api/pom.properties"); // Pufferfish
+ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/gq.bxteam.divinemc/divinemc-api/pom.properties"); // DivineMC
Properties properties = new Properties();
if (stream != null) {
diff --git a/src/main/resources/logo.png b/src/main/resources/logo.png
index a7d785f60c884ee4ee487cc364402d66c3dc2ecc..f54753531b3bf2e8b5377f342465e727c7da98f2 100644
GIT binary patch
literal 6677
zcmZ`ecT^MIvk65y(vr|S0wD$n1T=z3m0m+wF=$9cr3j%}P!W;dMd>0)Cy6mZP(Xpu
z`KXEn5Jf2hLO#R>ih{iOJMX-A-XCxG+?_jjX7=vRopyIq-Cd813CjzEKp-&(dmB#>
z2#omK1bMk5u9dOJxq$DSrHds9#LO1i@#p8_sw8_)7Z51s00<P900RBu4#j;0fuapS
zpfv&rgee4pVB~wP9%fvEpSv^GmJ5#<8XD;69=ACTcmtS27%K}a$75Db_D&i~$_6?*
zP$_9`HFae<c}-<yj44JRp>J<zZ;CcWYU}7D^$~CcQb*Us$V5{^^C;%1uC}hZv5Atb
z+yPa!y}iA0#xqIo1mGx7S1-`9<>|A35u(#^8|4ULRXr{u5ar-vE3hmqE3r=>bw!l>
zCLnNFgew+2R&lAAi)cmJ0#RrDqXICbhyX4Cp$t%{gN6nNQN~z96O4fg24$*eV1O|&
z`24~m`2Pr82s;ya_R9Y+a5FP`iYwq7063g=aRI@(eL)aESPJx4yI}4K0?UK`s+8LU
zIf51br|${Y`EMQ`5Qs<mfBCt5e-C?Z`z!MwsN(s<7zC0<JJ?uaFVC#cu3Aws5}-NG
z#qSfoFTDOGUf-K~9^g=jE=q7;L)~b+>-kkkt%z@DqvQS0OciO<6(B~X-Ttj8^Ly;I
zo6TV6_jdf1w>dz}4f>(bF>w9Nl+(tmyuNjboV5a{jFW#sdhZ3z{C6FC!V#*o?@AZ*
z6@#2M7W4S(D=_e$&8q=XmdM!qgOR%?ntYTjPFBys6aK5aZOW9A-@mVhM4$Tn#+hCB
zNpgxYSKw4B-@=Ml8HJRuwG70o3_~8YcHFp3NRQPixJk)8jWlBG`$)0fR?<9ouc(Iq
z@M>AWUQmUPC;T+To4^Nb6>2S#hFq7L&p%!1Cs%tkSst0NNYZm;6BFuVg$q)J!)F7(
z%(e_;?{knc?~C+ODT}S?y_c3y-kj+)Wgt5{`{U-T!|fUc+rlYhRs);U0u{fq@D7>$
z_>Lp=enScNrA5b3pV^mFIh4g1^)G(S4aMb`J2kRvHwN--6UVxbA8uFjF<}pE*7ZMK
zD7IlonkOy3A<Gq)*8^^DhO|fj1e6n%mInf-NeT7s>IJvqJ+^v3B{iHk+09aQ#>kl{
zmaISJQBQP<omSvWf{7uu*5XDx53JPMJ0a~}H1qN2`n|VJkuP6g>8%5~(PD4NTU;H%
zN4-1eLAj|t8F9I*tOJKM3*6eu_ik{zyQXVr`+F=q1YAwrdHH=#%BbwO{yyyY;)#O9
zGoK`Ujx6-fNTj483E1!FGtYVz6zXJkTq}>qH=7wK@z<-uMz+lx_|+jFzKR&rwU*h7
z-SX~-k+=i6A(lrB*0r`9T8GUNIhfO&-z;_$ZArSIsvPp?xN$s|$dHe^`OM^F>B%4e
z+B+^26JapEmg)E{;0#))&Eg{uHb-Q`84A;T-g<0_D1txOzm@fAkH7Bi)a>I9KNL*w
z8u{ixFO<d6eq$7K79U3u!zI^5GP{n$dMqSIV5iE99P4Kuxl|Q@3jB4S9J9&uFowIV
zuZ1z0Lpy$$DSnKleBNHnRm*QJxmm;_4$t*I3Gb&Of&3$jj&zm7K2>8tyq?{r4KmQm
zSNiE?)c%L{xJxhP4&5oKhr-|T5c1%mU!3b24|v+PPTx7XiKE<3_og)W8hwd4bQ{h>
zw@BZ$Vn;F^AsxsUQYH4)WS37yHJ(jv^McSfJ!KYWI{j#p^1Z|(l4aXFHm%b)_D;p6
zeK-F2{zQ2YFT{AfE%km<h_?NGr@1u?!TOnI5M<gb##aX$r+1HZ8HN4KrS0>cleZA9
zmujwY7rUA^wck?=KmRZL&VyCf#rO}){K)5E`+yI=l9Y}ctF9gtg(oT>q(z-%>r+DF
zn{-;VUxR+9B~Sb8RDV(I_k9?;D(8Gj$fHRTu6IN%?`EkCa{IH0=Sw41*UgZwulPmn
z)laGv2^e*bcaeZY?uLkYS|UaAAk@XKvKj$Q#dtIDN(~iqeqPuo)DqqwP}x9whzk*E
z)NIrkYyrM~c0&+-xfVm0sHynpwS>3uWK3zFR@OKpKT68yUK+jEWMymEb@OX(VqRCZ
zco5SyxoF6ae@doaqTnW6VQ3Jd$a`kjNV=eO@Zm$xZF6G}7ghtgdVi5!%XnRn%eXw-
z5iK<2&Q31*PFo0_vOm)B@jz8@r(e!mQfMwD=&?h;ZzRnDPg}ScJk3G;N{Twj!p|gP
zZ1NJDPDRo}kV&8^LC@`mm!?g5{Tm`pfl(A^nzA4%Aly)})h>skcaj#dh-WUB+2v)j
zr95b|Q+IN*So~Kd)bW>BXBm)nA4YzIBN`l>!5-{FPw;~?1hk@%>!qrYPf1$tE?pFO
zR(1GIYDWAQ2|+onsA2wkJGv%3*?Z~)U_KQDSyW$#ffv=J6c6A``RiloHWXzl{V~&*
z&V~<beeir8tL?j+irWnVceLgZ0`C@x^;0+wfOnH`V)NYzqazwz74*_jPL*9kt=}wr
z7;7=8Ne*=sGBEMD)g%+n>V*Q_`REbq*sw5LhB1AB)yLbGR_mdQ53v;X9z)~53wn#^
zhY>6hMd{+ahRAWu&JX=eM<CIkx&H;y^moZGD9?kzZuw?|$td~_zbcR0?CHRPdi$h!
zHnjY(ZCwNtgG@tba>}xe;S4x+E`U2F-MVhwq3$bl6tAdP#!*Q#rrb<ND@AdyO=NrP
zQg@e5-!@^u1Zjf!ooy%2zGaXzMBM~}vNwYS*~YXfAF$pidtGiMd>=PvH*R#*&lq@s
zX-}W#0!mYyVBv!INAOqqnnSQTPBlFE`K%FwcSl|yCbF%4rsak5(c8l<0|B)Wcnq5b
z;qZ#jE*)l^din^5G{0FHZdjz6H_Zrec>!FyViZ*%hx6hIKAA!_w~WU-FWRLUK+M}s
z&5}N$I)jR>0Ig;`n;K!5sc^81J5~A2&&QeWdELc>{Q7I^uvg7OwuOV?sn{?c+$)*B
z8QeC$v1qV4G*@HNZ_CAf((f$bV#JG!Hl+XLiK%Y#@}Sie32{*PFZ_*S1y+g7;<I+N
z?Un_R^Bby}!bJ4QFz_v+7xp6d9GsoPHioeVm!(irds4Sz|LBjb+tw>i{{F299LdV-
zt=1$T@Z7b<@1rPlc1ua?PK5P~ih4zQIUB|H=+IdkHnFWElD69}f$R77-p1elK4(L@
zKV-kTwe@F|x%E39IEPG%K2+FJ@fv&4&$-g`BnJcOnb{B_t@F`}n$J(hLMf7*<_?KT
zQGAry`2+CeXtPriR0G&2@TfhTq?8ToYlwWfI<POeX8cdYVM@(B&|ewHHvUFD(K5+F
zSLFI`MtX$P7Cl%&K8V!KFP+Q~{H(pH(rfpYLC+$_FUSya6Q67ipE5{az%?&sgy+?u
z2rUq8f_GjVJ3>jk9v_?J+L-R5aa8nyhmwNE<XJC1>WVs`qQVt|6;3F8s7O6OWRPGL
zZA@%BSq|u50S>~t9apT3%Ds`89)E=-_d3~pj+{CzRza4tq@^Iz(|;TZD?%b8UUnLB
zxPrC}d>`1q<>4_}sHTa^kjhCF6-jz&U+?my5q-yBP=50^sl^#56D&Jl7LO)hzh=`s
zsyB%5$`rJuZ$%&Q9%15n&C{07W;yq)H6sAjl-ep?><1=2&7Zxw#I<-6L@H<J{x)6g
zC+1cffxU?Wj_5&G*509Kn=Cbog#Fn~acsOCbfiXnBNFkTD9x&HUgZG~5Pgt<9zg(~
z;Dw2aEj#j7`>!fhEC7b^>|R<>!C<ifRX_Rw^aGEJ;e+J1$$A~!y&x8Gg^<34sxtC#
zS~?2|XiN?y&OGGGJ@oKLh<GRWu3a>4mhUdkjh+LNZ%J|%ty%H-cJRe6Y;427PH?td
zdXro(qo(HkAzXhi1D?grRmzh67%+V#iFBgg?hb+`wT;M%US0r<sjnXC6AmL&mYQ34
zwSkKi2cSClhGKf~{JYzCCm#5PWUwQ|erGd0>uLy);kyxtm;>YYP2JXBAWeEP7Y^my
zYXNvj{uB>TsCR$jfy?hh`BrE!wOw?Qd_WyBz~6V{Zk70k0M{k#9t`$TIO+b;c)nnK
z+`gfns;r5?3FZus4z>uGbxZRmvaGm%{+cmUAj7GYVqlP9s(zdmq&N4SY%Gz6syrf}
zKb7Wx6Kw`vB|d{3&e!7-J1N#+rlVNmDnNQ>9N*h)Ultw`Cy5AS>tIK_t1~2VehSRN
zOofI~k+m&ZrXXz92oC&FOaNTEnQz@~e19ssc3R?I=*ckp{xp)!dq(uLmRd9sr=MEW
zu5&pge3Wsoh7%Ga(d{2R>2@q0e7RT+VcUeahll^`d~VMbVD^9@E>-t<qeUC9RzU>X
zj+T|~-zErreB@U5m64RGN^2e1L7=@C-;_@Dr9>~I2)Dfw-Ioa4BOuzR%-7sBV2v=Q
z!P7RMtN@pnyHp8wyb536D8DO48TO=TxlnZzmPRd8Y-_K4$4+X9DwXrsI>f`<WG9jQ
zL+o`yjvp)6^|&F|b=n)arYeI#aZqtfGol`d`cG2Qr~Zwn_%CHEM9{*0Pl`hqJek){
z8Yg*oL?R52OdH$LP`7A|5j4LDSr<@Ug!NH^v$SeFOZrm0gKXrVuJ9vXgbI_kui|YG
zcO8@mBkwZsv&y|e@*237`KyzUmjPi|zx<~%DaL@Hty{DV17D(+#^&BNH&RIl$`Q`}
z^G=rQ^5KREldo(qA)rYz{Zc1{)*x+t2)ZiVfRFEwnBq(Lk3#ALQvuI*tDd0K1wAvN
zhoNi2?LofnBpb$)a9X7#^){pGgLt8oeVDvXIy>?uWiW*uF_OqO=E=V+Wc^KhHSdWr
zZm9Z+ED>0IGDwULbEkdLg%_?>0E^dIA_S#u#b6!XKAz*#3N@_;`FcCO%$YLU(hKeq
zMd9VC`hOCczshK~gG~F`Xb*(NhH!yFRQD@U013Dy`?Kv3u|9w#?Phx3=kjn{CXQ-M
zV^+}wN>kZ?P|~>mfKJa}W{T962LH}njNYD;X!_XwFCC*v(aR0~y1Ri{?1&Q#vV#Dn
zQc`3~%sl^hfE}&7Go_l3TahgQja9sPVj`ES>e<f$UZ1zN4oAs|j!iy9#8EhQ(OZ&q
z(<QGbx5Ud1k(f>rdt*vs4pmt3^Mvq(QFQX(-a`>n@lv=SVs;4kaY-sY6PPep8F~-g
zQgBMDVkT*k{{dDu4E!JD3b*_)m}D9f<@S;j<MJS+rgJ?MQJ|`7axsX-bMS{jexT0q
zdkH`$oxDV1=FY59!6MO-*CL%*s4RtFB`zW)H98(K&k)25=t5Vef5AkD%m&uZoltQk
zf$3(n$|&*rbv@|uEcRZm#nSm6dEt{1Ly=2dtyeSO>Ti2xsp5R_t_I-XImdpCvJ)v)
zw>Y#Hk4QbRbbgVW?Y{!Yb<5DS!t830X1KQ|wBM>M3h?^F^!@k4LYR)2&%Dq<HkMWi
z5qUmuVR`g5=|aRGk<t!ZJzr@dK-kAy7heQ0!eo1_!d{%x>RD??2n5d!c1yKT9OsEZ
zFmFEgOx|Du`q~L)Tz_7=7TMcT5a?b%g2~5z0Of&)uKSow7U`*^hX(>|9BZw)f)`po
zU`f&8rX*1CW>D{p!vQ<mI*!GSNKAFCM*d~zP?JPP;}*DkW?fSnoIbL;hNAOK&ZMDT
zDV}wTxL1Nei3_*Pa$>Eu0Fh}VNxE7|Svvo@a$T%B^jXpq=4+Y0+~$uO2a`<hke@gJ
zDe1egTQUeUKexw0eKeKr@1npX9%yV8f5|MglSj{$RS~J+jZpdiYGTb82EA65Xdq`0
z-&B&-WJ<ibEVFCy024saJ$yL{{f_eZO&~s<)VVC9;H8DV0x%V?NjN=+5uS=dLtN2O
zG-aaLY?2wmP+-r$N9q$ld1wKs^)f`f-3s}vD3K6doTBw%&fHCAh*XZw0L%-L*Z`CK
zCK70TKbFuN@mYBw4o%MCQVtemXkpDz&<l0ljchYOb7Upe8Bh}Rt3(n1xo*wO&!4Gk
ze1KH;>1DbLZ{M=x<2ZLQ&Ob8-J3X&*xUTe$D!E2I!8j(atSZO62<h*-u57{9OVje(
z<A>+_N-WbxQkJyi$~6X4Z1+W86N&e4c>?g{XF9eX7*0hyBh_omBt^uQ8Gj^-Z3+_t
zs&jo6z7eCV{iE|FMMRe`YyQwH3J>fXEFWYwI3Lbsj4t^DpPuUAv<RE}|9U-B!<7c)
zr3I9fX^}4IagFtUD!YBSlfvl&w1tK+MK0YHZXV%}8knA;@&vg}PoVZrTtL}&Eor{C
z?!_C=4)w`ZO+vNv9Z~<z+PaLfXa;e8kksbVi77qXx3Is~TG1czOORd<goQ~nTx&(R
z$#kbjLIWDhH)YI?@_58WJU3uPzU-%d#D}Q$HoP}J#;vP?>u7D<Nz4|a_+el5De&Br
zSBxD6Lt0y0Fa6f8&uB9G=yjQkr_LawCEsm{0>91siR*el5@qzBKGX1L3jBzot|R8f
zO<UKyfYMBU>ghP<*WXDf=oRu9qax~wuD6^DLnj42-NSs#lY*|+n00Y*Z`OgX5Qjc$
z+aWFtdZ6+jl}9jY0+gQYMiszi-#qN<%}-=}&^<ob<lfB#YmcJU>lTBZK70*$9|}P}
zL1bvT9F}?m$U}qNtBKWS6X<v?^7eSxQ(@RiXt%EjKwE#;ciFUX#?!4kXitZqi8~3V
z>g`>ml9>Uk0L^XMD;zOX@4<BC!QE(p^{V^W-3TpWv{u_PK3`8V7gSNgGR`Yd#V$z}
z#Vw`rF(sy4O+1*RLn4HiC8(=#4d{hu-HSo$xYIfr{KAD<OSQk2NNtgbD{oJ*Dy~}r
zry;DMbX(>%$w)>L$Ho$IA?Ln7^Ut@y=i<=6`!lo*YCm-mo`gO+r4}D86(0j*eZ|*J
zOEX6CiHtdGgLpuV(gpCsbbs<8PVFrb=Czaf7+u&q4DQqR2biXkUIqtapx2+Lr9mpc
z0%M2&+DG*AOeiD|fp{D0)GN<c2f`^}&h}wx>LPKrB#255Aa)+Ll!u!2!~;-@IA{9`
z&twsmLc_lXsMexXDC6^Xoy&<gC+kOnu`y|;Ywh458a$-LLgl*~Y<)O+VbHhH_s5qV
zJZNaRckPc1?Y>hN#To~4`q$pA97VW-Y`pHkQI&LN1+{Psu+33s53Tzx_I~=c<hbZV
z_I%QeosPrb0bxjYP}TPJf^zxh=^uhXVftqBIP<d$ufD!8q%*h1@N@=cQL5dETR74`
zmX+aXZdvGe#xKMh&f_GUiu(|mqhogLKHaV*rvc_Z`k~1c?f$he`Hun{3&6PX+3=`X
zSIVKO`D4whxPDvaj$GO#UdZiE)U7T<#Esv4J-K!(D>Z51O5zD3q|%l{lPufGVQ%>V
zc9Jjc;PWozkX7+AoNr#-!27Y-gJue*2J#_}KEyrvs!_jGXN4D#R}7vb77W=SUZ6Gs
z7Y)KXZ)A=Tq#u5)I#Nkocxpv^o_H{6Oa?Krs5W~x0i89Q0W2V}7T+q(^7^6=>EO#W
z`DpX-^DK4qz{Ir-et}j+Xc=(gmYnT3_kZw%i$RC-!!A91v3jnPs4JfsG&~GKU@Uk%
zENNX>DcG=i<<A{#Gp>rB<}b8O6NIoLHgvK2Tj%WZ=ep`+B)qH1538Kw(zLYpwj?RL
zKQC*8IZKJ85gXf<j|2Nyp3R<&D(BTxKf^kV(P=f8RcQsVEVKq>`D@XmrZ}z0B4$-%
z#5u_aJlT~Rz#nDlIJ6PugYP2<a;j&l1;yBxE(p0itkxBjt)3PQrrZv0!!`H4tL)3m
zSfXu7!pS%ESZl$xwsneAF%QX|^e4l4DcmA40aC*Qe4;#+@E)^e{$$W*a_qYzqK|Z?
zc?en8q<b`VGCwjx%4Y-mA};JpXnNgKm!S5Fzn%{{CA1*-C<JjjDuvxHSt*s|467#M
z>0>(80*@KTjt2Lvz5mZ0M7$)CcUk@p_s$^h?o_rF$>!zEoV+I-e)}5CY2o9PEjay*
zV>Cj8ZChL}gx7qpb>?}aNx}GS69W2l#$e=$@mq@2rNQ3ZaqlTtH2F0b9YVEg_&cmp
z9vx$cf7u~q1PkZir56Xw60;6fM=X)hnQ`bvgB}QZiFos!aZPc!EHRvJhPYeZiG3_?
zjZbnKVSm#-9*)S}?Zz7Ix5mdiDb3_8pG#x{I61G8qoRfu1(?S9zqVOT5UPa0RFVoy
zxGZG6EN57Ym|95?5w#v3susU+2$|LdW!O*>lhl?!cqW?wb$~FN*e&rbyxv*?dCe5X
zA3X1$($YNfAX74Uu7Tv&Y0zVaUwg5SyFa7>J}6Pc<8{{Dz36a2cWZ@ziU|3oYtGnA
znJD06B5HU9wr-RKbRVXY{N@dMhVhN*V%+a3VjRb0wX;hVazYu=%el;UduXEp%w^7<
zb|+!8yUq+Ya!HO6tIB5eqD~poR2<piLa!$zCim9_Emn~o0E>H$D+@pe77pwERgEIA
z0!|y>AQ6FFu;Cr?4;OGC36S8`-RHRs!ojv|9~nbh^^c7~^@OJH?SB5}xeQZzNnGTp
zU${G$vNFg^JlLjxT2*m!{P!2zieBFsmDoj7By5jYgbdVWx_kcpnE-OIb+w^e5#s*~
DA-Nv<
literal 14310
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%0ABLt+m?son?j
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
WX&3$!%>|s_1IbA#OV)^+1pg1OmmZn`

View File

@@ -1,249 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sun, 8 Jan 2023 09:57:55 +0300
Subject: [PATCH] Divine Configuration
diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java
index 2cc44fbf8e5bd436b6d4e19f6c06b351e750cb31..d432f5e58508da9691861fa0f057a30be562697b 100644
--- a/src/main/java/co/aikar/timings/TimingsExport.java
+++ b/src/main/java/co/aikar/timings/TimingsExport.java
@@ -242,7 +242,8 @@ public class TimingsExport extends Thread {
pair("spigot", mapAsJSON(Bukkit.spigot().getSpigotConfig(), null)),
pair("bukkit", mapAsJSON(Bukkit.spigot().getBukkitConfig(), null)),
pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)), // Pufferfish
- pair("pufferfish", mapAsJSON(gg.pufferfish.pufferfish.PufferfishConfig.getConfigCopy(), null)) // Pufferfish
+ pair("pufferfish", mapAsJSON(gg.pufferfish.pufferfish.PufferfishConfig.getConfigCopy(), null)), // Pufferfish // DivineMC
+ pair("divinemc", mapAsJSON(gq.bxteam.divinemc.DivineConfig.getConfigCopy(), null)) // DivineMC
));
new TimingsExport(listeners, parent, history).start();
diff --git a/src/main/java/gq/bxteam/divinemc/DivineCommand.java b/src/main/java/gq/bxteam/divinemc/DivineCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..8bdd69d8712ac160b8dba2750b920f27231b3893
--- /dev/null
+++ b/src/main/java/gq/bxteam/divinemc/DivineCommand.java
@@ -0,0 +1,68 @@
+package gq.bxteam.divinemc;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import net.md_5.bungee.api.ChatColor;
+import net.minecraft.server.MinecraftServer;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+
+public class DivineCommand extends Command {
+
+ public DivineCommand() {
+ super("divinemc");
+ this.description = "DivineMC related commands";
+ this.usageMessage = "/divinemc [reload | version]";
+ this.setPermission("bukkit.command.divinemc");
+ }
+
+ public static void init() {
+ MinecraftServer.getServer().server.getCommandMap().register("divinemc", "DivineMC", new DivineCommand());
+ }
+
+ @Override
+ public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
+ if (args.length == 1) {
+ return Stream.of("reload", "version")
+ .filter(arg -> arg.startsWith(args[0].toLowerCase()))
+ .collect(Collectors.toList());
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean execute(CommandSender sender, String commandLabel, String[] args) {
+ if (!testPermission(sender)) return true;
+ String prefix = ChatColor.of("#12fff6") + "" + ChatColor.BOLD + "DivineMC » " + ChatColor.of("#e8f9f9");
+
+ if (args.length != 1) {
+ sender.sendMessage(prefix + "Usage: " + usageMessage);
+ args = new String[]{"version"};
+ }
+
+ if (args[0].equalsIgnoreCase("reload")) {
+ MinecraftServer console = MinecraftServer.getServer();
+ try {
+ DivineConfig.load();
+ } catch (IOException e) {
+ sender.sendMessage(Component.text("Failed to reload.", NamedTextColor.RED));
+ e.printStackTrace();
+ return true;
+ }
+ console.server.reloadCount++;
+
+ Command.broadcastCommandMessage(sender, prefix + "DivineMC configuration has been reloaded.");
+ } else if (args[0].equalsIgnoreCase("version")) {
+ Command.broadcastCommandMessage(sender, prefix + "This server is running " + Bukkit.getName() + " version " + Bukkit.getVersion() + " (Implementing API version " + Bukkit.getBukkitVersion() + ")");
+ }
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/gq/bxteam/divinemc/DivineConfig.java b/src/main/java/gq/bxteam/divinemc/DivineConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..541acfc832fe4caa13b5fb46bc455fc6a7294af8
--- /dev/null
+++ b/src/main/java/gq/bxteam/divinemc/DivineConfig.java
@@ -0,0 +1,134 @@
+package gq.bxteam.divinemc;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.List;
+import net.minecraft.server.MinecraftServer;
+import org.apache.logging.log4j.Level;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.MemoryConfiguration;
+import org.jetbrains.annotations.Nullable;
+import org.simpleyaml.configuration.comments.CommentType;
+import org.simpleyaml.configuration.file.YamlFile;
+import org.simpleyaml.exceptions.InvalidConfigurationException;
+
+public class DivineConfig {
+
+ private static final YamlFile config = new YamlFile();
+ private static int updates = 0;
+
+ private static ConfigurationSection convertToBukkit(org.simpleyaml.configuration.ConfigurationSection section) {
+ ConfigurationSection newSection = new MemoryConfiguration();
+ for (String key : section.getKeys(false)) {
+ if (section.isConfigurationSection(key)) {
+ newSection.set(key, convertToBukkit(section.getConfigurationSection(key)));
+ } else {
+ newSection.set(key, section.get(key));
+ }
+ }
+ return newSection;
+ }
+
+ public static ConfigurationSection getConfigCopy() {
+ return convertToBukkit(config);
+ }
+
+ public static int getUpdates() {
+ return updates;
+ }
+
+ public static void load() throws IOException {
+ File configFile = new File("divinemc.yml");
+
+ if (configFile.exists()) {
+ try {
+ config.load(configFile);
+ } catch (InvalidConfigurationException e) {
+ throw new IOException(e);
+ }
+ }
+
+ getString("info.version", "1.0");
+ setComment("info",
+ "DivineMC Configuration",
+ "Join our Discord at https://discord.gg/p7cxhw7E2M",
+ "Download new builds at https://github.com/DivineMC/DivineMC/releases/latest");
+
+ for (Method method : DivineConfig.class.getDeclaredMethods()) {
+ if (Modifier.isStatic(method.getModifiers()) && Modifier.isPrivate(method.getModifiers()) && method.getParameterCount() == 0 &&
+ method.getReturnType() == Void.TYPE && !method.getName().startsWith("lambda")) {
+ method.setAccessible(true);
+ try {
+ method.invoke(null);
+ } catch (Throwable t) {
+ MinecraftServer.LOGGER.warn("Failed to load configuration option from " + method.getName(), t);
+ }
+ }
+ }
+
+ updates++;
+
+ config.save(configFile);
+ }
+
+ private static void setComment(String key, String... comment) {
+ if (config.contains(key)) {
+ config.setComment(key, String.join("\n", comment), CommentType.BLOCK);
+ }
+ }
+
+ private static void ensureDefault(String key, Object defaultValue, String... comment) {
+ if (!config.contains(key)) {
+ config.set(key, defaultValue);
+ config.setComment(key, String.join("\n", comment), CommentType.BLOCK);
+ }
+ }
+
+ private static boolean getBoolean(String key, boolean defaultValue, String... comment) {
+ return getBoolean(key, null, defaultValue, comment);
+ }
+
+ private static boolean getBoolean(String key, @Nullable String oldKey, boolean defaultValue, String... comment) {
+ ensureDefault(key, defaultValue, comment);
+ return config.getBoolean(key, defaultValue);
+ }
+
+ private static int getInt(String key, int defaultValue, String... comment) {
+ return getInt(key, null, defaultValue, comment);
+ }
+
+ private static int getInt(String key, @Nullable String oldKey, int defaultValue, String... comment) {
+ ensureDefault(key, defaultValue, comment);
+ return config.getInt(key, defaultValue);
+ }
+
+ private static double getDouble(String key, double defaultValue, String... comment) {
+ return getDouble(key, null, defaultValue, comment);
+ }
+
+ private static double getDouble(String key, @Nullable String oldKey, double defaultValue, String... comment) {
+ ensureDefault(key, defaultValue, comment);
+ return config.getDouble(key, defaultValue);
+ }
+
+ private static String getString(String key, String defaultValue, String... comment) {
+ return getOldString(key, null, defaultValue, comment);
+ }
+
+ private static String getOldString(String key, @Nullable String oldKey, String defaultValue, String... comment) {
+ ensureDefault(key, defaultValue, comment);
+ return config.getString(key, defaultValue);
+ }
+
+ private static List<String> getStringList(String key, List<String> defaultValue, String... comment) {
+ return getStringList(key, null, defaultValue, comment);
+ }
+
+ private static List<String> getStringList(String key, @Nullable String oldKey, List<String> defaultValue, String... comment) {
+ ensureDefault(key, defaultValue, comment);
+ return config.getStringList(key);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 673fb3955291407be37dc78be4eec9bf2018128b..f7934ce8a62404d7eaee2d334317d894e7c9ad05 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -223,6 +223,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
// Paper end
gg.pufferfish.pufferfish.PufferfishConfig.load(); // Pufferfish
gg.pufferfish.pufferfish.PufferfishCommand.init(); // Pufferfish
+ gq.bxteam.divinemc.DivineConfig.load(); // DivineMC
+ gq.bxteam.divinemc.DivineCommand.init(); // DivineMC
this.setPvpAllowed(dedicatedserverproperties.pvp);
this.setFlightAllowed(dedicatedserverproperties.allowFlight);

View File

@@ -1,65 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: BillyGalbreath <blake.galbreath@gmail.com>
Date: Sun, 13 Mar 2022 21:00:02 -0500
Subject: [PATCH] Fix legacy colors in console
Original license: MIT
Original project: https://github.com/PurpurMC/Purpur
diff --git a/src/main/java/io/papermc/paper/console/HexFormattingConverter.java b/src/main/java/io/papermc/paper/console/HexFormattingConverter.java
index b9922b07cb105618390187d98acdf89e728e1f5a..6a1eda942aa33fc0802066416f8bc64f5f15d011 100644
--- a/src/main/java/io/papermc/paper/console/HexFormattingConverter.java
+++ b/src/main/java/io/papermc/paper/console/HexFormattingConverter.java
@@ -38,6 +38,7 @@ public final class HexFormattingConverter extends LogEventPatternConverter {
private static final String ANSI_RESET = "\u001B[m";
private static final char COLOR_CHAR = 0x7f;
+ private static final char LEGACY_CHAR = 0xa7; // Purpur
public static final LegacyComponentSerializer SERIALIZER = LegacyComponentSerializer.builder()
.hexColors()
.flattener(PaperAdventure.FLATTENER)
@@ -49,6 +50,8 @@ public final class HexFormattingConverter extends LogEventPatternConverter {
private static final String RESET_RGB_ANSI = ANSI_RESET + RGB_ANSI;
private static final Pattern NAMED_PATTERN = Pattern.compile(COLOR_CHAR + "[0-9a-fk-orA-FK-OR]");
private static final Pattern RGB_PATTERN = Pattern.compile(COLOR_CHAR + "#([0-9a-fA-F]){6}");
+ private static final Pattern LEGACY_RGB_PATTERN = Pattern.compile(LEGACY_CHAR + "x((" + LEGACY_CHAR + "[0-9a-fA-F]){6})"); // Purpur
+ private static final Pattern LEGACY_PATTERN = Pattern.compile(LEGACY_CHAR + "([0-9a-fk-orxA-FK-ORX])"); // Purpur
private static final String[] RGB_ANSI_CODES = new String[]{
formatHexAnsi(NamedTextColor.BLACK), // Black §0
@@ -134,7 +137,21 @@ public final class HexFormattingConverter extends LogEventPatternConverter {
}
private static String convertRGBColors(final String input) {
- return RGB_PATTERN.matcher(input).replaceAll(result -> {
+ // Purpur start - lets just shove this back in place
+ Matcher matcher = LEGACY_RGB_PATTERN.matcher(input);
+ StringBuilder buffer = new StringBuilder();
+ while (matcher.find()) {
+ String s = matcher.group().replace(String.valueOf(LEGACY_CHAR), "").replace('x', '#');
+ int hex = Integer.decode(s);
+ int red = (hex >> 16) & 0xFF;
+ int green = (hex >> 8) & 0xFF;
+ int blue = hex & 0xFF;
+ String replacement = String.format(RGB_ANSI, red, green, blue);
+ matcher.appendReplacement(buffer, replacement);
+ }
+ matcher.appendTail(buffer);
+ return RGB_PATTERN.matcher(buffer.toString()).replaceAll(result -> {
+ // Purpur end
final int hex = Integer.decode(result.group().substring(1));
return formatHexAnsi(hex);
});
@@ -152,10 +169,11 @@ public final class HexFormattingConverter extends LogEventPatternConverter {
}
private static String stripRGBColors(final String input) {
- return RGB_PATTERN.matcher(input).replaceAll("");
+ return LEGACY_RGB_PATTERN.matcher(RGB_PATTERN.matcher(input).replaceAll("")).replaceAll(""); // Purpur
}
static void format(String content, StringBuilder result, int start, boolean ansi) {
+ content = LEGACY_PATTERN.matcher(content).replaceAll(COLOR_CHAR + "$1"); // Purpur
int next = content.indexOf(COLOR_CHAR);
int last = content.length() - 1;
if (next == -1 || next == last) {

View File

@@ -1,42 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: YatopiaMC <yatopiamc@gmail.com>
Date: Fri, 23 Oct 2020 09:20:01 -0700
Subject: [PATCH] Time Utilities
Original code by YatopiaMC, licensed under MIT
You can find the original code on https://github.com/YatopiaMC/Yatopia
diff --git a/src/main/java/org/yatopiamc/yatopia/server/util/TimeUtils.java b/src/main/java/org/yatopiamc/yatopia/server/util/TimeUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..bb023bcb4b1e1ab5261c83358ce0951cc35ba16d
--- /dev/null
+++ b/src/main/java/org/yatopiamc/yatopia/server/util/TimeUtils.java
@@ -0,0 +1,27 @@
+package org.yatopiamc.yatopia.server.util;
+
+import java.util.concurrent.TimeUnit;
+
+public class TimeUtils {
+
+ public static String getFriendlyName(TimeUnit unit) {
+ switch (unit) {
+ case NANOSECONDS:
+ return "ns";
+ case MILLISECONDS:
+ return "ms";
+ case MICROSECONDS:
+ return "micros";
+ case SECONDS:
+ return "s";
+ case MINUTES:
+ return "m";
+ case DAYS:
+ return "d";
+ case HOURS:
+ return "h";
+ default:
+ throw new AssertionError();
+ }
+ }
+}
\ No newline at end of file

View File

@@ -1,86 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 2No2Name <2No2Name@web.de>
Date: Tue, 14 Dec 2021 12:04:01 -0500
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 82bce6109d59cba30178a446f0ff129da6f3692f..28f3145193e8bc22f3bbd0442248ea09ccc91973 100644
--- a/src/main/java/net/minecraft/core/Direction.java
+++ b/src/main/java/net/minecraft/core/Direction.java
@@ -192,7 +192,7 @@ public enum Direction implements StringRepresentable {
}
public Direction getOpposite() {
- return from3DDataValue(this.oppositeIndex);
+ return VALUES[this.oppositeIndex]; // JettPack - lithium: fast util
}
public Direction getClockWise(Direction.Axis axis) {
@@ -442,7 +442,7 @@ public enum Direction implements StringRepresentable {
}
public static Direction getRandom(RandomSource random) {
- return Util.getRandom(VALUES, random);
+ return VALUES[random.nextInt(VALUES.length)]; // JettPack - lithium: fast util
}
public static Direction getNearest(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 ffc76354ead6937daf366c3d87bcb51d3e4c47f5..5be83bcfc719db1a71b00dc4a88fd794476a8ad9 100644
--- a/src/main/java/net/minecraft/world/phys/AABB.java
+++ b/src/main/java/net/minecraft/world/phys/AABB.java
@@ -16,6 +16,15 @@ public class AABB {
public final double maxY;
public final double maxZ;
+ // JettPack start - lithium: fast_util
+ static {
+ assert Direction.Axis.X.ordinal() == 0;
+ assert Direction.Axis.Y.ordinal() == 1;
+ assert Direction.Axis.Z.ordinal() == 2;
+ assert Direction.Axis.values().length == 3;
+ }
+ // JettPack end
+
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);
@@ -81,11 +90,33 @@ public class AABB {
}
public double min(Direction.Axis axis) {
- return axis.choose(this.minX, this.minY, this.minZ);
+ // JettPack start - lithium: fast_util
+ switch (axis.ordinal()) {
+ case 0: //X
+ return this.minX;
+ case 1: //Y
+ return this.minY;
+ case 2: //Z
+ return this.minZ;
+ }
+
+ throw new IllegalArgumentException();
+ // JettPack end
}
public double max(Direction.Axis axis) {
- return axis.choose(this.maxX, this.maxY, this.maxZ);
+ // JettPack start - lithium: fast_util
+ switch (axis.ordinal()) {
+ case 0: //X
+ return this.maxX;
+ case 1: //Y
+ return this.maxY;
+ case 2: //Z
+ return this.maxZ;
+ }
+
+ throw new IllegalArgumentException();
+ // JettPack end
}
@Override

View File

@@ -1,312 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: JellySquid <jellysquid+atwork@protonmail.com>
Date: Fri, 31 Jul 2020 21:46:32 -0500
Subject: [PATCH] lithium: HashedReferenceList
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/collections/HashedReferenceList.java b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/HashedReferenceList.java
new file mode 100644
index 0000000000000000000000000000000000000000..4128567173d3985257a1bdd4412c7db0ff81535d
--- /dev/null
+++ b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/HashedReferenceList.java
@@ -0,0 +1,281 @@
+package me.jellysquid.mods.lithium.common.util.collections;
+
+import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
+import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
+import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+/**
+ * Wraps a {@link List} with a hash table which provides O(1) lookups for {@link Collection#contains(Object)}. The type
+ * contained by this list must use reference-equality semantics.
+ */
+@SuppressWarnings("SuspiciousMethodCalls")
+public class HashedReferenceList<T> implements List<T> {
+ private final ReferenceArrayList<T> list;
+ private final Reference2IntOpenHashMap<T> counter;
+
+ public HashedReferenceList(List<T> list) {
+ this.list = new ReferenceArrayList<>();
+ this.list.addAll(list);
+
+ this.counter = new Reference2IntOpenHashMap<>();
+ this.counter.defaultReturnValue(0);
+
+ for (T obj : this.list) {
+ this.counter.addTo(obj, 1);
+ }
+ }
+
+ @Override
+ public int size() {
+ return this.list.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return this.list.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return this.counter.containsKey(o);
+ }
+
+ @Override
+ public Iterator<T> iterator() {
+ return this.listIterator();
+ }
+
+ @Override
+ public Object[] toArray() {
+ return this.list.toArray();
+ }
+
+ @SuppressWarnings("SuspiciousToArrayCall")
+ @Override
+ public <T1> T1[] toArray(T1 @NotNull [] a) {
+ return this.list.toArray(a);
+ }
+
+ @Override
+ public boolean add(T t) {
+ this.trackReferenceAdded(t);
+
+ return this.list.add(t);
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ this.trackReferenceRemoved(o);
+
+ return this.list.remove(o);
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> c) {
+ for (Object obj : c) {
+ if (!this.counter.containsKey(obj)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends T> c) {
+ for (T obj : c) {
+ this.trackReferenceAdded(obj);
+ }
+
+ return this.list.addAll(c);
+ }
+
+ @Override
+ public boolean addAll(int index, Collection<? extends T> c) {
+ for (T obj : c) {
+ this.trackReferenceAdded(obj);
+ }
+
+ return this.list.addAll(index, c);
+ }
+
+ @Override
+ public boolean removeAll(@NotNull Collection<?> c) {
+ if (this.size() >= 2 && c.size() > 4 && c instanceof List) {
+ //HashReferenceList uses reference equality, so using ReferenceOpenHashSet is fine
+ c = new ReferenceOpenHashSet<>(c);
+ }
+ this.counter.keySet().removeAll(c);
+ return this.list.removeAll(c);
+ }
+
+ @Override
+ public boolean retainAll(@NotNull Collection<?> c) {
+ this.counter.keySet().retainAll(c);
+ return this.list.retainAll(c);
+ }
+
+ @Override
+ public void clear() {
+ this.counter.clear();
+ this.list.clear();
+ }
+
+ @Override
+ public T get(int index) {
+ return this.list.get(index);
+ }
+
+ @Override
+ public T set(int index, T element) {
+ T prev = this.list.set(index, element);
+
+ if (prev != element) {
+ if (prev != null) {
+ this.trackReferenceRemoved(prev);
+ }
+
+ this.trackReferenceAdded(element);
+ }
+
+ return prev;
+ }
+
+ @Override
+ public void add(int index, T element) {
+ this.trackReferenceAdded(element);
+
+ this.list.add(index, element);
+ }
+
+ @Override
+ public T remove(int index) {
+ T prev = this.list.remove(index);
+
+ if (prev != null) {
+ this.trackReferenceRemoved(prev);
+ }
+
+ return prev;
+ }
+
+ @Override
+ public int indexOf(Object o) {
+ return this.list.indexOf(o);
+ }
+
+ @Override
+ public int lastIndexOf(Object o) {
+ return this.list.lastIndexOf(o);
+ }
+
+ @Override
+ public ListIterator<T> listIterator() {
+ return this.listIterator(0);
+ }
+
+ @Override
+ public ListIterator<T> listIterator(int index) {
+ return new ListIterator<>() {
+ private final ListIterator<T> inner = HashedReferenceList.this.list.listIterator(index);
+
+ @Override
+ public boolean hasNext() {
+ return this.inner.hasNext();
+ }
+
+ @Override
+ public T next() {
+ return this.inner.next();
+ }
+
+ @Override
+ public boolean hasPrevious() {
+ return this.inner.hasPrevious();
+ }
+
+ @Override
+ public T previous() {
+ return this.inner.previous();
+ }
+
+ @Override
+ public int nextIndex() {
+ return this.inner.nextIndex();
+ }
+
+ @Override
+ public int previousIndex() {
+ return this.inner.previousIndex();
+ }
+
+ @Override
+ public void remove() {
+ int last = this.previousIndex();
+
+ if (last == -1) {
+ throw new NoSuchElementException();
+ }
+
+ T prev = HashedReferenceList.this.get(last);
+
+ if (prev != null) {
+ HashedReferenceList.this.trackReferenceRemoved(prev);
+ }
+
+ this.inner.remove();
+ }
+
+ @Override
+ public void set(T t) {
+ int last = this.previousIndex();
+
+ if (last == -1) {
+ throw new NoSuchElementException();
+ }
+
+ T prev = HashedReferenceList.this.get(last);
+
+ if (prev != t) {
+ if (prev != null) {
+ HashedReferenceList.this.trackReferenceRemoved(prev);
+ }
+
+ HashedReferenceList.this.trackReferenceAdded(t);
+ }
+
+ this.inner.remove();
+ }
+
+ @Override
+ public void add(T t) {
+ HashedReferenceList.this.trackReferenceAdded(t);
+
+ this.inner.add(t);
+ }
+ };
+ }
+
+ @Override
+ public List<T> subList(int fromIndex, int toIndex) {
+ return this.list.subList(fromIndex, toIndex);
+ }
+
+ private void trackReferenceAdded(T t) {
+ this.counter.addTo(t, 1);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void trackReferenceRemoved(Object o) {
+ if (this.counter.addTo((T) o, -1) <= 1) {
+ this.counter.removeInt(o);
+ }
+ }
+
+ public static <T> HashedReferenceList<T> wrapper(List<T> list) {
+ return new HashedReferenceList<>(list);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 6aec1983a0236d6aa0507a2b3ad1c08b3330f0fc..78069d2dbd4ee5624e99a76547cbba354ef0b96e 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -118,9 +118,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
public static final int TICKS_PER_DAY = 24000;
public static final int MAX_ENTITY_SPAWN_Y = 20000000;
public static final int MIN_ENTITY_SPAWN_Y = -20000000;
- protected final List<TickingBlockEntity> blockEntityTickers = Lists.newArrayList(); public final int getTotalTileEntityTickers() { return this.blockEntityTickers.size(); } // Paper
+ protected final List<TickingBlockEntity> blockEntityTickers = me.jellysquid.mods.lithium.common.util.collections.HashedReferenceList.wrapper(Lists.newArrayList()); public final int getTotalTileEntityTickers() { return this.blockEntityTickers.size(); } // Paper // Jettpack - lithium: HashedReferenceList
protected final NeighborUpdater neighborUpdater;
- private final List<TickingBlockEntity> pendingBlockEntityTickers = Lists.newArrayList();
+ private final List<TickingBlockEntity> pendingBlockEntityTickers = me.jellysquid.mods.lithium.common.util.collections.HashedReferenceList.wrapper(Lists.newArrayList()); // Jettpack - lithium: HashedReferenceList
private boolean tickingBlockEntities;
public final Thread thread;
private final boolean isDebug;

View File

@@ -1,79 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ivan Pekov <ivan@mrivanplays.com>
Date: Sun, 27 Sep 2020 18:30:10 +0300
Subject: [PATCH] Add last tick time API
Original code by YatopiaMC, licensed under MIT
You can find the original code on https://github.com/YatopiaMC/Yatopia
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 9945d6efac1e1ea0d22d6fdfe8aa5d2805c615b2..b91a634777065969a4f3bb569a32c3645d42c4af 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1098,6 +1098,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Spigot End
public static volatile RuntimeException chunkSystemCrash; // Paper - rewrite chunk system
+ public static java.time.Duration lastTickTime = java.time.Duration.ZERO; // Yatopia
protected void runServer() {
try {
@@ -1172,7 +1173,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.nextTickTime += 50L;
this.startMetricsRecordingTick();
this.profiler.push("tick");
+ long tickStart = System.nanoTime(); // Yatopia
this.tickServer(this::haveTime);
+ lastTickTime = java.time.Duration.ofNanos(System.nanoTime() - tickStart); // Yatopia
this.profiler.popPush("nextTickWait");
this.mayHaveDelayedTasks = true;
this.delayedTasksMaxNextTickTime = Math.max(Util.getMillis() + 50L, this.nextTickTime);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index efc137a8a9f1da4a7ffff6028af368cc7f90d20a..b8f51b262561fce967f99801ad595de8faaddd0d 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2922,6 +2922,12 @@ public final class CraftServer implements Server {
public CraftPotionBrewer getPotionBrewer() {
return this.potionBrewer;
}
-
// Paper end
+
+ // Yatopia start
+ @Override
+ public java.time.Duration getLastTickTime() {
+ return net.minecraft.server.MinecraftServer.lastTickTime;
+ }
+ // Yatopia end
}
diff --git a/src/main/java/org/spigotmc/TicksPerSecondCommand.java b/src/main/java/org/spigotmc/TicksPerSecondCommand.java
index 9bede6a26c08ede063c7a38f1149c811df14b258..b735769b7876e54db2950ebb4170484447cfb9a6 100644
--- a/src/main/java/org/spigotmc/TicksPerSecondCommand.java
+++ b/src/main/java/org/spigotmc/TicksPerSecondCommand.java
@@ -32,6 +32,10 @@ public class TicksPerSecondCommand extends Command
tpsAvg[i] = TicksPerSecondCommand.format( tps[i] );
}
sender.sendMessage(ChatColor.GOLD + "TPS from last 1m, 5m, 15m: " + org.apache.commons.lang.StringUtils.join(tpsAvg, ", "));
+ // Yatopia start - Last tick time API
+ java.time.Duration lastTickTime = org.bukkit.Bukkit.getLastTickTime();
+ sender.sendMessage(ChatColor.GOLD + "Last tick: " + TicksPerSecondCommand.formatTo( lastTickTime, java.util.concurrent.TimeUnit.MILLISECONDS ) + " (" + formatTo( lastTickTime, java.util.concurrent.TimeUnit.NANOSECONDS ) + ")");
+ // Yatopia end
if (args.length > 0 && args[0].equals("mem") && sender.hasPermission("bukkit.command.tpsmemory")) {
sender.sendMessage(ChatColor.GOLD + "Current Memory Usage: " + ChatColor.GREEN + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024)) + "/" + (Runtime.getRuntime().totalMemory() / (1024 * 1024)) + " mb (Max: " + (Runtime.getRuntime().maxMemory() / (1024 * 1024)) + " mb)");
if (!hasShownMemoryWarning) {
@@ -50,4 +54,15 @@ public class TicksPerSecondCommand extends Command
return ( ( tps > 18.0 ) ? ChatColor.GREEN : ( tps > 16.0 ) ? ChatColor.YELLOW : ChatColor.RED ).toString()
+ ( ( tps > 21.0 ) ? "*" : "" ) + Math.min( Math.round( tps * 100.0 ) / 100.0, 20.0 ); // Paper - only print * at 21, we commonly peak to 20.02 as the tick sleep is not accurate enough, stop the noise
}
+
+ // Yatopia start - Last tick time API
+ public static String formatTo(java.time.Duration duration, java.util.concurrent.TimeUnit unit) {
+ java.util.concurrent.TimeUnit nanosUnit = java.util.concurrent.TimeUnit.NANOSECONDS;
+ long nanos = duration.toNanos();
+ long toAskedUnit = unit.convert( nanos, nanosUnit );
+ long ms = nanosUnit.toMillis( nanos );
+ ChatColor startingColor = ms < 40 ? ChatColor.GREEN : ( ms < 50 ) ? ChatColor.YELLOW : ChatColor.RED;
+ return startingColor.toString() + toAskedUnit + ChatColor.GOLD + org.yatopiamc.yatopia.server.util.TimeUtils.getFriendlyName( unit );
+ }
+ // Yatopia end
}

View File

@@ -1,112 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Gegy <gegy1000@gmail.com>
Date: Fri, 21 Jan 2022 10:19:06 -0500
Subject: [PATCH] lithium: shapes.blockstate_cache
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/collections/Object2BooleanCacheTable.java b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/Object2BooleanCacheTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..a833ec84b2053c805dd33821cc08939c1cb79e96
--- /dev/null
+++ b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/Object2BooleanCacheTable.java
@@ -0,0 +1,59 @@
+package me.jellysquid.mods.lithium.common.util.collections;
+
+import it.unimi.dsi.fastutil.HashCommon;
+import java.util.function.Predicate;
+import net.minecraft.util.Mth;
+
+/**
+ * A lossy hashtable implementation that stores a mapping between an object and a boolean.
+ * <p>
+ * Any hash collisions will result in an overwrite: this is safe because the correct value can always be recomputed,
+ * given that the given operator is deterministic.
+ * <p>
+ * This implementation is safe to use from multiple threads
+ */
+public final class Object2BooleanCacheTable<T> {
+ private final int mask;
+
+ private final Node<T>[] nodes;
+
+ private final Predicate<T> operator;
+
+ @SuppressWarnings("unchecked")
+ public Object2BooleanCacheTable(int capacity, Predicate<T> operator) {
+ int capacity1 = Mth.smallestEncompassingPowerOfTwo(capacity);
+ this.mask = capacity1 - 1;
+
+ this.nodes = (Node<T>[]) new Node[capacity1];
+
+ this.operator = operator;
+ }
+
+ private static <T> int hash(T key) {
+ return HashCommon.mix(key.hashCode());
+ }
+
+ public boolean get(T key) {
+ int idx = hash(key) & this.mask;
+
+ Node<T> node = this.nodes[idx];
+ if (node != null && key.equals(node.key)) {
+ return node.value;
+ }
+
+ boolean test = this.operator.test(key);
+ this.nodes[idx] = new Node<>(key, test);
+
+ return test;
+ }
+
+ static class Node<T> {
+ final T key;
+ final boolean value;
+
+ Node(T key, boolean value) {
+ this.key = key;
+ this.value = value;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
index 7b71073027f4cf79736546500ededdfbb83d968e..40f0e57bed6866bff69231b9135987ca53125ba3 100644
--- a/src/main/java/net/minecraft/world/level/block/Block.java
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
@@ -62,17 +62,19 @@ import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.slf4j.Logger;
+import me.jellysquid.mods.lithium.common.util.collections.Object2BooleanCacheTable; // JettPack
public class Block extends BlockBehaviour implements ItemLike {
private static final Logger LOGGER = LogUtils.getLogger();
private final Holder.Reference<Block> builtInRegistryHolder;
public static final IdMapper<BlockState> BLOCK_STATE_REGISTRY = new IdMapper<>();
- private static final LoadingCache<VoxelShape, Boolean> SHAPE_FULL_BLOCK_CACHE = CacheBuilder.newBuilder().maximumSize(512L).weakKeys().build(new CacheLoader<VoxelShape, Boolean>() {
- public Boolean load(VoxelShape voxelshape) {
- return !Shapes.joinIsNotEmpty(Shapes.block(), voxelshape, BooleanOp.NOT_SAME);
- }
- });
+ // JettPack start - lithium: shapes.blockstate_cache
+ private static final Object2BooleanCacheTable<VoxelShape> FULL_CUBE_CACHE = new Object2BooleanCacheTable<>(
+ 512,
+ shape -> !Shapes.joinIsNotEmpty(Shapes.block(), shape, BooleanOp.NOT_SAME)
+ );
+ // JettPack end
public static final int UPDATE_NEIGHBORS = 1;
public static final int UPDATE_CLIENTS = 2;
public static final int UPDATE_INVISIBLE = 4;
@@ -279,7 +281,7 @@ public class Block extends BlockBehaviour implements ItemLike {
}
public static boolean isShapeFullBlock(VoxelShape shape) {
- return (Boolean) Block.SHAPE_FULL_BLOCK_CACHE.getUnchecked(shape);
+ return FULL_CUBE_CACHE.get(shape); // JettPack - lithium: shapes.blockstate_cache
}
public boolean propagatesSkylightDown(BlockState state, BlockGetter world, BlockPos pos) {

View File

@@ -1,79 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: jellysquid3 <jellysquid3@users.noreply.github.com>
Date: Tue, 18 Jan 2022 10:37:18 -0500
Subject: [PATCH] lithium: ai.raid
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
diff --git a/src/main/java/net/minecraft/world/entity/raid/Raid.java b/src/main/java/net/minecraft/world/entity/raid/Raid.java
index 08b18428e867baf14f551beb72e3875b0c420639..d43927cdc77342d3fa03ae12f099fec93f473010 100644
--- a/src/main/java/net/minecraft/world/entity/raid/Raid.java
+++ b/src/main/java/net/minecraft/world/entity/raid/Raid.java
@@ -269,7 +269,16 @@ public class Raid {
this.status = Raid.RaidStatus.STOPPED;
}
+ private boolean isBarDirty; // JettPack
public void tick() {
+ // JettPack start - lithium: ai.raid
+ if (this.isBarDirty) {
+ this.raidEvent.setProgress(Mth.clamp(this.getHealthOfLivingRaiders() / this.totalHealth, 0.0F, 1.0F));
+
+ this.isBarDirty = false;
+ }
+ // JettPack end
+
if (!this.isStopped()) {
if (this.status == Raid.RaidStatus.ONGOING) {
boolean flag = this.active;
@@ -638,7 +647,7 @@ public class Raid {
}
public void updateBossbar() {
- this.raidEvent.setProgress(Mth.clamp(this.getHealthOfLivingRaiders() / this.totalHealth, 0.0F, 1.0F));
+ this.isBarDirty = true; // JettPack - lithium: ai.raid
}
public float getHealthOfLivingRaiders() {
diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java
index e5ccbaf72f29731f1d1aa939b9297b644a408cd4..940fcebe1e1ab7d249487d58958b24b62fb8eaab 100644
--- a/src/main/java/net/minecraft/world/entity/raid/Raider.java
+++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java
@@ -46,8 +46,9 @@ import net.minecraft.world.phys.Vec3;
public abstract class Raider extends PatrollingMonster {
protected static final EntityDataAccessor<Boolean> IS_CELEBRATING = SynchedEntityData.defineId(Raider.class, EntityDataSerializers.BOOLEAN);
+ public static final ItemStack CACHED_OMINOUS_BANNER = Raid.getLeaderBannerInstance(); // JettPack - lithium: ai.raid
static final Predicate<ItemEntity> ALLOWED_ITEMS = (entityitem) -> {
- return !entityitem.hasPickUpDelay() && entityitem.isAlive() && ItemStack.matches(entityitem.getItem(), Raid.getLeaderBannerInstance());
+ return !entityitem.hasPickUpDelay() && entityitem.isAlive() && ItemStack.matches(entityitem.getItem(), CACHED_OMINOUS_BANNER); // JettPack - lithium: ai.raid
};
@Nullable
protected Raid raid;
@@ -149,7 +150,7 @@ public abstract class Raider extends PatrollingMonster {
}
}
- if (!itemstack.isEmpty() && ItemStack.matches(itemstack, Raid.getLeaderBannerInstance()) && entityhuman != null) {
+ if (!itemstack.isEmpty() && ItemStack.matches(itemstack, CACHED_OMINOUS_BANNER) && entityhuman != null) { // JettPack - lithium: ai.raid
MobEffectInstance mobeffect = entityhuman.getEffect(MobEffects.BAD_OMEN);
byte b0 = 1;
int i;
@@ -311,6 +312,7 @@ public abstract class Raider extends PatrollingMonster {
public class ObtainRaidLeaderBannerGoal<T extends Raider> extends Goal {
private final T mob;
+ private static final ItemStack CACHED_OMINOUS_BANNER = Raid.getLeaderBannerInstance(); // JettPack
public ObtainRaidLeaderBannerGoal(T entityraider) { // CraftBukkit - decompile error
this.mob = entityraider;
@@ -322,7 +324,7 @@ public abstract class Raider extends PatrollingMonster {
if (!this.mob.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || !this.mob.canPickUpLoot()) return false; // Paper - respect game and entity rules for picking up items
Raid raid = this.mob.getCurrentRaid();
- if (this.mob.hasActiveRaid() && !this.mob.getCurrentRaid().isOver() && this.mob.canBeLeader() && !ItemStack.matches(this.mob.getItemBySlot(EquipmentSlot.HEAD), Raid.getLeaderBannerInstance())) {
+ if (this.mob.hasActiveRaid() && !this.mob.getCurrentRaid().isOver() && this.mob.canBeLeader() && !ItemStack.matches(this.mob.getItemBySlot(EquipmentSlot.HEAD), CACHED_OMINOUS_BANNER)) { // JettPack - lithium: ai.raid
Raider entityraider = raid.getLeader(this.mob.getWave());
if (entityraider == null || !entityraider.isAlive()) {

View File

@@ -1,82 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ivan Pekov <ivan@mrivanplays.com>
Date: Fri, 4 Sep 2020 10:07:42 +0300
Subject: [PATCH] Stop wasting resources on JsonList#get
Original code by YatopiaMC, licensed under MIT
You can find the original code on https://github.com/YatopiaMC/Yatopia
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index c0c14766adaac855112f85a203a6163b8adfdded..d4e3bc6dc71740d2f989e87f9b5cc48ac96ba8d5 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -702,13 +702,19 @@ public abstract class PlayerList {
if (getBans().isBanned(gameprofile) && (gameprofilebanentry = getBans().get(gameprofile)) != null) {
// Paper end
- ichatmutablecomponent = Component.translatable("multiplayer.disconnect.banned.reason", gameprofilebanentry.getReason());
- if (gameprofilebanentry.getExpires() != null) {
- ichatmutablecomponent.append((Component) Component.translatable("multiplayer.disconnect.banned.expiration", PlayerList.BAN_DATE_FORMAT.format(gameprofilebanentry.getExpires())));
- }
+ // Yatopia start - Stop wasting resources on JsonList#get
+ if (!gameprofilebanentry.hasExpired()) {
+ ichatmutablecomponent = Component.translatable("multiplayer.disconnect.banned.reason", gameprofilebanentry.getReason());
+ if (gameprofilebanentry.getExpires() != null) {
+ ichatmutablecomponent.append((Component) Component.translatable("multiplayer.disconnect.banned.expiration", PlayerList.BAN_DATE_FORMAT.format(gameprofilebanentry.getExpires())));
+ }
- // return chatmessage;
- event.disallow(PlayerLoginEvent.Result.KICK_BANNED, PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure
+ // return chatmessage;
+ event.disallow(PlayerLoginEvent.Result.KICK_BANNED, PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure
+ } else {
+ getBans().remove(gameprofile);
+ }
+ // Yatopia end
} else if (!this.isWhiteListed(gameprofile, event)) { // Paper
//ichatmutablecomponent = Component.translatable("multiplayer.disconnect.not_whitelisted"); // Paper
//event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.whitelistMessage)); // Spigot // Paper - Adventure - moved to isWhitelisted
diff --git a/src/main/java/net/minecraft/server/players/StoredUserList.java b/src/main/java/net/minecraft/server/players/StoredUserList.java
index 4fd709a550bf8da1e996894a1ca6b91206c31e9e..bf959b19b068a7cfbb9bed72448a4139b7d50095 100644
--- a/src/main/java/net/minecraft/server/players/StoredUserList.java
+++ b/src/main/java/net/minecraft/server/players/StoredUserList.java
@@ -73,9 +73,12 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
// Paper start
// this.g();
// return (V) this.d.get(this.a(k0)); // CraftBukkit - fix decompile error
- return (V) this.map.computeIfPresent(this.getKeyForUser(key), (k, v) -> {
+ // Yatopia start - Stop wasting resources on JsonList#get
+ return this.map.get(this.getKeyForUser(key));
+ /*return (V) this.map.computeIfPresent(this.getKeyForUser(key), (k, v) -> {
return v.hasExpired() ? null : v;
- });
+ });*/
+ // Yatopia end
// Paper end
}
@@ -150,7 +153,8 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
public void save() throws IOException {
this.removeExpired(); // Paper - remove expired values before saving
JsonArray jsonarray = new JsonArray();
- Stream<JsonObject> stream = this.map.values().stream().map((jsonlistentry) -> { // CraftBukkit - decompile error
+ // Yatopia start - Stop wasting resources on JsonList#get
+ /*Stream<JsonObject> stream = this.map.values().stream().map((jsonlistentry) -> { // CraftBukkit - decompile error
JsonObject jsonobject = new JsonObject();
Objects.requireNonNull(jsonlistentry);
@@ -158,7 +162,13 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
});
Objects.requireNonNull(jsonarray);
- stream.forEach(jsonarray::add);
+ stream.forEach(jsonarray::add);*/
+ for (V value : this.map.values()) {
+ JsonObject obj = new JsonObject();
+ value.serialize(obj);
+ jsonarray.add(obj);
+ }
+ // Yatopia end
BufferedWriter bufferedwriter = Files.newWriter(this.file, StandardCharsets.UTF_8);
try {

View File

@@ -1,43 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: foss-mc <69294560+foss-mc@users.noreply.github.com>
Date: Thu, 1 Jul 2021 12:17:44 +0000
Subject: [PATCH] Don't create new random instance
Original code by PatinaMC, licensed under GNU General Public License v3.0
You can find the original code on https://github.com/PatinaMC/Patina
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index ca5291a9573a62cb5c19539cf5c7aceff11f9829..5f3658625c05e9e1ff3e4685ce4cb5f6eb66cc49 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -396,7 +396,7 @@ public class ServerPlayer extends Player {
long l = k * k;
int i1 = l > 2147483647L ? Integer.MAX_VALUE : (int) l;
int j1 = this.getCoprime(i1);
- int k1 = RandomSource.create().nextInt(i1);
+ int k1 = worldserver.random.nextInt(i1); // Patina - don't create new random instance
for (int l1 = 0; l1 < i1; ++l1) {
int i2 = (k1 + j1 * l1) % i1;
@@ -433,7 +433,7 @@ public class ServerPlayer extends Player {
long l = k * k;
int i1 = l > 2147483647L ? Integer.MAX_VALUE : (int) l;
int j1 = this.getCoprime(i1);
- int k1 = RandomSource.create().nextInt(i1);
+ int k1 = world.random.nextInt(i1); // Patina - don't create new random instance
for (int l1 = 0; l1 < i1; ++l1) {
int i2 = (k1 + j1 * l1) % i1;
diff --git a/src/main/java/net/minecraft/server/rcon/thread/QueryThreadGs4.java b/src/main/java/net/minecraft/server/rcon/thread/QueryThreadGs4.java
index 1ef089dbf83de35d875c00efdf468c397be56978..c345f10cbf7f3451edc604f97cdf959d70639e17 100644
--- a/src/main/java/net/minecraft/server/rcon/thread/QueryThreadGs4.java
+++ b/src/main/java/net/minecraft/server/rcon/thread/QueryThreadGs4.java
@@ -349,7 +349,7 @@ public class QueryThreadGs4 extends GenericThread {
this.identBytes[2] = bs[5];
this.identBytes[3] = bs[6];
this.ident = new String(this.identBytes, StandardCharsets.UTF_8);
- this.challenge = RandomSource.create().nextInt(16777216);
+ this.challenge = java.util.concurrent.ThreadLocalRandom.current().nextInt(16777216); // Patina - don't create new random instance
this.challengeBytes = String.format(Locale.ROOT, "\t%s%d\u0000", this.ident, this.challenge).getBytes(StandardCharsets.UTF_8);
}

View File

@@ -1,38 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Wed, 6 Jan 2021 02:19:29 -0600
Subject: [PATCH] Fix rotating UP/DOWN CW and CCW
Original code by PurpurMC, licensed under MIT
You can find the original code on https://github.com/PurpurMC/Purpur
diff --git a/src/main/java/net/minecraft/core/Direction.java b/src/main/java/net/minecraft/core/Direction.java
index 28f3145193e8bc22f3bbd0442248ea09ccc91973..28ecd137dd37759e7890d71635289c3f6e994b87 100644
--- a/src/main/java/net/minecraft/core/Direction.java
+++ b/src/main/java/net/minecraft/core/Direction.java
@@ -248,6 +248,12 @@ public enum Direction implements StringRepresentable {
case EAST:
var10000 = SOUTH;
break;
+ // Purpur start
+ case UP:
+ return UP;
+ case DOWN:
+ return DOWN;
+ // Purpur end
default:
throw new IllegalStateException("Unable to get Y-rotated facing of " + this);
}
@@ -360,6 +366,12 @@ public enum Direction implements StringRepresentable {
case EAST:
var10000 = NORTH;
break;
+ // Purpur start
+ case UP:
+ return UP;
+ case DOWN:
+ return DOWN;
+ // Purpur end
default:
throw new IllegalStateException("Unable to get CCW facing of " + this);
}

View File

@@ -1,32 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 28 Mar 2020 01:51:32 -0500
Subject: [PATCH] Fix vanilla command permission handler
Original code by PurpurMC, licensed under MIT
You can find the original code on https://github.com/PurpurMC/Purpur
diff --git a/src/main/java/com/mojang/brigadier/tree/CommandNode.java b/src/main/java/com/mojang/brigadier/tree/CommandNode.java
index 39844531b03eb8a6c70700b4ecbf0ff1a557424d..632ae75cb3bbc7a3955872d14ad0fbc2459f32e8 100644
--- a/src/main/java/com/mojang/brigadier/tree/CommandNode.java
+++ b/src/main/java/com/mojang/brigadier/tree/CommandNode.java
@@ -35,6 +35,7 @@ public abstract class CommandNode<S> implements Comparable<CommandNode<S>> {
private final boolean forks;
private Command<S> command;
public LiteralCommandNode<CommandSourceStack> clientNode = null; // Paper
+ private String permission = null; public String getPermission() { return permission; } public void setPermission(String permission) { this.permission = permission; } // Purpur
// CraftBukkit start
public void removeCommand(String name) {
this.children.remove(name);
diff --git a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
index 6035af2cf08353b3d3801220d8116d8611a0cd37..7774ab6a2e553a40def4bb4dceea9e5f58d31c1e 100644
--- a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
+++ b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
@@ -94,6 +94,7 @@ public final class VanillaCommandWrapper extends BukkitCommand {
}
public static String getPermission(CommandNode<CommandSourceStack> vanillaCommand) {
+ if (vanillaCommand.getPermission() != null) return vanillaCommand.getPermission(); // Purpur
// Paper start
final String commandName;
if (vanillaCommand.getRedirect() == null) {

View File

@@ -1,80 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Simon Gardling <titaniumtown@gmail.com>
Date: Mon, 6 Dec 2021 10:34:33 -0500
Subject: [PATCH] Remove Spigot tick limiter
Original code by Titaniumtown, licensed under GNU General Public License v3.0
You can find the original code on https://gitlab.com/Titaniumtown/JettPack
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 78069d2dbd4ee5624e99a76547cbba354ef0b96e..234d7c309bd386862b6f9ddc8dc2d469ecf30030 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -179,8 +179,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
public final com.destroystokyo.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray
public final co.aikar.timings.WorldTimingsHandler timings; // Paper
public static BlockPos lastPhysicsProblem; // Spigot
- private org.spigotmc.TickLimiter entityLimiter;
- private org.spigotmc.TickLimiter tileLimiter;
+ //private org.spigotmc.TickLimiter entityLimiter; // JettPack - remove tick limiter
+ //private org.spigotmc.TickLimiter tileLimiter; // JettPack - remove tick limiter
private int tileTickPosition;
public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here
@@ -376,8 +376,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
// CraftBukkit end
timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings
this.keepSpawnInMemory = this.paperConfig().spawn.keepSpawnLoaded; // Paper
- this.entityLimiter = new org.spigotmc.TickLimiter(spigotConfig.entityMaxTickTime);
- this.tileLimiter = new org.spigotmc.TickLimiter(spigotConfig.tileMaxTickTime);
+ //this.entityLimiter = new org.spigotmc.TickLimiter(spigotConfig.entityMaxTickTime); // JettPack - remove tick limiter
+ //this.tileLimiter = new org.spigotmc.TickLimiter(spigotConfig.tileMaxTickTime); // JettPack - remove tick limiter
this.chunkPacketBlockController = this.paperConfig().anticheat.antiXray.enabled ? new com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray(this, executor) : com.destroystokyo.paper.antixray.ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray
}
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 5503ad6a93d331771a0e92c0da6adedf2ac81aff..7c1efc3b6045b2179139dd419e969569f1af9f6d 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -442,6 +442,7 @@ public class SpigotWorldConfig
this.hangingTickFrequency = this.getInt( "hanging-tick-frequency", 100 );
}
+ /* JettPack - remove tick limiter
public int tileMaxTickTime;
public int entityMaxTickTime;
private void maxTickTimes()
@@ -450,6 +451,7 @@ public class SpigotWorldConfig
this.entityMaxTickTime = this.getInt("max-tick-time.entity", 50);
this.log("Tile Max Tick Time: " + this.tileMaxTickTime + "ms Entity max Tick Time: " + this.entityMaxTickTime + "ms");
}
+ */
public int thunderChance;
private void thunderChance()
diff --git a/src/main/java/org/spigotmc/TickLimiter.java b/src/main/java/org/spigotmc/TickLimiter.java
deleted file mode 100644
index 4074538ea6090bf99d8ab04b1e98c2832a0e9a98..0000000000000000000000000000000000000000
--- a/src/main/java/org/spigotmc/TickLimiter.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.spigotmc;
-
-public class TickLimiter {
-
- private final int maxTime;
- private long startTime;
-
- public TickLimiter(int maxtime) {
- this.maxTime = maxtime;
- }
-
- public void initTick() {
- this.startTime = System.currentTimeMillis();
- }
-
- public boolean shouldContinue() {
- long remaining = System.currentTimeMillis() - this.startTime;
- return remaining < this.maxTime;
- }
-}

View File

@@ -1,24 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sat, 28 Dec 2013 21:25:06 -0500
Subject: [PATCH] Don't save Fireworks
Original code by Starlis, licensed under GNU General Public License v3.0
You can find the original code on https://github.com/starlis/empirecraft
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java b/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
index fca27f98989bf106060ba08196255fe32f850df5..d154a5d84cbb56f62a028d32ff48e9eb0a5dd829 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
@@ -357,4 +357,11 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier {
public boolean isAttackable() {
return false;
}
+
+ // EMC start
+ @Override
+ public boolean shouldBeSaved() {
+ return false;
+ }
+ // EMC end
}

View File

@@ -1,88 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Sun, 17 Oct 2021 14:53:35 -0400
Subject: [PATCH] Paper PR - BoneMeal API
diff --git a/src/main/java/net/minecraft/world/item/BoneMealItem.java b/src/main/java/net/minecraft/world/item/BoneMealItem.java
index c26665bc59c18c4da467fb6ae33e51a65ecf1de6..db31b8e00f63f3fa265dcc669816a5a250ee4910 100644
--- a/src/main/java/net/minecraft/world/item/BoneMealItem.java
+++ b/src/main/java/net/minecraft/world/item/BoneMealItem.java
@@ -36,15 +36,17 @@ public class BoneMealItem extends Item {
// CraftBukkit start - extract bonemeal application logic to separate, static method
return BoneMealItem.applyBonemeal(context);
}
-
- public static InteractionResult applyBonemeal(UseOnContext itemactioncontext) {
+ // Paper start - BoneMeal API
+ public static InteractionResult applyBonemeal(UseOnContext itemactioncontext) { return applyBonemeal(itemactioncontext, true); }
+ public static InteractionResult applyBonemeal(UseOnContext itemactioncontext, boolean showParticles) {
+ // Paper end - BoneMeal API
// CraftBukkit end
Level world = itemactioncontext.getLevel();
BlockPos blockposition = itemactioncontext.getClickedPos();
BlockPos blockposition1 = blockposition.relative(itemactioncontext.getClickedFace());
if (BoneMealItem.growCrop(itemactioncontext.getItemInHand(), world, blockposition)) {
- if (!world.isClientSide) {
+ if (showParticles && !world.isClientSide) { // Paper - BoneMeal API
world.levelEvent(1505, blockposition, 0);
}
@@ -54,7 +56,7 @@ public class BoneMealItem extends Item {
boolean flag = iblockdata.isFaceSturdy(world, blockposition, itemactioncontext.getClickedFace());
if (flag && BoneMealItem.growWaterPlant(itemactioncontext.getItemInHand(), world, blockposition1, itemactioncontext.getClickedFace())) {
- if (!world.isClientSide) {
+ if (showParticles && !world.isClientSide) { // Paper - BoneMeal API
world.levelEvent(1505, blockposition1, 0);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 5e9055fdf411029ea2fed91acd6b981f79156418..d3ceb6925c86640663439a9dc413df1d9126cc5f 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -2394,5 +2394,43 @@ public class CraftWorld extends CraftRegionAccessor implements World {
return this.adventure$pointers;
}
+
+ @Override
+ public boolean applyBoneMeal(@org.jetbrains.annotations.NotNull Location location, org.bukkit.block.BlockFace face, boolean showParticles, @org.jetbrains.annotations.Nullable Predicate<BlockState> predicate) {
+ BlockPos pos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
+ net.minecraft.world.item.context.UseOnContext context = new net.minecraft.world.item.context.UseOnContext(this.getHandle(), null, net.minecraft.world.InteractionHand.MAIN_HAND, net.minecraft.world.item.Items.BONE_MEAL.getDefaultInstance(), new net.minecraft.world.phys.BlockHitResult(Vec3.ZERO, CraftBlock.blockFaceToNotch(face), pos, false));
+
+ // Save old capturing state
+ boolean wasCapturingTrees = world.captureTreeGeneration;
+ boolean wasCapturingBlockStates = world.captureBlockStates;
+
+ Map<BlockPos, org.bukkit.craftbukkit.block.CraftBlockState> capturedBlocks = world.capturedBlockStates;
+ Map<BlockPos, net.minecraft.world.level.block.entity.BlockEntity> capturedTileEntities = world.capturedTileEntities;
+
+ // Create new state, capture everything
+ world.capturedBlockStates = new java.util.LinkedHashMap<>();
+ world.capturedTileEntities = new java.util.LinkedHashMap<>();
+
+ world.captureTreeGeneration = true;
+ world.captureBlockStates = true;
+
+ net.minecraft.world.InteractionResult result = net.minecraft.world.item.BoneMealItem.applyBonemeal(context, showParticles);
+
+ // Revert back booleans
+ world.captureTreeGeneration = wasCapturingTrees;
+ world.captureBlockStates = wasCapturingBlockStates;
+
+ for (BlockState blockState : world.capturedBlockStates.values()) {
+ if (predicate != null && predicate.test(blockState)) {
+ blockState.update(true);
+ }
+ }
+
+ // Revertback maps
+ world.capturedBlockStates = capturedBlocks;
+ world.capturedTileEntities = capturedTileEntities;
+
+ return result == net.minecraft.world.InteractionResult.CONSUME;
+ }
// Paper end
}

View File

@@ -1,20 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Thu, 14 Jan 2016 00:49:14 -0500
Subject: [PATCH] Do not drop items from Give command
Original code by Starlis, licensed under GNU General Public License v3.0
You can find the original code on https://github.com/starlis/empirecraft
diff --git a/src/main/java/net/minecraft/server/commands/GiveCommand.java b/src/main/java/net/minecraft/server/commands/GiveCommand.java
index ee7d29d85c8b024c9b23cba8ecd4192aa7e8aa7b..e50d8c5f6c4f2aa672732d1d42c4995c9b377530 100644
--- a/src/main/java/net/minecraft/server/commands/GiveCommand.java
+++ b/src/main/java/net/minecraft/server/commands/GiveCommand.java
@@ -58,6 +58,7 @@ public class GiveCommand {
boolean flag = entityplayer.getInventory().add(itemstack);
ItemEntity entityitem;
+ if (true) { continue; } // EMC - never drop items
if (flag && itemstack.isEmpty()) {
itemstack.setCount(1);
entityitem = entityplayer.drop(itemstack, false, false, false); // SPIGOT-2942: Add boolean to call event

View File

@@ -1,26 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Fri, 3 May 2019 23:53:16 -0500
Subject: [PATCH] Fix cow rotation when shearing mooshroom
Original code by PurpurMC, licensed under MIT
You can find the original code on https://github.com/PurpurMC/Purpur
diff --git a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
index 68a5ee85e64802e4509ba0d184fc0ceb3cbe2d11..a8b44440b0a06f227f1d50bf77794fc15aea4230 100644
--- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
+++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
@@ -180,7 +180,13 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder<Mushroo
// this.discard(); // CraftBukkit - moved down
entitycow.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());
entitycow.setHealth(this.getHealth());
+ // Purpur start
+ entitycow.copyPosition(this);
entitycow.yBodyRot = this.yBodyRot;
+ entitycow.setYHeadRot(this.getYHeadRot());
+ entitycow.yRotO = this.yRotO;
+ entitycow.xRotO = this.xRotO;
+ // Purpur end
if (this.hasCustomName()) {
entitycow.setCustomName(this.getCustomName());
entitycow.setCustomNameVisible(this.isCustomNameVisible());

View File

@@ -1,20 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 21 Mar 2020 18:33:05 -0500
Subject: [PATCH] End gateway should check if entity can use portal
Original code by PurpurMC, licensed under MIT
You can find the original code on https://github.com/PurpurMC/Purpur
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
index c73024cc62490c336ffe26313580e88d25ca7078..690d498a97b943a62e8ea415450ca44a2349fee0 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
@@ -178,6 +178,7 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity {
public static void teleportEntity(Level world, BlockPos pos, BlockState state, Entity entity, TheEndGatewayBlockEntity blockEntity) {
if (world instanceof ServerLevel && !blockEntity.isCoolingDown()) {
+ if (!entity.canChangeDimensions()) return; // Purpur
ServerLevel worldserver = (ServerLevel) world;
blockEntity.teleportCooldown = 100;

View File

@@ -1,24 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Wed, 4 Nov 2020 13:12:50 -0600
Subject: [PATCH] Arrows should not reset despawn counter
This prevents keeping arrows alive indefinitely (such as when the block
the arrow is stuck in gets removed, like a piston head going up/down)
Original code by PurpurMC, licensed under MIT
You can find the original code on https://github.com/PurpurMC/Purpur
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
index 5d6d26cfe8f0ab68a3145214b3fc126ca7a71a66..6d00e5d22147ae69de3723a46eabf0ecc577d421 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
@@ -312,7 +312,7 @@ public abstract class AbstractArrow extends Projectile {
Vec3 vec3d = this.getDeltaMovement();
this.setDeltaMovement(vec3d.multiply((double) (this.random.nextFloat() * 0.2F), (double) (this.random.nextFloat() * 0.2F), (double) (this.random.nextFloat() * 0.2F)));
- this.life = 0;
+ // this.life = 0; // Purpur - do not reset despawn counter
}
@Override

View File

@@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Fri, 11 Nov 2022 16:53:54 +0300
Subject: [PATCH] Skip cloning loot parameters
diff --git a/src/main/java/net/minecraft/advancements/Advancement.java b/src/main/java/net/minecraft/advancements/Advancement.java
index 31ef13a708db2e4a664b30090a562eb6e4597bab..f18357d4dffbfe35d7c205fec0cc026020afdf25 100644
--- a/src/main/java/net/minecraft/advancements/Advancement.java
+++ b/src/main/java/net/minecraft/advancements/Advancement.java
@@ -45,7 +45,7 @@ public class Advancement {
public Advancement(ResourceLocation id, @Nullable Advancement parent, @Nullable DisplayInfo display, AdvancementRewards rewards, Map<String, Criterion> criteria, String[][] requirements) {
this.id = id;
this.display = display;
- this.criteria = ImmutableMap.copyOf(criteria);
+ this.criteria = java.util.Collections.unmodifiableMap(criteria); // DivineMC - Skip cloning loot parameters
this.parent = parent;
this.rewards = rewards;
this.requirements = requirements;

View File

@@ -1,38 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: BillyGalbreath <Blake.Galbreath@Gmail.com>
Date: Sat, 15 Jan 2022 06:23:04 -0600
Subject: [PATCH] Dont eat blocks in non ticking chunks
Original code by PurpurMC, licensed under MIT
You can find the original code on https://github.com/PurpurMC/Purpur
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 3ce4dbf4eed442d89d6bbc8e4c6a000172041da5..364d899f4fba65f0ecae522c7dde4f1ef8ee632e 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -998,7 +998,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return this.anyPlayerCloseEnoughForSpawning(this.getUpdatingChunkIfPresent(chunkcoordintpair.toLong()), chunkcoordintpair, reducedRange);
}
- final boolean anyPlayerCloseEnoughForSpawning(ChunkHolder playerchunk, ChunkPos chunkcoordintpair, boolean reducedRange) {
+ public final boolean anyPlayerCloseEnoughForSpawning(ChunkHolder playerchunk, ChunkPos chunkcoordintpair, boolean reducedRange) { // Purpur - package -> public
// this function is so hot that removing the map lookup call can have an order of magnitude impact on its performance
// tested and confirmed via System.nanoTime()
com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> playersInRange = reducedRange ? playerchunk.playersInMobSpawnRange : playerchunk.playersInChunkTickRange;
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
index 80aa539f7c6a6ee44338de084cdcdf5fb4ef996a..9c2c2b3557f4a70c6c965f159a57682e1827d1ad 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
@@ -31,6 +31,12 @@ public class EatBlockGoal extends Goal {
@Override
public boolean canUse() {
+ // Purpur start
+ net.minecraft.world.level.chunk.LevelChunk chunk = this.mob.level.getChunkIfLoaded(this.mob.blockPosition);
+ if (chunk == null || chunk.playerChunk == null || !((net.minecraft.server.level.ServerLevel) this.mob.level).getChunkSource().chunkMap.anyPlayerCloseEnoughForSpawning(chunk.playerChunk, this.mob.chunkPosition(), false)) {
+ return false;
+ }
+ // Purpur end
if (this.mob.getRandom().nextInt(this.mob.isBaby() ? 50 : 1000) != 0) {
return false;
} else {

View File

@@ -1,119 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: etil2jz <81570777+etil2jz@users.noreply.github.com>
Date: Fri, 22 Apr 2022 22:44:56 +0200
Subject: [PATCH] carpetfixes: BiomeAccess prediction
Author: fxmorin <fx.e.morin@gmail.com>
Original license: MIT
Original project: https://github.com/fxmorin/carpet-fixes (Yarn mappings)
Copyright (c) 2020 Fx Morin
diff --git a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java
index 5695c5116c8a338b2e41aafcb2dc9f2146856970..6ee0a42dd048352c3df5d4788ea09170010a95b5 100644
--- a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java
+++ b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java
@@ -28,41 +28,72 @@ public class BiomeManager {
return new BiomeManager(storage, this.biomeZoomSeed);
}
+ // DivineMC start - carpetfixes: BiomeAccess prediction
+ private static final double maxOffset = 0.4500000001D; // DivineMC - carpetfixes: BiomeAccess prediction
public Holder<Biome> getBiome(BlockPos pos) {
- int i = pos.getX() - 2;
- int j = pos.getY() - 2;
- int k = pos.getZ() - 2;
- int l = i >> 2;
- int m = j >> 2;
- int n = k >> 2;
- double d = (double)(i & 3) / 4.0D;
- double e = (double)(j & 3) / 4.0D;
- double f = (double)(k & 3) / 4.0D;
- int o = 0;
- double g = Double.POSITIVE_INFINITY;
-
- for(int p = 0; p < 8; ++p) {
- boolean bl = (p & 4) == 0;
- boolean bl2 = (p & 2) == 0;
- boolean bl3 = (p & 1) == 0;
- int q = bl ? l : l + 1;
- int r = bl2 ? m : m + 1;
- int s = bl3 ? n : n + 1;
- double h = bl ? d : d - 1.0D;
- double t = bl2 ? e : e - 1.0D;
- double u = bl3 ? f : f - 1.0D;
- double v = getFiddledDistance(this.biomeZoomSeed, q, r, s, h, t, u);
- if (g > v) {
- o = p;
- g = v;
+ int xMinus2 = pos.getX() - 2;
+ int yMinus2 = pos.getY() - 2;
+ int zMinus2 = pos.getZ() - 2;
+ int x = xMinus2 >> 2; // BlockPos to BiomePos
+ int y = yMinus2 >> 2;
+ int z = zMinus2 >> 2;
+ double quartX = (double) (xMinus2 & 3) / 4.0D; // quartLocal divided by 4
+ double quartY = (double) (yMinus2 & 3) / 4.0D; // 0/4, 1/4, 2/4, 3/4
+ double quartZ = (double) (zMinus2 & 3) / 4.0D; // [0, 0.25, 0.5, 0.75]
+ int smallestX = 0;
+ double smallestDist = Double.POSITIVE_INFINITY;
+ for (int biomeX = 0; biomeX < 8; ++biomeX) {
+ boolean everyOtherQuad = (biomeX & 4) == 0; // 1 1 1 1 0 0 0 0
+ boolean everyOtherPair = (biomeX & 2) == 0; // 1 1 0 0 1 1 0 0
+ boolean everyOther = (biomeX & 1) == 0; // 1 0 1 0 1 0 1 0
+ double quartXX = everyOtherQuad ? quartX : quartX - 1.0D; //[-1.0,-0.75,-0.5,-0.25,0.0,0.25,0.5,0.75]
+ double quartYY = everyOtherPair ? quartY : quartY - 1.0D;
+ double quartZZ = everyOther ? quartZ : quartZ - 1.0D;
+
+ //This code block is new
+ double maxQuartYY = 0.0D, maxQuartZZ = 0.0D;
+ if (biomeX != 0) {
+ maxQuartYY = Mth.square(Math.max(quartYY + maxOffset, Math.abs(quartYY - maxOffset)));
+ maxQuartZZ = Mth.square(Math.max(quartZZ + maxOffset, Math.abs(quartZZ - maxOffset)));
+ double maxQuartXX = Mth.square(Math.max(quartXX + maxOffset,Math.abs(quartXX - maxOffset)));
+ if (smallestDist < maxQuartXX + maxQuartYY + maxQuartZZ) continue;
+ }
+
+ int xx = everyOtherQuad ? x : x + 1;
+ int yy = everyOtherPair ? y : y + 1;
+ int zz = everyOther ? z : z + 1;
+
+ //I transferred the code from method_38106 to here, so I could call continue halfway through
+ long seed = LinearCongruentialGenerator.next(this.biomeZoomSeed, xx);
+ seed = LinearCongruentialGenerator.next(seed, yy);
+ seed = LinearCongruentialGenerator.next(seed, zz);
+ seed = LinearCongruentialGenerator.next(seed, xx);
+ seed = LinearCongruentialGenerator.next(seed, yy);
+ seed = LinearCongruentialGenerator.next(seed, zz);
+ double offsetX = getFiddle(seed);
+ double sqrX = Mth.square(quartXX + offsetX);
+ if (biomeX != 0 && smallestDist < sqrX + maxQuartYY + maxQuartZZ) continue; //skip the rest of the loop
+ seed = LinearCongruentialGenerator.next(seed, this.biomeZoomSeed);
+ double offsetY = getFiddle(seed);
+ double sqrY = Mth.square(quartYY + offsetY);
+ if (biomeX != 0 && smallestDist < sqrX + sqrY + maxQuartZZ) continue; // skip the rest of the loop
+ seed = LinearCongruentialGenerator.next(seed, this.biomeZoomSeed);
+ double offsetZ = getFiddle(seed);
+ double biomeDist = sqrX + sqrY + Mth.square(quartZZ + offsetZ);
+
+ if (smallestDist > biomeDist) {
+ smallestX = biomeX;
+ smallestDist = biomeDist;
}
}
- int w = (o & 4) == 0 ? l : l + 1;
- int x = (o & 2) == 0 ? m : m + 1;
- int y = (o & 1) == 0 ? n : n + 1;
- return this.noiseBiomeSource.getNoiseBiome(w, x, y);
+ return(this.noiseBiomeSource.getNoiseBiome(
+ (smallestX & 4) == 0 ? x : x + 1,
+ (smallestX & 2) == 0 ? y : y + 1,
+ (smallestX & 1) == 0 ? z : z + 1
+ ));
}
+ // DivineMC end
public Holder<Biome> getNoiseBiomeAtPosition(double x, double y, double z) {
int i = QuartPos.fromBlock(Mth.floor(x));

View File

@@ -1,23 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Etil <81570777+etil2jz@users.noreply.github.com>
Date: Sun, 2 Jan 2022 20:37:30 +0100
Subject: [PATCH] Fix MC-121706
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/RangedBowAttackGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/RangedBowAttackGoal.java
index 6558b0d4bea99948fdc2b51751f3cfdc239d4b67..edb296ceaebfc296cf76682beeeda95d6ac2d93a 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/RangedBowAttackGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/RangedBowAttackGoal.java
@@ -111,10 +111,10 @@ public class RangedBowAttackGoal<T extends Monster & RangedAttackMob> extends Go
this.mob.getMoveControl().strafe(this.strafingBackwards ? -0.5F : 0.5F, this.strafingClockwise ? 0.5F : -0.5F);
this.mob.lookAt(livingEntity, 30.0F, 30.0F);
- } else {
- this.mob.getLookControl().setLookAt(livingEntity, 30.0F, 30.0F);
}
+ this.mob.getLookControl().setLookAt(livingEntity, 30.0F, 30.0F); // DivineMC - fix MC-121706
+
if (this.mob.isUsingItem()) {
if (!bl && this.seeTime < -60) {
this.mob.stopUsingItem();

View File

@@ -1,21 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: etil2jz <81570777+etil2jz@users.noreply.github.com>
Date: Fri, 22 Apr 2022 18:50:49 +0200
Subject: [PATCH] Fix hunger saturation depleting on peaceful
The food saturation value is depleted on peaceful, even though
the displayed hunger bar never goes down. Hunger (or any related value, including saturation)
should not go down on peaceful. See https://bugs.mojang.com/browse/MC-31819.
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index 2b02800666b358159c8ecb63208a14855f90657b..f68d53f085f4cb9ae94f5aa110ca0bd2a88aa5e1 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -1896,6 +1896,7 @@ public abstract class Player extends LivingEntity {
}
public void causeFoodExhaustion(float f, EntityExhaustionEvent.ExhaustionReason reason) {
+ if (this.level.getDifficulty() == Difficulty.PEACEFUL) return; // DivineMC - fix hunger saturation depleting on peaceful
// CraftBukkit end
if (!this.abilities.invulnerable) {
if (!this.level.isClientSide) {

View File

@@ -1,21 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: etil2jz <81570777+etil2jz@users.noreply.github.com>
Date: Fri, 29 Apr 2022 12:08:22 +0200
Subject: [PATCH] Fix mobs attacking themselves
If an entity is provoked by a second one using commands,
the second will join in the fight against itself,
causing it to attack itself repeatedly. See https://bugs.mojang.com/browse/MC-110386.
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/target/HurtByTargetGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/target/HurtByTargetGoal.java
index 39ea15c7577af186d93d4ad9a48034d746a86fc8..1de734820a5a4b1580c123a8e4a2513d52c42a4b 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/target/HurtByTargetGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/target/HurtByTargetGoal.java
@@ -114,6 +114,7 @@ public class HurtByTargetGoal extends TargetGoal {
}
protected void alertOther(Mob mob, LivingEntity target) {
+ if (mob == target) return; // DivineMC - avoid entities with suicidal thoughts /s
mob.setTarget(target, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_NEARBY_ENTITY, true); // CraftBukkit - reason
}
}

View File

@@ -1,62 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: astei <andrew@steinborn.me>
Date: Sat, 1 Oct 2022 09:56:47 +0200
Subject: [PATCH] PaperPR Optimize VarInts
Original license: GPLv3
Original project: https://github.com/PaperMC/Velocity
Paper pull request: https://github.com/PaperMC/Paper/pull/8418
diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
index 9938bb90bef84cf784f9a1ceb02a1a45aa8b48a1..015685c97dc4a3485e009e0bf6c8f04302249578 100644
--- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java
+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
@@ -102,15 +102,18 @@ public class FriendlyByteBuf extends ByteBuf {
this.source = parent;
}
- public static int getVarIntSize(int value) {
- for (int j = 1; j < 5; ++j) {
- if ((value & -1 << j * 7) == 0) {
- return j;
- }
+ //Paper start - Optimize VarInts
+ private static final int[] VARINT_EXACT_BYTE_LENGTHS = new int[33];
+ static {
+ for (int i = 0; i <= 32; ++i) {
+ VARINT_EXACT_BYTE_LENGTHS[i] = (int) Math.ceil((31d - (i - 1)) / 7d);
}
-
- return 5;
+ VARINT_EXACT_BYTE_LENGTHS[32] = 1; // Special case for the number 0.
+ }
+ public static int getVarIntSize(int value) {
+ return VARINT_EXACT_BYTE_LENGTHS[Integer.numberOfLeadingZeros(value)]; // Paper - Optimize VarInts
}
+ //Paper end - Optimize VarInts
public static int getVarLongSize(long value) {
for (int j = 1; j < 10; ++j) {
@@ -612,7 +615,22 @@ public class FriendlyByteBuf extends ByteBuf {
return new UUID(this.readLong(), this.readLong());
}
+ // Paper start - Optimize VarInts
public FriendlyByteBuf writeVarInt(int value) {
+ // Peel the one and two byte count cases explicitly as they are the most common VarInt sizes
+ // that the proxy will write, to improve inlining.
+ if ((value & (0xFFFFFFFF << 7)) == 0) {
+ writeByte(value);
+ } else if ((value & (0xFFFFFFFF << 14)) == 0) {
+ int w = (value & 0x7F | 0x80) << 8 | (value >>> 7);
+ writeShort(w);
+ } else {
+ writeVarInt_(value);
+ }
+ return this;
+ }
+ public FriendlyByteBuf writeVarInt_(int value) {
+ // Paper end - Optimize VarInts
while ((value & -128) != 0) {
this.writeByte(value & 127 | 128);
value >>>= 7;

View File

@@ -1,18 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: etil2jz <81570777+etil2jz@users.noreply.github.com>
Date: Mon, 8 Aug 2022 11:21:49 +0200
Subject: [PATCH] Fix MC-238526
diff --git a/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java b/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java
index 35cfa366baf6747105faa93f1220bb9cc31a5bd5..55d2a130d056da10b79d5291ab5e4ad7a809972f 100644
--- a/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java
+++ b/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java
@@ -82,6 +82,6 @@ public abstract class WaterAnimal extends PathfinderMob {
i = world.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.maximum.or(i);
j = world.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.minimum.or(j);
// Paper end
- return pos.getY() >= j && pos.getY() <= i && world.getFluidState(pos.below()).is(FluidTags.WATER) && world.getBlockState(pos.above()).is(Blocks.WATER);
+ return ((reason == MobSpawnType.SPAWNER) || (pos.getY() >= j && pos.getY() <= i)) && world.getFluidState(pos.below()).is(FluidTags.WATER) && world.getBlockState(pos.above()).is(Blocks.WATER); // DivineMC
}
}

View File

@@ -1,44 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: jellysquid3 <jellysquid3@users.noreply.github.com>
Date: Wed, 15 Dec 2021 11:30:23 -0500
Subject: [PATCH] lithium: cached hashcode
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
index a85e788ff5a55288df753a0e630b32270760f8de..ebb3808fbaaec82283db0839335b5efca28d4881 100644
--- a/src/main/java/net/minecraft/world/level/block/Block.java
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
@@ -604,11 +604,18 @@ public class Block extends BlockBehaviour implements ItemLike {
private final BlockState first;
private final BlockState second;
private final Direction direction;
+ private int hash; // JettPack
public BlockStatePairKey(BlockState self, BlockState other, Direction facing) {
this.first = self;
this.second = other;
this.direction = facing;
+ // JettPack start - lithium: cached_hashcode
+ int hash = this.first.hashCode();
+ hash = 31 * hash + this.second.hashCode();
+ hash = 31 * hash + this.direction.hashCode();
+ this.hash = hash;
+ // JettPack end
}
public boolean equals(Object object) {
@@ -624,11 +631,7 @@ public class Block extends BlockBehaviour implements ItemLike {
}
public int hashCode() {
- int i = this.first.hashCode();
-
- i = 31 * i + this.second.hashCode();
- i = 31 * i + this.direction.hashCode();
- return i;
+ return this.hash; // JettPack
}
}
}

View File

@@ -1,43 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: ishland <ishlandmc@yeah.net>
Date: Sun, 12 Dec 2021 17:19:00 -0500
Subject: [PATCH] vmp: skip entity move if movement is zero
Copyright (c) 2021-2022 ishland
Original code by RelativityMC, licensed under MIT
You can find the original code on https://github.com/RelativityMC/VMP-fabric (Yarn mappings)
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 8a2429f915da389360dcb16609fef7701b4a863a..bc8cdffb58369a5c1796d3323ed1facbedf9c823 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -299,6 +299,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
public float yRotO;
public float xRotO;
private AABB bb;
+ private boolean boundingBoxChanged = false; // DivineMC - vmp: skip entity move if movement is zero
public boolean onGround;
public boolean horizontalCollision;
public boolean verticalCollision;
@@ -1035,6 +1036,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
// Paper end - detailed watchdog information
public void move(MoverType movementType, Vec3 movement) {
+ // DivineMC start - vmp: skip entity move if movement is zero
+ if (!boundingBoxChanged && movement.equals(Vec3.ZERO)) {
+ boundingBoxChanged = false;
+ return;
+ }
+ // DivineMC end
// Paper start - detailed watchdog information
io.papermc.paper.util.TickThread.ensureTickThread("Cannot move an entity off-main");
synchronized (this.posLock) {
@@ -3862,6 +3869,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
}
public final void setBoundingBox(AABB boundingBox) {
+ if (!this.bb.equals(boundingBox)) boundingBoxChanged = true; // DivineMC - vmp: skip entity move if movement is zero
// CraftBukkit start - block invalid bounding boxes
double minX = boundingBox.minX,
minY = boundingBox.minY,

View File

@@ -1,100 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: etil2jz <81570777+etil2jz@users.noreply.github.com>
Date: Fri, 8 Apr 2022 22:21:48 +0200
Subject: [PATCH] lithium: suffocation
Author: 2No2Name <2No2Name@web.de>
Original license: GNU Lesser General Public License v3.0
Original project: https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index bc8cdffb58369a5c1796d3323ed1facbedf9c823..e273fed8e97c98bf5735d3a8c301968990d4cf32 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2623,39 +2623,64 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
return !this.isRemoved();
}
+ // DivineMC start - lithium: suffocation
+ /**
+ * @author 2No2Name
+ * @reason Avoid stream code, use optimized chunk section iteration order
+ */
public boolean isInWall() {
+ // [VanillaCopy] The whole method functionality including bug below. Cannot use ChunkAwareBlockCollisionSweeper due to ignoring of oversized blocks
if (this.noPhysics) {
return false;
- } else {
- float f = this.dimensions.width * 0.8F;
- AABB axisalignedbb = AABB.ofSize(this.getEyePosition(), (double) f, 1.0E-6D, (double) f);
-
- BlockPos.MutableBlockPos blockposition = new BlockPos.MutableBlockPos();
- int minX = Mth.floor(axisalignedbb.minX);
- int minY = Mth.floor(axisalignedbb.minY);
- int minZ = Mth.floor(axisalignedbb.minZ);
- int maxX = Mth.floor(axisalignedbb.maxX);
- int maxY = Mth.floor(axisalignedbb.maxY);
- int maxZ = Mth.floor(axisalignedbb.maxZ);
- for (int fz = minZ; fz <= maxZ; ++fz) {
- for (int fx = minX; fx <= maxX; ++fx) {
- for (int fy = minY; fy <= maxY; ++fy) {
- net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk)this.level.getChunkIfLoadedImmediately(fx >> 4, fz >> 4);
- if (chunk == null) {
- continue;
+ }
+ Vec3 position = this.getEyePosition();
+ double suffocationRadius = Math.abs((double) (this.dimensions.width * 0.8f) / 2.0);
+
+ double suffocationMinX = position.x - suffocationRadius;
+ double suffocationMinY = position.y - 5.0E-7;
+ double suffocationMinZ = position.z - suffocationRadius;
+ double suffocationMaxX = position.x + suffocationRadius;
+ double suffocationMaxY = position.y + 5.0E-7;
+ double suffocationMaxZ = position.z + suffocationRadius;
+ int minX = Mth.floor(suffocationMinX);
+ int minY = Mth.floor(suffocationMinY);
+ int minZ = Mth.floor(suffocationMinZ);
+ int maxX = Mth.floor(suffocationMaxX);
+ int maxY = Mth.floor(suffocationMaxY);
+ int maxZ = Mth.floor(suffocationMaxZ);
+
+ Level level = this.level;
+ //skip getting blocks when the entity is outside the world height
+ //also avoids infinite loop with entities below y = Integer.MIN_VALUE (some modded servers do that)
+ if (level.getMinBuildHeight() > maxY || level.getMaxBuildHeight() < minY) {
+ return false;
+ }
+
+ BlockPos.MutableBlockPos blockposition = new BlockPos.MutableBlockPos();
+ VoxelShape suffocationShape = null;
+
+ for (int y = minY; y <= maxY; y++) {
+ for (int z = minZ; z <= maxZ; z++) {
+ for (int x = minX; x <= maxX; x++) {
+ blockposition.set(x, y, z);
+ BlockState iblockdata = level.getBlockState(blockposition);
+ if (!iblockdata.isAir() && iblockdata.isSuffocating(this.level, blockposition)) {
+ if (suffocationShape == null) {
+ suffocationShape = Shapes.create(new AABB(suffocationMinX, suffocationMinY, suffocationMinZ, suffocationMaxX, suffocationMaxY, suffocationMaxZ));
}
- BlockState iblockdata = chunk.getBlockStateFinal(fx, fy, fz);
- blockposition.set(fx, fy, fz);
- if (!iblockdata.isAir() && iblockdata.isSuffocating(this.level, blockposition) && Shapes.joinIsNotEmpty(iblockdata.getCollisionShape(this.level, blockposition).move((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()), Shapes.create(axisalignedbb), BooleanOp.AND)) {
+ if (Shapes.joinIsNotEmpty(iblockdata.getCollisionShape(this.level, blockposition).
+ move(blockposition.getX(), blockposition.getY(), blockposition.getZ()),
+ suffocationShape, BooleanOp.AND)) {
return true;
}
}
}
}
- return false;
}
+ return false;
}
+ // DivineMC end
public InteractionResult interact(Player player, InteractionHand hand) {
return InteractionResult.PASS;

View File

@@ -1,25 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 2No2Name <2No2Name@web.de>
Date: Tue, 15 Mar 2022 07:14:26 +0100
Subject: [PATCH] lithium: ai.sensor.secondary_poi
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java
index cb1d91f9fe98f21c2afbe3894dfd9bca3bdd3ba6..1bb33123d26b0a261f30bad2a972f42d504b5e69 100644
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java
@@ -22,6 +22,12 @@ public class SecondaryPoiSensor extends Sensor<Villager> {
@Override
protected void doTick(ServerLevel world, Villager entity) {
+ // DivineMC start - lithium: ai.sensor.secondary_poi
+ if (entity.getVillagerData().getProfession().secondaryPoi().isEmpty()) {
+ entity.getBrain().eraseMemory(MemoryModuleType.SECONDARY_JOB_SITE);
+ return;
+ }
+ // DivineMC end
ResourceKey<Level> resourceKey = world.dimension();
BlockPos blockPos = entity.blockPosition();
List<GlobalPos> list = Lists.newArrayList();

View File

@@ -1,40 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 2No2Name <2No2Name@web.de>
Date: Tue, 21 Dec 2021 09:43:24 -0500
Subject: [PATCH] lithium: store gamerules in fastutil hashmap
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
diff --git a/src/main/java/net/minecraft/world/level/GameRules.java b/src/main/java/net/minecraft/world/level/GameRules.java
index 29d1f78dbc8410f9292f409b17705acde55979df..81b9cbc717283021fc902337102fbb3af35db101 100644
--- a/src/main/java/net/minecraft/world/level/GameRules.java
+++ b/src/main/java/net/minecraft/world/level/GameRules.java
@@ -27,6 +27,7 @@ import net.minecraft.network.protocol.game.ClientboundGameEventPacket;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import org.slf4j.Logger;
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; // JettPack
public class GameRules {
@@ -120,14 +121,16 @@ public class GameRules {
public GameRules() {
// Pufferfish start - use this to ensure gameruleArray is initialized
- this((Map) GameRules.GAME_RULE_TYPES.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry) -> {
+ // JettPack start - lithium: store gamerules in fastutil hashmap
+ this(new Object2ObjectOpenHashMap<>((Map) GameRules.GAME_RULE_TYPES.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry) -> {
return ((GameRules.Type) entry.getValue()).createRule();
- })));
+ }))));
+ // JettPack end
// Pufferfish end
}
private GameRules(Map<GameRules.Key<?>, GameRules.Value<?>> rules) {
- this.rules = rules;
+ this.rules = new Object2ObjectOpenHashMap<>(rules); // JettPack - lithium: store gamerules in fastutil hashmap
// Pufferfish start
int arraySize = rules.keySet().stream().mapToInt(key -> key.gameRuleIndex).max().orElse(-1) + 1;

View File

@@ -1,77 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: jellysquid3 <jellysquid3@users.noreply.github.com>
Date: Sat, 1 Jan 2022 03:59:58 -0500
Subject: [PATCH] lithium: precompute shape arrays
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 28ecd137dd37759e7890d71635289c3f6e994b87..c31da8e3709168d87ceb44826c9dee9fe7e117f0 100644
--- a/src/main/java/net/minecraft/core/Direction.java
+++ b/src/main/java/net/minecraft/core/Direction.java
@@ -42,7 +42,7 @@ public enum Direction implements StringRepresentable {
private final Direction.Axis axis;
private final Direction.AxisDirection axisDirection;
private final Vec3i normal;
- private static final Direction[] VALUES = values();
+ public static final Direction[] VALUES = values(); // JettPack
private static final Direction[] BY_3D_DATA = Arrays.stream(VALUES).sorted(Comparator.comparingInt((direction) -> {
return direction.data3d;
})).toArray((i) -> {
diff --git a/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java b/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java
index a544db042c8d2ecec8d323770552c4f10ca758a6..c04da8da5b40430b61972bce32cec4e8c0370bac 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java
@@ -4,6 +4,7 @@ import it.unimi.dsi.fastutil.doubles.AbstractDoubleList;
public class CubePointRange extends AbstractDoubleList {
private final int parts;
+ private double scale; // JettPack - lithium: shapes.precompute_shape_arrays
CubePointRange(int sectionCount) {
if (sectionCount <= 0) {
@@ -11,10 +12,11 @@ public class CubePointRange extends AbstractDoubleList {
} else {
this.parts = sectionCount;
}
+ this.scale = 1.0D / sectionCount; // JettPack - lithium: shapes.precompute_shape_arrays
}
public double getDouble(int i) {
- return (double)i / (double)this.parts;
+ return i * this.scale; // JettPack - lithium: shapes.precompute_shape_arrays
}
public int size() {
diff --git a/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java
index 68e89dbd79171627046e89699057964e44c40e7d..959588962acb0196ec9f1cc2502e62117f6ccdc4 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java
@@ -3,15 +3,25 @@ package net.minecraft.world.phys.shapes;
import it.unimi.dsi.fastutil.doubles.DoubleList;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
+import net.minecraft.world.phys.shapes.CubePointRange; // JettPack
public final class CubeVoxelShape extends VoxelShape {
+ private DoubleList[] list; // JettPack - lithium: shapes.precompute_shape_arrays
+
protected CubeVoxelShape(DiscreteVoxelShape voxels) {
super(voxels);
+ // JettPack start - lithium: shapes.precompute_shape_arrays
+ this.list = new DoubleList[Direction.VALUES.length];
+
+ for (Direction.Axis axis : Direction.Axis.VALUES) {
+ this.list[axis.ordinal()] = new CubePointRange(voxels.getSize(axis));
+ }
+ // JettPack end
}
@Override
protected DoubleList getCoords(Direction.Axis axis) {
- return new CubePointRange(this.shape.getSize(axis));
+ return this.list[axis.ordinal()]; // JettPack - lithium: shapes.precompute_shape_arrays
}
@Override

View File

@@ -1,21 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 2No2Name <2No2Name@web.de>
Date: Sat, 8 Jan 2022 04:32:41 +0100
Subject: [PATCH] lithium: entity.fast_elytra_check
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 791f672b30f2a4d3b329e2ce0f4fb9c2ca627b01..dcbeffd0b4ea7c245ac83fe7e097794fc24fe4e8 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -3440,6 +3440,8 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
private void updateFallFlying() {
+ if (!this.isFallFlying()) return; // DivineMC
+
boolean flag = this.getSharedFlag(7);
if (flag && !this.onGround && !this.isPassenger() && !this.hasEffect(MobEffects.LEVITATION)) {

View File

@@ -1,21 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 2No2Name <2No2Name@web.de>
Date: Sun, 9 Jan 2022 06:03:28 +0100
Subject: [PATCH] lithium: entity.fast_hand_swing
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index dcbeffd0b4ea7c245ac83fe7e097794fc24fe4e8..85f4b06cf4062fcc8199b66dd926dbe352584210 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -2459,6 +2459,8 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
protected void updateSwingTime() {
+ if (!this.swinging && this.swingTime == 0) return; // DivineMC
+
int i = this.getCurrentSwingDuration();
if (this.swinging) {

View File

@@ -1,35 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 2No2Name <2No2Name@web.de>
Date: Sat, 8 Jan 2022 03:51:28 +0100
Subject: [PATCH] lithium: entity.fast_powder_snow_check
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 85f4b06cf4062fcc8199b66dd926dbe352584210..be8060a46399f5d9c09003c2144f4b46b659cef5 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -565,11 +565,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
protected void tryAddFrost() {
- if (!this.getBlockStateOnLegacy().isAir()) {
+ //if (!this.getBlockStateOnLegacy().isAir()) { // DivineMC
int i = this.getTicksFrozen();
if (i > 0) {
- AttributeInstance attributemodifiable = this.getAttribute(Attributes.MOVEMENT_SPEED);
+ AttributeInstance attributemodifiable = this.getBlockStateOnLegacy().isAir() ? null : this.getAttribute(Attributes.MOVEMENT_SPEED); // DivineMC
if (attributemodifiable == null) {
return;
@@ -579,7 +579,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
attributemodifiable.addTransientModifier(new AttributeModifier(LivingEntity.SPEED_MODIFIER_POWDER_SNOW_UUID, "Powder snow slow", (double) f, AttributeModifier.Operation.ADDITION));
}
- }
+ //} // DivineMC
}

View File

@@ -1,28 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 2No2Name <2No2Name@web.de>
Date: Sun, 9 Jan 2022 17:53:11 +0100
Subject: [PATCH] lithium: collections.attributes
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
index e283eb57c25f7de222f9d09dca851169f5f6e488..7b30ad6c092d8b91ffd2eb264de323a506e9d68f 100644
--- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
+++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
@@ -17,11 +17,13 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.resources.ResourceLocation;
import org.slf4j.Logger;
+import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; // DivineMC
+import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; // DivineMC
public class AttributeMap {
private static final Logger LOGGER = LogUtils.getLogger();
- private final Map<Attribute, AttributeInstance> attributes = Maps.newHashMap();
- private final Set<AttributeInstance> dirtyAttributes = Sets.newHashSet();
+ private final Map<Attribute, AttributeInstance> attributes = new Reference2ReferenceOpenHashMap<>(0); // DivineMC
+ private final Set<AttributeInstance> dirtyAttributes = new ReferenceOpenHashSet<>(0); // DivineMC
private final AttributeSupplier supplier;
private final java.util.function.Function<Attribute, AttributeInstance> createInstance; // Pufferfish

View File

@@ -1,38 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 2No2Name <2No2Name@web.de>
Date: Fri, 7 Jan 2022 06:43:30 +0100
Subject: [PATCH] lithium: collections.entity_by_type
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/util/ClassInstanceMultiMap.java b/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java
index 50a9f33aa31e9273c7c52d4bb2b02f0f884f7ba5..9698c093dd8c18a5a5a4b157c3799191841552e2 100644
--- a/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java
+++ b/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java
@@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; // JettPack
import java.util.AbstractCollection;
import java.util.Collection;
import java.util.Collections;
@@ -13,7 +14,7 @@ import java.util.Map;
import java.util.stream.Collectors;
public class ClassInstanceMultiMap<T> extends AbstractCollection<T> {
- private final Map<Class<?>, List<T>> byClass = Maps.newHashMap();
+ private final Map<Class<?>, List<T>> byClass = new Reference2ReferenceOpenHashMap<>(); // JettPack
private final Class<T> baseClass;
private final List<T> allInstances = Lists.newArrayList();
@@ -58,7 +59,7 @@ public class ClassInstanceMultiMap<T> extends AbstractCollection<T> {
if (!this.baseClass.isAssignableFrom(type)) {
throw new IllegalArgumentException("Don't know how to search for " + type);
} else {
- List<? extends T> list = this.byClass.computeIfAbsent(type, (typeClass) -> {
+ List list = this.byClass.computeIfAbsent(type, (typeClass) -> { // JettPack - decomp fix
return this.allInstances.stream().filter(typeClass::isInstance).collect(Collectors.toList());
});
return Collections.unmodifiableCollection(list);

View File

@@ -1,52 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 2No2Name <2No2Name@web.de>
Date: Sat, 8 Jan 2022 03:33:04 +0100
Subject: [PATCH] lithium: collections.entity_filtering
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/util/ClassInstanceMultiMap.java b/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java
index 9698c093dd8c18a5a5a4b157c3799191841552e2..6f181fc878a96b09f126ea8d3b19ce3ee4588e19 100644
--- a/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java
+++ b/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java
@@ -56,15 +56,32 @@ public class ClassInstanceMultiMap<T> extends AbstractCollection<T> {
}
public <S> Collection<S> find(Class<S> type) {
- if (!this.baseClass.isAssignableFrom(type)) {
- throw new IllegalArgumentException("Don't know how to search for " + type);
- } else {
- List list = this.byClass.computeIfAbsent(type, (typeClass) -> { // JettPack - decomp fix
- return this.allInstances.stream().filter(typeClass::isInstance).collect(Collectors.toList());
- });
- return Collections.unmodifiableCollection(list);
+ // JettPack start
+ Collection<T> collection = this.byClass.get(type);
+
+ if (collection == null) {
+ collection = this.createAllOfType(type);
}
+
+ return (Collection<S>) Collections.unmodifiableCollection(collection);
+ // JettPack end
+ }
+
+ // JettPack start
+ private <S> Collection<T> createAllOfType(Class<S> type) {
+ List<T> list = new java.util.ArrayList<>();
+
+ for (T allElement : this.allInstances) {
+ if (type.isInstance(allElement)) {
+ list.add(allElement);
+ }
+ }
+
+ this.byClass.put(type, list);
+
+ return list;
}
+ // JettPack end
@Override
public Iterator<T> iterator() {

View File

@@ -1,458 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: jellysquid3 <jellysquid3@users.noreply.github.com>
Date: Mon, 10 Jan 2022 15:27:58 -0500
Subject: [PATCH] lithium: chunk.serialization
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/world/chunk/LithiumHashPalette.java b/src/main/java/me/jellysquid/mods/lithium/common/world/chunk/LithiumHashPalette.java
new file mode 100644
index 0000000000000000000000000000000000000000..16debe176798f316c122e8e7aef2b50ecb9883a6
--- /dev/null
+++ b/src/main/java/me/jellysquid/mods/lithium/common/world/chunk/LithiumHashPalette.java
@@ -0,0 +1,189 @@
+package me.jellysquid.mods.lithium.common.world.chunk;
+
+import com.google.common.collect.ImmutableList;
+import it.unimi.dsi.fastutil.HashCommon;
+import it.unimi.dsi.fastutil.objects.Reference2IntMap;
+import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Predicate;
+import net.minecraft.core.IdMap;
+import net.minecraft.network.FriendlyByteBuf;
+import net.minecraft.world.level.chunk.Palette;
+import net.minecraft.world.level.chunk.PaletteResize;
+
+import static it.unimi.dsi.fastutil.Hash.FAST_LOAD_FACTOR;
+
+/**
+ * Generally provides better performance over the vanilla {@link net.minecraft.world.level.chunk.HashMapPalette} when calling
+ * {@link LithiumHashPalette#idFor(Object)} through using a faster backing map and reducing pointer chasing.
+ */
+public class LithiumHashPalette<T> implements Palette<T> {
+ private static final int ABSENT_VALUE = -1;
+
+ private final IdMap<T> idList;
+ private final PaletteResize<T> resizeHandler;
+ private final int indexBits;
+
+ private final Reference2IntMap<T> table;
+ private T[] entries;
+ private int size = 0;
+
+ public LithiumHashPalette(IdMap<T> idList, PaletteResize<T> resizeHandler, int indexBits, T[] entries, Reference2IntMap<T> table, int size) {
+ this.idList = idList;
+ this.resizeHandler = resizeHandler;
+ this.indexBits = indexBits;
+ this.entries = entries;
+ this.table = table;
+ this.size = size;
+ }
+
+ public LithiumHashPalette(IdMap<T> idList, int bits, PaletteResize<T> resizeHandler, List<T> list) {
+ this(idList, bits, resizeHandler);
+
+ for (T t : list) {
+ this.addEntry(t);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public LithiumHashPalette(IdMap<T> idList, int bits, PaletteResize<T> resizeHandler) {
+ this.idList = idList;
+ this.indexBits = bits;
+ this.resizeHandler = resizeHandler;
+
+ int capacity = 1 << bits;
+
+ this.entries = (T[]) new Object[capacity];
+ this.table = new Reference2IntOpenHashMap<>(capacity, FAST_LOAD_FACTOR);
+ this.table.defaultReturnValue(ABSENT_VALUE);
+ }
+
+ @Override
+ public int idFor(T obj) {
+ int id = this.table.getInt(obj);
+
+ if (id == ABSENT_VALUE) {
+ id = this.computeEntry(obj);
+ }
+
+ return id;
+ }
+
+ @Override
+ public boolean maybeHas(Predicate<T> predicate) {
+ for (int i = 0; i < this.size; ++i) {
+ if (predicate.test(this.entries[i])) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private int computeEntry(T obj) {
+ int id = this.addEntry(obj);
+
+ if (id >= 1 << this.indexBits) {
+ if (this.resizeHandler == null) {
+ throw new IllegalStateException("Cannot grow");
+ } else {
+ id = this.resizeHandler.onResize(this.indexBits + 1, obj);
+ }
+ }
+
+ return id;
+ }
+
+ private int addEntry(T obj) {
+ int nextId = this.size;
+
+ if (nextId >= this.entries.length) {
+ this.resize(this.size);
+ }
+
+ this.table.put(obj, nextId);
+ this.entries[nextId] = obj;
+
+ this.size++;
+
+ return nextId;
+ }
+
+ private void resize(int neededCapacity) {
+ this.entries = Arrays.copyOf(this.entries, HashCommon.nextPowerOfTwo(neededCapacity + 1));
+ }
+
+ @Override
+ public T valueFor(int id) {
+ T[] entries = this.entries;
+
+ if (id >= 0 && id < entries.length) {
+ return entries[id];
+ }
+
+ return null;
+ }
+
+ @Override
+ public void read(FriendlyByteBuf buf) {
+ this.clear();
+
+ int entryCount = buf.readVarInt();
+
+ for (int i = 0; i < entryCount; ++i) {
+ this.addEntry(this.idList.byId(buf.readVarInt()));
+ }
+ }
+
+ @Override
+ public void write(FriendlyByteBuf buf) {
+ int size = this.size;
+ buf.writeVarInt(size);
+
+ for (int i = 0; i < size; ++i) {
+ buf.writeVarInt(this.idList.getId(this.valueFor(i)));
+ }
+ }
+
+ @Override
+ public int getSerializedSize() {
+ int size = FriendlyByteBuf.getVarIntSize(this.size);
+
+ for (int i = 0; i < this.size; ++i) {
+ size += FriendlyByteBuf.getVarIntSize(this.idList.getId(this.valueFor(i)));
+ }
+
+ return size;
+ }
+
+ @Override
+ public int getSize() {
+ return this.size;
+ }
+
+ @Override
+ public Palette<T> copy() {
+ return new LithiumHashPalette<>(this.idList, this.resizeHandler, this.indexBits, this.entries.clone(), new Reference2IntOpenHashMap<>(this.table), this.size);
+ }
+
+ private void clear() {
+ Arrays.fill(this.entries, null);
+ this.table.clear();
+ this.size = 0;
+ }
+
+ public List<T> getElements() {
+ ImmutableList.Builder<T> builder = new ImmutableList.Builder<>();
+ for (T entry : this.entries) {
+ if (entry != null) {
+ builder.add(entry);
+ }
+ }
+ return builder.build();
+ }
+
+ public static <A> Palette<A> create(int bits, IdMap<A> idList, PaletteResize<A> listener, List<A> list) {
+ return new LithiumHashPalette<>(idList, bits, listener, list);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraft/util/BitStorage.java b/src/main/java/net/minecraft/util/BitStorage.java
index 106610ccc74b70b557b01c61262d56c4f1147acf..fc986f02290fbe20246022072944980f35dd200c 100644
--- a/src/main/java/net/minecraft/util/BitStorage.java
+++ b/src/main/java/net/minecraft/util/BitStorage.java
@@ -1,6 +1,7 @@
package net.minecraft.util;
import java.util.function.IntConsumer;
+import net.minecraft.world.level.chunk.Palette; // JettPack
public interface BitStorage {
int getAndSet(int index, int value);
@@ -31,4 +32,6 @@ public interface BitStorage {
}
// Paper end
+
+ <T> void compact(Palette<T> srcPalette, Palette<T> dstPalette, short[] out); // JettPack - lithium: chunk.serialization
}
diff --git a/src/main/java/net/minecraft/util/SimpleBitStorage.java b/src/main/java/net/minecraft/util/SimpleBitStorage.java
index 36e33923bf48e56c743ed043bcbc66bc32f0422f..0272dee738e86e066108f5cc3729136335d8197e 100644
--- a/src/main/java/net/minecraft/util/SimpleBitStorage.java
+++ b/src/main/java/net/minecraft/util/SimpleBitStorage.java
@@ -2,6 +2,7 @@ package net.minecraft.util;
import java.util.function.IntConsumer;
import javax.annotation.Nullable;
+import net.minecraft.world.level.chunk.Palette; // JettPack
import org.apache.commons.lang3.Validate;
public class SimpleBitStorage implements BitStorage {
@@ -201,4 +202,44 @@ public class SimpleBitStorage implements BitStorage {
super(message);
}
}
+
+ // JettPack start - lithium: chunk.serialization
+ @Override
+ public <T> void compact(Palette<T> srcPalette, Palette<T> dstPalette, short[] out) {
+ if (this.size >= Short.MAX_VALUE) {
+ throw new IllegalStateException("Array too large");
+ }
+
+ if (this.size != out.length) {
+ throw new IllegalStateException("Array size mismatch");
+ }
+
+ short[] mappings = new short[(int) (this.mask + 1)];
+
+ int idx = 0;
+
+ for (long word : this.data) {
+ long bits = word;
+
+ for (int elementIdx = 0; elementIdx < this.valuesPerLong; ++elementIdx) {
+ int value = (int) (bits & this.mask);
+ int remappedId = mappings[value];
+
+ if (remappedId == 0) {
+ remappedId = dstPalette.idFor(srcPalette.valueFor(value)) + 1;
+ mappings[value] = (short) remappedId;
+ }
+
+ out[idx] = (short) (remappedId - 1);
+ bits >>= this.bits;
+
+ ++idx;
+
+ if (idx >= this.size) {
+ return;
+ }
+ }
+ }
+ }
+ // JettPack end
}
diff --git a/src/main/java/net/minecraft/util/ZeroBitStorage.java b/src/main/java/net/minecraft/util/ZeroBitStorage.java
index 5d8e9bdf5538b19681f21949368d862fab8a89ad..2224245a985dfe78565dfdb42840d3ed43530525 100644
--- a/src/main/java/net/minecraft/util/ZeroBitStorage.java
+++ b/src/main/java/net/minecraft/util/ZeroBitStorage.java
@@ -2,6 +2,7 @@ package net.minecraft.util;
import java.util.Arrays;
import java.util.function.IntConsumer;
+import net.minecraft.world.level.chunk.Palette; // JettPack
import org.apache.commons.lang3.Validate;
public class ZeroBitStorage implements BitStorage {
@@ -72,4 +73,6 @@ public class ZeroBitStorage implements BitStorage {
public BitStorage copy() {
return this;
}
+
+ @Override public <T> void compact(Palette<T> srcPalette, Palette<T> dstPalette, short[] out) {} // JettPack
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/PaletteResize.java b/src/main/java/net/minecraft/world/level/chunk/PaletteResize.java
index acae3eb30e0689048937f479dc3070f0688abdad..9c2b79655f2c63a208c7087d5d897db0fb23f697 100644
--- a/src/main/java/net/minecraft/world/level/chunk/PaletteResize.java
+++ b/src/main/java/net/minecraft/world/level/chunk/PaletteResize.java
@@ -1,5 +1,5 @@
package net.minecraft.world.level.chunk;
-interface PaletteResize<T> {
+public interface PaletteResize<T> { // JettPack - make public
int onResize(int newBits, T object);
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
index 7c770d131d39da6900fdd22df36707d5f43e8cd0..34e98db58044d87c8264c977e16dd17a36182501 100644
--- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
@@ -22,8 +22,23 @@ import net.minecraft.util.Mth;
import net.minecraft.util.SimpleBitStorage;
import net.minecraft.util.ThreadingDetector;
import net.minecraft.util.ZeroBitStorage;
+import me.jellysquid.mods.lithium.common.world.chunk.LithiumHashPalette; // JettPack
public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainerRO<T> {
+ // JettPack start - lithium: chunk.serialization
+ private static final ThreadLocal<short[]> CACHED_ARRAY_4096 = ThreadLocal.withInitial(() -> new short[4096]);
+ private static final ThreadLocal<short[]> CACHED_ARRAY_64 = ThreadLocal.withInitial(() -> new short[64]);
+ private Optional<LongStream> asOptional(long[] data) {
+ return Optional.of(Arrays.stream(data));
+ }
+ private short[] getOrCreate(int size) {
+ return switch (size) {
+ case 64 -> CACHED_ARRAY_64.get();
+ case 4096 -> CACHED_ARRAY_4096.get();
+ default -> new short[size];
+ };
+ }
+ // JettPack end
private static final int MIN_PALETTE_BITS = 0;
private final PaletteResize<T> dummyPaletteResize = (newSize, added) -> {
return 0;
@@ -303,30 +318,54 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
public synchronized PalettedContainerRO.PackedData<T> pack(IdMap<T> idList, PalettedContainer.Strategy paletteProvider) { // Paper - synchronize
this.acquire();
- PalettedContainerRO.PackedData var12;
+ // JettPack start - lithium: chunk.serialization
+ Optional<LongStream> data = Optional.empty();
+ List<T> elements = null;
try {
- HashMapPalette<T> hashMapPalette = new HashMapPalette<>(idList, this.data.storage.getBits(), this.dummyPaletteResize);
- int i = paletteProvider.size();
- int[] is = new int[i];
- this.data.storage.unpack(is);
- swapPalette(is, (id) -> {
- return hashMapPalette.idFor(this.data.palette.valueFor(id));
- });
- int j = paletteProvider.calculateBitsForSerialization(idList, hashMapPalette.getSize());
- Optional<LongStream> optional;
- if (j != 0) {
- SimpleBitStorage simpleBitStorage = new SimpleBitStorage(j, i, is);
- optional = Optional.of(Arrays.stream(simpleBitStorage.getRaw()));
- } else {
- optional = Optional.empty();
+ // The palette that will be serialized
+ LithiumHashPalette<T> hashPalette = null;
+
+ final Palette<T> palette = this.data.palette();
+ final BitStorage storage = this.data.storage();
+ if (storage instanceof ZeroBitStorage || palette.getSize() == 1) {
+ // If the palette only contains one entry, don't attempt to repack it.
+ elements = List.of(palette.valueFor(0));
+ } else if (palette instanceof LithiumHashPalette<T> lithiumHashPalette) {
+ hashPalette = lithiumHashPalette;
}
- var12 = new PalettedContainerRO.PackedData<>(hashMapPalette.getEntries(), optional);
+ if (elements == null) {
+ LithiumHashPalette<T> compactedPalette = new LithiumHashPalette<>(idList, storage.getBits(), this.dummyPaletteResize);
+ short[] array = this.getOrCreate(paletteProvider.size());
+
+ storage.compact(this.data.palette(), compactedPalette, array);
+
+ // If the palette didn't change during compaction, do a simple copy of the data array
+ if (hashPalette != null && hashPalette.getSize() == compactedPalette.getSize() && storage.getBits() == paletteProvider.calculateBitsForSerialization(idList, hashPalette.getSize())) { // paletteSize can de-sync from palette - see https://github.com/CaffeineMC/lithium-fabric/issues/279
+ data = this.asOptional(storage.getRaw().clone());
+ elements = hashPalette.getElements();
+ } else {
+ int bits = paletteProvider.calculateBitsForSerialization(idList, compactedPalette.getSize());
+ if (bits != 0) {
+ // Re-pack the integer array as the palette has changed size
+ SimpleBitStorage copy = new SimpleBitStorage(bits, array.length);
+ for (int i = 0; i < array.length; ++i) {
+ copy.set(i, array[i]);
+ }
+
+ // We don't need to clone the data array as we are the sole owner of it
+ data = this.asOptional(copy.getRaw());
+ }
+
+ elements = compactedPalette.getElements();
+ }
+ }
} finally {
this.release();
}
- return var12;
+ return new PalettedContainerRO.PackedData<>(elements, data);
+ // JettPack end
}
private static <T> void swapPalette(int[] is, IntUnaryOperator applier) {
@@ -366,17 +405,37 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
@Override
public void count(PalettedContainer.CountConsumer<T> counter) {
- if (this.data.palette.getSize() == 1) {
- counter.accept(this.data.palette.valueFor(0), this.data.storage.getSize());
- } else {
- Int2IntOpenHashMap int2IntOpenHashMap = new Int2IntOpenHashMap();
- this.data.storage.getAll((key) -> {
- int2IntOpenHashMap.addTo(key, 1);
- });
- int2IntOpenHashMap.int2IntEntrySet().forEach((entry) -> {
- counter.accept(this.data.palette.valueFor(entry.getIntKey()), entry.getIntValue());
- });
+ // JettPack start - lithium: chunk.serialization
+ int len = this.data.palette().getSize();
+
+ // Do not allocate huge arrays if we're using a large palette
+ if (len > 4096) {
+ // VanillaCopy
+ if (this.data.palette.getSize() == 1) {
+ counter.accept(this.data.palette.valueFor(0), this.data.storage.getSize());
+ } else {
+ Int2IntOpenHashMap int2IntOpenHashMap = new Int2IntOpenHashMap();
+ this.data.storage.getAll((key) -> {
+ int2IntOpenHashMap.addTo(key, 1);
+ });
+ int2IntOpenHashMap.int2IntEntrySet().forEach((entry) -> {
+ counter.accept(this.data.palette.valueFor(entry.getIntKey()), entry.getIntValue());
+ });
+ }
+ }
+
+ short[] counts = new short[len];
+
+ this.data.storage().getAll(i -> counts[i]++);
+
+ for (int i = 0; i < counts.length; i++) {
+ T obj = this.data.palette().valueFor(i);
+
+ if (obj != null) {
+ counter.accept(obj, counts[i]);
+ }
}
+ // JettPack end
}
static record Configuration<T>(Palette.Factory factory, int bits) {

View File

@@ -1,175 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 2No2Name <2No2Name@web.de>
Date: Thu, 13 Jan 2022 15:38:29 -0500
Subject: [PATCH] lithium: cache iterate outwards
Original code by the PR below, licensed under GNU Lesser General Public License v3.0
You can find the original code on https://github.com/CaffeineMC/lithium-fabric/pull/123 (Yarn mappings)
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/IterateOutwardsCache.java b/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/IterateOutwardsCache.java
new file mode 100644
index 0000000000000000000000000000000000000000..a5d3aa309d3fdaab9e0fea2dfb91a080a3ac1193
--- /dev/null
+++ b/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/IterateOutwardsCache.java
@@ -0,0 +1,71 @@
+package me.jellysquid.mods.lithium.common.cached_blockpos_iteration;
+
+import it.unimi.dsi.fastutil.longs.LongArrayList;
+import it.unimi.dsi.fastutil.longs.LongList;
+import java.util.Iterator;
+import java.util.Random;
+import java.util.concurrent.ConcurrentHashMap;
+import net.minecraft.core.BlockPos;
+
+/**
+ * @author 2No2Name, original implemenation by SuperCoder7979 and Gegy1000
+ */
+public class IterateOutwardsCache {
+ //POS_ZERO must not be replaced with BlockPos.ORIGIN, otherwise iterateOutwards at BlockPos.ORIGIN will not use the cache
+ public static final BlockPos POS_ZERO = new BlockPos(0,0,0);
+
+
+ private final ConcurrentHashMap<Long, LongArrayList> table;
+ private final int capacity;
+ private final Random random;
+
+ public IterateOutwardsCache(int capacity) {
+ this.capacity = capacity;
+ this.table = new ConcurrentHashMap<>(31);
+ this.random = new Random();
+ }
+
+ private void fillPositionsWithIterateOutwards(LongList entry, int xRange, int yRange, int zRange) {
+ // Add all positions to the cached list
+ for (BlockPos pos : BlockPos.withinManhattan(POS_ZERO, xRange, yRange, zRange)) {
+ entry.add(pos.asLong());
+ }
+ }
+
+ public LongList getOrCompute(int xRange, int yRange, int zRange) {
+ long key = BlockPos.asLong(xRange, yRange, zRange);
+
+ LongArrayList entry = this.table.get(key);
+ if (entry != null) {
+ return entry;
+ }
+
+ // Cache miss: compute and store
+ entry = new LongArrayList(128);
+
+ this.fillPositionsWithIterateOutwards(entry, xRange, yRange, zRange);
+
+ //decrease the array size, as of now it won't be modified anymore anyways
+ entry.trim();
+
+ //this might overwrite an entry as the same entry could have been computed and added during this thread's computation
+ //we do not use computeIfAbsent, as it can delay other threads for too long
+ Object previousEntry = this.table.put(key, entry);
+
+
+ if (previousEntry == null && this.table.size() > this.capacity) {
+ //prevent a memory leak by randomly removing about 1/8th of the elements when the exceed the desired capacity is exceeded
+ final Iterator<Long> iterator = this.table.keySet().iterator();
+ //prevent an unlikely infinite loop caused by another thread filling the table concurrently using counting
+ for (int i = -this.capacity; iterator.hasNext() && i < 5; i++) {
+ Long key2 = iterator.next();
+ //random is not threadsafe, but it doesn't matter here, because we don't need quality random numbers
+ if (this.random.nextInt(8) == 0 && key2 != key) {
+ iterator.remove();
+ }
+ }
+ }
+
+ return entry;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/LongList2BlockPosMutableIterable.java b/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/LongList2BlockPosMutableIterable.java
new file mode 100644
index 0000000000000000000000000000000000000000..493661ff3ac7247b68b7b02784b09b0eaf88fc52
--- /dev/null
+++ b/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/LongList2BlockPosMutableIterable.java
@@ -0,0 +1,46 @@
+package me.jellysquid.mods.lithium.common.cached_blockpos_iteration;
+
+import it.unimi.dsi.fastutil.longs.LongIterator;
+import it.unimi.dsi.fastutil.longs.LongList;
+import java.util.Iterator;
+import net.minecraft.core.BlockPos;
+
+/**
+ * @author 2No2Name
+ */
+public class LongList2BlockPosMutableIterable implements Iterable<BlockPos> {
+
+ private final LongList positions;
+ private final int xOffset, yOffset, zOffset;
+
+ public LongList2BlockPosMutableIterable(BlockPos offset, LongList posList) {
+ this.xOffset = offset.getX();
+ this.yOffset = offset.getY();
+ this.zOffset = offset.getZ();
+ this.positions = posList;
+ }
+
+ @Override
+ public Iterator<BlockPos> iterator() {
+ return new Iterator<BlockPos>() {
+
+ private final LongIterator it = LongList2BlockPosMutableIterable.this.positions.iterator();
+ private final BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
+
+ @Override
+ public boolean hasNext() {
+ return it.hasNext();
+ }
+
+ @Override
+ public net.minecraft.core.BlockPos next() {
+ long nextPos = this.it.nextLong();
+ return this.pos.set(
+ LongList2BlockPosMutableIterable.this.xOffset + BlockPos.getX(nextPos),
+ LongList2BlockPosMutableIterable.this.yOffset + BlockPos.getY(nextPos),
+ LongList2BlockPosMutableIterable.this.zOffset + BlockPos.getZ(nextPos));
+ }
+ };
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java
index b37e0ff164a894d2033fb94bbbc2f630a0e66bcd..79eae7a38ecfdf438f13ec7573326585b3c5f466 100644
--- a/src/main/java/net/minecraft/core/BlockPos.java
+++ b/src/main/java/net/minecraft/core/BlockPos.java
@@ -18,6 +18,12 @@ import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
+// JettPack start
+import it.unimi.dsi.fastutil.longs.LongList;
+import me.jellysquid.mods.lithium.common.cached_blockpos_iteration.IterateOutwardsCache;
+import me.jellysquid.mods.lithium.common.cached_blockpos_iteration.LongList2BlockPosMutableIterable;
+import static me.jellysquid.mods.lithium.common.cached_blockpos_iteration.IterateOutwardsCache.POS_ZERO;
+// JettPack end
@Immutable
public class BlockPos extends Vec3i {
@@ -279,7 +285,18 @@ public class BlockPos extends Vec3i {
};
}
+ // JettPack start - lithium: cached iterate outwards
+ private static final IterateOutwardsCache ITERATE_OUTWARDS_CACHE = new IterateOutwardsCache(50);
+ private static final LongList HOGLIN_PIGLIN_CACHE = ITERATE_OUTWARDS_CACHE.getOrCompute(8, 4, 8);
+ // JettPack end
+
public static Iterable<BlockPos> withinManhattan(BlockPos center, int rangeX, int rangeY, int rangeZ) {
+ // JettPack start - lithium: cached iterate outwards
+ if (center != POS_ZERO) {
+ final LongList positions = rangeX == 8 && rangeY == 4 && rangeZ == 8 ? HOGLIN_PIGLIN_CACHE : ITERATE_OUTWARDS_CACHE.getOrCompute(rangeX, rangeY, rangeZ);
+ return new LongList2BlockPosMutableIterable(center, positions);
+ }
+ // JettPack end
int i = rangeX + rangeY + rangeZ;
// Paper start - rename variables to fix conflict with anonymous class (remap fix)
int centerX = center.getX();

View File

@@ -1,31 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: ishland <ishlandmc@yeah.net>
Date: Sat, 12 Mar 2022 16:03:35 +0100
Subject: [PATCH] vmp: use linked map for entity trackers for faster iteration
Copyright (c) 2021-2022 ishland
Original code by RelativityMC, licensed under MIT
You can find the original code on https://github.com/RelativityMC/VMP-fabric (Yarn mappings)
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 364d899f4fba65f0ecae522c7dde4f1ef8ee632e..6ae3f09f01e7ad72d46aeb950cca83b0d2a8d88b 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -117,6 +117,7 @@ import org.bukkit.entity.Player;
// CraftBukkit end
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; // Paper
+import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap; // DivineMC - vmp: use linked map for entity trackers for faster iteration
public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider {
@@ -298,7 +299,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper - rewrite chunk system
this.tickingGenerated = new AtomicInteger();
this.playerMap = new PlayerMap();
- this.entityMap = new Int2ObjectOpenHashMap();
+ this.entityMap = new Int2ObjectLinkedOpenHashMap<>(); // DivineMC - vmp: use linked map for entity trackers for faster iteration
this.chunkTypeCache = new Long2ByteOpenHashMap();
this.chunkSaveCooldowns = new Long2LongOpenHashMap();
this.unloadQueue = Queues.newConcurrentLinkedQueue();

View File

@@ -1,164 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 2No2Name <2No2Name@web.de>
Date: Fri, 21 Jan 2022 08:41:34 -0500
Subject: [PATCH] lithium: block.moving_block_shapes
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
index 221c5d080d55326e458c1182823d6b49224ef498..6491fe817a0998910caa2d5aa4ebd7b8ced9ecda 100644
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
@@ -55,6 +55,74 @@ public class PistonMovingBlockEntity extends BlockEntity {
this.extending = extending;
this.isSourcePiston = source;
}
+ // JettPack start - lithium: block.moving_block_shapes
+ private static final VoxelShape[] PISTON_BASE_WITH_MOVING_HEAD_SHAPES = precomputePistonBaseWithMovingHeadShapes();
+
+ /**
+ * We cache the offset and simplified VoxelShapes that are otherwise constructed on every call of getCollisionShape.
+ * For each offset direction and distance (6 directions, 2 distances each, and no direction with 0 distance) we
+ * store the offset and simplified VoxelShapes in the original VoxelShape when they are accessed the first time.
+ * We use safe publication, because both the Render and Server thread are using the cache.
+ *
+ * @param blockShape the original shape, must not be modified after passing it as an argument to this method
+ * @param offset the offset distance
+ * @param direction the offset direction
+ * @return blockShape offset and simplified
+ */
+ private static VoxelShape getOffsetAndSimplified(VoxelShape blockShape, float offset, Direction direction) {
+ VoxelShape offsetSimplifiedShape = blockShape.getOffsetSimplifiedShape(offset, direction);
+ if (offsetSimplifiedShape == null) {
+ //create the offset shape and store it for later use
+ offsetSimplifiedShape = blockShape.move(direction.getStepX() * offset, direction.getStepY() * offset, direction.getStepZ() * offset).optimize();
+ blockShape.setShape(offset, direction, offsetSimplifiedShape);
+ }
+ return offsetSimplifiedShape;
+ }
+
+ /**
+ * Precompute all 18 possible configurations for the merged piston base and head shape.
+ *
+ * @return The array of the merged VoxelShapes, indexed by {@link PistonBlockEntityMixin#getIndexForMergedShape(float, Direction)}
+ */
+ private static VoxelShape[] precomputePistonBaseWithMovingHeadShapes() {
+ float[] offsets = {0f, 0.5f, 1f};
+ Direction[] directions = Direction.values();
+
+ VoxelShape[] mergedShapes = new VoxelShape[offsets.length * directions.length];
+
+ for (Direction facing : directions) {
+ VoxelShape baseShape = Blocks.PISTON.defaultBlockState().setValue(PistonBaseBlock.EXTENDED, true)
+ .setValue(PistonBaseBlock.FACING, facing).getCollisionShape(null, null);
+ for (float offset : offsets) {
+ //this cache is only required for the merged piston head + base shape.
+ //this shape is only used when !this.extending
+ //here: isShort = this.extending != 1.0F - this.progress < 0.25F can be simplified to:
+ //isShort = f < 0.25F , because f = getAmountExtended(this.progress) can be simplified to f == 1.0F - this.progress
+ //therefore isShort is dependent on the offset:
+ boolean isShort = offset < 0.25f;
+
+ VoxelShape headShape = (Blocks.PISTON_HEAD.defaultBlockState().setValue(PistonHeadBlock.FACING, facing))
+ .setValue(PistonHeadBlock.SHORT, isShort).getCollisionShape(null, null);
+
+ VoxelShape offsetHead = headShape.move(facing.getStepX() * offset,
+ facing.getStepY() * offset,
+ facing.getStepZ() * offset);
+ mergedShapes[getIndexForMergedShape(offset, facing)] = Shapes.or(baseShape, offsetHead);
+ }
+
+ }
+
+ return mergedShapes;
+ }
+
+ private static int getIndexForMergedShape(float offset, Direction direction) {
+ if (offset != 0f && offset != 0.5f && offset != 1f) {
+ return -1;
+ }
+ //shape of offset 0 is still dependent on the direction, due to piston head and base being directional blocks
+ return (int) (2 * offset) + (3 * direction.get3DDataValue());
+ }
+ // JettPack end
@Override
public CompoundTag getUpdateTag() {
@@ -355,10 +423,27 @@ public class PistonMovingBlockEntity extends BlockEntity {
}
float f = this.getExtendedProgress(this.progress);
+ // JettPack start - lithium: block.moving_block_shapes
+ if (this.extending || !this.isSourcePiston || !(this.movedState.getBlock() instanceof PistonBaseBlock)) {
+ //here voxelShape2.isEmpty() is guaranteed, vanilla code would call union() which calls simplify()
+ VoxelShape blockShape = blockState.getCollisionShape(world, pos);
+
+ //we cache the simplified shapes, as the simplify() method costs a lot of CPU time and allocates several objects
+ VoxelShape offsetAndSimplified = getOffsetAndSimplified(blockShape, Math.abs(f), f < 0f ? this.direction.getOpposite() : this.direction);
+ return offsetAndSimplified;
+ } else {
+ //retracting piston heads have to act like their base as well, as the base block is replaced with the moving block
+ //f >= 0f is guaranteed (assuming no other mod interferes)
+ int index = getIndexForMergedShape(f, this.direction);
+ return PISTON_BASE_WITH_MOVING_HEAD_SHAPES[index];
+ }
+ /*
double d = (double)((float)this.direction.getStepX() * f);
double e = (double)((float)this.direction.getStepY() * f);
double g = (double)((float)this.direction.getStepZ() * f);
return Shapes.or(voxelShape, blockState.getCollisionShape(world, pos).move(d, e, g));
+ */
+ // JettPack end
}
}
diff --git a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java
index 2182afd1b95acf14c55bddfeec17dae0a63e1f00..461ac9a464c4a66e302798032c6019bb60f6862b 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java
@@ -26,6 +26,44 @@ public abstract class VoxelShape {
}
// Paper end
+ // JettPack start - lithium: block.moving_block_shapes
+ private volatile VoxelShape[] offsetAndSimplified;
+
+ public void setShape(float offset, Direction direction, VoxelShape offsetShape) {
+ if (offsetShape == null) {
+ throw new IllegalArgumentException("offsetShape must not be null!");
+ }
+ int index = getIndexForOffsetSimplifiedShapes(offset, direction);
+ VoxelShape[] offsetAndSimplifiedShapes = this.offsetAndSimplified;
+ if (offsetAndSimplifiedShapes == null) {
+ offsetAndSimplifiedShapes = new VoxelShape[1 + 2 * 6];
+ } else {
+ offsetAndSimplifiedShapes = offsetAndSimplifiedShapes.clone();
+ }
+ offsetAndSimplifiedShapes[index] = offsetShape;
+ this.offsetAndSimplified = offsetAndSimplifiedShapes;
+ }
+
+ public VoxelShape getOffsetSimplifiedShape(float offset, Direction direction) {
+ VoxelShape[] offsetAndSimplified = this.offsetAndSimplified;
+ if (offsetAndSimplified == null) {
+ return null;
+ }
+ int index = getIndexForOffsetSimplifiedShapes(offset, direction);
+ return offsetAndSimplified[index];
+ }
+
+ private static int getIndexForOffsetSimplifiedShapes(float offset, Direction direction) {
+ if (offset != 0f && offset != 0.5f && offset != 1f) {
+ throw new IllegalArgumentException("offset must be one of {0f, 0.5f, 1f}");
+ }
+ if (offset == 0f) {
+ return 0; //can treat offsetting by 0 in all directions the same
+ }
+ return (int) (2 * offset) + 2 * direction.get3DDataValue();
+ }
+ // JettPack end
+
protected VoxelShape(DiscreteVoxelShape voxels) { // Paper - protected
this.shape = voxels;
}

View File

@@ -1,23 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Tue, 14 Mar 2023 22:59:14 +0300
Subject: [PATCH] Fix MC-93826
diff --git a/src/main/java/net/minecraft/world/entity/animal/Animal.java b/src/main/java/net/minecraft/world/entity/animal/Animal.java
index 3c4d142e982c34a23bdb5da1f51c8dcacc0532c1..9e32d6a089df23ff6edce81df131aeb21218bac5 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Animal.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Animal.java
@@ -69,7 +69,11 @@ public abstract class Animal extends AgeableMob {
double d1 = this.random.nextGaussian() * 0.02D;
double d2 = this.random.nextGaussian() * 0.02D;
- this.level.addParticle(ParticleTypes.HEART, this.getRandomX(1.0D), this.getRandomY() + 0.5D, this.getRandomZ(1.0D), d0, d1, d2);
+ // DivineMC start - Fix MC-93826
+ if (this.level instanceof ServerLevel serverLevel) {
+ serverLevel.sendParticles(ParticleTypes.HEART, this.getRandomX(1.0D), this.getRandomY() + 0.5D, this.getRandomZ(1.0D), 1, d0, d1, d2, 0);
+ }
+ // DivineMC end
}
}

View File

@@ -1,384 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Wed, 15 Mar 2023 16:20:48 +0300
Subject: [PATCH] Optimize default values for configs
diff --git a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java
index e0076044d0a29e33ee297fe6180a041436075297..cf3aecfc34ab4d1f2ddf43bdad4379ec07c89539 100644
--- a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java
+++ b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java
@@ -219,7 +219,7 @@ public class PufferfishConfig {
public static int maxProjectileLoadsPerProjectile;
private static void projectileLoading() {
maxProjectileLoadsPerTick = getInt("projectile.max-loads-per-tick", 10, "Controls how many chunks are allowed", "to be sync loaded by projectiles in a tick.");
- maxProjectileLoadsPerProjectile = getInt("projectile.max-loads-per-projectile", 10, "Controls how many chunks a projectile", "can load in its lifetime before it gets", "automatically removed.");
+ maxProjectileLoadsPerProjectile = getInt("projectile.max-loads-per-projectile", 8, "Controls how many chunks a projectile", "can load in its lifetime before it gets", "automatically removed."); // DivineMC - optimize default values for configs
setComment("projectile", "Optimizes projectile settings");
}
diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
index 01bdf134fc21220ab7ecca51f2dcd51c0b466bba..83373befc7357094a13c74bf87ac148017cfd45f 100644
--- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
+++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
@@ -55,7 +55,7 @@ public class GlobalConfiguration extends ConfigurationPart {
public boolean enabled = true;
public boolean reallyEnabled = false;
public boolean verbose = true;
- public String url = "https://timings.aikar.co/";
+ public String url = "https://timin.gs/"; // DivineMC - optimize default values for configs
public boolean serverNamePrivacy = false;
public List<String> hiddenConfigEntries = List.of(
"database",
@@ -291,9 +291,9 @@ public class GlobalConfiguration extends ConfigurationPart {
public boolean fixEntityPositionDesync = true;
public boolean loadPermissionsYmlBeforePlugins = true;
@Constraints.Min(4)
- public int regionFileCacheSize = 256;
+ public int regionFileCacheSize = 512; // DivineMC - optimize default values for configs
@Comment("See https://luckformula.emc.gs")
- public boolean useAlternativeLuckFormula = false;
+ public boolean useAlternativeLuckFormula = true; // DivineMC - optimize default values for configs
public boolean lagCompensateBlockBreaking = true;
public boolean useDimensionTypeForCustomSpawners = false;
public boolean strictAdvancementDimensionCheck = false;
diff --git a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java
index 51cf0014c4229fc8671804d885b6381996810130..b4a3207ddb31d44e95732f2f01fbaceadfbf01b2 100644
--- a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java
+++ b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java
@@ -115,9 +115,9 @@ public class WorldConfiguration extends ConfigurationPart {
public ArmorStands armorStands;
- public class ArmorStands extends ConfigurationPart {
- public boolean doCollisionEntityLookups = true;
- public boolean tick = true;
+ public class ArmorStands extends ConfigurationPart { // DivineMC - optimize default values for configs
+ public boolean doCollisionEntityLookups = false;
+ public boolean tick = false;
}
public Spawning spawning;
@@ -201,8 +201,8 @@ public class WorldConfiguration extends ConfigurationPart {
public Behavior behavior;
public class Behavior extends ConfigurationPart {
- public boolean disableChestCatDetection = false;
- public boolean spawnerNerfedMobsShouldJump = false;
+ public boolean disableChestCatDetection = true; // DivineMC - optimize default values for configs
+ public boolean spawnerNerfedMobsShouldJump = true; // DivineMC - optimize default values for configs
public int experienceMergeMaxValue = -1;
public boolean shouldRemoveDragon = false;
public boolean zombiesTargetTurtleEggs = true;
@@ -249,7 +249,7 @@ public class WorldConfiguration extends ConfigurationPart {
public int playerInsomniaStartTicks = 72000;
public int phantomsSpawnAttemptMinSeconds = 60;
public int phantomsSpawnAttemptMaxSeconds = 119;
- public boolean parrotsAreUnaffectedByPlayerMovement = false;
+ public boolean parrotsAreUnaffectedByPlayerMovement = true; // DivineMC - optimize default values for configs
public double zombieVillagerInfectionChance = -1.0;
public MobsCanAlwaysPickUpLoot mobsCanAlwaysPickUpLoot;
@@ -259,7 +259,7 @@ public class WorldConfiguration extends ConfigurationPart {
}
public boolean disablePlayerCrits = false;
- public boolean nerfPigmenFromNetherPortals = false;
+ public boolean nerfPigmenFromNetherPortals = true; // DivineMC - optimize default values for configs
public PillagerPatrols pillagerPatrols;
public class PillagerPatrols extends ConfigurationPart {
@@ -317,7 +317,7 @@ public class WorldConfiguration extends ConfigurationPart {
public class Environment extends ConfigurationPart {
public boolean disableThunder = false;
public boolean disableIceAndSnow = false;
- public boolean optimizeExplosions = false;
+ public boolean optimizeExplosions = true; // DivineMC - optimize default values for configs
public boolean disableExplosionKnockback = false;
public boolean generateFlatBedrock = false;
public FrostedIce frostedIce;
@@ -363,7 +363,7 @@ public class WorldConfiguration extends ConfigurationPart {
public class Maps extends ConfigurationPart {
public int itemFrameCursorLimit = 128;
- public int itemFrameCursorUpdateInterval = 10;
+ public int itemFrameCursorUpdateInterval = 20; // DivineMC - optimize default values for configs
}
public Fixes fixes;
@@ -389,7 +389,7 @@ public class WorldConfiguration extends ConfigurationPart {
public class Hopper extends ConfigurationPart {
public boolean cooldownWhenFull = true;
public boolean disableMoveEvent = false;
- public boolean ignoreOccludingBlocks = false;
+ public boolean ignoreOccludingBlocks = true; // DivineMC - optimize default values for configs
}
public Collisions collisions;
@@ -397,9 +397,9 @@ public class WorldConfiguration extends ConfigurationPart {
public class Collisions extends ConfigurationPart {
public boolean onlyPlayersCollide = false;
public boolean allowVehicleCollisions = true;
- public boolean fixClimbingBypassingCrammingRule = false;
+ public boolean fixClimbingBypassingCrammingRule = true; // DivineMC - optimize default values for configs
@RequiresSpigotInitialization(MaxEntityCollisionsInitializer.class)
- public int maxEntityCollisions = 8;
+ public int maxEntityCollisions = 2; // DivineMC - optimize default values for configs
public boolean allowPlayerCrammingDamage = false;
}
@@ -407,18 +407,31 @@ public class WorldConfiguration extends ConfigurationPart {
public class Chunks extends ConfigurationPart {
public AutosavePeriod autoSaveInterval = AutosavePeriod.def();
- public int maxAutoSaveChunksPerTick = 24;
+ public int maxAutoSaveChunksPerTick = 12; // DivineMC - optimize default values for configs
public int fixedChunkInhabitedTime = -1;
- public boolean preventMovingIntoUnloadedChunks = false;
- public Duration delayChunkUnloadsBy = Duration.of("10s");
+ public boolean preventMovingIntoUnloadedChunks = true; // DivineMC - optimize default values for configs
+ public Duration delayChunkUnloadsBy = Duration.of("5s"); // DivineMC - optimize default values for configs
public Reference2IntMap<EntityType<?>> entityPerChunkSaveLimit = Util.make(new Reference2IntOpenHashMap<>(BuiltInRegistries.ENTITY_TYPE.size()), map -> {
- map.defaultReturnValue(-1);
- map.put(EntityType.EXPERIENCE_ORB, -1);
- map.put(EntityType.SNOWBALL, -1);
- map.put(EntityType.ENDER_PEARL, -1);
- map.put(EntityType.ARROW, -1);
- map.put(EntityType.FIREBALL, -1);
- map.put(EntityType.SMALL_FIREBALL, -1);
+ // DivineMC start - optimize default values for configs
+ map.put(EntityType.EXPERIENCE_ORB, 16);
+ map.put(EntityType.SNOWBALL, 8);
+ map.put(EntityType.ENDER_PEARL, 8);
+ map.put(EntityType.ARROW, 16);
+ map.put(EntityType.FIREBALL, 8);
+ map.put(EntityType.SMALL_FIREBALL, 8);
+ map.put(EntityType.DRAGON_FIREBALL, 3);
+ map.put(EntityType.EGG, 8);
+ map.put(EntityType.EYE_OF_ENDER, 8);
+ map.put(EntityType.FIREWORK_ROCKET, 8);
+ map.put(EntityType.POTION, 8);
+ map.put(EntityType.LLAMA_SPIT, 3);
+ map.put(EntityType.SHULKER_BULLET, 8);
+ map.put(EntityType.SPECTRAL_ARROW, 16);
+ map.put(EntityType.EXPERIENCE_BOTTLE, 3);
+ map.put(EntityType.TRIDENT, 16);
+ map.put(EntityType.WITHER_SKULL, 4);
+ map.put(EntityType.AREA_EFFECT_CLOUD, 8);
+ // DivineMC end
});
}
@@ -432,11 +445,22 @@ public class WorldConfiguration extends ConfigurationPart {
public TickRates tickRates;
public class TickRates extends ConfigurationPart {
- public int grassSpread = 1;
- public int containerUpdate = 1;
- public int mobSpawner = 1;
- public Table<EntityType<?>, String, Integer> sensor = Util.make(HashBasedTable.create(), table -> table.put(EntityType.VILLAGER, "secondarypoisensor", 40));
- public Table<EntityType<?>, String, Integer> behavior = Util.make(HashBasedTable.create(), table -> table.put(EntityType.VILLAGER, "validatenearbypoi", -1));
+ // DivineMC start - optimize default values for configs
+ public int grassSpread = 4;
+ public int containerUpdate = 3;
+ public int mobSpawner = 2;
+ public Table<EntityType<?>, String, Integer> sensor = Util.make(HashBasedTable.create(), table -> {
+ table.put(EntityType.VILLAGER, "secondarypoisensor", 80);
+ table.put(EntityType.VILLAGER, "nearestbedsensor", 80);
+ table.put(EntityType.VILLAGER, "villagerbabiessensor", 40);
+ table.put(EntityType.VILLAGER, "playersensor", 40);
+ table.put(EntityType.VILLAGER, "nearestlivingentitysensor", 40);
+ });
+ public Table<EntityType<?>, String, Integer> behavior = Util.make(HashBasedTable.create(), table -> {
+ table.put(EntityType.VILLAGER, "validatenearbypoi", 60);
+ table.put(EntityType.VILLAGER, "acquirepoi", 120);
+ });
+ // DivineMC end
}
@Setting(FeatureSeedsGeneration.FEATURE_SEEDS_KEY)
@@ -444,7 +468,7 @@ public class WorldConfiguration extends ConfigurationPart {
public class FeatureSeeds extends ConfigurationPart.Post {
@Setting(FeatureSeedsGeneration.GENERATE_KEY)
- public boolean generateRandomSeedsForAll = false;
+ public boolean generateRandomSeedsForAll = true; // DivineMC - optimize default values for configs
@Setting(FeatureSeedsGeneration.FEATURES_KEY)
public Reference2LongMap<Holder<ConfiguredFeature<?, ?>>> features = new Reference2LongOpenHashMap<>();
@@ -458,9 +482,9 @@ public class WorldConfiguration extends ConfigurationPart {
public class Misc extends ConfigurationPart {
public int lightQueueSize = 20;
- public boolean updatePathfindingOnBlockUpdate = true;
+ public boolean updatePathfindingOnBlockUpdate = false; // DivineMC - optimize default values for configs
public boolean showSignClickCommandFailureMsgsToPlayer = false;
- public RedstoneImplementation redstoneImplementation = RedstoneImplementation.VANILLA;
+ public RedstoneImplementation redstoneImplementation = RedstoneImplementation.ALTERNATE_CURRENT; // DivineMC - optimize default values for configs
public boolean disableEndCredits = false;
public float maxLeashDistance = 10f;
public boolean disableSprintInterruptionOnAttack = false;
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 7c1efc3b6045b2179139dd419e969569f1af9f6d..5827c8a5b563e6411e02aa4db03e6d8d56ef3a5b 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -146,14 +146,14 @@ public class SpigotWorldConfig
public double itemMerge;
private void itemMerge()
{
- this.itemMerge = this.getDouble("merge-radius.item", 2.5 );
+ this.itemMerge = this.getDouble("merge-radius.item", 3.5 ); // DivineMC - optimize default values for configs
this.log( "Item Merge Radius: " + this.itemMerge );
}
public double expMerge;
private void expMerge()
{
- this.expMerge = this.getDouble("merge-radius.exp", 3.0 );
+ this.expMerge = this.getDouble("merge-radius.exp", 4.0 ); // DivineMC - optimize default values for configs
this.log( "Experience Merge Radius: " + this.expMerge );
}
@@ -192,7 +192,7 @@ public class SpigotWorldConfig
public byte mobSpawnRange;
private void mobSpawnRange()
{
- this.mobSpawnRange = (byte) getInt( "mob-spawn-range", 8 ); // Paper - Vanilla
+ this.mobSpawnRange = (byte) getInt( "mob-spawn-range", 2 ); // Paper - Vanilla // DivineMC - optimize default values for configs
this.log( "Mob Spawn Range: " + this.mobSpawnRange );
}
@@ -203,14 +203,14 @@ public class SpigotWorldConfig
this.log( "Item Despawn Rate: " + this.itemDespawnRate );
}
- public int animalActivationRange = 32;
- public int monsterActivationRange = 32;
+ public int animalActivationRange = 16; // DivineMC - optimize default values for configs
+ public int monsterActivationRange = 24; // DivineMC - optimize default values for configs
public int raiderActivationRange = 48;
- public int miscActivationRange = 16;
+ public int miscActivationRange = 8; // DivineMC - optimize default values for configs
// Paper start
public int flyingMonsterActivationRange = 32;
- public int waterActivationRange = 16;
- public int villagerActivationRange = 32;
+ public int waterActivationRange = 8; // DivineMC - optimize default values for configs
+ public int villagerActivationRange = 16; // DivineMC - optimize default values for configs
public int wakeUpInactiveAnimals = 4;
public int wakeUpInactiveAnimalsEvery = 60*20;
public int wakeUpInactiveAnimalsFor = 5*20;
@@ -227,7 +227,7 @@ public class SpigotWorldConfig
public int villagersWorkImmunityFor = 20;
public boolean villagersActiveForPanic = true;
// Paper end
- public boolean tickInactiveVillagers = true;
+ public boolean tickInactiveVillagers = false; // DivineMC - optimize default values for configs
public boolean ignoreSpectatorActivation = false;
private void activationRange()
{
@@ -293,7 +293,7 @@ public class SpigotWorldConfig
{
this.set( "ticks-per.hopper-check", 1 );
}
- this.hopperCheck = this.getInt( "ticks-per.hopper-check", 1 );
+ this.hopperCheck = this.getInt( "ticks-per.hopper-check", 8 ); // DivineMC - optimize default values for configs
this.hopperAmount = this.getInt( "hopper-amount", 1 );
this.hopperCanLoadChunks = this.getBoolean( "hopper-can-load-chunks", false );
this.log( "Hopper Transfer: " + this.hopperTransfer + " Hopper Check: " + this.hopperCheck + " Hopper Amount: " + this.hopperAmount + " Hopper Can Load Chunks: " + this.hopperCanLoadChunks );
@@ -303,7 +303,7 @@ public class SpigotWorldConfig
public int tridentDespawnRate;
private void arrowDespawnRate()
{
- this.arrowDespawnRate = this.getInt( "arrow-despawn-rate", 1200 );
+ this.arrowDespawnRate = this.getInt( "arrow-despawn-rate", 300 ); // DivineMC - optimize default values for configs
this.tridentDespawnRate = this.getInt( "trident-despawn-rate", this.arrowDespawnRate );
this.log( "Arrow Despawn Rate: " + this.arrowDespawnRate + " Trident Respawn Rate:" + this.tridentDespawnRate );
}
@@ -318,14 +318,14 @@ public class SpigotWorldConfig
public boolean nerfSpawnerMobs;
private void nerfSpawnerMobs()
{
- this.nerfSpawnerMobs = this.getBoolean( "nerf-spawner-mobs", false );
+ this.nerfSpawnerMobs = this.getBoolean( "nerf-spawner-mobs", true ); // DivineMC - optimize default values for configs
this.log( "Nerfing mobs spawned from spawners: " + this.nerfSpawnerMobs );
}
public boolean enableZombiePigmenPortalSpawns;
private void enableZombiePigmenPortalSpawns()
{
- this.enableZombiePigmenPortalSpawns = this.getBoolean( "enable-zombie-pigmen-portal-spawns", true );
+ this.enableZombiePigmenPortalSpawns = this.getBoolean("enable-zombie-pigmen-portal-spawns", false ); // DivineMC - optimize default values for configs
this.log( "Allow Zombie Pigmen to spawn from portal blocks: " + this.enableZombiePigmenPortalSpawns );
}
@@ -439,7 +439,7 @@ public class SpigotWorldConfig
public int hangingTickFrequency;
private void hangingTickFrequency()
{
- this.hangingTickFrequency = this.getInt( "hanging-tick-frequency", 100 );
+ this.hangingTickFrequency = this.getInt( "hanging-tick-frequency", 200 ); // DivineMC - optimize default values for configs
}
/* JettPack - remove tick limiter
diff --git a/src/main/resources/configurations/bukkit.yml b/src/main/resources/configurations/bukkit.yml
index eef7c125b2689f29cae5464659eacdf33f5695b2..c6b04acb5371a0ac454c5e377bccad5b0972aed8 100644
--- a/src/main/resources/configurations/bukkit.yml
+++ b/src/main/resources/configurations/bukkit.yml
@@ -18,28 +18,28 @@ settings:
update-folder: update
plugin-profiling: false
connection-throttle: 4000
- query-plugins: true
+ query-plugins: false
deprecated-verbose: default
shutdown-message: Server closed
minimum-api: none
use-map-color-cache: true
spawn-limits:
- monsters: 70
- animals: 10
- water-animals: 5
- water-ambient: 20
- water-underground-creature: 5
- axolotls: 5
- ambient: 15
+ monsters: 20
+ animals: 5
+ water-animals: 2
+ water-ambient: 2
+ water-underground-creature: 3
+ axolotls: 3
+ ambient: 1
chunk-gc:
- period-in-ticks: 600
+ period-in-ticks: 400
ticks-per:
animal-spawns: 400
- monster-spawns: 1
- water-spawns: 1
- water-ambient-spawns: 1
- water-underground-creature-spawns: 1
- axolotl-spawns: 1
- ambient-spawns: 1
+ monster-spawns: 10
+ water-spawns: 400
+ water-ambient-spawns: 400
+ water-underground-creature-spawns: 400
+ axolotl-spawns: 400
+ ambient-spawns: 400
autosave: 6000
aliases: now-in-commands.yml
diff --git a/src/main/resources/configurations/commands.yml b/src/main/resources/configurations/commands.yml
index 18f54571200e2eca09a39b88f170fe7b99d8618f..dd43550118df25f8cad1bbe9f4a4a74d492b4fc4 100644
--- a/src/main/resources/configurations/commands.yml
+++ b/src/main/resources/configurations/commands.yml
@@ -11,6 +11,4 @@
command-block-overrides: []
ignore-vanilla-permissions: false
-aliases:
- icanhasbukkit:
- - "version $1-"
+aliases:
\ No newline at end of file

View File

@@ -1,208 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: SoSeDiK <mrsosedik@gmail.com>
Date: Fri, 2 Dec 2022 21:44:23 +0200
Subject: [PATCH] Dynamic minecart speed
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
index 9a80cf593bbdd7681bc9395daf4545a98e07636f..012d4ad1651d7a9118b24e0589d8bdf28ed0b708 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
@@ -573,7 +573,108 @@ public abstract class AbstractMinecart extends Entity {
d5 = -d5;
}
- double d8 = Math.min(2.0D, vec3d1.horizontalDistance());
+ // Kiterino start - dynamic minecart speed
+ double vanillaMaxHorizontalMovementPerTick = 0.4D;
+ double horizontalMomentumPerTick = vec3d1.horizontalDistance();
+
+ java.util.function.DoubleSupplier calculateMaxHorizontalMovementPerTick = () -> {
+ final double fallbackSpeedFactor = 1.15D;
+ double fallback = this.getMaxSpeed();
+
+ if (this.getPassengers().isEmpty())
+ return fallback;
+
+ if (horizontalMomentumPerTick < vanillaMaxHorizontalMovementPerTick)
+ return fallback;
+
+ fallback *= fallbackSpeedFactor;
+
+ boolean hasEligibleShape = blockpropertytrackposition == RailShape.NORTH_SOUTH || blockpropertytrackposition == RailShape.EAST_WEST;
+ if (!hasEligibleShape)
+ return fallback;
+
+ boolean hasEligibleType = state.is(Blocks.RAIL) || (state.is(Blocks.POWERED_RAIL) && state.getValue(PoweredRailBlock.POWERED));
+ if (!hasEligibleType)
+ return fallback;
+
+ var eligibleNeighbors = new java.util.concurrent.atomic.AtomicInteger();
+
+ java.util.HashSet<BlockPos> checkedPositions = new java.util.HashSet<>();
+ checkedPositions.add(pos);
+
+ java.util.function.BiFunction<BlockPos, RailShape, java.util.ArrayList<Pair<BlockPos, RailShape>>> checkNeighbors = (cPos, cRailShape) -> {
+ Pair<Vec3i, Vec3i> cAdjPosDiff = AbstractMinecart.exits(cRailShape);
+ java.util.ArrayList<Pair<BlockPos, RailShape>> newNeighbors = new java.util.ArrayList<>();
+
+ BlockPos n1Pos = cPos.offset(cAdjPosDiff.getFirst());
+
+ if (!checkedPositions.contains(n1Pos)) {
+ BlockState n1State = this.level.getBlockState(n1Pos);
+ boolean n1HasEligibleType = n1State.is(Blocks.RAIL) || (n1State.is(Blocks.POWERED_RAIL) && n1State.getValue(PoweredRailBlock.POWERED));
+ if (!n1HasEligibleType)
+ return new java.util.ArrayList<>();
+
+ RailShape n1RailShape = n1State.getValue(((BaseRailBlock) n1State.getBlock()).getShapeProperty());
+ if (n1RailShape != blockpropertytrackposition)
+ return new java.util.ArrayList<>();
+
+ checkedPositions.add(n1Pos);
+ eligibleNeighbors.incrementAndGet();
+ newNeighbors.add(Pair.of(n1Pos, n1RailShape));
+ }
+
+ BlockPos n2Pos = cPos.offset(cAdjPosDiff.getSecond());
+ if (!checkedPositions.contains(n2Pos)) {
+ BlockState n2State = this.level.getBlockState(n2Pos);
+ boolean n2HasEligibleType = n2State.is(Blocks.RAIL) || (n2State.is(Blocks.POWERED_RAIL) && n2State.getValue(PoweredRailBlock.POWERED));
+ if (!n2HasEligibleType)
+ return new java.util.ArrayList<>();
+
+ RailShape n2RailShape = n2State.getValue(((BaseRailBlock) n2State.getBlock()).getShapeProperty());
+
+ if (n2RailShape != blockpropertytrackposition)
+ return new java.util.ArrayList<>();
+
+ checkedPositions.add(n2Pos);
+ eligibleNeighbors.incrementAndGet();
+ newNeighbors.add(Pair.of(n2Pos, n2RailShape));
+ }
+
+ return newNeighbors;
+ };
+
+
+ java.util.ArrayList<Pair<BlockPos, RailShape>> newNeighbors = checkNeighbors.apply(pos, blockpropertytrackposition);
+
+ while (!newNeighbors.isEmpty() && eligibleNeighbors.get() < 16) {
+ java.util.ArrayList<Pair<BlockPos, RailShape>> tempNewNeighbors = new java.util.ArrayList<>(newNeighbors);
+ newNeighbors.clear();
+
+ for (Pair<BlockPos, RailShape> newNeighbor : tempNewNeighbors) {
+ java.util.ArrayList<Pair<BlockPos, RailShape>> result = checkNeighbors.apply(newNeighbor.getFirst(), newNeighbor.getSecond());
+
+ if (result.isEmpty()) {
+ newNeighbors.clear();
+ break;
+ }
+
+ newNeighbors.addAll(result);
+ }
+ }
+
+ int eligibleForwardRailTrackCount = eligibleNeighbors.get() / 2;
+
+ if (eligibleForwardRailTrackCount <= 1)
+ return fallback;
+
+ return (2.01D + eligibleForwardRailTrackCount * 4D) / 20D;
+ };
+
+ double maxHorizontalMovementPerTick = calculateMaxHorizontalMovementPerTick.getAsDouble();
+ double maxHorizontalMomentumPerTick = Math.max(maxHorizontalMovementPerTick * 5D, 4.2D);
+ // Kiterino end
+
+ double d8 = Math.min(maxHorizontalMomentumPerTick, vec3d1.horizontalDistance()); // Kiterino - dynamic minecart speed, unhardcode 2.0D
vec3d1 = new Vec3(d8 * d4 / d6, vec3d1.y, d8 * d5 / d6);
this.setDeltaMovement(vec3d1);
@@ -596,8 +697,15 @@ public abstract class AbstractMinecart extends Entity {
d11 = this.getDeltaMovement().horizontalDistance();
if (d11 < 0.03D) {
this.setDeltaMovement(Vec3.ZERO);
- } else {
- this.setDeltaMovement(this.getDeltaMovement().multiply(0.5D, 0.0D, 0.5D));
+ }
+ else {
+ // Kiterino start - dynamic minecart speed
+ double brakeFactor = 0.5D;
+ if (horizontalMomentumPerTick > 4D * vanillaMaxHorizontalMovementPerTick) {
+ brakeFactor = Math.pow(brakeFactor, 1D + ((horizontalMomentumPerTick - 3.99D * vanillaMaxHorizontalMovementPerTick) / 1.2D));
+ }
+ // Kiterino end
+ this.setDeltaMovement(this.getDeltaMovement().multiply(brakeFactor, 0.0D, brakeFactor)); // Kiterino - dynamic minecart speed, unhardcode 0.5D
}
}
@@ -626,9 +734,10 @@ public abstract class AbstractMinecart extends Entity {
d2 = d12 + d5 * d15;
this.setPos(d0, d1, d2);
d16 = this.isVehicle() ? 0.75D : 1.0D;
- d17 = this.getMaxSpeed();
+ d17 = maxHorizontalMomentumPerTick;
vec3d1 = this.getDeltaMovement();
- this.move(MoverType.SELF, new Vec3(Mth.clamp(d16 * vec3d1.x, -d17, d17), 0.0D, Mth.clamp(d16 * vec3d1.z, -d17, d17)));
+ var movement = new Vec3(Mth.clamp(d16 * vec3d1.x, -d17, d17), 0D, Mth.clamp(d16 * vec3d1.z, -d17, d17));
+ this.move(MoverType.SELF, movement); // Kiterino - dynamic minecart speed, expose into the variable
if (baseblockposition.getY() != 0 && Mth.floor(this.getX()) - pos.getX() == baseblockposition.getX() && Mth.floor(this.getZ()) - pos.getZ() == baseblockposition.getZ()) {
this.setPos(this.getX(), this.getY() + (double) baseblockposition.getY(), this.getZ());
} else if (baseblockposition1.getY() != 0 && Mth.floor(this.getX()) - pos.getX() == baseblockposition1.getX() && Mth.floor(this.getZ()) - pos.getZ() == baseblockposition1.getZ()) {
@@ -658,26 +767,52 @@ public abstract class AbstractMinecart extends Entity {
if (i != pos.getX() || j != pos.getZ()) {
vec3d4 = this.getDeltaMovement();
d18 = vec3d4.horizontalDistance();
- this.setDeltaMovement(d18 * (double) (i - pos.getX()), vec3d4.y, d18 * (double) (j - pos.getZ()));
+ this.setDeltaMovement(d18 * Mth.clamp((double) i - pos.getX(), -1D, 1D), vec3d4.y, d18 * Mth.clamp((double) j - pos.getZ(), -1D, 1D)); // Kiterino - dynamic minecart speed, clamp values
}
if (flag) {
vec3d4 = this.getDeltaMovement();
d18 = vec3d4.horizontalDistance();
+ final double basisAccelerationPerTick = 0.021D; // Kiterino - dynamic minecart speed
if (d18 > 0.01D) {
+ // Kiterino start - dynamic minecart speed
+ if (!getPassengers().isEmpty()) {
+ // Based on 10 ticks per second basis spent per powered block we calculate a fair acceleration per tick
+ // due to spending less ticks per powered block on higher speeds (and even skipping blocks)
+ final double basisTicksPerSecond = 10D;
+ // Tps = Ticks per second
+ final double tickMovementForBasisTps = 1D / basisTicksPerSecond;
+ final double maxSkippedBlocksToConsider = 3D;
+
+ double acceleration = basisAccelerationPerTick;
+ final double distanceMovedHorizontally = movement.horizontalDistance();
+
+ if (distanceMovedHorizontally > tickMovementForBasisTps) {
+ acceleration *= Math.min((1D + maxSkippedBlocksToConsider) * basisTicksPerSecond, distanceMovedHorizontally / tickMovementForBasisTps);
+
+ // Add progressively slower (or faster) acceleration for higher speeds;
+ double highspeedFactor = 1D + Mth.clamp(-0.45D * (distanceMovedHorizontally / tickMovementForBasisTps / basisTicksPerSecond), -0.7D, 2D);
+ acceleration *= highspeedFactor;
+ }
+ this.setDeltaMovement(vec3d4.add(acceleration * (vec3d4.x / d18), 0D, acceleration * (vec3d4.z / d18)));
+ } else {
+ this.setDeltaMovement(vec3d4.add(vec3d4.x / d18 * 0.06D, 0D, vec3d4.z / d18 * 0.06D));
+ }
+ // Kiterino end
double d20 = 0.06D;
- this.setDeltaMovement(vec3d4.add(vec3d4.x / d18 * 0.06D, 0.0D, vec3d4.z / d18 * 0.06D));
+ // this.setDeltaMovement(vec3d4.add(vec3d4.x / d18 * 0.06D, 0.0D, vec3d4.z / d18 * 0.06D)); // Kiterino - dynamic minecart speed
} else {
Vec3 vec3d5 = this.getDeltaMovement();
double d21 = vec3d5.x;
double d22 = vec3d5.z;
+ final double railStopperAcceleration = basisAccelerationPerTick * 16D; // Kiterino
if (blockpropertytrackposition == RailShape.EAST_WEST) {
if (this.isRedstoneConductor(pos.west())) {
- d21 = 0.02D;
+ d21 = railStopperAcceleration; // Kiterino - dynamic minecart speed, unhardcode 0.02D
} else if (this.isRedstoneConductor(pos.east())) {
- d21 = -0.02D;
+ d21 = -railStopperAcceleration; // Kiterino - dynamic minecart speed, unhardcode -0.02D
}
} else {
if (blockpropertytrackposition != RailShape.NORTH_SOUTH) {

View File

@@ -1,21 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: SoSeDiK <mrsosedik@gmail.com>
Date: Fri, 2 Dec 2022 23:05:04 +0200
Subject: [PATCH] Increase manual minecart speed
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
index 012d4ad1651d7a9118b24e0589d8bdf28ed0b708..522a04150da9473812f1ae3406664c2ea392d2ba 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
@@ -685,8 +685,8 @@ public abstract class AbstractMinecart extends Entity {
double d9 = vec3d2.horizontalDistanceSqr();
double d10 = this.getDeltaMovement().horizontalDistanceSqr();
- if (d9 > 1.0E-4D && d10 < 0.01D) {
- this.setDeltaMovement(this.getDeltaMovement().add(vec3d2.x * 0.1D, 0.0D, vec3d2.z * 0.1D));
+ if (d9 > 1.0E-4D && d10 < 0.04D) { // Kiterino - increase max manual speed
+ this.setDeltaMovement(this.getDeltaMovement().add(vec3d2.x * 0.12D, 0.0D, vec3d2.z * 0.12D)); // Kiterino - slightly increase speed buildup
flag1 = false;
}
}

View File

@@ -1,27 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: SoSeDiK <mrsosedik@gmail.com>
Date: Sun, 4 Dec 2022 21:57:07 +0200
Subject: [PATCH] Allow placing rails on more surfaces
diff --git a/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java b/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java
index a3f877bf03f75cbfbd128c856322bcd427b95d21..96860dc68c7e7c59c27465a74b833e189db9d85b 100644
--- a/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java
@@ -51,7 +51,7 @@ public abstract class BaseRailBlock extends Block implements SimpleWaterloggedBl
@Override
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
- return canSupportRigidBlock(world, pos.below());
+ return canSupportCenter(world, pos.below(), Direction.UP); // Kiterino
}
@Override
@@ -86,6 +86,7 @@ public abstract class BaseRailBlock extends Block implements SimpleWaterloggedBl
}
private static boolean shouldBeRemoved(BlockPos pos, Level world, RailShape shape) {
+ if (canSupportCenter(world, pos.below(), Direction.UP)) return false; // Kiterino
if (!canSupportRigidBlock(world, pos.below())) {
return true;
} else {

View File

@@ -1,160 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Justin <justin@justinf.dev>
Date: Wed, 24 Aug 2022 05:17:20 -0700
Subject: [PATCH] Paper PR - Add Entity hidden by default flag
Adds a boolean to the server Entity controlling if the entity should be hidden by default.
The TrackedEntity maintains a set of all players that will be able to see the entity even
when it is hidden by default. This set is modified when Player#showEntity and Player#hideEntity
are invoked. Changes are made to the way that TrackedEntity updates players when the entity is
hidden by default - if a player is not present in the above set, the update is abandoned.
This functionality is expanded when a Player is hidden by default. The player will send out
PlayerInfo packets to hide themselves from other Players when hiddenByDefault. There remains a
discrepancy when trying to getHiddenPlayers - players that are hidden by default are currently
not returned from this method, only those hidden with hideEntity or hidePlayer.
Hiding entities by default also respects precedent of keeping entities hidden when other plugins
explicitly hide them from a player. If an entity is hidden by default and by a plugin, the entity
must have the plugin that hid them from a player show them in order to be shown to a player again.
If no plugin had previously hidden the entity before the entity was hidden by default, then any
plugin that attempts to show the entity to a player will succeed in doing so.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 6ae3f09f01e7ad72d46aeb950cca83b0d2a8d88b..07985de694f76e55f8eef2ac7dca6e404980519d 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -1515,6 +1515,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
private final int range;
SectionPos lastSectionPos;
public final Set<ServerPlayerConnection> seenBy = new ReferenceOpenHashSet<>(); // Paper - optimise map impl
+ public final Set<ServerPlayerConnection> showToEvenWhenHiddenByDefault = new ReferenceOpenHashSet<>(); // Paper - Entity hiddenByDefault
public TrackedEntity(Entity entity, int i, int j, boolean flag) {
this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index e273fed8e97c98bf5735d3a8c301968990d4cf32..21d980628bcaf80ed8809122766b626713974ed4 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -400,6 +400,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
private UUID originWorld;
public boolean freezeLocked = false; // Paper - Freeze Tick Lock API
public boolean collidingWithWorldBorder; // Paper
+ public boolean hiddenByDefault; // Paper
public void setOrigin(@javax.annotation.Nonnull Location location) {
this.origin = location.toVector();
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 57a0dbb23a32123d30c3b3572f4d129be9d97847..6286431870438767e779f37aef1e6d9dd9fbec65 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1442,4 +1442,30 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
return !this.getHandle().level.noCollision(this.getHandle(), aabb);
}
// Paper End - Collision API
+
+ // Paper start - Entity hiddenByDefault
+ @Override
+ public void setHiddenByDefault(boolean hiddenByDefault) {
+ this.getHandle().hiddenByDefault = hiddenByDefault;
+
+ // We need to update the players again
+ ChunkMap.TrackedEntity entityTracker = this.getHandle().tracker;
+
+ // Tracker was not initialized yet
+ if (entityTracker == null) {
+ return;
+ }
+
+ // If the entity is already hiddenByDefault, we reset our "show to" set to again hide the entity from all players that may be seeing the entity
+ // We also clear the "show to" set when we stop hiding by default
+ entityTracker.showToEvenWhenHiddenByDefault.clear();
+
+ entityTracker.updatePlayers(this.server.getHandle().getPlayers());
+ }
+
+ @Override
+ public boolean isHiddenByDefault() {
+ return this.getHandle().hiddenByDefault;
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 1bada55af5d16437da4d16f9ded55f88a6121eb4..0fbc2971cdf15799c1f0beb1b3670894c41db9c8 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1814,6 +1814,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
ChunkMap tracker = ((ServerLevel) this.getHandle().level).getChunkSource().chunkMap;
ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId());
if (entry != null) {
+ entry.showToEvenWhenHiddenByDefault.remove(this.getHandle().connection); // Paper - Entity hiddenByDefault
entry.removePlayer(this.getHandle());
}
@@ -1892,9 +1893,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
}
ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId());
- if (entry != null && !entry.seenBy.contains(this.getHandle().connection)) {
- entry.updatePlayer(this.getHandle());
+ // Paper start - Entity hiddenByDefault
+ if (entry != null) {
+ entry.showToEvenWhenHiddenByDefault.add(this.getHandle().connection);
+
+ if (!entry.seenBy.contains(this.getHandle().connection)) {
+ entry.updatePlayer(this.getHandle());
+ }
}
+ // Paper end
server.getPluginManager().callEvent(new PlayerShowEntityEvent(this, entity)); // Paper
}
// Paper start
@@ -1970,7 +1977,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public boolean canSee(org.bukkit.entity.Entity entity) {
- return entity.isVisibleByDefault() ^ this.invertedVisibilityEntities.containsKey(entity.getUniqueId());
+ // Paper start - Entity hiddenByDefault
+ boolean shownWhenHiddenByDefault = true;
+
+ if (entity.isHiddenByDefault()) {
+ ChunkMap.TrackedEntity tracker = ((CraftEntity) entity).getHandle().tracker;
+ shownWhenHiddenByDefault = tracker == null || tracker.showToEvenWhenHiddenByDefault.contains(this.getHandle().connection);
+ }
+
+ return shownWhenHiddenByDefault && (entity.isVisibleByDefault() ^ this.invertedVisibilityEntities.containsKey(entity.getUniqueId()));
+ // Paper end
}
public boolean canSee(UUID uuid) {
@@ -3143,6 +3159,30 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
}
// Paper end
+ // Paper start - Entity hiddenByDefault
+ @Override
+ public void setHiddenByDefault(boolean hiddenByDefault) {
+ // Update server lists
+ if (hiddenByDefault) {
+ for (CraftPlayer player : this.server.getOnlinePlayers()) {
+ if (player == this || !player.canSee(this)) continue;
+
+ player.getHandle().connection.send(new ClientboundPlayerInfoRemovePacket(List.of(this.getHandle().getUUID())));
+ }
+ } else {
+ for (CraftPlayer player : this.server.getOnlinePlayers()) {
+ if (player == this || player.canSee(this)) continue;
+
+ player.getHandle().connection.send(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, this.getHandle()));
+ }
+ }
+
+ // Now, process trackers
+ super.setHiddenByDefault(hiddenByDefault);
+ }
+ // Paper end
+
+
public Player.Spigot spigot()
{
return this.spigot;