aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-Server-Patches/0482-Fix-Light-Command.patch
diff options
context:
space:
mode:
Diffstat (limited to 'Spigot-Server-Patches/0482-Fix-Light-Command.patch')
-rw-r--r--Spigot-Server-Patches/0482-Fix-Light-Command.patch168
1 files changed, 168 insertions, 0 deletions
diff --git a/Spigot-Server-Patches/0482-Fix-Light-Command.patch b/Spigot-Server-Patches/0482-Fix-Light-Command.patch
new file mode 100644
index 0000000000..d4d8453264
--- /dev/null
+++ b/Spigot-Server-Patches/0482-Fix-Light-Command.patch
@@ -0,0 +1,168 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Aikar <[email protected]>
+Date: Thu, 7 May 2020 19:17:36 -0400
+Subject: [PATCH] Fix Light Command
+
+This lets you run /paper fixlight <chunkRadius> (max 5) to automatically
+fix all light data in the chunks.
+
+diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
+index f7d98a5ba54d041eef10b04f821e0958ad898b0a..a12bc81933c15606b7cde46937f504eafc4ff030 100644
+--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
++++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
+@@ -20,6 +20,7 @@ import org.bukkit.command.Command;
+ import org.bukkit.command.CommandSender;
+ import org.bukkit.craftbukkit.CraftServer;
+ import org.bukkit.craftbukkit.CraftWorld;
++import org.bukkit.craftbukkit.entity.CraftPlayer;
+ import org.bukkit.entity.Player;
+
+ import java.io.File;
+@@ -36,14 +37,14 @@ public class PaperCommand extends Command {
+ public PaperCommand(String name) {
+ super(name);
+ this.description = "Paper related commands";
+- this.usageMessage = "/paper [heap | entity | reload | version | debug | dumpwaiting | chunkinfo | syncloadinfo]";
++ this.usageMessage = "/paper [heap | entity | reload | version | debug | dumpwaiting | chunkinfo | syncloadinfo | fixlight]";
+ this.setPermission("bukkit.command.paper");
+ }
+
+ @Override
+ public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
+ if (args.length <= 1)
+- return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "dumpwaiting", "chunkinfo", "syncloadinfo");
++ return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "dumpwaiting", "chunkinfo", "syncloadinfo", "fixlight");
+
+ switch (args[0].toLowerCase(Locale.ENGLISH))
+ {
+@@ -144,6 +145,9 @@ public class PaperCommand extends Command {
+ case "syncloadinfo":
+ this.doSyncLoadInfo(sender, args);
+ break;
++ case "fixlight":
++ this.doFixLight(sender, args);
++ break;
+ case "ver":
+ case "version":
+ Command ver = org.bukkit.Bukkit.getServer().getCommandMap().getCommand("version");
+@@ -160,6 +164,77 @@ public class PaperCommand extends Command {
+ return true;
+ }
+
++ private void doFixLight(CommandSender sender, String[] args) {
++ if (!(sender instanceof Player)) {
++ sender.sendMessage("Only players can use this command");
++ return;
++ }
++ int radius = 2;
++ if (args.length > 1) {
++ try {
++ radius = Math.min(5, Integer.parseInt(args[1]));
++ } catch (Exception e) {
++ sender.sendMessage("Not a number");
++ return;
++ }
++
++ }
++
++ CraftPlayer player = (CraftPlayer) sender;
++ EntityPlayer handle = player.getHandle();
++ net.minecraft.server.WorldServer world = (WorldServer) handle.world;
++ LightEngineThreaded lightengine = world.getChunkProvider().getLightEngine();
++
++ BlockPosition center = MCUtil.toBlockPosition(player.getLocation());
++ Deque<ChunkCoordIntPair> queue = new ArrayDeque<>(MCUtil.getSpiralOutChunks(center, radius));
++ updateLight(sender, world, lightengine, queue);
++ }
++
++ private void updateLight(CommandSender sender, WorldServer world, LightEngineThreaded lightengine, Deque<ChunkCoordIntPair> queue) {
++ ChunkCoordIntPair coord = queue.poll();
++ if (coord == null) {
++ sender.sendMessage("All Chunks Light updated");
++ return;
++ }
++ world.getChunkProvider().getChunkAtAsynchronously(coord.x, coord.z, false, false).whenCompleteAsync((either, ex) -> {
++ if (ex != null) {
++ sender.sendMessage("Error loading chunk " + coord);
++ updateLight(sender, world, lightengine, queue);
++ return;
++ }
++ Chunk chunk = (Chunk) either.left().orElse(null);
++ if (chunk == null) {
++ updateLight(sender, world, lightengine, queue);
++ return;
++ }
++ lightengine.a(world.paperConfig.lightQueueSize + 16 * 256); // ensure full chunk can fit into queue
++ sender.sendMessage("Updating Light " + coord);
++ int cx = chunk.getPos().x << 4;
++ int cz = chunk.getPos().z << 4;
++ for (int y = 0; y < world.getHeight(); y++) {
++ for (int x = 0; x < 16; x++) {
++ for (int z = 0; z < 16; z++) {
++ BlockPosition pos = new BlockPosition(cx + x, y, cz + z);
++ lightengine.a(pos);
++ }
++ }
++ }
++ lightengine.queueUpdate();
++ PlayerChunk visibleChunk = world.getChunkProvider().playerChunkMap.getVisibleChunk(chunk.coordinateKey);
++ if (visibleChunk != null) {
++ world.getChunkProvider().playerChunkMap.addLightTask(visibleChunk, () -> {
++ MinecraftServer.getServer().processQueue.add(() -> {
++ visibleChunk.sendPacketToTrackedPlayers(new PacketPlayOutLightUpdate(chunk.getPos(), lightengine, true), false);
++ updateLight(sender, world, lightengine, queue);
++ });
++ });
++ } else {
++ updateLight(sender, world, lightengine, queue);
++ }
++ lightengine.a(world.paperConfig.lightQueueSize);
++ }, MinecraftServer.getServer());
++ }
++
+ private void doSyncLoadInfo(CommandSender sender, String[] args) {
+ if (!SyncLoadFinder.ENABLED) {
+ sender.sendMessage(ChatColor.RED + "This command requires the server startup flag '-Dpaper.debug-sync-loads=true' to be set.");
+diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
+index 40347212ad1bcf857d5b8ddb0ee6a698e2568201..e5751adde516544722b95016f64b2a46c16e77ce 100644
+--- a/src/main/java/net/minecraft/server/PlayerChunk.java
++++ b/src/main/java/net/minecraft/server/PlayerChunk.java
+@@ -314,6 +314,7 @@ public class PlayerChunk {
+
+ }
+
++ public void sendPacketToTrackedPlayers(Packet<?> packet, boolean flag) { a(packet, flag); } // Paper - OBFHELPER
+ private void a(Packet<?> packet, boolean flag) {
+ // Paper start - per player view distance
+ // there can be potential desync with player's last mapped section and the view distance map, so use the
+diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
+index f67a8b655d0d0a9397650f771bc68f148ca9edcc..3711914d59c61b652c6c675812ca5ecc29f95130 100644
+--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
++++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
+@@ -96,6 +96,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+ private final ChunkTaskQueueSorter p;
+ private final Mailbox<ChunkTaskQueueSorter.a<Runnable>> mailboxWorldGen;
+ final Mailbox<ChunkTaskQueueSorter.a<Runnable>> mailboxMain; // Paper - private -> package private
++ // Paper start
++ final Mailbox<ChunkTaskQueueSorter.a<Runnable>> mailboxLight;
++ public void addLightTask(PlayerChunk playerchunk, Runnable run) {
++ this.mailboxLight.a(ChunkTaskQueueSorter.a(playerchunk, run));
++ }
++ // Paper end
+ public final WorldLoadListener worldLoadListener;
+ public final PlayerChunkMap.a chunkDistanceManager;
+ private final AtomicInteger u;
+@@ -287,11 +293,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+ Mailbox<Runnable> mailbox = Mailbox.a("main", iasynctaskhandler::a);
+
+ this.worldLoadListener = worldloadlistener;
+- ThreadedMailbox<Runnable> threadedmailbox1 = ThreadedMailbox.a(executor, "light");
++ ThreadedMailbox<Runnable> lightthreaded; ThreadedMailbox<Runnable> threadedmailbox1 = lightthreaded = ThreadedMailbox.a(executor, "light"); // Paper
+
+ this.p = new ChunkTaskQueueSorter(ImmutableList.of(threadedmailbox, mailbox, threadedmailbox1), executor, Integer.MAX_VALUE);
+ this.mailboxWorldGen = this.p.a(threadedmailbox, false);
+ this.mailboxMain = this.p.a(mailbox, false);
++ this.mailboxLight = this.p.a(lightthreaded, false);// Paper
+ this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getDimensionManager().hasSkyLight(), threadedmailbox1, this.p.a(threadedmailbox1, false));
+ this.chunkDistanceManager = new PlayerChunkMap.a(executor, iasynctaskhandler); this.chunkDistanceManager.chunkMap = this; // Paper
+ this.l = supplier;