From cfd625c6f097fedaef90fc9750eef07e9ae81a0a Mon Sep 17 00:00:00 2001 From: yoyosource Date: Thu, 13 Apr 2023 19:52:56 +0200 Subject: [PATCH 1/5] Remove sout Signed-off-by: yoyosource --- .../de/steamwar/bausystem/features/tracer/record/Recorder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/Recorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/Recorder.java index fe941f5f..8b3fcea0 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/Recorder.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/Recorder.java @@ -190,7 +190,6 @@ public class Recorder implements Listener { TraceRecorder traceRecorder = get((TNTPrimed) entity); Region region = tntTraceRecorderMap.get((TNTPrimed) entity); boolean inBuildRegion = event.blockList().stream().anyMatch(block -> region.inRegion(block.getLocation(), RegionType.BUILD, RegionExtensionType.EXTENSION)); - System.out.println(event.blockList() + " " + inBuildRegion); traceRecorder.explode((TNTPrimed) entity, inBuildRegion); tntTraceRecorderMap.remove(entity); tick(); From e60ae56b67e1c6522192816afdf51ec45d5fee1d Mon Sep 17 00:00:00 2001 From: yoyosource Date: Fri, 14 Apr 2023 18:43:59 +0200 Subject: [PATCH 2/5] Fix TPSLimit 0 Signed-off-by: yoyosource --- .../features/tpslimit/FreezeUtils.java | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/FreezeUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/FreezeUtils.java index b9a24ad1..c3c12fa9 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/FreezeUtils.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/FreezeUtils.java @@ -20,13 +20,27 @@ package de.steamwar.bausystem.features.tpslimit; import com.comphenix.tinyprotocol.Reflection; +import com.comphenix.tinyprotocol.TinyProtocol; +import de.steamwar.bausystem.BauSystem; +import de.steamwar.core.BountifulWrapper; +import de.steamwar.core.ChatWrapper; import lombok.Getter; import lombok.experimental.UtilityClass; import org.bukkit.Bukkit; import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; import yapion.utils.ReflectionsUtils; import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; @UtilityClass public class FreezeUtils { @@ -64,10 +78,84 @@ public class FreezeUtils { if (freezeEnabled) { try { field.set(getWorldHandle.invoke(world), state); + cacheEntityPackets(state); frozen = state; } catch (IllegalAccessException e) { // Ignored; } } } + + private List packets = new ArrayList<>(); + private Set entities = new HashSet<>(); + private BukkitTask task = null; + + private Class vec3dClass = Reflection.getClass("{nms.world.phys}.Vec3D"); + private Reflection.FieldAccessor zeroVec3d = (Reflection.FieldAccessor) Reflection.getField(vec3dClass, vec3dClass, 0); + private Object ZERO_VEC3D = zeroVec3d.get(null); + private Class velocityPacketClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityVelocity"); + private Reflection.ConstructorInvoker velocityPacketConstructor = Reflection.getConstructor(velocityPacketClass, int.class, vec3dClass); + + private Class teleportPacketClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityTeleport"); + private Class entityClass = Reflection.getClass("{nms.world.entity}.Entity"); + private Reflection.ConstructorInvoker teleportPacketConstructor = Reflection.getConstructor(teleportPacketClass, entityClass); + + private Class craftEntityClass = Reflection.getClass("{obc}.entity.CraftEntity"); + private Reflection.MethodInvoker getHandle = Reflection.getMethod(craftEntityClass, "getHandle"); + + private Object noGravityDataWatcher = BountifulWrapper.impl.getDataWatcherObject(5, Boolean.class); + private Object fuseDataWatcher = BountifulWrapper.impl.getDataWatcherObject(8, Integer.class); + + private void cacheEntityPackets(boolean state) { + if (state) { + createPackets(); + + if (task == null) { + task = new BukkitRunnable() { + @Override + public void run() { + createPackets(); + + for (Player player : Bukkit.getOnlinePlayers()) { + for (Object packet : packets) { + TinyProtocol.instance.sendPacket(player, packet); + } + } + } + }.runTaskTimer(BauSystem.getInstance(), 1, 1); + } + } else { + packets.clear(); + entities.clear(); + + if (task != null) { + task.cancel(); + task = null; + } + } + } + + private void createPackets() { + List entities = Bukkit.getWorlds().get(0).getEntities().stream() + .filter(e -> !(e instanceof Player)) + .filter(e -> !FreezeUtils.entities.contains(e)) + .collect(Collectors.toList()); + + for (Entity entity : entities) { + packets.add(teleportPacketConstructor.invoke(getHandle.invoke(entity))); + } + for (Entity entity : entities) { + packets.add(velocityPacketConstructor.invoke(entity.getEntityId(), ZERO_VEC3D)); + } + for (Entity entity : entities) { + packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), noGravityDataWatcher, true)); + } + for (Entity entity : entities) { + if (!(entity instanceof TNTPrimed)) continue; + TNTPrimed tnt = (TNTPrimed) entity; + packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), fuseDataWatcher, tnt.getFuseTicks())); + } + + FreezeUtils.entities.addAll(entities); + } } From 3c1275393fd4644e532bb7efbf8faf3eb81af41a Mon Sep 17 00:00:00 2001 From: yoyosource Date: Fri, 14 Apr 2023 18:45:00 +0200 Subject: [PATCH 3/5] Hotfix Memory Leak Signed-off-by: yoyosource --- .../de/steamwar/bausystem/features/tpslimit/FreezeUtils.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/FreezeUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/FreezeUtils.java index c3c12fa9..bdb00e1a 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/FreezeUtils.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/FreezeUtils.java @@ -136,6 +136,10 @@ public class FreezeUtils { } private void createPackets() { + if (FreezeUtils.entities.stream().anyMatch(Entity::isDead)) { + entities.clear(); + packets.clear(); + } List entities = Bukkit.getWorlds().get(0).getEntities().stream() .filter(e -> !(e instanceof Player)) .filter(e -> !FreezeUtils.entities.contains(e)) From 3f5f4d7b80c26d71d19b2df3374fd3874b835505 Mon Sep 17 00:00:00 2001 From: yoyosource Date: Sun, 16 Apr 2023 11:26:09 +0200 Subject: [PATCH 4/5] Remove tnt flicker Signed-off-by: yoyosource --- .../de/steamwar/bausystem/features/tpslimit/FreezeUtils.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/FreezeUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/FreezeUtils.java index bdb00e1a..294cffd0 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/FreezeUtils.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/FreezeUtils.java @@ -157,7 +157,8 @@ public class FreezeUtils { for (Entity entity : entities) { if (!(entity instanceof TNTPrimed)) continue; TNTPrimed tnt = (TNTPrimed) entity; - packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), fuseDataWatcher, tnt.getFuseTicks())); + int fuse = tnt.getFuseTicks(); + packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), fuseDataWatcher, fuse - (fuse % 5) + 1)); } FreezeUtils.entities.addAll(entities); From e9d7c8211f78d9898cb9bc04dee8ee6b3596aa91 Mon Sep 17 00:00:00 2001 From: yoyosource Date: Sun, 16 Apr 2023 12:11:43 +0200 Subject: [PATCH 5/5] Add ShieldPrinting Signed-off-by: yoyosource --- BauSystem_Main/src/BauSystem.properties | 10 ++ BauSystem_Main/src/BauSystem_de.properties | 10 ++ .../shieldprinting/ShieldPrinting.java | 101 ++++++++++++++++ .../shieldprinting/ShieldPrintingCommand.java | 110 ++++++++++++++++++ .../shieldprinting/ShieldPrintingState.java | 27 +++++ 5 files changed, 258 insertions(+) create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrintingCommand.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrintingState.java diff --git a/BauSystem_Main/src/BauSystem.properties b/BauSystem_Main/src/BauSystem.properties index 892091c3..27f1c19d 100644 --- a/BauSystem_Main/src/BauSystem.properties +++ b/BauSystem_Main/src/BauSystem.properties @@ -509,6 +509,16 @@ SCRIPT_GUI_CONSTANT_TPS_LORE = §etps§7 of the server SCRIPT_GUI_CONSTANT_TPS_LIMIT_NAME = §7Constant §etps_limit SCRIPT_GUI_CONSTANT_TPS_LIMIT_LORE = §etps_limit§7 of the server +# Shield Printing +SHIELD_PRINTING_NO_REGION = §cYou are not in a region. +SHIELD_PRINTING_NOT_RUNNING = §cThe shield printing is not running. +SHIELD_PRINTING_DISALLOWED = §cYou are not allowed to use shield printing here. + +SHIELD_PRINTING_START = §aThe shield printing has been started. +SHIELD_PRINTING_COPY = §aThe shield has been copied. +SHIELD_PRINTING_APPLY = §aThe shield has been applied. +SHIELD_PRINTING_STOP = §aThe shield printing has been stopped. + # Unsign Book UNSIGN_HELP=§8/§eunsign §8- §7Make a signed book writable again diff --git a/BauSystem_Main/src/BauSystem_de.properties b/BauSystem_Main/src/BauSystem_de.properties index d08d7d41..a1461a99 100644 --- a/BauSystem_Main/src/BauSystem_de.properties +++ b/BauSystem_Main/src/BauSystem_de.properties @@ -502,6 +502,16 @@ SCRIPT_GUI_CONSTANT_TPS_LORE = §etps§7 vom Server SCRIPT_GUI_CONSTANT_TPS_LIMIT_NAME = §7Constant §etps_limit SCRIPT_GUI_CONSTANT_TPS_LIMIT_LORE = §etps_limit§7 vom Server +# Shield Printing +SHIELD_PRINTING_NO_REGION = §cDu bist in keiner Region. +SHIELD_PRINTING_NOT_RUNNING = §cShield printing ist nicht aktiv. +SHIELD_PRINTING_DISALLOWED = §cDu darfst Shield printing nicht benutzen. + +SHIELD_PRINTING_START = §aShield printing wurde gestartet. +SHIELD_PRINTING_COPY = §aSchilde wurden kopiert. +SHIELD_PRINTING_APPLY = §aSchilde wurden angewendet. +SHIELD_PRINTING_STOP = §aShield printing wurde gestoppt. + # Unsign Book UNSIGN_HELP=§8/§eunsign §8- §7Mache ein Buch beschreibbar diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java b/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java new file mode 100644 index 00000000..9cf829b5 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java @@ -0,0 +1,101 @@ +/* + * 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.shieldprinting; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.region.Region; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.BlockData; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPistonExtendEvent; +import org.bukkit.event.block.BlockPistonRetractEvent; +import org.bukkit.util.Vector; + +import java.util.*; + +public class ShieldPrinting implements Listener { + + private static final World WORLD = Bukkit.getWorlds().get(0); + + /** + * Vector of current position, Vector of origin + */ + private Map shieldMap = new HashMap<>(); + private Map shieldData = new HashMap<>(); + + private final Region region; + + public ShieldPrinting(Region region) { + this.region = region; + Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance()); + } + + public void copy() { + for (Map.Entry entry : shieldMap.entrySet()) { + shieldData.put(entry.getValue(), entry.getKey().toLocation(WORLD).getBlock().getBlockData()); + } + } + + public void apply() { + for (Map.Entry entry : shieldData.entrySet()) { + entry.getKey().toLocation(WORLD).getBlock().setBlockData(entry.getValue()); + } + } + + public void disable() { + BlockPistonExtendEvent.getHandlerList().unregister(this); + BlockPistonRetractEvent.getHandlerList().unregister(this); + shieldMap.clear(); + shieldData.clear(); + } + + @EventHandler + public void onBlockPistonExtend(BlockPistonExtendEvent event) { + update(event.getDirection(), event.getBlocks()); + } + + @EventHandler + public void onBlockPistonRetract(BlockPistonRetractEvent event) { + update(event.getDirection(), event.getBlocks()); + } + + private void update(BlockFace direction, List blockList) { + Set toRemove = new HashSet<>(); + Map temp = new HashMap<>(); + for (Block block : blockList) { + if (Region.getRegion(block.getLocation()) != region) continue; + Vector vector = block.getLocation().toVector(); + Vector origin = vector.clone(); + vector = vector.add(direction.getDirection()); + if (shieldMap.containsKey(origin)) { + toRemove.add(origin); + temp.put(vector, shieldMap.get(origin)); + } else { + temp.put(vector, origin); + } + } + shieldMap.keySet().removeAll(toRemove); + shieldMap.putAll(temp); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrintingCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrintingCommand.java new file mode 100644 index 00000000..a789c748 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrintingCommand.java @@ -0,0 +1,110 @@ +/* + * 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.shieldprinting; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.region.Region; +import de.steamwar.command.SWCommand; +import de.steamwar.command.TypeValidator; +import de.steamwar.linkage.Linked; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.Map; + +@Linked +public class ShieldPrintingCommand extends SWCommand { + + public ShieldPrintingCommand() { + super("shieldprinting"); + } + + private Map shieldMap = new HashMap<>(); + + @Register + public void genericCommand(@Validator Player player, ShieldPrintingState shieldPrintingState) { + Region region = Region.getRegion(player.getLocation()); + if (region.isGlobal()) { + // BauSystem.MESSAGE.send("SHIELD_PRINTING_NO_REGION", player); + return; + } + ShieldPrinting shieldPrinting; + switch (shieldPrintingState) { + case START: + shieldPrinting = shieldMap.put(region, new ShieldPrinting(region)); + if (shieldPrinting != null) { + shieldPrinting.disable(); + } + BauSystem.MESSAGE.send("SHIELD_PRINTING_START", player); + break; + case COPY: + shieldPrinting = shieldMap.get(region); + if (shieldPrinting == null) { + BauSystem.MESSAGE.send("SHIELD_PRINTING_NOT_RUNNING", player); + return; + } + shieldPrinting.copy(); + BauSystem.MESSAGE.send("SHIELD_PRINTING_COPY", player); + break; + case APPLY: + shieldPrinting = shieldMap.get(region); + if (shieldPrinting == null) { + BauSystem.MESSAGE.send("SHIELD_PRINTING_NOT_RUNNING", player); + return; + } + shieldPrinting.apply(); + BauSystem.MESSAGE.send("SHIELD_PRINTING_APPLY", player); + break; + } + } + + @Register("stop") + public void stopCommand(@Validator Player player) { + Region region = Region.getRegion(player.getLocation()); + if (region.isGlobal()) { + BauSystem.MESSAGE.send("SHIELD_PRINTING_NO_REGION", player); + return; + } + ShieldPrinting shieldPrinting = shieldMap.remove(region); + if (shieldPrinting == null) { + BauSystem.MESSAGE.send("SHIELD_PRINTING_NOT_RUNNING", player); + return; + } + shieldPrinting.disable(); + BauSystem.MESSAGE.send("SHIELD_PRINTING_STOP", player); + } + + @ClassValidator(value = Player.class, local = true) + public TypeValidator validator() { + return (commandSender, player, messageSender) -> { + if (!Permission.hasPermission(player, Permission.WORLD)) { + messageSender.send("SHIELD_PRINTING_DISALLOWED", player); + return false; + } + Region region = Region.getRegion(player.getLocation()); + if (region.isGlobal()) { + messageSender.send("SHIELD_PRINTING_NO_REGION", player); + return false; + } + return true; + }; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrintingState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrintingState.java new file mode 100644 index 00000000..0f782f67 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrintingState.java @@ -0,0 +1,27 @@ +/* + * 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.shieldprinting; + +public enum ShieldPrintingState { + + START, + COPY, + APPLY +}