even even even more work
This commit is contained in:
parent
8ac3123f9f
commit
03a53a63b6
215 changed files with 1750 additions and 2211 deletions
|
@ -0,0 +1,82 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mystiflow <mystiflow@gmail.com>
|
||||
Date: Fri, 6 Jul 2018 13:21:30 +0100
|
||||
Subject: [PATCH] Send nearby packets from world player list not server list
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
|
||||
index 939cec9121c051c5459084e4078740a7607803f3..917ea676d9ce2ea0b10e3a75b7f35f011c3599f6 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerList.java
|
||||
@@ -910,8 +910,25 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public void sendPacketNearby(@Nullable EntityHuman entityhuman, double d0, double d1, double d2, double d3, DimensionManager dimensionmanager, Packet<?> packet) {
|
||||
- for (int i = 0; i < this.players.size(); ++i) {
|
||||
- EntityPlayer entityplayer = (EntityPlayer) this.players.get(i);
|
||||
+ // Paper start - Use world list instead of server list where preferable
|
||||
+ sendPacketNearby(entityhuman, d0, d1, d2, d3, dimensionmanager, null, packet); // Retained for compatibility
|
||||
+ }
|
||||
+
|
||||
+ public void sendPacketNearby(@Nullable EntityHuman entityhuman, double d0, double d1, double d2, double d3, WorldServer world, Packet<?> packet) {
|
||||
+ sendPacketNearby(entityhuman, d0, d1, d2, d3, world.worldProvider.getDimensionManager(), world, packet);
|
||||
+ }
|
||||
+
|
||||
+ public void sendPacketNearby(@Nullable EntityHuman entityhuman, double d0, double d1, double d2, double d3, DimensionManager dimensionmanager, @Nullable WorldServer world, Packet<?> packet) {
|
||||
+ if (world == null && entityhuman != null && entityhuman.world instanceof WorldServer) {
|
||||
+ world = (WorldServer) entityhuman.world;
|
||||
+ }
|
||||
+
|
||||
+ List<? extends EntityHuman> players1 = world == null ? players : world.players;
|
||||
+ for (int j = 0; j < players1.size(); ++j) {
|
||||
+ EntityHuman entity = players1.get(j);
|
||||
+ if (!(entity instanceof EntityPlayer)) continue;
|
||||
+ EntityPlayer entityplayer = (EntityPlayer) entity;
|
||||
+ // Paper end
|
||||
|
||||
// CraftBukkit start - Test if player receiving packet can see the source of the packet
|
||||
if (entityhuman != null && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) {
|
||||
@@ -919,7 +936,7 @@ public abstract class PlayerList {
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
- if (entityplayer != entityhuman && entityplayer.dimension == dimensionmanager) {
|
||||
+ if (entityplayer != entityhuman && (world != null || entityplayer.dimension == dimensionmanager)) { // Paper
|
||||
double d4 = d0 - entityplayer.locX();
|
||||
double d5 = d1 - entityplayer.locY();
|
||||
double d6 = d2 - entityplayer.locZ();
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index 3067ab76d94c58fbfd52fac6754bf6d6d7f01d09..6e878c9b9dee511812df5ea2491d953f677c3f58 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -1276,7 +1276,7 @@ public class WorldServer extends World {
|
||||
}
|
||||
// CraftBukkit end
|
||||
this.globalEntityList.add(entitylightning);
|
||||
- this.server.getPlayerList().sendPacketNearby((EntityHuman) null, entitylightning.locX(), entitylightning.locY(), entitylightning.locZ(), 512.0D, this.worldProvider.getDimensionManager(), new PacketPlayOutSpawnEntityWeather(entitylightning));
|
||||
+ this.server.getPlayerList().sendPacketNearby((EntityHuman) null, entitylightning.locX(), entitylightning.locY(), entitylightning.locZ(), 512.0D, this, new PacketPlayOutSpawnEntityWeather(entitylightning)); // Paper - use world instead of dimension
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1408,7 +1408,7 @@ public class WorldServer extends World {
|
||||
BlockActionData blockactiondata = (BlockActionData) this.I.removeFirst();
|
||||
|
||||
if (this.a(blockactiondata)) {
|
||||
- this.server.getPlayerList().sendPacketNearby((EntityHuman) null, (double) blockactiondata.a().getX(), (double) blockactiondata.a().getY(), (double) blockactiondata.a().getZ(), 64.0D, this.worldProvider.getDimensionManager(), new PacketPlayOutBlockAction(blockactiondata.a(), blockactiondata.b(), blockactiondata.c(), blockactiondata.d()));
|
||||
+ this.server.getPlayerList().sendPacketNearby((EntityHuman) null, (double) blockactiondata.a().getX(), (double) blockactiondata.a().getY(), (double) blockactiondata.a().getZ(), 64.0D, this, new PacketPlayOutBlockAction(blockactiondata.a(), blockactiondata.b(), blockactiondata.c(), blockactiondata.d()));
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 6c3cd51d92d2271cd216c42c18733d549fbe668d..ad951812835b1fa786e964c533efc4547c57b7a2 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -2122,7 +2122,7 @@ public class CraftWorld implements World {
|
||||
double z = loc.getZ();
|
||||
|
||||
PacketPlayOutCustomSoundEffect packet = new PacketPlayOutCustomSoundEffect(new MinecraftKey(sound), SoundCategory.valueOf(category.name()), new Vec3D(x, y, z), volume, pitch);
|
||||
- world.getMinecraftServer().getPlayerList().sendPacketNearby(null, x, y, z, volume > 1.0F ? 16.0F * volume : 16.0D, this.world.getWorldProvider().getDimensionManager(), packet);
|
||||
+ world.getMinecraftServer().getPlayerList().sendPacketNearby(null, x, y, z, volume > 1.0F ? 16.0F * volume : 16.0D, this.world, packet); // Paper - this.world.dimension -> this.world
|
||||
}
|
||||
|
||||
private static Map<String, GameRules.GameRuleKey<?>> gamerules;
|
99
removed/1.16/0298-Support-Overriding-World-Seeds.patch
Normal file
99
removed/1.16/0298-Support-Overriding-World-Seeds.patch
Normal file
|
@ -0,0 +1,99 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 17 Sep 2018 23:05:31 -0400
|
||||
Subject: [PATCH] Support Overriding World Seeds
|
||||
|
||||
Allows you to add to paper.yml
|
||||
|
||||
seed-overrides:
|
||||
world_name: some seed value
|
||||
|
||||
This will ignore every where a seed is set/created/loaded and force
|
||||
a world to use the specified seed.
|
||||
|
||||
This seed will end up being saved to the world data file, so it is
|
||||
a permanent change in that it won't go back if you remove it from paper.yml
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
index 214b577b326bc794fa3721deb6171228dd4f25e6..559e6b42ba5bf0ea92cccbabd2ef1d4c27b03064 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
@@ -11,6 +11,7 @@ import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
+import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -19,6 +20,7 @@ import com.google.common.collect.Lists;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
+import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import co.aikar.timings.Timings;
|
||||
@@ -310,4 +312,23 @@ public class PaperConfig {
|
||||
}
|
||||
tabSpamLimit = getInt("settings.spam-limiter.tab-spam-limit", tabSpamLimit);
|
||||
}
|
||||
+
|
||||
+ public static Map<String, Long> seedOverride = new java.util.HashMap<>();
|
||||
+ private static void worldSeedOverrides() {
|
||||
+ ConfigurationSection seeds = config.getConfigurationSection("seed-overrides");
|
||||
+ if (seeds != null) {
|
||||
+ TimingsManager.hiddenConfigs.add("seed-overrides");
|
||||
+ for (String key : seeds.getKeys(false)) {
|
||||
+ String seedString = seeds.getString(key);
|
||||
+ long seed;
|
||||
+ try {
|
||||
+ seed = Long.parseLong(seedString);
|
||||
+ } catch (Exception e) {
|
||||
+ seed = (long) seedString.hashCode();
|
||||
+ }
|
||||
+ log("Seed Override: " + key + " => " + seed);
|
||||
+ seedOverride.put(key, seed);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 3b89f62ab0522d23f47fd59c2f06fa7d0eacb7af..85f989829b5ad1d7681b57cf68519a4806b26ea1 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -378,7 +378,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
this.convertWorld(name); // Run conversion now
|
||||
|
||||
org.bukkit.generator.ChunkGenerator gen = this.server.getGenerator(name);
|
||||
- WorldSettings worldsettings = new WorldSettings(i, this.getGamemode(), this.getGenerateStructures(), this.isHardcore(), worldtype);
|
||||
+ WorldSettings worldsettings = new WorldSettings(com.destroystokyo.paper.PaperConfig.seedOverride.getOrDefault(name, i), this.getGamemode(), this.getGenerateStructures(), this.isHardcore(), worldtype); // Paper
|
||||
worldsettings.setGeneratorSettings(jsonelement);
|
||||
|
||||
if (j == 0) {
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldData.java b/src/main/java/net/minecraft/server/WorldData.java
|
||||
index 561b6d94696eebc255279f45d2ca6b88b2490f78..95518e54d1fd7ada51df1cdc3562affccd48bfcb 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldData.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldData.java
|
||||
@@ -127,7 +127,7 @@ public class WorldData {
|
||||
this.d = nbttagcompound2.getBoolean("Snapshot");
|
||||
}
|
||||
|
||||
- this.e = nbttagcompound.getLong("RandomSeed");
|
||||
+ this.e = com.destroystokyo.paper.PaperConfig.seedOverride.getOrDefault(nbttagcompound.getString("LevelName"), nbttagcompound.getLong("RandomSeed")); // Paper
|
||||
if (nbttagcompound.hasKeyOfType("generatorName", 8)) {
|
||||
String s = nbttagcompound.getString("generatorName");
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index d15a857b30511bda9bbeddf651b4633e4bea473d..011d0927da7a2a67dcd6d75e3af07d38f30acf81 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -1016,7 +1016,7 @@ public final class CraftServer implements Server {
|
||||
WorldSettings worldSettings;
|
||||
// See MinecraftServer.a(String, String, long, WorldType, JsonElement)
|
||||
if (worlddata == null) {
|
||||
- worldSettings = new WorldSettings(creator.seed(), EnumGamemode.getById(getDefaultGameMode().getValue()), generateStructures, hardcore, type);
|
||||
+ worldSettings = new WorldSettings(com.destroystokyo.paper.PaperConfig.seedOverride.getOrDefault(name, creator.seed()), EnumGamemode.getById(getDefaultGameMode().getValue()), generateStructures, hardcore, type); // Paper
|
||||
JsonElement parsedSettings = new JsonParser().parse(creator.generatorSettings());
|
||||
if (parsedSettings.isJsonObject()) {
|
||||
worldSettings.setGeneratorSettings(parsedSettings.getAsJsonObject());
|
22
removed/1.16/0302-Avoid-dimension-id-collisions.patch
Normal file
22
removed/1.16/0302-Avoid-dimension-id-collisions.patch
Normal file
|
@ -0,0 +1,22 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Tue, 25 Sep 2018 06:53:43 +0200
|
||||
Subject: [PATCH] Avoid dimension id collisions
|
||||
|
||||
getDimensionId() returns the dimension id - 1. So without this patch
|
||||
we would reuse an existing dimension id, if some other dimension was
|
||||
unloaded before.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 011d0927da7a2a67dcd6d75e3af07d38f30acf81..3c43f318c4cff914128e2f7060516ce7ebb6e1c9 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -1002,7 +1002,7 @@ public final class CraftServer implements Server {
|
||||
boolean used = false;
|
||||
do {
|
||||
for (WorldServer server : console.getWorlds()) {
|
||||
- used = server.getWorldProvider().getDimensionManager().getDimensionID() == dimension;
|
||||
+ used = server.getWorldProvider().getDimensionManager().getDimensionID() + 1 == dimension; // Paper - getDimensionID returns the dimension - 1, so we have to add 1
|
||||
if (used) {
|
||||
dimension++;
|
||||
break;
|
|
@ -0,0 +1,83 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Trigary <trigary0@gmail.com>
|
||||
Date: Fri, 14 Sep 2018 17:42:08 +0200
|
||||
Subject: [PATCH] Limit lightning strike effect distance
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 487b0d5cd608e84a793eba5fdbd50a9f3d95c79b..b8789c8ecc5a6e4117bb7ce0d5487a6e5774b67f 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -242,6 +242,28 @@ public class PaperWorldConfig {
|
||||
}
|
||||
}
|
||||
|
||||
+ public double sqrMaxThunderDistance;
|
||||
+ public double sqrMaxLightningImpactSoundDistance;
|
||||
+ public double maxLightningFlashDistance;
|
||||
+ private void lightningStrikeDistanceLimit() {
|
||||
+ sqrMaxThunderDistance = getInt("lightning-strike-distance-limit.sound", -1);
|
||||
+ if (sqrMaxThunderDistance > 0) {
|
||||
+ sqrMaxThunderDistance *= sqrMaxThunderDistance;
|
||||
+ }
|
||||
+
|
||||
+ sqrMaxLightningImpactSoundDistance = getInt("lightning-strike-distance-limit.impact-sound", -1);
|
||||
+ if (sqrMaxLightningImpactSoundDistance < 0) {
|
||||
+ sqrMaxLightningImpactSoundDistance = 32 * 32; //Vanilla value
|
||||
+ } else {
|
||||
+ sqrMaxLightningImpactSoundDistance *= sqrMaxLightningImpactSoundDistance;
|
||||
+ }
|
||||
+
|
||||
+ maxLightningFlashDistance = getInt("lightning-strike-distance-limit.flash", -1);
|
||||
+ if (maxLightningFlashDistance < 0) {
|
||||
+ maxLightningFlashDistance = 512; // Vanilla value
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
public int fixedInhabitedTime;
|
||||
private void fixedInhabitedTime() {
|
||||
if (PaperConfig.version < 16) {
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityLightning.java b/src/main/java/net/minecraft/server/EntityLightning.java
|
||||
index 7c518983a9c21a9b221e1fa1b0baa3d5c9ccadbf..bdb534deb47a945d5cbfad688eeab5e3388a4df5 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityLightning.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityLightning.java
|
||||
@@ -64,6 +64,17 @@ public class EntityLightning extends Entity {
|
||||
double deltaX = this.locX() - player.locX();
|
||||
double deltaZ = this.locZ() - player.locZ();
|
||||
double distanceSquared = deltaX * deltaX + deltaZ * deltaZ;
|
||||
+ // Paper start - Limit lightning strike effect distance
|
||||
+ if (distanceSquared <= this.world.paperConfig.sqrMaxLightningImpactSoundDistance) {
|
||||
+ player.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(SoundEffects.ENTITY_LIGHTNING_BOLT_IMPACT,
|
||||
+ SoundCategory.WEATHER, this.locX(), this.locY(), this.locZ(), 2.0f, 0.5F + this.random.nextFloat() * 0.2F));
|
||||
+ }
|
||||
+
|
||||
+ if (world.paperConfig.sqrMaxThunderDistance != -1 && distanceSquared >= world.paperConfig.sqrMaxThunderDistance) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ // Paper end
|
||||
if (distanceSquared > viewDistance * viewDistance) {
|
||||
double deltaLength = Math.sqrt(distanceSquared);
|
||||
double relativeX = player.locX() + (deltaX / deltaLength) * viewDistance;
|
||||
@@ -74,7 +85,7 @@ public class EntityLightning extends Entity {
|
||||
}
|
||||
}
|
||||
// CraftBukkit end
|
||||
- this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_LIGHTNING_BOLT_IMPACT, SoundCategory.WEATHER, 2.0F, 0.5F + this.random.nextFloat() * 0.2F);
|
||||
+ //this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_LIGHTNING_BOLT_IMPACT, SoundCategory.WEATHER, 2.0F, 0.5F + this.random.nextFloat() * 0.2F); // Paper - Limit lightning strike effect distance (the packet is now sent from inside the loop)
|
||||
}
|
||||
|
||||
--this.lifeTicks;
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index 6e878c9b9dee511812df5ea2491d953f677c3f58..271a1ef3d0aae7c1d0b373963504e70f2843cd24 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -1276,7 +1276,7 @@ public class WorldServer extends World {
|
||||
}
|
||||
// CraftBukkit end
|
||||
this.globalEntityList.add(entitylightning);
|
||||
- this.server.getPlayerList().sendPacketNearby((EntityHuman) null, entitylightning.locX(), entitylightning.locY(), entitylightning.locZ(), 512.0D, this, new PacketPlayOutSpawnEntityWeather(entitylightning)); // Paper - use world instead of dimension
|
||||
+ this.server.getPlayerList().sendPacketNearby((EntityHuman) null, entitylightning.locX(), entitylightning.locY(), entitylightning.locZ(), paperConfig.maxLightningFlashDistance, this, new PacketPlayOutSpawnEntityWeather(entitylightning)); // Paper - use world instead of dimension, limit lightning strike effect distance
|
||||
}
|
||||
|
||||
@Override
|
1148
removed/1.16/0326-Optimize-redstone-algorithm.patch
Normal file
1148
removed/1.16/0326-Optimize-redstone-algorithm.patch
Normal file
File diff suppressed because it is too large
Load diff
217
removed/1.16/0356-Fire-event-on-GS4-query.patch
Normal file
217
removed/1.16/0356-Fire-event-on-GS4-query.patch
Normal file
|
@ -0,0 +1,217 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
|
||||
Date: Sun, 17 Mar 2019 21:46:56 +0200
|
||||
Subject: [PATCH] Fire event on GS4 query
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/RemoteConnectionThread.java b/src/main/java/net/minecraft/server/RemoteConnectionThread.java
|
||||
index 66bfbcf02b5584a3abb29f5d7a32e3bb2c6abbea..d821ef9a757494d02eb3be36a619c67562faf967 100644
|
||||
--- a/src/main/java/net/minecraft/server/RemoteConnectionThread.java
|
||||
+++ b/src/main/java/net/minecraft/server/RemoteConnectionThread.java
|
||||
@@ -15,7 +15,7 @@ public abstract class RemoteConnectionThread implements Runnable {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private static final AtomicInteger i = new AtomicInteger(0);
|
||||
protected boolean a;
|
||||
- protected final IMinecraftServer b;
|
||||
+ protected final IMinecraftServer b; protected IMinecraftServer getServer() { return this.b; } // Paper - OBFHELPER
|
||||
protected final String c;
|
||||
protected Thread d;
|
||||
protected final int e = 5;
|
||||
@@ -94,6 +94,7 @@ public abstract class RemoteConnectionThread implements Runnable {
|
||||
this.b.g(s);
|
||||
}
|
||||
|
||||
+ protected int getPlayerCount() { return this.d(); } // Paper - OBFHELPER
|
||||
protected int d() {
|
||||
return this.b.getPlayerCount();
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/RemoteStatusListener.java b/src/main/java/net/minecraft/server/RemoteStatusListener.java
|
||||
index f4f4e31d3c2ee8c7ecbe441f38b518217baa4ba5..d5025938473d3585e83994e890f742cf26c8061e 100644
|
||||
--- a/src/main/java/net/minecraft/server/RemoteStatusListener.java
|
||||
+++ b/src/main/java/net/minecraft/server/RemoteStatusListener.java
|
||||
@@ -21,19 +21,19 @@ public class RemoteStatusListener extends RemoteConnectionThread {
|
||||
|
||||
private long h;
|
||||
private final int i;
|
||||
- private final int j;
|
||||
- private final int k;
|
||||
- private final String l;
|
||||
- private final String m;
|
||||
+ private final int j; private int getServerPort() { return this.j; } // Paper - OBFHELPER
|
||||
+ private final int k; private int getMaxPlayers() { return this.k; } // Paper - OBFHELPER
|
||||
+ private final String l; private String getMotd() { return this.l; } // Paper - OBFHELPER
|
||||
+ private final String m; private String getWorldName() { return this.m; } // Paper - OBFHELPER
|
||||
private DatagramSocket n;
|
||||
private final byte[] o = new byte[1460];
|
||||
private DatagramPacket p;
|
||||
private final Map<SocketAddress, String> q;
|
||||
- private String r;
|
||||
+ private String r; private String getServerHost() { return this.r; } // Paper - OBFHELPER
|
||||
private String s;
|
||||
private final Map<SocketAddress, RemoteStatusListener.RemoteStatusChallenge> t;
|
||||
private final long u;
|
||||
- private final RemoteStatusReply v;
|
||||
+ private final RemoteStatusReply v; private RemoteStatusReply getCachedFullResponse() { return this.v; } // Paper - OBFHELPER
|
||||
private long w;
|
||||
|
||||
public RemoteStatusListener(IMinecraftServer iminecraftserver) {
|
||||
@@ -91,6 +91,7 @@ public class RemoteStatusListener extends RemoteConnectionThread {
|
||||
|
||||
remotestatusreply.a((int) 0);
|
||||
remotestatusreply.a(this.a(datagrampacket.getSocketAddress()));
|
||||
+ /* Paper start - GS4 Query event
|
||||
remotestatusreply.a(this.l);
|
||||
remotestatusreply.a("SMP");
|
||||
remotestatusreply.a(this.m);
|
||||
@@ -98,6 +99,31 @@ public class RemoteStatusListener extends RemoteConnectionThread {
|
||||
remotestatusreply.a(Integer.toString(this.k));
|
||||
remotestatusreply.a((short) this.j);
|
||||
remotestatusreply.a(this.r);
|
||||
+ */
|
||||
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType queryType =
|
||||
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType.BASIC;
|
||||
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse queryResponse = com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.builder()
|
||||
+ .motd(this.getMotd())
|
||||
+ .map(this.getWorldName())
|
||||
+ .currentPlayers(this.getPlayerCount())
|
||||
+ .maxPlayers(this.getMaxPlayers())
|
||||
+ .port(this.getServerPort())
|
||||
+ .hostname(this.getServerHost())
|
||||
+ .gameVersion(this.getServer().getVersion())
|
||||
+ .serverVersion(org.bukkit.Bukkit.getServer().getName() + " on " + org.bukkit.Bukkit.getServer().getBukkitVersion())
|
||||
+ .build();
|
||||
+ com.destroystokyo.paper.event.server.GS4QueryEvent queryEvent =
|
||||
+ new com.destroystokyo.paper.event.server.GS4QueryEvent(queryType, datagrampacket.getAddress(), queryResponse);
|
||||
+ queryEvent.callEvent();
|
||||
+ queryResponse = queryEvent.getResponse();
|
||||
+ remotestatusreply.writeString(queryResponse.getMotd());
|
||||
+ remotestatusreply.writeString("SMP");
|
||||
+ remotestatusreply.writeString(queryResponse.getMap());
|
||||
+ remotestatusreply.writeString(Integer.toString(queryResponse.getCurrentPlayers()));
|
||||
+ remotestatusreply.writeString(Integer.toString(queryResponse.getMaxPlayers()));
|
||||
+ remotestatusreply.writeShort((short) queryResponse.getPort());
|
||||
+ remotestatusreply.writeString(queryResponse.getHostname());
|
||||
+ // Paper end
|
||||
this.a(remotestatusreply.a(), datagrampacket);
|
||||
this.a("Status [" + socketaddress + "]");
|
||||
}
|
||||
@@ -134,6 +160,7 @@ public class RemoteStatusListener extends RemoteConnectionThread {
|
||||
this.v.a("splitnum");
|
||||
this.v.a((int) 128);
|
||||
this.v.a((int) 0);
|
||||
+ /* Paper start - GS4 Query event
|
||||
this.v.a("hostname");
|
||||
this.v.a(this.l);
|
||||
this.v.a("gametype");
|
||||
@@ -169,6 +196,79 @@ public class RemoteStatusListener extends RemoteConnectionThread {
|
||||
}
|
||||
|
||||
this.v.a((int) 0);
|
||||
+ */
|
||||
+ // Pack plugins
|
||||
+ java.util.List<com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.PluginInformation> plugins = java.util.Collections.emptyList();
|
||||
+ org.bukkit.plugin.Plugin[] bukkitPlugins;
|
||||
+ if(((DedicatedServer) this.getServer()).server.getQueryPlugins() && (bukkitPlugins = org.bukkit.Bukkit.getPluginManager().getPlugins()).length > 0) {
|
||||
+ plugins = java.util.stream.Stream.of(bukkitPlugins)
|
||||
+ .map(plugin -> com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.PluginInformation.of(plugin.getName(), plugin.getDescription().getVersion()))
|
||||
+ .collect(java.util.stream.Collectors.toList());
|
||||
+ }
|
||||
+
|
||||
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse queryResponse = com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.builder()
|
||||
+ .motd(this.getMotd())
|
||||
+ .map(this.getWorldName())
|
||||
+ .currentPlayers(this.getPlayerCount())
|
||||
+ .maxPlayers(this.getMaxPlayers())
|
||||
+ .port(this.getServerPort())
|
||||
+ .hostname(this.getServerHost())
|
||||
+ .plugins(plugins)
|
||||
+ .players(this.getServer().getPlayers())
|
||||
+ .gameVersion(this.getServer().getVersion())
|
||||
+ .serverVersion(org.bukkit.Bukkit.getServer().getName() + " on " + org.bukkit.Bukkit.getServer().getBukkitVersion())
|
||||
+ .build();
|
||||
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType queryType =
|
||||
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType.FULL;
|
||||
+ com.destroystokyo.paper.event.server.GS4QueryEvent queryEvent =
|
||||
+ new com.destroystokyo.paper.event.server.GS4QueryEvent(queryType, datagrampacket.getAddress(), queryResponse);
|
||||
+ queryEvent.callEvent();
|
||||
+ queryResponse = queryEvent.getResponse();
|
||||
+ this.getCachedFullResponse().writeString("hostname");
|
||||
+ this.getCachedFullResponse().writeString(queryResponse.getMotd());
|
||||
+ this.getCachedFullResponse().writeString("gametype");
|
||||
+ this.getCachedFullResponse().writeString("SMP");
|
||||
+ this.getCachedFullResponse().writeString("game_id");
|
||||
+ this.getCachedFullResponse().writeString("MINECRAFT");
|
||||
+ this.getCachedFullResponse().writeString("version");
|
||||
+ this.getCachedFullResponse().writeString(queryResponse.getGameVersion());
|
||||
+ this.getCachedFullResponse().writeString("plugins");
|
||||
+ java.lang.StringBuilder pluginsString = new java.lang.StringBuilder();
|
||||
+ pluginsString.append(queryResponse.getServerVersion());
|
||||
+ if(!queryResponse.getPlugins().isEmpty()) {
|
||||
+ pluginsString.append(": ");
|
||||
+ Iterator<com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.PluginInformation> iter = queryResponse.getPlugins().iterator();
|
||||
+ while(iter.hasNext()) {
|
||||
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.PluginInformation info = iter.next();
|
||||
+ pluginsString.append(info.getName());
|
||||
+ if (info.getVersion() != null) {
|
||||
+ pluginsString.append(' ').append(info.getVersion().replaceAll(";", ","));
|
||||
+ }
|
||||
+ if (iter.hasNext()) {
|
||||
+ pluginsString.append(';').append(' ');
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ this.getCachedFullResponse().writeString(pluginsString.toString());
|
||||
+ this.getCachedFullResponse().writeString("map");
|
||||
+ this.getCachedFullResponse().writeString(queryResponse.getMap());
|
||||
+ this.getCachedFullResponse().writeString("numplayers");
|
||||
+ this.getCachedFullResponse().writeString(Integer.toString(queryResponse.getCurrentPlayers()));
|
||||
+ this.getCachedFullResponse().writeString("maxplayers");
|
||||
+ this.getCachedFullResponse().writeString(Integer.toString(queryResponse.getMaxPlayers()));
|
||||
+ this.getCachedFullResponse().writeString("hostport");
|
||||
+ this.getCachedFullResponse().writeString(Integer.toString(queryResponse.getPort()));
|
||||
+ this.getCachedFullResponse().writeString("hostip");
|
||||
+ this.getCachedFullResponse().writeString(queryResponse.getHostname());
|
||||
+ // The "meaningless data" start, copied from above
|
||||
+ this.getCachedFullResponse().writeInt(0);
|
||||
+ this.getCachedFullResponse().writeInt(1);
|
||||
+ this.getCachedFullResponse().writeString("player_");
|
||||
+ this.getCachedFullResponse().writeInt(0);
|
||||
+ // "Meaningless data" end
|
||||
+ queryResponse.getPlayers().forEach(this.getCachedFullResponse()::writeStringUnchecked);
|
||||
+ this.getCachedFullResponse().writeInt(0);
|
||||
+ // Paper end
|
||||
return this.v.a();
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/RemoteStatusReply.java b/src/main/java/net/minecraft/server/RemoteStatusReply.java
|
||||
index 848b5c3f0e00f32d565dc5a241e17fa6d152ae8d..73efea7e1354df306c0eadfc52b75ec8ed9883d9 100644
|
||||
--- a/src/main/java/net/minecraft/server/RemoteStatusReply.java
|
||||
+++ b/src/main/java/net/minecraft/server/RemoteStatusReply.java
|
||||
@@ -18,15 +18,27 @@ public class RemoteStatusReply {
|
||||
this.b.write(abyte, 0, abyte.length);
|
||||
}
|
||||
|
||||
+ public void writeString(String string) throws IOException { this.a(string); } // Paper - OBFHELPER
|
||||
public void a(String s) throws IOException {
|
||||
this.b.writeBytes(s);
|
||||
this.b.write(0);
|
||||
}
|
||||
+ // Paper start - unchecked exception variant to use in Stream API
|
||||
+ public void writeStringUnchecked(String string) {
|
||||
+ try {
|
||||
+ writeString(string);
|
||||
+ } catch (IOException e) {
|
||||
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(e);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
+ public void writeInt(int i) throws IOException { this.a(i); } // Paper - OBFHELPER
|
||||
public void a(int i) throws IOException {
|
||||
this.b.write(i);
|
||||
}
|
||||
|
||||
+ public void writeShort(short i) throws IOException { this.a(i); } // Paper - OBFHELPER
|
||||
public void a(short short0) throws IOException {
|
||||
this.b.writeShort(Short.reverseBytes(short0));
|
||||
}
|
223
removed/1.16/0373-Fix-some-generation-concurrency-issues.patch
Normal file
223
removed/1.16/0373-Fix-some-generation-concurrency-issues.patch
Normal file
|
@ -0,0 +1,223 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Fri, 24 May 2019 07:53:16 +0100
|
||||
Subject: [PATCH] Fix some generation concurrency issues
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index a59a965104a2c2977fa3b3d0a199913df268bbd3..69db339c29c8f06026f05b0b5bb8019099af3fdf 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -86,6 +86,23 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
||||
private int tileTickPosition;
|
||||
public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
|
||||
public java.util.ArrayDeque<BlockRedstoneTorch.RedstoneUpdateInfo> redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here
|
||||
+ // Paper start - yes this is hacky as shit
|
||||
+ RegionLimitedWorldAccess regionLimited;
|
||||
+ World originalWorld;
|
||||
+ public World regionLimited(RegionLimitedWorldAccess limitedWorldAccess) {
|
||||
+ try {
|
||||
+ World clone = (World) super.clone();
|
||||
+ clone.regionLimited = limitedWorldAccess;
|
||||
+ clone.originalWorld = this;
|
||||
+ return clone;
|
||||
+ } catch (CloneNotSupportedException e1) {
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+ ChunkCoordIntPair[] strongholdCoords;
|
||||
+ List<StructureStart> strongholdStuctures = Lists.newArrayList();
|
||||
+ final java.lang.Object stuctureLock = new Object();
|
||||
+ // Paper end
|
||||
|
||||
public CraftWorld getWorld() {
|
||||
return this.world;
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureStateProviderWeighted.java b/src/main/java/net/minecraft/server/WorldGenFeatureStateProviderWeighted.java
|
||||
index 22e14fe1e98c8439f8db74c9464137a497fdaf7c..e2af6d43b2eafeecad8fd070fc70195c7b0bb93f 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldGenFeatureStateProviderWeighted.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldGenFeatureStateProviderWeighted.java
|
||||
@@ -23,18 +23,18 @@ public class WorldGenFeatureStateProviderWeighted extends WorldGenFeatureStatePr
|
||||
this(new WeightedList<>(dynamic.get("entries").orElseEmptyList(), IBlockData::a));
|
||||
}
|
||||
|
||||
- public WorldGenFeatureStateProviderWeighted a(IBlockData iblockdata, int i) {
|
||||
+ public synchronized WorldGenFeatureStateProviderWeighted a(IBlockData iblockdata, int i) { // Paper
|
||||
this.b.a(iblockdata, i);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
- public IBlockData a(Random random, BlockPosition blockposition) {
|
||||
+ public synchronized IBlockData a(Random random, BlockPosition blockposition) { // Paper
|
||||
return (IBlockData) this.b.b(random);
|
||||
}
|
||||
|
||||
@Override
|
||||
- public <T> T a(DynamicOps<T> dynamicops) {
|
||||
+ public synchronized <T> T a(DynamicOps<T> dynamicops) { // Paper
|
||||
Builder<T, T> builder = ImmutableMap.builder();
|
||||
|
||||
builder.put(dynamicops.createString("type"), dynamicops.createString(IRegistry.t.getKey(this.a).toString())).put(dynamicops.createString("entries"), this.b.a(dynamicops, (iblockdata) -> {
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldGenStronghold.java b/src/main/java/net/minecraft/server/WorldGenStronghold.java
|
||||
index fc4348b60242e4a9d8612c3b8ce01711c32f4b1c..44be7169ffd5961df28d21a319d2cc7569662baf 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldGenStronghold.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldGenStronghold.java
|
||||
@@ -10,10 +10,12 @@ import javax.annotation.Nullable;
|
||||
|
||||
public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyConfiguration> {
|
||||
|
||||
+ /* // Paper start - no shared state
|
||||
private boolean a;
|
||||
private ChunkCoordIntPair[] aq;
|
||||
private final List<StructureStart> ar = Lists.newArrayList();
|
||||
private long as;
|
||||
+ */
|
||||
|
||||
public WorldGenStronghold(Function<Dynamic<?>, ? extends WorldGenFeatureEmptyConfiguration> function) {
|
||||
super(function);
|
||||
@@ -21,16 +23,22 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
|
||||
|
||||
@Override
|
||||
public boolean a(BiomeManager biomemanager, ChunkGenerator<?> chunkgenerator, Random random, int i, int j, BiomeBase biomebase) {
|
||||
+ // Paper start
|
||||
+ /*
|
||||
if (this.as != chunkgenerator.getSeed()) {
|
||||
this.d();
|
||||
}
|
||||
+ */
|
||||
+ final World world = chunkgenerator.getWorld();
|
||||
|
||||
- if (!this.a) {
|
||||
+ synchronized (world.stuctureLock) {
|
||||
+ if ( world.strongholdCoords == null) {
|
||||
this.a(chunkgenerator);
|
||||
- this.a = true;
|
||||
- }
|
||||
+ // this.a = true;
|
||||
+ }}
|
||||
+ // Paper end
|
||||
|
||||
- ChunkCoordIntPair[] achunkcoordintpair = this.aq;
|
||||
+ ChunkCoordIntPair[] achunkcoordintpair = world.strongholdCoords; // Paper
|
||||
int k = achunkcoordintpair.length;
|
||||
|
||||
for (int l = 0; l < k; ++l) {
|
||||
@@ -45,9 +53,11 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
|
||||
}
|
||||
|
||||
private void d() {
|
||||
+ /* // Paper
|
||||
this.a = false;
|
||||
this.aq = null;
|
||||
this.ar.clear();
|
||||
+ */ // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,25 +75,32 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
|
||||
return 8;
|
||||
}
|
||||
|
||||
+
|
||||
@Nullable
|
||||
@Override
|
||||
public synchronized BlockPosition getNearestGeneratedFeature(World world, ChunkGenerator<? extends GeneratorSettingsDefault> chunkgenerator, BlockPosition blockposition, int i, boolean flag) {
|
||||
if (!chunkgenerator.getWorldChunkManager().a(this)) {
|
||||
return null;
|
||||
} else {
|
||||
+ // Paper start - no shared state
|
||||
+ /*
|
||||
if (this.as != world.getSeed()) {
|
||||
this.d();
|
||||
}
|
||||
+ */
|
||||
|
||||
- if (!this.a) {
|
||||
- this.a(chunkgenerator);
|
||||
- this.a = true;
|
||||
+ synchronized (world.stuctureLock) {
|
||||
+ if ( world.strongholdCoords == null) {
|
||||
+ this.a(chunkgenerator);
|
||||
+ //this.a = true;
|
||||
+ }
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
BlockPosition blockposition1 = null;
|
||||
BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
|
||||
double d0 = Double.MAX_VALUE;
|
||||
- ChunkCoordIntPair[] achunkcoordintpair = this.aq;
|
||||
+ ChunkCoordIntPair[] achunkcoordintpair = world.strongholdCoords; // Paper
|
||||
int j = achunkcoordintpair.length;
|
||||
|
||||
for (int k = 0; k < j; ++k) {
|
||||
@@ -106,7 +123,7 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
|
||||
}
|
||||
|
||||
private void a(ChunkGenerator<?> chunkgenerator) {
|
||||
- this.as = chunkgenerator.getSeed();
|
||||
+ //this.as = chunkgenerator.getSeed(); // Paper
|
||||
List<BiomeBase> list = Lists.newArrayList();
|
||||
Iterator iterator = IRegistry.BIOME.iterator();
|
||||
|
||||
@@ -122,15 +139,15 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
|
||||
int j = chunkgenerator.getSettings().f();
|
||||
int k = chunkgenerator.getSettings().g();
|
||||
|
||||
- this.aq = new ChunkCoordIntPair[j];
|
||||
+ ChunkCoordIntPair[] strongholdCoords = chunkgenerator.getWorld().strongholdCoords = new ChunkCoordIntPair[j]; // Paper
|
||||
int l = 0;
|
||||
- Iterator iterator1 = this.ar.iterator();
|
||||
+ Iterator iterator1 = chunkgenerator.getWorld().strongholdStuctures.iterator(); // Paper
|
||||
|
||||
while (iterator1.hasNext()) {
|
||||
StructureStart structurestart = (StructureStart) iterator1.next();
|
||||
|
||||
- if (l < this.aq.length) {
|
||||
- this.aq[l++] = new ChunkCoordIntPair(structurestart.f(), structurestart.g());
|
||||
+ if (l < strongholdCoords.length) { // Paper
|
||||
+ strongholdCoords[l++] = new ChunkCoordIntPair(structurestart.f(), structurestart.g()); // Paper
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,11 +157,11 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
|
||||
double d0 = random.nextDouble() * 3.141592653589793D * 2.0D;
|
||||
int i1 = l;
|
||||
|
||||
- if (l < this.aq.length) {
|
||||
+ if (l < strongholdCoords.length) { // Paper
|
||||
int j1 = 0;
|
||||
int k1 = 0;
|
||||
|
||||
- for (int l1 = 0; l1 < this.aq.length; ++l1) {
|
||||
+ for (int l1 = 0; l1 < strongholdCoords.length; ++l1) { // Paper
|
||||
double d1 = (double) (4 * i + i * k1 * 6) + (random.nextDouble() - 0.5D) * (double) i * 2.5D;
|
||||
int i2 = (int) Math.round(Math.cos(d0) * d1);
|
||||
int j2 = (int) Math.round(Math.sin(d0) * d1);
|
||||
@@ -156,7 +173,7 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
|
||||
}
|
||||
|
||||
if (l1 >= i1) {
|
||||
- this.aq[l1] = new ChunkCoordIntPair(i2, j2);
|
||||
+ strongholdCoords[l1] = new ChunkCoordIntPair(i2, j2); // Paper
|
||||
}
|
||||
|
||||
d0 += 6.283185307179586D / (double) k;
|
||||
@@ -165,7 +182,7 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
|
||||
++k1;
|
||||
j1 = 0;
|
||||
k += 2 * k / (k1 + 1);
|
||||
- k = Math.min(k, this.aq.length - l1);
|
||||
+ k = Math.min(k, strongholdCoords.length - l1); // Paper
|
||||
d0 += random.nextDouble() * 3.141592653589793D * 2.0D;
|
||||
}
|
||||
}
|
||||
@@ -207,7 +224,7 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
|
||||
this.a(chunkgenerator.getSeaLevel(), this.d, 10);
|
||||
} while (this.b.isEmpty() || worldgenstrongholdpieces_worldgenstrongholdstart.b == null);
|
||||
|
||||
- ((WorldGenStronghold) this.l()).ar.add(this);
|
||||
+ chunkgenerator.getWorld().strongholdStuctures.add(this); // Paper - this worries me, this is never cleared, even in vanilla (world seed never changes "world", and that appears to be the only relevant world)
|
||||
}
|
||||
}
|
||||
}
|
320
removed/1.16/0378-incremental-chunk-saving.patch
Normal file
320
removed/1.16/0378-incremental-chunk-saving.patch
Normal file
|
@ -0,0 +1,320 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 9 Jun 2019 03:53:22 +0100
|
||||
Subject: [PATCH] incremental chunk saving
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 071e5e7f729d6c3ffb70506e7ef32eebee1e9118..48676152152faf7a7b9524ac37d8b4a8c32c4e2c 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -487,4 +487,19 @@ public class PaperWorldConfig {
|
||||
keepLoadedRange = (short) (getInt("keep-spawn-loaded-range", Math.min(spigotConfig.viewDistance, 10)) * 16);
|
||||
log( "Keep Spawn Loaded Range: " + (keepLoadedRange/16));
|
||||
}
|
||||
+
|
||||
+ public int autoSavePeriod = -1;
|
||||
+ private void autoSavePeriod() {
|
||||
+ autoSavePeriod = getInt("auto-save-interval", -1);
|
||||
+ if (autoSavePeriod > 0) {
|
||||
+ log("Auto Save Interval: " +autoSavePeriod + " (" + (autoSavePeriod / 20) + "s)");
|
||||
+ } else if (autoSavePeriod < 0) {
|
||||
+ autoSavePeriod = net.minecraft.server.MinecraftServer.getServer().autosavePeriod;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public int maxAutoSaveChunksPerTick = 24;
|
||||
+ private void maxAutoSaveChunksPerTick() {
|
||||
+ maxAutoSaveChunksPerTick = getInt("max-auto-save-chunks-per-tick", 24);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
||||
index 962f425bbb7165740e77664dc543f976ef3d9c4a..dd3857bb6a002d8432ecbc6c6b52a39e5d55e6a6 100644
|
||||
--- a/src/main/java/net/minecraft/server/Chunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
||||
@@ -42,7 +42,7 @@ public class Chunk implements IChunkAccess {
|
||||
private TickList<Block> o;
|
||||
private TickList<FluidType> p;
|
||||
private boolean q;
|
||||
- private long lastSaved;
|
||||
+ public long lastSaved; // Paper
|
||||
private volatile boolean s;
|
||||
private long inhabitedTime;
|
||||
@Nullable
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
index 8a8fb6acaabc5fc179a23ce3e23ddb54e1ee23a4..7b855ec2914a8a31ce0ade0f7ad085dd04f71478 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
@@ -525,6 +525,15 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
} // Paper - Timings
|
||||
}
|
||||
|
||||
+ // Paper start - duplicate save, but call incremental
|
||||
+ public void saveIncrementally() {
|
||||
+ this.tickDistanceManager();
|
||||
+ try (co.aikar.timings.Timing timed = world.timings.chunkSaveData.startTiming()) { // Paper - Timings
|
||||
+ this.playerChunkMap.saveIncrementally();
|
||||
+ } // Paper - Timings
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
// CraftBukkit start
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 257adcf4d5387fc18d5c48e0fa221f68539ad8f9..7920d24ab089fb8360ef74946cf7dc35cb7625eb 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -168,6 +168,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
public static int currentTick = 0; // Paper - Further improve tick loop
|
||||
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
|
||||
public int autosavePeriod;
|
||||
+ public boolean serverAutoSave = false; // Paper
|
||||
public File bukkitDataPackFolder;
|
||||
public CommandDispatcher vanillaCommandDispatcher;
|
||||
private boolean forceTicks;
|
||||
@@ -1116,14 +1117,28 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
this.serverPing.b().a(agameprofile);
|
||||
}
|
||||
|
||||
- if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit
|
||||
- MinecraftServer.LOGGER.debug("Autosave started");
|
||||
+ //if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit // Paper - move down
|
||||
+ //MinecraftServer.LOGGER.debug("Autosave started"); // Paper
|
||||
+ serverAutoSave = (autosavePeriod > 0 && this.ticks % autosavePeriod == 0); // Paper
|
||||
this.methodProfiler.enter("save");
|
||||
+ if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // Paper
|
||||
this.playerList.savePlayers();
|
||||
- this.saveChunks(true, false, false);
|
||||
+ }// Paper
|
||||
+ // Paper start
|
||||
+ for (WorldServer world : getWorlds()) {
|
||||
+ if (world.paperConfig.autoSavePeriod > 0) {
|
||||
+ try {
|
||||
+ world.saveIncrementally(serverAutoSave);
|
||||
+ } catch (ExceptionWorldConflict exceptionWorldConflict) {
|
||||
+ MinecraftServer.LOGGER.warn(exceptionWorldConflict.getMessage());
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
this.methodProfiler.exit();
|
||||
- MinecraftServer.LOGGER.debug("Autosave finished");
|
||||
- }
|
||||
+ //MinecraftServer.LOGGER.debug("Autosave finished"); // Paper
|
||||
+ //} // Paper
|
||||
|
||||
this.methodProfiler.enter("snooper");
|
||||
if (((DedicatedServer) this).getDedicatedServerProperties().snooperEnabled && !this.snooper.d() && this.ticks > 100) { // Spigot
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
index 47e3e618c9e683e6975fb64e1094dc7078574dae..ed9ada49c7cc1131691bd6e005b2380274ef23e3 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
@@ -41,6 +41,9 @@ public class PlayerChunk {
|
||||
|
||||
private final PlayerChunkMap chunkMap; // Paper
|
||||
|
||||
+ long lastAutoSaveTime; // Paper - incremental autosave
|
||||
+ long inactiveTimeStart; // Paper - incremental autosave
|
||||
+
|
||||
public PlayerChunk(ChunkCoordIntPair chunkcoordintpair, int i, LightEngine lightengine, PlayerChunk.c playerchunk_c, PlayerChunk.d playerchunk_d) {
|
||||
this.statusFutures = new AtomicReferenceArray(PlayerChunk.CHUNK_STATUSES.size());
|
||||
this.fullChunkFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE;
|
||||
@@ -386,7 +389,19 @@ public class PlayerChunk {
|
||||
boolean flag2 = playerchunk_state.isAtLeast(PlayerChunk.State.BORDER);
|
||||
boolean flag3 = playerchunk_state1.isAtLeast(PlayerChunk.State.BORDER);
|
||||
|
||||
+ boolean prevHasBeenLoaded = this.hasBeenLoaded; // Paper
|
||||
this.hasBeenLoaded |= flag3;
|
||||
+ // Paper start - incremental autosave
|
||||
+ if (this.hasBeenLoaded & !prevHasBeenLoaded) {
|
||||
+ long timeSinceAutoSave = this.inactiveTimeStart - this.lastAutoSaveTime;
|
||||
+ if (timeSinceAutoSave < 0) {
|
||||
+ // safest bet is to assume autosave is needed here
|
||||
+ timeSinceAutoSave = this.chunkMap.world.paperConfig.autoSavePeriod;
|
||||
+ }
|
||||
+ this.lastAutoSaveTime = this.chunkMap.world.getTime() - timeSinceAutoSave;
|
||||
+ this.chunkMap.autoSaveQueue.add(this);
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (!flag2 && flag3) {
|
||||
// Paper start - cache ticking ready status
|
||||
int expectCreateCount = ++this.fullChunkCreateCount;
|
||||
@@ -506,8 +521,32 @@ public class PlayerChunk {
|
||||
}
|
||||
|
||||
public void m() {
|
||||
+ boolean prev = this.hasBeenLoaded; // Paper
|
||||
+ this.hasBeenLoaded = getChunkState(this.ticketLevel).isAtLeast(PlayerChunk.State.BORDER);
|
||||
+ // Paper start - incremental autosave
|
||||
+ if (prev != this.hasBeenLoaded) {
|
||||
+ if (this.hasBeenLoaded) {
|
||||
+ long timeSinceAutoSave = this.inactiveTimeStart - this.lastAutoSaveTime;
|
||||
+ if (timeSinceAutoSave < 0) {
|
||||
+ // safest bet is to assume autosave is needed here
|
||||
+ timeSinceAutoSave = this.chunkMap.world.paperConfig.autoSavePeriod;
|
||||
+ }
|
||||
+ this.lastAutoSaveTime = this.chunkMap.world.getTime() - timeSinceAutoSave;
|
||||
+ this.chunkMap.autoSaveQueue.add(this);
|
||||
+ } else {
|
||||
+ this.inactiveTimeStart = this.chunkMap.world.getTime();
|
||||
+ this.chunkMap.autoSaveQueue.remove(this);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - incremental autosave
|
||||
+ public boolean setHasBeenLoaded() {
|
||||
this.hasBeenLoaded = getChunkState(this.ticketLevel).isAtLeast(PlayerChunk.State.BORDER);
|
||||
+ return this.hasBeenLoaded;
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
public void a(ProtoChunkExtension protochunkextension) {
|
||||
for (int i = 0; i < this.statusFutures.length(); ++i) {
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
index 34f470779fa5d1cf9638431253024481236c073b..4f5b516144829a7ae11f21a56789ac7a1f256250 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
@@ -332,6 +332,64 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - incremental autosave
|
||||
+ final it.unimi.dsi.fastutil.objects.ObjectRBTreeSet<PlayerChunk> autoSaveQueue = new it.unimi.dsi.fastutil.objects.ObjectRBTreeSet<>((playerchunk1, playerchunk2) -> {
|
||||
+ int timeCompare = Long.compare(playerchunk1.lastAutoSaveTime, playerchunk2.lastAutoSaveTime);
|
||||
+ if (timeCompare != 0) {
|
||||
+ return timeCompare;
|
||||
+ }
|
||||
+
|
||||
+ return Long.compare(MCUtil.getCoordinateKey(playerchunk1.location), MCUtil.getCoordinateKey(playerchunk2.location));
|
||||
+ });
|
||||
+
|
||||
+ protected void saveIncrementally() {
|
||||
+ int savedThisTick = 0;
|
||||
+ // optimized since we search far less chunks to hit ones that need to be saved
|
||||
+ List<PlayerChunk> reschedule = new ArrayList<>(this.world.paperConfig.maxAutoSaveChunksPerTick);
|
||||
+ long currentTick = this.world.getTime();
|
||||
+ long maxSaveTime = currentTick - this.world.paperConfig.autoSavePeriod;
|
||||
+
|
||||
+ for (Iterator<PlayerChunk> iterator = this.autoSaveQueue.iterator(); iterator.hasNext();) {
|
||||
+ PlayerChunk playerchunk = iterator.next();
|
||||
+ if (playerchunk.lastAutoSaveTime > maxSaveTime) {
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ iterator.remove();
|
||||
+
|
||||
+ IChunkAccess ichunkaccess = playerchunk.getChunkSave().getNow(null);
|
||||
+ if (ichunkaccess instanceof Chunk) {
|
||||
+ boolean shouldSave = ((Chunk)ichunkaccess).lastSaved <= maxSaveTime;
|
||||
+
|
||||
+ if (shouldSave && this.saveChunk(ichunkaccess)) {
|
||||
+ ++savedThisTick;
|
||||
+
|
||||
+ if (!playerchunk.setHasBeenLoaded()) {
|
||||
+ // do not fall through to reschedule logic
|
||||
+ playerchunk.inactiveTimeStart = currentTick;
|
||||
+ if (savedThisTick >= this.world.paperConfig.maxAutoSaveChunksPerTick) {
|
||||
+ break;
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ reschedule.add(playerchunk);
|
||||
+
|
||||
+ if (savedThisTick >= this.world.paperConfig.maxAutoSaveChunksPerTick) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0, len = reschedule.size(); i < len; ++i) {
|
||||
+ PlayerChunk playerchunk = reschedule.get(i);
|
||||
+ playerchunk.lastAutoSaveTime = this.world.getTime();
|
||||
+ this.autoSaveQueue.add(playerchunk);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
protected void save(boolean flag) {
|
||||
if (flag) {
|
||||
List<PlayerChunk> list = (List) this.visibleChunks.values().stream().filter(PlayerChunk::hasBeenLoaded).peek(PlayerChunk::m).collect(Collectors.toList());
|
||||
@@ -442,6 +500,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
|
||||
this.world.unloadChunk(chunk);
|
||||
}
|
||||
+ this.autoSaveQueue.remove(playerchunk); // Paper
|
||||
|
||||
this.lightEngine.a(ichunkaccess.getPos());
|
||||
this.lightEngine.queueUpdate();
|
||||
@@ -623,6 +682,8 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
playerchunk.a(new ProtoChunkExtension(chunk));
|
||||
}
|
||||
|
||||
+ chunk.setLastSaved(this.world.getTime() - 1); // Paper - avoid autosaving newly generated/loaded chunks
|
||||
+
|
||||
chunk.a(() -> {
|
||||
return PlayerChunk.getChunkState(playerchunk.getTicketLevel());
|
||||
});
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index ca0a23be27ee8174204867d463eb89a10931ff84..a0484d8062ecfb817cfd5b996915dc8f9a4eb2bd 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -817,11 +817,44 @@ public class WorldServer extends World {
|
||||
return this.worldProvider.c();
|
||||
}
|
||||
|
||||
+ // Paper start - derived from below
|
||||
+ public void saveIncrementally(boolean doFull) throws ExceptionWorldConflict {
|
||||
+ ChunkProviderServer chunkproviderserver = this.getChunkProvider();
|
||||
+
|
||||
+ if (doFull) {
|
||||
+ org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld()));
|
||||
+ }
|
||||
+
|
||||
+ try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) {
|
||||
+ if (doFull) {
|
||||
+ this.saveData();
|
||||
+ }
|
||||
+
|
||||
+ timings.worldSaveChunks.startTiming(); // Paper
|
||||
+ if (!this.isSavingDisabled()) chunkproviderserver.saveIncrementally();
|
||||
+ timings.worldSaveChunks.stopTiming(); // Paper
|
||||
+
|
||||
+
|
||||
+ // CraftBukkit start - moved from MinecraftServer.saveChunks
|
||||
+ // PAIL - rename
|
||||
+ if (doFull) {
|
||||
+ WorldServer worldserver1 = this;
|
||||
+ WorldData worlddata = worldserver1.getWorldData();
|
||||
+
|
||||
+ worldserver1.getWorldBorder().save(worlddata);
|
||||
+ worlddata.setCustomBossEvents(this.server.getBossBattleCustomData().save());
|
||||
+ worldserver1.getDataManager().saveWorldData(worlddata, this.server.getPlayerList().save());
|
||||
+ // CraftBukkit end
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public void save(@Nullable IProgressUpdate iprogressupdate, boolean flag, boolean flag1) throws ExceptionWorldConflict {
|
||||
ChunkProviderServer chunkproviderserver = this.getChunkProvider();
|
||||
|
||||
if (!flag1) {
|
||||
- org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit
|
||||
+ if (flag) org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit
|
||||
try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) { // Paper
|
||||
if (iprogressupdate != null) {
|
||||
iprogressupdate.a(new ChatMessage("menu.savingLevel", new Object[0]));
|
||||
@@ -848,6 +881,7 @@ public class WorldServer extends World {
|
||||
// CraftBukkit end
|
||||
}
|
||||
|
||||
+ protected void saveData() throws ExceptionWorldConflict { this.m_(); } // Paper - OBFHELPER
|
||||
protected void m_() throws ExceptionWorldConflict {
|
||||
this.checkSession();
|
||||
this.worldProvider.i();
|
Loading…
Add table
Add a link
Reference in a new issue