SteamWar/BauSystem2.0
Archiviert
12
0

Merge branch 'master' into SkullCommand
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Dieser Commit ist enthalten in:
YoyoNow 2023-04-21 18:49:37 +02:00
Commit 5019f79b67
32 geänderte Dateien mit 1287 neuen und 112 gelöschten Zeilen

Datei anzeigen

@ -28,6 +28,7 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.*;
import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.server.level.PlayerInteractManager;
import net.minecraft.world.level.EnumGamemode;
import net.minecraft.world.phys.Vec3D;
@ -44,7 +45,6 @@ import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.LongSupplier;
public class NMSWrapper19 implements NMSWrapper {
@ -91,7 +91,9 @@ public class NMSWrapper19 implements NMSWrapper {
if (entity instanceof TNTPrimed) {
net.minecraft.world.entity.Entity serverEntity = ((CraftEntity) entity).getHandle();
packets.add(new PacketPlayOutEntityMetadata(serverEntity.ah(), Objects.requireNonNull(serverEntity.al().c())));
List<DataWatcher.b<?>> list = serverEntity.al().c();
if(list != null)
packets.add(new PacketPlayOutEntityMetadata(serverEntity.ah(), list));
}
});
}

Datei anzeigen

@ -21,19 +21,60 @@ package de.steamwar.bausystem.utils;
import net.minecraft.network.protocol.game.PacketPlayInFlying;
import net.minecraft.server.level.EntityPlayer;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class PlayerMovementWrapper19 implements PlayerMovementWrapper {
private static class Position {
private double x;
private double y;
private double z;
private float yaw;
private float pitch;
}
private Map<UUID, Position> playerLocationMap = new HashMap<>();
@Override
public void setPosition(Player player, Object object) {
Position position = playerLocationMap.computeIfAbsent(player.getUniqueId(), uuid -> {
Position pos = new Position();
Location location = player.getLocation();
pos.x = location.getX();
pos.y = location.getY();
pos.z = location.getZ();
pos.yaw = location.getYaw();
pos.pitch = location.getPitch();
return pos;
});
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
if (packetPlayInFlying.h) {
entityPlayer.b(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c, packetPlayInFlying.d, packetPlayInFlying.e);
position.x = packetPlayInFlying.a;
position.y = packetPlayInFlying.b;
position.z = packetPlayInFlying.c;
position.yaw = packetPlayInFlying.d;
position.pitch = packetPlayInFlying.e;
} else {
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
position.x = packetPlayInFlying.a;
position.y = packetPlayInFlying.b;
position.z = packetPlayInFlying.c;
}
}
@Override
public void disable(Player player) {
Position position = playerLocationMap.remove(player.getUniqueId());
if (position != null) {
player.teleport(new Location(player.getWorld(), position.x, position.y, position.z, position.yaw, position.pitch));
}
}
}

Datei anzeigen

@ -509,6 +509,18 @@ 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_BOSSBAR = §fMovements: {0}
SHIELD_PRINTING_BOSSBAR_COPIED = §fMovements: {0} Copied: {1}
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
@ -655,8 +667,10 @@ INVENTORY_FILL_DISABLE = §cInventoryFiller deactivated
KILLCHECKER_HELP_ENABLE = §8/§ekillchecker enable §8- §7Enables Killchecker / Recalculates kills
KILLCHECKER_HELP_DISABLE = §8/§ekillchecker disable §8- §7Disables Killchecker
KILLCHECKER_INFO = §7Shows the overlaps of cannon kills in your build area.
KILLCHECKER_INFO2 = §7Only colorable blocks like Wool, Terractotta, Stained Glass and Concrete are counted.
KILLCHECKER_ENABLE = §aKillchecker activated
KILLCHECKER_DISABLE = §cKillchecker deactivated
KILLCHECKER_BOSSBAR = §e§l{0} §7(§e{1}%§7) §e§l{2}§7 cannons
# BlockCounter
BLOCK_COUNTER_HELP_TOGGLE = §8/§eblockcounter §8- §7Toggle on/off
@ -918,6 +932,8 @@ SKULL_GUI_ITEM_NAME = §ePlayer Heads
ANVIL_INV_NAME=Player name
# StructureVoid
STRUCTURE_VOID_COMMAND_HELP=§8/§estructureVoid §8-§7 Receive a StructureVoid
# Dragon Egg
DRAGON_EGG_COMMAND_HELP=§8/§edragonegg §8-§7 Receive a Dragon Egg
# NightVision
NIGHT_VISION_HELP=§8/§enightvision §8-§7 Toggel nightvision.
NIGHT_VISION_OFF=§eNightvision deactivated

Datei anzeigen

@ -502,6 +502,18 @@ 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_BOSSBAR = §fBewegungen: {0}
SHIELD_PRINTING_BOSSBAR_COPIED = §fBewegungen: {0} Kopiert: {1}
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
@ -628,8 +640,10 @@ INVENTORY_FILL_DISABLE = §cInventoryFiller deactivated
KILLCHECKER_HELP_ENABLE = §8/§ekillchecker enable §8- §7Aktiviert Killchecker / Berechnet kills neu
KILLCHECKER_HELP_DISABLE = §8/§ekillchecker disable §8- §7Deaktiviert Killchecker
KILLCHECKER_INFO = §7Zeigt Überlappungen der Kanonen Kills im Baubereich an.
KILLCHECKER_INFO2 = §7Nur farbige Blöcke wie Wolle, Terracotta, Stained Glass und Concrete wird gezählt.
KILLCHECKER_ENABLE = §aKillchecker aktiviert
KILLCHECKER_DISABLE = §cKillchecker deaktiviert
KILLCHECKER_BOSSBAR = §e§l{0} §7(§e{1}%§7) §e§l{2}§7 Kanonnen
# BlockCounter
BLOCK_COUNTER_HELP_TOGGLE = §8/§eblockcounter §8- §7Wechsel zwischen an und aus
@ -889,6 +903,8 @@ SKULL_GUI_ITEM_NAME = §eSpieler Köpfe
ANVIL_INV_NAME=Spieler name
# StructureVoid
STRUCTURE_VOID_COMMAND_HELP=§8/§estructureVoid §8-§7 Erhalte ein StructureVoid
# Dragon Egg
DRAGON_EGG_COMMAND_HELP=§8/§edragonegg §8-§7 Erhalte ein Drachenei
# NightVision
NIGHT_VISION_HELP=§8/§enightvision §8-§7 Schalte Nightvision an oder aus.
NIGHT_VISION_OFF=§eNightvision deaktiviert

Datei anzeigen

@ -0,0 +1,34 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.killchecker;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Cuboid {
private double x;
private double y;
private double z;
private double dx;
private double dy;
private double dz;
}

Datei anzeigen

@ -21,8 +21,10 @@ package de.steamwar.bausystem.features.killchecker;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.utils.bossbar.BossBarService;
import de.steamwar.command.SWCommand;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.LinkedInstance;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
@ -42,17 +44,21 @@ public class KillcheckerCommand extends SWCommand implements Listener {
private Map<Region, KillcheckerVisualizer> visualizers = new HashMap<>();
@LinkedInstance
public BossBarService bossBarService;
public KillcheckerCommand() {
super("killchecker");
addDefaultHelpMessage("KILLCHECKER_INFO");
addDefaultHelpMessage("KILLCHECKER_INFO2");
}
@Register(value = "enable", description = "KILLCHECKER_HELP_ENABLE")
public void genericCommand(Player player) {
public void genericCommand(Player player, @OptionalValue("-outline") @StaticValue(value = {"-area", "-outline"}, allowISE = true) boolean onlyOutline) {
Region region = Region.getRegion(player.getLocation());
KillcheckerVisualizer killcheckerVisualizer = visualizers.computeIfAbsent(region, KillcheckerVisualizer::new);
KillcheckerVisualizer killcheckerVisualizer = visualizers.computeIfAbsent(region, region1 -> new KillcheckerVisualizer(region1, bossBarService));
killcheckerVisualizer.recalc();
killcheckerVisualizer.show(player);
killcheckerVisualizer.show(player, onlyOutline);
BauSystem.MESSAGE.send("KILLCHECKER_ENABLE", player);
}
@ -73,7 +79,7 @@ public class KillcheckerCommand extends SWCommand implements Listener {
Player player = event.getPlayer();
Set<Region> regions = new HashSet<>();
visualizers.forEach((region, visualizer) -> {
if (visualizer.hide(player)) {
if (visualizer.disconnect(player)) {
regions.add(region);
}
});

Datei anzeigen

@ -19,11 +19,13 @@
package de.steamwar.bausystem.features.killchecker;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.region.Point;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.utils.RegionExtensionType;
import de.steamwar.bausystem.region.utils.RegionType;
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
import de.steamwar.bausystem.utils.bossbar.BossBarService;
import de.steamwar.entity.REntity;
import de.steamwar.entity.REntityServer;
import de.steamwar.entity.RFallingBlockEntity;
@ -31,6 +33,9 @@ import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.entity.Player;
import java.util.HashMap;
@ -40,33 +45,59 @@ import java.util.Set;
public class KillcheckerVisualizer {
private static final Material[] materials = new Material[] {Material.YELLOW_STAINED_GLASS, Material.ORANGE_STAINED_GLASS, Material.RED_STAINED_GLASS, Material.PURPLE_STAINED_GLASS, Material.BLACK_STAINED_GLASS};
private static final Material[] MATERIALS = new Material[] {Material.YELLOW_STAINED_GLASS, Material.ORANGE_STAINED_GLASS, Material.RED_STAINED_GLASS, Material.PURPLE_STAINED_GLASS, Material.BLACK_STAINED_GLASS};
private static final World WORLD = Bukkit.getWorlds().get(0);
private Point minPoint;
private Point maxPoint;
private static final double SURROUND = 4;
private final Point minPoint;
private final Point maxPoint;
private Set<Player> players = new HashSet<>();
private final int yArea;
private final int zArea;
private final int xArea;
public KillcheckerVisualizer(Region region) {
private final Set<Player> players = new HashSet<>();
private final Set<Player> areaPlayers = new HashSet<>();
private final Region region;
private final BossBarService bossBarService;
public KillcheckerVisualizer(Region region, BossBarService bossBarService) {
this.region = region;
this.minPoint = region.getMinPoint(RegionType.BUILD, RegionExtensionType.NORMAL);
this.maxPoint = region.getMaxPoint(RegionType.BUILD, RegionExtensionType.NORMAL);
yArea = (maxPoint.getX() - minPoint.getX()) * (maxPoint.getZ() - minPoint.getZ());
zArea = (maxPoint.getX() - minPoint.getX()) * (maxPoint.getY() - minPoint.getY());
xArea = (maxPoint.getY() - minPoint.getY()) * (maxPoint.getZ() - minPoint.getZ());
this.bossBarService = bossBarService;
}
private REntityServer rEntityServer = new REntityServer();
private final REntityServer outline = new REntityServer();
private final REntityServer inner = new REntityServer();
private Map<Point, Integer> killCount = new HashMap<>();
private Map<Point, REntity> rEntities = new HashMap<>();
private final Map<Point, Integer> killCount = new HashMap<>();
private final Set<Point> outlinePointsCache = new HashSet<>();
private final Map<Point, REntity> rEntities = new HashMap<>();
private double percent = 0;
private int kills = 0;
private int cannonCount = 0;
public void recalc() {
Set<Cuboid> cuboids = new HashSet<>();
Set<Point> points = new HashSet<>();
for (int x = minPoint.getX() + 1; x < maxPoint.getX() - 1; x++) {
for (int x = minPoint.getX() + 1; x < maxPoint.getX(); x++) {
for (int y = minPoint.getY(); y < maxPoint.getY(); y++) {
for (int z = minPoint.getZ() + 1; z < maxPoint.getZ() - 1; z++) {
for (int z = minPoint.getZ() + 1; z < maxPoint.getZ(); z++) {
if (points.contains(new Point(x, y, z))) continue;
Block block = WORLD.getBlockAt(x, y, z);
if (block.getType().isAir()) continue;
String name = block.getType().name();
if (!name.endsWith("_WOOL") && !name.endsWith("_STAINED_GLASS") && !name.endsWith("_CONCRETE") && !name.endsWith("_TERRACOTTA")) continue;
if (name.equals("_GLAZED_TERRACOTTA")) continue;
Cuboid cuboid = create(block.getType(), x, y, z);
cuboids.add(cuboid);
for (int dx = (int) cuboid.getX(); dx <= cuboid.getDx(); dx++) {
@ -79,60 +110,162 @@ public class KillcheckerVisualizer {
}
}
}
cannonCount = cuboids.size();
Map<Point, Integer> kill = new HashMap<>();
for (int x = minPoint.getX(); x < maxPoint.getX(); x++) {
for (int z = minPoint.getZ(); z < maxPoint.getZ(); z++) {
int yKills = 0;
int yCount = 0;
Set<Point> yPoints = new HashSet<>();
for (int x = minPoint.getX(); x <= maxPoint.getX(); x++) {
for (int z = minPoint.getZ(); z <= maxPoint.getZ(); z++) {
Set<Cuboid> cuboidSet = new HashSet<>();
for (Cuboid cuboid : cuboids) {
if (x >= cuboid.getX() - 3.5 && x <= cuboid.getDx() + 3.5 && z >= cuboid.getZ() - 3.5 && z <= cuboid.getDz() + 3.5) {
if (x >= cuboid.getX() - SURROUND && x < cuboid.getDx() + SURROUND && z >= cuboid.getZ() - SURROUND && z < cuboid.getDz() + SURROUND) {
cuboidSet.add(cuboid);
}
}
if (cuboidSet.size() > 1) {
Point p1 = new Point(x, minPoint.getY(), z);
kill.put(p1, Math.max(kill.getOrDefault(p1, 0), cuboidSet.size()));
Point p2 = new Point(x, maxPoint.getY(), z);
yCount++;
yKills += splitIntoDoubleKills(cuboidSet.size());
Point p2 = new Point(x, maxPoint.getY() + 1, z);
yPoints.add(p2);
kill.put(p2, Math.max(kill.getOrDefault(p2, 0), cuboidSet.size()));
}
}
}
for (int y = minPoint.getY(); y < maxPoint.getY(); y++) {
for (int z = minPoint.getZ(); z < maxPoint.getZ(); z++) {
int xKills = 0;
int xCount = 0;
Set<Point> xPoints = new HashSet<>();
for (int y = minPoint.getY(); y <= maxPoint.getY(); y++) {
for (int z = minPoint.getZ(); z <= maxPoint.getZ(); z++) {
Set<Cuboid> cuboidSet = new HashSet<>();
for (Cuboid cuboid : cuboids) {
if (y >= cuboid.getY() - 3.5 && y <= cuboid.getDy() + 3.5 && z >= cuboid.getZ() - 3.5 && z <= cuboid.getDz() + 3.5) {
if (y >= cuboid.getY() - SURROUND && y < cuboid.getDy() + SURROUND && z >= cuboid.getZ() - SURROUND && z < cuboid.getDz() + SURROUND) {
cuboidSet.add(cuboid);
}
}
if (cuboidSet.size() > 1) {
Point p1 = new Point(minPoint.getX(), y, z);
xCount++;
xKills += splitIntoDoubleKills(cuboidSet.size());
Point p1 = new Point(minPoint.getX() - 1, y, z);
xPoints.add(p1);
kill.put(p1, Math.max(kill.getOrDefault(p1, 0), cuboidSet.size()));
Point p2 = new Point(maxPoint.getX(), y, z);
Point p2 = new Point(maxPoint.getX() + 1, y, z);
xPoints.add(p2);
kill.put(p2, Math.max(kill.getOrDefault(p2, 0), cuboidSet.size()));
}
}
}
for (int x = minPoint.getX(); x < maxPoint.getX(); x++) {
for (int y = minPoint.getY(); y < maxPoint.getY(); y++) {
int zKills = 0;
int zCount = 0;
Set<Point> zPoints = new HashSet<>();
for (int x = minPoint.getX(); x <= maxPoint.getX(); x++) {
for (int y = minPoint.getY(); y <= maxPoint.getY(); y++) {
Set<Cuboid> cuboidSet = new HashSet<>();
for (Cuboid cuboid : cuboids) {
if (x >= cuboid.getX() - 3.5 && x <= cuboid.getDx() + 3.5 && y >= cuboid.getY() - 3.5 && y <= cuboid.getDy() + 3.5) {
if (x >= cuboid.getX() - SURROUND && x < cuboid.getDx() + SURROUND && y >= cuboid.getY() - SURROUND && y < cuboid.getDy() + SURROUND) {
cuboidSet.add(cuboid);
}
}
if (cuboidSet.size() > 1) {
Point p1 = new Point(x, y, minPoint.getZ());
zCount++;
zKills += splitIntoDoubleKills(cuboidSet.size());
Point p1 = new Point(x, y, minPoint.getZ() - 1);
zPoints.add(p1);
kill.put(p1, Math.max(kill.getOrDefault(p1, 0), cuboidSet.size()));
Point p2 = new Point(x, y, maxPoint.getZ());
Point p2 = new Point(x, y, maxPoint.getZ() + 1);
zPoints.add(p2);
kill.put(p2, Math.max(kill.getOrDefault(p2, 0), cuboidSet.size()));
}
}
}
Set<Point> outlinePoints = new HashSet<>();
yPoints.forEach(point -> {
Point p1 = new Point(point.getX() - 1, point.getY(), point.getZ());
Point p2 = new Point(point.getX() + 1, point.getY(), point.getZ());
Point p3 = new Point(point.getX(), point.getY(), point.getZ() - 1);
Point p4 = new Point(point.getX(), point.getY(), point.getZ() + 1);
Point p5 = new Point(point.getX() - 1, point.getY(), point.getZ() - 1);
Point p6 = new Point(point.getX() - 1, point.getY(), point.getZ() + 1);
Point p7 = new Point(point.getX() + 1, point.getY(), point.getZ() - 1);
Point p8 = new Point(point.getX() + 1, point.getY(), point.getZ() + 1);
int count = kill.get(point);
int surrounded = 0;
if (kill.getOrDefault(p1, 0) == count) surrounded++;
if (kill.getOrDefault(p2, 0) == count) surrounded++;
if (kill.getOrDefault(p3, 0) == count) surrounded++;
if (kill.getOrDefault(p4, 0) == count) surrounded++;
if (surrounded != 4) outlinePoints.add(point);
if (kill.getOrDefault(p5, 0) != count) outlinePoints.add(point);
if (kill.getOrDefault(p6, 0) != count) outlinePoints.add(point);
if (kill.getOrDefault(p7, 0) != count) outlinePoints.add(point);
if (kill.getOrDefault(p8, 0) != count) outlinePoints.add(point);
});
xPoints.forEach(point -> {
Point p1 = new Point(point.getX(), point.getY() - 1, point.getZ());
Point p2 = new Point(point.getX(), point.getY() + 1, point.getZ());
Point p3 = new Point(point.getX(), point.getY(), point.getZ() - 1);
Point p4 = new Point(point.getX(), point.getY(), point.getZ() + 1);
Point p5 = new Point(point.getX(), point.getY() - 1, point.getZ() - 1);
Point p6 = new Point(point.getX(), point.getY() - 1, point.getZ() + 1);
Point p7 = new Point(point.getX(), point.getY() + 1, point.getZ() - 1);
Point p8 = new Point(point.getX(), point.getY() + 1, point.getZ() + 1);
int count = kill.get(point);
int surrounded = 0;
if (kill.getOrDefault(p1, 0) == count) surrounded++;
if (kill.getOrDefault(p2, 0) == count) surrounded++;
if (kill.getOrDefault(p3, 0) == count) surrounded++;
if (kill.getOrDefault(p4, 0) == count) surrounded++;
if (surrounded != 4) outlinePoints.add(point);
if (kill.getOrDefault(p5, 0) != count) outlinePoints.add(point);
if (kill.getOrDefault(p6, 0) != count) outlinePoints.add(point);
if (kill.getOrDefault(p7, 0) != count) outlinePoints.add(point);
if (kill.getOrDefault(p8, 0) != count) outlinePoints.add(point);
});
zPoints.forEach(point -> {
Point p1 = new Point(point.getX() - 1, point.getY(), point.getZ());
Point p2 = new Point(point.getX() + 1, point.getY(), point.getZ());
Point p3 = new Point(point.getX(), point.getY() - 1, point.getZ());
Point p4 = new Point(point.getX(), point.getY() + 1, point.getZ());
Point p5 = new Point(point.getX() - 1, point.getY() - 1, point.getZ());
Point p6 = new Point(point.getX() - 1, point.getY() + 1, point.getZ());
Point p7 = new Point(point.getX() + 1, point.getY() - 1, point.getZ());
Point p8 = new Point(point.getX() + 1, point.getY() + 1, point.getZ());
int count = kill.get(point);
int surrounded = 0;
if (kill.getOrDefault(p1, 0) == count) surrounded++;
if (kill.getOrDefault(p2, 0) == count) surrounded++;
if (kill.getOrDefault(p3, 0) == count) surrounded++;
if (kill.getOrDefault(p4, 0) == count) surrounded++;
if (surrounded != 4) outlinePoints.add(point);
if (kill.getOrDefault(p5, 0) != count) outlinePoints.add(point);
if (kill.getOrDefault(p6, 0) != count) outlinePoints.add(point);
if (kill.getOrDefault(p7, 0) != count) outlinePoints.add(point);
if (kill.getOrDefault(p8, 0) != count) outlinePoints.add(point);
});
double xPercent = zCount / (double) xArea;
double yPercent = yCount / (double) yArea;
double zPercent = xCount / (double) zArea;
percent = (xPercent + yPercent + zPercent) / 3;
kills = zKills + yKills + xKills;
players.forEach(this::updateBossBar);
Set<Point> pointSet = new HashSet<>(killCount.keySet());
Set<Point> outlinePointsCacheLast = new HashSet<>(outlinePointsCache);
outlinePointsCache.clear();
for (Point point : pointSet) {
if (!kill.containsKey(point)) {
rEntities.get(point).die();
@ -142,16 +275,37 @@ public class KillcheckerVisualizer {
}
kill.forEach((point, count) -> {
if (rEntities.containsKey(point)) {
if (killCount.get(point) == count) return;
if (killCount.get(point) == count && outlinePoints.contains(point) == outlinePointsCacheLast.contains(point)) return;
rEntities.get(point).die();
}
RFallingBlockEntity entity = new RFallingBlockEntity(rEntityServer, point.toLocation(WORLD, 0.5, 0, 0.5), materials[Math.min(count - 1, materials.length) - 1]);
RFallingBlockEntity entity = new RFallingBlockEntity(outlinePoints.contains(point) ? outline : inner, point.toLocation(WORLD, 0.5, 0, 0.5), MATERIALS[Math.min(count - 1, MATERIALS.length) - 1]);
entity.setNoGravity(true);
rEntities.put(point, entity);
if (outlinePoints.contains(point)) outlinePointsCache.add(point);
killCount.put(point, count);
});
}
private int splitIntoDoubleKills(int kills) {
return kills * (kills - 1) / 2;
}
private void updateBossBar(Player player) {
BauSystemBossbar bossbar = bossBarService.get(player, region, "killchecker");
bossbar.setTitle(BauSystem.MESSAGE.parse("KILLCHECKER_BOSSBAR", player, kills, ((int) (percent * 1000) / 10.0), cannonCount));
bossbar.setProgress(percent);
if (percent >= 0.35) {
bossbar.setColor(BarColor.RED);
} else if (percent >= 0.25) {
bossbar.setColor(BarColor.PURPLE);
} else if (percent >= 0.15) {
bossbar.setColor(BarColor.YELLOW);
} else {
bossbar.setColor(BarColor.GREEN);
}
}
private Cuboid create(Material type, int x, int y, int z) {
Set<Point> checked = new HashSet<>();
Set<Point> points = new HashSet<>();
@ -202,16 +356,42 @@ public class KillcheckerVisualizer {
return new Cuboid(minX, minY, minZ, maxX, maxY, maxZ);
}
public boolean show(Player player) {
rEntityServer.addPlayer(player);
public boolean show(Player player, boolean onlyOutline) {
outline.addPlayer(player);
if (!onlyOutline) {
inner.addPlayer(player);
areaPlayers.add(player);
} else if (areaPlayers.contains(player)) {
inner.removePlayer(player);
areaPlayers.remove(player);
}
updateBossBar(player);
return players.add(player);
}
public boolean hide(Player player) {
rEntityServer.removePlayer(player);
outline.removePlayer(player);
if (areaPlayers.contains(player)) {
inner.removePlayer(player);
}
players.remove(player);
areaPlayers.remove(player);
bossBarService.remove(player, region, "killchecker");
if (players.isEmpty()) {
rEntityServer.close();
outline.close();
inner.close();
return true;
}
return false;
}
public boolean disconnect(Player player) {
players.remove(player);
areaPlayers.remove(player);
bossBarService.remove(player, region, "killchecker");
if (players.isEmpty()) {
outline.close();
inner.close();
return true;
}
return false;

Datei anzeigen

@ -24,6 +24,7 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.bukkit.block.Block;
@AllArgsConstructor
@RequiredArgsConstructor
@Getter
@ -46,34 +47,25 @@ public enum LoaderButton {
switch (block.getType()) {
case LEVER:
return LoaderButton.SWITCH;
case ACACIA_BUTTON:
case BIRCH_BUTTON:
case DARK_OAK_BUTTON:
case JUNGLE_BUTTON:
case OAK_BUTTON:
case SPRUCE_BUTTON:
return LoaderButton.WOOD_BUTTON;
case STONE_BUTTON:
return LoaderButton.STONE_BUTTON;
case ACACIA_PRESSURE_PLATE:
case BIRCH_PRESSURE_PLATE:
case DARK_OAK_PRESSURE_PLATE:
case JUNGLE_PRESSURE_PLATE:
case OAK_PRESSURE_PLATE:
case SPRUCE_PRESSURE_PLATE:
case STONE_PRESSURE_PLATE:
return LoaderButton.PRESSURE_PLATE;
case HEAVY_WEIGHTED_PRESSURE_PLATE:
case LIGHT_WEIGHTED_PRESSURE_PLATE:
return LoaderButton.WEIGHTED_PRESSURE_PLATE;
case TRIPWIRE:
return LoaderButton.TRIPWIRE;
case NOTE_BLOCK:
return LoaderButton.NOTEBLOCK;
case DAYLIGHT_DETECTOR:
return LoaderButton.DAYLIGHTSENSOR;
case HEAVY_WEIGHTED_PRESSURE_PLATE:
case LIGHT_WEIGHTED_PRESSURE_PLATE:
return LoaderButton.WEIGHTED_PRESSURE_PLATE;
default:
return LoaderButton.INVALID;
if (block.getType().name().contains("STONE_BUTTON")) {
return LoaderButton.STONE_BUTTON;
} else if (block.getType().name().contains("BUTTON")) {
return LoaderButton.WOOD_BUTTON;
} else if (block.getType().name().contains("PRESSURE_PLATE")) {
return LoaderButton.PRESSURE_PLATE;
} else {
return LoaderButton.INVALID;
}
}
}
}

Datei anzeigen

@ -35,6 +35,7 @@ import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockExplodeEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
@ -83,7 +84,7 @@ public class TNTListener implements Listener {
explode(event.blockList(), event.getBlock().getLocation(), null, null);
}
@EventHandler
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onExplode(EntityExplodeEvent event) {
explode(event.blockList(), event.getLocation(), EventType.TNTExplodeInBuild, event);
}

Datei anzeigen

@ -191,30 +191,6 @@ public final class ScriptExecutor {
private String[] replaceExpressions(String s) {
s = s.replaceAll(" +", " ");
// TODO: Remove this code as the Expression System below will replace it!
Set<String> variables = new HashSet<>(localVariables.allVariables());
variables.addAll(Constants.allVariables());
variables.addAll(globalVariables.allVariables());
for (int i = 0; i < 3; i++) {
for (String variable : variables) {
s = s.replace("<" + variable + ">", getValue(variable));
s = s.replace("<" + variable + ".type>", getOrItselfValue(variable).type());
}
for (String constVariable : Constants.allVariables()) {
s = s.replace("<const." + constVariable + ">", getConstant(constVariable));
s = s.replace("<const." + constVariable + ".type>", Constants.getConstant(constVariable, player).type());
}
for (String localVariable : localVariables.allVariables()) {
s = s.replace("<local." + localVariable + ">", getLocal(localVariable));
s = s.replace("<local." + localVariable + ".type>", getLocalVariables().getValue(localVariable).type());
}
for (String globalVariable : globalVariables.allVariables()) {
s = s.replace("<global." + globalVariable + ">", getGlobal(globalVariable));
s = s.replace("<global." + globalVariable + ".type>", globalVariables.getValue(globalVariable).type());
}
}
StringBuilder result = new StringBuilder();
int depth = 0;
StringBuilder st = new StringBuilder();

Datei anzeigen

@ -47,7 +47,7 @@ public class ScriptListener implements Listener {
new ScriptExecutor((BookMeta) item.getItemMeta(), event.getPlayer(), null);
}
@EventHandler
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerJoin(PlayerJoinEvent event) {
GLOBAL_CONTEXT.put(event.getPlayer(), new Context());
}

Datei anzeigen

@ -46,7 +46,7 @@ public class If implements SpecialCommand {
BauSystem.MESSAGE.send("SCRIPT_COMMAND_ERROR_NO_BOOLEAN", scriptExecutor.getPlayer());
return false;
}
if (v.asBoolean()) {
if (v.asBoolean() && command.length > 2) {
jumpToIndex(scriptExecutor, command[2]);
} else if (command.length > 3) {
jumpToIndex(scriptExecutor, command[3]);

Datei anzeigen

@ -80,7 +80,7 @@ public class Substring implements SpecialCommand {
} else {
result = new Value.StringValue(v1.asString().substring((int) v2.asLong()));
}
} catch (ArrayIndexOutOfBoundsException e) {
} catch (ArrayIndexOutOfBoundsException | StringIndexOutOfBoundsException e) {
result = new Value.StringValue("");
}
scriptExecutor.getLocalVariables().putValue(resultName, result);

Datei anzeigen

@ -30,6 +30,7 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.EntityType;
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.Action;
import org.bukkit.event.block.BlockBreakEvent;
@ -58,7 +59,7 @@ public class EventListener implements Listener {
}, 2, 2);
}
@EventHandler
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoin(PlayerJoinEvent event) {
manager.callEvent(EventType.SelfJoin, event.getPlayer(), event);
}

Datei anzeigen

@ -41,6 +41,9 @@ public class DivideOperator implements Operator {
if (is(value, Value.StringValue.class, Value.BooleanValue.class) || is(value2, Value.StringValue.class, Value.BooleanValue.class)) {
throw new IllegalArgumentException("SCRIPT_COMMAND_ARITHMETIC_DIV_ERROR");
}
if (value2.asDouble() == 0) {
return new Value.DoubleValue(Double.NaN);
}
return new Value.DoubleValue(value.asDouble() / value2.asDouble());
}
}

Datei anzeigen

@ -0,0 +1,195 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.shieldprinting;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
import de.steamwar.bausystem.utils.bossbar.BossBarService;
import de.steamwar.bausystem.utils.bossbar.RegionedBossbar;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.boss.BarColor;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockFormEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.block.EntityBlockFormEvent;
import org.bukkit.event.entity.EntityAirChangeEvent;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntitySpawnEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.util.Vector;
import java.util.*;
public class ShieldPrinting implements Listener {
private static final World WORLD = Bukkit.getWorlds().get(0);
static {
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
ShieldPrintingCommand.SHIELD_PRINTING_MAP.values().forEach(shieldPrinting -> {
shieldPrinting.fallingBlocks.replaceAll((entity, location) -> {
if (entity.isDead()) return null;
return location;
});
});
}, 1, 1);
}
/**
* Vector of current position, Vector of origin
*/
private Map<Vector, Vector> shieldMap = new HashMap<>();
private Map<Vector, BlockData> shieldData = new HashMap<>();
private final Region region;
public ShieldPrinting(Region region) {
this.region = region;
Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance());
updateBossbars();
}
public void copy() {
for (Map.Entry<Vector, Vector> entry : shieldMap.entrySet()) {
shieldData.put(entry.getValue(), entry.getKey().toLocation(WORLD).getBlock().getBlockData());
}
updateBossbars();
}
public void apply() {
for (Map.Entry<Vector, BlockData> entry : shieldData.entrySet()) {
entry.getKey().toLocation(WORLD).getBlock().setBlockData(entry.getValue(), false);
}
}
public void disable() {
HandlerList.unregisterAll(this);
shieldMap.clear();
shieldData.clear();
for (Player player : Bukkit.getOnlinePlayers()) {
BossBarService.instance.remove(player, region, "shieldprinting");
}
}
@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<Block> blockList) {
Set<Vector> toRemove = new HashSet<>();
Map<Vector, Vector> 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);
toRemove.clear();
for (Map.Entry<Vector, Vector> entry : shieldMap.entrySet()) {
if (entry.getKey().equals(entry.getValue())) {
toRemove.add(entry.getKey());
}
}
shieldMap.keySet().removeAll(toRemove);
updateBossbars();
}
private Map<Entity, Location> fallingBlocks = new HashMap<>();
@EventHandler
public void onEntitySpawn(EntitySpawnEvent event) {
if (event.getEntityType() != EntityType.FALLING_BLOCK) return;
if (Region.getRegion(event.getLocation()) != region) return;
fallingBlocks.put(event.getEntity(), event.getLocation().getBlock().getLocation());
}
@EventHandler
public void onEntityChangeBlock(EntityChangeBlockEvent event) {
if (!event.getBlock().getType().isAir()) return;
if (event.getEntityType() != EntityType.FALLING_BLOCK) return;
if (Region.getRegion(event.getBlock().getLocation()) != region) return;
Location origin = fallingBlocks.remove(event.getEntity());
if (origin == null) return;
Location destination = event.getBlock().getLocation();
Vector originOrigin = shieldMap.remove(origin.toVector());
shieldMap.put(destination.toVector(), originOrigin != null ? originOrigin : origin.toVector());
updateBossbars();
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getClickedBlock() == null) return;
if (event.getItem() == null) return;
if (Region.getRegion(event.getClickedBlock().getLocation()) != region) return;
Vector vector = event.getClickedBlock().getLocation().toVector();
if (!shieldMap.containsKey(vector)) return;
event.getClickedBlock().setType(Material.AIR);
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
updateBossbar(event.getPlayer());
}
private void updateBossbars() {
for (Player player : Bukkit.getOnlinePlayers()) {
updateBossbar(player);
}
}
private void updateBossbar(Player player) {
BauSystemBossbar bossbar = BossBarService.instance.get(player, region, "shieldprinting");
bossbar.setColor(BarColor.YELLOW);
bossbar.setTitle(BauSystem.MESSAGE.parse(shieldData.isEmpty() ? "SHIELD_PRINTING_BOSSBAR" : "SHIELD_PRINTING_BOSSBAR_COPIED", player, shieldMap.size(), shieldData.size()));
}
}

Datei anzeigen

@ -0,0 +1,129 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
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 org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import java.util.HashMap;
import java.util.Map;
@Linked
public class ShieldPrintingCommand extends SWCommand implements Listener {
public ShieldPrintingCommand() {
super("shieldprinting");
}
static final Map<Region, ShieldPrinting> SHIELD_PRINTING_MAP = 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 = SHIELD_PRINTING_MAP.put(region, new ShieldPrinting(region));
if (shieldPrinting != null) {
shieldPrinting.disable();
}
BauSystem.MESSAGE.send("SHIELD_PRINTING_START", player);
break;
case COPY:
shieldPrinting = SHIELD_PRINTING_MAP.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 = SHIELD_PRINTING_MAP.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 = SHIELD_PRINTING_MAP.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<Player> 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;
};
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getClickedBlock() == null) {
return;
}
Region region = Region.getRegion(event.getClickedBlock().getLocation());
if (region.isGlobal()) {
return;
}
ShieldPrinting shieldPrinting = SHIELD_PRINTING_MAP.get(region);
if (shieldPrinting == null) {
return;
}
shieldPrinting.onPlayerInteract(event);
}
}

Datei anzeigen

@ -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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.shieldprinting;
public enum ShieldPrintingState {
START,
COPY,
APPLY
}

Datei anzeigen

@ -136,22 +136,22 @@ public class TNTElementGUI {
// Alignment
inv.setItem(23, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_NEGATIVE_Z", player), clickType -> { // Z negative
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.align(new Vector(0.5, 0, 0.49));
tntElement.align(new Vector(0, 0, 0.49));
tntElement.change();
}));
inv.setItem(25, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_POSITIVE_Z", player), clickType -> { // Z positive
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.align(new Vector(0.5, 0, 0.51));
tntElement.align(new Vector(0, 0, 0.51));
tntElement.change();
}));
inv.setItem(15, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_POSITIVE_X", player), clickType -> { // X positive
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.align(new Vector(0.51, 0, 0.5));
tntElement.align(new Vector(0.51, 0, 0));
tntElement.change();
}));
inv.setItem(33, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_NEGATIVE_X", player), clickType -> { // X negative
if (clickType == ClickType.DOUBLE_CLICK) return;
tntElement.align(new Vector(0.49, 0, 0.5));
tntElement.align(new Vector(0.49, 0, 0));
tntElement.change();
}));
inv.setItem(24, new SWItem(Material.SUNFLOWER, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_CENTER", player), clickType -> { // CENTER

Datei anzeigen

@ -293,22 +293,25 @@ public class TNTElement implements SimulatorElement {
parentVector = tntGroup.getPosition();
}
if (vector.getX() - (int) vector.getX() == 0.49) {
vector.setX(vector.getX() + 0.02);
}
if (vector.getX() - (int) vector.getX() == -0.49) {
vector.setX(vector.getX() - 0.02);
}
if (vector.getZ() - (int) vector.getZ() == 0.49) {
vector.setZ(vector.getZ() + 0.02);
}
if (vector.getZ() - (int) vector.getZ() == -0.49) {
vector.setZ(vector.getZ() - 0.02);
if (offset.getX() != 0) {
if (vector.getX() - (int) vector.getX() == 0.49) {
vector.setX(vector.getX() + 0.02);
}
if (vector.getX() - (int) vector.getX() == -0.49) {
vector.setX(vector.getX() - 0.02);
}
vector.setX(vector.getBlockX() + offset.getX());
}
vector.setX(vector.getBlockX() + offset.getX());
vector.setY(vector.getBlockY() + offset.getY());
vector.setZ(vector.getBlockZ() + offset.getZ());
if (offset.getZ() != 0) {
if (vector.getZ() - (int) vector.getZ() == 0.49) {
vector.setZ(vector.getZ() + 0.02);
}
if (vector.getZ() - (int) vector.getZ() == -0.49) {
vector.setZ(vector.getZ() - 0.02);
}
vector.setZ(vector.getBlockZ() + offset.getZ());
}
setPosition(vector.subtract(parentVector));
}

Datei anzeigen

@ -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,89 @@ public class FreezeUtils {
if (freezeEnabled) {
try {
field.set(getWorldHandle.invoke(world), state);
cacheEntityPackets(state);
frozen = state;
} catch (IllegalAccessException e) {
// Ignored;
}
}
}
private List<Object> packets = new ArrayList<>();
private Set<Entity> entities = new HashSet<>();
private BukkitTask task = null;
private Class<?> vec3dClass = Reflection.getClass("{nms.world.phys}.Vec3D");
private Reflection.FieldAccessor<Object> zeroVec3d = (Reflection.FieldAccessor<Object>) 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() {
if (FreezeUtils.entities.stream().anyMatch(Entity::isDead)) {
entities.clear();
packets.clear();
}
List<Entity> 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;
int fuse = tnt.getFuseTicks();
packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), fuseDataWatcher, fuse - (fuse % 5) + 1));
}
FreezeUtils.entities.addAll(entities);
}
}

Datei anzeigen

@ -32,6 +32,7 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntitySpawnEvent;
@ -180,7 +181,7 @@ public class Recorder implements Listener {
});
}
@EventHandler
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onEntityExplode(EntityExplodeEvent event) {
Entity entity = event.getEntity();
if (!(entity instanceof TNTPrimed)) {
@ -188,7 +189,8 @@ public class Recorder implements Listener {
}
TraceRecorder traceRecorder = get((TNTPrimed) entity);
Region region = tntTraceRecorderMap.get((TNTPrimed) entity);
traceRecorder.explode((TNTPrimed) entity, !event.blockList().isEmpty() && region.inRegion(event.getLocation(), RegionType.BUILD, RegionExtensionType.EXTENSION));
boolean inBuildRegion = event.blockList().stream().anyMatch(block -> region.inRegion(block.getLocation(), RegionType.BUILD, RegionExtensionType.EXTENSION));
traceRecorder.explode((TNTPrimed) entity, inBuildRegion);
tntTraceRecorderMap.remove(entity);
tick();
}

Datei anzeigen

@ -202,6 +202,8 @@ public class EntityShowMode implements ShowMode<TNTPosition> {
entity.setDisplayName(fuseTicks + "");
} else if (showModeParameter.isCount()) {
entity.setDisplayName(new HashSet<>(records).size() + "");
} else if (showModeParameter.isTicksSinceStart()) {
entity.setDisplayName((80 - fuseTicks) + tntPosition.getRecord().getOffset() + "");
}
}

Datei anzeigen

@ -31,6 +31,7 @@ public class ShowModeParameter {
private boolean ticks = false;
private boolean count = false;
private boolean buildDestroyOnly = false;
private boolean ticksSinceStart = false;
public void enableWater() {
this.water = true;
@ -63,4 +64,8 @@ public class ShowModeParameter {
public void enableBuildDestroyOnly() {
this.buildDestroyOnly = true;
}
public void enableTicksSinceStart() {
this.ticksSinceStart = true;
}
}

Datei anzeigen

@ -38,9 +38,10 @@ public enum ShowModeParameterType {
}, Arrays.asList("-advanced", "-a"), "INTERPOLATE_Y", "INTERPOLATE_XZ"),
SOURCE(ShowModeParameter::enableSourceOnly, Arrays.asList("-source", "-sourceonly", "-ignite"), "TICKS", "ADVANCED", "INTERPOLATE_Y", "INTERPOLATE_XZ", "WATER"),
EXPLODE(ShowModeParameter::enableExplodeOnly, Arrays.asList("-explode", "-explodeonly"), "TICKS", "ADVANCED", "INTERPOLATE_Y", "INTERPOLATE_XZ", "WATER"),
TICKS(ShowModeParameter::enableTicks, Arrays.asList("-ticks", "-t"), "EXPLODE", "SOURCE", "COUNT"),
COUNT(ShowModeParameter::enableCount, Arrays.asList("-count", "-c"), "COUNT"),
BUILD_DESTROY_ONLY(ShowModeParameter::enableBuildDestroyOnly, Arrays.asList("-builddestroy", "-builddestoryonly"), "WATER");
TICKS(ShowModeParameter::enableTicks, Arrays.asList("-ticks", "-t"), "EXPLODE", "SOURCE", "COUNT", "TICKS_SINCE_START"),
COUNT(ShowModeParameter::enableCount, Arrays.asList("-count", "-c"), "TICKS", "TICKS_SINCE_START"),
BUILD_DESTROY_ONLY(ShowModeParameter::enableBuildDestroyOnly, Arrays.asList("-builddestroy", "-builddestoryonly"), "WATER"),
TICKS_SINCE_START(ShowModeParameter::enableTicksSinceStart, Arrays.asList("-tickssincestart", "-tss"), "TICKS", "COUNT");
@Getter
private final Consumer<ShowModeParameter> showModeParameterConsumer;

Datei anzeigen

@ -0,0 +1,40 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.util;
import de.steamwar.bausystem.SWUtils;
import de.steamwar.command.SWCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@Linked
public class DragonEggCommand extends SWCommand {
public DragonEggCommand() {
super("dragonegg", "enderdragon", "dragon", "egg", "enderei", "ender");
}
@Register(description = "DRAGON_EGG_COMMAND_HELP")
public void genericCommand(Player p) {
SWUtils.giveItemToPlayer(p, new ItemStack(Material.DRAGON_EGG, 1));
}
}

Datei anzeigen

@ -97,6 +97,7 @@ public class XrayCommand extends SWCommand implements Listener {
techHiderCommand.disable(region, player);
if (hidden.get(region).contains(player)) {
hidden.get(region).remove(player);
PlayerMovementWrapper.impl.disable(player);
BauSystem.MESSAGE.sendPrefixless("XRAY_OFF", player, ChatMessageType.ACTION_BAR);
} else {
hidden.get(region).add(player);

Datei anzeigen

@ -27,4 +27,6 @@ public interface PlayerMovementWrapper {
PlayerMovementWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
void setPosition(Player player, Object object);
default void disable(Player player) {
}
}

Datei anzeigen

@ -0,0 +1,51 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.utils.bossbar;
import de.steamwar.bausystem.region.Region;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarFlag;
import org.bukkit.boss.BarStyle;
public interface BauSystemBossbar {
String getTitle();
void setTitle(String title);
double getProgress();
void setProgress(double progress);
BarColor getColor();
void setColor(BarColor color);
BarStyle getStyle();
void setStyle(BarStyle style);
boolean hasFlag(BarFlag flag);
void addFlag(BarFlag flag);
void removeFlag(BarFlag flag);
boolean isVisible();
void setVisible(boolean visible);
Region getRegion();
void cleanup();
}

Datei anzeigen

@ -0,0 +1,96 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.utils.bossbar;
import de.steamwar.bausystem.region.Region;
import de.steamwar.linkage.Linked;
import org.bukkit.Bukkit;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
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.PlayerQuitEvent;
import java.util.HashMap;
import java.util.Map;
@Linked
public class BossBarService implements Listener {
public static BossBarService instance;
public BossBarService() {
instance = this;
}
private final Map<Player, Map<Region, Map<String, BauSystemBossbar>>> playerBossBars = new HashMap<>();
public synchronized BauSystemBossbar get(Player player, Region region, String key) {
return playerBossBars.computeIfAbsent(player, p -> new HashMap<>())
.computeIfAbsent(region, r -> new HashMap<>())
.computeIfAbsent(key, k -> {
BossBar bossBar = Bukkit.createBossBar("", BarColor.WHITE, BarStyle.SOLID);
bossBar.addPlayer(player);
if (region.isGlobal()) {
return new GlobalBossbar(bossBar);
} else {
return new RegionedBossbar(bossBar, region, player);
}
});
}
public synchronized void removeAll(Player player, String key) {
Map<Region, Map<String, BauSystemBossbar>> regionMap = playerBossBars.get(player);
if (regionMap == null) return;
for (Map<String, BauSystemBossbar> bossBarMap : regionMap.values()) {
BauSystemBossbar bossBar = bossBarMap.remove(key);
if (bossBar == null) continue;
bossBar.cleanup();
}
}
public synchronized void removeAll(Player player) {
Map<Region, Map<String, BauSystemBossbar>> regionMap = playerBossBars.remove(player);
if (regionMap == null) return;
for (Map<String, BauSystemBossbar> bossBarMap : regionMap.values()) {
for (BauSystemBossbar bossBar : bossBarMap.values()) {
bossBar.cleanup();
}
}
}
public synchronized void remove(Player player, Region region, String key) {
Map<Region, Map<String, BauSystemBossbar>> regionMap = playerBossBars.get(player);
if (regionMap == null) return;
Map<String, BauSystemBossbar> bossBarMap = regionMap.get(region);
if (bossBarMap == null) return;
BauSystemBossbar bossBar = bossBarMap.remove(key);
if (bossBar == null) return;
bossBar.cleanup();
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onPlayerQuit(PlayerQuitEvent event) {
removeAll(event.getPlayer());
}
}

Datei anzeigen

@ -0,0 +1,112 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.utils.bossbar;
import de.steamwar.bausystem.region.GlobalRegion;
import de.steamwar.bausystem.region.Region;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarFlag;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
public class GlobalBossbar implements BauSystemBossbar {
private BossBar bossBar;
public GlobalBossbar(BossBar bossBar) {
this.bossBar = bossBar;
}
@Override
public String getTitle() {
return bossBar.getTitle();
}
@Override
public void setTitle(String title) {
bossBar.setTitle(title);
}
@Override
public double getProgress() {
return bossBar.getProgress();
}
@Override
public void setProgress(double progress) {
bossBar.setProgress(progress);
}
@Override
public BarColor getColor() {
return bossBar.getColor();
}
@Override
public void setColor(BarColor color) {
bossBar.setColor(color);
}
@Override
public BarStyle getStyle() {
return bossBar.getStyle();
}
@Override
public void setStyle(BarStyle style) {
bossBar.setStyle(style);
}
@Override
public boolean hasFlag(BarFlag flag) {
return bossBar.hasFlag(flag);
}
@Override
public void addFlag(BarFlag flag) {
bossBar.addFlag(flag);
}
@Override
public void removeFlag(BarFlag flag) {
bossBar.removeFlag(flag);
}
@Override
public boolean isVisible() {
return bossBar.isVisible();
}
@Override
public void setVisible(boolean visible) {
bossBar.setVisible(visible);
}
@Override
public Region getRegion() {
return GlobalRegion.getInstance();
}
@Override
public void cleanup() {
bossBar.removeAll();
bossBar = null;
}
}

Datei anzeigen

@ -0,0 +1,148 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.utils.bossbar;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.utils.RegionExtensionType;
import de.steamwar.bausystem.region.utils.RegionType;
import org.bukkit.Bukkit;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarFlag;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
public class RegionedBossbar implements BauSystemBossbar, Listener {
private BossBar bossBar;
private Region region;
private Player player;
public RegionedBossbar(BossBar bossBar, Region region, Player player) {
this.bossBar = bossBar;
this.region = region;
this.player = player;
Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance());
}
@Override
public String getTitle() {
return bossBar.getTitle();
}
@Override
public void setTitle(String title) {
bossBar.setTitle(title);
}
@Override
public double getProgress() {
return bossBar.getProgress();
}
@Override
public void setProgress(double progress) {
bossBar.setProgress(progress);
}
@Override
public BarColor getColor() {
return bossBar.getColor();
}
@Override
public void setColor(BarColor color) {
bossBar.setColor(color);
}
@Override
public BarStyle getStyle() {
return bossBar.getStyle();
}
@Override
public void setStyle(BarStyle style) {
bossBar.setStyle(style);
}
@Override
public boolean hasFlag(BarFlag flag) {
return bossBar.hasFlag(flag);
}
@Override
public void addFlag(BarFlag flag) {
bossBar.addFlag(flag);
}
@Override
public void removeFlag(BarFlag flag) {
bossBar.removeFlag(flag);
}
@Override
public boolean isVisible() {
return bossBar.isVisible();
}
@Override
public void setVisible(boolean visible) {
bossBar.setVisible(visible);
}
@Override
public Region getRegion() {
return region;
}
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
if (event.getPlayer() != player) return;
if (region.inRegion(event.getTo(), RegionType.NORMAL, RegionExtensionType.NORMAL)) {
bossBar.addPlayer(player);
} else {
bossBar.removePlayer(player);
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
if (event.getPlayer() != player) return;
cleanup();
}
@Override
public void cleanup() {
if (bossBar != null) {
bossBar.removeAll();
bossBar = null;
}
region = null;
player = null;
PlayerMoveEvent.getHandlerList().unregister(this);
PlayerQuitEvent.getHandlerList().unregister(this);
}
}