diff --git a/SpigotCore/SpigotCore_20/build.gradle.kts b/SpigotCore/SpigotCore_20/build.gradle.kts index 3e894ccc..25808631 100644 --- a/SpigotCore/SpigotCore_20/build.gradle.kts +++ b/SpigotCore/SpigotCore_20/build.gradle.kts @@ -26,5 +26,6 @@ dependencies { compileOnly(libs.spigotapi) + compileOnly(libs.worldedit15) compileOnly(libs.nms20) } diff --git a/SpigotCore/SpigotCore_20/src/de/steamwar/core/WorldEditRenderer20.java b/SpigotCore/SpigotCore_20/src/de/steamwar/core/WorldEditRenderer20.java new file mode 100644 index 00000000..d84f4abb --- /dev/null +++ b/SpigotCore/SpigotCore_20/src/de/steamwar/core/WorldEditRenderer20.java @@ -0,0 +1,217 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.core; + +import com.sk89q.worldedit.EmptyClipboardException; +import com.sk89q.worldedit.IncompleteRegionException; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.regions.RegionSelector; +import com.sk89q.worldedit.world.World; +import de.steamwar.core.renderers.CuboidRegionRenderer; +import de.steamwar.core.renderers.RegionRenderer; +import de.steamwar.entity.REntityServer; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.player.*; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; + +public class WorldEditRenderer20 implements WorldEditRenderer, Listener { + + private static final Map servers = new HashMap<>(); + private static final Map clipboards = new HashMap<>(); + private static final Map regionSelections = new HashMap<>(); + + private static final Material WAND = FlatteningWrapper.impl.getMaterial("WOOD_AXE"); + + private final WorldEditPlugin we; + + private static final Map, Supplier>> rendererMap = new HashMap<>(); + + static { + rendererMap.put(CuboidRegion.class, CuboidRegionRenderer::new); + } + + public WorldEditRenderer20() { + we = WorldEditWrapper.getWorldEditPlugin(); + Bukkit.getPluginManager().registerEvents(this, Core.getInstance()); + Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> { + for (Player player : Bukkit.getOnlinePlayers()) { + render(player); + } + }, 10, 10); + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerJoin(PlayerJoinEvent event) { + Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { + render(event.getPlayer()); + }, 0); + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) { + Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { + render(event.getPlayer()); + }, 0); + } + + @EventHandler + public void onPlayerDropItem(PlayerDropItemEvent event) { + Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { + render(event.getPlayer()); + }, 0); + } + + @EventHandler + public void onPlayerItemHeld(PlayerItemHeldEvent event) { + Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { + render(event.getPlayer()); + }, 0); + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { + render(event.getPlayer()); + }, 0); + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerInteract(PlayerInteractEvent event) { + Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { + render(event.getPlayer()); + }, 0); + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerMove(PlayerMoveEvent event) { + Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { + render(event.getPlayer(), true, false); + }, 0); + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerQuit(PlayerQuitEvent event) { + REntityServer server = servers.remove(event.getPlayer()); + clipboards.remove(event.getPlayer()); + regionSelections.remove(event.getPlayer()); + if (server == null) return; + server.close(); + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) { + String command = event.getMessage().split(" ")[0]; + command = command.replaceFirst("/", ""); + command = command.toLowerCase(); + if (WorldEdit.getInstance().getPlatformManager().getPlatformCommandManager().getCommandManager().containsCommand(command)) { + Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { + render(event.getPlayer()); + }, 10); + } + } + + private void render(Player player) { + render(player, true, true); + } + + private void render(Player player, boolean renderClipboard, boolean renderRegionSelection) { + if (player.getInventory().getItemInMainHand().getType() != WAND) { + REntityServer entityServer = servers.remove(player); + clipboards.remove(player); + regionSelections.remove(player); + if (entityServer != null) entityServer.close(); + return; + } + + REntityServer server = servers.computeIfAbsent(player, __ -> { + REntityServer _server = new REntityServer(); + _server.addPlayer(player); + return _server; + }); + + LocalSession session = we.getSession(player); + if (renderClipboard) { + renderClipboard(server, session, player); + } + if (renderRegionSelection) { + renderSelection(server, session, player); + } + } + + @SuppressWarnings("unchecked") + private void renderClipboard(REntityServer server, LocalSession session, Player player) { + try { + Region region = session.getClipboard().getClipboard().getRegion(); + clipboards.compute(player, (__, regionRenderer) -> { + if (regionRenderer != null && !regionRenderer.canDisplay(region)) { + regionRenderer.clear(); + regionRenderer = null; + } + if (regionRenderer == null) { + return rendererMap.getOrDefault(region.getClass(), RegionRenderer.NOOPImpl::new).get(); + } else { + return regionRenderer; + } + }).update(server, region, session.getClipboard(), Material.LIME_CONCRETE.createBlockData()); + } catch (EmptyClipboardException e) { + RegionRenderer regionRenderer = clipboards.remove(player); + if (regionRenderer != null) regionRenderer.clear(); + } + } + + @SuppressWarnings("unchecked") + private void renderSelection(REntityServer server, LocalSession session, Player player) { + World world = session.getSelectionWorld(); + if (world == null) { + return; + } + RegionSelector regionSelector = session.getRegionSelector(world); + try { + Region region = regionSelector.getRegion(); + regionSelections.compute(player, (__, regionRenderer) -> { + if (regionRenderer != null && !regionRenderer.canDisplay(region)) { + regionRenderer.clear(); + regionRenderer = null; + } + if (regionRenderer == null) { + return rendererMap.getOrDefault(region.getClass(), RegionRenderer.NOOPImpl::new).get(); + } else { + return regionRenderer; + } + }).update(server, region, null, Material.PURPLE_CONCRETE.createBlockData()); + } catch (IncompleteRegionException e) { + RegionRenderer regionRenderer = regionSelections.remove(player); + if (regionRenderer != null) regionRenderer.clear(); + } + } +} diff --git a/SpigotCore/SpigotCore_20/src/de/steamwar/core/renderers/CuboidRegionRenderer.java b/SpigotCore/SpigotCore_20/src/de/steamwar/core/renderers/CuboidRegionRenderer.java new file mode 100644 index 00000000..70391d3d --- /dev/null +++ b/SpigotCore/SpigotCore_20/src/de/steamwar/core/renderers/CuboidRegionRenderer.java @@ -0,0 +1,159 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.core.renderers; + +import com.sk89q.worldedit.math.transform.Transform; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.session.ClipboardHolder; +import de.steamwar.core.WorldEditWrapper; +import de.steamwar.entity.RBlockDisplay; +import de.steamwar.entity.REntityServer; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.data.BlockData; +import org.bukkit.entity.Display; +import org.bukkit.entity.Player; +import org.bukkit.util.Transformation; +import org.bukkit.util.Vector; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +public class CuboidRegionRenderer implements RegionRenderer { + + private static final World WORLD = Bukkit.getWorlds().get(0); + private static final float offset = 1 / 1024f; + private static final float width = 1 / 16f; + + private Vector lastA = null; + private Vector lastB = null; + + private RBlockDisplay bd01; + private RBlockDisplay bd02; + private RBlockDisplay bd03; + private RBlockDisplay bd04; + private RBlockDisplay bd05; + private RBlockDisplay bd06; + private RBlockDisplay bd07; + private RBlockDisplay bd08; + private RBlockDisplay bd09; + private RBlockDisplay bd10; + private RBlockDisplay bd11; + private RBlockDisplay bd12; + + @Override + public boolean canDisplay(Region region) { + return region instanceof CuboidRegion; + } + + public void update(REntityServer server, CuboidRegion region, ClipboardHolder holder, BlockData block) { + Vector a; + Vector b; + if (holder != null) { + Player player = server.getPlayers().stream().findFirst().orElse(null); + if (player == null) return; + Vector pos = player.getLocation().toVector(); + Transform transform = holder.getTransform(); + a = WorldEditWrapper.impl.applyTransform(WorldEditWrapper.impl.getMinimum(region).subtract(WorldEditWrapper.impl.getOrigin(holder.getClipboard())), transform).add(pos); + b = WorldEditWrapper.impl.applyTransform(WorldEditWrapper.impl.getMaximum(region).subtract(WorldEditWrapper.impl.getOrigin(holder.getClipboard())), transform).add(pos); + } else { + a = WorldEditWrapper.impl.getMinimum(region); + b = WorldEditWrapper.impl.getMaximum(region); + } + + if (a.equals(lastA) && b.equals(lastB)) { + return; + } + + drawCuboid(server, toBlockVector(a), toBlockVector(b), block); + } + + @Override + public void clear() { + if (bd01 != null) bd01.die(); + if (bd02 != null) bd02.die(); + if (bd03 != null) bd03.die(); + if (bd04 != null) bd04.die(); + if (bd05 != null) bd05.die(); + if (bd06 != null) bd06.die(); + if (bd07 != null) bd07.die(); + if (bd08 != null) bd08.die(); + if (bd09 != null) bd09.die(); + if (bd10 != null) bd10.die(); + if (bd11 != null) bd11.die(); + if (bd12 != null) bd12.die(); + } + + private void drawCuboid(REntityServer server, Vector min, Vector max, BlockData block) { + max.add(new Vector(1 - width, 1 - width, 1 - width)); + + bd01 = drawLine(bd01, server, new Vector(min.getX() - offset, min.getY(), min.getZ()), new Vector(max.getX() + width, min.getY(), min.getZ()), block); + bd02 = drawLine(bd02, server, new Vector(min.getX() - offset, max.getY(), min.getZ()), new Vector(max.getX() + width, max.getY(), min.getZ()), block); + bd03 = drawLine(bd03, server, new Vector(min.getX() - offset, min.getY(), max.getZ()), new Vector(max.getX() + width, min.getY(), max.getZ()), block); + bd04 = drawLine(bd04, server, new Vector(min.getX() - offset, max.getY(), max.getZ()), new Vector(max.getX() + width, max.getY(), max.getZ()), block); + + bd05 = drawLine(bd05, server, new Vector(min.getX(), min.getY() - offset, min.getZ()), new Vector(min.getX(), max.getY() + width, min.getZ()), block); + bd06 = drawLine(bd06, server, new Vector(max.getX(), min.getY() - offset, min.getZ()), new Vector(max.getX(), max.getY() + width, min.getZ()), block); + bd07 = drawLine(bd07, server, new Vector(min.getX(), min.getY() - offset, max.getZ()), new Vector(min.getX(), max.getY() + width, max.getZ()), block); + bd08 = drawLine(bd08, server, new Vector(max.getX(), min.getY() - offset, max.getZ()), new Vector(max.getX(), max.getY() + width, max.getZ()), block); + + bd09 = drawLine(bd09, server, new Vector(min.getX(), min.getY(), min.getZ() - offset), new Vector(min.getX(), min.getY(), max.getZ() + width), block); + bd10 = drawLine(bd10, server, new Vector(max.getX(), min.getY(), min.getZ() - offset), new Vector(max.getX(), min.getY(), max.getZ() + width), block); + bd11 = drawLine(bd11, server, new Vector(min.getX(), max.getY(), min.getZ() - offset), new Vector(min.getX(), max.getY(), max.getZ() + width), block); + bd12 = drawLine(bd12, server, new Vector(max.getX(), max.getY(), min.getZ() - offset), new Vector(max.getX(), max.getY(), max.getZ() + width), block); + } + + private RBlockDisplay drawLine(RBlockDisplay display, REntityServer server, Vector from, Vector to, BlockData block) { + Location spawnLocation = from.clone().add(to).divide(new Vector(2, 2, 2)).toLocation(WORLD); + if (display == null) { + display = new RBlockDisplay(server, spawnLocation); + } + + Vector vector = to.clone().subtract(from); + if (vector.getX() == 0) { + vector.setX(vector.getX() + width + offset * 2); + } + if (vector.getY() == 0) { + vector.setY(vector.getY() + width + offset * 2); + } + if (vector.getZ() == 0) { + vector.setZ(vector.getZ() + width + offset * 2); + } + + Vector transformVec = from.subtract(spawnLocation.toVector()); + transformVec.subtract(new Vector(offset, offset, offset)); + + display.setTransform(new Transformation(toVec3f(transformVec), new Quaternionf(0, 0, 0, 1), toVec3f(vector), new Quaternionf(0, 0, 0, 1))); + display.setBrightness(new Display.Brightness(15, 15)); + display.setBlock(block); + display.move(spawnLocation); + + return display; + } + + private Vector toBlockVector(Vector vector) { + return new Vector(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ()); + } + + private Vector3f toVec3f(Vector vector) { + return new Vector3f((float) vector.getX(), (float) vector.getY(), (float) vector.getZ()); + } +} diff --git a/SpigotCore/SpigotCore_20/src/de/steamwar/core/renderers/RegionRenderer.java b/SpigotCore/SpigotCore_20/src/de/steamwar/core/renderers/RegionRenderer.java new file mode 100644 index 00000000..53121deb --- /dev/null +++ b/SpigotCore/SpigotCore_20/src/de/steamwar/core/renderers/RegionRenderer.java @@ -0,0 +1,47 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.core.renderers; + +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.session.ClipboardHolder; +import de.steamwar.entity.REntityServer; +import org.bukkit.block.data.BlockData; + +public interface RegionRenderer { + + boolean canDisplay(Region region); + void update(REntityServer server, R region, ClipboardHolder holder, BlockData block); + void clear(); + + final class NOOPImpl implements RegionRenderer { + @Override + public boolean canDisplay(Region region) { + return false; + } + + @Override + public void update(REntityServer server, Region region, ClipboardHolder holder, BlockData block) { + } + + @Override + public void clear() { + } + } +} diff --git a/SpigotCore/SpigotCore_8/src/de/steamwar/core/WorldEditRenderer8.java b/SpigotCore/SpigotCore_8/src/de/steamwar/core/WorldEditRenderer8.java new file mode 100644 index 00000000..df3a6633 --- /dev/null +++ b/SpigotCore/SpigotCore_8/src/de/steamwar/core/WorldEditRenderer8.java @@ -0,0 +1,23 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.core; + +public class WorldEditRenderer8 implements WorldEditRenderer { +} diff --git a/SpigotCore/SpigotCore_9/build.gradle.kts b/SpigotCore/SpigotCore_9/build.gradle.kts index a888faf1..c149a3fd 100644 --- a/SpigotCore/SpigotCore_9/build.gradle.kts +++ b/SpigotCore/SpigotCore_9/build.gradle.kts @@ -26,4 +26,5 @@ dependencies { compileOnly(project(":SpigotCore:SpigotCore_8", "default")) compileOnly(libs.nms9) + compileOnly(libs.worldedit12) } diff --git a/SpigotCore/SpigotCore_9/src/de/steamwar/core/WorldEditRenderer9.java b/SpigotCore/SpigotCore_9/src/de/steamwar/core/WorldEditRenderer9.java new file mode 100644 index 00000000..971a759c --- /dev/null +++ b/SpigotCore/SpigotCore_9/src/de/steamwar/core/WorldEditRenderer9.java @@ -0,0 +1,125 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.core; + +import com.sk89q.worldedit.EmptyClipboardException; +import com.sk89q.worldedit.IncompleteRegionException; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.math.transform.Transform; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.regions.RegionSelector; +import com.sk89q.worldedit.world.World; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +public class WorldEditRenderer9 implements WorldEditRenderer { + + private static final int VIEW_DISTANCE = 64; + private static final int SQ_VIEW_DISTANCE = VIEW_DISTANCE * VIEW_DISTANCE; + + private static final double STEP_SIZE = 0.5; + + private static final Vector ONES = new Vector(1, 1, 1); + + private static final Material WAND = FlatteningWrapper.impl.getMaterial("WOOD_AXE"); + + private final WorldEditPlugin we; + + public WorldEditRenderer9() { + we = WorldEditWrapper.getWorldEditPlugin(); + + Bukkit.getScheduler().runTaskTimer(Core.getInstance(), this::render, 20, 20); + } + + private void render() { + for(Player player : Bukkit.getOnlinePlayers()) { + if(player.getInventory().getItemInMainHand().getType() != WAND) + continue; + + LocalSession session = we.getSession(player); + try { + Clipboard clipboard = session.getClipboard().getClipboard(); + Vector pos = player.getLocation().toVector(); + Region region = clipboard.getRegion(); + Transform transform = session.getClipboard().getTransform(); + Vector a = WorldEditWrapper.impl.applyTransform(WorldEditWrapper.impl.getMinimum(region).subtract(WorldEditWrapper.impl.getOrigin(clipboard)), transform).add(pos); + Vector b = WorldEditWrapper.impl.applyTransform(WorldEditWrapper.impl.getMaximum(region).subtract(WorldEditWrapper.impl.getOrigin(clipboard)), transform).add(pos); + drawCuboid(Vector.getMinimum(a, b), Vector.getMaximum(a, b), TrickyParticleWrapper.impl.getVillagerHappy(), player); + } catch (EmptyClipboardException e) { + //ignore + } + + World world = session.getSelectionWorld(); + if(world != null) { + RegionSelector regionSelector = session.getRegionSelector(world); + try { + Region region = regionSelector.getRegion(); + drawCuboid(WorldEditWrapper.impl.getMinimum(region), WorldEditWrapper.impl.getMaximum(region), Particle.DRAGON_BREATH, player); + } catch (IncompleteRegionException e) { + //ignore + } + } + } + } + + private void drawCuboid(Vector min, Vector max, Particle particle, Player owner) { + max.add(ONES); + + for(double x = min.getBlockX(); x <= max.getBlockX(); x += STEP_SIZE) { + draw(x, min.getBlockY(), min.getBlockZ(), particle, owner); + draw(x, min.getBlockY(), max.getBlockZ(), particle, owner); + draw(x, max.getBlockY(), min.getBlockZ(), particle, owner); + draw(x, max.getBlockY(), max.getBlockZ(), particle, owner); + } + + for(double y = min.getBlockY() + STEP_SIZE; y <= max.getBlockY() - STEP_SIZE; y += STEP_SIZE) { + draw(min.getBlockX(), y, min.getBlockZ(), particle, owner); + draw(min.getBlockX(), y, max.getBlockZ(), particle, owner); + draw(max.getBlockX(), y, min.getBlockZ(), particle, owner); + draw(max.getBlockX(), y, max.getBlockZ(), particle, owner); + } + + for(double z = min.getBlockZ() + STEP_SIZE; z <= max.getBlockZ() - STEP_SIZE; z += STEP_SIZE) { + draw(min.getBlockX(), min.getBlockY(), z, particle, owner); + draw(min.getBlockX(), max.getBlockY(), z, particle, owner); + draw(max.getBlockX(), min.getBlockY(), z, particle, owner); + draw(max.getBlockX(), max.getBlockY(), z, particle, owner); + } + } + + private void draw(double x, double y, double z, Particle particle, Player owner) { + for(Player player : Bukkit.getOnlinePlayers()) { + Location location = player.getLocation(); + double dx = x - location.getX(); + double dy = y - location.getY(); + double dz = z - location.getZ(); + if(dx*dx + dy*dy + dz*dz > SQ_VIEW_DISTANCE) + continue; + + player.spawnParticle(player == owner ? particle : org.bukkit.Particle.TOWN_AURA, x, y, z, 1, 0.0, 0.0, 0.0, 0.0); + } + } +} diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/Core.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/Core.java index 4e7b7576..24b207e8 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/Core.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/Core.java @@ -102,8 +102,8 @@ public class Core extends JavaPlugin{ if(Core.getVersion() >= 19) new ServerDataHandler(); - if(Core.getVersion() > 8 && Bukkit.getPluginManager().getPlugin("WorldEdit") != null) - new WorldEditRenderer(); + if(Bukkit.getPluginManager().getPlugin("WorldEdit") != null) + WorldEditRenderer.impl.init(); Bukkit.getScheduler().runTaskTimer(this, TabCompletionCache::invalidateOldEntries, 20, 20); Bukkit.getScheduler().runTaskTimer(Core.getInstance(), SteamwarUser::clear, 72000, 72000); diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/WorldEditRenderer.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/WorldEditRenderer.java index 377efe13..6b90f1d2 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/WorldEditRenderer.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/WorldEditRenderer.java @@ -1,126 +1,27 @@ /* - * This file is a part of the SteamWar software. + * This file is a part of the SteamWar software. * - * Copyright (C) 2024 SteamWar.de-Serverteam + * Copyright (C) 2020 SteamWar.de-Serverteam * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ package de.steamwar.core; -import com.sk89q.worldedit.EmptyClipboardException; -import com.sk89q.worldedit.IncompleteRegionException; -import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.extent.clipboard.Clipboard; -import com.sk89q.worldedit.math.transform.Transform; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.regions.RegionSelector; -import com.sk89q.worldedit.world.World; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; +public interface WorldEditRenderer { + WorldEditRenderer impl = VersionDependent.getVersionImpl(Core.getInstance()); -public class WorldEditRenderer { - - private static final int VIEW_DISTANCE = 64; - private static final int SQ_VIEW_DISTANCE = VIEW_DISTANCE * VIEW_DISTANCE; - - private static final double STEP_SIZE = 0.5; - - private static final Vector ONES = new Vector(1, 1, 1); - - private static final Material WAND = FlatteningWrapper.impl.getMaterial("WOOD_AXE"); - - private final WorldEditPlugin we; - - public WorldEditRenderer() { - we = WorldEditWrapper.getWorldEditPlugin(); - - Bukkit.getScheduler().runTaskTimer(Core.getInstance(), this::render, 20, 20); - } - - private void render() { - for(Player player : Bukkit.getOnlinePlayers()) { - //noinspection deprecation - if(player.getItemInHand().getType() != WAND) - continue; - - LocalSession session = we.getSession(player); - try { - Clipboard clipboard = session.getClipboard().getClipboard(); - Vector pos = player.getLocation().toVector(); - Region region = clipboard.getRegion(); - Transform transform = session.getClipboard().getTransform(); - Vector a = WorldEditWrapper.impl.applyTransform(WorldEditWrapper.impl.getMinimum(region).subtract(WorldEditWrapper.impl.getOrigin(clipboard)), transform).add(pos); - Vector b = WorldEditWrapper.impl.applyTransform(WorldEditWrapper.impl.getMaximum(region).subtract(WorldEditWrapper.impl.getOrigin(clipboard)), transform).add(pos); - drawCuboid(Vector.getMinimum(a, b), Vector.getMaximum(a, b), TrickyParticleWrapper.impl.getVillagerHappy(), player); - } catch (EmptyClipboardException e) { - //ignore - } - - World world = session.getSelectionWorld(); - if(world != null) { - RegionSelector regionSelector = session.getRegionSelector(world); - try { - Region region = regionSelector.getRegion(); - drawCuboid(WorldEditWrapper.impl.getMinimum(region), WorldEditWrapper.impl.getMaximum(region), Particle.DRAGON_BREATH, player); - } catch (IncompleteRegionException e) { - //ignore - } - } - } - } - - private void drawCuboid(Vector min, Vector max, Particle particle, Player owner) { - max.add(ONES); - - for(double x = min.getBlockX(); x <= max.getBlockX(); x += STEP_SIZE) { - draw(x, min.getBlockY(), min.getBlockZ(), particle, owner); - draw(x, min.getBlockY(), max.getBlockZ(), particle, owner); - draw(x, max.getBlockY(), min.getBlockZ(), particle, owner); - draw(x, max.getBlockY(), max.getBlockZ(), particle, owner); - } - - for(double y = min.getBlockY() + STEP_SIZE; y <= max.getBlockY() - STEP_SIZE; y += STEP_SIZE) { - draw(min.getBlockX(), y, min.getBlockZ(), particle, owner); - draw(min.getBlockX(), y, max.getBlockZ(), particle, owner); - draw(max.getBlockX(), y, min.getBlockZ(), particle, owner); - draw(max.getBlockX(), y, max.getBlockZ(), particle, owner); - } - - for(double z = min.getBlockZ() + STEP_SIZE; z <= max.getBlockZ() - STEP_SIZE; z += STEP_SIZE) { - draw(min.getBlockX(), min.getBlockY(), z, particle, owner); - draw(min.getBlockX(), max.getBlockY(), z, particle, owner); - draw(max.getBlockX(), min.getBlockY(), z, particle, owner); - draw(max.getBlockX(), max.getBlockY(), z, particle, owner); - } - } - - private void draw(double x, double y, double z, Particle particle, Player owner) { - for(Player player : Bukkit.getOnlinePlayers()) { - Location location = player.getLocation(); - double dx = x - location.getX(); - double dy = y - location.getY(); - double dz = z - location.getZ(); - if(dx*dx + dy*dy + dz*dz > SQ_VIEW_DISTANCE) - continue; - - player.spawnParticle(player == owner ? particle : Particle.TOWN_AURA, x, y, z, 1, 0.0, 0.0, 0.0, 0.0); - } + default void init() { } }