From d09c3548a78d07744426b05e29b55e6771ffc60d Mon Sep 17 00:00:00 2001 From: yoyosource Date: Tue, 24 Oct 2023 18:11:04 +0200 Subject: [PATCH] Add SimulatorStorage Add SimulatorCursor showing highlighted entity --- .../features/simulator/SimulatorCursor.java | 1 + .../features/simulator2/SimulatorCursor.java | 198 ++++++++++++------ .../features/simulator2/SimulatorStorage.java | 57 +++++ .../simulator2/SimulatorTestCommand.java | 2 +- .../features/simulator2/SimulatorWatcher.java | 8 + .../features/simulator2/world/.gitkeep | 0 6 files changed, 200 insertions(+), 66 deletions(-) create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorStorage.java delete mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/world/.gitkeep diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java index e8fc1bac..eede5d32 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java @@ -44,6 +44,7 @@ public class SimulatorCursor { private Map rEntityServerMap = new HashMap<>(); public void show(Player player, TNTSimulator tntSimulator, RayTraceUtils.RRayTraceResult result) { + if (true) return; REntityServer cursor = rEntityServerMap.get(player); if (cursor != null) diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorCursor.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorCursor.java index 485bcd83..323ef04a 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorCursor.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorCursor.java @@ -22,7 +22,7 @@ package de.steamwar.bausystem.features.simulator2; import com.comphenix.tinyprotocol.Reflection; import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.SWUtils; +import de.steamwar.bausystem.features.simulator2.data.Simulator; import de.steamwar.bausystem.utils.ItemUtils; import de.steamwar.bausystem.utils.RayTraceUtils; import de.steamwar.entity.REntity; @@ -30,6 +30,8 @@ import de.steamwar.entity.REntityServer; import de.steamwar.entity.RFallingBlockEntity; import de.steamwar.linkage.Linked; import de.steamwar.linkage.api.Plain; +import lombok.AllArgsConstructor; +import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; @@ -37,17 +39,13 @@ import org.bukkit.World; import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerDropItemEvent; -import org.bukkit.event.player.PlayerItemHeldEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.*; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import java.util.function.BiFunction; @Linked @@ -58,7 +56,8 @@ public class SimulatorCursor implements Plain, Listener { private Class look = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInLook"); private Class positionLook = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPositionLook"); - private Map cursors = new HashMap<>(); + private Map cursorType = Collections.synchronizedMap(new HashMap<>()); + private Map cursors = Collections.synchronizedMap(new HashMap<>()); public static boolean isSimulatorItem(ItemStack itemStack) { return ItemUtils.isItem(itemStack, "simulator"); @@ -66,17 +65,7 @@ public class SimulatorCursor implements Plain, Listener { public SimulatorCursor() { BiFunction function = (player, object) -> { - if (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand())) { - removeCursor(player); - return object; - } - RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), new ArrayList<>()); - if (rayTraceResult == null) { - removeCursor(player); - return object; - } - - showCursor(player, rayTraceResult); + calcCursor(player); return object; }; TinyProtocol.instance.addFilter(position, function); @@ -86,78 +75,107 @@ public class SimulatorCursor implements Plain, Listener { @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { - Player player = event.getPlayer(); - if (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand())) { - return; - } - RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), new ArrayList<>()); - if (rayTraceResult == null) { - return; - } - - showCursor(player, rayTraceResult); + calcCursor(event.getPlayer()); } @EventHandler public void onPlayerDropItem(PlayerDropItemEvent event) { - Player player = event.getPlayer(); - if (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand())) { - removeCursor(player); - return; - } - RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), new ArrayList<>()); - if (rayTraceResult == null) { - removeCursor(player); - return; - } - - showCursor(player, rayTraceResult); + calcCursor(event.getPlayer()); } @EventHandler public void onPlayerItemHeld(PlayerItemHeldEvent event) { Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { - Player player = event.getPlayer(); - if (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand())) { - removeCursor(player); - return; - } - RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), new ArrayList<>()); - if (rayTraceResult == null) { - removeCursor(player); - return; - } - - showCursor(player, rayTraceResult); + calcCursor(event.getPlayer()); }, 1); } @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { + cursorType.remove(event.getPlayer()); cursors.remove(event.getPlayer()); } - private void removeCursor(Player player) { - cursors.computeIfPresent(player, (player1, rEntityServer) -> { - rEntityServer.close(); - return null; - }); + private static final Map LAST_SNEAKS = new HashMap<>(); + + static { + Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> { + long millis = System.currentTimeMillis(); + LAST_SNEAKS.entrySet().removeIf(entry -> millis - entry.getValue() > 200); + }, 1, 1); } - private void showCursor(Player player, RayTraceUtils.RRayTraceResult rayTraceResult) { + @EventHandler(priority = EventPriority.HIGH) + public void onPlayerToggleSneak(PlayerToggleSneakEvent event) { + if (!event.isSneaking()) return; + Player player = event.getPlayer(); + if (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand())) { + return; + } + if (LAST_SNEAKS.containsKey(player)) { + CursorType type = cursorType.getOrDefault(player, CursorType.TNT).switchType(); + cursorType.put(player, type); + calcCursor(player); + } else { + LAST_SNEAKS.put(player, System.currentTimeMillis()); + } + } + + private void calcCursor(Player player) { + if (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand())) { + removeCursor(player); + return; + } + Simulator simulator = SimulatorStorage.getSimulator(player); + List entities = SimulatorWatcher.getEntitiesOfSimulator(simulator); + RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), entities); + if (rayTraceResult == null) { + removeCursor(player); + return; + } + + showCursor(player, rayTraceResult); + } + + private void removeCursor(Player player) { + REntityServer entityServer = cursors.get(player); + if (entityServer != null) { + entityServer.getEntities().forEach(REntity::die); + } + } + + private synchronized void showCursor(Player player, RayTraceUtils.RRayTraceResult rayTraceResult) { REntityServer entityServer = cursors.computeIfAbsent(player, __ -> { REntityServer rEntityServer = new REntityServer(); rEntityServer.addPlayer(player); - RFallingBlockEntity rFallingBlockEntity = new RFallingBlockEntity(rEntityServer, new Location(WORLD, 0, 0, 0, 0, 0), Material.GLASS); - rFallingBlockEntity.setNoGravity(true); return rEntityServer; }); - entityServer.getEntities().forEach(rEntity -> { - rEntity.move(getPos(player, rayTraceResult).toLocation(WORLD)); + + CursorType type = cursorType.getOrDefault(player, CursorType.TNT); + REntity hitEntity = rayTraceResult.getHitEntity(); + Location location = hitEntity != null ? new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ()).toLocation(WORLD) : + type.position.apply(player, rayTraceResult).toLocation(WORLD); + + Material material = hitEntity != null ? Material.GLASS : type.getMaterial(); + List entities = entityServer.getEntitiesByType(RFallingBlockEntity.class); + entities.removeIf(rFallingBlockEntity -> { + if (rFallingBlockEntity.getMaterial() != material) { + rFallingBlockEntity.die(); + return true; + } + rFallingBlockEntity.move(location); + return false; }); + if (entities.isEmpty()) { + RFallingBlockEntity rFallingBlockEntity = new RFallingBlockEntity(entityServer, location, material); + rFallingBlockEntity.setNoGravity(true); + if (material == Material.GLASS) { + rFallingBlockEntity.setGlowing(true); + } + } } - public static Vector getPos(Player player, RayTraceUtils.RRayTraceResult result) { + public static Vector getPosTNT(Player player, RayTraceUtils.RRayTraceResult result) { Vector pos = result.getHitPosition(); BlockFace face = result.getHitBlockFace(); @@ -196,4 +214,54 @@ public class SimulatorCursor implements Plain, Listener { return pos; } + + private static Vector getPosRedstoneBlock(Player player, RayTraceUtils.RRayTraceResult result) { + Vector pos = result.getHitPosition(); + + BlockFace face = result.getHitBlockFace(); + if (face != null) { + switch (face) { + case DOWN: + pos.setY(pos.getY() - 0.98); + break; + case EAST: + pos.setX(pos.getX() + 0.49); + break; + case WEST: + pos.setX(pos.getX() - 0.49); + break; + case NORTH: + pos.setZ(pos.getZ() - 0.49); + break; + case SOUTH: + pos.setZ(pos.getZ() + 0.49); + break; + default: + break; + } + } + + pos.setX(pos.getBlockX() + 0.5); + pos.setY(pos.getBlockY()); + pos.setZ(pos.getBlockZ() + 0.5); + return pos; + } + + @Getter + @AllArgsConstructor + public enum CursorType { + TNT(Material.TNT, SimulatorCursor::getPosTNT), + REDSTONE_BLOCK(Material.REDSTONE_BLOCK, SimulatorCursor::getPosRedstoneBlock), + ; + + private Material material; + private BiFunction position; + + public CursorType switchType() { + if (this == TNT) { + return REDSTONE_BLOCK; + } + return TNT; + } + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorStorage.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorStorage.java new file mode 100644 index 00000000..a4b7b7e6 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorStorage.java @@ -0,0 +1,57 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 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.bausystem.features.simulator2; + +import de.steamwar.bausystem.SWUtils; +import de.steamwar.bausystem.features.simulator2.data.Simulator; +import de.steamwar.bausystem.utils.ItemUtils; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.Map; + +public class SimulatorStorage { + + private static Map simulatorMap = new HashMap<>(); + private static NamespacedKey simulatorSelection = SWUtils.getNamespaceKey("simulator_selection"); + + public static Simulator getSimulator(Player player) { + Simulator simulator = getSimulator(player.getInventory().getItemInMainHand()); + if (simulator != null) return simulator; + return getSimulator(player.getInventory().getItemInOffHand()); + } + + public static Simulator getSimulator(ItemStack itemStack) { + if (!SimulatorCursor.isSimulatorItem(itemStack)) { + return null; + } + String selection = ItemUtils.getTag(itemStack, simulatorSelection); + if (selection == null) { + return null; + } + return simulatorMap.computeIfAbsent(selection, SimulatorStorage::loadSimulator); + } + + private static Simulator loadSimulator(String name) { + return SimulatorTestCommand.SIMULATOR; // TODO: Implement Loading and legacy Loading + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorTestCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorTestCommand.java index d7f8a766..4a739a77 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorTestCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorTestCommand.java @@ -36,7 +36,7 @@ import org.bukkit.util.Vector; @Linked public class SimulatorTestCommand extends SWCommand { - private static final Simulator SIMULATOR = new Simulator("TestSim"); + static final Simulator SIMULATOR = new Simulator("TestSim"); public SimulatorTestCommand() { super("simtest"); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorWatcher.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorWatcher.java index 8bc0d8c6..b15e6889 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorWatcher.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorWatcher.java @@ -111,4 +111,12 @@ public class SimulatorWatcher { return rEntityServer.getPlayers().isEmpty() ? null : rEntityServer; }); } + + List getEntitiesOfSimulator(Simulator simulator) { + REntityServer entityServer = entityServers.get(simulator); + if (entityServer == null) { + return Collections.emptyList(); + } + return entityServer.getEntities(); + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/world/.gitkeep b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/world/.gitkeep deleted file mode 100644 index e69de29b..00000000