From c383fab2c2dab9e1b32abf47b30e60e19cba8da5 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Wed, 30 Oct 2019 12:58:21 +0100 Subject: [PATCH] cfi packet listener --- .../com/boydti/fawe/bukkit/FaweBukkit.java | 8 +- .../adapter/mc1_14/Spigot_v1_14_R4.java | 8 +- .../bukkit/listener/CFIPacketListener.java | 190 +++++++++--------- .../main/java/com/boydti/fawe/FaweCache.java | 3 + .../cfi/HeightMapMCAGenerator.java | 28 +-- .../main/java/com/boydti/fawe/util/Jars.java | 4 +- .../com/sk89q/worldedit/LocalSession.java | 17 ++ .../worldedit/command/UtilityCommands.java | 9 + 8 files changed, 153 insertions(+), 114 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java index c9aac5c8e..e05c1c149 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java @@ -141,15 +141,15 @@ public class FaweBukkit implements IFawe, Listener { PluginManager manager = Bukkit.getPluginManager(); if (manager.getPlugin("PacketListenerApi") == null) { - File output = new File(plugin.getDataFolder().getParentFile(), "PacketListenerAPI_v3.6.0-SNAPSHOT.jar"); - byte[] jarData = Jars.PL_v3_6_0.download(); + File output = new File(plugin.getDataFolder().getParentFile(), "PacketListenerAPI_v3.7.3-SNAPSHOT.jar"); + byte[] jarData = Jars.PL_v3_7_3.download(); try (FileOutputStream fos = new FileOutputStream(output)) { fos.write(jarData); } } if (manager.getPlugin("MapManager") == null) { - File output = new File(plugin.getDataFolder().getParentFile(), "MapManager_v1.4.0-SNAPSHOT.jar"); - byte[] jarData = Jars.MM_v1_4_0.download(); + File output = new File(plugin.getDataFolder().getParentFile(), "MapManager_v1.7.3-SNAPSHOT.jar"); + byte[] jarData = Jars.MM_v1_7_3.download(); try (FileOutputStream fos = new FileOutputStream(output)) { fos.write(jarData); } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/Spigot_v1_14_R4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/Spigot_v1_14_R4.java index 5efdd8b86..bbde523c5 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/Spigot_v1_14_R4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/Spigot_v1_14_R4.java @@ -20,6 +20,7 @@ package com.boydti.fawe.bukkit.adapter.mc1_14; import com.boydti.fawe.Fawe; +import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.implementation.ChunkPacket; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; @@ -679,7 +680,12 @@ public final class Spigot_v1_14_R4 extends CachedBukkitAdapter implements Bukkit nmsPacket = MapChunkUtil_1_14.create(this, packet); packet.setNativePacket(nmsPacket); } - entityPlayer.playerConnection.sendPacket(nmsPacket); + try { + FaweCache.IMP.CHUNK_FLAG.get().set(true); + entityPlayer.playerConnection.sendPacket(nmsPacket); + } finally { + FaweCache.IMP.CHUNK_FLAG.get().set(false); + } } }); } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/listener/CFIPacketListener.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/listener/CFIPacketListener.java index 8574de6f4..b7be10671 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/listener/CFIPacketListener.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/listener/CFIPacketListener.java @@ -1,5 +1,6 @@ package com.boydti.fawe.bukkit.listener; +import com.boydti.fawe.FaweCache; import com.boydti.fawe.command.CFICommands; import com.boydti.fawe.object.RunnableVal3; import com.boydti.fawe.object.brush.visualization.VirtualWorld; @@ -15,20 +16,32 @@ import com.comphenix.protocol.wrappers.BlockPosition; import com.comphenix.protocol.wrappers.ChunkCoordIntPair; import com.comphenix.protocol.wrappers.EnumWrappers; import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitPlayer; import com.sk89q.worldedit.event.platform.BlockInteractEvent; import com.sk89q.worldedit.event.platform.Interaction; import com.sk89q.worldedit.extension.platform.PlatformManager; import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.world.block.BlockState; import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.List; + +import com.sk89q.worldedit.world.block.BlockStateHolder; +import com.sk89q.worldedit.world.block.BlockTypes; import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; /** * The CFIPacketListener handles packets for editing the VirtualWorld @@ -45,99 +58,90 @@ public class CFIPacketListener implements Listener { this.plugin = plugin; this.protocolmanager = ProtocolLibrary.getProtocolManager(); - // TODO NOT IMPLEMENTED -// // Direct digging to the virtual world -// registerBlockEvent(PacketType.Play.Client.BLOCK_DIG, false, new RunnableVal3() { -// @Override -// public void run(Builder event, URI gen, String pt) { -// try { -// Player plr = event.getPlayer(); -// BlockVector3 realPos = pt.add(gen.getOrigin().toBlockPoint()); -// if (!sendBlockChange(plr, gen, pt, Interaction.HIT)) { -// gen.setBlock(pt, BlockTypes.AIR.getDefaultState()); -// } -// } catch (WorldEditException e) { -// e.printStackTrace(); -// } -// } -// }); -// -// // Direct placing to the virtual world -// RunnableVal3 placeTask = new RunnableVal3() { -// @Override -// public void run(Builder event, URI gen, String pt) { -// try { -// Player plr = event.getPlayer(); -// List hands = event.getPacket().getHands().getValues(); -// -// EnumWrappers.Hand enumHand = hands.isEmpty() ? EnumWrappers.Hand.MAIN_HAND : hands.get(0); -// PlayerInventory inv = plr.getInventory(); -// ItemStack hand = enumHand == EnumWrappers.Hand.MAIN_HAND ? inv.getItemInMainHand() : inv.getItemInOffHand(); -// if (hand.getType().isBlock()) { -// Material type = hand.getType(); -// switch (type) { -// case AIR: -// case CAVE_AIR: -// case VOID_AIR: -// break; -// default: { -// BlockStateHolder block = BukkitAdapter.asBlockState(hand); -// if (block != null) { -// gen.setBlock(pt, block); -// return; -// } -// } -// } -// } -// pt = getRelPos(event, gen); -// sendBlockChange(plr, gen, pt, Interaction.OPEN); -// } catch (WorldEditException e) { -// e.printStackTrace(); -// } -// } -// }; -// registerBlockEvent(PacketType.Play.Client.BLOCK_PLACE, true, placeTask); -// registerBlockEvent(PacketType.Play.Client.USE_ITEM, true, placeTask); -// -// // Cancel block change packets where the real world overlaps with the virtual one -// registerBlockEvent(PacketType.Play.Server.BLOCK_CHANGE, false, new RunnableVal3() { -// @Override -// public void run(Builder event, URI gen, String pt) { -// // Do nothing -// } -// }); -// -// // Modify chunk packets where the real world overlaps with the virtual one -// protocolmanager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.MAP_CHUNK) { -// @Override -// public void onPacketSending(PacketEvent event) { -// if (!event.isServerPacket()) return; -// -// VirtualWorld gen = getGenerator(event); -// if (gen != null) { -// BlockVector3 origin = gen.getOrigin().toBlockPoint(); -// PacketContainer packet = event.getPacket(); -// StructureModifier ints = packet.getIntegers(); -// int cx = ints.read(0); -// int cz = ints.read(1); -// -// int ocx = origin.getBlockX() >> 4; -// int ocz = origin.getBlockZ() >> 4; -// -// if (gen.contains(BlockVector3.at((cx - ocx) << 4, 0, (cz - ocz) << 4))) { -// event.setCancelled(true); -// -// Player plr = event.getPlayer(); -// -// FaweQueue queue = SetQueue.IMP.getNewQueue(plr.getWorld().getName(), true, false); -// -// FaweChunk toSend = gen.getSnapshot(cx - ocx, cz - ocz); -// toSend.setLoc(gen, cx, cz); -// queue.sendChunkUpdate(toSend, FawePlayer.wrap(plr)); -// } -// } -// } -// }); + // Direct digging to the virtual world + registerBlockEvent(PacketType.Play.Client.BLOCK_DIG, false, new RunnableVal3() { + @Override + public void run(PacketEvent event, VirtualWorld gen, BlockVector3 pt) { + try { + Player plr = event.getPlayer(); + BlockVector3 realPos = pt.add(gen.getOrigin().toBlockPoint()); + if (!sendBlockChange(plr, gen, pt, Interaction.HIT)) { + gen.setBlock(pt, BlockTypes.AIR.getDefaultState()); + } + } catch (WorldEditException e) { + e.printStackTrace(); + } + } + }); + + // Direct placing to the virtual world + RunnableVal3 placeTask = new RunnableVal3() { + @Override + public void run(PacketEvent event, VirtualWorld gen, BlockVector3 pt) { + try { + Player plr = event.getPlayer(); + List hands = event.getPacket().getHands().getValues(); + + EnumWrappers.Hand enumHand = hands.isEmpty() ? EnumWrappers.Hand.MAIN_HAND : hands.get(0); + PlayerInventory inv = plr.getInventory(); + ItemStack hand = enumHand == EnumWrappers.Hand.MAIN_HAND ? inv.getItemInMainHand() : inv.getItemInOffHand(); + if (hand.getType().isBlock()) { + Material type = hand.getType(); + switch (type) { + case AIR: + case CAVE_AIR: + case VOID_AIR: + break; + default: { + BlockStateHolder block = BukkitAdapter.asBlockState(hand); + if (block != null) { + gen.setBlock(pt, block); + return; + } + } + } + } + pt = getRelPos(event, gen); + sendBlockChange(plr, gen, pt, Interaction.OPEN); + } catch (WorldEditException e) { + e.printStackTrace(); + } + } + }; + registerBlockEvent(PacketType.Play.Client.BLOCK_PLACE, true, placeTask); + registerBlockEvent(PacketType.Play.Client.USE_ITEM, true, placeTask); + + // Cancel block change packets where the real world overlaps with the virtual one + registerBlockEvent(PacketType.Play.Server.BLOCK_CHANGE, false, new RunnableVal3() { + @Override + public void run(PacketEvent event, VirtualWorld gen, BlockVector3 pt) { + // Do nothing + } + }); + + // Modify chunk packets where the real world overlaps with the virtual one + protocolmanager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.MAP_CHUNK) { + @Override + public void onPacketSending(PacketEvent event) { + if (!event.isServerPacket() || FaweCache.IMP.CHUNK_FLAG.get().get()) return; + VirtualWorld gen = getGenerator(event); + if (gen != null) { + BlockVector3 origin = gen.getOrigin().toBlockPoint(); + PacketContainer packet = event.getPacket(); + StructureModifier ints = packet.getIntegers(); + int cx = ints.read(0); + int cz = ints.read(1); + + int ocx = origin.getBlockX() >> 4; + int ocz = origin.getBlockZ() >> 4; + + if (gen.contains(BlockVector3.at((cx - ocx) << 4, 0, (cz - ocz) << 4))) { + event.setCancelled(true); + gen.refreshChunk(cx - ocx, cz - ocz); + } + } + } + }); // The following few listeners are to ignore block collisions where the virtual and real world overlap diff --git a/worldedit-core/src/main/java/com/boydti/fawe/FaweCache.java b/worldedit-core/src/main/java/com/boydti/fawe/FaweCache.java index 3cd039f48..07a6fe0b9 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/FaweCache.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/FaweCache.java @@ -45,6 +45,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; import static com.google.common.base.Preconditions.checkNotNull; @@ -104,6 +105,7 @@ public enum FaweCache implements Trimable { @Override public synchronized boolean trim(boolean aggressive) { + CHUNK_FLAG.clean(); BYTE_BUFFER_8192.clean(); BLOCK_TO_PALETTE.clean(); PALETTE_TO_BLOCK.clean(); @@ -205,6 +207,7 @@ public enum FaweCache implements Trimable { /* thread cache */ + public final CleanableThreadLocal CHUNK_FLAG = new CleanableThreadLocal<>(AtomicBoolean::new); // resets to false public final CleanableThreadLocal BYTE_BUFFER_8192 = new CleanableThreadLocal<>(() -> new byte[8192]); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/HeightMapMCAGenerator.java b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/HeightMapMCAGenerator.java index 4f2a0e81f..df4fbec81 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/HeightMapMCAGenerator.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/HeightMapMCAGenerator.java @@ -289,12 +289,10 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr int lenCX = (getWidth() + 15) >> 4; int lenCZ = (getLength() + 15) >> 4; - int OX = chunkOffset.getBlockX(); - int OZ = chunkOffset.getBlockZ(); Location position = player.getLocation(); - int pcx = (position.getBlockX() >> 4) - OX; - int pcz = (position.getBlockZ() >> 4) - OZ; + int pcx = (position.getBlockX() >> 4) - chunkOffset.getBlockX(); + int pcz = (position.getBlockZ() >> 4) - chunkOffset.getBlockZ(); int scx = Math.max(0, pcx - 15); int scz = Math.max(0, pcz - 15); @@ -303,21 +301,23 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr for (int chunkZ = scz; chunkZ <= ecz; chunkZ++) { for (int chunkX = scx; chunkX <= ecx; chunkX++) { - int finalChunkX = chunkX; - int finalChunkZ = chunkZ; - int realWorldX = chunkX + OX; - int realWorldZ = chunkZ + OZ; - - Supplier blocksSupplier = () -> getChunk(finalChunkX, finalChunkZ); - - ChunkPacket packet = new ChunkPacket(realWorldX, realWorldZ, blocksSupplier, true); - world.sendFakeChunk(player, packet); + refreshChunk(world, chunkX, chunkZ); } } } } + public void refreshChunk(World world, int chunkX, int chunkZ) { + Supplier blocksSupplier = () -> getChunk(chunkX, chunkZ); + + int realChunkX = chunkX + chunkOffset.getBlockX(); + int realChunkZ = chunkZ + chunkOffset.getBlockZ(); + + ChunkPacket packet = new ChunkPacket(realChunkX, realChunkZ, blocksSupplier, true); + world.sendFakeChunk(player, packet); + } + @Override public void sendFakeChunk(@Nullable Player player, ChunkPacket packet) { if (this.player != null) { @@ -328,7 +328,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr @Override public void refreshChunk(int chunkX, int chunkZ) { if (chunkOffset != null && player != null) { - player.getWorld().refreshChunk(chunkX, chunkZ); + refreshChunk(player.getWorld(), chunkX, chunkZ); } } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/Jars.java b/worldedit-core/src/main/java/com/boydti/fawe/util/Jars.java index 3633d7baa..e991ee747 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/util/Jars.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/util/Jars.java @@ -10,10 +10,10 @@ import java.util.Base64; public enum Jars { - MM_v1_4_0("https://github.com/InventivetalentDev/MapManager/releases/download/1.7.3-SNAPSHOT/MapManager_v1.7.3-SNAPSHOT.jar", + MM_v1_7_3("https://github.com/InventivetalentDev/MapManager/releases/download/1.7.3-SNAPSHOT/MapManager_v1.7.3-SNAPSHOT.jar", "M3YLUQZZ66K2DMVDCYLEU38U3ZKRKHRAXQGGPVKFO6G=", 554831), - PL_v3_6_0("https://github.com/InventivetalentDev/PacketListenerAPI/releases/download/3.7.3-SNAPSHOT/PacketListenerAPI_v3.7.3-SNAPSHOT.jar", + PL_v3_7_3("https://github.com/InventivetalentDev/PacketListenerAPI/releases/download/3.7.3-SNAPSHOT/PacketListenerAPI_v3.7.3-SNAPSHOT.jar", "ETDBRZLN5PRVDFR/MSQDPM6JJER3WQOKHCN8FUXO5ZM=", 167205), ; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index 9fff40e3c..fd829d664 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -39,6 +39,7 @@ import com.boydti.fawe.util.StringMan; import com.boydti.fawe.util.TextureHolder; import com.boydti.fawe.util.TextureUtil; import com.boydti.fawe.wrappers.WorldWrapper; +import com.google.common.collect.Maps; import com.sk89q.jchronic.Chronic; import com.sk89q.jchronic.Options; import com.sk89q.jchronic.utils.Span; @@ -90,7 +91,9 @@ import java.io.FileOutputStream; import java.io.IOException; import java.time.ZoneId; import java.util.Calendar; +import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.IdentityHashMap; import java.util.LinkedList; import java.util.List; @@ -167,6 +170,7 @@ public class LocalSession implements TextureHolder { private boolean useServerCUI = false; // Save this to not annoy players. private ItemType wandItem; private ItemType navWandItem; + private Map macros = new HashMap<>(); /** * Construct the object. @@ -296,6 +300,19 @@ public class LocalSession implements TextureHolder { } } + public Map getMacros() { + return Collections.unmodifiableMap(this.macros); + } + + public void setMacro(String key, String value) { + this.macros.put(key, value); + setDirty(); + } + + public String getMacro(String key) { + return this.macros.get(key); + } + /** * Get whether this session is "dirty" and has changes that needs to * be committed. diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index aa46a1c61..0fe010331 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -111,6 +111,15 @@ public class UtilityCommands { this.we = we; } + @Command( + name = "/macro", + desc = "Generate or run a macro" + ) + @CommandPermissions("worldedit.macro") + public void macro(Player player, LocalSession session, String name, String argument) throws IOException { + + } + @Command( name = "/heightmapinterface", desc = "Generate the heightmap interface: https://github.com/boy0001/HeightMap"