mirror of
https://github.com/PaperMC/Paper.git
synced 2024-08-26 22:50:23 +02:00
Upstream has released updates that appears to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing
Bukkit Changes:
565a5727 #533: Add consumed item, hand and consumeItem boolean to EntityShootBowEvent
CraftBukkit Changes:
927200a9
#718: Add consumed item, hand and consumeItem boolean to EntityShootBowEvent
169 lines
8.8 KiB
Diff
169 lines
8.8 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
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 2784ea71b9f5ee93f6de8e5a3a135457f1be17a3..874bf7d3ddd22ddc4ea08dac1f548d246d85e991 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
|
@@ -321,6 +321,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 3e73ef8059139b09518075bb6dc89a67f46be51a..56a2d028040bb77bffee72330bc2a19986b45d00 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
@@ -97,6 +97,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;
|
|
@@ -288,11 +294,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;
|