From 5d8a0139abc2d0e752dd3fdcfdd222b0e576d6e8 Mon Sep 17 00:00:00 2001 From: stijnb1234 Date: Sat, 21 Nov 2020 13:06:26 +0100 Subject: [PATCH] Started with Malfunction GUI --- pom.xml | 19 ++++ .../themeparkplus/ThemeParkPlus.java | 14 ++- .../themeparkplus/api/PlusAPI.java | 22 +++- .../api/objects/MalfunctionReport.java | 21 ++-- .../themeparkplus/gui/MalfunctionGUI.java | 102 ++++++++++++++++++ .../listeners/FastpassListeners.java | 1 - .../listeners/MalfunctionListener.java | 34 ++++++ .../listeners/SignListeners.java | 5 + .../listeners/StatusChangeListener.java | 30 +++++- src/main/resources/config.yml | 37 ++++++- src/main/resources/messages.yml | 4 +- 11 files changed, 271 insertions(+), 18 deletions(-) create mode 100644 src/main/lombok/nl/sbdeveloper/themeparkplus/gui/MalfunctionGUI.java create mode 100644 src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/MalfunctionListener.java diff --git a/pom.xml b/pom.xml index 9734812..c63ff9b 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,10 @@ org.bstats nl.sbdeveloper.themeparkplus.libs.bstats + + com.samjakob.spigui + nl.sbdeveloper.themeparkplus.libs.spigui + @@ -172,5 +176,20 @@ worldguardwrapper 1.1.9-SNAPSHOT + + com.samjakob + SpiGUI + v1.1 + + + org.spigotmc + spigot-api + + + org.bukkit + bukkit + + + diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/ThemeParkPlus.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/ThemeParkPlus.java index fa23474..9ddb15b 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/ThemeParkPlus.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/ThemeParkPlus.java @@ -1,5 +1,6 @@ package nl.sbdeveloper.themeparkplus; +import com.samjakob.spigui.SpiGUI; import net.milkbowl.vault.economy.Economy; import nl.sbdeveloper.themeparkplus.commands.TPPCMD; import nl.sbdeveloper.themeparkplus.commands.TPPTabComplete; @@ -32,7 +33,9 @@ public final class ThemeParkPlus extends JavaPlugin { private static Economy econ = null; private static String webhookURL; - private final int configVersion = 2; + private static SpiGUI spiGUI; + + private final int configVersion = 3; @Override public void onEnable() { @@ -140,6 +143,7 @@ public final class ThemeParkPlus extends JavaPlugin { Bukkit.getPluginManager().registerEvents(new DirectionalGateListener(), this); Bukkit.getPluginManager().registerEvents(new FastpassListeners(), this); Bukkit.getPluginManager().registerEvents(new SignListeners(), this); + Bukkit.getPluginManager().registerEvents(new MalfunctionListener(), this); Bukkit.getPluginManager().registerEvents(new WaitingTimeListener(), this); if (getSConfig().getFile().getBoolean("AntiFreerun.Enabled")) { Bukkit.getPluginManager().registerEvents(new AntiFreerunListener(), this); @@ -157,6 +161,10 @@ public final class ThemeParkPlus extends JavaPlugin { } } + Bukkit.getLogger().info("[ThemeParkPlus] Loading GUI helper..."); + spiGUI = new SpiGUI(this); + spiGUI.setEnableAutomaticPagination(false); + Bukkit.getLogger().info("[ThemeParkPlus] Loading data..."); try { data.load(); @@ -205,6 +213,10 @@ public final class ThemeParkPlus extends JavaPlugin { return webhookURL; } + public static SpiGUI getSpiGUI() { + return spiGUI; + } + private boolean setupEconomy() { if (getServer().getPluginManager().getPlugin("Vault") == null) { return false; diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/api/PlusAPI.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/api/PlusAPI.java index 22f44ed..8a9d029 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/api/PlusAPI.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/api/PlusAPI.java @@ -4,6 +4,7 @@ import de.tr7zw.changeme.nbtapi.NBTItem; import nl.iobyte.themepark.api.attraction.Attraction; import nl.sbdeveloper.themeparkplus.ThemeParkPlus; import nl.sbdeveloper.themeparkplus.api.objects.Gate; +import nl.sbdeveloper.themeparkplus.api.objects.MalfunctionReport; import nl.sbdeveloper.themeparkplus.api.objects.WaitingRow; import nl.sbdeveloper.themeparkplus.util.ConfigUtil; import nl.sbdeveloper.themeparkplus.util.XMaterial; @@ -18,8 +19,25 @@ import org.jetbrains.annotations.Nullable; import java.util.*; public class PlusAPI { - private static HashMap gates = new HashMap<>(); - private static HashMap rows = new HashMap<>(); + private static final HashMap gates = new HashMap<>(); + private static final HashMap rows = new HashMap<>(); + private static final HashMap reports = new HashMap<>(); + + public static void addReport(MalfunctionReport report) { + reports.put(report.getRideID(), report); + } + + public static void removeReport(String rideID) { + reports.remove(rideID); + } + + public static MalfunctionReport getReport(String rideID) { + return reports.get(rideID); + } + + public static boolean isReported(String rideID) { + return reports.containsKey(rideID); + } /** * Add a gate diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/api/objects/MalfunctionReport.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/api/objects/MalfunctionReport.java index ac67429..3fc8892 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/api/objects/MalfunctionReport.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/api/objects/MalfunctionReport.java @@ -1,18 +1,19 @@ package nl.sbdeveloper.themeparkplus.api.objects; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; +import lombok.*; import java.time.LocalDateTime; import java.util.UUID; -/** @deprecated Please don't use! It's not implemented yet. */ -@Getter @Setter @NoArgsConstructor @AllArgsConstructor +@Getter @NoArgsConstructor public class MalfunctionReport { - private String rideID; - private UUID reporterUUID; - private LocalDateTime reportDate; - private String reason; + @Getter private String rideID; + @Getter private UUID reporterUUID; + @Getter private final LocalDateTime reportDate = LocalDateTime.now(); + @Getter @Setter private String reason = "Unknown"; + + public MalfunctionReport(String rideID, UUID reporterUUID) { + this.rideID = rideID; + this.reporterUUID = reporterUUID; + } } diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/gui/MalfunctionGUI.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/gui/MalfunctionGUI.java new file mode 100644 index 0000000..2c3e7c9 --- /dev/null +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/gui/MalfunctionGUI.java @@ -0,0 +1,102 @@ +package nl.sbdeveloper.themeparkplus.gui; + +import com.samjakob.spigui.SGMenu; +import com.samjakob.spigui.buttons.SGButton; +import com.samjakob.spigui.item.ItemBuilder; +import nl.iobyte.themepark.api.API; +import nl.iobyte.themepark.api.attraction.Attraction; +import nl.iobyte.themepark.api.attraction.component.Status; +import nl.sbdeveloper.themeparkplus.ThemeParkPlus; +import nl.sbdeveloper.themeparkplus.api.PlusAPI; +import nl.sbdeveloper.themeparkplus.api.objects.MalfunctionReport; +import nl.sbdeveloper.themeparkplus.util.ConfigUtil; +import nl.sbdeveloper.themeparkplus.util.XMaterial; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; + +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class MalfunctionGUI { + public static void open(Attraction att, Player p) { + SGMenu menu = ThemeParkPlus.getSpiGUI().create(ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Malfunction.GUI.Title").replace("%ridename%", att.getId())), 1); + + SGButton report = new SGButton(getItem("Report", ConfigUtil.makecolored(att.getName()))).withListener((InventoryClickEvent e) -> { + if (!PlusAPI.isReported(att.getId())) { + MalfunctionReport malfunctionReport = new MalfunctionReport(att.getId(), p.getUniqueId()); + PlusAPI.addReport(malfunctionReport); + att.setStatus(Status.MALFUNCTION, null); //Player must be null, otherwise we will get a loop in the listener + + //TODO Send message + } else { + //TODO Already reported + } + p.closeInventory(); + }); + menu.setButton(getSlot("Report"), report); + + SGButton fix = new SGButton(getItem("Fix", PlusAPI.getReport(att.getId()))).withListener((InventoryClickEvent e) -> { + if (PlusAPI.isReported(att.getId())) { + + PlusAPI.removeReport(att.getId()); + att.setStatus(Status.CLOSED, null); //Player must be null, otherwise we will get a loop in the listener + + //TODO Send message + } else { + //TODO No malfunction + } + p.closeInventory(); + }); + menu.setButton(getSlot("Fix"), fix); + + SGButton cancel = new SGButton(getItem("Cancel")).withListener((InventoryClickEvent e) -> p.closeInventory()); + menu.setButton(getSlot("Cancel"), cancel); + + p.openInventory(menu.getInventory()); + } + + private static int getSlot(String type) { + return ThemeParkPlus.getSConfig().getFile().getInt("Malfunction.GUI.Buttons." + type + ".Slot"); + } + + private static ItemStack getItem(String type, Object... data) { //data is a string or a report + String material = ThemeParkPlus.getSConfig().getFile().getString("Malfunction.GUI.Buttons." + type + ".Material"); + String name = ThemeParkPlus.getSConfig().getFile().getString("Malfunction.GUI.Buttons." + type + ".Name"); + List lores = ThemeParkPlus.getSConfig().getFile().getStringList("Malfunction.GUI.Buttons." + type + ".Lores"); + + if (material == null || name == null || lores.isEmpty()) return null; //Something is wrong in the config + + List loresFormatted = new ArrayList<>(); + switch (type) { + case "Report": + lores.forEach(lore -> loresFormatted.add(lore.replace("%ridename%", (String) data[0]))); + break; + case "Fix": + String ridename = "this ride"; + String reporter = "-"; + String date = "-"; + String reason = "-"; + if (data[0] != null) { + ridename = API.getAttraction(((MalfunctionReport) data[0]).getRideID()).getName(); + reporter = Bukkit.getOfflinePlayer(((MalfunctionReport) data[0]).getReporterUUID()).getName(); + date = ((MalfunctionReport) data[0]).getReportDate().format(DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss")); + reason = ((MalfunctionReport) data[0]).getReason(); + } + + for (String lore : lores) { + loresFormatted.add(lore.replace("%ridename%", ridename).replace("%reporter%", reporter).replace("%date%", date).replace("%reason%", reason)); + } + break; + default: + break; + } + + Optional stack = XMaterial.matchXMaterial(material); + + return stack.map(xMaterial -> new ItemBuilder(xMaterial.parseItem()).name(name).lore(loresFormatted).build()).orElse(null); + } +} diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/FastpassListeners.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/FastpassListeners.java index 121b53a..f4752a9 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/FastpassListeners.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/FastpassListeners.java @@ -46,7 +46,6 @@ public class FastpassListeners implements Listener { //Buy a ticket String attID = sign.getLine(2); if (!API.isAttraction(attID)) return; - Attraction att = API.getAttraction(attID); double price; diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/MalfunctionListener.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/MalfunctionListener.java new file mode 100644 index 0000000..c09e865 --- /dev/null +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/MalfunctionListener.java @@ -0,0 +1,34 @@ +package nl.sbdeveloper.themeparkplus.listeners; + +import nl.iobyte.themepark.api.API; +import nl.iobyte.themepark.api.attraction.Attraction; +import nl.sbdeveloper.themeparkplus.ThemeParkPlus; +import nl.sbdeveloper.themeparkplus.gui.MalfunctionGUI; +import nl.sbdeveloper.themeparkplus.util.ConfigUtil; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.block.Sign; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.EquipmentSlot; + +public class MalfunctionListener implements Listener { + @EventHandler + public void onClickSign(PlayerInteractEvent e) { + if (e.getClickedBlock() == null || e.getAction() != Action.RIGHT_CLICK_BLOCK || !(e.getClickedBlock().getState() instanceof Sign) || e.getHand() != EquipmentSlot.HAND) return; + + String mrLineOne = ChatColor.stripColor(ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Malfunction.Sign.Row1"))); + String mrLineTwo = ChatColor.stripColor(ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Malfunction.Sign.Row2"))); + + Sign sign = (Sign) e.getClickedBlock().getState(); + if (ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase(mrLineOne) && ChatColor.stripColor(sign.getLine(1)).equalsIgnoreCase(mrLineTwo)) { + String attID = sign.getLine(2); + if (!API.isAttraction(attID)) return; + Attraction att = API.getAttraction(attID); + + MalfunctionGUI.open(att, e.getPlayer()); + } + } +} diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/SignListeners.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/SignListeners.java index 30276ed..41ea2a1 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/SignListeners.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/SignListeners.java @@ -52,6 +52,8 @@ public class SignListeners implements Listener { String sLineTwo = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.ScannerSign.Row2")); String wrLineOne = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("WaitingRow.Sign.Row1")); String wrLineTwo = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("WaitingRow.Sign.Row2")); + String mrLineOne = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Malfunction.Sign.Row1")); + String mrLineTwo = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Malfunction.Sign.Row2")); if (lines[1].equalsIgnoreCase("Machine") && !lines[2].isEmpty() && !lines[3].isEmpty()) { e.setLine(0, mLineOne); @@ -78,6 +80,9 @@ public class SignListeners implements Listener { e.setLine(3, "0 min."); p.sendMessage(ConfigUtil.getMessage("WaitingRow.SignCreated")); + } else if (lines[1].equalsIgnoreCase("Malfunction") && !lines[2].isEmpty()) { + e.setLine(0, mrLineOne); + e.setLine(1, mrLineTwo); } else { p.sendMessage(ConfigUtil.getMessage("General.IncorrectSign")); } diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/StatusChangeListener.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/StatusChangeListener.java index 7280ca8..0025ae4 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/StatusChangeListener.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/StatusChangeListener.java @@ -1,9 +1,13 @@ package nl.sbdeveloper.themeparkplus.listeners; +import nl.iobyte.themepark.api.attraction.Attraction; import nl.iobyte.themepark.api.attraction.component.Status; import nl.iobyte.themepark.api.attraction.manager.StatusManager; import nl.iobyte.themepark.api.events.attraction.ChangeStatusEvent; +import nl.iobyte.themepark.api.events.attraction.PreChangeStatusEvent; import nl.sbdeveloper.themeparkplus.ThemeParkPlus; +import nl.sbdeveloper.themeparkplus.api.PlusAPI; +import nl.sbdeveloper.themeparkplus.api.objects.MalfunctionReport; import nl.sbdeveloper.themeparkplus.util.ConfigUtil; import nl.sbdeveloper.themeparkplus.util.DiscordWebhook; import org.bukkit.Bukkit; @@ -16,9 +20,33 @@ import java.awt.*; import java.io.IOException; /** - * Status change listener for discord webhook + * Status change listener for malfunction menu and discord webhook */ public class StatusChangeListener implements Listener { + @EventHandler + public void onStatusChange(PreChangeStatusEvent e) { + Attraction att = e.getAttraction(); + + if (!PlusAPI.isReported(att.getId()) && e.getAfter() == Status.MALFUNCTION && e.getPlayer() != null) { + if (ThemeParkPlus.getSConfig().getFile().getBoolean("Malfunction.AllowCommandReport")) { + MalfunctionReport malfunctionReport = new MalfunctionReport(att.getId(), e.getPlayer().getUniqueId()); + PlusAPI.addReport(malfunctionReport); + } else { + e.setCancelled(true); + e.getPlayer().sendMessage(ConfigUtil.getMessage("Malfunction.NoCommand")); + } + } + + if (PlusAPI.isReported(att.getId()) && e.getAfter() != Status.MALFUNCTION && e.getPlayer() != null) { + if (ThemeParkPlus.getSConfig().getFile().getBoolean("Malfunction.AllowCommandFix")) { + PlusAPI.removeReport(att.getId()); + } else { + e.setCancelled(true); + e.getPlayer().sendMessage(ConfigUtil.getMessage("Malfunction.NoCommand")); + } + } + } + @EventHandler public void onStatusChange(@NotNull ChangeStatusEvent e) { if (e.getAfter() != Status.GLOBAL) { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index a94c745..a87d1e1 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -8,8 +8,41 @@ MessageInConsole: true WaitingRow: MinutesPerPlayer: 1.5 Sign: - Row1: "&8[&6ThemeParkPlus&8]" - Row2: "&bWaitingRow" + Row1: '&8[&6ThemeParkPlus&8]' + Row2: '&bWaitingRow' +Malfunction: + AllowCommandReport: true + AllowCommandFix: false + Sign: + Row1: '&8[&6ThemeParkPlus&8]' + Row2: '&bMalfunction' + GUI: + Title: '&3Report Malfunction for %ridename%' + Buttons: + Report: + Slot: 2 + Material: GREEN_WOOL + Name: '&2&lReport Malfunction' + Lores: + - '&fClick here to report malfunction for %ridename%.' + - '&r' + - '&cAbuse of this function is not allowed!' + Fix: + Slot: 4 + Material: STONE_PICKAXE + Name: '&e&lFix Ride' + Lores: + - '&fClick here to fix %ridename%!' + - '&r' + - '&fReporter: &7%reporter%' + - '&fDate: &7%date%' + - '&fReason: &7%reason%' + Cancel: + Slot: 6 + Material: RED_WOOL + Name: '&4&lCancel Report' + Lores: + - '&fClick here to cancel.' Fastpass: Item: DisplayName: '&6Fastpass Ticket' diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml index 8749371..e346250 100644 --- a/src/main/resources/messages.yml +++ b/src/main/resources/messages.yml @@ -38,4 +38,6 @@ WaitingRow: SignCreated: '&aYou''ve successfully created a waitingrow sign!' WrongLocation: '&cA waitingrow sign (from the attraction %ridename%) couldn''t be found! It will be deleted.' RedstoneTimer: - Started: '&aThe timer successfully started. It will go off in &f%sec1% &asecond(s), and will turn off in &f%sec2% &asecond(s) after that.' \ No newline at end of file + Started: '&aThe timer successfully started. It will go off in &f%sec1% &asecond(s), and will turn off in &f%sec2% &asecond(s) after that.' +Malfunction: + NoCommand: '&cYou can''t report or fix a ride using the command. Please use this Malfunction Sign at the ride.' \ No newline at end of file