Add ScriptMenu for custom commands
Signed-off-by: yoyosource <yoyosource@nidido.de>
Dieser Commit ist enthalten in:
Ursprung
79df6d8d79
Commit
c6208161ab
@ -19,12 +19,17 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.script;
|
package de.steamwar.bausystem.features.script;
|
||||||
|
|
||||||
|
import de.steamwar.bausystem.SWUtils;
|
||||||
import de.steamwar.bausystem.features.script.variables.Value;
|
import de.steamwar.bausystem.features.script.variables.Value;
|
||||||
import de.steamwar.bausystem.linkage.LinkageType;
|
import de.steamwar.bausystem.linkage.LinkageType;
|
||||||
import de.steamwar.bausystem.linkage.Linked;
|
import de.steamwar.bausystem.linkage.Linked;
|
||||||
import de.steamwar.core.VersionedCallable;
|
import de.steamwar.core.VersionedCallable;
|
||||||
|
import de.steamwar.inventory.SWItem;
|
||||||
|
import de.steamwar.inventory.SWListInv;
|
||||||
|
import de.steamwar.sql.UserConfig;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
@ -34,27 +39,28 @@ import org.bukkit.event.player.PlayerJoinEvent;
|
|||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.BookMeta;
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
import yapion.hierarchy.output.LengthOutput;
|
||||||
|
import yapion.hierarchy.output.StringOutput;
|
||||||
|
import yapion.hierarchy.types.YAPIONArray;
|
||||||
|
import yapion.hierarchy.types.YAPIONMap;
|
||||||
|
import yapion.hierarchy.types.YAPIONObject;
|
||||||
|
import yapion.hierarchy.types.YAPIONValue;
|
||||||
|
import yapion.parser.YAPIONParser;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
import java.util.stream.Collectors;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Linked(LinkageType.LISTENER)
|
@Linked(LinkageType.LISTENER)
|
||||||
public class CustomCommandListener implements Listener {
|
public class CustomCommandListener implements Listener {
|
||||||
|
|
||||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
private interface CustomCommand {
|
||||||
private static class CustomCommand {
|
default Map<String, Value> check(String[] args, String[] command) {
|
||||||
private final BookMeta bookMeta;
|
|
||||||
private final String[] args;
|
|
||||||
|
|
||||||
public boolean execute(String[] command, PlayerCommandPreprocessEvent e) {
|
|
||||||
if (args.length != command.length) {
|
if (args.length != command.length) {
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args[0].equals(command[0])) {
|
if (!args[0].equals(command[0])) {
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Value> arguments = new HashMap<>();
|
Map<String, Value> arguments = new HashMap<>();
|
||||||
@ -64,20 +70,71 @@ public class CustomCommandListener implements Listener {
|
|||||||
arguments.put(current.substring(1, current.length() - 1), new Value.StringValue(command[i]));
|
arguments.put(current.substring(1, current.length() - 1), new Value.StringValue(command[i]));
|
||||||
} else {
|
} else {
|
||||||
if (!current.equals(command[i])) {
|
if (!current.equals(command[i])) {
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean execute(String[] command, PlayerCommandPreprocessEvent e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
private static class InventoryCommand implements CustomCommand {
|
||||||
|
private final BookMeta bookMeta;
|
||||||
|
private final String[] args;
|
||||||
|
|
||||||
|
public boolean execute(String[] command, PlayerCommandPreprocessEvent e) {
|
||||||
|
Map<String, Value> arguments = check(args, command);
|
||||||
|
if (arguments == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
new ScriptExecutor(bookMeta, e.getPlayer(), arguments);
|
new ScriptExecutor(bookMeta, e.getPlayer(), arguments);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
private static class MenuCommand implements CustomCommand {
|
||||||
|
private final List<String> pages;
|
||||||
|
private final String[] args;
|
||||||
|
|
||||||
|
public boolean execute(String[] command, PlayerCommandPreprocessEvent e) {
|
||||||
|
Map<String, Value> arguments = check(args, command);
|
||||||
|
if (arguments == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
e.setCancelled(true);
|
||||||
|
new ScriptExecutor(pages, e.getPlayer(), arguments);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toYAPION(YAPIONMap yapionMap) {
|
||||||
|
YAPIONArray yapionArray = new YAPIONArray();
|
||||||
|
pages.forEach(yapionArray::add);
|
||||||
|
yapionMap.put(String.join(" ", args), yapionArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack toItem() {
|
||||||
|
SWItem swItem = new SWItem(Material.WRITABLE_BOOK, String.join(" ", args));
|
||||||
|
BookMeta bookMeta = (BookMeta) swItem.getItemMeta();
|
||||||
|
bookMeta.setPages(pages.toArray(new String[0]));
|
||||||
|
swItem.setItemMeta(bookMeta);
|
||||||
|
return swItem.getItemStack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Map<Player, List<CustomCommand>> playerMap = new HashMap<>();
|
private Map<Player, List<CustomCommand>> playerMap = new HashMap<>();
|
||||||
|
|
||||||
private void updateInventory(Player p) {
|
private void updateInventory(Player p) {
|
||||||
playerMap.remove(p);
|
playerMap.computeIfPresent(p, (player, customCommands) -> {
|
||||||
|
customCommands.removeIf(InventoryCommand.class::isInstance);
|
||||||
|
return customCommands;
|
||||||
|
});
|
||||||
for (ItemStack item : p.getInventory().getContents()) {
|
for (ItemStack item : p.getInventory().getContents()) {
|
||||||
if (item == null || isNoBook(item) || item.getItemMeta() == null) {
|
if (item == null || isNoBook(item) || item.getItemMeta() == null) {
|
||||||
continue;
|
continue;
|
||||||
@ -94,20 +151,54 @@ public class CustomCommandListener implements Listener {
|
|||||||
if (!s.startsWith("#!CMD /")) {
|
if (!s.startsWith("#!CMD /")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
playerMap.computeIfAbsent(p, player -> new ArrayList<>()).add(new CustomCommand(bookMeta, s.substring(6).split(" ")));
|
playerMap.computeIfAbsent(p, player -> new ArrayList<>()).add(new InventoryCommand(bookMeta, s.substring(6).split(" ")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
updateInventory(event.getPlayer());
|
Player p = event.getPlayer();
|
||||||
|
updateInventory(p);
|
||||||
|
|
||||||
|
String s = UserConfig.getConfig(p.getUniqueId(), "bausystem-commands");
|
||||||
|
YAPIONObject yapionObject;
|
||||||
|
if (s == null) {
|
||||||
|
yapionObject = new YAPIONObject();
|
||||||
|
} else {
|
||||||
|
yapionObject = YAPIONParser.parse(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
yapionObject.getYAPIONMapOrSetDefault("", new YAPIONMap()).forEach((key, value) -> {
|
||||||
|
String[] command = ((YAPIONValue<String>) key).get().split(" ");
|
||||||
|
List<String> 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));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerQuit(PlayerQuitEvent e) {
|
public void onPlayerQuit(PlayerQuitEvent e) {
|
||||||
|
save(e.getPlayer());
|
||||||
playerMap.remove(e.getPlayer());
|
playerMap.remove(e.getPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean save(Player p) {
|
||||||
|
if (!playerMap.containsKey(p)) {
|
||||||
|
UserConfig.removePlayerConfig(p.getUniqueId(), "bausystem-commands");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
YAPIONObject yapionObject = new YAPIONObject();
|
||||||
|
YAPIONMap yapionMap = new YAPIONMap();
|
||||||
|
yapionObject.add("", yapionMap);
|
||||||
|
playerMap.get(p).stream().filter(MenuCommand.class::isInstance).map(MenuCommand.class::cast).forEach(menuCommand -> {
|
||||||
|
menuCommand.toYAPION(yapionMap);
|
||||||
|
});
|
||||||
|
if (yapionObject.toYAPION(new LengthOutput()).getLength() > 64 * 1024) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
UserConfig.updatePlayerConfig(p.getUniqueId(), "bausystem-commands", yapionObject.toYAPION(new StringOutput()).getResult());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onInventoryClose(InventoryCloseEvent e) {
|
public void onInventoryClose(InventoryCloseEvent e) {
|
||||||
if (e.getPlayer() instanceof Player) {
|
if (e.getPlayer() instanceof Player) {
|
||||||
@ -122,13 +213,13 @@ public class CustomCommandListener implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<CustomCommand> customCommands = playerMap.get(e.getPlayer());
|
List<CustomCommand> inventoryCommands = playerMap.get(e.getPlayer());
|
||||||
if (customCommands == null) {
|
if (inventoryCommands == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] command = e.getMessage().split(" ");
|
String[] command = e.getMessage().split(" ");
|
||||||
for (CustomCommand customCommand : customCommands) {
|
for (CustomCommand customCommand : inventoryCommands) {
|
||||||
if (customCommand.execute(command, e)) {
|
if (customCommand.execute(command, e)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -138,4 +229,53 @@ public class CustomCommandListener implements Listener {
|
|||||||
private boolean isNoBook(ItemStack item) {
|
private boolean isNoBook(ItemStack item) {
|
||||||
return VersionedCallable.call(new VersionedCallable<>(() -> ScriptListener_15.isNoBook(item), 15));
|
return VersionedCallable.call(new VersionedCallable<>(() -> ScriptListener_15.isNoBook(item), 15));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void openCommandsMenu(Player p) {
|
||||||
|
List<SWListInv.SWListEntry<MenuCommand>> menuCommands = new ArrayList<>();
|
||||||
|
playerMap.getOrDefault(p, new ArrayList<>()).stream().filter(MenuCommand.class::isInstance).map(MenuCommand.class::cast).forEach(menuCommand -> {
|
||||||
|
String command = "§e" + String.join(" ", menuCommand.args);
|
||||||
|
|
||||||
|
menuCommands.add(new SWListInv.SWListEntry<>(new SWItem(Material.BOOK, command, Arrays.asList("§7Klicke zum rausnehmen"), false, clickType -> {
|
||||||
|
}), menuCommand));
|
||||||
|
});
|
||||||
|
SWListInv<MenuCommand> menuCommandSWListInv = new SWListInv<>(p, "§eScript Commands", false, menuCommands, (clickType, menuCommand) -> {
|
||||||
|
playerMap.get(p).removeIf(customCommand -> customCommand == menuCommand);
|
||||||
|
SWUtils.giveItemToPlayer(p, menuCommand.toItem());
|
||||||
|
p.closeInventory();
|
||||||
|
save(p);
|
||||||
|
});
|
||||||
|
menuCommandSWListInv.setItem(49, new SWItem(Material.HOPPER, "§eHinzufügen", Arrays.asList("§7Klicke mit einem Buch zum hinzufügen"), false, clickType -> {
|
||||||
|
ItemStack item = p.getItemOnCursor();
|
||||||
|
if (item.getType().isAir()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isNoBook(item) || item.getItemMeta() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BookMeta bookMeta = ((BookMeta) item.getItemMeta());
|
||||||
|
if (bookMeta.getPageCount() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (bookMeta.getPage(1).isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String s = bookMeta.getPage(1).split("\n")[0];
|
||||||
|
if (!s.startsWith("#!CMD /")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MenuCommand menuCommand = new MenuCommand(bookMeta.getPages(), s.substring(6).split(" "));
|
||||||
|
playerMap.computeIfAbsent(p, player -> new ArrayList<>()).add(menuCommand);
|
||||||
|
if (!save(p)) {
|
||||||
|
playerMap.get(p).removeIf(customCommand -> customCommand == menuCommand);
|
||||||
|
p.closeInventory();
|
||||||
|
save(p);
|
||||||
|
p.sendMessage("§cScript CMD-Buch Limit erreicht");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p.setItemOnCursor(null);
|
||||||
|
openCommandsMenu(p);
|
||||||
|
}));
|
||||||
|
menuCommandSWListInv.open();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package de.steamwar.bausystem.features.script;
|
|||||||
|
|
||||||
import de.steamwar.bausystem.linkage.LinkageType;
|
import de.steamwar.bausystem.linkage.LinkageType;
|
||||||
import de.steamwar.bausystem.linkage.Linked;
|
import de.steamwar.bausystem.linkage.Linked;
|
||||||
|
import de.steamwar.bausystem.linkage.LinkedInstance;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import de.steamwar.inventory.SWListInv;
|
import de.steamwar.inventory.SWListInv;
|
||||||
@ -22,15 +23,19 @@ public class ScriptCommand extends SWCommand {
|
|||||||
super("script");
|
super("script");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@LinkedInstance
|
||||||
|
private CustomCommandListener customCommandListener = null;
|
||||||
|
|
||||||
private static List<SWListInv.SWListEntry<SpecialCommand>> swItems = new ArrayList<>();
|
private static List<SWListInv.SWListEntry<SpecialCommand>> swItems = new ArrayList<>();
|
||||||
|
|
||||||
@Register(help = true)
|
@Register(help = true)
|
||||||
public void genericHelp(Player p, String... args) {
|
public void genericHelp(Player p, String... args) {
|
||||||
p.sendMessage("§8/§escript §8- §7Öffnet die ScriptGUI");
|
p.sendMessage("§8/§escript §8- §7Öffnet die ScriptGUI");
|
||||||
|
p.sendMessage("§8/§escript menu §8- §7Öffnet die ScriptMenuGUI für Custom Command b auübergreifend");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
public void giveCommand(Player p) {
|
public void menuCommand(Player p) {
|
||||||
if (swItems.isEmpty()) {
|
if (swItems.isEmpty()) {
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7", new ArrayList<>(), false, clickType -> {
|
swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7", new ArrayList<>(), false, clickType -> {
|
||||||
@ -127,4 +132,8 @@ public class ScriptCommand extends SWCommand {
|
|||||||
swListInv.open();
|
swListInv.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Register({"menu"})
|
||||||
|
public void menuGUICommand(Player p) {
|
||||||
|
customCommandListener.openCommandsMenu(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,30 +46,56 @@ public final class ScriptExecutor {
|
|||||||
this.player = player;
|
this.player = player;
|
||||||
globalVariables = ScriptListener.getGlobalContext(player);
|
globalVariables = ScriptListener.getGlobalContext(player);
|
||||||
|
|
||||||
boolean initial = true;
|
parseMeta(bookMeta);
|
||||||
for (String page : bookMeta.getPages()) {
|
|
||||||
for (String command : page.split("\n")) {
|
|
||||||
command = command.replaceAll(" +", " ");
|
|
||||||
if (command.startsWith("#") || command.trim().isEmpty()) {
|
|
||||||
if (initial && command.startsWith("#!CMD /")) {
|
|
||||||
specialCommand = command.substring(7).split(" ")[0];
|
|
||||||
}
|
|
||||||
initial = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
initial = false;
|
|
||||||
if (command.startsWith(".")) {
|
|
||||||
jumpPoints.put(command.substring(1), commands.size());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
commands.add(command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (commands.isEmpty()) return;
|
if (commands.isEmpty()) return;
|
||||||
localVariables.forEach(this.localVariables::putValue);
|
localVariables.forEach(this.localVariables::putValue);
|
||||||
resume();
|
resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ScriptExecutor(List<String> pages, Player player, Map<String, Value> localVariables) {
|
||||||
|
this.player = player;
|
||||||
|
globalVariables = ScriptListener.getGlobalContext(player);
|
||||||
|
|
||||||
|
parseList(pages);
|
||||||
|
if (commands.isEmpty()) return;
|
||||||
|
localVariables.forEach(this.localVariables::putValue);
|
||||||
|
resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseMeta(BookMeta bookMeta) {
|
||||||
|
boolean initial = true;
|
||||||
|
for (String page : bookMeta.getPages()) {
|
||||||
|
initial = parsePage(page, initial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseList(List<String> pages) {
|
||||||
|
boolean initial = true;
|
||||||
|
for (String page : pages) {
|
||||||
|
initial = parsePage(page, initial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean parsePage(String page, boolean initial) {
|
||||||
|
for (String command : page.split("\n")) {
|
||||||
|
command = command.replaceAll(" +", " ");
|
||||||
|
if (command.startsWith("#") || command.trim().isEmpty()) {
|
||||||
|
if (initial && command.startsWith("#!CMD /")) {
|
||||||
|
specialCommand = command.substring(7).split(" ")[0];
|
||||||
|
}
|
||||||
|
initial = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
initial = false;
|
||||||
|
if (command.startsWith(".")) {
|
||||||
|
jumpPoints.put(command.substring(1), commands.size());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
commands.add(command);
|
||||||
|
}
|
||||||
|
return initial;
|
||||||
|
}
|
||||||
|
|
||||||
public void resume() {
|
public void resume() {
|
||||||
if (!player.isOnline()) {
|
if (!player.isOnline()) {
|
||||||
return;
|
return;
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.steamwar.bausystem.features.script;
|
package de.steamwar.bausystem.features.script.items;
|
||||||
|
|
||||||
import de.steamwar.bausystem.Permission;
|
import de.steamwar.bausystem.Permission;
|
||||||
import de.steamwar.bausystem.config.ColorConfig;
|
import de.steamwar.bausystem.config.ColorConfig;
|
||||||
@ -31,9 +31,9 @@ import org.bukkit.event.inventory.ClickType;
|
|||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
@Linked(LinkageType.BAU_GUI_ITEM)
|
@Linked(LinkageType.BAU_GUI_ITEM)
|
||||||
public class ScriptBookBauGuiItem extends BauGuiItem {
|
public class ScriptMenuBauGuiItem extends BauGuiItem {
|
||||||
|
|
||||||
public ScriptBookBauGuiItem() {
|
public ScriptMenuBauGuiItem() {
|
||||||
super(15);
|
super(15);
|
||||||
}
|
}
|
||||||
|
|
In neuem Issue referenzieren
Einen Benutzer sperren