diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomScript.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomScript.java new file mode 100644 index 00000000..6c9eb5f7 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomScript.java @@ -0,0 +1,211 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.script; + +import de.steamwar.bausystem.features.script.variables.Value; +import de.steamwar.inventory.SWItem; +import lombok.RequiredArgsConstructor; +import lombok.experimental.UtilityClass; +import org.bukkit.Material; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; +import yapion.hierarchy.types.YAPIONArray; +import yapion.hierarchy.types.YAPIONMap; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@UtilityClass +public class CustomScript { + + public interface Script { + } + + public interface MenuScript { + void toYAPION(YAPIONMap yapionMap); + ItemStack toItem(); + } + + public interface CustomEvent extends Script { + String eventName(); + boolean execute(PlayerEvent e); + } + + @RequiredArgsConstructor + public class InventoryEvent implements CustomEvent { + private final BookMeta bookMeta; + private final String eventName; + + @Override + public String eventName() { + return eventName; + } + + @Override + public boolean execute(PlayerEvent e) { + new ScriptExecutor(bookMeta, e.getPlayer()); + return true; + } + } + + @RequiredArgsConstructor + public class MenuEvent implements CustomEvent, MenuScript { + private final List pages; + private final String eventName; + + @Override + public String eventName() { + return eventName; + } + + @Override + public boolean execute(PlayerEvent e) { + new ScriptExecutor(pages, e.getPlayer()); + return false; + } + + @Override + public void toYAPION(YAPIONMap yapionMap) { + YAPIONArray yapionArray = new YAPIONArray(); + pages.forEach(yapionArray::add); + yapionMap.put(eventName, yapionArray); + } + + @Override + public ItemStack toItem() { + SWItem swItem = new SWItem(Material.WRITABLE_BOOK, "§7Event§8: §e" + eventName); + BookMeta bookMeta = (BookMeta) swItem.getItemMeta(); + bookMeta.setPages(pages.toArray(new String[0])); + swItem.setItemMeta(bookMeta); + return swItem.getItemStack(); + } + } + + public interface CustomCommand extends Script { + default Map check(String[] args, String[] command) { + if (args.length < command.length) { + return null; + } + + if (!args[0].equals(command[0])) { + return null; + } + + Map arguments = new HashMap<>(); + if (!check(arguments, args, command, 0, 0)) { + return null; + } + return arguments; + } + + default boolean check(Map arguments, String[] args, String[] command, int argsIndex, int commandIndex) { + if (command.length <= commandIndex) { + for (int i = argsIndex; i < args.length; i++) { + if (!(args[i].startsWith("(") && args[i].endsWith(")"))) { + return false; + } + } + return true; + } + if (args.length <= argsIndex) return true; + + String currentArg = args[argsIndex]; + String currentCommand = command[commandIndex]; + + if (currentArg.startsWith("<") && currentArg.endsWith(">")) { + arguments.put(trim(currentArg, 1), new Value.StringValue(currentCommand)); + return check(arguments, args, command, argsIndex + 1, commandIndex + 1); + } else if (currentArg.startsWith("(<") && currentArg.endsWith(">)")) { + arguments.put(trim(currentArg, 2), new Value.StringValue(currentCommand)); + return check(arguments, args, command, argsIndex + 1, commandIndex + 1); + } else if (currentArg.startsWith("(") && currentArg.endsWith(")")) { + if (!trim(currentArg, 1).equals(currentCommand)) { + arguments.put(trim(currentArg, 1), new Value.BooleanValue(false)); + return check(arguments, args, command, argsIndex + 1, commandIndex); + } else { + arguments.put(trim(currentArg, 1), new Value.BooleanValue(true)); + return check(arguments, args, command, argsIndex + 1, commandIndex + 1); + } + } else { + if (!currentArg.equals(currentCommand)) return false; + return check(arguments, args, command, argsIndex + 1, commandIndex + 1); + } + } + + default String trim(String s, int count) { + return s.substring(count, s.length() - count); + } + + boolean execute(String[] command, PlayerCommandPreprocessEvent e); + } + + @RequiredArgsConstructor + public class InventoryCommand implements CustomCommand { + private final BookMeta bookMeta; + private final String[] args; + + public boolean execute(String[] command, PlayerCommandPreprocessEvent e) { + Map arguments = check(args, command); + if (arguments == null) { + return false; + } + + e.setCancelled(true); + new ScriptExecutor(bookMeta, e.getPlayer(), arguments); + return true; + } + } + + @RequiredArgsConstructor + public class MenuCommand implements CustomCommand, MenuScript { + private final List pages; + private final String[] args; + + public boolean execute(String[] command, PlayerCommandPreprocessEvent e) { + Map arguments = check(args, command); + if (arguments == null) { + return false; + } + + e.setCancelled(true); + new ScriptExecutor(pages, e.getPlayer(), arguments); + return true; + } + + @Override + public void toYAPION(YAPIONMap yapionMap) { + YAPIONArray yapionArray = new YAPIONArray(); + pages.forEach(yapionArray::add); + yapionMap.put(String.join(" ", args), yapionArray); + } + + @Override + public ItemStack toItem() { + SWItem swItem = new SWItem(Material.WRITABLE_BOOK, "§8/§e" + String.join(" ", args)); + BookMeta bookMeta = (BookMeta) swItem.getItemMeta(); + bookMeta.setPages(pages.toArray(new String[0])); + swItem.setItemMeta(bookMeta); + return swItem.getItemStack(); + } + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomCommandListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomScriptListener.java similarity index 96% rename from BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomCommandListener.java rename to BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomScriptListener.java index 4945a789..5b98bc44 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomCommandListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomScriptListener.java @@ -51,7 +51,7 @@ import java.util.*; import java.util.stream.Collectors; @Linked(LinkageType.LISTENER) -public class CustomCommandListener implements Listener { +public class CustomScriptListener implements Listener { private interface CustomCommand { default Map check(String[] args, String[] command) { @@ -191,15 +191,19 @@ public class CustomCommandListener implements Listener { Player p = event.getPlayer(); updateInventory(p); - String s = UserConfig.getConfig(p.getUniqueId(), "bausystem-commands"); + String s = UserConfig.getConfig(p.getUniqueId(), "bausystem-scripts"); YAPIONObject yapionObject; if (s == null) { yapionObject = new YAPIONObject(); } else { yapionObject = YAPIONParser.parse(s); + if (yapionObject.containsKey("")) { + yapionObject.add("commands", yapionObject.getMap("")); + yapionObject.remove(""); + } } - yapionObject.getYAPIONMapOrSetDefault("", new YAPIONMap()).forEach((key, value) -> { + yapionObject.getYAPIONMapOrSetDefault("commands", new YAPIONMap()).forEach((key, value) -> { String[] command = ((YAPIONValue) key).get().split(" "); List pages = ((YAPIONArray) value).stream().map(YAPIONValue.class::cast).map(YAPIONValue::get).map(String.class::cast).collect(Collectors.toList()); playerMap.computeIfAbsent(p, player -> new ArrayList<>()).add(new MenuCommand(pages, command)); @@ -216,7 +220,7 @@ public class CustomCommandListener implements Listener { if (!playerMap.containsKey(p)) return new YAPIONObject(); YAPIONObject yapionObject = new YAPIONObject(); YAPIONMap yapionMap = new YAPIONMap(); - yapionObject.add("", yapionMap); + yapionObject.add("commands", yapionMap); playerMap.get(p).stream().filter(MenuCommand.class::isInstance).map(MenuCommand.class::cast).forEach(menuCommand -> { menuCommand.toYAPION(yapionMap); }); @@ -225,14 +229,14 @@ public class CustomCommandListener implements Listener { private boolean save(Player p) { if (!playerMap.containsKey(p)) { - UserConfig.removePlayerConfig(p.getUniqueId(), "bausystem-commands"); + UserConfig.removePlayerConfig(p.getUniqueId(), "bausystem-scripts"); return true; } YAPIONObject yapionObject = output(p); if (yapionObject.toYAPION(new LengthOutput()).getLength() > 64 * 1024) { return false; } - UserConfig.updatePlayerConfig(p.getUniqueId(), "bausystem-commands", yapionObject.toYAPION(new StringOutput()).getResult()); + UserConfig.updatePlayerConfig(p.getUniqueId(), "bausystem-scripts", yapionObject.toYAPION(new StringOutput()).getResult()); return true; } @@ -331,7 +335,7 @@ public class CustomCommandListener implements Listener { p.closeInventory(); SWUtils.giveItemToPlayer(p, p.getItemOnCursor()); save(p); - p.sendMessage("§cScript CMD-Buch Limit erreicht"); + p.sendMessage("§cScript-Buch Limit erreicht"); return; } p.setItemOnCursor(null); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptCommand.java index f2828e72..156be531 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptCommand.java @@ -24,7 +24,7 @@ public class ScriptCommand extends SWCommand { } @LinkedInstance - private CustomCommandListener customCommandListener = null; + private CustomScriptListener customScriptListener = null; private static List> swItems = new ArrayList<>(); @@ -134,6 +134,6 @@ public class ScriptCommand extends SWCommand { @Register({"menu"}) public void menuGUICommand(Player p) { - customCommandListener.openCommandsMenu(p); + customScriptListener.openCommandsMenu(p); } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptExecutor.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptExecutor.java index 46529054..d2da1bb6 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptExecutor.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptExecutor.java @@ -42,6 +42,10 @@ public final class ScriptExecutor { this(bookMeta, player, new HashMap<>()); } + public ScriptExecutor(List pages, Player player) { + this(pages, player, new HashMap<>()); + } + public ScriptExecutor(BookMeta bookMeta, Player player, Map localVariables) { this.player = player; globalVariables = ScriptListener.getGlobalContext(player);