diff options
Diffstat (limited to 'Spigot-Server-Patches/0482-Fix-Light-Command.patch')
-rw-r--r-- | Spigot-Server-Patches/0482-Fix-Light-Command.patch | 168 |
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; |