From 9ae7e45911a8258b06df8644122d79bcb7a962a5 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Sat, 19 Jun 2021 19:50:37 +0200 Subject: [PATCH] Initial Commit --- .gitignore | 3 + dependency-reduced-pom.xml | 155 ++++++++++ pom.xml | 125 ++++++++ .../java/nl/iobyte/themepark/ThemePark.java | 75 +++++ .../nl/iobyte/themepark/api/ThemeParkAPI.java | 110 +++++++ .../api/attraction/AttractionService.java | 190 ++++++++++++ .../api/attraction/enums/Status.java | 187 ++++++++++++ .../api/attraction/objects/Attraction.java | 142 +++++++++ .../api/attraction/objects/Region.java | 115 ++++++++ .../api/config/ConfigurationManager.java | 252 ++++++++++++++++ .../api/config/enums/StorageKey.java | 55 ++++ .../api/config/enums/StorageLocation.java | 25 ++ .../api/config/objects/Configuration.java | 170 +++++++++++ .../config/objects/ConfigurationUpdater.java | 77 +++++ .../api/database/DatabaseService.java | 94 ++++++ .../api/database/objects/Database.java | 122 ++++++++ .../database/objects/types/MySQLDatabase.java | 47 +++ .../database/objects/types/NullDatabase.java | 28 ++ .../objects/types/SQLiteDatabase.java | 95 ++++++ .../themepark/api/event/EventDispatcher.java | 44 +++ .../AttractionCoverChangeEvent.java | 12 + .../attraction/AttractionCreateEvent.java | 13 + .../AttractionDescriptionChangeEvent.java | 12 + .../AttractionLocationChangeEvent.java | 13 + .../attraction/AttractionNameChangeEvent.java | 12 + .../AttractionRegionChangeEvent.java | 12 + .../attraction/AttractionRemoveEvent.java | 13 + .../AttractionStatusChangeEvent.java | 13 + .../api/event/objects/AttractionEvent.java | 18 ++ .../api/event/objects/ChangeEvent.java | 32 ++ .../api/event/objects/RegionEvent.java | 18 ++ .../api/event/objects/StatusEvent.java | 18 ++ .../api/event/region/RegionCreateEvent.java | 13 + .../event/region/RegionNameChangeEvent.java | 12 + .../api/event/region/RegionRemoveEvent.java | 13 + .../event/ridecount/RideCountAddEvent.java | 19 ++ .../event/status/StatusColorChangeEvent.java | 12 + .../status/StatusHexColorChangeEvent.java | 12 + .../status/StatusMaterialChangeEvent.java | 13 + .../event/status/StatusNameChangeEvent.java | 12 + .../status/StatusTeleportChangeEvent.java | 12 + .../themepark/api/load/DataLoadService.java | 35 +++ .../api/load/interfaces/IDataLoader.java | 10 + .../api/load/objects/DatabaseLoader.java | 68 +++++ .../api/load/objects/MenuDataLoader.java | 18 ++ .../api/load/objects/SignDataLoader.java | 50 ++++ .../api/load/objects/StatusDataLoader.java | 191 ++++++++++++ .../themepark/api/menu/MenuService.java | 35 +++ .../themepark/api/menu/objects/MainMenu.java | 129 ++++++++ .../api/menu/objects/StatusMenu.java | 276 ++++++++++++++++++ .../api/menu/objects/actions/PageAction.java | 21 ++ .../api/menu/objects/actions/TPAction.java | 20 ++ .../objects/handlers/CommandMenuHandler.java | 34 +++ .../handlers/JsonMessageMenuHandler.java | 38 +++ .../handlers/PlainMessageMenuHandler.java | 35 +++ .../objects/handlers/StatusMenuHandler.java | 24 ++ .../themepark/api/message/MessageKey.java | 63 ++++ .../nl/iobyte/themepark/api/message/Text.java | 25 ++ .../api/ridecount/RideCountService.java | 110 +++++++ .../ridecount/objects/AttractionCount.java | 151 ++++++++++ .../api/ridecount/objects/RideCount.java | 81 +++++ .../api/ridecount/objects/TopData.java | 143 +++++++++ .../themepark/api/sign/SignManager.java | 119 ++++++++ .../api/sign/objects/StatusSign.java | 44 +++ .../themepark/commands/ThemeParkCommand.java | 44 +++ .../arguments/AttractionArgument.java | 43 +++ .../arguments/NoAttractionArgument.java | 42 +++ .../commands/arguments/NoRegionArgument.java | 42 +++ .../commands/arguments/RegionArgument.java | 43 +++ .../commands/subcommands/HelpCommand.java | 71 +++++ .../commands/subcommands/ItemCommand.java | 43 +++ .../commands/subcommands/MenuCommand.java | 35 +++ .../attraction/AttractionCommands.java | 19 ++ .../attraction/AttractionCoverCommand.java | 34 +++ .../attraction/AttractionCreateCommand.java | 76 +++++ .../attraction/AttractionListCommand.java | 107 +++++++ .../attraction/AttractionLocationCommand.java | 31 ++ .../attraction/AttractionNameCommand.java | 34 +++ .../attraction/AttractionRegionCommand.java | 35 +++ .../attraction/AttractionRemoveCommand.java | 33 +++ .../attraction/AttractionStatusCommand.java | 35 +++ .../attraction/AttractionWarpCommand.java | 50 ++++ .../subcommands/region/RegionCommands.java | 14 + .../region/RegionCreateCommand.java | 39 +++ .../subcommands/region/RegionListCommand.java | 78 +++++ .../subcommands/region/RegionNameCommand.java | 34 +++ .../region/RegionRemoveCommand.java | 32 ++ .../ridecount/RideCountAddCommand.java | 48 +++ .../ridecount/RideCountCommands.java | 12 + .../ridecount/RideCountGetCommand.java | 44 +++ .../status/StatusColorCommand.java | 35 +++ .../subcommands/status/StatusCommands.java | 15 + .../status/StatusHexColorCommand.java | 36 +++ .../status/StatusMaterialCommand.java | 53 ++++ .../subcommands/status/StatusNameCommand.java | 35 +++ .../status/StatusTeleportCommand.java | 35 +++ .../listeners/AttractionListener.java | 212 ++++++++++++++ .../themepark/listeners/GeneralListener.java | 54 ++++ .../themepark/listeners/PlayerListener.java | 208 +++++++++++++ .../themepark/listeners/RegionListener.java | 90 ++++++ .../listeners/RideCountListener.java | 92 ++++++ .../themepark/listeners/StatusListener.java | 86 ++++++ .../listeners/StatusSignListener.java | 104 +++++++ .../themepark/logger/ThemeParkLogger.java | 13 + .../nl/iobyte/themepark/scheduler/Task.java | 50 ++++ .../scheduler/ThemeParkScheduler.java | 62 ++++ .../themepark/traincarts/RideCountSign.java | 78 +++++ .../iobyte/themepark/utils/LocationUtil.java | 52 ++++ .../iobyte/themepark/utils/PlaceHolder.java | 16 + .../iobyte/themepark/utils/StatusMessage.java | 85 ++++++ .../themepark/utils/VersionComparator.java | 43 +++ src/main/resources/menu.yml | 45 +++ src/main/resources/message.yml | 20 ++ src/main/resources/plugin.yml | 9 + src/main/resources/settings.yml | 15 + themepark.iml | 80 +++++ 116 files changed, 6876 insertions(+) create mode 100644 .gitignore create mode 100644 dependency-reduced-pom.xml create mode 100644 pom.xml create mode 100644 src/main/java/nl/iobyte/themepark/ThemePark.java create mode 100644 src/main/java/nl/iobyte/themepark/api/ThemeParkAPI.java create mode 100644 src/main/java/nl/iobyte/themepark/api/attraction/AttractionService.java create mode 100644 src/main/java/nl/iobyte/themepark/api/attraction/enums/Status.java create mode 100644 src/main/java/nl/iobyte/themepark/api/attraction/objects/Attraction.java create mode 100644 src/main/java/nl/iobyte/themepark/api/attraction/objects/Region.java create mode 100644 src/main/java/nl/iobyte/themepark/api/config/ConfigurationManager.java create mode 100644 src/main/java/nl/iobyte/themepark/api/config/enums/StorageKey.java create mode 100644 src/main/java/nl/iobyte/themepark/api/config/enums/StorageLocation.java create mode 100644 src/main/java/nl/iobyte/themepark/api/config/objects/Configuration.java create mode 100644 src/main/java/nl/iobyte/themepark/api/config/objects/ConfigurationUpdater.java create mode 100644 src/main/java/nl/iobyte/themepark/api/database/DatabaseService.java create mode 100644 src/main/java/nl/iobyte/themepark/api/database/objects/Database.java create mode 100644 src/main/java/nl/iobyte/themepark/api/database/objects/types/MySQLDatabase.java create mode 100644 src/main/java/nl/iobyte/themepark/api/database/objects/types/NullDatabase.java create mode 100644 src/main/java/nl/iobyte/themepark/api/database/objects/types/SQLiteDatabase.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/EventDispatcher.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionCoverChangeEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionCreateEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionDescriptionChangeEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionLocationChangeEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionNameChangeEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionRegionChangeEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionRemoveEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionStatusChangeEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/objects/AttractionEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/objects/ChangeEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/objects/RegionEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/objects/StatusEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/region/RegionCreateEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/region/RegionNameChangeEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/region/RegionRemoveEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/ridecount/RideCountAddEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/status/StatusColorChangeEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/status/StatusHexColorChangeEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/status/StatusMaterialChangeEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/status/StatusNameChangeEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/event/status/StatusTeleportChangeEvent.java create mode 100644 src/main/java/nl/iobyte/themepark/api/load/DataLoadService.java create mode 100644 src/main/java/nl/iobyte/themepark/api/load/interfaces/IDataLoader.java create mode 100644 src/main/java/nl/iobyte/themepark/api/load/objects/DatabaseLoader.java create mode 100644 src/main/java/nl/iobyte/themepark/api/load/objects/MenuDataLoader.java create mode 100644 src/main/java/nl/iobyte/themepark/api/load/objects/SignDataLoader.java create mode 100644 src/main/java/nl/iobyte/themepark/api/load/objects/StatusDataLoader.java create mode 100644 src/main/java/nl/iobyte/themepark/api/menu/MenuService.java create mode 100644 src/main/java/nl/iobyte/themepark/api/menu/objects/MainMenu.java create mode 100644 src/main/java/nl/iobyte/themepark/api/menu/objects/StatusMenu.java create mode 100644 src/main/java/nl/iobyte/themepark/api/menu/objects/actions/PageAction.java create mode 100644 src/main/java/nl/iobyte/themepark/api/menu/objects/actions/TPAction.java create mode 100644 src/main/java/nl/iobyte/themepark/api/menu/objects/handlers/CommandMenuHandler.java create mode 100644 src/main/java/nl/iobyte/themepark/api/menu/objects/handlers/JsonMessageMenuHandler.java create mode 100644 src/main/java/nl/iobyte/themepark/api/menu/objects/handlers/PlainMessageMenuHandler.java create mode 100644 src/main/java/nl/iobyte/themepark/api/menu/objects/handlers/StatusMenuHandler.java create mode 100644 src/main/java/nl/iobyte/themepark/api/message/MessageKey.java create mode 100644 src/main/java/nl/iobyte/themepark/api/message/Text.java create mode 100644 src/main/java/nl/iobyte/themepark/api/ridecount/RideCountService.java create mode 100644 src/main/java/nl/iobyte/themepark/api/ridecount/objects/AttractionCount.java create mode 100644 src/main/java/nl/iobyte/themepark/api/ridecount/objects/RideCount.java create mode 100644 src/main/java/nl/iobyte/themepark/api/ridecount/objects/TopData.java create mode 100644 src/main/java/nl/iobyte/themepark/api/sign/SignManager.java create mode 100644 src/main/java/nl/iobyte/themepark/api/sign/objects/StatusSign.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/ThemeParkCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/arguments/AttractionArgument.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/arguments/NoAttractionArgument.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/arguments/NoRegionArgument.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/arguments/RegionArgument.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/HelpCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/ItemCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/MenuCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionCommands.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionCoverCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionCreateCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionListCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionLocationCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionNameCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionRegionCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionRemoveCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionStatusCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionWarpCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionCommands.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionCreateCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionListCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionNameCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionRemoveCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/ridecount/RideCountAddCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/ridecount/RideCountCommands.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/ridecount/RideCountGetCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusColorCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusCommands.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusHexColorCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusMaterialCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusNameCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusTeleportCommand.java create mode 100644 src/main/java/nl/iobyte/themepark/listeners/AttractionListener.java create mode 100644 src/main/java/nl/iobyte/themepark/listeners/GeneralListener.java create mode 100644 src/main/java/nl/iobyte/themepark/listeners/PlayerListener.java create mode 100644 src/main/java/nl/iobyte/themepark/listeners/RegionListener.java create mode 100644 src/main/java/nl/iobyte/themepark/listeners/RideCountListener.java create mode 100644 src/main/java/nl/iobyte/themepark/listeners/StatusListener.java create mode 100644 src/main/java/nl/iobyte/themepark/listeners/StatusSignListener.java create mode 100644 src/main/java/nl/iobyte/themepark/logger/ThemeParkLogger.java create mode 100644 src/main/java/nl/iobyte/themepark/scheduler/Task.java create mode 100644 src/main/java/nl/iobyte/themepark/scheduler/ThemeParkScheduler.java create mode 100644 src/main/java/nl/iobyte/themepark/traincarts/RideCountSign.java create mode 100644 src/main/java/nl/iobyte/themepark/utils/LocationUtil.java create mode 100644 src/main/java/nl/iobyte/themepark/utils/PlaceHolder.java create mode 100644 src/main/java/nl/iobyte/themepark/utils/StatusMessage.java create mode 100644 src/main/java/nl/iobyte/themepark/utils/VersionComparator.java create mode 100644 src/main/resources/menu.yml create mode 100644 src/main/resources/message.yml create mode 100644 src/main/resources/plugin.yml create mode 100644 src/main/resources/settings.yml create mode 100644 themepark.iml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..46270ec --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Project exclude paths +/target/ +/.idea/ \ No newline at end of file diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml new file mode 100644 index 0000000..67791cb --- /dev/null +++ b/dependency-reduced-pom.xml @@ -0,0 +1,155 @@ + + + 4.0.0 + nl.iobyte + themepark + 3.0.0 + + + + maven-shade-plugin + 3.2.0 + + + package + + shade + + + + + + + *:* + + com/cryptomorin/xseries/XBlock* + com/cryptomorin/xseries/XEnchantment* + com/cryptomorin/xseries/XEntity* + com/cryptomorin/xseries/XItemStack* + com/cryptomorin/xseries/XMaterialUtil* + com/cryptomorin/xseries/XPotion* + com/cryptomorin/xseries/XSound* + com/cryptomorin/xseries/XBiome* + com/cryptomorin/xseries/NMSExtras* + com/cryptomorin/xseries/NoteBlockMusic* + + + + + + + + + + placeholderapi + https://repo.extendedclip.com/content/repositories/placeholderapi/ + + + onarandombox + http://repo.onarandombox.com/content/groups/public + + + MG-Dev Jenkins CI Maven Repository + https://ci.mg-dev.eu/plugin/repository/everything + + + + + org.spigotmc + spigot-api + 1.12.2-R0.1-SNAPSHOT + provided + + + commons-lang + commons-lang + + + json-simple + com.googlecode.json-simple + + + guava + com.google.guava + + + gson + com.google.code.gson + + + snakeyaml + org.yaml + + + bungeecord-chat + net.md-5 + + + + + me.clip + placeholderapi + 2.10.9 + provided + + + annotations + org.jetbrains + + + + + com.bergerkiller.bukkit + TrainCarts + 1.16.5-v1 + provided + + + LightAPI-fork + io.github.qveshn + + + SmoothCoastersAPI + me.m56738 + + + cloud-paper + org.bergerhealer.cloud.commandframework + + + cloud-annotations + org.bergerhealer.cloud.commandframework + + + cloud-minecraft-extras + org.bergerhealer.cloud.commandframework + + + commodore + me.lucko + + + adventure-platform-bukkit + net.kyori + + + + + com.bergerkiller.bukkit + BKCommonLib + 1.16.5-v1 + provided + + + Mountiplex + com.bergerkiller.mountiplex + + + + + + 11 + 11 + UTF-8 + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..4646c09 --- /dev/null +++ b/pom.xml @@ -0,0 +1,125 @@ + + + 4.0.0 + + + 11 + 11 + UTF-8 + + + nl.iobyte + themepark + 3.0.0 + + + + placeholderapi + https://repo.extendedclip.com/content/repositories/placeholderapi/ + + + onarandombox + http://repo.onarandombox.com/content/groups/public + + + MG-Dev Jenkins CI Maven Repository + https://ci.mg-dev.eu/plugin/repository/everything + + + + + + org.spigotmc + spigot-api + 1.12.2-R0.1-SNAPSHOT + provided + + + nl.iobyte + commandapi + 1.1 + + + nl.iobyte + menuapi + 1.0 + + + com.zaxxer + HikariCP + 4.0.3 + + + me.clip + placeholderapi + 2.10.9 + provided + + + com.dumptruckman.minecraft + JsonConfiguration + 1.1 + + + net.minidev + json-smart + 1.1.1 + + + com.bergerkiller.bukkit + TrainCarts + 1.16.5-v1 + provided + + + com.bergerkiller.bukkit + BKCommonLib + 1.16.5-v1 + provided + + + com.github.cryptomorin + XSeries + 8.1.0 + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.0 + + + + *:* + + com/cryptomorin/xseries/XBlock* + com/cryptomorin/xseries/XEnchantment* + com/cryptomorin/xseries/XEntity* + com/cryptomorin/xseries/XItemStack* + com/cryptomorin/xseries/XMaterialUtil* + com/cryptomorin/xseries/XPotion* + com/cryptomorin/xseries/XSound* + com/cryptomorin/xseries/XBiome* + com/cryptomorin/xseries/NMSExtras* + com/cryptomorin/xseries/NoteBlockMusic* + + + + + + + package + + shade + + + + + + + \ No newline at end of file diff --git a/src/main/java/nl/iobyte/themepark/ThemePark.java b/src/main/java/nl/iobyte/themepark/ThemePark.java new file mode 100644 index 0000000..8d1f924 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/ThemePark.java @@ -0,0 +1,75 @@ +package nl.iobyte.themepark; + +import nl.iobyte.menuapi.MenuAPI; +import nl.iobyte.themepark.api.ThemeParkAPI; +import nl.iobyte.themepark.commands.ThemeParkCommand; +import nl.iobyte.themepark.listeners.*; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; +import java.lang.reflect.Method; + +public class ThemePark extends JavaPlugin { + + private static ThemePark instance; + private final ThemeParkAPI api = new ThemeParkAPI(); + private boolean disabling = false; + + public void onEnable() { + instance = this; + api.enable(); + loadCommands(); + loadListeners(); + loadTrainCarts(); + } + + private void loadCommands() { + new ThemeParkCommand(); + } + + private void loadListeners() { + PluginManager pm = Bukkit.getPluginManager(); + pm.registerEvents(new PlayerListener(), this); + pm.registerEvents(new RegionListener(), this); + pm.registerEvents(new AttractionListener(), this); + pm.registerEvents(new StatusListener(), this); + pm.registerEvents(new RideCountListener(), this); + pm.registerEvents(new StatusSignListener(), this); + pm.registerEvents(new GeneralListener(), this); + MenuAPI.register(this); + } + + private void loadTrainCarts() { + try { + Plugin plugin = Bukkit.getPluginManager().getPlugin("Train_Carts"); + if (plugin != null && plugin.isEnabled()) { + Class clazz = Class.forName("com.bergerkiller.bukkit.tc.signactions.SignAction"); + Class sign = Class.forName("nl.iobyte.themepark.traincarts.RideCountSign"); + Method method = clazz.getMethod("register", clazz); + method.invoke(clazz, sign.newInstance()); + } + } catch (Exception e) { + System.out.println("["+getName()+"] Unable to hook into TrainCarts"); + } + } + + public void onDisable() { + disabling = true; + api.disable(); + + instance = null; + } + + public static ThemePark getInstance() { + return instance; + } + + public ThemeParkAPI getAPI() { + return api; + } + + public boolean isDisabling() { + return disabling; + } +} diff --git a/src/main/java/nl/iobyte/themepark/api/ThemeParkAPI.java b/src/main/java/nl/iobyte/themepark/api/ThemeParkAPI.java new file mode 100644 index 0000000..b62b802 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/ThemeParkAPI.java @@ -0,0 +1,110 @@ +package nl.iobyte.themepark.api; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.AttractionService; +import nl.iobyte.themepark.api.config.ConfigurationManager; +import nl.iobyte.themepark.api.database.DatabaseService; +import nl.iobyte.themepark.api.event.EventDispatcher; +import nl.iobyte.themepark.api.load.DataLoadService; +import nl.iobyte.themepark.api.menu.MenuService; +import nl.iobyte.themepark.api.ridecount.RideCountService; +import nl.iobyte.themepark.api.sign.SignManager; + +public class ThemeParkAPI { + + //Data + private ConfigurationManager configurationManager; + private final DataLoadService dataLoadService = new DataLoadService(); + private final DatabaseService databaseService = new DatabaseService(); + private final MenuService menuService = new MenuService(); + private EventDispatcher eventDispatcher; + + //Attraction + private final AttractionService attractionService = new AttractionService(); + private final RideCountService rideCountService = new RideCountService(); + private final SignManager signManager = new SignManager(); + + /** + * Enable the API + */ + public void enable() { + //Prepare Configuration + configurationManager = new ConfigurationManager(ThemePark.getInstance()); + + //Load data + eventDispatcher = new EventDispatcher(ThemePark.getInstance()); + dataLoadService.init(); + } + + /** + * Disable the API + */ + public void disable() { + databaseService.stop(); + } + + /** + * Get the configuration manager + * @return ConfigurationManager + */ + public ConfigurationManager getConfigurationManager() { + return configurationManager; + } + + /** + * Get the attraction service + * @return AttractionService + */ + public AttractionService getAttractionService() { + return attractionService; + } + + /** + * Get the data load service + * @return DataLoadService + */ + public DataLoadService getDataLoadService() { + return dataLoadService; + } + + /** + * Get the menu service + * @return MenuService + */ + public MenuService getMenuService() { + return menuService; + } + + /** + * Get the ride count service + * @return RideCountService + */ + public RideCountService getRideCountService() { + return rideCountService; + } + + /** + * Get the sign manager + * @return SignManager + */ + public SignManager getSignManager() { + return signManager; + } + + /** + * Get the database service + * @return DatabaseService + */ + public DatabaseService getDatabaseService() { + return databaseService; + } + + /** + * Get the event dispatcher + * @return EventDispatcher + */ + public EventDispatcher getEventDispatcher() { + return eventDispatcher; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/attraction/AttractionService.java b/src/main/java/nl/iobyte/themepark/api/attraction/AttractionService.java new file mode 100644 index 0000000..6e0a175 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/attraction/AttractionService.java @@ -0,0 +1,190 @@ +package nl.iobyte.themepark.api.attraction; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.attraction.objects.Region; +import nl.iobyte.themepark.api.event.attraction.AttractionCreateEvent; +import nl.iobyte.themepark.api.event.attraction.AttractionRemoveEvent; +import nl.iobyte.themepark.api.event.region.RegionCreateEvent; +import nl.iobyte.themepark.api.event.region.RegionRemoveEvent; +import nl.iobyte.themepark.api.message.Text; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +public class AttractionService { + + private final LinkedHashMap regions = new LinkedHashMap<>(); + private final Map attractions = new HashMap<>(); + + /** + * Add Region + * @param region Region + */ + public void addRegion(Region region) { + if(region.getID() == null || region.getID().isEmpty()) + return; + + if(hasRegion(region.getID())) + return; + + regions.put(region.getID(), region); + ThemePark.getInstance().getAPI().getEventDispatcher().call(new RegionCreateEvent( + region + )); + } + + /** + * Has Region with ID + * @param id String + * @return Boolean + */ + public boolean hasRegion(String id) { + if(id == null || id.isEmpty()) + return false; + + return regions.containsKey(id); + } + + /** + * Get Region by ID + * @param id String + * @return Region + */ + public Region getRegion(String id) { + if(id == null || id.isEmpty()) + return null; + + return regions.get(id); + } + + /** + * Get Map with Regions + * @return LinkedHashMap + */ + public LinkedHashMap getRegions() { + return regions; + } + + /** + * Remove Region by ID + * @param id String + * @return Region + */ + public Region removeRegion(String id) { + Region region = regions.remove(id); + if(region == null) + return null; + + for(Attraction attraction : region.getAttractions().values()) + attractions.remove(attraction.getID()); + + ThemePark.getInstance().getAPI().getEventDispatcher().call(new RegionRemoveEvent( + region + )); + + return region; + } + + /** + * Add Attraction + * @param attraction Attraction + */ + public void addAttraction(Attraction attraction) { + if(attraction.getID() == null || attraction.getID().isEmpty()) + return; + + if(hasAttraction(attraction.getID())) + return; + + if(!hasRegion(attraction.getRegionID())) + return; + + getRegion(attraction.getRegionID()).addAttraction(attraction); + attractions.put(attraction.getID(), attraction); + ThemePark.getInstance().getAPI().getEventDispatcher().call(new AttractionCreateEvent( + attraction + )); + } + + /** + * Has Attraction with ID + * @param id String + * @return Boolean + */ + public boolean hasAttraction(String id) { + if(id == null || id.isEmpty()) + return false; + + return attractions.containsKey(id); + } + + /** + * Get Attraction by ID + * @param id String + * @return Attraction + */ + public Attraction getAttraction(String id) { + if(id == null || id.isEmpty()) + return null; + + return attractions.get(id); + } + + /** + * Get Attraction by Name + * @param name String + * @return Attraction + */ + public Attraction getAttractionByName(String name) { + if(name == null || name.isEmpty()) + return null; + + name = Text.strip(name); + for(Attraction attraction : attractions.values()) + if(Text.strip(attraction.getName()).equals(name)) + return attraction; + + return null; + } + + public Map getAttractionsByStatus(Status status) { + if(status == null) + return null; + + Map map = new HashMap<>(); + for(Map.Entry entrySet : attractions.entrySet()) + if(entrySet.getValue().getStatus() == status) + map.put(entrySet.getKey(), entrySet.getValue()); + + return map; + } + + /** + * Get Map with Attractions + * @return Map + */ + public Map getAttractions() { + return attractions; + } + + /** + * Remove Attraction by ID + * @param id String + * @return Attraction + */ + public Attraction removeAttraction(String id) { + Attraction attraction = attractions.remove(id); + if(attraction == null) + return null; + + getRegion(attraction.getRegionID()).removeAttraction(id); + ThemePark.getInstance().getAPI().getEventDispatcher().call(new AttractionRemoveEvent( + attraction + )); + + return attraction; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/attraction/enums/Status.java b/src/main/java/nl/iobyte/themepark/api/attraction/enums/Status.java new file mode 100644 index 0000000..52ca123 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/attraction/enums/Status.java @@ -0,0 +1,187 @@ +package nl.iobyte.themepark.api.attraction.enums; + +import com.cryptomorin.xseries.XMaterial; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.event.status.*; +import org.bukkit.inventory.ItemStack; + +public enum Status { + + CONSTRUCTION(1, "&7", "#95a5a6", "Under Contruction", "STAINED_CLAY:1",false), + OPEN(2, "&a", "#4cd137", "Open", "STAINED_CLAY:5", true), + CLOSED(3, "&4", "#e84118", "Closed", "STAINED_CLAY:14", false), + MAINTENANCE(4, "&6", "#f39c12", "Under Maintenance", "STAINED_CLAY:4", false), + MALFUNCTION(5, "&5", "#8e44ad", "Malfunction", "STAINED_CLAY:11", false); + + private final int id; + private String color, hex_color, name; + private XMaterial material; + private boolean teleport; + Status(int id, String color, String hex_color, String name, String material, boolean teleport) { + this.id = id; + this.color = color; + this.hex_color = hex_color; + this.name = name; + this.material = XMaterial.matchXMaterial(material).orElse(XMaterial.RED_CONCRETE); + this.teleport = teleport; + } + + /** + * Get ID of Status + * @return Integer + */ + public int getID() { + return id; + } + + /** + * Get Color of Status + * @return String + */ + public String getColor() { + return color; + } + + /** + * Set Color of Status + * @param color String + */ + public void setColor(String color) { + String old = this.color; + this.color = color; + ThemePark.getInstance().getAPI().getEventDispatcher().call(new StatusColorChangeEvent( + this, + old, + color + )); + } + + /** + * Get HexColor of Status + * @return String + */ + public String getHexColor() { + return hex_color; + } + + /** + * Set HexColor of Status + * @param hex_color String + */ + public void setHexColor(String hex_color) { + String old = this.hex_color; + this.hex_color = hex_color; + ThemePark.getInstance().getAPI().getEventDispatcher().call(new StatusHexColorChangeEvent( + this, + old, + hex_color + )); + } + + /** + * Get Name of Status + * @return String + */ + public String getName() { + return name; + } + + /** + * Set Name of Status + * @param name String + */ + public void setName(String name) { + String old = this.name; + this.name = name; + ThemePark.getInstance().getAPI().getEventDispatcher().call(new StatusNameChangeEvent( + this, + old, + name + )); + } + + /** + * Get XMaterial of Status + * @return XMaterial + */ + public XMaterial getMaterial() { + return material; + } + + /** + * Set Material of Status + * @param material Material + */ + public void setMaterial(XMaterial material) { + XMaterial old = this.material; + this.material = material; + ThemePark.getInstance().getAPI().getEventDispatcher().call(new StatusMaterialChangeEvent( + this, + old, + material + )); + } + + /** + * Get Item of Status + * @return ItemStack + */ + public ItemStack getItem() { + return material.parseItem(); + } + + /** + * Can Teleport with Status + * @return Boolean + */ + public boolean canTeleport() { + return teleport; + } + + /** + * Set if can Teleport with Status + * @param teleport Boolean + */ + public void setCanTeleport(boolean teleport) { + boolean old = this.teleport; + this.teleport = teleport; + ThemePark.getInstance().getAPI().getEventDispatcher().call(new StatusTeleportChangeEvent( + this, + old, + teleport + )); + } + + /** + * Get Status by name of enum + * @param str String + * @return Status + */ + public static Status get(String str) { + if(str == null || str.isEmpty()) + return null; + + try { + return Status.valueOf(str.toUpperCase()); + } catch (Exception e) { + return null; + } + } + + /** + * Get Status by ID + * @param id Integer + * @return String + */ + public static Status get(int id) { + if(id <= 1 || id > values().length) + return null; + + for(Status status : values()) + if(status.id == id) + return status; + + return null; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/attraction/objects/Attraction.java b/src/main/java/nl/iobyte/themepark/api/attraction/objects/Attraction.java new file mode 100644 index 0000000..55b9ee4 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/attraction/objects/Attraction.java @@ -0,0 +1,142 @@ +package nl.iobyte.themepark.api.attraction.objects; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.event.attraction.*; +import org.bukkit.Location; + +public class Attraction { + + private final String id; + private String region_id, name,cover; + private Status status; + private transient Location location; + + public Attraction(String id, String region_id, String name, String cover, Status status, Location location) { + this.id = id; + this.region_id = region_id; + this.name = name; + this.cover = cover; + this.status = status; + this.location = location; + } + + /** + * Get ID of Attraction + * @return String + */ + public String getID() { + return id; + } + + /** + * Get RegionID of Attraction + * @return String + */ + public String getRegionID() { + return region_id; + } + + /** + * Set RegionID of Attraction + * @param region_id String + */ + public void setRegionID(String region_id) { + String old = this.region_id; + this.region_id = region_id; + ThemePark.getInstance().getAPI().getEventDispatcher().call(new AttractionRegionChangeEvent( + this, + old, + region_id + )); + } + + /** + * Get Name of Attraction + * @return String + */ + public String getName() { + return name; + } + + /** + * Set Name of Attraction + * @param name String + */ + public void setName(String name) { + String old = this.name; + this.name = name; + ThemePark.getInstance().getAPI().getEventDispatcher().call(new AttractionNameChangeEvent( + this, + old, + name + )); + } + + /** + * Get Cover of Attraction + * @return String + */ + public String getCover() { + return cover; + } + + /** + * Set Cover of Attraction + * @param cover String + */ + public void setCover(String cover) { + String old = this.cover; + this.cover = cover; + ThemePark.getInstance().getAPI().getEventDispatcher().call(new AttractionCoverChangeEvent( + this, + old, + cover + )); + } + + /** + * Get Status of Attraction + * @return Status + */ + public Status getStatus() { + return status; + } + + /** + * Set Status of Attraction + * @param status Attraction + */ + public void setStatus(Status status) { + Status old = this.status; + this.status = status; + ThemePark.getInstance().getAPI().getEventDispatcher().call(new AttractionStatusChangeEvent( + this, + old, + status + )); + } + + /** + * Get Location of Attraction + * @return Location + */ + public Location getLocation() { + return location; + } + + /** + * Set Location of Attraction + * @param location Attraction + */ + public void setLocation(Location location) { + Location old = this.location; + this.location = location; + ThemePark.getInstance().getAPI().getEventDispatcher().call(new AttractionLocationChangeEvent( + this, + old, + location + )); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/attraction/objects/Region.java b/src/main/java/nl/iobyte/themepark/api/attraction/objects/Region.java new file mode 100644 index 0000000..e9c2636 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/attraction/objects/Region.java @@ -0,0 +1,115 @@ +package nl.iobyte.themepark.api.attraction.objects; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.config.objects.Configuration; +import nl.iobyte.themepark.api.event.region.RegionNameChangeEvent; + +import java.util.LinkedHashMap; + +public class Region { + + private final String id; + private String name; + private transient final Configuration configuration; + private final LinkedHashMap attractions = new LinkedHashMap<>(); + + public Region(String id, String name) { + this.id = id; + this.name = name; + configuration = new Configuration(ThemePark.getInstance(), "attractions/"+id+".yml", false); + } + + /** + * Get ID of Region + * @return String + */ + public String getID() { + return id; + } + + /** + * Get Name of Region + * @return String + */ + public String getName() { + return name; + } + + /** + * Set Name of Region + * @param name String + */ + public void setName(String name) { + String old = this.name; + this.name = name; + ThemePark.getInstance().getAPI().getEventDispatcher().call(new RegionNameChangeEvent( + this, + old, + name + )); + } + + /** + * Get Map with Attractions + * @return LinkedHashMap + */ + public LinkedHashMap getAttractions() { + return attractions; + } + + /** + * Get Region Configuration file + * @return Configuration + */ + public Configuration getConfiguration() { + return configuration; + } + + /** + * Add Attraction to Region + * @param attraction Attraction + */ + public void addAttraction(Attraction attraction) { + if(attraction.getID() == null || attraction.getID().isEmpty()) + return; + + if(hasAttraction(attraction.getID())) + return; + + attractions.put(attraction.getID(), attraction); + } + + /** + * Has Attraction with ID + * @param id String + * @return Attraction + */ + public boolean hasAttraction(String id) { + if(id == null || id.isEmpty()) + return false; + + return attractions.containsKey(id); + } + + /** + * Get Attraction by ID from Region + * @param id String + * @return Attraction + */ + public Attraction getAttraction(String id) { + if(id == null || id.isEmpty()) + return null; + + return attractions.get(id); + } + + /** + * Remove Attraction by ID from Region + * @param id String + * @return Attraction + */ + public Attraction removeAttraction(String id) { + return attractions.remove(id); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/config/ConfigurationManager.java b/src/main/java/nl/iobyte/themepark/api/config/ConfigurationManager.java new file mode 100644 index 0000000..2bedacb --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/config/ConfigurationManager.java @@ -0,0 +1,252 @@ +package nl.iobyte.themepark.api.config; + +import nl.iobyte.themepark.api.config.enums.StorageKey; +import nl.iobyte.themepark.api.config.enums.StorageLocation; +import nl.iobyte.themepark.api.config.objects.Configuration; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.plugin.Plugin; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ConfigurationManager { + + private final Map locations = new HashMap<>(); + + public ConfigurationManager(Plugin plugin) { + for(StorageLocation location : StorageLocation.values()) + locations.put(location, new Configuration(plugin, location.getName(), true)); + } + + /** + * Get configuration instance belonging to a storage location + * @param location StorageLocation + * @return Configuration instance + */ + public Configuration getConfiguration(StorageLocation location) { + if(location == null) + return null; + + return locations.get(location); + } + + /** + * Save specific storage location + * @param location StorageLocation + */ + public void save(StorageLocation location) { + if(location == null) + return; + + getConfiguration(location).save(); + } + + /** + * Save all storage locations + */ + public void saveAll() { + for(Configuration configuration : locations.values()) + configuration.save(); + } + + /** + * Check if configuration contains storage key + * @param key StorageKey + * @return Boolean + */ + public boolean contains(StorageKey key) { + if(key == null) + return false; + + return contains(key.getLocation(), key.getPath()); + } + + /** + * Check if storage location contains path + * @param location StorageLocation + * @param path String + * @return Boolean + */ + public boolean contains(StorageLocation location, String path) { + if(location == null) + return false; + + return getConfiguration(location).contains(path); + } + + /** + * Set value to StorageKey + * @param key StorageKey + * @param value Object to set StorageKey to + */ + public void set(StorageKey key, Object value) { + if(key == null) + return; + + set(key.getLocation(), key.getPath(), value); + } + + /** + * Set value to path in storage location + * @param location StorageLocation + * @param path String + * @param value Object to set path to + */ + public void set(StorageLocation location, String path, Object value) { + if(location == null) + return; + + getConfiguration(location).set(path, value); + } + + /** + * Get object value of storage key + * @param key StorageKey + * @return Object + */ + public Object get(StorageKey key) { + if(key == null) + return null; + + return get(key.getLocation(), key.getPath()); + } + + /** + * Get object value of path in storage location + * @param location StorageLocation + * @param path Path + * @return Object + */ + public Object get(StorageLocation location, String path) { + if(location == null) + return null; + + return getConfiguration(location).get(path); + } + + /** + * Get string value of storage key + * @param key StorageKey + * @return String + */ + public String getString(StorageKey key) { + if(key == null) + return null; + + return getString(key.getLocation(), key.getPath()); + } + + /** + * Get string value of path in storage location + * @param location StorageLocation + * @param path Path + * @return String + */ + public String getString(StorageLocation location, String path) { + if(location == null) + return null; + + return getConfiguration(location).getString(path); + } + + /** + * Get int value of storage key + * @param key StorageKey + * @return int + */ + public int getInt(StorageKey key) { + if(key == null) + return 0; + + return getInt(key.getLocation(), key.getPath()); + } + + /** + * Get int value of path in storage location + * @param location StorageLocation + * @param path Path + * @return int + */ + public int getInt(StorageLocation location, String path) { + if(location == null) + return 0; + + return getConfiguration(location).getInt(path); + } + + /** + * Get boolean value of storage key + * @param key StorageKey + * @return boolean + */ + public boolean getBoolean(StorageKey key) { + if(key == null) + return false; + + return getBoolean(key.getLocation(), key.getPath()); + } + + /** + * Get boolean value of path in storage location + * @param location StorageLocation + * @param path Path + * @return boolean + */ + public boolean getBoolean(StorageLocation location, String path) { + if(location == null) + return false; + + return getConfiguration(location).getBoolean(path); + } + + /** + * Get string list value of storage key + * @param key StorageKey + * @return List + */ + public List getStringList(StorageKey key) { + if(key == null) + return null; + + return getStringList(key.getLocation(), key.getPath()); + } + + /** + * Get string list value of path in storage location + * @param location StorageLocation + * @param path Path + * @return List + */ + public List getStringList(StorageLocation location, String path) { + if(location == null) + return null; + + return getConfiguration(location).getStringList(path); + } + + /** + * Get string list value of storage key + * @param key StorageKey + * @return List + */ + public ConfigurationSection getSection(StorageKey key) { + if(key == null) + return null; + + return getSection(key.getLocation(), key.getPath()); + } + + /** + * Get string list value of path in storage location + * @param location StorageLocation + * @param path Path + * @return List + */ + public ConfigurationSection getSection(StorageLocation location, String path) { + if(location == null) + return null; + + return getConfiguration(location).getSection(path); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/config/enums/StorageKey.java b/src/main/java/nl/iobyte/themepark/api/config/enums/StorageKey.java new file mode 100644 index 0000000..5244307 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/config/enums/StorageKey.java @@ -0,0 +1,55 @@ +package nl.iobyte.themepark.api.config.enums; + +public enum StorageKey { + + //Database Settings + MYSQL_ENABLED(StorageLocation.SETTINGS, "mysql.enabled"), + MYSQL_URL(StorageLocation.SETTINGS, "mysql.url"), + MYSQL_HOST(StorageLocation.SETTINGS, "mysql.host"), + MYSQL_PORT(StorageLocation.SETTINGS, "mysql.port"), + MYSQL_NAME(StorageLocation.SETTINGS, "mysql.name"), + MYSQL_USERNAME(StorageLocation.SETTINGS, "mysql.username"), + MYSQL_PASSWORD(StorageLocation.SETTINGS, "mysql.password"), + + //Menu Settings + MENU_SIZE_MAIN(StorageLocation.MENU, "menu.main.size"), + MENU_TITLE_MAIN(StorageLocation.MENU, "menu.main.title"), + MENU_TITLE_STATUS(StorageLocation.MENU, "menu.status.title"), + + //Menu Item + MENU_ITEM_ENABLED(StorageLocation.MENU, "menu.item.enabled"), + MENU_ITEM_MATERIAL(StorageLocation.MENU, "menu.item.material"), + MENU_ITEM_DATA(StorageLocation.MENU, "menu.item.data"), + MENU_ITEM_NAME(StorageLocation.MENU, "menu.item.name"), + MENU_ITEM_SLOT(StorageLocation.MENU, "menu.item.slot"), + MENU_ITEM_CLEAR(StorageLocation.MENU, "menu.item.clear"), + MENU_ITEM_WORLDS(StorageLocation.MENU, "menu.item.worlds"), + + //Status Sign + SIGN_STATUS_NAME(StorageLocation.SETTINGS, "sign.status.name"), + SIGN_STATUS_TITLE(StorageLocation.SETTINGS, "sign.status.title"); + + private final StorageLocation location; + private final String path; + StorageKey(StorageLocation location, String path) { + this.location = location; + this.path = path; + } + + /** + * Get storage location key is stored in + * @return StorageLocation + */ + public StorageLocation getLocation() { + return location; + } + + /** + * Get path to value + * @return String + */ + public String getPath() { + return path; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/config/enums/StorageLocation.java b/src/main/java/nl/iobyte/themepark/api/config/enums/StorageLocation.java new file mode 100644 index 0000000..b5ad9a0 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/config/enums/StorageLocation.java @@ -0,0 +1,25 @@ +package nl.iobyte.themepark.api.config.enums; + +public enum StorageLocation { + + SIGN_DATA("sign.yml"), + MESSAGE("message.yml"), + SETTINGS("settings.yml"), + STATUS_SETTINGS("status.yml"), + REGIONS("regions.yml"), + MENU("menu.yml"); + + private final String name; + StorageLocation(String name) { + this.name = name; + } + + /** + * Returns filename of StorageLocation + * @return String + */ + public String getName() { + return name; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/config/objects/Configuration.java b/src/main/java/nl/iobyte/themepark/api/config/objects/Configuration.java new file mode 100644 index 0000000..5517925 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/config/objects/Configuration.java @@ -0,0 +1,170 @@ +package nl.iobyte.themepark.api.config.objects; + +import com.dumptruckman.bukkit.configuration.json.JsonConfiguration; +import nl.iobyte.themepark.logger.ThemeParkLogger; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; +import java.io.File; +import java.util.List; + +public class Configuration { + + private final Plugin plugin; + private File file; + private FileConfiguration config; + private final String fileName; + + public Configuration(Plugin plugin, String fileName, boolean update) { + this.plugin = plugin; + this.fileName = fileName; + load(update); + } + + /** + * Load config from file + */ + private void load(boolean update) { + file = new File(plugin.getDataFolder(), fileName); + if(!file.getParentFile().exists()) { + if (!file.getParentFile().mkdirs()) { + ThemeParkLogger.toConsole("Unable to create parent directories for config file: " + fileName); + return; + } + } + + if(!file.exists()) { + if(plugin.getResource(fileName) == null) { + try { + if(!file.createNewFile()) + ThemeParkLogger.toConsole("Unable to create config file: " + fileName); + } catch(Exception e) { + ThemeParkLogger.toConsole("Unable to create config file: " + fileName); + return; + } + } else { + plugin.saveResource(fileName, true); + } + } + + if(fileName.endsWith(".json")) { + config = JsonConfiguration.loadConfiguration(file); + } else { + config = YamlConfiguration.loadConfiguration(file); + } + + if(!update) + return; + + new ConfigurationUpdater(this).update(); + } + + /** + * Get plugin + * @return Plugin + */ + public Plugin getPlugin() { + return plugin; + } + + /** + * Get file name of configuration + * @return String + */ + public String getFileName() { + return fileName; + } + + /** + * Save config to file + */ + public void save() { + try { + config.save(file); + } catch(Exception e) { + e.printStackTrace(); + } + } + + /** + * Delete config file + */ + public void delete() { + if(!file.delete()) + ThemeParkLogger.toConsole("Unable to remove file: "+fileName); + } + + /** + * Check if config contains path + * @param key Path + * @return Boolean + */ + public boolean contains(String key) { + return config.contains(key); + } + + /** + * Set config value + * @param key Path to value + * @param value Value + */ + public void set(String key, Object value) { + config.set(key, value); + } + + /** + * Get object + * @param key Path to object + * @return Object + */ + public Object get(String key) { + return config.get(key); + } + + /** + * Get string + * @param key Path to string + * @return String + */ + public String getString(String key) { + return config.getString(key); + } + + /** + * Get integer + * @param key Path to integer + * @return Integer + */ + public int getInt(String key) { + return config.getInt(key); + } + + /** + * Get boolean + * @param key Path to boolean + * @return Boolean + */ + public boolean getBoolean(String key) { + return config.getBoolean(key); + } + + /** + * Get List of strings + * @param key Path to list + * @return List of strings + */ + public List getStringList(String key) { + return config.getStringList(key); + } + + /** + * Get section of config + * @param key Path to section + * @return Section of config + */ + public ConfigurationSection getSection(String key) { + return config.getConfigurationSection(key); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/config/objects/ConfigurationUpdater.java b/src/main/java/nl/iobyte/themepark/api/config/objects/ConfigurationUpdater.java new file mode 100644 index 0000000..048cd5e --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/config/objects/ConfigurationUpdater.java @@ -0,0 +1,77 @@ +package nl.iobyte.themepark.api.config.objects; + +import nl.iobyte.themepark.utils.VersionComparator; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +public class ConfigurationUpdater { + + private final Configuration config; + + public ConfigurationUpdater(Configuration config) { + this.config = config; + } + + public String getCurrentVersion() { + if(!config.contains("version")) + return "1.0"; + + return config.getString("version"); + } + + public void update() { + if(config.getFileName().endsWith(".json")) { + return; + } + + InputStream resource = config.getPlugin().getResource(config.getFileName()); + if(resource == null) + return; + + FileConfiguration data; + try(InputStreamReader reader = new InputStreamReader(resource, StandardCharsets.UTF_8)) { + data = YamlConfiguration.loadConfiguration(reader); + } catch (Exception e) { + e.printStackTrace(); + return; + } + + String saved_version = "1.0"; + if(data.contains("version")) + saved_version = data.getString("version"); + + VersionComparator comparator = new VersionComparator(); + int i = comparator.compare(saved_version, getCurrentVersion()); + if(i <= 0) + return; + + insertChanges(data.getConfigurationSection(""), ""); + config.set("version", saved_version); + config.save(); + } + + private void insertChanges(ConfigurationSection section, String root) { + if(section == null || section.getKeys(false).isEmpty()) + return; + + String path; + for(String str : section.getKeys(false)) { + path = root.equals("") ? str : root + "." + str; + ConfigurationSection s = section.getConfigurationSection(str); + if(s != null) { + insertChanges(s, path); + continue; + } + + if(config.contains(path)) + continue; + + config.set(path, section.get(str)); + } + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/database/DatabaseService.java b/src/main/java/nl/iobyte/themepark/api/database/DatabaseService.java new file mode 100644 index 0000000..ad0d139 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/database/DatabaseService.java @@ -0,0 +1,94 @@ +package nl.iobyte.themepark.api.database; + +import nl.iobyte.themepark.api.database.objects.Database; +import nl.iobyte.themepark.api.database.objects.types.NullDatabase; +import nl.iobyte.themepark.scheduler.Task; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +public class DatabaseService { + + private final Map databases = new HashMap<>(); + + /** + * Add Database to DatabaseService + * @param id String + * @param database Database + */ + public void addDatabase(String id, Database database) { + if(id == null || id.isEmpty() || database == null) + return; + + if(databases.containsKey(id)) + return; + + databases.put(id, database); + } + + /** + * Get Database + * @param id String + * @return Database + */ + public Database getDatabase(String id) { + if(id == null || id.isEmpty()) + return new NullDatabase(); + + return databases.getOrDefault(id, new NullDatabase()); + } + + public Task executeAsync(String id, String query, Map objects) { + return getDatabase(id).executeAsync(query, objects); + } + + public boolean execute(String id, String query, Map objects) { + return getDatabase(id).execute(query, objects); + } + + public Task executeUpdateAsync(String id, String query, Map objects) { + return getDatabase(id).executeUpdateAsync(query, objects); + } + + public int executeUpdate(String id, String query, Map objects) { + return getDatabase(id).executeUpdate(query, objects); + } + + public Task>> executeQueryAsync(String id, String query, Map objects) { + return getDatabase(id).executeQueryAsync(query, objects); + } + + public ArrayList> executeQuery(String id, String query, Map objects) { + return getDatabase(id).executeQuery(query, objects); + } + + /** + * Check if Database exists + * @param id String + * @return Boolean + */ + public boolean hasDatabase(String id) { + if(id == null || id.isEmpty()) + return false; + + return databases.containsKey(id); + } + + /** + * Remove Database + * @param id String + */ + public void removeDatabase(String id) { + Database db = databases.remove(id); + if(db == null) + return; + + db.closeConnection(); + } + + public void stop() { + for(Database database : databases.values()) + database.closeConnection(); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/database/objects/Database.java b/src/main/java/nl/iobyte/themepark/api/database/objects/Database.java new file mode 100644 index 0000000..74a4a97 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/database/objects/Database.java @@ -0,0 +1,122 @@ +package nl.iobyte.themepark.api.database.objects; + +import nl.iobyte.themepark.scheduler.ThemeParkScheduler; +import nl.iobyte.themepark.scheduler.Task; + +import java.sql.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +public abstract class Database { + + public abstract Connection getConnection() throws SQLException; + + public abstract void closeConnection(); + + public Task executeAsync(String query, Map objects) { + Task task = new Task<>(); + ThemeParkScheduler.runAsync(() -> task.success(execute( + query, + objects + ))); + + return task; + } + + public boolean execute(String query, Map objects) { + if(query == null || query.isEmpty()) + return false; + + boolean b = false; + try(Connection conn = getConnection()) { + PreparedStatement statement = conn.prepareStatement(query); + statement.closeOnCompletion(); + if(objects != null) + for(Map.Entry entry : objects.entrySet()) + statement.setObject(entry.getKey(), entry.getValue()); + + b = statement.execute(); + } catch(Exception e) { + System.out.println("Query: "+query); + System.out.println("Map: "+objects); + e.printStackTrace(); + } + + return b; + } + + public Task executeUpdateAsync(String query, Map objects) { + Task task = new Task<>(); + ThemeParkScheduler.runAsync(() -> task.success(executeUpdate( + query, + objects + ))); + + return task; + } + + public int executeUpdate(String query, Map objects) { + if (query == null || query.isEmpty()) + return 0; + + int i = 0; + try(Connection conn = getConnection()) { + PreparedStatement statement = conn.prepareStatement(query); + statement.closeOnCompletion(); + for (Map.Entry entry : objects.entrySet()) + statement.setObject(entry.getKey(), entry.getValue()); + + i = statement.executeUpdate(); + } catch (Exception e) { + e.printStackTrace(); + } + + return i; + } + + public Task>> executeQueryAsync(String query, Map objects) { + Task>> task = new Task<>(); + ThemeParkScheduler.runAsync(() -> task.success(executeQuery( + query, + objects + ))); + + return task; + } + + public ArrayList> executeQuery(String query, Map objects) { + if (query == null || query.isEmpty()) + return null; + + ArrayList> set = null; + try(Connection conn = getConnection()) { + PreparedStatement statement = conn.prepareStatement(query); + statement.closeOnCompletion(); + if (objects != null) + for (Map.Entry entry : objects.entrySet()) + statement.setObject(entry.getKey(), entry.getValue()); + + set = new ArrayList<>(); + + ResultSet result = statement.executeQuery(); + ResultSetMetaData metadata = result.getMetaData(); + int columnCount = metadata.getColumnCount(); + while(result.next()) { + Map map = new HashMap<>(); + for(int i = 1; i <= columnCount; i++) + map.put(metadata.getColumnName(i), result.getObject(i)); + + set.add(map); + } + + result.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + return set; + } + +} + diff --git a/src/main/java/nl/iobyte/themepark/api/database/objects/types/MySQLDatabase.java b/src/main/java/nl/iobyte/themepark/api/database/objects/types/MySQLDatabase.java new file mode 100644 index 0000000..500f020 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/database/objects/types/MySQLDatabase.java @@ -0,0 +1,47 @@ +package nl.iobyte.themepark.api.database.objects.types; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.database.objects.Database; +import nl.iobyte.themepark.logger.ThemeParkLogger; +import java.sql.Connection; +import java.sql.SQLException; + +public class MySQLDatabase extends Database { + + private final String dbName; + private final HikariDataSource source; + + public MySQLDatabase(String url, String host, int port, String dbName, String username, String password) { + if(url == null || url.isEmpty()) + url = "jdbc:mysql://%host%:%port%/%database%?useSSL=false"; + + this.dbName = dbName; + HikariConfig config = new HikariConfig(); + config.setPoolName(ThemePark.getInstance().getName()); + config.setUsername(username); + config.setPassword(password); + config.setDriverClassName("com.mysql.jdbc.Driver"); + config.setMaximumPoolSize(5); + config.setJdbcUrl(url.replace("%host%", host).replace("%port%", String.valueOf(port)).replace("%database%", dbName)); + source = new HikariDataSource(config); + } + + /** + * Get Connection + * @return Connection + */ + public Connection getConnection() throws SQLException { + return source.getConnection(); + } + + /** + * Close connection + */ + public void closeConnection() { + ThemeParkLogger.toConsole("Closing the database connection for " + dbName); + source.close(); + } + +} \ No newline at end of file diff --git a/src/main/java/nl/iobyte/themepark/api/database/objects/types/NullDatabase.java b/src/main/java/nl/iobyte/themepark/api/database/objects/types/NullDatabase.java new file mode 100644 index 0000000..bbe10ff --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/database/objects/types/NullDatabase.java @@ -0,0 +1,28 @@ +package nl.iobyte.themepark.api.database.objects.types; + +import nl.iobyte.themepark.api.database.objects.Database; +import java.sql.Connection; +import java.util.ArrayList; +import java.util.Map; + +public class NullDatabase extends Database { + + public Connection getConnection() { + return null; + } + + public void closeConnection() {} + + public boolean execute(String query, Map objects) { + return false; + } + + public int executeUpdate(String query, Map objects) { + return 0; + } + + public ArrayList> executeQuery(String query, Map objects) { + return new ArrayList<>(); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/database/objects/types/SQLiteDatabase.java b/src/main/java/nl/iobyte/themepark/api/database/objects/types/SQLiteDatabase.java new file mode 100644 index 0000000..741e091 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/database/objects/types/SQLiteDatabase.java @@ -0,0 +1,95 @@ +package nl.iobyte.themepark.api.database.objects.types; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.database.objects.Database; +import nl.iobyte.themepark.logger.ThemeParkLogger; +import java.io.File; +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Properties; + +public class SQLiteDatabase extends Database { + + private final String dbName; + private String v; + private HikariDataSource source; + + public SQLiteDatabase(String dbName) { + this.dbName = dbName; + + File dbFile = new File(ThemePark.getInstance().getDataFolder(), dbName + ".db"); + if (!dbFile.exists()) { + try { + ThemeParkLogger.toConsole("Generating the " + dbName + ".db!"); + if (!dbFile.createNewFile()) { + ThemeParkLogger.toConsole("Couldn't generate the " + dbName + ".db!"); + return; + } + } catch (IOException e) { + ThemeParkLogger.toConsole("Couldn't generate the " + dbName + ".db!"); + return; + } + } + + HikariConfig config = new HikariConfig(); + config.setPoolName(ThemePark.getInstance().getName()); + config.setUsername(null); + config.setPassword(null); + config.setDriverClassName("org.sqlite.JDBC"); + config.setConnectionTestQuery("SELECT 1"); + config.setMaximumPoolSize(5); + + Properties prop = new Properties(); + prop.setProperty("date_string_format", "yyyy-MM-dd HH:mm:ss"); + + config.setJdbcUrl("jdbc:sqlite:" + dbFile.getAbsolutePath()); + config.setDataSourceProperties(prop); + source = new HikariDataSource(config); + + try(Connection conn = getConnection()) { + PreparedStatement statement = conn.prepareStatement("SELECT sqlite_version() AS version"); + statement.closeOnCompletion(); + + ResultSet set = statement.executeQuery(); + while(set.next()) { + v = set.getString("version"); + } + + set.close(); + } catch(Exception e) { + e.printStackTrace(); + } + + if(v == null) { + System.out.println("Unable to get SQLite version."); + } else { + System.out.println("SQLite database running on version: "+v); + } + } + + public String getVersion() { + return v; + } + + /** + * Get Database Connection + * @return Connection + */ + public Connection getConnection() throws SQLException { + return source.getConnection(); + } + + /** + * Close Connection + */ + public void closeConnection() { + ThemeParkLogger.toConsole("Closing the database connection for " + dbName + ".db!"); + source.close(); + } + +} \ No newline at end of file diff --git a/src/main/java/nl/iobyte/themepark/api/event/EventDispatcher.java b/src/main/java/nl/iobyte/themepark/api/event/EventDispatcher.java new file mode 100644 index 0000000..332def0 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/EventDispatcher.java @@ -0,0 +1,44 @@ +package nl.iobyte.themepark.api.event; + +import org.bukkit.Bukkit; +import org.bukkit.event.Event; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; + +public class EventDispatcher { + + private final Plugin plugin; + + public EventDispatcher(Plugin plugin) { + this.plugin = plugin; + } + + /** + * Dispatch Event without Callback + * @param event Event + */ + public void call(Event event) { + call(event, null); + } + + /** + * Dispatch Event with Callback + * @param event Event + * @param callback Runnable + */ + public void call(Event event, Runnable callback) { + PluginManager pm = Bukkit.getPluginManager(); + if(Bukkit.isPrimaryThread()) { + pm.callEvent(event); + if(callback != null) + callback.run(); + } else { + Bukkit.getScheduler().runTask(plugin, () -> { + pm.callEvent(event); + if(callback != null) + Bukkit.getScheduler().runTaskAsynchronously(plugin, callback); + }); + } + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionCoverChangeEvent.java b/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionCoverChangeEvent.java new file mode 100644 index 0000000..212bebd --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionCoverChangeEvent.java @@ -0,0 +1,12 @@ +package nl.iobyte.themepark.api.event.attraction; + +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.event.objects.AttractionEvent; + +public class AttractionCoverChangeEvent extends AttractionEvent { + + public AttractionCoverChangeEvent(Attraction attraction, String old, String current) { + super(attraction, old, current); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionCreateEvent.java b/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionCreateEvent.java new file mode 100644 index 0000000..690cd9d --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionCreateEvent.java @@ -0,0 +1,13 @@ +package nl.iobyte.themepark.api.event.attraction; + +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.event.objects.AttractionEvent; + +public class AttractionCreateEvent extends AttractionEvent { + + public AttractionCreateEvent(Attraction attraction) { + super(attraction, null, null); + } + +} + diff --git a/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionDescriptionChangeEvent.java b/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionDescriptionChangeEvent.java new file mode 100644 index 0000000..e096887 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionDescriptionChangeEvent.java @@ -0,0 +1,12 @@ +package nl.iobyte.themepark.api.event.attraction; + +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.event.objects.AttractionEvent; + +public class AttractionDescriptionChangeEvent extends AttractionEvent { + + public AttractionDescriptionChangeEvent(Attraction attraction, String old, String current) { + super(attraction, old, current); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionLocationChangeEvent.java b/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionLocationChangeEvent.java new file mode 100644 index 0000000..4b0aff9 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionLocationChangeEvent.java @@ -0,0 +1,13 @@ +package nl.iobyte.themepark.api.event.attraction; + +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.event.objects.AttractionEvent; +import org.bukkit.Location; + +public class AttractionLocationChangeEvent extends AttractionEvent { + + public AttractionLocationChangeEvent(Attraction attraction, Location old, Location current) { + super(attraction, old, current); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionNameChangeEvent.java b/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionNameChangeEvent.java new file mode 100644 index 0000000..0fa476b --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionNameChangeEvent.java @@ -0,0 +1,12 @@ +package nl.iobyte.themepark.api.event.attraction; + +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.event.objects.AttractionEvent; + +public class AttractionNameChangeEvent extends AttractionEvent { + + public AttractionNameChangeEvent(Attraction attraction, String old, String current) { + super(attraction, old, current); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionRegionChangeEvent.java b/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionRegionChangeEvent.java new file mode 100644 index 0000000..aab6673 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionRegionChangeEvent.java @@ -0,0 +1,12 @@ +package nl.iobyte.themepark.api.event.attraction; + +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.event.objects.AttractionEvent; + +public class AttractionRegionChangeEvent extends AttractionEvent { + + public AttractionRegionChangeEvent(Attraction attraction, String old, String current) { + super(attraction, old, current); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionRemoveEvent.java b/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionRemoveEvent.java new file mode 100644 index 0000000..35ec811 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionRemoveEvent.java @@ -0,0 +1,13 @@ +package nl.iobyte.themepark.api.event.attraction; + +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.event.objects.AttractionEvent; + +public class AttractionRemoveEvent extends AttractionEvent { + + public AttractionRemoveEvent(Attraction attraction) { + super(attraction, null, null); + } + +} + diff --git a/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionStatusChangeEvent.java b/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionStatusChangeEvent.java new file mode 100644 index 0000000..ea99cb2 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/attraction/AttractionStatusChangeEvent.java @@ -0,0 +1,13 @@ +package nl.iobyte.themepark.api.event.attraction; + +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.event.objects.AttractionEvent; + +public class AttractionStatusChangeEvent extends AttractionEvent { + + public AttractionStatusChangeEvent(Attraction attraction, Status old, Status current) { + super(attraction, old, current); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/objects/AttractionEvent.java b/src/main/java/nl/iobyte/themepark/api/event/objects/AttractionEvent.java new file mode 100644 index 0000000..b7f703a --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/objects/AttractionEvent.java @@ -0,0 +1,18 @@ +package nl.iobyte.themepark.api.event.objects; + +import nl.iobyte.themepark.api.attraction.objects.Attraction; + +public class AttractionEvent extends ChangeEvent { + + private final Attraction attraction; + + public AttractionEvent(Attraction attraction, T old, T current) { + super(old, current); + this.attraction = attraction; + } + + public Attraction getAttraction() { + return attraction; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/objects/ChangeEvent.java b/src/main/java/nl/iobyte/themepark/api/event/objects/ChangeEvent.java new file mode 100644 index 0000000..b1f23af --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/objects/ChangeEvent.java @@ -0,0 +1,32 @@ +package nl.iobyte.themepark.api.event.objects; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class ChangeEvent extends Event { + + private static final HandlerList handlers = new HandlerList(); + private final T old, current; + + public ChangeEvent(T old, T current) { + this.old = old; + this.current = current; + } + + public T getOld() { + return old; + } + + public T getCurrent() { + return current; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/objects/RegionEvent.java b/src/main/java/nl/iobyte/themepark/api/event/objects/RegionEvent.java new file mode 100644 index 0000000..f78aa1b --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/objects/RegionEvent.java @@ -0,0 +1,18 @@ +package nl.iobyte.themepark.api.event.objects; + +import nl.iobyte.themepark.api.attraction.objects.Region; + +public class RegionEvent extends ChangeEvent { + + private final Region region; + + public RegionEvent(Region region, T old, T current) { + super(old, current); + this.region = region; + } + + public Region getRegion() { + return region; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/objects/StatusEvent.java b/src/main/java/nl/iobyte/themepark/api/event/objects/StatusEvent.java new file mode 100644 index 0000000..24cefc2 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/objects/StatusEvent.java @@ -0,0 +1,18 @@ +package nl.iobyte.themepark.api.event.objects; + +import nl.iobyte.themepark.api.attraction.enums.Status; + +public class StatusEvent extends ChangeEvent { + + private final Status status; + + public StatusEvent(Status status, T old, T current) { + super(old, current); + this.status = status; + } + + public Status getStatus() { + return status; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/region/RegionCreateEvent.java b/src/main/java/nl/iobyte/themepark/api/event/region/RegionCreateEvent.java new file mode 100644 index 0000000..e286e75 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/region/RegionCreateEvent.java @@ -0,0 +1,13 @@ +package nl.iobyte.themepark.api.event.region; + +import nl.iobyte.themepark.api.attraction.objects.Region; +import nl.iobyte.themepark.api.event.objects.RegionEvent; + +public class RegionCreateEvent extends RegionEvent { + + public RegionCreateEvent(Region region) { + super(region, null, null); + } + +} + diff --git a/src/main/java/nl/iobyte/themepark/api/event/region/RegionNameChangeEvent.java b/src/main/java/nl/iobyte/themepark/api/event/region/RegionNameChangeEvent.java new file mode 100644 index 0000000..03b05be --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/region/RegionNameChangeEvent.java @@ -0,0 +1,12 @@ +package nl.iobyte.themepark.api.event.region; + +import nl.iobyte.themepark.api.attraction.objects.Region; +import nl.iobyte.themepark.api.event.objects.RegionEvent; + +public class RegionNameChangeEvent extends RegionEvent { + + public RegionNameChangeEvent(Region region, String old, String current) { + super(region, old, current); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/region/RegionRemoveEvent.java b/src/main/java/nl/iobyte/themepark/api/event/region/RegionRemoveEvent.java new file mode 100644 index 0000000..621491e --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/region/RegionRemoveEvent.java @@ -0,0 +1,13 @@ +package nl.iobyte.themepark.api.event.region; + +import nl.iobyte.themepark.api.attraction.objects.Region; +import nl.iobyte.themepark.api.event.objects.RegionEvent; + +public class RegionRemoveEvent extends RegionEvent { + + public RegionRemoveEvent(Region region) { + super(region, null, null); + } + +} + diff --git a/src/main/java/nl/iobyte/themepark/api/event/ridecount/RideCountAddEvent.java b/src/main/java/nl/iobyte/themepark/api/event/ridecount/RideCountAddEvent.java new file mode 100644 index 0000000..904ef23 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/ridecount/RideCountAddEvent.java @@ -0,0 +1,19 @@ +package nl.iobyte.themepark.api.event.ridecount; + +import nl.iobyte.themepark.api.event.objects.ChangeEvent; +import nl.iobyte.themepark.api.ridecount.objects.RideCount; + +public class RideCountAddEvent extends ChangeEvent { + + private final RideCount count; + + public RideCountAddEvent(RideCount count, int old, int current) { + super(old, current); + this.count = count; + } + + public RideCount getRideCount() { + return count; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/status/StatusColorChangeEvent.java b/src/main/java/nl/iobyte/themepark/api/event/status/StatusColorChangeEvent.java new file mode 100644 index 0000000..7278e73 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/status/StatusColorChangeEvent.java @@ -0,0 +1,12 @@ +package nl.iobyte.themepark.api.event.status; + +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.event.objects.StatusEvent; + +public class StatusColorChangeEvent extends StatusEvent { + + public StatusColorChangeEvent(Status status, String old, String current) { + super(status, old, current); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/status/StatusHexColorChangeEvent.java b/src/main/java/nl/iobyte/themepark/api/event/status/StatusHexColorChangeEvent.java new file mode 100644 index 0000000..9a9a0ba --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/status/StatusHexColorChangeEvent.java @@ -0,0 +1,12 @@ +package nl.iobyte.themepark.api.event.status; + +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.event.objects.StatusEvent; + +public class StatusHexColorChangeEvent extends StatusEvent { + + public StatusHexColorChangeEvent(Status status, String old, String current) { + super(status, old, current); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/status/StatusMaterialChangeEvent.java b/src/main/java/nl/iobyte/themepark/api/event/status/StatusMaterialChangeEvent.java new file mode 100644 index 0000000..ad383b0 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/status/StatusMaterialChangeEvent.java @@ -0,0 +1,13 @@ +package nl.iobyte.themepark.api.event.status; + +import com.cryptomorin.xseries.XMaterial; +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.event.objects.StatusEvent; + +public class StatusMaterialChangeEvent extends StatusEvent { + + public StatusMaterialChangeEvent(Status status, XMaterial old, XMaterial current) { + super(status, old, current); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/status/StatusNameChangeEvent.java b/src/main/java/nl/iobyte/themepark/api/event/status/StatusNameChangeEvent.java new file mode 100644 index 0000000..c67b427 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/status/StatusNameChangeEvent.java @@ -0,0 +1,12 @@ +package nl.iobyte.themepark.api.event.status; + +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.event.objects.StatusEvent; + +public class StatusNameChangeEvent extends StatusEvent { + + public StatusNameChangeEvent(Status status, String old, String current) { + super(status, old, current); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/event/status/StatusTeleportChangeEvent.java b/src/main/java/nl/iobyte/themepark/api/event/status/StatusTeleportChangeEvent.java new file mode 100644 index 0000000..0821732 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/event/status/StatusTeleportChangeEvent.java @@ -0,0 +1,12 @@ +package nl.iobyte.themepark.api.event.status; + +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.event.objects.StatusEvent; + +public class StatusTeleportChangeEvent extends StatusEvent { + + public StatusTeleportChangeEvent(Status status, boolean old, boolean current) { + super(status, old, current); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/load/DataLoadService.java b/src/main/java/nl/iobyte/themepark/api/load/DataLoadService.java new file mode 100644 index 0000000..2c707fe --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/load/DataLoadService.java @@ -0,0 +1,35 @@ +package nl.iobyte.themepark.api.load; + +import nl.iobyte.themepark.api.load.interfaces.IDataLoader; +import nl.iobyte.themepark.api.load.objects.*; +import java.util.ArrayList; +import java.util.List; + +public class DataLoadService { + + private final List loaders = new ArrayList<>(); + + public DataLoadService() { + addLoader(new DatabaseLoader()); + addLoader(new StatusDataLoader()); + addLoader(new SignDataLoader()); + addLoader(new MenuDataLoader()); + } + + /** + * Add IDataLoader + * @param dataLoader IDataLoader + */ + public void addLoader(IDataLoader dataLoader) { + loaders.add(dataLoader); + } + + /** + * Call all IDataLoaders + */ + public void init() { + for(IDataLoader loader : loaders) + loader.load(); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/load/interfaces/IDataLoader.java b/src/main/java/nl/iobyte/themepark/api/load/interfaces/IDataLoader.java new file mode 100644 index 0000000..fbecf49 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/load/interfaces/IDataLoader.java @@ -0,0 +1,10 @@ +package nl.iobyte.themepark.api.load.interfaces; + +public interface IDataLoader { + + /** + * Called when loading data + */ + void load(); + +} diff --git a/src/main/java/nl/iobyte/themepark/api/load/objects/DatabaseLoader.java b/src/main/java/nl/iobyte/themepark/api/load/objects/DatabaseLoader.java new file mode 100644 index 0000000..ec78a3b --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/load/objects/DatabaseLoader.java @@ -0,0 +1,68 @@ +package nl.iobyte.themepark.api.load.objects; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.ThemeParkAPI; +import nl.iobyte.themepark.api.config.ConfigurationManager; +import nl.iobyte.themepark.api.config.enums.StorageKey; +import nl.iobyte.themepark.api.database.DatabaseService; +import nl.iobyte.themepark.api.database.objects.types.MySQLDatabase; +import nl.iobyte.themepark.api.database.objects.types.SQLiteDatabase; +import nl.iobyte.themepark.api.load.interfaces.IDataLoader; + +public class DatabaseLoader implements IDataLoader { + + public void load() { + ThemeParkAPI api = ThemePark.getInstance().getAPI(); + DatabaseService service = api.getDatabaseService(); + ConfigurationManager manager = api.getConfigurationManager(); + + //Add SQLite Database + service.addDatabase( + "local", + new SQLiteDatabase("sqlite") + ); + + if(manager.getBoolean(StorageKey.MYSQL_ENABLED)) + service.addDatabase( + "remote", + new MySQLDatabase( + manager.getString(StorageKey.MYSQL_URL), + manager.getString(StorageKey.MYSQL_HOST), + manager.getInt(StorageKey.MYSQL_PORT), + manager.getString(StorageKey.MYSQL_NAME), + manager.getString(StorageKey.MYSQL_USERNAME), + manager.getString(StorageKey.MYSQL_PASSWORD) + ) + ); + + //Create Database tables + loadTables(service); + } + + private void loadTables(DatabaseService service) { + //Create SQLite Tables + service.execute( + "local", + "CREATE TABLE IF NOT EXISTS counts(uuid VARCHAR(255) NOT NULL, attraction_id VARCHAR(255) NOT NULL, year SMALLINT(2), month SMALLINT(2), week SMALLINT(2), day SMALLINT(2), count SMALLINT(2), UNIQUE(uuid, attraction_id, year, day))", + null + ); + + //Create MySQL Tables + service.execute( + "remote", + "CREATE TABLE IF NOT EXISTS regions(id VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))", + null + ); + service.execute( + "remote", + "CREATE TABLE IF NOT EXISTS attractions(id VARCHAR(255) NOT NULL, region_id VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, cover VARCHAR(255) NOT NULL, status_id INT(11), PRIMARY KEY(id))", + null + ); + service.execute( + "remote", + "CREATE TABLE IF NOT EXISTS states(id INT(11), name VARCHAR(255) NOT NULL, color VARCHAR(7) NOT NULL, PRIMARY KEY(id))", + null + ); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/load/objects/MenuDataLoader.java b/src/main/java/nl/iobyte/themepark/api/load/objects/MenuDataLoader.java new file mode 100644 index 0000000..3a4eb5c --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/load/objects/MenuDataLoader.java @@ -0,0 +1,18 @@ +package nl.iobyte.themepark.api.load.objects; + +import nl.iobyte.menuapi.MenuAPI; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.load.interfaces.IDataLoader; +import nl.iobyte.themepark.api.menu.objects.handlers.StatusMenuHandler; + +public class MenuDataLoader implements IDataLoader { + + public void load() { + //Register default IActionHandlers + MenuAPI.addActionHandler(new StatusMenuHandler()); + + //Load Menu's + ThemePark.getInstance().getAPI().getMenuService().init(); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/load/objects/SignDataLoader.java b/src/main/java/nl/iobyte/themepark/api/load/objects/SignDataLoader.java new file mode 100644 index 0000000..f783055 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/load/objects/SignDataLoader.java @@ -0,0 +1,50 @@ +package nl.iobyte.themepark.api.load.objects; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.ThemeParkAPI; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.config.ConfigurationManager; +import nl.iobyte.themepark.api.config.enums.StorageLocation; +import nl.iobyte.themepark.api.load.interfaces.IDataLoader; +import nl.iobyte.themepark.api.sign.objects.StatusSign; +import nl.iobyte.themepark.utils.LocationUtil; +import org.bukkit.Location; +import org.bukkit.block.Sign; +import java.util.List; + +public class SignDataLoader implements IDataLoader { + + /** + * Called when loading data + */ + public void load() { + ThemeParkAPI api = ThemePark.getInstance().getAPI(); + ConfigurationManager manager = api.getConfigurationManager(); + + for(Attraction attraction : api.getAttractionService().getAttractions().values()) { + if(attraction == null) { + return; + } + + if(!manager.contains(StorageLocation.SIGN_DATA, "signs." + attraction.getID())) { + return; + } + + List locations = manager.getStringList(StorageLocation.SIGN_DATA, "signs." + attraction.getID()); + for(String string : locations) { + Location location = LocationUtil.fromString(string); + if(location == null) { + continue; + } + + + if(!(location.getBlock().getState() instanceof Sign)) { + continue; + } + + api.getSignManager().addSign(new StatusSign(attraction, location)); + } + } + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/load/objects/StatusDataLoader.java b/src/main/java/nl/iobyte/themepark/api/load/objects/StatusDataLoader.java new file mode 100644 index 0000000..be46f13 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/load/objects/StatusDataLoader.java @@ -0,0 +1,191 @@ +package nl.iobyte.themepark.api.load.objects; + +import com.cryptomorin.xseries.XMaterial; +import com.google.common.base.Strings; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.ThemeParkAPI; +import nl.iobyte.themepark.api.attraction.AttractionService; +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.attraction.objects.Region; +import nl.iobyte.themepark.api.config.enums.StorageKey; +import nl.iobyte.themepark.api.config.objects.Configuration; +import nl.iobyte.themepark.api.config.ConfigurationManager; +import nl.iobyte.themepark.api.config.enums.StorageLocation; +import nl.iobyte.themepark.api.database.objects.Database; +import nl.iobyte.themepark.api.load.interfaces.IDataLoader; +import nl.iobyte.themepark.utils.LocationUtil; +import org.bukkit.Location; +import org.bukkit.configuration.ConfigurationSection; +import java.util.HashMap; +import java.util.Map; + +public class StatusDataLoader implements IDataLoader { + + /** + * Called when loading data + */ + public void load() { + ThemeParkAPI api = ThemePark.getInstance().getAPI(); + ConfigurationManager manager = api.getConfigurationManager(); + + //Load data + loadStatus(manager); + loadRegions(api, manager); + + //Insert into Database + prepareDatabase(api); + } + + private void loadStatus(ConfigurationManager manager) { + if(!manager.contains(StorageLocation.STATUS_SETTINGS, "states")) + return; + + ConfigurationSection section = manager.getSection(StorageLocation.STATUS_SETTINGS, "states"); + if(section.getKeys(false).isEmpty()) + return; + + Status status; + String path; + for(String id : section.getKeys(false)) { + status = Status.get(id); + if(status == null) + continue; + + path = "states."+id; + if(manager.contains(StorageLocation.STATUS_SETTINGS, path+".name")) + status.setName(manager.getString(StorageLocation.STATUS_SETTINGS, path+".name")); + + if(manager.contains(StorageLocation.STATUS_SETTINGS, path+".color")) + status.setColor(manager.getString(StorageLocation.STATUS_SETTINGS, path+".color")); + + if(manager.contains(StorageLocation.STATUS_SETTINGS, path+".hex_color")) + status.setHexColor(manager.getString(StorageLocation.STATUS_SETTINGS, path+".hex_color")); + + if(manager.contains(StorageLocation.STATUS_SETTINGS, path+".teleport")) + status.setCanTeleport(manager.getBoolean(StorageLocation.STATUS_SETTINGS, path+".teleport")); + + XMaterial material = null; + if(manager.contains(StorageLocation.STATUS_SETTINGS, path+".material")) + material = XMaterial.matchXMaterial(manager.getString(StorageLocation.STATUS_SETTINGS, path + ".material")).orElse(XMaterial.RED_CONCRETE); + + if(material == null) + continue; + + status.setMaterial(material); + } + } + + /** + * Load Regions from config + * @param api ThemeParkAPI + * @param manager ConfigurationManager + */ + private void loadRegions(ThemeParkAPI api, ConfigurationManager manager) { + //See if any regions exist + AttractionService attractionService = api.getAttractionService(); + if(!manager.contains(StorageLocation.REGIONS, "regions")) + return; + + ConfigurationSection section = manager.getSection(StorageLocation.REGIONS, "regions"); + if(section.getKeys(false).isEmpty()) + return; + + //Load regions + for(String id : section.getKeys(false)) { + String name = manager.getString(StorageLocation.REGIONS, "regions."+id+".name"); + + Region region = new Region(id, name); + attractionService.addRegion(region); + loadAttractions(api, region); //try loading Attractions for Region + } + } + + /** + * Load Attractions for specific Region + * @param api ThemeParkAPI + * @param region Region + */ + private void loadAttractions(ThemeParkAPI api, Region region) { + //See if any attractions exist + Configuration config = region.getConfiguration(); + if(!config.contains("attractions")) + return; + + ConfigurationSection section = config.getSection("attractions"); + if(section.getKeys(false).isEmpty()) + return; + + //Load Attractions + for(String id : section.getKeys(false)) { + String name = config.getString("attractions."+id+".name"); + String cover = config.getString("attractions."+id+".cover"); + Status status = Status.get(config.getString("attractions."+id+".status")); + Location location = LocationUtil.fromString(config.getString("attractions."+id+".location")); + + Attraction attraction = new Attraction(id, region.getID(), name, cover, status, location); + api.getAttractionService().addAttraction(attraction); + } + } + + private void prepareDatabase(ThemeParkAPI api) { + AttractionService service = api.getAttractionService(); + Database db = api.getDatabaseService().getDatabase("remote"); + + //Variables + int size; + Map parameters = new HashMap<>(); + + //Prepare Status Query Parameters + for(Status status : Status.values()) { + size = parameters.size(); + parameters.put(size + 1, status.getID()); + parameters.put(size + 2, status.getName()); + parameters.put(size + 3, status.getHexColor()); + } + + //Execute Status Query + db.executeAsync( + "INSERT IGNORE INTO states(id, name, color) VALUES "+ Strings.repeat("(?,?,?),", Status.values().length - 1)+"(?,?,?)", + new HashMap<>(parameters) + ); + + //Prepare Region Query Parameters + parameters.clear(); + for(Region region : service.getRegions().values()) { + size = parameters.size(); + parameters.put(size + 1, region.getID()); + parameters.put(size + 2, region.getName()); + } + + if(parameters.isEmpty()) + return; + + //Execute Region Query + db.executeAsync( + "INSERT IGNORE INTO regions(id, name) VALUES "+ Strings.repeat("(?,?),", service.getRegions().values().size() - 1)+"(?,?)", + new HashMap<>(parameters) + ); + + //Prepare Attraction Query Parameters + parameters.clear(); + for(Attraction attraction : service.getAttractions().values()) { + size = parameters.size(); + parameters.put(size + 1, attraction.getID()); + parameters.put(size + 2, attraction.getRegionID()); + parameters.put(size + 3, attraction.getName()); + parameters.put(size + 4, attraction.getCover()); + parameters.put(size + 5, attraction.getStatus().getID()); + } + + if(parameters.isEmpty()) + return; + + //Execute Region Query + db.executeAsync( + "INSERT IGNORE INTO attractions(id, region_id, name, cover, status_id) VALUES "+ Strings.repeat("(?,?,?,?,?),", service.getAttractions().values().size() - 1)+"(?,?,?,?,?)", + parameters + ); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/menu/MenuService.java b/src/main/java/nl/iobyte/themepark/api/menu/MenuService.java new file mode 100644 index 0000000..84cd921 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/menu/MenuService.java @@ -0,0 +1,35 @@ +package nl.iobyte.themepark.api.menu; + +import nl.iobyte.themepark.api.menu.objects.MainMenu; +import nl.iobyte.themepark.api.menu.objects.StatusMenu; + +public class MenuService { + + private final MainMenu mainMenu = new MainMenu(); + private final StatusMenu statusMenu = new StatusMenu(); + + /** + * Load all menu's + */ + public void init() { + mainMenu.load(); + statusMenu.load(); + } + + /** + * Get main menu + * @return MainMenu + */ + public MainMenu getMainMenu() { + return mainMenu; + } + + /** + * Get status menu + * @return StatusMenu + */ + public StatusMenu getStatusMenu() { + return statusMenu; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/menu/objects/MainMenu.java b/src/main/java/nl/iobyte/themepark/api/menu/objects/MainMenu.java new file mode 100644 index 0000000..bc5eab6 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/menu/objects/MainMenu.java @@ -0,0 +1,129 @@ +package nl.iobyte.themepark.api.menu.objects; + +import nl.iobyte.menuapi.MenuAPI; +import nl.iobyte.menuapi.action.HandlerAction; +import nl.iobyte.menuapi.basic.Menu; +import nl.iobyte.menuapi.interfaces.IActionHandler; +import nl.iobyte.menuapi.item.ItemBuilder; +import nl.iobyte.menuapi.item.MenuItem; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.config.ConfigurationManager; +import nl.iobyte.themepark.api.config.enums.StorageKey; +import nl.iobyte.themepark.api.config.enums.StorageLocation; +import nl.iobyte.themepark.api.menu.objects.handlers.CommandMenuHandler; +import nl.iobyte.themepark.api.menu.objects.handlers.JsonMessageMenuHandler; +import nl.iobyte.themepark.api.menu.objects.handlers.PlainMessageMenuHandler; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; + +public class MainMenu { + + private Menu menu; + + public void load() { + ConfigurationManager manager = ThemePark.getInstance().getAPI().getConfigurationManager(); + + //Prepare Menu + menu = new Menu(manager.getString(StorageKey.MENU_TITLE_MAIN), manager.getInt(StorageKey.MENU_SIZE_MAIN)); + + //Load Items + loadItems(manager); + + //Build Menu + menu.build(); + } + + private void loadItems(ConfigurationManager manager) { + //See if any items exist + if(!manager.contains(StorageLocation.MENU, "items")) + return; + + ConfigurationSection section = manager.getSection(StorageLocation.MENU, "items"); + if(section.getKeys(false).isEmpty()) + return; + + //Load items + String path; + ItemBuilder builder; + MenuItem item; + IActionHandler handler; + for(String id : section.getKeys(false)) { + path = "items."+id; + + int slot = manager.getInt(StorageLocation.MENU, path+".slot"); + if(slot < 0 || slot >= menu.getSize()) + continue; + + String name = manager.getString(StorageLocation.MENU, path+".name"); + if(name == null || name.equals("")) + name = " "; + + Material material = Material.getMaterial(manager.getString(StorageLocation.MENU, path+".material")); + if(material == null) + continue; + + int amount = manager.getInt(StorageLocation.MENU, path+".amount"); + if(amount < 1) + amount = 1; + + short data = Short.parseShort(manager.getString(StorageLocation.MENU, path+".data")); + if(data < 0) + continue; + + builder = new ItemBuilder(material, amount, data); + builder.setName(name); + + String lore = manager.getString(StorageLocation.MENU, path+".lore"); + if(lore == null || lore.equals("")) { + builder.setLore(manager.getStringList(StorageLocation.MENU, path+".lore")); + } else { + builder.setLore(lore); + } + + item = new MenuItem( + builder.getItem(), + true + ); + + handler = getHandler(manager, path); + if(handler != null) { + item.addActions(handler); + } else { + item.addActions(new HandlerAction( + manager.getString(StorageLocation.MENU, path+".action") + )); + } + + menu.setItem( + slot, + item + ); + } + } + + private IActionHandler getHandler(ConfigurationManager manager, String path) { + String action = manager.getString(StorageLocation.MENU, path+".action"); + if(action == null || action.isEmpty()) + return null; + + if(MenuAPI.hasActionHandler(action)) + return MenuAPI.getActionHandler(action); + + switch (action.toUpperCase()) { + case "COMMAND": + return new CommandMenuHandler(manager.getString(StorageLocation.MENU, path+".command")); + case "JSON_MESSAGE": + return new JsonMessageMenuHandler(manager.getString(StorageLocation.MENU, path+".message")); + case "PLAIN_MESSAGE": + return new PlainMessageMenuHandler(manager.getString(StorageLocation.MENU, path+".message")); + default: + return null; + } + } + + public void open(Player player) { + menu.open(player); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/menu/objects/StatusMenu.java b/src/main/java/nl/iobyte/themepark/api/menu/objects/StatusMenu.java new file mode 100644 index 0000000..1e4c72f --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/menu/objects/StatusMenu.java @@ -0,0 +1,276 @@ +package nl.iobyte.themepark.api.menu.objects; + +import com.google.common.collect.Iterables; +import nl.iobyte.menuapi.enums.Types; +import nl.iobyte.menuapi.item.ItemBuilder; +import nl.iobyte.menuapi.item.MenuItem; +import nl.iobyte.menuapi.multi.MenuPage; +import nl.iobyte.menuapi.multi.MultiMenu; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.ThemeParkAPI; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.attraction.objects.Region; +import nl.iobyte.themepark.api.config.enums.StorageKey; +import nl.iobyte.themepark.api.menu.objects.actions.PageAction; +import nl.iobyte.themepark.api.menu.objects.actions.TPAction; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; + +public class StatusMenu { + + private MultiMenu menu; + private final HashMap> region_index = new HashMap<>(); + private final HashMap attraction_index = new HashMap<>(); + + /** + * Load the menu + */ + public void load() { + ThemeParkAPI api = ThemePark.getInstance().getAPI(); + region_index.clear(); + attraction_index.clear(); + + //Prepare data + LinkedHashMap regions = new LinkedHashMap<>(); + LinkedHashMap> attractions = new LinkedHashMap<>(); + for(Region region : api.getAttractionService().getRegions().values()) { + if(region.getAttractions().isEmpty()) { + regions.put(regions.size(), region); + attractions.put(attractions.size(), new ArrayList<>()); + continue; + } + + + Iterable> iterable = Iterables.partition(region.getAttractions().values(), 8); + for(List list : iterable) { + regions.put(regions.size(), region); + attractions.put(attractions.size(), list); + } + } + + //Prepare menu + loadMenuPages(api, regions.size()); + + //Load menu content + loadMenuContent(regions, attractions); + + //Load next/previous page items + loadPageItems(); + + //Build Menu + menu.build(); + } + + /** + * Update Region item + * @param region Region + */ + public void updateRegion(Region region) { + if(region == null) + return; + + if(!region_index.containsKey(region.getID())) + return; + + List indexes = region_index.get(region.getID()); + if(indexes == null || indexes.isEmpty()) + return; + + for(int slot : indexes) { + menu.setItem(slot, getRegion(region)); + menu.updateItem(slot); + } + } + + /** + * Update Attraction item + * @param attraction Attraction + */ + public void updateAttraction(Attraction attraction) { + if(attraction == null) + return; + + if(!attraction_index.containsKey(attraction.getID())) + return; + + int slot = attraction_index.get(attraction.getID()); + if(slot < 1) + return; + + menu.setItem(slot, getAttraction(attraction)); + menu.updateItem(slot); + } + + /** + * Open menu on first page for Player + * @param player Player + */ + public void open(Player player) { + open(player, 1); + } + + /** + * Open menu for Player + * @param player Player + * @param page Integer + */ + public void open(Player player, int page) { + menu.open(player, page); + } + + /** + * Initialize menu and page sizes + * @param api ThemeParkAPI + * @param regions Integer + */ + private void loadMenuPages(ThemeParkAPI api, int regions) { + ArrayList page_sizes = new ArrayList<>(); + if(regions <= 6) { + if(regions == 0) + regions = 1; + + page_sizes.add(regions * 9); + } else { + int pages = regions / 5; + for (int i = 0; i < pages; i++) + page_sizes.add(54); + + pages = regions % 5; + if (pages > 0) + page_sizes.add(pages * 9 + 9); + } + + menu = new MultiMenu(api.getConfigurationManager().getString(StorageKey.MENU_TITLE_STATUS), page_sizes); + } + + /** + * Add regions and attractions to menu + * @param regions LinkedHashMap + * @param attractions LinkedHashMap> + */ + private void loadMenuContent(LinkedHashMap regions, LinkedHashMap> attractions) { + int region_size = regions.size(); + for(int i = 0; i < region_size; i++) { + Region region = regions.get(i); + if(region == null) + continue; + + int j = 1; + int start_index = i * 9; + if(region_size > 6) + start_index += (i / 5) * 9; + + //Add item index to map + List indexes = region_index.computeIfAbsent(region.getID(), s -> new ArrayList<>()); + indexes.add(start_index); + region_index.put(region.getID(), indexes); + + //Add item to menu + menu.setItem(start_index, new MenuItem(getRegion(region), true)); + + List list = attractions.get(i); + if(list == null) + continue; + + //Add attractions to menu + for(Attraction attraction : list) { + MenuItem item = new MenuItem(getAttraction(attraction), true); + item.addActions(Types.NORMAL.getTypesList(), new TPAction(attraction)); + + int slot = start_index + j; + attraction_index.put(attraction.getID(), slot); + menu.setItem(slot, item); + j++; + } + } + } + + /** + * Load next/previous page items + */ + private void loadPageItems() { + int page_size = menu.getPageSizes().size(); + for (int i = 0; i < page_size; i++) { + MenuPage page = menu.getPage(i + 1); + int size = page.getSize(); + if (i > 0) + page.setItem(size - 6, getPrevious(i)); + + if (i < (page_size - 1)) + page.setItem(size - 4, getNext(i)); + + if(page_size > 1) { + ItemBuilder builder = new ItemBuilder(Material.MINECART); + builder.setName("&6Page: &f" + (i + 1)); + page.setItem(size - 5, new MenuItem(builder.getItem(), true)); + } + } + } + + /** + * Get ItemStack of Region + * @param region Region + * @return ItemStack + */ + private static ItemStack getRegion(Region region) { + ItemBuilder builder = new ItemBuilder(Material.NAME_TAG); + builder.setName(region.getName()); + + return builder.getItem(); + } + + /** + * Get ItemStack of Attraction + * @param attraction Attraction + * @return ItemStack + */ + private static ItemStack getAttraction(Attraction attraction) { + ItemBuilder builder = new ItemBuilder(attraction.getStatus().getItem()); + builder.setName(attraction.getName()) + .setLore(attraction.getStatus().getColor() + attraction.getStatus().getName()); + + return builder.getItem(); + } + + /** + * Get next page MenuItem + * @param page Integer + * @return MenuItem + */ + private MenuItem getNext(int page) { + return getPage("&6&LNext \u23F5", page + 1); + } + + /** + * Get previous page MenuItem + * @param page Integer + * @return MenuItem + */ + private MenuItem getPrevious(int page) { + return getPage("&6&L\u23F4 Previous", page - 1); + } + + /** + * Get next/previous page MenuItem + * @param text String + * @param page Integer + * @return MenuItem + */ + private MenuItem getPage(String text, int page) { + ItemBuilder builder = new ItemBuilder(Material.ARROW); + builder.setName(text); + + MenuItem item = new MenuItem(builder.getItem(), true); + item.addActions(new PageAction( + menu, + page + 1 + )); + return item; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/menu/objects/actions/PageAction.java b/src/main/java/nl/iobyte/themepark/api/menu/objects/actions/PageAction.java new file mode 100644 index 0000000..85df751 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/menu/objects/actions/PageAction.java @@ -0,0 +1,21 @@ +package nl.iobyte.themepark.api.menu.objects.actions; + +import nl.iobyte.menuapi.action.MenuAction; +import nl.iobyte.menuapi.multi.MultiMenu; +import org.bukkit.entity.Player; + +public class PageAction extends MenuAction { + + private final MultiMenu menu; + private final int page; + + public PageAction(MultiMenu menu, int page) { + this.menu = menu; + this.page = page; + } + + public void execute(Player player) { + menu.open(player, page); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/menu/objects/actions/TPAction.java b/src/main/java/nl/iobyte/themepark/api/menu/objects/actions/TPAction.java new file mode 100644 index 0000000..c0befb8 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/menu/objects/actions/TPAction.java @@ -0,0 +1,20 @@ +package nl.iobyte.themepark.api.menu.objects.actions; + +import nl.iobyte.menuapi.action.MenuAction; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +public class TPAction extends MenuAction { + + private final Attraction attraction; + + public TPAction(Attraction attraction) { + this.attraction = attraction; + } + + public void execute(Player player) { + Bukkit.dispatchCommand(player, "pp attraction warp "+attraction.getID()); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/menu/objects/handlers/CommandMenuHandler.java b/src/main/java/nl/iobyte/themepark/api/menu/objects/handlers/CommandMenuHandler.java new file mode 100644 index 0000000..6c47e02 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/menu/objects/handlers/CommandMenuHandler.java @@ -0,0 +1,34 @@ +package nl.iobyte.themepark.api.menu.objects.handlers; + +import nl.iobyte.menuapi.enums.Types; +import nl.iobyte.menuapi.interfaces.IActionHandler; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import java.util.List; + +public class CommandMenuHandler implements IActionHandler { + + private final String command; + + public CommandMenuHandler(String command) { + if(command.startsWith("/")) + command = command.replaceFirst("/", ""); + + this.command = command; + } + + public String getID() { + return "COMMAND"; + } + + public List getClickTypes() { + return Types.NORMAL.getTypesList(); + } + + public void execute(Player player) { + player.closeInventory(); + Bukkit.dispatchCommand(player, command); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/menu/objects/handlers/JsonMessageMenuHandler.java b/src/main/java/nl/iobyte/themepark/api/menu/objects/handlers/JsonMessageMenuHandler.java new file mode 100644 index 0000000..9186391 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/menu/objects/handlers/JsonMessageMenuHandler.java @@ -0,0 +1,38 @@ +package nl.iobyte.themepark.api.menu.objects.handlers; + +import nl.iobyte.menuapi.enums.Types; +import nl.iobyte.menuapi.interfaces.IActionHandler; +import nl.iobyte.themepark.utils.PlaceHolder; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import java.util.List; + +public class JsonMessageMenuHandler implements IActionHandler { + + private final String message; + + public JsonMessageMenuHandler(String message) { + this.message = message; + } + + public String getID() { + return "JSON_MESSAGE"; + } + + public List getClickTypes() { + return Types.NORMAL.getTypesList(); + } + + public void execute(Player player) { + player.closeInventory(); + Bukkit.dispatchCommand( + Bukkit.getConsoleSender(), + "tellraw "+player.getName()+" "+PlaceHolder.setPlaceHolders( + player, + message + ) + ); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/menu/objects/handlers/PlainMessageMenuHandler.java b/src/main/java/nl/iobyte/themepark/api/menu/objects/handlers/PlainMessageMenuHandler.java new file mode 100644 index 0000000..ce4dcdd --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/menu/objects/handlers/PlainMessageMenuHandler.java @@ -0,0 +1,35 @@ +package nl.iobyte.themepark.api.menu.objects.handlers; + +import nl.iobyte.menuapi.enums.Types; +import nl.iobyte.menuapi.interfaces.IActionHandler; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.utils.PlaceHolder; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import java.util.List; + +public class PlainMessageMenuHandler implements IActionHandler { + + private final String message; + + public PlainMessageMenuHandler(String message) { + this.message = Text.color(message); + } + + public String getID() { + return "PLAIN_MESSAGE"; + } + + public List getClickTypes() { + return Types.NORMAL.getTypesList(); + } + + public void execute(Player player) { + player.closeInventory(); + player.sendMessage(PlaceHolder.setPlaceHolders( + player, + message + )); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/menu/objects/handlers/StatusMenuHandler.java b/src/main/java/nl/iobyte/themepark/api/menu/objects/handlers/StatusMenuHandler.java new file mode 100644 index 0000000..93e094d --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/menu/objects/handlers/StatusMenuHandler.java @@ -0,0 +1,24 @@ +package nl.iobyte.themepark.api.menu.objects.handlers; + +import nl.iobyte.menuapi.enums.Types; +import nl.iobyte.menuapi.interfaces.IActionHandler; +import nl.iobyte.themepark.ThemePark; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import java.util.List; + +public class StatusMenuHandler implements IActionHandler { + + public String getID() { + return "STATUS_MENU"; + } + + public List getClickTypes() { + return Types.NORMAL.getTypesList(); + } + + public void execute(Player player) { + ThemePark.getInstance().getAPI().getMenuService().getStatusMenu().open(player); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/message/MessageKey.java b/src/main/java/nl/iobyte/themepark/api/message/MessageKey.java new file mode 100644 index 0000000..731b275 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/message/MessageKey.java @@ -0,0 +1,63 @@ +package nl.iobyte.themepark.api.message; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.config.enums.StorageLocation; +import org.bukkit.entity.Player; + +public enum MessageKey { + + //Prefix + PREFIX("prefix"), + + //Session + CLIENT_UNABLE_TO_CONNECT("client.connect.unable"), + CLIENT_GENERATE_TO_CONNECT("client.connect.generate"), + CLIENT_CLICK_TO_CONNECT("client.connect.click"), + CLIENT_HOVER_TO_CONNECT("client.connect.hover"), + + //Connection + CLIENT_CONNECTION_EXISTS("client.connection.exists"), + CLIENT_CONNECTION_OPEN("client.connection.open"), + CLIENT_CONNECTION_CLOSED("client.connection.closed"), + + //Ridecount + RIDECOUNT_ADD("ridecount.add"), + + //Attraction Teleport + ATTRACTION_TELEPORT_STATUS("attraction.teleport.status"), + ATTRACTION_TELEPORT_SUCCESS("attraction.teleport.success"); + + private final String path; + MessageKey(String path) { + this.path = path; + } + + /** + * Get path to message + * @return String + */ + public String getPath() { + return path; + } + + /** + * Get and color message from config + * @return String + */ + public String getMessage() { + String msg = Text.color(ThemePark.getInstance().getAPI().getConfigurationManager().getString(StorageLocation.MESSAGE, path)); + if(this != MessageKey.PREFIX) + msg = msg.replace("{prefix}", MessageKey.PREFIX.getMessage()); + + return msg; + } + + /** + * Send message with color to Player + * @param player Player + */ + public void send(Player player) { + player.sendMessage(getMessage()); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/message/Text.java b/src/main/java/nl/iobyte/themepark/api/message/Text.java new file mode 100644 index 0000000..0ed6694 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/message/Text.java @@ -0,0 +1,25 @@ +package nl.iobyte.themepark.api.message; + +import org.bukkit.ChatColor; + +public class Text { + + /** + * Color text + * @param str String + * @return String + */ + public static String color(String str) { + return ChatColor.translateAlternateColorCodes('&', str); + } + + /** + * Strip text of color + * @param str String + * @return String + */ + public static String strip(String str) { + return ChatColor.stripColor(color(str)); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/ridecount/RideCountService.java b/src/main/java/nl/iobyte/themepark/api/ridecount/RideCountService.java new file mode 100644 index 0000000..77cf6cf --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/ridecount/RideCountService.java @@ -0,0 +1,110 @@ +package nl.iobyte.themepark.api.ridecount; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.ridecount.objects.AttractionCount; +import nl.iobyte.themepark.api.ridecount.objects.RideCount; +import nl.iobyte.themepark.api.ridecount.objects.TopData; +import org.bukkit.Bukkit; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +public class RideCountService { + + private final Map counts = new ConcurrentHashMap<>(); + private final TopData topData = new TopData(); + private boolean changed = false; + + public AttractionCount getCount(String id) { + if(id == null || id.isEmpty()) + return null; + + if(!ThemePark.getInstance().getAPI().getAttractionService().hasAttraction(id)) + return null; + + return counts.computeIfAbsent(id, k -> new AttractionCount(id)); + } + + public void setCount(String id, UUID uuid, int amount, int total_amount) { + if(amount == 0 || total_amount == 0 || id == null || id.isEmpty() || uuid == null) + return; + + AttractionCount count = getCount(id); + if(count == null) + return; + + count.setCount(uuid, amount, total_amount); + } + + public RideCount getCount(String id, UUID uuid) { + if(id == null || id.isEmpty() || uuid == null) + return null; + + AttractionCount count = getCount(id); + if(count == null) + return null; + + return count.getCount(uuid); + } + + public void addCount(String id, UUID uuid, int amount) { + if(amount == 0 || id == null || id.isEmpty() || uuid == null) + return; + + AttractionCount count = getCount(id); + if(count == null) + return; + + count.addCount(uuid, amount); + changed = true; + } + + public void clearCount(UUID uuid) { + if(uuid == null) + return; + + for(AttractionCount attractionCount : counts.values()) + attractionCount.removeCount(uuid); + } + + public boolean hasChanged() { + return changed; + } + + public List getChanges(long timestamp) { + List list = new ArrayList<>(); + for(AttractionCount attractionCount : counts.values()) + for(Map> m1 : attractionCount.getCounts().values()) + for(Map m2 : m1.values()) + for(RideCount count : m2.values()) + if(count.getUpdatedAt() != -1 && count.getUpdatedAt() > timestamp) + list.add(count); + + return list; + } + + public void clearNonApplicable() { + changed = false; + Calendar calendar = new GregorianCalendar(); + calendar.setTime(new Date()); + + int year = calendar.get(Calendar.YEAR); + int day = calendar.get(Calendar.DAY_OF_YEAR); + for(AttractionCount attractionCount : counts.values()) { + attractionCount.removeOld( + year, + day + ); + + Map map = attractionCount.getCounts(year, day); + if(map == null) + return; + + map.entrySet().removeIf(e -> Bukkit.getPlayer(e.getValue().getUUID()) == null); + } + } + + public TopData getTopData() { + return topData; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/ridecount/objects/AttractionCount.java b/src/main/java/nl/iobyte/themepark/api/ridecount/objects/AttractionCount.java new file mode 100644 index 0000000..637fba1 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/ridecount/objects/AttractionCount.java @@ -0,0 +1,151 @@ +package nl.iobyte.themepark.api.ridecount.objects; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.event.ridecount.RideCountAddEvent; +import nl.iobyte.themepark.scheduler.ThemeParkScheduler; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +public class AttractionCount { + + private final String attraction_id; + private final Map>> counts = new ConcurrentHashMap<>(); + private int current_year, current_month, current_week, current_day; + private long next_day; + + public AttractionCount(String attraction_id) { + this.attraction_id = attraction_id; + updateTimes(); + } + + public String getAttractionID() { + return attraction_id; + } + + public Map>> getCounts() { + return counts; + } + + public Map> getCounts(int year) { + return counts.get(year); + } + + public Map getCounts(int year, int day) { + Map> map = getCounts(year); + if(map == null) + return null; + + return map.get(day); + } + + public void remove() { + counts.clear(); + } + + public void removeOld(int year, int day) { + counts.entrySet().removeIf(e -> e.getKey() != year); + counts.values().forEach(m -> m.entrySet().removeIf(e -> e.getKey() != day)); + } + + private Map get(int year, int day) { + Map> ym = counts.computeIfAbsent(year, k -> new ConcurrentHashMap<>()); + return ym.computeIfAbsent(day, k -> new ConcurrentHashMap<>()); + } + + public void setCount(UUID uuid, int amount, int total_amount) { + if(next_day <= System.currentTimeMillis()) + updateTimes(); + + Map counts = get(current_year, current_day); + counts.computeIfAbsent(uuid, k -> new RideCount( + uuid, + attraction_id, + amount, + total_amount, + current_year, + current_month, + current_week, + current_day + )); + } + + public RideCount getCount(UUID uuid) { + if(next_day <= System.currentTimeMillis()) + updateTimes(); + + Map counts = get(current_year, current_day); + return counts.get(uuid); + } + + public void addCount(UUID uuid, int amount) { + if(next_day <= System.currentTimeMillis()) + updateTimes(); + + ThemeParkScheduler.runAsync(() -> { + Map counts = get(current_year, current_day); + RideCount rc = counts.computeIfAbsent(uuid, k -> { + ArrayList> result = ThemePark.getInstance().getAPI().getDatabaseService().executeQuery( + "local", + "SELECT sum(count) AS total_count FROM counts WHERE uuid=? AND attraction_id=? AND year=? AND month=? GROUP BY uuid", + new HashMap(){{ + put(1, uuid); + put(2, attraction_id); + put(3, current_year); + put(4, current_month); + }} + ); + + int total_amount = 0; + if(result != null) + for(Map row : result) + total_amount = (int) row.get("total_count"); + + return new RideCount( + uuid, + attraction_id, + 0, + total_amount, + current_year, + current_month, + current_week, + current_day + ); + }); + + //Event Parameters + int old = rc.getCount(); + int current = old + amount; + + //Add amount -> execute event + rc.addCount(amount); + ThemePark.getInstance().getAPI().getEventDispatcher().call(new RideCountAddEvent( + rc, + old, + current + )); + }); + } + + public void removeCount(UUID uuid) { + for(Map> m1 : counts.values()) + for(Map m2 : m1.values()) + m2.entrySet().removeIf(e -> e.getKey() == uuid && e.getValue().getUpdatedAt() == -1); + } + + private void updateTimes() { + Calendar calendar = new GregorianCalendar(); + calendar.setTime(new Date()); + calendar.set(Calendar.HOUR, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + + current_year = calendar.get(Calendar.YEAR); + current_month = calendar.get(Calendar.MONTH) + 1; + current_week = calendar.get(Calendar.WEEK_OF_YEAR); + current_day = calendar.get(Calendar.DAY_OF_YEAR); + next_day = calendar.getTimeInMillis(); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/ridecount/objects/RideCount.java b/src/main/java/nl/iobyte/themepark/api/ridecount/objects/RideCount.java new file mode 100644 index 0000000..1d066db --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/ridecount/objects/RideCount.java @@ -0,0 +1,81 @@ +package nl.iobyte.themepark.api.ridecount.objects; + +import java.util.UUID; + +public class RideCount { + + private final UUID uuid; + private final String attraction_id; + private final int year, month, week, day; + private int count, total_count; + private long updated_at; + + public RideCount(UUID uuid, String attraction_id, int count, int total_count, int year, int month, int week, int day) { + this( + uuid, + attraction_id, + count, + total_count, + year, + month, + week, + day, + -1 + ); + } + + public RideCount(UUID uuid, String attraction_id, int count, int total_count, int year, int month, int week, int day, long updated_at) { + this.uuid = uuid; + this.attraction_id = attraction_id; + this.count = count; + this.total_count = total_count; + this.year = year; + this.month = month; + this.week = week; + this.day = day; + this.updated_at = updated_at; + } + + public UUID getUUID() { + return uuid; + } + + public String getAttractionID() { + return attraction_id; + } + + public int getYear() { + return year; + } + + public int getMonth() { + return month; + } + + public int getWeek() { + return week; + } + + public int getDay() { + return day; + } + + public int getCount() { + return count; + } + + public int getTotalCount() { + return total_count; + } + + public void addCount(int count) { + this.count += count; + this.total_count += count; + updated_at = System.currentTimeMillis(); + } + + public long getUpdatedAt() { + return updated_at; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/ridecount/objects/TopData.java b/src/main/java/nl/iobyte/themepark/api/ridecount/objects/TopData.java new file mode 100644 index 0000000..9799360 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/ridecount/objects/TopData.java @@ -0,0 +1,143 @@ +package nl.iobyte.themepark.api.ridecount.objects; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.ThemeParkAPI; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.database.objects.Database; +import nl.iobyte.themepark.scheduler.ThemeParkScheduler; +import java.util.*; +import java.util.concurrent.CompletableFuture; + +public class TopData { + + public CompletableFuture> getDay(Attraction attraction) { + return get(attraction, 0); + } + + public CompletableFuture> getWeek(Attraction attraction) { + return get(attraction, 1); + } + + public CompletableFuture> getMonth(Attraction attraction) { + return get(attraction, 2); + } + + public CompletableFuture> getYear(Attraction attraction) { + return get(attraction, 3); + } + + private CompletableFuture> get(Attraction attraction, int i) { + CompletableFuture> fc = new CompletableFuture<>(); + if(attraction == null) { + fc.complete(null); + return fc; + } + + ThemeParkAPI api = ThemePark.getInstance().getAPI(); + if(!api.getAttractionService().hasAttraction(attraction.getID())) { + fc.complete(null); + return fc; + } + + Database db = api.getDatabaseService().getDatabase("local"); + if(db == null) { + fc.complete(null); + return fc; + } + + ThemeParkScheduler.runAsync(() -> { + Calendar calendar = new GregorianCalendar(); + calendar.setTime(new Date()); + + HashMap map = new HashMap<>(); + map.put(1, attraction.getID()); + + String timeSort; + switch (i) { + case 0: + timeSort = "day=? AND year=?"; + map.put(2, calendar.get(Calendar.DAY_OF_YEAR)); + map.put(3, calendar.get(Calendar.YEAR)); + break; + case 1: + timeSort = "week=? AND year=?"; + map.put(2, calendar.get(Calendar.WEEK_OF_YEAR)); + map.put(3, calendar.get(Calendar.YEAR)); + break; + case 2: + timeSort = "month=? AND year=?"; + map.put(2, calendar.get(Calendar.MONTH) + 1); + map.put(3, calendar.get(Calendar.YEAR)); + break; + default: + timeSort = "year=?"; + map.put(2, calendar.get(Calendar.YEAR)); + break; + } + + ArrayList> results = db.executeQuery("SELECT uuid, SUM(count) AS count FROM counts WHERE attraction_id=? AND "+timeSort+" GROUP BY uuid ORDER BY count DESC LIMIT 3", map); + if(results == null || results.isEmpty()) { + fc.complete(null); + return; + } + + HashMap top = new HashMap<>(); + for(Map m : results) { + UUID uuid = UUID.fromString((String) m.get("uuid")); + int points = (int) m.get("count"); + if(points < 0) + continue; + + top.put(uuid, points); + } + + fc.complete(top); + }); + return fc; + } + + public CompletableFuture> getTotal(Attraction attraction) { + CompletableFuture> fc = new CompletableFuture<>(); + if(attraction == null) { + fc.complete(null); + return fc; + } + + ThemeParkAPI api = ThemePark.getInstance().getAPI(); + if(!api.getAttractionService().hasAttraction(attraction.getID())) { + fc.complete(null); + return fc; + } + + Database db = api.getDatabaseService().getDatabase("local"); + if(db == null) { + fc.complete(null); + return fc; + } + + ThemeParkScheduler.runAsync(() -> { + HashMap map = new HashMap<>(); + map.put(1, attraction.getID()); + + ArrayList> results = db.executeQuery("SELECT uuid, SUM(count) AS count FROM counts WHERE attraction_id=? GROUP BY uuid ORDER BY count DESC LIMIT 3", map); + if(results == null || results.isEmpty()) { + fc.complete(null); + return; + } + + HashMap top = new HashMap<>(); + for(Map m : results) { + UUID uuid = UUID.fromString((String) m.get("uuid")); + int points = (int) m.get("count"); + if(points < 0) + continue; + + top.put(uuid, points); + } + + fc.complete(top); + }); + return fc; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/sign/SignManager.java b/src/main/java/nl/iobyte/themepark/api/sign/SignManager.java new file mode 100644 index 0000000..b698d37 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/sign/SignManager.java @@ -0,0 +1,119 @@ +package nl.iobyte.themepark.api.sign; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.config.enums.StorageLocation; +import nl.iobyte.themepark.api.sign.objects.StatusSign; +import nl.iobyte.themepark.utils.LocationUtil; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Sign; +import java.util.ArrayList; +import java.util.HashMap; + +public class SignManager { + + private final HashMap> signs = new HashMap<>(); + + public HashMap> getSigns() { + return signs; + } + + public void addSign(StatusSign sign) { + if(sign == null || sign.getLocation() == null) + return; + + if(!(sign.getLocation().getBlock().getState() instanceof Sign)) + return; + + if(signs.containsKey(sign.getAttraction())) { + signs.get(sign.getAttraction()).add(sign); + return; + } + + ArrayList array = new ArrayList<>(); + array.add(sign); + signs.put(sign.getAttraction(), array); + } + + public boolean hasSigns(Attraction attraction) { + if(attraction == null) + return false; + + return signs.containsKey(attraction) && (signs.get(attraction).size() > 0); + } + + public boolean isSign(Attraction attraction, Location location) { + if(attraction == null || location == null) + return false; + + ArrayList array = signs.get(attraction); + if(array == null) + return false; + + String loc = LocationUtil.toString(location); + + for(StatusSign sign : array) { + String str = LocationUtil.toString(sign.getLocation()); + if(loc.equals(str)) + return true; + } + + return false; + } + + public void update(Attraction attraction) { + if(attraction == null) + return; + + if(!hasSigns(attraction)) + return; + + for(StatusSign sign : signs.get(attraction)) + sign.update(); + } + + public void remove(Attraction attraction) { + if(attraction == null || !signs.containsKey(attraction)) + return; + + for(StatusSign sign : signs.get(attraction)) + sign.getLocation().getBlock().setType(Material.AIR); + + signs.remove(attraction); + ThemePark.getInstance().getAPI().getConfigurationManager().set(StorageLocation.SIGN_DATA, "signs."+attraction.getID(), null); + } + + public void removeSign(StatusSign sign) { + if(sign == null || sign.getLocation() == null || sign.getAttraction() == null) + return; + + if(!hasSigns(sign.getAttraction())) + return; + + Location loc1 = sign.getLocation(); + String str1 = LocationUtil.toString(loc1); + ArrayList array = signs.get(sign.getAttraction()); + for(StatusSign s : new ArrayList<>(array)) { + Location loc2 = s.getLocation(); + if(loc1 == null || loc2 == null) + return; + + String str2 = LocationUtil.toString(loc2); + + if(!str1.equals(str2)) + return; + + array.remove(s); + } + + if(array.isEmpty()) { + signs.remove(sign.getAttraction()); + ThemePark.getInstance().getAPI().getConfigurationManager().set(StorageLocation.SIGN_DATA, "signs."+sign.getAttraction().getID(), null); + return; + } + + signs.put(sign.getAttraction(), array); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/api/sign/objects/StatusSign.java b/src/main/java/nl/iobyte/themepark/api/sign/objects/StatusSign.java new file mode 100644 index 0000000..c41ddb3 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/api/sign/objects/StatusSign.java @@ -0,0 +1,44 @@ +package nl.iobyte.themepark.api.sign.objects; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.message.Text; +import org.bukkit.Location; +import org.bukkit.block.Sign; + +public class StatusSign { + + private final Attraction attraction; + private final Location location; + + public StatusSign(Attraction attraction, Location location) { + this.attraction = attraction; + this.location = location; + } + + public Attraction getAttraction() { + return attraction; + } + + public Location getLocation() { + return location; + } + + public void update() { + Status status = attraction.getStatus(); + if(!location.getChunk().isLoaded()) + location.getChunk().load(); + + if(!(location.getBlock().getState() instanceof Sign)) { + ThemePark.getInstance().getAPI().getSignManager().removeSign(this); + return; + } + + Sign sign = (Sign) location.getBlock().getState(); + sign.setLine(1, Text.color(attraction.getName())); + sign.setLine(2, Text.color(status.getColor()+status.getName())); + sign.update(); + } + +} \ No newline at end of file diff --git a/src/main/java/nl/iobyte/themepark/commands/ThemeParkCommand.java b/src/main/java/nl/iobyte/themepark/commands/ThemeParkCommand.java new file mode 100644 index 0000000..482385b --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/ThemeParkCommand.java @@ -0,0 +1,44 @@ +package nl.iobyte.themepark.commands; + +import nl.iobyte.commandapi.CommandFactory; +import nl.iobyte.commandapi.middlewares.PermissionMiddleware; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.commands.subcommands.HelpCommand; +import nl.iobyte.themepark.commands.subcommands.ItemCommand; +import nl.iobyte.themepark.commands.subcommands.MenuCommand; +import nl.iobyte.themepark.commands.subcommands.attraction.AttractionCommands; +import nl.iobyte.themepark.commands.subcommands.region.RegionCommands; +import nl.iobyte.themepark.commands.subcommands.ridecount.RideCountCommands; +import nl.iobyte.themepark.commands.subcommands.status.StatusCommands; + +public class ThemeParkCommand { + + //Load command data + public ThemeParkCommand() { + CommandFactory factory = new CommandFactory("themepark"); + factory.addSubCommand(new HelpCommand(factory)) + .addSubCommand(new MenuCommand()); + + //Admin + factory.addSubCommand(new ItemCommand()); + + //Region + RegionCommands.load(factory); + + //Attraction + AttractionCommands.load(factory); + + //Status + StatusCommands.load(factory); + + //RideCount + RideCountCommands.load(factory); + + //Middleware + factory.addMiddleware(new PermissionMiddleware()); + + //Register command + factory.registerCommand(ThemePark.getInstance()); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/arguments/AttractionArgument.java b/src/main/java/nl/iobyte/themepark/commands/arguments/AttractionArgument.java new file mode 100644 index 0000000..fb5cfb5 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/arguments/AttractionArgument.java @@ -0,0 +1,43 @@ +package nl.iobyte.themepark.commands.arguments; + +import nl.iobyte.commandapi.interfaces.ICommandArgument; +import nl.iobyte.commandapi.objects.ArgumentCheck; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import java.util.List; + +public class AttractionArgument implements ICommandArgument { + + /** + * Message to display when giving an error + * @return String + */ + public String getMessage(String[] args) { + return "No Attraction found with ID: "+ ChatColor.WHITE+args[0]; + } + + /** + * Check if argument is valid Attraction + * @param sender CommandSender + * @param args Arguments passed by Command + * @param previousArguments Previous arguments + * @return Boolean + */ + public ArgumentCheck checkArgument(CommandSender sender, String[] args, List previousArguments) { + return new ArgumentCheck(ThemePark.getInstance().getAPI().getAttractionService().hasAttraction(args[0]), 1); + } + + /** + * Get Attraction passed by command + * @param sender CommandSender + * @param args Arguments passed by Command + * @param previousArguments Previous arguments + * @return Attraction + */ + public Attraction getArgument(CommandSender sender, String[] args, List previousArguments) { + return ThemePark.getInstance().getAPI().getAttractionService().getAttraction(args[0]); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/arguments/NoAttractionArgument.java b/src/main/java/nl/iobyte/themepark/commands/arguments/NoAttractionArgument.java new file mode 100644 index 0000000..2581837 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/arguments/NoAttractionArgument.java @@ -0,0 +1,42 @@ +package nl.iobyte.themepark.commands.arguments; + +import nl.iobyte.commandapi.interfaces.ICommandArgument; +import nl.iobyte.commandapi.objects.ArgumentCheck; +import nl.iobyte.themepark.ThemePark; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import java.util.List; + +public class NoAttractionArgument implements ICommandArgument { + + /** + * Message to display when giving an error + * @return String + */ + public String getMessage(String[] args) { + return "Attraction with ID: "+ChatColor.WHITE+args[0]+ChatColor.RED+" already exists"; + } + + /** + * Check if argument is a not existing Attraction + * @param sender CommandSender + * @param args Arguments passed by Command + * @param previousArguments Previous arguments + * @return Boolean + */ + public ArgumentCheck checkArgument(CommandSender sender, String[] args, List previousArguments) { + return new ArgumentCheck(!ThemePark.getInstance().getAPI().getAttractionService().hasAttraction(args[0]), 1); + } + + /** + * Get String passed by command + * @param sender CommandSender + * @param args Arguments passed by Command + * @param previousArguments Previous arguments + * @return String + */ + public String getArgument(CommandSender sender, String[] args, List previousArguments) { + return args[0]; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/arguments/NoRegionArgument.java b/src/main/java/nl/iobyte/themepark/commands/arguments/NoRegionArgument.java new file mode 100644 index 0000000..55e13fc --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/arguments/NoRegionArgument.java @@ -0,0 +1,42 @@ +package nl.iobyte.themepark.commands.arguments; + +import nl.iobyte.commandapi.interfaces.ICommandArgument; +import nl.iobyte.commandapi.objects.ArgumentCheck; +import nl.iobyte.themepark.ThemePark; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import java.util.List; + +public class NoRegionArgument implements ICommandArgument { + + /** + * Message to display when giving an error + * @return String + */ + public String getMessage(String[] args) { + return "Region with ID: "+ChatColor.WHITE+args[0]+ChatColor.RED+" already exists"; + } + + /** + * Check if argument is a not existing Attraction + * @param sender CommandSender + * @param args Arguments passed by Command + * @param previousArguments Previous arguments + * @return Boolean + */ + public ArgumentCheck checkArgument(CommandSender sender, String[] args, List previousArguments) { + return new ArgumentCheck(!ThemePark.getInstance().getAPI().getAttractionService().hasRegion(args[0]), 1); + } + + /** + * Get String passed by command + * @param sender CommandSender + * @param args Arguments passed by Command + * @param previousArguments Previous arguments + * @return String + */ + public String getArgument(CommandSender sender, String[] args, List previousArguments) { + return args[0]; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/arguments/RegionArgument.java b/src/main/java/nl/iobyte/themepark/commands/arguments/RegionArgument.java new file mode 100644 index 0000000..2bcb9ed --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/arguments/RegionArgument.java @@ -0,0 +1,43 @@ +package nl.iobyte.themepark.commands.arguments; + +import nl.iobyte.commandapi.interfaces.ICommandArgument; +import nl.iobyte.commandapi.objects.ArgumentCheck; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.objects.Region; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import java.util.List; + +public class RegionArgument implements ICommandArgument { + + /** + * Message to display when giving an error + * @return String + */ + public String getMessage(String[] args) { + return "No Region found with ID: "+ ChatColor.WHITE+args[0]; + } + + /** + * Check if argument is valid Region + * @param sender CommandSender + * @param args Arguments passed by Command + * @param previousArguments Previous arguments + * @return Boolean + */ + public ArgumentCheck checkArgument(CommandSender sender, String[] args, List previousArguments) { + return new ArgumentCheck(ThemePark.getInstance().getAPI().getAttractionService().hasRegion(args[0]), 1); + } + + /** + * Get Region passed by command + * @param sender CommandSender + * @param args Arguments passed by Command + * @param previousArguments Previous arguments + * @return Region + */ + public Region getArgument(CommandSender sender, String[] args, List previousArguments) { + return ThemePark.getInstance().getAPI().getAttractionService().getRegion(args[0]); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/HelpCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/HelpCommand.java new file mode 100644 index 0000000..613ec89 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/HelpCommand.java @@ -0,0 +1,71 @@ +package nl.iobyte.themepark.commands.subcommands; + +import nl.iobyte.commandapi.CommandFactory; +import nl.iobyte.commandapi.arguments.number.IntegerArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.api.message.Text; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class HelpCommand extends SubCommand { + + private final CommandFactory factory; + + public HelpCommand(CommandFactory factory) { + super(new String[]{"help"}); + + this.factory = factory; + addSyntax("/themepark help"); + addSyntax("/themepark help ") + .addArgument(new IntegerArgument()); + } + + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + //Send CommandSender list of commands it has access to + public void onConsoleCommand(CommandSender sender, List list, int i) { + List commands = factory.getApplicableSubCommands(sender); + if(commands.size() <= 5) { + sendSinglePage(sender, commands); + return; + } + + sendMultiPage(sender, commands, list, i); + } + + private void sendSinglePage(CommandSender sender, List commands) { + sender.sendMessage(Text.color("&f&l>==== &6&lThemePark &l&f====<")); + for (SubCommand command : commands) + sender.sendMessage(Text.color("&f" + command.getApplicableSyntaxList(sender).get(0).getUsage())); + + sender.sendMessage(Text.color("&f&l>==== &6&lThemePark &l&f====<")); + } + + private void sendMultiPage(CommandSender sender, List commands, List list, int i) { + int page = 1; + int pages = (int) Math.ceil(((double) commands.size()) / 5); + if(i == 1) + page = (Integer) list.get(0); + + if(page < 1 || page > pages) { + sender.sendMessage(Text.color("&6&lThemePark &f➢ Page &6"+page+" &fdoesn't exist")); + return; + } + + page--; + int start = page * 5; + int end = page * 5 + 5; + if(end > commands.size()) + end = commands.size(); + + sender.sendMessage(Text.color("&f&l>==== &6&lThemePark &f(&6"+(page + 1)+"&f/&6"+pages+"&f) &l&f====<")); + for(i = start; i < end; i++) + sender.sendMessage(Text.color("&f" + commands.get(i).getApplicableSyntaxList(sender).get(0).getUsage())); + + sender.sendMessage(Text.color("&f&l>==== &6&lThemePark &l&f====<")); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/ItemCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/ItemCommand.java new file mode 100644 index 0000000..e810206 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/ItemCommand.java @@ -0,0 +1,43 @@ +package nl.iobyte.themepark.commands.subcommands; + +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.menuapi.item.ItemBuilder; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.config.ConfigurationManager; +import nl.iobyte.themepark.api.config.enums.StorageKey; +import nl.iobyte.themepark.api.message.Text; +import org.bukkit.Material; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class ItemCommand extends SubCommand { + + public ItemCommand() { + super("themepark.admin", "item"); + + addSyntax("/themepark item") + .setAllowConsole(false); + } + + public void onPlayerCommand(Player player, List objects, int i) { + ConfigurationManager manager = ThemePark.getInstance().getAPI().getConfigurationManager(); + + Material material = Material.getMaterial(manager.getString(StorageKey.MENU_ITEM_MATERIAL)); + short data = Short.parseShort(manager.getString(StorageKey.MENU_ITEM_DATA)); + String name = Text.color(manager.getString(StorageKey.MENU_ITEM_NAME)); + if(material == null || name.isEmpty()) + return; + + ItemBuilder builder = new ItemBuilder(material, 1, data); + builder.setName(name); + + player.getInventory().addItem(builder.getItem()); + player.updateInventory(); + player.sendMessage(Text.color("&6&lThemeParkMC &f➢ Added item to your inventory")); + } + + //Give CommandSender overview of Plugin status + public void onConsoleCommand(CommandSender sender, List objects, int i) {} + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/MenuCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/MenuCommand.java new file mode 100644 index 0000000..baa2a02 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/MenuCommand.java @@ -0,0 +1,35 @@ +package nl.iobyte.themepark.commands.subcommands; + +import nl.iobyte.commandapi.arguments.StringArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.menu.MenuService; +import nl.iobyte.themepark.scheduler.ThemeParkScheduler; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class MenuCommand extends SubCommand { + + public MenuCommand() { + super(null, "menu"); + + addSyntax("/themepark menu"); + + addSyntax("/themepark menu") + .addArgument(new StringArgument("status")); + } + + public void onPlayerCommand(Player player, List objects, int i) { + MenuService service = ThemePark.getInstance().getAPI().getMenuService(); + if(i == 0) { + ThemeParkScheduler.runSync(() -> service.getMainMenu().open(player)); + return; + } + + ThemeParkScheduler.runSync(() -> service.getStatusMenu().open(player)); + } + + public void onConsoleCommand(CommandSender sender, List objects, int i) {} + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionCommands.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionCommands.java new file mode 100644 index 0000000..ef4ae7b --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionCommands.java @@ -0,0 +1,19 @@ +package nl.iobyte.themepark.commands.subcommands.attraction; + +import nl.iobyte.commandapi.CommandFactory; + +public class AttractionCommands { + + public static void load(CommandFactory factory) { + factory.addSubCommand(new AttractionListCommand()) + .addSubCommand(new AttractionWarpCommand()) + .addSubCommand(new AttractionCreateCommand()) + .addSubCommand(new AttractionRegionCommand()) + .addSubCommand(new AttractionNameCommand()) + .addSubCommand(new AttractionCoverCommand()) + .addSubCommand(new AttractionStatusCommand()) + .addSubCommand(new AttractionLocationCommand()) + .addSubCommand(new AttractionRemoveCommand()); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionCoverCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionCoverCommand.java new file mode 100644 index 0000000..8accb30 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionCoverCommand.java @@ -0,0 +1,34 @@ +package nl.iobyte.themepark.commands.subcommands.attraction; + +import nl.iobyte.commandapi.arguments.StringArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.commands.arguments.AttractionArgument; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class AttractionCoverCommand extends SubCommand { + + public AttractionCoverCommand() { + super("themepark.admin", "attraction", "cover"); + + addSyntax("/themepark attraction cover ") + .addArgument(new AttractionArgument()) + .addArgument(new StringArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + Attraction attraction = (Attraction) list.get(0); + String url = (String) list.get(1); + attraction.setCover(url); + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ &aSuccessfully changed the cover of attraction &f"+attraction.getID())); + } +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionCreateCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionCreateCommand.java new file mode 100644 index 0000000..3568b54 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionCreateCommand.java @@ -0,0 +1,76 @@ +package nl.iobyte.themepark.commands.subcommands.attraction; + +import nl.iobyte.commandapi.arguments.EnumArgument; +import nl.iobyte.commandapi.arguments.MessageArgument; +import nl.iobyte.commandapi.arguments.StringArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.attraction.objects.Region; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.commands.arguments.NoAttractionArgument; +import nl.iobyte.themepark.commands.arguments.RegionArgument; +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class AttractionCreateCommand extends SubCommand { + + public AttractionCreateCommand() { + super("themepark.admin", "attraction", "create"); + + addSyntax("/themepark attraction create ") + .addArgument(new NoAttractionArgument()) + .addArgument(new RegionArgument()) + .addArgument(new MessageArgument()); + + addSyntax("/themepark attraction create ") + .addArgument(new NoAttractionArgument()) + .addArgument(new RegionArgument()) + .addArgument(new MessageArgument()) + .addArgument(new EnumArgument(Status.values())); + + addSyntax("/themepark attraction create ") + .addArgument(new NoAttractionArgument()) + .addArgument(new RegionArgument()) + .addArgument(new MessageArgument()) + .addArgument(new EnumArgument(Status.values())) + .addArgument(new StringArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + String id = (String) list.get(0); + Region region = (Region) list.get(1); + String name = (String) list.get(2); + Status status = Status.CONSTRUCTION; + if(i != 0) + status = (Status) list.get(3); + + String cover = "https://via.placeholder.com/500x500"; + if(i > 1) + cover = (String) list.get('4'); + + Location location = null; + if(sender instanceof Player) + location = ((Player) sender).getLocation(); + + ThemePark.getInstance().getAPI().getAttractionService().addAttraction(new Attraction( + id, + region.getID(), + name, + cover, + status, + location + )); + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ &aSuccessfully created attraction &f"+id)); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionListCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionListCommand.java new file mode 100644 index 0000000..e0850ff --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionListCommand.java @@ -0,0 +1,107 @@ +package nl.iobyte.themepark.commands.subcommands.attraction; + +import com.google.common.collect.Iterables; +import nl.iobyte.commandapi.arguments.number.IntegerArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.attraction.objects.Region; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.commands.arguments.RegionArgument; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.Collection; +import java.util.List; + +public class AttractionListCommand extends SubCommand { + + public AttractionListCommand() { + super("themepark.admin", "attraction", "list"); + + addSyntax("/themepark attraction list"); + + addSyntax("/themepark attraction list ") + .addArgument(new IntegerArgument()); + + addSyntax("/themepark attraction list ") + .addArgument(new RegionArgument()); + + addSyntax("/themepark attraction list ") + .addArgument(new RegionArgument()) + .addArgument(new IntegerArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + int page = 1; + String title = "&6&lThemePark"; + Collection attractions; + if(i < 2) { + if(i == 1) + page = (Integer) list.get(0); + + attractions = ThemePark.getInstance().getAPI().getAttractionService().getAttractions().values(); + } else { + if(i == 3) + page = (Integer) list.get(1); + + Region region = (Region) list.get(0); + title = region.getName(); + attractions = region.getAttractions().values(); + } + + if(attractions.size() <= 5) { + sendSinglePage(sender, title, attractions); + } else { + sendMultiPage(sender, page, title, attractions); + } + } + + private void sendSinglePage(CommandSender sender, String title, Collection attractions) { + sender.sendMessage(Text.color("&f&l>==== &r"+title+" &l&f====<")); + if(attractions.isEmpty()) { + sender.sendMessage(Text.color("&6No attractions found")); + } else { + for (Attraction attraction : attractions) + sender.sendMessage(Text.color( + "&6ID: &f" + attraction.getID() + + " &6Region: &f" + attraction.getRegionID() + + " &6Name: &r" + attraction.getName() + + " &6Status: &r" + attraction.getStatus().getColor() + attraction.getStatus().getName())); + } + + sender.sendMessage(Text.color("&f&l>==== &r"+title+" &l&f====<")); + } + + private void sendMultiPage(CommandSender sender, int page, String title, Collection attractions) { + int pages = (int) Math.ceil(((double) attractions.size()) / 5); + if(page < 1 || page > pages) { + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ Page &6"+page+" &fdoesn't exist")); + return; + } + + int i = 0; + for(List lr : Iterables.partition(attractions, 5)) { + i++; + if(i != page) + continue; + + sender.sendMessage(Text.color("&f&l>==== &r"+title+" &f(&6"+page+"&f/&6"+pages+"&f) &l&f====<")); + for(Attraction attraction : lr) + sender.sendMessage(Text.color( + "&6ID: &f"+attraction.getID() + +" &6Region: &f"+attraction.getRegionID() + +" &6Name: &r"+attraction.getName() + +" &6Status: &r"+attraction.getStatus().getColor()+attraction.getStatus().getName())); + + sender.sendMessage(Text.color("&f&l>==== &r"+title+" &l&f====<")); + break; + } + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionLocationCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionLocationCommand.java new file mode 100644 index 0000000..bfa6ca3 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionLocationCommand.java @@ -0,0 +1,31 @@ +package nl.iobyte.themepark.commands.subcommands.attraction; + +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.commands.arguments.AttractionArgument; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class AttractionLocationCommand extends SubCommand { + + public AttractionLocationCommand() { + super("themepark.admin", "attraction", "location"); + + addSyntax("/themepark attraction location ") + .addArgument(new AttractionArgument()) + .setAllowConsole(false); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + Attraction attraction = (Attraction) list.get(0); + attraction.setLocation(player.getLocation()); + player.sendMessage(Text.color("&6&lThemeParkMC &f➢ &aSuccessfully changed the location of attraction &f"+attraction.getID())); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) {} + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionNameCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionNameCommand.java new file mode 100644 index 0000000..5e9e096 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionNameCommand.java @@ -0,0 +1,34 @@ +package nl.iobyte.themepark.commands.subcommands.attraction; + +import nl.iobyte.commandapi.arguments.MessageArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.commands.arguments.AttractionArgument; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class AttractionNameCommand extends SubCommand { + + public AttractionNameCommand() { + super("themepark.admin", "attraction", "name"); + + addSyntax("/themepark attraction name ") + .addArgument(new AttractionArgument()) + .addArgument(new MessageArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + Attraction attraction = (Attraction) list.get(0); + String name = (String) list.get(1); + attraction.setName(name); + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ &aSuccessfully changed the name of attraction &f"+attraction.getID())); + } +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionRegionCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionRegionCommand.java new file mode 100644 index 0000000..780fdfc --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionRegionCommand.java @@ -0,0 +1,35 @@ +package nl.iobyte.themepark.commands.subcommands.attraction; + +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.attraction.objects.Region; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.commands.arguments.AttractionArgument; +import nl.iobyte.themepark.commands.arguments.RegionArgument; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class AttractionRegionCommand extends SubCommand { + + public AttractionRegionCommand() { + super("themepark.admin", "attraction", "region"); + + addSyntax("/themepark attraction region ") + .addArgument(new AttractionArgument()) + .addArgument(new RegionArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + Attraction attraction = (Attraction) list.get(0); + Region region = (Region) list.get(1); + attraction.setRegionID(region.getID()); + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ &aSuccessfully changed the region of attraction &f"+attraction.getID())); + } +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionRemoveCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionRemoveCommand.java new file mode 100644 index 0000000..5eda678 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionRemoveCommand.java @@ -0,0 +1,33 @@ +package nl.iobyte.themepark.commands.subcommands.attraction; + +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.commands.arguments.AttractionArgument; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class AttractionRemoveCommand extends SubCommand { + + public AttractionRemoveCommand() { + super("themepark.admin", "attraction", "remove"); + + addSyntax("/themepark attraction remove ") + .addArgument(new AttractionArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + Attraction attraction = (Attraction) list.get(0); + ThemePark.getInstance().getAPI().getAttractionService().removeAttraction(attraction.getID()); + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ &aSuccessfully removed attraction &f"+attraction.getID())); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionStatusCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionStatusCommand.java new file mode 100644 index 0000000..51ba374 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionStatusCommand.java @@ -0,0 +1,35 @@ +package nl.iobyte.themepark.commands.subcommands.attraction; + +import nl.iobyte.commandapi.arguments.EnumArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.commands.arguments.AttractionArgument; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class AttractionStatusCommand extends SubCommand { + + public AttractionStatusCommand() { + super("themepark.admin", "attraction", "status"); + + addSyntax("/themepark attraction status ") + .addArgument(new AttractionArgument()) + .addArgument(new EnumArgument(Status.values())); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + Attraction attraction = (Attraction) list.get(0); + Status status = (Status) list.get(1); + attraction.setStatus(status); + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ &aSuccessfully changed the status of attraction &f"+attraction.getID())); + } +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionWarpCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionWarpCommand.java new file mode 100644 index 0000000..fbd4af3 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/attraction/AttractionWarpCommand.java @@ -0,0 +1,50 @@ +package nl.iobyte.themepark.commands.subcommands.attraction; + +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.message.MessageKey; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.commands.arguments.AttractionArgument; +import nl.iobyte.themepark.scheduler.ThemeParkScheduler; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class AttractionWarpCommand extends SubCommand { + + public AttractionWarpCommand() { + super("themepark.admin", "attraction", "warp"); + + addSyntax("/themepark attraction warp ") + .addArgument(new AttractionArgument()) + .setAllowConsole(false); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + Attraction attraction = (Attraction) list.get(0); + if(!attraction.getStatus().canTeleport()) { + String message = MessageKey.ATTRACTION_TELEPORT_STATUS.getMessage(); + message = message.replace("{name}", attraction.getName()); + message = message.replace("{status}", attraction.getStatus().getColor() + attraction.getStatus().getName()); + player.sendMessage(Text.color(message)); + return; + } + + if(attraction.getLocation() == null) { + player.sendMessage(Text.color("&6&lThemeParkMC &f➢ &4No location available for this attraction")); + return; + } + + ThemeParkScheduler.runSync(() -> { + player.teleport(attraction.getLocation()); + String message = MessageKey.ATTRACTION_TELEPORT_SUCCESS.getMessage(); + message = message.replace("{name}", attraction.getName()); + player.sendMessage(Text.color(message)); + }); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) {} + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionCommands.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionCommands.java new file mode 100644 index 0000000..86b74f6 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionCommands.java @@ -0,0 +1,14 @@ +package nl.iobyte.themepark.commands.subcommands.region; + +import nl.iobyte.commandapi.CommandFactory; + +public class RegionCommands { + + public static void load(CommandFactory factory) { + factory.addSubCommand(new RegionListCommand()) + .addSubCommand(new RegionCreateCommand()) + .addSubCommand(new RegionNameCommand()) + .addSubCommand(new RegionRemoveCommand()); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionCreateCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionCreateCommand.java new file mode 100644 index 0000000..d726b1e --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionCreateCommand.java @@ -0,0 +1,39 @@ +package nl.iobyte.themepark.commands.subcommands.region; + +import nl.iobyte.commandapi.arguments.MessageArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.objects.Region; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.commands.arguments.NoRegionArgument; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class RegionCreateCommand extends SubCommand { + + public RegionCreateCommand() { + super("themepark.admin", "region", "create"); + + addSyntax("/themepark region create ") + .addArgument(new NoRegionArgument()) + .addArgument(new MessageArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + String id = (String) list.get(0); + String name = (String) list.get(1); + + ThemePark.getInstance().getAPI().getAttractionService().addRegion(new Region( + id, + name + )); + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ &aSuccessfully created region &f"+id)); + } +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionListCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionListCommand.java new file mode 100644 index 0000000..69714d3 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionListCommand.java @@ -0,0 +1,78 @@ +package nl.iobyte.themepark.commands.subcommands.region; + +import com.google.common.collect.Iterables; +import nl.iobyte.commandapi.arguments.number.IntegerArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.objects.Region; +import nl.iobyte.themepark.api.message.Text; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.Collection; +import java.util.List; + +public class RegionListCommand extends SubCommand { + + public RegionListCommand() { + super("themepark.admin", "region", "list"); + + addSyntax("/themepark region list"); + + addSyntax("/themepark region list ") + .addArgument(new IntegerArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + Collection regions = ThemePark.getInstance().getAPI().getAttractionService().getRegions().values(); + if(regions.size() <= 5) { + sendSinglePage(sender, regions); + } else { + sendMultiPage(sender, regions, list, i); + } + } + + private void sendSinglePage(CommandSender sender, Collection regions) { + sender.sendMessage(Text.color("&f&l>==== &6&lThemePark &l&f====<")); + if(regions.isEmpty()) { + sender.sendMessage(Text.color("&6No regions found")); + } else { + for (Region region : regions) + sender.sendMessage(Text.color("&6ID: &f" + region.getID() + " &6Name: &r" + region.getName())); + } + + sender.sendMessage(Text.color("&f&l>==== &6&lThemePark &l&f====<")); + } + + private void sendMultiPage(CommandSender sender, Collection regions, List list, int i) { + int page = 1; + int pages = (int) Math.ceil(((double) regions.size()) / 5); + if(i == 1) + page = (Integer) list.get(0); + + if(page < 1 || page > pages) { + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ Page &6"+page+" &fdoesn't exist")); + return; + } + + i = 0; + for(List lr : Iterables.partition(regions, 5)) { + i++; + if(i != page) + continue; + + sender.sendMessage(Text.color("&f&l>==== &6&lThemePark &f(&6"+(page + 1)+"&f/&6"+pages+"&f) &l&f====<")); + for(Region region : lr) + sender.sendMessage(Text.color("&6ID: &f"+region.getID()+" &6Name: &r"+region.getName())); + + sender.sendMessage(Text.color("&f&l>==== &6&lThemePark &l&f====<")); + break; + } + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionNameCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionNameCommand.java new file mode 100644 index 0000000..86de9af --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionNameCommand.java @@ -0,0 +1,34 @@ +package nl.iobyte.themepark.commands.subcommands.region; + +import nl.iobyte.commandapi.arguments.MessageArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.api.attraction.objects.Region; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.commands.arguments.RegionArgument; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class RegionNameCommand extends SubCommand { + + public RegionNameCommand() { + super("themepark.admin", "region", "name"); + + addSyntax("/themepark region name ") + .addArgument(new RegionArgument()) + .addArgument(new MessageArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + Region region = (Region) list.get(0); + String name = (String) list.get(1); + region.setName(name); + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ &aSuccessfully changed the name of region &f"+region.getID())); + } +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionRemoveCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionRemoveCommand.java new file mode 100644 index 0000000..dc5b344 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/region/RegionRemoveCommand.java @@ -0,0 +1,32 @@ +package nl.iobyte.themepark.commands.subcommands.region; + +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.objects.Region; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.commands.arguments.RegionArgument; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class RegionRemoveCommand extends SubCommand { + + public RegionRemoveCommand() { + super("themepark.admin", "region", "remove"); + + addSyntax("/themepark region remove ") + .addArgument(new RegionArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + Region region = (Region) list.get(0); + ThemePark.getInstance().getAPI().getAttractionService().removeRegion(region.getID()); + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ &aSuccessfully removed region &f"+region.getID())); + } +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/ridecount/RideCountAddCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/ridecount/RideCountAddCommand.java new file mode 100644 index 0000000..58e9382 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/ridecount/RideCountAddCommand.java @@ -0,0 +1,48 @@ +package nl.iobyte.themepark.commands.subcommands.ridecount; + +import nl.iobyte.commandapi.arguments.PlayersArgument; +import nl.iobyte.commandapi.arguments.number.IntegerArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.commands.arguments.AttractionArgument; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class RideCountAddCommand extends SubCommand { + + public RideCountAddCommand() { + super("themepark.admin", "ridecount", "add"); + + addSyntax("/themepark ridecount add ") + .addArgument(new AttractionArgument()) + .addArgument(new PlayersArgument()) + .addArgument(new IntegerArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + Attraction attraction = (Attraction) list.get(0); + List players = (List) list.get(1); + int amount = (Integer) list.get(2); + + for(Player player : players) + ThemePark.getInstance().getAPI().getRideCountService().addCount( + attraction.getID(), + player.getUniqueId(), + amount + ); + + sender.sendMessage(Text.color( + "&6&lThemeParkMC &f➢ &aSuccessfully added count of: &6"+amount+"x &ato attraction: &f"+attraction.getID()+" &afor &6"+players.size()+" &aplayers" + )); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/ridecount/RideCountCommands.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/ridecount/RideCountCommands.java new file mode 100644 index 0000000..acaf0fe --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/ridecount/RideCountCommands.java @@ -0,0 +1,12 @@ +package nl.iobyte.themepark.commands.subcommands.ridecount; + +import nl.iobyte.commandapi.CommandFactory; + +public class RideCountCommands { + + public static void load(CommandFactory factory) { + factory.addSubCommand(new RideCountGetCommand()) + .addSubCommand(new RideCountAddCommand()); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/ridecount/RideCountGetCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/ridecount/RideCountGetCommand.java new file mode 100644 index 0000000..475f44f --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/ridecount/RideCountGetCommand.java @@ -0,0 +1,44 @@ +package nl.iobyte.themepark.commands.subcommands.ridecount; + +import nl.iobyte.commandapi.arguments.PlayerArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.api.ridecount.objects.RideCount; +import nl.iobyte.themepark.commands.arguments.AttractionArgument; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class RideCountGetCommand extends SubCommand { + + public RideCountGetCommand() { + super("themepark.admin", "ridecount", "get"); + + addSyntax("/themepark ridecount get ") + .addArgument(new AttractionArgument()) + .addArgument(new PlayerArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + Attraction attraction = (Attraction) list.get(0); + Player player = (Player) list.get(1); + + RideCount count = ThemePark.getInstance().getAPI().getRideCountService().getCount( + attraction.getID(), + player.getUniqueId() + ); + + sender.sendMessage(Text.color( + "&6&lThemeParkMC &f➢ You have ridden attraction: &f"+attraction.getID()+" &ffor &6"+(count == null ? 0 : count.getCount())+"x" + )); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusColorCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusColorCommand.java new file mode 100644 index 0000000..9e27bc3 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusColorCommand.java @@ -0,0 +1,35 @@ +package nl.iobyte.themepark.commands.subcommands.status; + +import nl.iobyte.commandapi.arguments.EnumArgument; +import nl.iobyte.commandapi.arguments.StringArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.message.Text; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class StatusColorCommand extends SubCommand { + + public StatusColorCommand() { + super("themepark.admin", "status", "color"); + + addSyntax("/themepark status color ") + .addArgument(new EnumArgument(Status.values())) + .addArgument(new StringArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + Status status = (Status) list.get(0); + String color = (String) list.get(1); + status.setColor(color); + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ &aSuccessfully changed the color of status &f"+status.toString())); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusCommands.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusCommands.java new file mode 100644 index 0000000..dedb7ae --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusCommands.java @@ -0,0 +1,15 @@ +package nl.iobyte.themepark.commands.subcommands.status; + +import nl.iobyte.commandapi.CommandFactory; + +public class StatusCommands { + + public static void load(CommandFactory factory) { + factory.addSubCommand(new StatusNameCommand()) + .addSubCommand(new StatusColorCommand()) + .addSubCommand(new StatusHexColorCommand()) + .addSubCommand(new StatusMaterialCommand()) + .addSubCommand(new StatusTeleportCommand()); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusHexColorCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusHexColorCommand.java new file mode 100644 index 0000000..f81b35d --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusHexColorCommand.java @@ -0,0 +1,36 @@ +package nl.iobyte.themepark.commands.subcommands.status; + +import nl.iobyte.commandapi.arguments.EnumArgument; +import nl.iobyte.commandapi.arguments.StringArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.message.Text; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; + +public class StatusHexColorCommand extends SubCommand { + + public StatusHexColorCommand() { + super("themepark.admin", "status", "hex_color"); + + addSyntax("/themepark status hex_color ") + .addArgument(new EnumArgument(Status.values())) + .addArgument(new StringArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + Status status = (Status) list.get(0); + String hex_color = (String) list.get(1); + status.setHexColor(hex_color); + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ &aSuccessfully changed the hex color of status &f"+status.toString())); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusMaterialCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusMaterialCommand.java new file mode 100644 index 0000000..7b82468 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusMaterialCommand.java @@ -0,0 +1,53 @@ +package nl.iobyte.themepark.commands.subcommands.status; + +import com.cryptomorin.xseries.XMaterial; +import nl.iobyte.commandapi.arguments.EnumArgument; +import nl.iobyte.commandapi.arguments.MaterialArgument; +import nl.iobyte.commandapi.arguments.number.ShortArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.message.Text; +import org.bukkit.Material; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class StatusMaterialCommand extends SubCommand { + + public StatusMaterialCommand() { + super("themepark.admin", "status", "material"); + + addSyntax("/themepark status material ") + .addArgument(new EnumArgument(Status.values())) + .addArgument(new MaterialArgument()); + + addSyntax("/themepark status material ") + .addArgument(new EnumArgument(Status.values())) + .addArgument(new MaterialArgument()) + .addArgument(new ShortArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + Status status = (Status) list.get(0); + XMaterial material; + if(i == 0) { + material = XMaterial.matchXMaterial((Material) list.get(1)); + } else { + material = XMaterial.matchXMaterial(list.get(1).toString()+":"+list.get(2).toString()).orElse(null); + if(material == null) { + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ &4Unable to parse specified material:data")); + return; + } + } + + status.setMaterial(material); + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ &aSuccessfully changed the material of status &f"+status.toString())); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusNameCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusNameCommand.java new file mode 100644 index 0000000..5789ca9 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusNameCommand.java @@ -0,0 +1,35 @@ +package nl.iobyte.themepark.commands.subcommands.status; + +import nl.iobyte.commandapi.arguments.EnumArgument; +import nl.iobyte.commandapi.arguments.MessageArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.message.Text; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class StatusNameCommand extends SubCommand { + + public StatusNameCommand() { + super("themepark.admin", "status", "name"); + + addSyntax("/themepark status name ") + .addArgument(new EnumArgument(Status.values())) + .addArgument(new MessageArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + Status status = (Status) list.get(0); + String name = (String) list.get(1); + status.setName(name); + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ &aSuccessfully changed the name of status &f"+status.toString())); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusTeleportCommand.java b/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusTeleportCommand.java new file mode 100644 index 0000000..33aa0e9 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/commands/subcommands/status/StatusTeleportCommand.java @@ -0,0 +1,35 @@ +package nl.iobyte.themepark.commands.subcommands.status; + +import nl.iobyte.commandapi.arguments.BooleanArgument; +import nl.iobyte.commandapi.arguments.EnumArgument; +import nl.iobyte.commandapi.interfaces.SubCommand; +import nl.iobyte.themepark.api.attraction.enums.Status; +import nl.iobyte.themepark.api.message.Text; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.List; + +public class StatusTeleportCommand extends SubCommand { + + public StatusTeleportCommand() { + super("themepark.admin", "status", "teleport"); + + addSyntax("/themepark status teleport ") + .addArgument(new EnumArgument(Status.values())) + .addArgument(new BooleanArgument()); + } + + @Override + public void onPlayerCommand(Player player, List list, int i) { + onConsoleCommand(player, list, i); + } + + @Override + public void onConsoleCommand(CommandSender sender, List list, int i) { + Status status = (Status) list.get(0); + boolean b = (boolean) list.get(1); + status.setCanTeleport(b); + sender.sendMessage(Text.color("&6&lThemeParkMC &f➢ &aSuccessfully changed if status &f"+status.toString()+" &acan teleport")); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/listeners/AttractionListener.java b/src/main/java/nl/iobyte/themepark/listeners/AttractionListener.java new file mode 100644 index 0000000..1efba0d --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/listeners/AttractionListener.java @@ -0,0 +1,212 @@ +package nl.iobyte.themepark.listeners; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.ThemeParkAPI; +import nl.iobyte.themepark.api.attraction.AttractionService; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.attraction.objects.Region; +import nl.iobyte.themepark.api.config.objects.Configuration; +import nl.iobyte.themepark.api.event.attraction.*; +import nl.iobyte.themepark.utils.LocationUtil; +import nl.iobyte.themepark.utils.StatusMessage; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import java.util.HashMap; + +public class AttractionListener implements Listener { + + @EventHandler + public void onCreate(AttractionCreateEvent e) { + ThemeParkAPI api = ThemePark.getInstance().getAPI(); + Attraction attraction = e.getAttraction(); + Region region = api.getAttractionService().getRegion( + attraction.getRegionID() + ); + + //Add to Region's config + String path = "attractions."+attraction.getID(); + Configuration config = region.getConfiguration(); + config.set(path+".name", attraction.getName()); + config.set(path+".cover", attraction.getCover()); + config.set(path+".status", attraction.getStatus().toString()); + config.set(path+".location", LocationUtil.toString(attraction.getLocation())); + + //Update Menu + ThemePark.getInstance().getAPI().getMenuService().getStatusMenu().load(); + + //Update MySQL Database + ThemePark.getInstance().getAPI().getDatabaseService().executeAsync( + "remote", + "INSERT IGNORE INTO attractions(id, region_id, name, cover, status_id) VALUES (?,?,?,?,?)", + new HashMap() {{ + put(1, attraction.getID()); + put(2, attraction.getRegionID()); + put(3, attraction.getName()); + put(4, attraction.getCover()); + put(5, attraction.getStatus().getID()); + }} + ); + } + + @EventHandler + public void onRegionChange(AttractionRegionChangeEvent e) { + Attraction attraction = e.getAttraction(); + AttractionService service = ThemePark.getInstance().getAPI().getAttractionService(); + + //Remove from old Region + Region region = service.getRegion(e.getOld()); + region.removeAttraction(attraction.getID()); + + //Remove from old Region's config + Configuration config = region.getConfiguration(); + config.set("attractions."+attraction.getID(), null); + + //Add to new Region + region = service.getRegion(e.getCurrent()); + region.addAttraction(attraction); + + //Add to new Region's config + String path = "attractions."+attraction.getID(); + config = region.getConfiguration(); + config.set(path+".name", attraction.getName()); + config.set(path+".cover", attraction.getCover()); + config.set(path+".status", attraction.getStatus().toString()); + config.set(path+".location", LocationUtil.toString(attraction.getLocation())); + + //Update Menu + ThemePark.getInstance().getAPI().getMenuService().getStatusMenu().load(); + + //Update MySQL Database + ThemePark.getInstance().getAPI().getDatabaseService().executeAsync( + "remote", + "UPDATE attractions SET region_id=? WHERE id=?", + new HashMap() {{ + put(1, e.getCurrent()); + put(2, attraction.getID()); + }} + ); + } + + @EventHandler + public void onNameChange(AttractionNameChangeEvent e) { + Attraction attraction = e.getAttraction(); + Region region = ThemePark.getInstance().getAPI().getAttractionService().getRegion( + attraction.getRegionID() + ); + + //Change name in Region's config + Configuration config = region.getConfiguration(); + config.set("attractions."+attraction.getID()+".name", e.getCurrent()); + + //Update Menu + ThemePark.getInstance().getAPI().getMenuService().getStatusMenu().updateAttraction(attraction); + + //Update Sign + ThemePark.getInstance().getAPI().getSignManager().update(attraction); + + //Update MySQL Database + ThemePark.getInstance().getAPI().getDatabaseService().executeAsync( + "remote", + "UPDATE attractions SET name=? WHERE id=?", + new HashMap<>() {{ + put(1, e.getCurrent()); + put(2, attraction.getID()); + }} + ); + } + + @EventHandler + public void onCoverChange(AttractionCoverChangeEvent e) { + Attraction attraction = e.getAttraction(); + Region region = ThemePark.getInstance().getAPI().getAttractionService().getRegion( + attraction.getRegionID() + ); + + //Change cover in Region's config + Configuration config = region.getConfiguration(); + config.set("attractions."+attraction.getID()+".cover", e.getCurrent()); + + //Update MySQL Database + ThemePark.getInstance().getAPI().getDatabaseService().executeAsync( + "remote", + "UPDATE attractions SET cover=? WHERE id=?", + new HashMap() {{ + put(1, e.getCurrent()); + put(2, attraction.getID()); + }} + ); + } + + @EventHandler + public void onStatusChange(AttractionStatusChangeEvent e) { + Attraction attraction = e.getAttraction(); + Region region = ThemePark.getInstance().getAPI().getAttractionService().getRegion( + attraction.getRegionID() + ); + + //Change status in Region's config + Configuration config = region.getConfiguration(); + config.set("attractions."+attraction.getID()+".status", e.getCurrent().toString()); + + //Update Menu + ThemePark.getInstance().getAPI().getMenuService().getStatusMenu().updateAttraction(attraction); + + //Update Sign + ThemePark.getInstance().getAPI().getSignManager().update(attraction); + + //Update MySQL Database + ThemePark.getInstance().getAPI().getDatabaseService().executeAsync( + "remote", + "UPDATE attractions SET status_id=? WHERE id=?", + new HashMap<>() {{ + put(1, e.getCurrent().getID()); + put(2, attraction.getID()); + }} + ); + + //Send Message + StatusMessage.broadcast(attraction); + } + + @EventHandler + public void onLocationChange(AttractionLocationChangeEvent e) { + ThemeParkAPI api = ThemePark.getInstance().getAPI(); + Attraction attraction = e.getAttraction(); + Region region = api.getAttractionService().getRegion( + attraction.getRegionID() + ); + + //Change location in Region's config + Configuration config = region.getConfiguration(); + config.set("attractions."+attraction.getID()+".location", LocationUtil.toString(e.getCurrent())); + } + + @EventHandler + public void onRemove(AttractionRemoveEvent e) { + ThemeParkAPI api = ThemePark.getInstance().getAPI(); + Attraction attraction = e.getAttraction(); + Region region = api.getAttractionService().getRegion( + attraction.getRegionID() + ); + + //Remove from Region's config + Configuration config = region.getConfiguration(); + config.set("attractions."+attraction.getID(), null); + + //Update Menu + api.getMenuService().getStatusMenu().load(); + + //Update Sign + ThemePark.getInstance().getAPI().getSignManager().remove(attraction); + + //Update MySQL Database + ThemePark.getInstance().getAPI().getDatabaseService().executeAsync( + "remote", + "DELETE attractions, ridecounts FROM attractions LEFT JOIN attractions.id=ridecounts.attraction_id WHERE attractions.id=?", + new HashMap<>() {{ + put(1, attraction.getID()); + }} + ); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/listeners/GeneralListener.java b/src/main/java/nl/iobyte/themepark/listeners/GeneralListener.java new file mode 100644 index 0000000..bca1cad --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/listeners/GeneralListener.java @@ -0,0 +1,54 @@ +package nl.iobyte.themepark.listeners; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.AttractionService; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.event.objects.AttractionEvent; +import nl.iobyte.themepark.api.event.objects.RegionEvent; +import nl.iobyte.themepark.api.event.objects.StatusEvent; +import nl.iobyte.themepark.api.menu.objects.StatusMenu; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class GeneralListener implements Listener { + + @EventHandler + public void onRegion(RegionEvent e) { + StatusMenu menu = ThemePark.getInstance().getAPI().getMenuService().getStatusMenu(); + if(e.getCurrent() == null) { + menu.load(); + return; + } + + menu.updateRegion(e.getRegion()); + } + + @EventHandler + public void onAttraction(AttractionEvent e) { + StatusMenu menu = ThemePark.getInstance().getAPI().getMenuService().getStatusMenu(); + if(e.getCurrent() == null) { + menu.load(); + return; + } + + String name = e.getEventName(); + if(name.contains("Location") || name.contains("Cover")) + return; + + menu.updateAttraction(e.getAttraction()); + } + + @EventHandler + public void onStatus(StatusEvent e) { + String name = e.getEventName(); + if(!name.contains("Name") && !name.contains("Color")) + return; + + StatusMenu menu = ThemePark.getInstance().getAPI().getMenuService().getStatusMenu(); + AttractionService service = ThemePark.getInstance().getAPI().getAttractionService(); + for(Attraction attraction : service.getAttractions().values()) + if(attraction.getStatus() == e.getStatus()) + menu.updateAttraction(attraction); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/listeners/PlayerListener.java b/src/main/java/nl/iobyte/themepark/listeners/PlayerListener.java new file mode 100644 index 0000000..04e1a66 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/listeners/PlayerListener.java @@ -0,0 +1,208 @@ +package nl.iobyte.themepark.listeners; + +import nl.iobyte.menuapi.item.ItemBuilder; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.ThemeParkAPI; +import nl.iobyte.themepark.api.config.ConfigurationManager; +import nl.iobyte.themepark.api.config.enums.StorageKey; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.scheduler.ThemeParkScheduler; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.*; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import java.util.*; +import java.util.concurrent.CompletableFuture; + +public class PlayerListener implements Listener { + + @EventHandler + public void onJoin(PlayerJoinEvent e) { + Player player = e.getPlayer(); + ThemeParkAPI api = ThemePark.getInstance().getAPI(); + + //Handle Menu item onJoin + doItem(player); + + //Load RideCount data + Calendar calendar = new GregorianCalendar(); + calendar.setTime(new Date()); + api.getDatabaseService().executeQueryAsync( + "local", + "SELECT count, attraction_id, (SELECT sum(count) FROM counts AS t1 WHERE t1.uuid=t2.uuid AND t1.attraction_id=t2.attraction_id AND t1.year=t2.year AND t1.month=? GROUP BY t1.uuid) AS total_count FROM counts AS t2 WHERE uuid=? AND year=? AND day=?", + new HashMap<>() {{ + put(1, calendar.get(Calendar.MONTH)); + put(2, player.getUniqueId().toString()); + put(3, calendar.get(Calendar.YEAR)); + put(4, calendar.get(Calendar.DAY_OF_YEAR)); + }} + ).setWhenSuccessful(result -> { + if(result != null) + for(Map row : result) + api.getRideCountService().setCount( + (String) row.get("attraction_id"), + player.getUniqueId(), + (int) row.get("count"), + (int) (row.get("total_count") == null ? row.get("count") : row.get("total_count")) + ); + }); + + } + + @EventHandler + public void onSwitch(PlayerChangedWorldEvent e) { + //Handle Menu item onSwitch + doItem(e.getPlayer()); + } + + @EventHandler + public void onQuit(PlayerQuitEvent e) { + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + + //Clear Unwanted RideCount + ThemeParkScheduler.runAsync(() -> ThemePark.getInstance().getAPI().getRideCountService().clearCount(uuid)); + } + + //Handle Menu item + @EventHandler + public void onInteract(PlayerInteractEvent e) { + if(e.getItem() == null) + return; + + ConfigurationManager manager = ThemePark.getInstance().getAPI().getConfigurationManager(); + Material material = Material.getMaterial(manager.getString(StorageKey.MENU_ITEM_MATERIAL)); + + ItemStack item = e.getItem(); + if(item.getType() != material) + return; + + if(!item.hasItemMeta()) + return; + + String name = Text.color(manager.getString(StorageKey.MENU_ITEM_NAME)); + if(!item.getItemMeta().getDisplayName().equals(name)) + return; + + if(e.getAction() == Action.LEFT_CLICK_AIR || e.getAction() == Action.LEFT_CLICK_BLOCK) + return; + + e.setCancelled(true); + Player player = e.getPlayer(); + ThemePark.getInstance().getAPI().getMenuService().getMainMenu().open(player); + } + + //Handle Menu item drop + @EventHandler + public void onDrop(PlayerDropItemEvent e) { + Player player = e.getPlayer(); + if(player.hasPermission("themepark.admin")) + return; + + ConfigurationManager manager = ThemePark.getInstance().getAPI().getConfigurationManager(); + if(!manager.getBoolean(StorageKey.MENU_ITEM_ENABLED)) + return; + + Material material = Material.getMaterial(manager.getString(StorageKey.MENU_ITEM_MATERIAL)); + ItemStack item = e.getItemDrop().getItemStack(); + if(item.getType() != material) + return; + + if(!item.hasItemMeta()) + return; + + String name = Text.color(manager.getString(StorageKey.MENU_ITEM_NAME)); + if(!item.getItemMeta().getDisplayName().equals(name)) + return; + + e.setCancelled(true); + } + + @EventHandler + public void onClick(InventoryClickEvent e) { + Player player = (Player) e.getWhoClicked(); + if(player.hasPermission("themepark.admin")) + return; + + Inventory inventory = e.getClickedInventory(); + if(inventory.getType() != InventoryType.PLAYER) + return; + + ConfigurationManager manager = ThemePark.getInstance().getAPI().getConfigurationManager(); + if(!manager.getBoolean(StorageKey.MENU_ITEM_ENABLED)) + return; + + ItemStack item = e.getCursor(); + if(item == null) + return; + + Material material = Material.getMaterial(manager.getString(StorageKey.MENU_ITEM_MATERIAL)); + if(item.getType() != material) + return; + + if(!item.hasItemMeta()) + return; + + String name = Text.color(manager.getString(StorageKey.MENU_ITEM_NAME)); + if(!item.getItemMeta().getDisplayName().equals(name)) + return; + + e.setCancelled(true); + } + + /** + * Called on join / world switch + * @param player Player + */ + private void doItem(Player player) { + ConfigurationManager manager = ThemePark.getInstance().getAPI().getConfigurationManager(); + + CompletableFuture fc = new CompletableFuture<>(); + Bukkit.getScheduler().runTaskAsynchronously(ThemePark.getInstance(), () -> { + if(!manager.getBoolean(StorageKey.MENU_ITEM_ENABLED)) { + fc.complete(null); + return; + } + + Material material = Material.getMaterial(manager.getString(StorageKey.MENU_ITEM_MATERIAL)); + short data = Short.parseShort(manager.getString(StorageKey.MENU_ITEM_DATA)); + String name = Text.color(manager.getString(StorageKey.MENU_ITEM_NAME)); + if(material == null || name.isEmpty()) { + fc.complete(null); + return; + } + + ItemBuilder builder = new ItemBuilder(material, 1, data); + builder.setName(name); + if(manager.getBoolean(StorageKey.MENU_ITEM_CLEAR)) + player.getInventory().clear(); + + List worlds = manager.getStringList(StorageKey.MENU_ITEM_WORLDS); + if(worlds != null && !worlds.isEmpty()) { + if (worlds.contains(player.getLocation().getWorld().getName())) { + fc.complete(new ItemStack(Material.AIR)); + return; + } + } + + fc.complete(builder.getItem()); + }); + + fc.thenAccept(item -> { + if(item == null) + return; + + int slot = manager.getInt(StorageKey.MENU_ITEM_SLOT); + player.getInventory().setItem(slot, item); + player.updateInventory(); + }); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/listeners/RegionListener.java b/src/main/java/nl/iobyte/themepark/listeners/RegionListener.java new file mode 100644 index 0000000..fb3e8d3 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/listeners/RegionListener.java @@ -0,0 +1,90 @@ +package nl.iobyte.themepark.listeners; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.objects.Region; +import nl.iobyte.themepark.api.config.enums.StorageLocation; +import nl.iobyte.themepark.api.event.region.RegionCreateEvent; +import nl.iobyte.themepark.api.event.region.RegionNameChangeEvent; +import nl.iobyte.themepark.api.event.region.RegionRemoveEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import java.util.HashMap; + +public class RegionListener implements Listener { + + @EventHandler + public void onCreate(RegionCreateEvent e) { + Region region = e.getRegion(); + + //Add Region to config + ThemePark.getInstance().getAPI().getConfigurationManager().set( + StorageLocation.REGIONS, + "regions."+region.getID()+".name", + region.getName() + ); + + //Update Menu + ThemePark.getInstance().getAPI().getMenuService().getStatusMenu().load(); + + //Update MySQL Database + ThemePark.getInstance().getAPI().getDatabaseService().executeAsync( + "remote", + "INSERT IGNORE INTO regions(id, name) VALUES (?,?)", + new HashMap<>() {{ + put(1, region.getID()); + put(2, region.getName()); + }} + ); + } + + @EventHandler + public void onNameChange(RegionNameChangeEvent e) { + Region region = e.getRegion(); + + //Change Region name in config + ThemePark.getInstance().getAPI().getConfigurationManager().set( + StorageLocation.REGIONS, + "regions."+region.getID()+".name", + region.getName() + ); + + //Update Menu + ThemePark.getInstance().getAPI().getMenuService().getStatusMenu().updateRegion(region); + + //Update MySQL Database + ThemePark.getInstance().getAPI().getDatabaseService().executeAsync( + "remote", + "UPDATE regions SET name=? WHERE id=?", + new HashMap<>() {{ + put(1, region.getName()); + put(2, region.getID()); + }} + ); + } + + @EventHandler + public void onRemove(RegionRemoveEvent e) { + Region region = e.getRegion(); + region.getConfiguration().delete(); + + //Remove Region from config + ThemePark.getInstance().getAPI().getConfigurationManager().set( + StorageLocation.REGIONS, + "regions."+region.getID(), + null + ); + + //Update Menu + ThemePark.getInstance().getAPI().getMenuService().getStatusMenu().load(); + + //Update MySQL Database + ThemePark.getInstance().getAPI().getDatabaseService().executeAsync( + "remote", + "DELETE regions, attractions, ridecounts FROM regions LEFT JOIN attractions ON regions.id=attractions.region_id LEFT JOIN ridecounts ON attractions.id=ridecounts.attraction_id WHERE regions.id=?", + new HashMap<>() {{ + put(1, region.getID()); + }} + ); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/listeners/RideCountListener.java b/src/main/java/nl/iobyte/themepark/listeners/RideCountListener.java new file mode 100644 index 0000000..e22f0b9 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/listeners/RideCountListener.java @@ -0,0 +1,92 @@ +package nl.iobyte.themepark.listeners; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.database.objects.types.SQLiteDatabase; +import nl.iobyte.themepark.api.event.ridecount.RideCountAddEvent; +import nl.iobyte.themepark.api.message.MessageKey; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.api.ridecount.objects.RideCount; +import nl.iobyte.themepark.scheduler.ThemeParkScheduler; +import nl.iobyte.themepark.utils.VersionComparator; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import java.util.HashMap; + +public class RideCountListener implements Listener { + + @EventHandler + public void onAdd(RideCountAddEvent e) { + RideCount rc = e.getRideCount(); + ThemeParkScheduler.runAsync(() -> { + VersionComparator vc = new VersionComparator(); + int i = vc.compare( + ((SQLiteDatabase) ThemePark.getInstance().getAPI().getDatabaseService().getDatabase("local")).getVersion(), + "3.24.0" + ); + + if(i >= 0) { + ThemePark.getInstance().getAPI().getDatabaseService().execute( + "local", + "INSERT INTO counts(uuid, attraction_id, year, month, week, day, count) VALUES (?,?,?,?,?,?,?) ON CONFLICT(uuid, attraction_id, year, day) DO UPDATE SET count=?", + new HashMap<>() {{ + put(1, rc.getUUID().toString()); + put(2, rc.getAttractionID()); + put(3, rc.getYear()); + put(4, rc.getMonth()); + put(5, rc.getWeek()); + put(6, rc.getDay()); + put(7, rc.getCount()); + put(8, rc.getCount()); + }} + ); + } else { + boolean b = ThemePark.getInstance().getAPI().getDatabaseService().execute( + "local", + "INSERT OR IGNORE INTO counts(uuid, attraction_id, year, month, week, day, count) VALUES (?,?,?,?,?,?,?)", + new HashMap<>() {{ + put(1, rc.getUUID().toString()); + put(2, rc.getAttractionID()); + put(3, rc.getYear()); + put(4, rc.getMonth()); + put(5, rc.getWeek()); + put(6, rc.getDay()); + put(7, rc.getCount()); + }} + ); + + if(b) + return; + + ThemePark.getInstance().getAPI().getDatabaseService().execute( + "local", + "UPDATE counts SET count=? WHERE uuid=? AND attraction_id=? AND year=? AND day=?", + new HashMap<>() {{ + put(1, rc.getCount()); + put(2, rc.getUUID().toString()); + put(3, rc.getAttractionID()); + put(4, rc.getYear()); + put(5, rc.getDay()); + }} + ); + } + }); + + Player player = Bukkit.getPlayer(rc.getUUID()); + if(player == null) + return; + + Attraction attraction = ThemePark.getInstance().getAPI().getAttractionService().getAttraction(rc.getAttractionID()); + if(attraction == null) + return; + + player.sendMessage( + MessageKey.RIDECOUNT_ADD.getMessage().replace("%NAME%", Text.strip(attraction.getName())) + .replace("%AMOUNT%", String.valueOf(e.getCurrent() - e.getOld())) + .replace("%TOTAL%", String.valueOf(rc.getTotalCount())) + ); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/listeners/StatusListener.java b/src/main/java/nl/iobyte/themepark/listeners/StatusListener.java new file mode 100644 index 0000000..a41903a --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/listeners/StatusListener.java @@ -0,0 +1,86 @@ +package nl.iobyte.themepark.listeners; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.config.enums.StorageLocation; +import nl.iobyte.themepark.api.event.status.*; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import java.util.HashMap; + +public class StatusListener implements Listener { + + @EventHandler + public void onNameChange(StatusColorChangeEvent e) { + //Update Sign + for(Attraction attraction : ThemePark.getInstance().getAPI().getAttractionService().getAttractionsByStatus(e.getStatus()).values()) + ThemePark.getInstance().getAPI().getSignManager().update(attraction); + + ThemePark.getInstance().getAPI().getConfigurationManager().set( + StorageLocation.STATUS_SETTINGS, + "states."+e.getStatus().toString()+".color", + e.getCurrent() + ); + } + + @EventHandler + public void onNameChange(StatusNameChangeEvent e) { + //Update MySQL Database + ThemePark.getInstance().getAPI().getDatabaseService().executeAsync( + "remote", + "UPDATE states SET name=? WHERE id=?", + new HashMap<>() {{ + put(1, e.getCurrent()); + put(2, e.getStatus().getID()); + }} + ); + + ThemePark.getInstance().getAPI().getConfigurationManager().set( + StorageLocation.STATUS_SETTINGS, + "states."+e.getStatus().toString()+".name", + e.getCurrent() + ); + + //Update Sign + for(Attraction attraction : ThemePark.getInstance().getAPI().getAttractionService().getAttractionsByStatus(e.getStatus()).values()) + ThemePark.getInstance().getAPI().getSignManager().update(attraction); + } + + @EventHandler + public void onHexColorChange(StatusHexColorChangeEvent e) { + //Update MySQL Database + ThemePark.getInstance().getAPI().getDatabaseService().executeAsync( + "remote", + "UPDATE states SET color=? WHERE id=?", + new HashMap() {{ + put(1, e.getCurrent()); + put(2, e.getStatus().getID()); + }} + ); + + ThemePark.getInstance().getAPI().getConfigurationManager().set( + StorageLocation.STATUS_SETTINGS, + "states."+e.getStatus().toString()+".hex_color", + e.getCurrent() + ); + } + + @EventHandler + public void onCanTeleportChange(StatusTeleportChangeEvent e) { + ThemePark.getInstance().getAPI().getConfigurationManager().set( + StorageLocation.STATUS_SETTINGS, + "states."+e.getStatus().toString()+".teleport", + e.getCurrent() + ); + } + + @EventHandler + public void onMaterialChange(StatusMaterialChangeEvent e) { + ThemePark.getInstance().getAPI().getConfigurationManager().set( + StorageLocation.STATUS_SETTINGS, + "states."+e.getStatus().toString()+".material", + e.getCurrent().toString() + ); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/listeners/StatusSignListener.java b/src/main/java/nl/iobyte/themepark/listeners/StatusSignListener.java new file mode 100644 index 0000000..3d6bc6d --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/listeners/StatusSignListener.java @@ -0,0 +1,104 @@ +package nl.iobyte.themepark.listeners; + +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.AttractionService; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.config.ConfigurationManager; +import nl.iobyte.themepark.api.config.enums.StorageKey; +import nl.iobyte.themepark.api.message.MessageKey; +import nl.iobyte.themepark.api.message.Text; +import nl.iobyte.themepark.api.sign.SignManager; +import nl.iobyte.themepark.api.sign.objects.StatusSign; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.player.PlayerInteractEvent; + +public class StatusSignListener implements Listener { + + private final AttractionService service = ThemePark.getInstance().getAPI().getAttractionService(); + private final SignManager manager = ThemePark.getInstance().getAPI().getSignManager(); + private final ConfigurationManager config = ThemePark.getInstance().getAPI().getConfigurationManager(); + + @EventHandler + public void onPlace(SignChangeEvent e) { + if(!e.getLine(0).equalsIgnoreCase(config.getString(StorageKey.SIGN_STATUS_NAME))) + return; + + String id = e.getLine(1); + if(id == null || id.isEmpty() || !service.hasAttraction(id)) + return; + + Attraction attraction = service.getAttraction(id); + e.setLine(0, Text.color(config.getString(StorageKey.SIGN_STATUS_TITLE))); + e.setLine(1, Text.color(attraction.getName())); + e.setLine(2, Text.color(attraction.getStatus().getColor() + attraction.getStatus().getName())); + + Location location = e.getBlock().getLocation(); + StatusSign statusSign = new StatusSign(attraction, location); + manager.addSign(statusSign); + } + + @EventHandler + public void onBreak(BlockBreakEvent e) { + if(e.getBlock() == null) + return; + + Block block = e.getBlock(); + if(!(block.getState() instanceof Sign)) + return; + + Sign sign = (Sign) block.getState(); + if(!sign.getLine(0).equals(Text.color(config.getString(StorageKey.SIGN_STATUS_TITLE)))) + return; + + Attraction attraction = service.getAttractionByName(sign.getLine(1)); + Location location = e.getBlock().getLocation(); + + StatusSign s = new StatusSign(attraction, location); + manager.removeSign(s); + } + + @EventHandler + public void onClick(PlayerInteractEvent e) { + if(e.getAction() != Action.RIGHT_CLICK_BLOCK) + return; + + Block b = e.getClickedBlock(); + if(!(b.getState() instanceof Sign)) + return; + + Sign sign = (Sign) b.getState(); + if(!sign.getLine(0).equals(Text.color(config.getString(StorageKey.SIGN_STATUS_TITLE)))) + return; + + Attraction attraction = service.getAttractionByName(sign.getLine(1)); + if(!manager.isSign(attraction, sign.getLocation())) + return; + + Location location = attraction.getLocation(); + if(location == null) + return; + + Player player = e.getPlayer(); + if(!attraction.getStatus().canTeleport()) { + String message = MessageKey.ATTRACTION_TELEPORT_STATUS.getMessage(); + message = message.replace("{name}", attraction.getName()); + message = message.replace("{status}", attraction.getStatus().getColor() + attraction.getStatus().getName()); + player.sendMessage(Text.color(message)); + return; + } + + player.teleport(location); + String message = MessageKey.ATTRACTION_TELEPORT_SUCCESS.getMessage(); + message = message.replace("{name}", attraction.getName()); + player.sendMessage(Text.color(message)); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/logger/ThemeParkLogger.java b/src/main/java/nl/iobyte/themepark/logger/ThemeParkLogger.java new file mode 100644 index 0000000..5bdeb8f --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/logger/ThemeParkLogger.java @@ -0,0 +1,13 @@ +package nl.iobyte.themepark.logger; + +public class ThemeParkLogger { + + /** + * Print message to the console + * @param msg Message string + */ + public static void toConsole(String msg) { + System.out.println("[ThemePark] "+msg); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/scheduler/Task.java b/src/main/java/nl/iobyte/themepark/scheduler/Task.java new file mode 100644 index 0000000..e11af1c --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/scheduler/Task.java @@ -0,0 +1,50 @@ +package nl.iobyte.themepark.scheduler; + +import java.util.function.Consumer; + +public class Task { + + private Consumer whenFails; + private Consumer whenSuccessful; + + /** + * Set what to do if task fails + * @param whenFails BiConsumer with ErrorCode and Message + */ + public void setWhenFails(Consumer whenFails) { + this.whenFails = whenFails; + } + + /** + * Set what to do if task is successful + * @param whenSuccessful Consumer with the result + */ + public void setWhenSuccessful(Consumer whenSuccessful) { + this.whenSuccessful = whenSuccessful; + } + + /** + * Task was a success + * @param data Return data + */ + public void success(T data) { + if(whenSuccessful != null) + whenSuccessful.accept(data); + } + + /** + * Task failed without message + */ + public void fail() { + if (whenFails != null) whenFails.accept("No message provided"); + } + + /** + * Task failed with message + * @param message Error message + */ + public void fail(String message) { + if (whenFails != null) whenFails.accept(message); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/scheduler/ThemeParkScheduler.java b/src/main/java/nl/iobyte/themepark/scheduler/ThemeParkScheduler.java new file mode 100644 index 0000000..fdd0b17 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/scheduler/ThemeParkScheduler.java @@ -0,0 +1,62 @@ +package nl.iobyte.themepark.scheduler; + +import nl.iobyte.themepark.ThemePark; +import org.bukkit.Bukkit; + +public class ThemeParkScheduler { + + /** + * Execute runnable in sync + * @param r Runnable + */ + public static void runSync(Runnable r) { + if(ThemePark.getInstance().isDisabling()) { + r.run(); + return; + } + + Bukkit.getScheduler().runTask(ThemePark.getInstance(), r); + } + + /** + * Execute runnable in sync after delay of X ticks + * @param r Runnable + * @param delay Delay + */ + public static void runSyncLater(Runnable r, long delay) { + if(ThemePark.getInstance().isDisabling()) { + r.run(); + return; + } + + Bukkit.getScheduler().runTaskLater(ThemePark.getInstance(), r, delay); + } + + /** + * Execute runnable in async + * @param r Runnable + */ + public static void runAsync(Runnable r) { + if(ThemePark.getInstance().isDisabling()) { + r.run(); + return; + } + + Bukkit.getScheduler().runTaskAsynchronously(ThemePark.getInstance(), r); + } + + /** + * Execute runnable in async after delay of X ticks + * @param r Runnable + * @param delay Delay + */ + public static void runAsyncLater(Runnable r, long delay) { + if(ThemePark.getInstance().isDisabling()) { + r.run(); + return; + } + + Bukkit.getScheduler().runTaskLaterAsynchronously(ThemePark.getInstance(), r, delay); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/traincarts/RideCountSign.java b/src/main/java/nl/iobyte/themepark/traincarts/RideCountSign.java new file mode 100644 index 0000000..8a5d862 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/traincarts/RideCountSign.java @@ -0,0 +1,78 @@ +package nl.iobyte.themepark.traincarts; + +import com.bergerkiller.bukkit.tc.controller.MinecartMember; +import com.bergerkiller.bukkit.tc.events.SignActionEvent; +import com.bergerkiller.bukkit.tc.events.SignChangeActionEvent; +import com.bergerkiller.bukkit.tc.signactions.SignAction; +import com.bergerkiller.bukkit.tc.signactions.SignActionType; +import com.bergerkiller.bukkit.tc.utils.SignBuildOptions; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.ThemeParkAPI; +import org.bukkit.entity.Player; +import java.util.ArrayList; + +public class RideCountSign extends SignAction { + + @Override + public boolean match(final SignActionEvent info) { + return info.getLine(1).equalsIgnoreCase("ridecount") && !info.getLine(2).isEmpty() && !info.getLine(3).isEmpty(); + } + + @Override + public void execute(final SignActionEvent info) { + if (!info.isPowered()) + return; + + if (info.isTrainSign() && info.isAction(SignActionType.REDSTONE_ON, SignActionType.GROUP_ENTER) && info.hasGroup()) { + ArrayList players = new ArrayList<>(); + for (final MinecartMember member : info.getGroup()) + players.addAll(member.getEntity().getPlayerPassengers()); + + count(players, info); + return; + } + + if (!info.isCartSign() || !info.isAction(SignActionType.REDSTONE_ON, SignActionType.MEMBER_ENTER) || !info.hasMember()) { + if (info.isRCSign() && info.isAction(SignActionType.REDSTONE_ON)) { + ArrayList players = new ArrayList<>(); + for (final MinecartMember member : info.getGroup()) + players.addAll(member.getEntity().getPlayerPassengers()); + + count(players, info); + } + + return; + } + + if (!info.getMember().getEntity().isEmpty()) { + ArrayList players = new ArrayList<>(info.getMember().getEntity().getPlayerPassengers()); + count(players, info); + } + } + + @Override + public boolean build(SignChangeActionEvent event) { + return SignBuildOptions.create() + .setName(event.isCartSign() ? "cart ridecount sign" : "train ridecount sign") + .setDescription("Add a count to a player for an attraction") + .handle(event.getPlayer()); + } + + private void count(ArrayList players, SignActionEvent info) { + String id = info.getLine(2); + ThemeParkAPI api = ThemePark.getInstance().getAPI(); + if(!api.getAttractionService().hasAttraction(id)) + return; + + int amount = 1; + try { + amount = Integer.parseInt(info.getLine(3)); + } catch (Exception e) { + e.printStackTrace(); + } + + for(Player player : players) + api.getRideCountService().addCount(id, player.getUniqueId(), amount); + } + +} \ No newline at end of file diff --git a/src/main/java/nl/iobyte/themepark/utils/LocationUtil.java b/src/main/java/nl/iobyte/themepark/utils/LocationUtil.java new file mode 100644 index 0000000..a317c4e --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/utils/LocationUtil.java @@ -0,0 +1,52 @@ +package nl.iobyte.themepark.utils; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; + +public class LocationUtil { + + /** + * Get String from Location instance + * @param location Location + * @return String + */ + public static String toString(Location location) { + if(location == null) + return ""; + + return location.getWorld().getName() + +","+location.getX() + +","+location.getY() + +","+location.getZ() + +","+location.getYaw() + +","+location.getPitch(); + } + + /** + * Get Location instance from String + * @param str String + * @return Location + */ + public static Location fromString(String str) { + if(str == null || str.isEmpty()) + return null; + + String[] args = str.split(","); + if(args.length < 6) + return null; + + World world = Bukkit.getWorld(args[0]); + double x = Double.parseDouble(args[1]); + double y = Double.parseDouble(args[2]); + double z = Double.parseDouble(args[3]); + float yaw = Float.parseFloat(args[4]); + float pitch = Float.parseFloat(args[5]); + + Location location = new Location(world, x, y, z); + location.setYaw(yaw); + location.setPitch(pitch); + return location; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/utils/PlaceHolder.java b/src/main/java/nl/iobyte/themepark/utils/PlaceHolder.java new file mode 100644 index 0000000..f9f0269 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/utils/PlaceHolder.java @@ -0,0 +1,16 @@ +package nl.iobyte.themepark.utils; + +import me.clip.placeholderapi.PlaceholderAPI; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +public class PlaceHolder { + + public static String setPlaceHolders(Player player, String str) { + if(Bukkit.getPluginManager().getPlugin("PlaceholderAPI") == null) + return str; + + return PlaceholderAPI.setPlaceholders(player, str); + } + +} diff --git a/src/main/java/nl/iobyte/themepark/utils/StatusMessage.java b/src/main/java/nl/iobyte/themepark/utils/StatusMessage.java new file mode 100644 index 0000000..646bff0 --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/utils/StatusMessage.java @@ -0,0 +1,85 @@ +package nl.iobyte.themepark.utils; + +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import nl.iobyte.themepark.ThemePark; +import nl.iobyte.themepark.api.attraction.objects.Attraction; +import nl.iobyte.themepark.api.config.enums.StorageLocation; +import nl.iobyte.themepark.api.message.MessageKey; +import nl.iobyte.themepark.api.message.Text; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class StatusMessage { + + public static void broadcast(Attraction attraction) { + HashMap change = new HashMap<>(); + change.put("{name}", attraction.getName()); + ClickEvent click = new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/themepark attraction warp "+attraction.getID()); + HoverEvent hover = new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(Text.color(ThemePark.getInstance().getAPI().getConfigurationManager().getString(StorageLocation.MESSAGE, "attraction.changed.hover")))); + if(hover.getValue()[0].toPlainText().isEmpty()) + hover = null; + + BaseComponent message = parseTP("attraction.changed."+attraction.getStatus().toString(), change, click, hover); + if(message == null) + return; + + for(Player player : Bukkit.getOnlinePlayers()) + player.spigot().sendMessage(message); + } + + private static BaseComponent parseTP(String path, HashMap change, ClickEvent click, HoverEvent hover) { + String message = ThemePark.getInstance().getAPI().getConfigurationManager().getString(StorageLocation.MESSAGE, path); + message = message.replace("{prefix}", MessageKey.PREFIX.getMessage()); + for(Map.Entry entrySet : change.entrySet()) + message = message.replace(entrySet.getKey(), entrySet.getValue()); + + message = Text.color(message); + if(click != null) { + String regex = "(.*)\\[TP\\](.*?)\\[/TP\\](.*)"; + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(message); + while (m.find()) { + String first = m.group(1); + String middle = m.group(2); + String last = m.group(3); + + BaseComponent[] components = TextComponent.fromLegacyText(first); + BaseComponent component = components[0]; + for(int i = 1; i < components.length; i++) + component.addExtra(components[i]); + + components = TextComponent.fromLegacyText(middle); + BaseComponent compClick = components[0]; + for(int i = 1; i < components.length; i++) + compClick.addExtra(components[i]); + + compClick.setClickEvent(click); + if(hover != null) + compClick.setHoverEvent(hover); + + component.addExtra(compClick); + components = TextComponent.fromLegacyText(last); + BaseComponent compLast = components[0]; + for (BaseComponent baseComponent : components) component.addExtra(baseComponent); + + component.addExtra(compLast); + return component; + } + } + + BaseComponent[] components = TextComponent.fromLegacyText(message); + BaseComponent component = components[0]; + for(int i = 1; i < components.length; i++) + component.addExtra(components[i]); + + return component; + } + +} diff --git a/src/main/java/nl/iobyte/themepark/utils/VersionComparator.java b/src/main/java/nl/iobyte/themepark/utils/VersionComparator.java new file mode 100644 index 0000000..0d012bf --- /dev/null +++ b/src/main/java/nl/iobyte/themepark/utils/VersionComparator.java @@ -0,0 +1,43 @@ +package nl.iobyte.themepark.utils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +public class VersionComparator implements Comparator { + + /** + * Check if Version B is older,newer or the same than A + * @param s1 String + * @param s2 String + * @return int + */ + public int compare(String s1, String s2) { + if(s1.equals(s2)) + return 0; + + List l1 = new ArrayList<>(Arrays.asList(s1.split("\\."))); + List l2 = new ArrayList<>(Arrays.asList(s2.split("\\."))); + while(l1.size() != l2.size()) { + if(l1.size() < l2.size()) { + l1.add("0"); + } else { + l2.add("0"); + } + } + + int i = 0; + while (i < l1.size() && l1.get(i).equals(l2.get(i))) + i++; + + int a = 0; + try { + if (i < l1.size()) + a = Integer.signum(Integer.valueOf(l1.get(i)).compareTo(Integer.valueOf(l2.get(i)))); + } catch (Exception e) { } + + return a; + } + +} diff --git a/src/main/resources/menu.yml b/src/main/resources/menu.yml new file mode 100644 index 0000000..5dd6c7f --- /dev/null +++ b/src/main/resources/menu.yml @@ -0,0 +1,45 @@ +version: 1.0 + +menu: + item: + enabled: true + material: 'NETHER_STAR' + data: 0 + name: '&6Themepark' + slot: 4 + clear: true + worlds: + - world_nether + - world_the_end + main: + size: 27 + title: '&6&lThemePark' + status: + title: '&6&lAttraction Status' + +items: + '0': + slot: 11 + amount: 1 + name: '&6&lStore' + data: 0 + material: GOLD_INGOT + action: JSON_MESSAGE + message: '[{"text":"Click ","color":"gold"},{"text":"HERE","bold":true,"color":"aqua","clickEvent":{"action":"open_url","value":"https://www.iobyte.nl"},"hoverEvent":{"action":"show_text","contents":{"text":"Click + to go to store","color":"gold"}}},{"text":" to go to the store","color":"gold"}]' + '1': + slot: 13 + amount: 1 + name: '&6&lAttraction Status' + data: 0 + material: MINECART + action: STATUS_MENU + lore: '&fSee what''s open' + '2': + slot: 15 + amount: 1 + name: '&6&lAudio' + data: 0 + material: JUKEBOX + action: COMMAND + command: /audio diff --git a/src/main/resources/message.yml b/src/main/resources/message.yml new file mode 100644 index 0000000..7e24db8 --- /dev/null +++ b/src/main/resources/message.yml @@ -0,0 +1,20 @@ +version: 1.0 + +prefix: '&6&lThemeParkMC &r&f➢' + +ridecount: + add: "{prefix} &aYou have ridden attraction: &f%NAME% &6%AMOUNT%x &afor a total of &6%TOTAL%x" + +attraction: + changed: + hover: "&6Click to Warp" + CONSTRUCTION: "{prefix} &fAttraction: {name} &fis now &7Under Construction" + OPEN: "{prefix} &fAttraction: [TP]&r{name}[/TP] &fhas been &aOpened" + CLOSED: "{prefix} &fAttraction: &r{name} &fhas been &4Closed" + MAINTENANCE: "{prefix} &fAttraction: &r{name} &fis now in &6Maintenance" + MALFUNCTION: "{prefix} &fAttraction: &r{name} &fhas been closed due to a &5Malfunction" + ACTIVE: "{prefix} &fShow: &r{name} &fis now &aActive" + INACTIVE: "{prefix} &fShow: &r{name} &fis now &4In Active" + teleport: + status: "{prefix} &4It's not possible to teleport to &r{name} &4because it's {status}" + success: "{prefix} &ayou have been teleported to the attraction: &r{name}" \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..79b2532 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,9 @@ +name: ThemePark +version: 3.0.0 +author: IOByte +website: 'https://www.iobyte.nl' +main: nl.iobyte.themepark.ThemePark +softdepend: [PlaceholderAPI,Train_Carts,Multiverse-Core,MultiWorld] +api-version: 1.13 +commands: + themepark: \ No newline at end of file diff --git a/src/main/resources/settings.yml b/src/main/resources/settings.yml new file mode 100644 index 0000000..3fcbd6e --- /dev/null +++ b/src/main/resources/settings.yml @@ -0,0 +1,15 @@ +version: 1.1 + +mysql: + enabled: false + host: 'localhost' + port: 3306 + name: 'database' + username: 'root' + password: '' + url: 'jdbc:mysql://%host%:%port%/%database%?useSSL=false' + +sign: + status: + name: '[ThemeParkMC]' + title: '&f[&6&lThemeParkMC&f]' \ No newline at end of file diff --git a/themepark.iml b/themepark.iml new file mode 100644 index 0000000..0630145 --- /dev/null +++ b/themepark.iml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file