diff --git a/BauSystem_12/src/de/steamwar/bausystem/tracer/TraceEntity_12.java b/BauSystem_12/src/de/steamwar/bausystem/tracer/TraceEntity_12.java index c42cf23..d39c62f 100644 --- a/BauSystem_12/src/de/steamwar/bausystem/tracer/TraceEntity_12.java +++ b/BauSystem_12/src/de/steamwar/bausystem/tracer/TraceEntity_12.java @@ -49,7 +49,7 @@ class TraceEntity_12 extends EntityFallingBlock implements AbstractTraceEntity { } else if (references++ > 0) return; - PacketPlayOutSpawnEntity packetPlayOutSpawnEntity = new PacketPlayOutSpawnEntity(this, 0, 0); + PacketPlayOutSpawnEntity packetPlayOutSpawnEntity = new PacketPlayOutSpawnEntity(this, 70, Block.getCombinedId(getBlock())); PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection; playerConnection.sendPacket(packetPlayOutSpawnEntity); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java index dd1817f..78869bc 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java @@ -23,6 +23,7 @@ import de.steamwar.bausystem.commands.*; import de.steamwar.bausystem.world.*; import de.steamwar.core.CommandRemover; import de.steamwar.core.Core; +import de.steamwar.core.VersionedRunnable; import de.steamwar.scoreboard.SWScoreboard; import de.steamwar.sql.SteamwarUser; import org.bukkit.Bukkit; @@ -97,8 +98,11 @@ public class BauSystem extends JavaPlugin implements Listener { getCommand("detonator").setExecutor(new CommandDetonator()); getCommand("detonator").setTabCompleter(new CommandDetonatorTabCompleter()); getCommand("script").setExecutor(new CommandScript()); + getCommand("scriptvars").setExecutor(new CommandScriptVars()); + getCommand("scriptvars").setTabCompleter(new CommandScriptVarsTabCompleter()); getCommand("simulator").setExecutor(new CommandSimulator()); getCommand("simulator").setTabCompleter(new CommandSimulatorTabCompleter()); + getCommand("redstonetester").setExecutor(new CommandRedstoneTester()); getCommand("gui").setExecutor(new CommandGUI()); Bukkit.getPluginManager().registerEvents(this, this); @@ -109,6 +113,7 @@ public class BauSystem extends JavaPlugin implements Listener { Bukkit.getPluginManager().registerEvents(new TNTSimulatorListener(), this); Bukkit.getPluginManager().registerEvents(new CommandGUI(), this); Bukkit.getPluginManager().registerEvents(new DetonatorListener(), this); + VersionedRunnable.call(new VersionedRunnable(() -> Bukkit.getPluginManager().registerEvents(new RedstoneListener(), this), 15)); new AFKStopper(); autoShutdown = Bukkit.getScheduler().runTaskLater(this, Bukkit::shutdown, 1200); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandGUI.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandGUI.java index 48abaca..5038659 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandGUI.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandGUI.java @@ -53,8 +53,6 @@ public class CommandGUI implements CommandExecutor, Listener { OPEN_INVS.remove(player); }); - inv.setItem(37, getMaterial("GLASS_PANE", "THIN_GLASS"), "§7Platzhalter", clickType -> { - }); inv.setItem(43, getMaterial("GLASS_PANE", "THIN_GLASS"), "§7Platzhalter", clickType -> { }); inv.setItem(42, Material.NETHER_STAR, "§7Bau GUI Item", Arrays.asList("§7Du kannst dieses Item zum Öffnen der BauGUI nutzen", "§7oder Doppel F (Swap hands) drücken."), false, clickType -> { @@ -78,6 +76,14 @@ public class CommandGUI implements CommandExecutor, Listener { player.performCommand("sim wand"); }); + ItemStack redstoneWand = wand(player, RedstoneListener.WAND, "§8/§7redstonetester", Permission.build, "Du hast keine Buildrechte"); + inv.setItem(37, redstoneWand, clickType -> { + if (Welt.noPermission(player, Permission.build)) + return; + player.closeInventory(); + player.performCommand("redstonetester"); + }); + inv.setItem(40, getMaterial("WOODEN_AXE", "WOOD_AXE"), "§eWorldedit Axt", getNoPermsLore(Arrays.asList("§8//§7wand"), player, "§cDu hast keine Worldeditrechte", Permission.worldedit), false, clickType -> { if (Welt.noPermission(player, Permission.world)) return; @@ -571,7 +577,7 @@ public class CommandGUI implements CommandExecutor, Listener { ItemMeta meta = base.getItemMeta(); List lore = meta.getLore(); lore.add(command); - if (Welt.noPermission(player, permission)) + if (permission != null && Welt.noPermission(player, permission)) lore.add(noPermissionMessage); meta.setLore(lore); base.setItemMeta(meta); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandRedstoneTester.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandRedstoneTester.java new file mode 100644 index 0000000..08c794a --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandRedstoneTester.java @@ -0,0 +1,60 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.SWUtils; +import de.steamwar.bausystem.world.RedstoneListener; +import de.steamwar.bausystem.world.Welt; +import de.steamwar.core.VersionedRunnable; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class CommandRedstoneTester implements CommandExecutor { + + private boolean permissionCheck(Player player) { + if (Welt.noPermission(player, Permission.build)) { + player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht den Redstonetester nutzen"); + return false; + } + return true; + } + + @Override + public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) { + if (!(commandSender instanceof Player)) + return false; + Player player = (Player) commandSender; + VersionedRunnable.call(new VersionedRunnable(() -> { + player.sendMessage(BauSystem.PREFIX + "Der RedstoneTester ist nicht in der 1.12 verfügbar"); + }, 8), new VersionedRunnable(() -> { + if (!permissionCheck(player)) { + return; + } + player.sendMessage(BauSystem.PREFIX + "Messe die Zeit zwischen der Aktivierung zweier Redstone Komponenten"); + SWUtils.giveItemToPlayer(player, RedstoneListener.WAND); + }, 15)); + return false; + } + +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandScript.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandScript.java index 95ddb92..1af6767 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandScript.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandScript.java @@ -47,8 +47,13 @@ public class CommandScript implements CommandExecutor { pages.add("§6Variablen§8\n\nMit Variablen kann man sich Zahlen speichern. Man definiert diese mit 'var '.\n\nBeispiel:\n§9# Setze i zu 0\nvar i 0§8\n\nEs gibt einige spezial values. Dazu zählen"); pages.add("§8'true', 'yes', 'false' und 'no', welche für 1, 1, 0 und 0 stehen.\n\nMan kann eine Variable auch um einen erhöhen oder verkleinern. Hierfür schreibt man statt einer Zahl '++', 'inc' oder '--', 'dec'.\n\nBeispiel:\n§9var i ++"); pages.add("§8Variablen kann man referenzieren\ndurch '<' vor dem Variablennamen und '>' nach diesem. Diese kann man in jedem Befehl verwenden.\n\nBeispiel:\n§9# Stacked um 10\nvar stacks 10\n/stack "); + pages.add("§8Man kann auch explizit eine globale, locale, oder konstante variable referenzieren, indem 'global.', 'local.' oder 'const.' vor den Namen in die Klammern zu schreiben."); + pages.add("§8Um Variablen über das Script ausführen zu speichern gibt es 'global' und 'unglobal' als Befehle. Der erste speichert eine locale Variable global und das zweite löscht eine globale wieder."); + pages.add("§8Des weiteren kann man Lokale Variablen mit 'unvar' löschen. Nach dem verlassen einer Welt werden alle Globalen Variablen gelöscht. Globale Variablen kann man mit '/scriptvars' einsehen."); pages.add("§6Konstanten§8\n\nNeben den variablen gibt es noch 5 Konstante Werte, welche nicht mit dem 'var' Befehl verändert werden können.\n\nDiese sind:\n- trace/autotrace\n- tnt\n- freeze\n- fire"); + pages.add("§8Des weiteren gibt es 3 weitere Variablen, welche explizit Spieler gebunden sind\n\nDiese sind:\n- x\n- y\n- z"); pages.add("§6Abfragen§8\n\nMit Abfragen kann man nur Gleichheit von 2 Werten überprüft werden. Hierfür verwendet man\n'if '.\nNach den zwei Werten kann man ein oder 2 Jump-Points schreiben\n'if [...] (JP)'."); + pages.add("§8Des weiteren kann man überprüfen, ob eine Variable existiert mit 'if exists' wonach dann wieder 1 oder 2 Jump-Points sein müssen."); pages.add("§8Ein Jump-Point ist eine Zeile Script, wohin man springen kann. Dieser wird mit einem '.' am Anfang der Zeile beschrieben und direkt danach der Jump-Point Namen ohne Leerzeichen.\n\nBeispiel:\n§9# Jump-Point X\n.X§8"); pages.add("§8Um zu einem Jump-Point ohne Abfrage zu springen kann man den\n'jump ' Befehl verwenden."); pages.add("§6Schleifen§8\n\nSchleifen werden mit Jump-Points, if Abfragen und Jumps gebaut.\n\nBeispiel:\n§9var i 0\n.JUMP\nvar i ++\nif i 10 END JUMP\n.END§8"); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandScriptVars.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandScriptVars.java new file mode 100644 index 0000000..946e07b --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandScriptVars.java @@ -0,0 +1,68 @@ +package de.steamwar.bausystem.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.world.ScriptListener; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.Map; + +public class CommandScriptVars implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + return false; + } + Player player = (Player) sender; + if (args.length == 0) { + Map globalVariables = ScriptListener.GLOBAL_VARIABLES.get(player); + if (globalVariables == null) { + player.sendMessage(BauSystem.PREFIX + "§cKeine globalen Variablen definiert"); + return false; + } + int i = 0; + player.sendMessage(BauSystem.PREFIX + globalVariables.size() + " Variable(n)"); + for (Map.Entry var : globalVariables.entrySet()) { + if (i++ >= 40) break; + player.sendMessage("- " + var.getKey() + "=" + var.getValue()); + } + return false; + } + String varName = args[0]; + if (args.length == 1) { + Map globalVariables = ScriptListener.GLOBAL_VARIABLES.get(player); + if (globalVariables == null) { + player.sendMessage(BauSystem.PREFIX + "§cKeine globalen Variablen definiert"); + return false; + } + if (!globalVariables.containsKey(varName)) { + player.sendMessage(BauSystem.PREFIX + "§cUnbekannte Variable"); + return false; + } + player.sendMessage(BauSystem.PREFIX + varName + "=" + globalVariables.get(varName)); + return false; + } + switch (args[1].toLowerCase()) { + case "delete": + case "clear": + case "remove": + if (!ScriptListener.GLOBAL_VARIABLES.containsKey(player)) { + player.sendMessage(BauSystem.PREFIX + "§cKeine globalen Variablen definiert"); + break; + } + ScriptListener.GLOBAL_VARIABLES.get(player).remove(varName); + player.sendMessage(BauSystem.PREFIX + "Variable " + varName + " gelöscht"); + break; + default: + int value = ScriptListener.parseValue(args[1]); + ScriptListener.GLOBAL_VARIABLES.computeIfAbsent(player, p -> new HashMap<>()).put(varName, value); + player.sendMessage(BauSystem.PREFIX + varName + " auf " + value + " gesetzt"); + } + return false; + } + +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandScriptVarsTabCompleter.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandScriptVarsTabCompleter.java new file mode 100644 index 0000000..f9fa6ef --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandScriptVarsTabCompleter.java @@ -0,0 +1,34 @@ +package de.steamwar.bausystem.commands; + +import de.steamwar.bausystem.SWUtils; +import de.steamwar.bausystem.world.ScriptListener; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +public class CommandScriptVarsTabCompleter implements TabCompleter { + + @Override + public List onTabComplete(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + return new ArrayList<>(); + } + Player player = (Player) sender; + if (args.length == 1) { + List variables = new ArrayList<>(ScriptListener.GLOBAL_VARIABLES.getOrDefault(player, new HashMap<>()).keySet()); + return SWUtils.manageList(variables, args); + } + if (args.length != 2) { + return new ArrayList<>(); + } + int value = ScriptListener.GLOBAL_VARIABLES.getOrDefault(player, new HashMap<>()).getOrDefault(args[0], 0); + return SWUtils.manageList(Arrays.asList(value + "", "true", "false", "yes", "no", "delete", "clear", "remove"), args); + } + +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/world/RedstoneListener.java b/BauSystem_Main/src/de/steamwar/bausystem/world/RedstoneListener.java new file mode 100644 index 0000000..1fd82b3 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/world/RedstoneListener.java @@ -0,0 +1,175 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.world; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.inventory.SWItem; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Powerable; +import org.bukkit.block.data.type.Piston; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockDispenseEvent; +import org.bukkit.event.block.BlockPistonExtendEvent; +import org.bukkit.event.block.BlockPistonRetractEvent; +import org.bukkit.event.block.BlockRedstoneEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class RedstoneListener implements Listener { + + public static final ItemStack WAND = new SWItem(Material.BLAZE_ROD, "§eRedstonetester", Arrays.asList("§eLinksklick Block §8- §7Setzt die 1. Position", "§eRechtsklick Block §8- §7Setzt die 2. Position", "§eShift-Rechtsklick Luft §8- §7Zurücksetzten"), false, null).getItemStack(); + private static Map playerMap = new HashMap<>(); + + private boolean permissionCheck(Player player) { + if (Welt.noPermission(player, Permission.build)) { + player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht den Redstonetester nutzen"); + return false; + } + return true; + } + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + if (!WAND.isSimilar(event.getItem())) return; + Player player = event.getPlayer(); + Block block = event.getClickedBlock(); + event.setCancelled(true); + + if (!permissionCheck(event.getPlayer())) { + return; + } + + switch (event.getAction()) { + case RIGHT_CLICK_AIR: + if (player.isSneaking()) { + playerMap.remove(event.getPlayer()); + player.sendMessage(BauSystem.PREFIX + "Positionen gelöscht§8."); + } + break; + case LEFT_CLICK_BLOCK: + if (!validBlock(event.getPlayer(), block.getBlockData())) return; + playerMap.computeIfAbsent(event.getPlayer(), RedstoneTester::new).loc1 = block.getLocation(); + sendLocation(event.getPlayer(), "POS1", block.getLocation()); + break; + case RIGHT_CLICK_BLOCK: + if (!validBlock(event.getPlayer(), block.getBlockData())) return; + playerMap.computeIfAbsent(event.getPlayer(), RedstoneTester::new).loc2 = block.getLocation(); + sendLocation(event.getPlayer(), "POS2", block.getLocation()); + break; + default: + break; + } + } + + private void sendLocation(Player player, String prefix, Location location) { + player.sendMessage(BauSystem.PREFIX + prefix + "§8: §e" + locationToString(location)); + } + + private static String locationToString(Location location) { + return location.getBlockX() + " " + location.getBlockY() + " " + location.getBlockZ(); + } + + private boolean validBlock(Player player, BlockData block) { + if (block instanceof Powerable) return true; + if (block instanceof Piston) return true; + player.sendMessage(BauSystem.PREFIX + "§cUnbekannte Position"); + return false; + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + playerMap.remove(event.getPlayer()); + } + + @EventHandler + public void onPistonExtend(BlockPistonExtendEvent e) { + playerMap.forEach((player, redstoneTester) -> { + redstoneTester.activate(e.getBlock().getLocation()); + }); + } + + @EventHandler + public void onPistonRetract(BlockPistonRetractEvent e) { + playerMap.forEach((player, redstoneTester) -> { + redstoneTester.activate(e.getBlock().getLocation()); + }); + } + + @EventHandler + public void onRedstoneEvent(BlockRedstoneEvent e) { + playerMap.forEach((player, redstoneTester) -> { + redstoneTester.activate(e.getBlock().getLocation()); + }); + } + + @EventHandler + public void onBlockDispense(BlockDispenseEvent e) { + playerMap.forEach((player, redstoneTester) -> { + redstoneTester.activate(e.getBlock().getLocation()); + }); + } + + private static class RedstoneTester { + + private final Player player; + private Location loc1 = null; + private Location loc2 = null; + + private long lastTick = 0; + private Long tick = null; + + public RedstoneTester(Player player) { + this.player = player; + } + + private void activate(Location location) { + if (loc1 == null || loc2 == null) { + tick = null; + return; + } + if (loc1.equals(location)) { + if (TPSUtils.currentTick.get() - lastTick > 100) { + tick = null; + } + lastTick = TPSUtils.currentTick.get(); + if (tick == null) { + tick = TPSUtils.currentTick.get(); + } + return; + } + if (tick != null && loc2.equals(location)) { + player.sendMessage(BauSystem.PREFIX + "Differenz§8: §e" + (TPSUtils.currentTick.get() - tick) + "§8 - §7in Ticks §8(§7Ticks/2 -> Redstoneticks§8)"); + } + } + + } + +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/world/ScriptListener.java b/BauSystem_Main/src/de/steamwar/bausystem/world/ScriptListener.java index f20994a..cf084e2 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/world/ScriptListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/world/ScriptListener.java @@ -34,16 +34,32 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.BookMeta; import java.util.*; +import java.util.function.Function; import java.util.function.IntBinaryOperator; import java.util.function.IntUnaryOperator; import java.util.logging.Level; public class ScriptListener implements Listener { + public static final Map> GLOBAL_VARIABLES = new HashMap<>(); + private static final Map> CONSTANTS = new HashMap<>(); + + static { + CONSTANTS.put("trace", player -> RecordStateMachine.getRecordStatus().isTracing() ? 1 : 0); + CONSTANTS.put("autotrace", player -> RecordStateMachine.getRecordStatus().isAutoTrace() ? 1 : 0); + CONSTANTS.put("tnt", player -> Region.getRegion(player.getLocation()).getTntMode() == CommandTNT.TNTMode.OFF ? 0 : 1); + CONSTANTS.put("freeze", player -> Region.getRegion(player.getLocation()).isFreeze() ? 1 : 0); + CONSTANTS.put("fire", player -> Region.getRegion(player.getLocation()).isFire() ? 1 : 0); + CONSTANTS.put("x", player -> player.getLocation().getBlockX()); + CONSTANTS.put("y", player -> player.getLocation().getBlockY()); + CONSTANTS.put("z", player -> player.getLocation().getBlockZ()); + } + private Set playerSet = new HashSet<>(); public ScriptListener() { @@ -74,6 +90,11 @@ public class ScriptListener implements Listener { new ScriptExecutor((BookMeta) item.getItemMeta(), event.getPlayer()); } + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + GLOBAL_VARIABLES.remove(event.getPlayer()); + } + private boolean isNoBook(ItemStack item) { return VersionedCallable.call(new VersionedCallable<>(() -> ScriptListener_12.isNoBook(item), 8), new VersionedCallable<>(() -> ScriptListener_15.isNoBook(item), 15)); @@ -93,6 +114,7 @@ public class ScriptListener implements Listener { for (String page : bookMeta.getPages()) { for (String command : page.split("\n")) { + command = command.replaceAll(" +", " "); if (command.startsWith("#") || command.trim().isEmpty()) continue; if (command.startsWith(".")) { jumpPoints.put(command.substring(1), commands.size()); @@ -146,6 +168,15 @@ public class ScriptListener implements Listener { case "var": ScriptListener.variableCommand(this, generateArgumentArray("var", this, command)); continue; + case "unvar": + ScriptListener.unvariableCommand(this, generateArgumentArray("unvar", this, command)); + continue; + case "global": + ScriptListener.globalCommand(this, generateArgumentArray("global", this, command)); + continue; + case "unglobal": + ScriptListener.unglobalCommand(this, generateArgumentArray("unglobal", this, command)); + continue; case "add": ScriptListener.arithmeticCommand(this, generateArgumentArray("add", this, command), (left, right) -> left + right); continue; @@ -246,10 +277,22 @@ public class ScriptListener implements Listener { String s = String.join(" ", args); Set variables = new HashSet<>(scriptExecutor.variables.keySet()); - variables.addAll(Arrays.asList("trace", "autotrace", "tnt", "freeze", "fire")); + variables.addAll(CONSTANTS.keySet()); + if (GLOBAL_VARIABLES.containsKey(scriptExecutor.player)) { + variables.addAll(GLOBAL_VARIABLES.get(scriptExecutor.player).keySet()); + } for (String variable : variables) { s = s.replace("<" + variable + ">", getValue(scriptExecutor, variable) + ""); } + for (String constVariable : CONSTANTS.keySet()) { + s = s.replace("", getConstantValue(scriptExecutor, constVariable) + ""); + } + for (String localVariable : scriptExecutor.variables.keySet()) { + s = s.replace("", getLocalValue(scriptExecutor, localVariable) + ""); + } + for (String globalVariable : GLOBAL_VARIABLES.getOrDefault(scriptExecutor.player, new HashMap<>()).keySet()) { + s = s.replace("", getGlobalValue(scriptExecutor, globalVariable) + ""); + } return s.split(" "); } @@ -283,6 +326,44 @@ public class ScriptListener implements Listener { setValue(scriptExecutor, args[0], parseValue(args[1])); } + private static void unvariableCommand(ScriptExecutor scriptExecutor, String[] args) { + if (args.length < 1) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cVariablen Namen fehlt."); + return; + } + if (!isLocalVariable(scriptExecutor, args[0])) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cVariable is nicht definiert"); + return; + } + scriptExecutor.variables.remove(args[0]); + } + + private static void globalCommand(ScriptExecutor scriptExecutor, String[] args) { + if (args.length < 1) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cVariablen Namen fehlt."); + return; + } + if (!isLocalVariable(scriptExecutor, args[0])) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cVariable is nicht definiert"); + return; + } + GLOBAL_VARIABLES.computeIfAbsent(scriptExecutor.player, player -> new HashMap<>()).put(args[0], scriptExecutor.variables.getOrDefault(args[0], 0)); + } + + private static void unglobalCommand(ScriptExecutor scriptExecutor, String[] args) { + if (args.length < 1) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cVariablen Namen fehlt."); + return; + } + if (!isGlobalVariable(scriptExecutor, args[0])) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cVariable is nicht definiert"); + return; + } + if (GLOBAL_VARIABLES.containsKey(scriptExecutor.player)) { + GLOBAL_VARIABLES.get(scriptExecutor.player).remove(args[0]); + } + } + private static int ifCommand(ScriptExecutor scriptExecutor, String[] args) { if (args.length < 2) { scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cDie ersten beiden Argumente sind Zahlen/Boolsche Werte oder Variablen."); @@ -292,6 +373,13 @@ public class ScriptListener implements Listener { int jumpTruePoint = scriptExecutor.jumpPoints.getOrDefault(args[2], -1); int jumpFalsePoint = args.length > 3 ? scriptExecutor.jumpPoints.getOrDefault(args[3], -1) : -1; + if (args[1].equals("exists")) { + if (isVariable(scriptExecutor, args[0])) { + return jumpTruePoint; + } else { + return jumpFalsePoint; + } + } int firstValue = getValueOrParse(scriptExecutor, args[0]); int secondValue = getValueOrParse(scriptExecutor, args[1]); if (firstValue == secondValue) { @@ -389,37 +477,52 @@ public class ScriptListener implements Listener { } private static int getValue(ScriptExecutor scriptExecutor, String key) { - Region region = Region.getRegion(scriptExecutor.player.getLocation()); - switch (key) { - case "trace": - return RecordStateMachine.getRecordStatus().isTracing() ? 1 : 0; - case "autotrace": - return RecordStateMachine.getRecordStatus().isAutoTrace() ? 1 : 0; - case "tnt": - return region.getTntMode() == CommandTNT.TNTMode.OFF ? 0 : 1; - case "freeze": - return !region.isFreeze() ? 0 : 1; - case "fire": - return !region.isFire() ? 0 : 1; - default: - return scriptExecutor.variables.getOrDefault(key, 0); + if (CONSTANTS.containsKey(key)) { + return CONSTANTS.get(key).apply(scriptExecutor.player); } + if (GLOBAL_VARIABLES.containsKey(scriptExecutor.player) && GLOBAL_VARIABLES.get(scriptExecutor.player).containsKey(key)) { + return GLOBAL_VARIABLES.get(scriptExecutor.player).get(key); + } + return scriptExecutor.variables.getOrDefault(key, 0); + } + + private static int getConstantValue(ScriptExecutor scriptExecutor, String key) { + return CONSTANTS.getOrDefault(key, player -> 0).apply(scriptExecutor.player); + } + + private static int getGlobalValue(ScriptExecutor scriptExecutor, String key) { + if (!GLOBAL_VARIABLES.containsKey(scriptExecutor.player)) { + return 0; + } + return GLOBAL_VARIABLES.get(scriptExecutor.player).getOrDefault(key, 0); + } + + private static int getLocalValue(ScriptExecutor scriptExecutor, String key) { + return scriptExecutor.variables.getOrDefault(key, 0); } private static boolean isVariable(ScriptExecutor scriptExecutor, String key) { - switch (key) { - case "trace": - case "autotrace": - case "tnt": - case "freeze": - case "fire": - return true; - default: - return scriptExecutor.variables.containsKey(key); + if (CONSTANTS.containsKey(key)) { + return true; } + if (GLOBAL_VARIABLES.containsKey(scriptExecutor.player) && GLOBAL_VARIABLES.get(scriptExecutor.player).containsKey(key)) { + return true; + } + return scriptExecutor.variables.containsKey(key); } - private static int parseValue(String value) { + private static boolean isLocalVariable(ScriptExecutor scriptExecutor, String key) { + return isVariable(scriptExecutor, key) && !isGlobalVariable(scriptExecutor, key); + } + + private static boolean isGlobalVariable(ScriptExecutor scriptExecutor, String key) { + if (!GLOBAL_VARIABLES.containsKey(scriptExecutor.player)) { + return false; + } + return GLOBAL_VARIABLES.get(scriptExecutor.player).containsKey(key); + } + + public static int parseValue(String value) { if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes")) { return 1; } else if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no")) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/world/TPSUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/world/TPSUtils.java index 53777f2..6ec2518 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/world/TPSUtils.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/world/TPSUtils.java @@ -26,6 +26,8 @@ import de.steamwar.core.TPSWatcher; import de.steamwar.core.VersionedRunnable; import org.bukkit.Bukkit; +import java.util.function.Supplier; + public class TPSUtils { private TPSUtils() { @@ -36,12 +38,19 @@ public class TPSUtils { private static long nanoOffset = 0; private static long nanoDOffset = 0; + private static long ticksSinceServerStart = 0; + public static final Supplier currentTick = () -> ticksSinceServerStart; + public static void init() { VersionedRunnable.call(new VersionedRunnable(() -> warp = false, 8), new VersionedRunnable(() -> { Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), () -> nanoOffset += nanoDOffset, 1, 1); TPSUtils_15.init(() -> nanoOffset); }, 15)); + + Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), () -> { + ticksSinceServerStart++; + }, 1, 1); } public static void setTPS(double tps) { diff --git a/BauSystem_Main/src/plugin.yml b/BauSystem_Main/src/plugin.yml index 113cb9a..dd285ac 100644 --- a/BauSystem_Main/src/plugin.yml +++ b/BauSystem_Main/src/plugin.yml @@ -36,6 +36,9 @@ commands: detonator: aliases: dt script: + scriptvars: simulator: aliases: sim - gui: \ No newline at end of file + gui: + redstonetester: + aliases: rt \ No newline at end of file